1/** 2 * \file 3 * \brief Driver for booting the Xeon Phi Coprocessor card on a Barrelfish Host 4 */ 5 6/* 7 * Copyright (c) 2014 ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <barrelfish/barrelfish.h> 16#include <barrelfish/waitset.h> 17 18#include <virtio/virtio.h> 19#include <virtio/virtqueue.h> 20#include <virtio/virtqueue_host.h> 21#include <virtio/virtio_device.h> 22#include <virtio/virtio_host.h> 23#include <virtio/devices/virtio_block.h> 24 25#include "host.h" 26#include "device.h" 27#include "request.h" 28#include "service.h" 29 30struct virtio_device *host; 31 32static errval_t handle_open(struct virtio_device *vdev, uint8_t backend, struct capref *ret_frame) 33{ 34 assert(host); 35 36 virtio_host_get_device_cap(vdev, ret_frame); 37 38 assert(!capref_is_null(*ret_frame)); 39 40 return SYS_ERR_OK; 41} 42 43static errval_t handle_add(struct virtio_device *vdev, struct capref ring, 44 uint16_t ndesc, uint8_t buf_bits,uint16_t vq_id) 45{ 46 debug_printf("handle_add\n"); 47 return SYS_ERR_OK; 48} 49 50 51static struct virtio_host_cb host_cb = { 52 .open = handle_open, 53 .add = handle_add 54}; 55 56static void virtq_do_work(struct virtqueue_host *vqh, 57 void *arg, 58 struct virtio_host_buf *buf, 59 uint16_t idx) 60{ 61 debug_printf("virtq_do_work"); 62 63 64 65 virtio_vq_host_desc_enqueue(vqh, buf, idx); 66} 67 68int main(int argc, char *argv[]) 69{ 70 errval_t err; 71 72 debug_printf("VirtIO block device host started.\n"); 73 74 struct virtqueue_setup vq_setup = { 75 .name = "Request Virtqueue", 76 .vring_ndesc = 16, 77 .max_indirect =0, 78 .worker_arg = NULL, 79 .worker_fn = virtq_do_work 80 }; 81 82 struct virtio_device_setup setup = { 83 .features = 0xFFFFFFFFFFFFFFFF, 84 .vq_num = 1, 85 .vq_setup = &vq_setup, 86 .hc_cb = &host_cb, 87 .hc_type = VIRTIO_HOST_CHAN_FLOUNDER, 88 .backend = { 89 .type = VIRTIO_DEVICE_BACKEND_MMIO, 90 .args = {} 91 }, 92 .hc_iface = VIRTIO_BLOCK_FLOUNDER_IFACE, 93 .dev_type = VIRTIO_DEVICE_TYPE_BLOCK 94 }; 95 96 err = virtio_host_init(&host, 97 &setup); 98 if (err_is_fail(err)) { 99 USER_PANIC_ERR(err, "Service initialization failed.\n"); 100 } 101 102 struct waitset *ws = get_default_waitset(); 103 while(1) { 104 uint8_t idle_count = 0; 105 err = virtio_host_poll_device(host); 106 if (err_is_fail(err)) { 107 if (err_no(err) == VIRTIO_ERR_DEVICE_IDLE) { 108 idle_count++; 109 } else { 110 USER_PANIC_ERR(err, "error while polling device"); 111 } 112 } 113 err = event_dispatch_non_block(ws); 114 if (err_is_fail(err)) { 115 if (err_no(err) == LIB_ERR_NO_EVENT) { 116 idle_count++; 117 } else { 118 USER_PANIC_ERR(err, "error while dispatching events"); 119 } 120 } 121 if (idle_count == 2) { 122 thread_yield(); 123 } 124 } 125 126 debug_printf("VirtIO block device host terminated.\n"); 127} 128 129