1/* 2 * Copyright (c) 2014 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <string.h> 11 12#include <barrelfish/barrelfish.h> 13 14#include <virtio/virtio.h> 15#include <virtio/virtqueue.h> 16#include <virtio/virtqueue_host.h> 17#include <virtio/virtio_device.h> 18#include <virtio/virtio_host.h> 19 20#include "device.h" 21 22#include "backends/virtio_mmio.h" 23#include "backends/virtio_pci.h" 24 25#include "host/channel.h" 26 27 28static lpaddr_t paddr_offset = 0x0; 29 30/** 31 * 32 */ 33 34/** 35 * 36 */ 37errval_t virtio_host_init(struct virtio_device **host, 38 struct virtio_device_setup *setup) 39{ 40 errval_t err = SYS_ERR_OK; 41 42 switch(setup->backend.type) { 43 case VIRTIO_DEVICE_BACKEND_PCI: 44 assert(!"NYI: PCI backend"); 45 break; 46 47 case VIRTIO_DEVICE_BACKEND_MMIO: 48 err = virtio_device_mmio_init_host(host, setup); 49 break; 50 case VIRTIO_DEVICE_BACKEND_IO: 51 assert(!"NYI: IO backend"); 52 break; 53 default: 54 err = VIRTIO_ERR_ARG_INVALID; 55 break; 56 } 57 58 if (err_is_fail(err)) { 59 return err; 60 } 61 62 struct virtio_device *vdev = *host; 63 64 strncpy(vdev->dev_name, setup->dev_name, sizeof(vdev->dev_name)); 65 vdev->dev_t_st = setup->dev_t_st; 66 strncpy(vdev->hc_iface, setup->hc_iface, sizeof(vdev->hc_iface)); 67 68 vdev->cb_h = setup->hc_cb; 69 70 vdev->vq_num = setup->vq_num; 71 72 setup->vq_setup->device = vdev; 73 74 err = virtio_vq_host_alloc(&vdev->vqh, setup->vq_setup, setup->vq_num); 75 assert(err_is_ok(err)); 76 77 switch (setup->hc_type) { 78 case VIRTIO_HOST_CHAN_FLOUNDER: 79 err = virtio_host_flounder_init(vdev); 80 break; 81 82 case VIRTIO_HOST_CHAN_XEON_PHI: 83 err = virtio_host_xeon_phi_init(); 84 break; 85 default: 86 err = -1; 87 break; 88 } 89 90 if (err_is_fail(err)) { 91 return err; 92 } 93 94 return SYS_ERR_OK; 95} 96 97errval_t virtio_host_poll_device(struct virtio_device *host) 98{ 99 errval_t err; 100 if (host->f->poll) { 101 err = host->f->poll(host); 102 if (err_is_fail(err)) { 103 return err; 104 } 105 } else { 106 return VIRTIO_ERR_BACKEND; 107 } 108 return virtio_vq_host_poll(host->vqh, host->vq_num); 109 110} 111 112errval_t virtio_host_get_device_cap(struct virtio_device *host, 113 struct capref *ret_cap) 114{ 115 if(ret_cap) { 116 *ret_cap = host->dev_cap; 117 } 118 return SYS_ERR_OK; 119} 120 121lpaddr_t virtio_host_translate_host_addr(lpaddr_t host_phys) 122{ 123 lpaddr_t guest_addr = (host_phys - paddr_offset); 124 assert(guest_addr <= host_phys); 125 return guest_addr; 126} 127 128lpaddr_t virtio_host_translate_guest_addr(lpaddr_t guest_phys) 129{ 130 lpaddr_t host_addr = (guest_phys + paddr_offset); 131 assert(guest_phys <= host_addr); 132 return host_addr; 133} 134 135