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#include <barrelfish/barrelfish.h>
15
16#include <virtio/virtio.h>
17#include <virtio/virtio_device.h>
18#include <virtio/devices/virtio_block.h>
19#include <virtio/virtio_guest.h>
20
21#include <dev/virtio/virtio_blk_dev.h>
22
23#include "device.h"
24#include "request.h"
25#include "service.h"
26
27struct vblock_device blk_dev;
28
29int main(int argc, char *argv[])
30{
31    errval_t err;
32
33    debug_printf("VirtIO block device driver started.\n");
34
35    err = virtio_guest_init(VIRTIO_GUEST_CHAN_FLOUNDER,
36                            VIRTIO_BLOCK_FLOUNDER_IFACE);
37    if (err_is_fail(err)) {
38        USER_PANIC_ERR(err, "Could not initialize the library\n");
39    }
40
41    struct capref dev_frame;
42    err = virtio_guest_open_device(VIRTIO_DEVICE_BACKEND_MMIO, &dev_frame);
43    if (err_is_fail(err)) {
44        USER_PANIC_ERR(err, "Could not open the device\n");
45    }
46
47    struct frame_identity id;
48    err = invoke_frame_identify(dev_frame, &id);
49    if (err_is_fail(err)) {
50        USER_PANIC_ERR(err, "identifying the frame failed\n");
51    }
52
53    size_t dev_size = id.bytes;
54
55    void *dev_regs;
56    err = vspace_map_one_frame_attr(&dev_regs, dev_size, dev_frame, VIRTIO_VREGION_FLAGS_DEVICE, NULL, NULL);
57    if (err_is_fail(err)) {
58        USER_PANIC_ERR(err, "failed to map the device frame");
59    }
60
61    vblock_device_init(&blk_dev, dev_regs, dev_size);
62
63    uint32_t count = 0;
64    while(count < 32) {
65        debug_printf("\n\n------------------------------------Round: %u\n", count++);
66        struct vblock_req *req = vblock_request_alloc(&blk_dev);
67        if (!req) {
68            USER_PANIC("no request available\n");
69            break;
70        }
71
72        struct virtio_buffer *buf = virtio_buffer_alloc(blk_dev.alloc);
73        if (!buf) {
74            vblock_request_free(&blk_dev, req);
75            USER_PANIC("no buffer available\n");
76            break;
77        }
78
79        snprintf(buf->buf, buf->length, "Hello world!!\n");
80
81        err = virtio_blist_append(&req->bl, buf);
82        assert(err_is_ok(err));
83
84        assert(req->bl.length == 1);
85
86        err = vblock_request_exec(&blk_dev, req);
87        if (err_is_fail(err)) {
88            USER_PANIC_ERR(err, "execute the request");
89        }
90
91        struct virtio_buffer *ret_buf = virtio_blist_head(&req->bl);
92        assert(req->bl.length == 0);
93
94        assert(ret_buf == buf);
95
96        debug_printf("data=[%s]", (char*)ret_buf->buf);
97
98
99        virtio_buffer_free(buf);
100
101        vblock_request_free(&blk_dev, req);
102    }
103
104    debug_printf("VirtIO block device driver terminated.\n");
105}
106