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