Some initial implementations of VirtIO - libvirtio - driver stubs
authorReto Achermann <acreto@student.ethz.ch>
Mon, 9 Jun 2014 20:36:18 +0000 (22:36 +0200)
committerStefan Kaestle <stefan.kaestle@inf.ethz.ch>
Wed, 20 Aug 2014 20:03:35 +0000 (22:03 +0200)
28 files changed:
errors/errno.fugu
hake/symbolic_targets.mk
include/virtio/virtio.h
include/virtio/virtio_device.h [new file with mode: 0644]
include/virtio/virtio_mmio.h [deleted file]
include/virtio/virtio_pci.h [deleted file]
include/virtio/virtio_ring.h
include/virtio/virtqueue.h [new file with mode: 0644]
lib/virtio/Hakefile
lib/virtio/backends/virtio_device_mmio.c [new file with mode: 0644]
lib/virtio/backends/virtio_device_pci.c [new file with mode: 0644]
lib/virtio/backends/virtio_mmio.h [new file with mode: 0644]
lib/virtio/backends/virtio_pci.h [copied from usr/drivers/virtio/net/main.c with 50% similarity]
lib/virtio/debug.h [new file with mode: 0644]
lib/virtio/virtio_buffer.c [new file with mode: 0644]
lib/virtio/virtio_buffer.h [new file with mode: 0644]
lib/virtio/virtio_device.c [copied from usr/drivers/virtio/net/main.c with 64% similarity]
lib/virtio/virtio_ring.c
lib/virtio/virtqueue.c [new file with mode: 0644]
usr/drivers/virtio/block/Hakefile [new file with mode: 0644]
usr/drivers/virtio/block/main_guest.c [copied from usr/drivers/virtio/net/main.c with 91% similarity]
usr/drivers/virtio/block/main_host.c [copied from usr/drivers/virtio/block/main.c with 100% similarity]
usr/drivers/virtio/console/Hakefile [new file with mode: 0644]
usr/drivers/virtio/console/main_guest.c [moved from usr/drivers/virtio/console/main.c with 100% similarity]
usr/drivers/virtio/console/main_host.c [moved from usr/drivers/virtio/net/main.c with 100% similarity]
usr/drivers/virtio/net/Hakefile [new file with mode: 0644]
usr/drivers/virtio/net/main_guest.c [copied from usr/drivers/virtio/block/main.c with 100% similarity]
usr/drivers/virtio/net/main_host.c [moved from usr/drivers/virtio/block/main.c with 100% similarity]

index 0b8adf4..b44cd1d 100755 (executable)
@@ -1000,3 +1000,10 @@ errors bulk_transfer BULK_TRANSFER_ {
     
 };
 
+errors virtio VIRTIO_ERR_ {
+       failure SIZE_INVALID            "Size of the ringe is zero or not a power of two",
+       failure MAX_INDIRECT            "Too much indirect descriptors",
+       failure CAP_SIZE                        "Supplied cap is too small",
+       failure QUEUE_FULL                      "The queue was full",
+       failure QUEUE_EMPTY                     "The queue was empty",
+};
index a8e9df2..fd2ceca 100644 (file)
@@ -507,7 +507,8 @@ XEON_PHI_MODULES =\
        k1om/sbin/spawnd \
        k1om/sbin/startd \
        k1om/sbin/xeon_phi \
-       k1om/sbin/xeon_phi_test
+       k1om/sbin/xeon_phi_test \
+       k1om/sbin/virtio_blk
        
 
 menu.lst.k1om: $(SRCDIR)/hake/menu.lst.k1om
index 90bc2a8..2f883c0 100644 (file)
 
 #include <barrelfish/barrelfish.h>
 
-/*
- * 2.1 Device Status Field
- */
-
-/// The device is in the reset state (not discovered by the guest)
-#define VIRTIO_DEVICE_STATUS_RESET       0x00
-
-/// Guest OS has found the device and recognized it as a valid virtio device.
-#define VIRTIO_DEVICE_STATUS_ACKNOWLEDGE 0x01
-
-/// Guest OS knows how to drive the device i.e. recognized as valid virtio device.
-#define VIRTIO_DEVICE_STATUS_DRIVER      0x02
-
-/// Driver is set up and ready to drive the device.
-#define VIRTIO_DEVICE_STATUS_DRIVER_OK   0x04
-
-/// Driver has acknowledged all the features it understands
-#define VIRTIO_DEVICE_STATUS_FEATURES_OK 0x08
-
-/// Something went wrong in the guest, and it has given up on the device.
-#define VIRTIO_DEVICE_STATUS_FAILED      0x80
-
-/*
- * 5.0 Device Types
- * The following device IDs are used to identify different types of virtio
- * devices. Some device IDs are reserved for devices which are not currently
- * defined in this standard.
- */
-
-/// Invalid device identifier
-#define VIRTIO_DEVICE_TYPE_INVALID   0x00
-
-/// Device type for network interface cards
-#define VIRTIO_DEVICE_TYPE_NET       0x01
-
-/// Device type for block devices
-#define VIRTIO_DEVICE_TYPE_BLOCK     0x02
-
-/// Device type for console devices
-#define VIRTIO_DEVICE_TYPE_CONSOLE   0x03
-
-/// Device type for entorpy devices
-#define VIRTIO_DEVICE_TYPE_ENTORPY   0x04
-
-//#define VIRTIO_DEVICE_TYPE_LEGACY_BALLOON 5
-
-/// Device type for IO memory devices
-#define VIRTIO_DEVICE_TYPE_IOMEM     0x06
-
-/// Device type for rpmgs devices
-#define VIRTIO_DEVICE_TYPE_RPMSG     0x07
-
-/// Device type for SCSI host devices
-#define VIRTIO_DEVICE_TYPE_SCSIHOST  0x08
-
-/// Device type for 9P transport devices
-#define VIRTIO_DEVICE_TYPE_9PTRANSP  0x09
-
-/// Device type for MAC 802.11 WLAn devices
-#define VIRTIO_DEVICE_TYPE_WLAN      0x0A
-
-/// Device type for RPROC serial devices
-#define VIRTIO_DEVICE_TYPE_SERIAL    0x0B
-
-/// Device type for virtio CAIF devices
-#define VIRTIO_DEVICE_TYPE_CAIF      0x0C
-
-/// Device type for memory ballooning devices
-#define VIRTIO_DEVICE_TYPE_BALLOON   0x0D
-
-/// Device type for GPU devices
-#define VIRTIO_DEVICE_TYPE_GPU       0x0E
-
-/// Device type for timer / clock devices
-#define VIRTIO_DEVICE_TYPE_TIMER     0x0F
-
 
 /*
  * Generic Feature Bits
  */
+
 /// Generate interrupt if queue is completely used
 #define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)
 
 #define VIRTIO_TRANSPORT_F_END      32
 
 
+
+
 /**
- * \brief this struct represents a virtio device
+ * \brief this struct represents a virtio driver
  *
- * This can be seen as on the host side of the virtio channel
+ * This can be seen as on the guest side of the virtio channel
  */
-struct virtio_device
+struct virtio_driver
 {
-    struct virtio_device_id id; ///< the virtio device id
-
-    struct virtio_fn    fn;     ///< backend specific implementation
-
     void *device_config;
 
-    size_t          num_queues; ///< number of vqueues associated with the dev
-    struct vring    vqueues;    ///< the
 
 };
 
 
 /**
- * \brief this struct represents a virtio driver
- *
- * This can be seen as on the guest side of the virtio channel
+ * VirtIO Memory segment
  */
-struct virtio_driver
+struct virtio_buffer
 {
-    void *device_config;
 
+};
 
+struct virtio_buffer_allocator
+{
+    struct virtio_buffer *buffers;
+    uint16_t size;
+    uint16_t top;
 };
 
-/**
- * \brief adds a buffer to the available ring
- */
-errval_t virtio_add_buffer();
+errval_t virtio_buffer_alloc_init(struct virtio_buffer_allocator *alloc,
+                                  uint16_t nbufs);
+
+errval_t virtio_buffer_alloc(void);
+errval_t virtio_buffer_free(void);
+
+
+errval_t virtio_buffer_list_reset(void);
+errval_t virtio_buffer_list_append(void);
 
-/**
- * \brief gets the next used buffer
- */
-errval_t virtio_get_buffer();
 
-/**
- * \brief
- */
-void virtio_disable_callback(void);
 
-/**
- * \brief
- */
-void virtio_enable_callback();
 
 
 #endif // VIRTIO_H
diff --git a/include/virtio/virtio_device.h b/include/virtio/virtio_device.h
new file mode 100644 (file)
index 0000000..7b888c2
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef VIRTIO_VIRTIO_DEVICE_H
+#define VIRTIO_VIRTIO_DEVICE_H
+
+
+struct virtio_device;
+
+/*
+ * 2.1 Device Status Field
+ */
+
+/// The device is in the reset state (not discovered by the guest)
+#define VIRTIO_DEVICE_STATUS_RESET       0x00
+
+/// Guest OS has found the device and recognized it as a valid virtio device.
+#define VIRTIO_DEVICE_STATUS_ACKNOWLEDGE 0x01
+
+/// Guest OS knows how to drive the device i.e. recognized as valid virtio device.
+#define VIRTIO_DEVICE_STATUS_DRIVER      0x02
+
+/// Driver is set up and ready to drive the device.
+#define VIRTIO_DEVICE_STATUS_DRIVER_OK   0x04
+
+/// Driver has acknowledged all the features it understands
+#define VIRTIO_DEVICE_STATUS_FEATURES_OK 0x08
+
+/// Something went wrong in the guest, and it has given up on the device.
+#define VIRTIO_DEVICE_STATUS_FAILED      0x80
+
+/*
+ * 5.0 Device Types
+ * The following device IDs are used to identify different types of virtio
+ * devices. Some device IDs are reserved for devices which are not currently
+ * defined in this standard.
+ */
+
+/// Invalid device identifier
+#define VIRTIO_DEVICE_TYPE_INVALID   0x00
+
+/// Device type for network interface cards
+#define VIRTIO_DEVICE_TYPE_NET       0x01
+
+/// Device type for block devices
+#define VIRTIO_DEVICE_TYPE_BLOCK     0x02
+
+/// Device type for console devices
+#define VIRTIO_DEVICE_TYPE_CONSOLE   0x03
+
+/// Device type for entorpy devices
+#define VIRTIO_DEVICE_TYPE_ENTORPY   0x04
+
+//#define VIRTIO_DEVICE_TYPE_LEGACY_BALLOON 5
+
+/// Device type for IO memory devices
+#define VIRTIO_DEVICE_TYPE_IOMEM     0x06
+
+/// Device type for rpmgs devices
+#define VIRTIO_DEVICE_TYPE_RPMSG     0x07
+
+/// Device type for SCSI host devices
+#define VIRTIO_DEVICE_TYPE_SCSIHOST  0x08
+
+/// Device type for 9P transport devices
+#define VIRTIO_DEVICE_TYPE_9PTRANSP  0x09
+
+/// Device type for MAC 802.11 WLAn devices
+#define VIRTIO_DEVICE_TYPE_WLAN      0x0A
+
+/// Device type for RPROC serial devices
+#define VIRTIO_DEVICE_TYPE_SERIAL    0x0B
+
+/// Device type for virtio CAIF devices
+#define VIRTIO_DEVICE_TYPE_CAIF      0x0C
+
+/// Device type for memory ballooning devices
+#define VIRTIO_DEVICE_TYPE_BALLOON   0x0D
+
+/// Device type for GPU devices
+#define VIRTIO_DEVICE_TYPE_GPU       0x0E
+
+/// Device type for timer / clock devices
+#define VIRTIO_DEVICE_TYPE_TIMER     0x0F
+
+/**
+ * specifies the possible virtio backends to be used
+ */
+enum virtio_device_backend {
+    VIRTIO_DEVICE_BACKEND_INVALID,
+    VIRTIO_DEVICE_BACKEND_PCI,
+    VIRTIO_DEVICE_BACKEND_MMIO,
+};
+
+/*
+ * 4.1.2 PCI Device Discovery
+ *
+ * Any PCI device with Vendor ID 0x1AF4, and Device ID 0x1000 through 0x103F
+ * inclusive is a virtio device. The Subsystem Device ID indicates which virtio
+ * device is supported by the device.
+ */
+
+#define VIRTIO_PCI_VENDOR_ID 0x1AF4
+#define VIRTIO_PCI_DEVICE_ID 0x1000
+#define VIRTIO_PCI_DEVICE_ID2 0x103F
+
+
+/**
+ * contains necessary values for the device initialization process
+ */
+struct virtio_device_init
+{
+    uint8_t type;                           ///< expected type of the device
+    enum virtio_device_backend  backend;    ///< which backend to use
+};
+
+/**
+ * contains function pointers to backend specific functions
+ */
+struct virtio_device_fn
+{
+    errval_t(*virtio_dev_init_t)(struct virtio_device *dev);
+};
+
+/**
+ * represents a virtio device
+ */
+struct virtio_device
+{
+    uint8_t type;
+    enum virtio_device_backend backend;
+    struct virtio_device_fn *f;
+};
+
+/**
+ * \brief initializes the common part of the virtio device structure
+ *
+ * \param dev       device structure to initialize
+ * \param init      additional information passed for the init process
+ * \param dev_regs  memory location of the device registers
+ */
+errval_t virtio_device_init(struct virtio_device **dev,
+                            struct virtio_device_init *init,
+                            void *dev_regs);
+
+/**
+ * \brief initializes the common part of the virtio device structure based on
+ *        a supplied cap which gets mapped
+ *
+ * \param dev       device structure to initialize
+ * \param init      additional information passed for the init process
+ * \param dev_cap   capability representing the device registers
+ */
+errval_t virtio_device_init_with_cap(struct virtio_device **dev,
+                                     struct capref dev_cap);
+
+
+#endif // VIRTIO_VIRTIO_DEVICE_H
diff --git a/include/virtio/virtio_mmio.h b/include/virtio/virtio_mmio.h
deleted file mode 100644 (file)
index dd2bccf..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2014 ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#ifndef VIRTIO_VIRTIO_MMIO_H
-#define VIRTIO_VIRTIO_MMIO_H
-
-#include <barrelfish/barrelfish.h>
-#include <virtio/virtio.h>
-
-/**
- * \brief initializes a new virtio device structure
- */
-errval_t virtio_mmio_device_init(struct virtio_device **vdev,
-                                 void *device_config,
-                                 struct capref mmio);
-
-/**
- * \brief de-initialization of the device structure and freeing of resources
- */
-errval_t virtio_mmio_device_free(struct virtio_device **vdev);
-
-/**
- * \brief initializes a new virtio driver structure
- */
-errval_t virtio_mmio_driver_init(struct virtio_driver **vdrv,
-                                 struct capref mmio);
-
-/**
- * \brief de-initialization of the driver structure and freeing of resources
- */
-errval_t virtio_mmio_driver_free(struct virtio_driver **vdrv);
-
-#endif // VIRTIO_VIRTIO_MMIO_H
diff --git a/include/virtio/virtio_pci.h b/include/virtio/virtio_pci.h
deleted file mode 100644 (file)
index f6ebc0c..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2014 ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#ifndef VIRTIO_VIRTIO_PCI_H
-#define VIRTIO_VIRTIO_PCI_H
-
-#include <barrelfish/barrelfish.h>
-
-/*
- * 4.1.2 PCI Device Discovery
- *
- * Any PCI device with Vendor ID 0x1AF4, and Device ID 0x1000 through 0x103F
- * inclusive is a virtio device. The Subsystem Device ID indicates which virtio
- * device is supported by the device.
- */
-
-#define VIRTIO_PCI_VENDOR_ID 0x1AF4
-#define VIRTIO_PCI_DEVICE_ID 0x1000
-#define VIRTIO_PCI_DEVICE_ID2 0x103F
-
-
-
-/**
- * \brief initializes a new virtio device structure
- */
-errval_t virtio_pci_device_init(struct virtio_device **vdev,
-                                 struct capref mmio);
-
-/**
- * \brief de-initialization of the device structure and freeing of resources
- */
-errval_t virtio_pci_device_free(struct virtio_device **vdev);
-
-/**
- * \brief initializes a new virtio driver structure
- */
-errval_t virtio_pci_driver_init(struct virtio_driver **vdrv,
-                                 struct capref mmio);
-
-/**
- * \brief de-initialization of the driver structure and freeing of resources
- */
-errval_t virtio_pci_driver_free(struct virtio_driver **vdrv);
-
-
-#endif // VIRTIO_VIRTIO_PCI_H
index 57b7a67..d9ec6ea 100644 (file)
 
 #include <barrelfish/barrelfish.h>
 
+/*
+ * This file contains the Virtio VRing description as defined in the VirtIO
+ * specification.
+ *
+ * Extracted from the Virtio Specification 1.0
+ * http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf
+ */
+
 /**
  * 2.4.5 The Virtqueue Descriptor Table
  *
+ * The descriptor table refers to the buffers the driver is using for the device.
+ *
  * Alignment Constraint: 16 byte boundary
  */
 struct vring_desc
 {
     lpaddr_t addr;   ///< Address (guest-physical).
-    uint32_t length; ///< Length
-    uint16_t flags;  ///< The flags, see VIRTQ_DESC_F_*
-    uint16_t next;   ///< Next field if flags & NEXT
+    uint32_t length; ///< Length of the data in the buffer
+    uint16_t flags;  ///< The flags, see VRING_DESC_F_*
+    uint16_t next;   ///< Next field used for chaining if flags & NEXT
 };
 
 /// This marks a buffer as continuing via the next field.
-#define VIRTQ_DESC_F_NEXT       0x01
+#define VIRTIO_RING_DESC_F_NEXT       0x01
 
 /// This marks a buffer as device write-only (otherwise device read-only).
-#define VIRTQ_DESC_F_WRITE      0x02
+#define VIRTIO_RING_DESC_F_WRITE      0x02
+
+/// This means the buffer contains a list of buffer descriptors.
+#define VIRTIO_RING_DESC_F_INDIRECT   0x04
+
 
-/// This means the buffer contains a list of buffer descriptors. */
-#define VIRTQ_DESC_F_INDIRECT   0x04
 
 /**
  * 2.4.5.3 Indirect Descriptors
  */
 struct indirect_vring_desc
 {
-    struct vring_desc desc[];  ///< The actual descriptors (16 bytes each)
+    struct vring_desc desc[0];  ///< The actual descriptors (16 bytes each)
 };
 
 /// gets the number of Virtqueue descriptors of the table
-#define VIRTQ_NUM_INDIRECT(vdesc) \
+#define VIRTIO_RING_NUM_INDIRECT(vdesc) \
     ((vdesc)->length)/16;
 
-#define VIRTIO_MAX_INDIRECT ((uint32_t) (PAGE_SIZE / 16))
+#define VIRTIO_RING_MAX_INDIRECT ((uint32_t) (BASE_PAGE_SIZE / 16))
 
 /**
  * 2.4.6 The Virtqueue Available Ring
@@ -59,14 +71,23 @@ struct indirect_vring_desc
 
 struct vring_avail
 {
-    uint16_t flags;        ///< Ring flags for disabling interrupts
+    uint16_t flags;        ///< Ring flags see VRING_AVAIL_F_*
     uint16_t idx;          ///< where the driver would put the next descriptor
-    uint16_t ring[];       ///< refers to a head of descriptor chain
-    /* Only if VIRTIO_F_EVENT_IDX uint16_t used_event;  */
+    uint16_t ring[0];       ///< refers to a head of descriptor chain
+    /* Only if VIRTIO_RING_F_EVENT_IDX uint16_t used_event;  */
 };
 
-/// disable interrupts on this queue
-#define VIRTQ_AVAIL_F_NO_INTERRUPT 1
+/// disable sending interrupts when the host consumes a buffer
+#define VIRTIO_RING_AVAIL_F_NO_INTERRUPT 1
+
+/**
+ * is an element of the used ring
+ */
+struct vring_used_elem
+{
+    uint32_t id;        ///< index of start of used descriptor chain
+    uint32_t length;    ///< total length of descriptor chain
+};
 
 /**
  * 2.4.8 The Virtqueue Used Ring
@@ -78,20 +99,16 @@ struct vring_avail
  */
 struct vring_used
 {
-    uint16_t flags;                 ///< disabling the notification
+    uint16_t flags;                 ///< see VRING_USED_F*
     uint16_t idx;                   ///< where the driver would put next desc
-    struct virtq_used_elem ring[];  ///< refers to a head of a descriptor chain
-    /* Only if VIRTIO_F_EVENT_IDX uint16_t avail_event; */
+    struct vring_used_elem ring[0]; ///< refers to a head of a descriptor chain
+    /* Only if VIRTIO_RING_F_EVENT_IDX uint16_t avail_event; */
 };
 
-struct virtq_used_elem
-{
-    uint32_t id;        ///< index of start of used descriptor chain
-    uint32_t length;    ///< total length of descriptor chain
-};
 
-/// disable the notification
-#define VIRTQ_USED_F_NO_NOTIFY 1
+
+/// disable the notification when the guest adds a buffer
+#define VIRTIO_RING_USED_F_NO_NOTIFY 1
 
 /**
  * 2.4 Virtqueues
@@ -106,35 +123,39 @@ struct vring
     struct vring_desc *desc;    ///< the actual descriptors (16 bytes each)
     struct vring_avail *avail;  ///< ring of available descriptor heads
     struct vring_used *used;    ///< ring of used descriptor heads
-    struct capref desc_cap;     ///< capability for the descriptor table
-    struct capref avail_cap;    ///< capability for the available ring
-    struct capref used_cap;     ///< capability for the used ring
-    struct capref buf_cap[];    ///< capabilities for the used buffers
 };
 
 /**
- * \brief Calculates the size of a virtqueue structure in memory aligned
+ * \brief Calculates the size of a vring structure in memory aligned
  *
  * \param num   the queue size
  * \param align the alignment constraints
  */
-static inline uintptr_t
-virtq_size(uint16_t num,
-           uintptr_t align)
+static inline size_t vring_size(uint16_t num, uintptr_t align)
 {
-    return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (2 + num) + align
-            - 1)
-            & ~(align - 1))
-           + sizeof(uint16_t) * 2 + sizeof(struct vring_used_elem) * num;
+    // calcualte the size of the descriptor table
+    size_t size = num * sizeof(struct vring_desc);
+
+    // calculate the size of the available ring:
+    // flags + idx + num * ring + used_event
+    size += sizeof(uint16_t) * (2 + num + 1);
+
+    // do the alignment
+    size = (size + align - 1) & ~(align - 1);
+
+    // calculate the size of the used ring:
+    // flags + idx + num *  used_element + avail_event
+    size += sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * num;
+
+    return size;
 }
 
 /**
  *
  */
-static inline int
-vring_need_event(uint16_t event_idx,
-                 uint16_t new_idx,
-                 uint16_t old_idx)
+static inline uint16_t vring_need_event(uint16_t event_idx,
+                                        uint16_t new_idx,
+                                        uint16_t old_idx)
 {
     return (uint16_t) (new_idx - event_idx - 1) < (uint16_t) (new_idx - old_idx);
 }
@@ -145,8 +166,7 @@ vring_need_event(uint16_t event_idx,
  * Note: This field is located at the very end of of the available ring data
  *       structure.
  */
-static inline uint16_t *
-vring_used_event(struct vring *vr)
+static inline uint16_t *vring_get_used_event(struct vring *vr)
 {
     return &vr->avail->ring[vr->num];
 }
@@ -157,40 +177,107 @@ vring_used_event(struct vring *vr)
  * Note: This field is located at the very end of of the used ring data
  *       structure.
  */
-static inline uint16_t *
-vring_avail_event(struct vring *vr)
+static inline uint16_t *vring_get_avail_event(struct vring *vr)
 {
     return (uint16_t *) &vr->used->ring[vr->num];
 }
 
+/*
+ * We layout the vring structure in memory as follows:
+ *
+ * struct vring {
+ *      // The actual descriptors (16 bytes each)
+ *      struct vring_desc desc[num];
+ *
+ *      // A ring of available descriptor heads with free-running index.
+ *      uint16_t avail_flags;
+ *      uint16_t avail_idx;
+ *      uint16_t available[num];
+ *      uint16_t used_event_idx;
+ *
+ *      // Padding to the next align boundary.
+ *      char pad[];
+ *
+ *      // A ring of used descriptor heads with free-running index.
+ *      uint16_t used_flags;
+ *      uint16_t used_idx;
+ *      struct vring_used_elem used[num];
+ *      uint16_t avail_event_idx;
+ * };
+ */
+
 
 /**
- * \brief allocates a new vring structure
+ * \brief Initializes a vring structure
+ *
+ * \param vr    vring structure to initialize
+ * \param num   the number of vring descriptors
+ * \param addr  pointer to a contiguous memory range for the rings
+ * \param align alignment constraints for the vring
  *
- * \param vr    pointer to the vring structure
- * \param num   the number of queue elements
- * \param align the alignment constraints for the vring
  */
-errval_t
-vring_alloc(struct vring *vr,
-            uint16_t num,
-            uintptr_t align);
+static inline void vring_init(struct vring *vr,
+                              uint16_t num,
+                              uintptr_t align,
+                              void *addr)
+{
+    /* num must be a power of two */
+    assert(((num != 0) && ((num & (~num + 1)) == num)));
+
+    uintptr_t p = (uintptr_t)addr;
+
+    vr->num = num;
+    vr->desc = (struct vring_desc *) p;
+
+    vr->avail = (struct vring_avail *) (p + num * sizeof(struct vring_desc));
+
+    p = (uintptr_t)&vr->avail->ring[num];
+    vr->used = (void *) ((p + align-1) & ~(align-1));
+
+}
 
 /**
- * \brief frees the resources used by the vring structure
+ * \brief Maps the given capability and initializes the vring on the memory
+ *        backed by the supplied capability
+ *
+ * \param vr    pointer to the vring structure to be initialized
+ * \param num   the number of elements in the ring
+ * \param align alignment constraints for the vring
+ * \param cap   frame capability used as backing memory for the structure
+ *
+ * \return SYS_ERR_OK on success
+ *         errno      on failure
+ */
+errval_t vring_init_from_cap(struct vring *vr,
+                             uint16_t num,
+                             uintptr_t align,
+                             struct capref cap);
+
+/**
+ * \brief allocates a new vring structure
+ *
+ * \param vr        pointer to the vring structure
+ * \param num       the number of queue elements
+ * \param align     the alignment constraints for the vring
+ * \param ret_frame returned frame capability
+ *
+ * \return SYS_ERR_OK on success
+ *         errno      on failure
  */
-errval_t
-vring_free(struct vring *vr);
+errval_t vring_alloc(struct vring *vr,
+                     uint16_t num,
+                     uintptr_t align,
+                     struct capref *ret_frame);
 
 /**
- * \brief    Initializes a vring structure with the given caps
+ * \brief frees the resources used by the vring structure
  *
- * \param vr The vring to initialize
+ * \param vr the vring to be freed
  *
- * The capabilities must already been set in the vring structure. The caps
- * will be mapped into the vspace and the addresses set accordingly
+ * \return SYS_ERR_OK on success
+ *         errno      on failure
  */
-errval_t
-vring_init(struct vring *vr);
+errval_t vring_free(struct vring *vr);
+
 
 #endif // VIRTIO_VIRTIO_RING_H
diff --git a/include/virtio/virtqueue.h b/include/virtio/virtqueue.h
new file mode 100644 (file)
index 0000000..e12c554
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef VIRTIO_VIRTQUEUE_H
+#define VIRTIO_VIRTQUEUE_H
+
+#include <barrelfish/barrelfish.h>
+
+/*
+ * Extracted from the Virtio Specification 1.0
+ * http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf
+ *
+ * VIRQUEUES:
+ *
+ * Size is determined by a 16bit integer.
+ * The queue consists of a descriptor table, available ring, used ring
+ * Each of the three parts are physically-contiguous in guest memory.
+ *
+ */
+
+// forward definition
+struct virtqueue;
+
+/// interrupt handler for virtqueue interrupts
+typedef void (*virtq_intr_hander_t)(struct virtqueue *, void *);
+
+/// the maximum length of the name field
+#define VIRTQUEUE_NAME_SIZE 32
+
+/// the maximum number of elements in a vring
+#define VIRTQUEUE_SIZE_MAX (1<<15)
+
+/// this value marks the end of a descriptor chain
+#define VIRTQUEUE_CHAIN_END VIRTQUEUE_SIZE_MAX
+
+/// Feature flag indicating that the ring supports indirect descriptors
+#define VIRTIO_RING_F_INDIRECT_DESC (1 << 28)
+
+/// Feature flag indicating that the ring supports interrupt suppression
+#define VIRTIO_RING_F_EVENT_IDX     (1 << 29)
+
+
+/**
+ * this structure holds necessary data to allocate a new virtqueue
+ */
+struct virtqueue_setup {
+    char name[VIRTQUEUE_NAME_SIZE];     ///< the name of the queue
+    struct virtio_device *device;       ///< device this queue belongs to
+    uint16_t queue_id;                  ///< queue id of this queue
+    uint16_t vring_ndesc;               ///< size of the vring
+    lvaddr_t vring_align;               ///< alignment of the vring
+    virtq_intr_hander_t intr_handler;   ///< interrupt handler function
+    void *intr_arg;                     ///< argument for the interrupt handler
+    uint16_t max_indirect;              ///< maximum indirect descriptors
+};
+
+/**
+ *
+ */
+enum virtqueue_intr_postpone {
+   VIRTQUEUE_INTR_POSTPONE_SHORT,
+   VIRTQUEUE_INTR_POSTPONE_LONG,
+   VIRTQUEUE_INTR_POSTPONE_EMPTIED,
+};
+
+
+/**
+ * \brief allocates and initiates a new virtqueue structure
+ *
+ * \param setup  pointer to the setup information
+ * \param vq     pointer where to store the new virtqueue pointer
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_virtqueue_alloc(struct virtqueue_setup *setup,
+                                struct virtqueue **vq);
+
+/**
+ * \brief allocates and initiates a new virtqueue structure
+ *
+ * \param setup     pointer to the setup information
+ * \param vring_cap capability to be used for the vring
+ * \param vq        pointer where to store the new virtqueue pointer
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_virtqueue_alloc_with_caps(struct virtqueue_setup *setup,
+                                          struct capref vring_cap,
+                                          struct virtqueue **vq);
+
+/**
+ * \brief frees the resources of previously allocated virtqueues
+ *
+ * \param vq pointer to the virtqueue memory to be freed
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_virtqueue_free(struct virtqueue *vq);
+
+/*
+void    *virtqueue_drain(struct virtqueue *vq, int *last);
+int  virtqueue_reinit(struct virtqueue *vq, uint16_t size);
+*/
+
+
+/*
+ * ===========================================================================
+ * Getter functions for certain values of the virtqueue structure
+ */
+
+/**
+ * \brief Returns the physical address of the vring.
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns the physical address of the vring
+ */
+lpaddr_t virtio_virtqueue_get_vring_paddr(struct virtqueue *vq);
+
+
+/**
+ * \brief Returns the frame capability of the vring
+ *
+ * \param vq        pointer to the virtqueue structure
+ * \param ret_cap   memory location where to store the capref
+ */
+void virtio_virtqueue_get_vring_cap(struct virtqueue *vq,
+                                    struct capref *ret_cap);
+
+
+/**
+ * \brief Returns the number of elements (number of descriptors)in the vring of
+ *        this virtqueue
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns number of elements in the vring
+ */
+uint16_t virtio_virtqueue_get_num_desc(struct virtqueue *vq);
+
+/**
+ * \brief Checks if the virtqueue is empty
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns 0 the queue is not empty
+ *          1 the queue is empty
+ */
+bool virtio_virtqueue_is_empty(struct virtqueue *vq);
+
+/**
+ * \brief Checks if the virtqueue is full
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns 0 the queue is not full
+ *          1 the queue is full
+ */
+bool virtio_virtqueue_is_full(struct virtqueue *vq);
+
+/**
+ * \brief Calculates the number of used descriptors in this queue
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns number of used descriptors
+ */
+uint16_t virtio_virtqueue_get_num_used(struct virtqueue *vq);
+
+
+/*
+ * ===========================================================================
+ * Interrupt handling
+ */
+
+/**
+ * \brief enables the interrupts on the next descriptor processed
+ *
+ * \param vq the virtqueue to enable the interrupts
+ *
+ * \returns 1 if the interrupts have been enabled
+ *          0 if the interrupts have not been enabled
+ */
+bool virtio_virtqueue_intr_enable(struct virtqueue *vq);
+
+/**
+ * \brief postpones the interrupt to a later point of time
+ *
+ * \param vq the virtqueue to enable the interrupts
+ * \param
+ *
+ * \returns 1 if the interrupts have been enabled
+ *          0 if the interrupts have not been enabled
+ */
+bool virtio_virtqueue_intr_postpone(struct virtqueue *vq,
+                                    enum virtqueue_intr_postpone hint);
+
+/**
+ * \brief checks if the interrupts can be disabled
+ *
+ * \param vq virtual queue to check
+ *
+ * \returns 1 if the interrupts have been disabled
+ *          0 if the interrupts are not changed
+ *
+ */
+bool virtio_virtqueue_intr_filter(struct virtqueue *vq);
+
+/**
+ * \brief calls the interrupt handler for this virtqueue
+ *
+ * \param vq virtqueue to call the intr handler for
+ */
+void virtio_virtqueue_intr_handle(struct virtqueue *vq);
+
+/**
+ * \brief disables the interrupts for the given virtqueue by giving a hint
+ *        to the host
+ *
+ * \param vq        virtqueue to disable the interrupts
+ */
+void virtio_virtqueue_intr_disable(struct virtqueue *vq);
+
+
+/**
+ * \brief notifies the host about the new queued descriptors
+ *
+ * \param vq virtqueue to notify the host
+ */
+void virtio_virtqueue_notify_host(struct virtqueue *vq);
+
+
+/**
+ * \brief masks the ring features out of a features bit mask
+ *
+ * \param features  the features to mask
+ *
+ * \returns bitmask of masked features
+ */
+static inline uint64_t virtio_virtqueue_mask_features(uint64_t features)
+{
+    uint64_t mask;
+
+    mask = (1 << VIRTIO_TRANSPORT_F_START) - 1;
+    mask |= VIRTIO_RING_F_INDIRECT_DESC;
+    mask |= VIRTIO_RING_F_EVENT_IDX;
+
+    return (features & mask);
+}
+
+/*
+ * ===========================================================================
+ * Virtqueue Queue Management
+ */
+
+errval_t virtio_virtqueue_desc_enqueue(struct virtqueue *vq,
+                                       struct virtio_buffer *buf,
+                                       void *vaddr,
+                                       uint16_t writeable,
+                                       uint16_t readable);
+
+#if 0
+int  virtqueue_enqueue(struct virtqueue *vq, void *cookie,
+         struct sglist *sg, int readable, int writable);
+void    *virtqueue_dequeue(struct virtqueue *vq, uint32_t *len);
+void    *virtqueue_poll(struct virtqueue *vq, uint32_t *len);
+
+
+
+uint64_t virtqueue_filter_features(uint64_t features);
+
+void     virtqueue_dump(struct virtqueue *vq);
+#endif
+
+
+#endif // VIRTIO_VIRTQUEUE_H
index 61038da..009059e 100644 (file)
 --------------------------------------------------------------------------
 
 [ build library { target = "virtio",
-                      cFiles = [ "virtio_ring.c" ],
-                      mackerelDevices = [ "virtio/virtio_mmio", "virtio/virtio_blk" ]
+                      cFiles = [ "virtio_ring.c", 
+                                        "virtqueue.c", 
+                                        "virtio_device.c",
+                                        "backends/virtio_device_mmio.c",
+                                        "backends/virtio_device_pci.c" ],
+                      mackerelDevices = [ "virtio/virtio_mmio" ]
                 }
 ]
diff --git a/lib/virtio/backends/virtio_device_mmio.c b/lib/virtio/backends/virtio_device_mmio.c
new file mode 100644 (file)
index 0000000..e5e49d0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+
+#include <virtio/virtio.h>
+#include <virtio/virtio_device.h>
+
+#include "backends/virtio_mmio.h"
+
+/**
+ * \brief initializes and allocates a VirtIO device structure for the MMIO backend
+ */
+errval_t virtio_device_mmio_init(struct virtio_device **dev,
+                                 struct virtio_device_init *info)
+{
+    return SYS_ERR_OK;
+}
+
+
+
diff --git a/lib/virtio/backends/virtio_device_pci.c b/lib/virtio/backends/virtio_device_pci.c
new file mode 100644 (file)
index 0000000..de6e11d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+
+#include <virtio/virtio.h>
+#include <virtio/virtio_device.h>
+
+#include "backends/virtio_pci.h"
+
+
+errval_t virtio_device_pci_alloc(struct virtio_device **dev)
+{
+    return SYS_ERR_OK;
+}
+
+errval_t virtio_device_pci_free(struct virtio_device **dev)
+{
+    return SYS_ERR_OK;
+}
+
+
+
diff --git a/lib/virtio/backends/virtio_mmio.h b/lib/virtio/backends/virtio_mmio.h
new file mode 100644 (file)
index 0000000..e25a9eb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef VIRTIO_VIRTIO_MMIO_H
+#define VIRTIO_VIRTIO_MMIO_H
+
+#include <barrelfish/barrelfish.h>
+
+#include <virtio/virtio.h>
+#include <virtio/virtio_device.h>
+
+struct virtio_device_mmio
+{
+    struct virtio_device dev;
+
+};
+
+/**
+ * \brief initializes and allocates a VirtIO device structure for the MMIO backend
+ *
+ * \param dev   returns a pointer to the newly allocated device structure
+ * \param info  initialization parameters
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_device_mmio_init(struct virtio_device **dev,
+                                 struct virtio_device_init *info);
+
+#endif // VIRTIO_VIRTIO_MMIO_H
similarity index 50%
copy from usr/drivers/virtio/net/main.c
copy to lib/virtio/backends/virtio_pci.h
index 11da963..e9e29be 100644 (file)
@@ -1,8 +1,3 @@
-/**
- * \file
- * \brief Driver for booting the Xeon Phi Coprocessor card on a Barrelfish Host
- */
-
 /*
  * Copyright (c) 2014 ETH Zurich.
  * All rights reserved.
@@ -12,4 +7,18 @@
  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
  */
 
+#ifndef VIRTIO_VIRTIO_PCI_H
+#define VIRTIO_VIRTIO_PCI_H
+
+#include <barrelfish/barrelfish.h>
+
+
+
+#define VIRTIO_PCI_VRING_ALIGNMENT 4096
+
+errval_t virtio_device_pci_alloc(struct virtio_device **dev);
+
+errval_t virtio_device_pci_free(struct virtio_device **dev);
+
 
+#endif // VIRTIO_VIRTIO_PCI_H
diff --git a/lib/virtio/debug.h b/lib/virtio/debug.h
new file mode 100644 (file)
index 0000000..455ead2
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef VIRTIO_DEBUG_H_
+#define VIRTIO_DEBUG_H_
+
+#define VIRTIO_DEBUG_ENABLED 1
+#define VIRTIO_DEBUG_VQ_ENABLED 1
+
+#if VIRTIO_DEBUG_ENABLED
+#define VIRTIO_DEBUG_PRINT(msg...) debug_printf(msg)
+#else
+#define VIRTIO_DEBUG_PRINT(msg...)
+#endif
+
+#ifdef VIRTIO_DEBUG_VQ_ENABLED
+#define VIRTIO_DEBUG_VQ(msg...) VIRTIO_DEBUG_PRINT("[VIRTQUEUE] " msg)
+#else
+#define VIRTIO_DEBUG_VQ(msg...)
+#endif
+
+
+#endif /* VIRTIO_DEBUG_H_ */
diff --git a/lib/virtio/virtio_buffer.c b/lib/virtio/virtio_buffer.c
new file mode 100644 (file)
index 0000000..6a835de
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+
+#include <virtio/virtio.h>
+
+#if 0
+
+void stack_alloc_init(struct stack_allocator *alloc, size_t size)
+{
+    alloc->size = size;
+    alloc->top = 0;
+    alloc->stack = calloc(size, sizeof(void *));
+}
+
+bool stack_alloc_free(struct stack_allocator *alloc, void *el)
+{
+    if (alloc->top >= alloc->size) {
+        return false;
+    }
+
+    alloc->stack[alloc->top++] = el;
+    return true;
+}
+
+void *stack_alloc_alloc(struct stack_allocator *alloc)
+{
+    if (alloc->top == 0) {
+        return NULL;
+    }
+    return alloc->stack[--alloc->top];
+}
+
+
+#endif
+
diff --git a/lib/virtio/virtio_buffer.h b/lib/virtio/virtio_buffer.h
new file mode 100644 (file)
index 0000000..e576d7c
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef VIRTIO_VIRTIO_BUFFER_H
+#define VIRTIO_VIRTIO_BUFFER_H
+
+/**
+ * library internal representation of a buffer allocator
+ */
+struct virtio_buffer_allocator
+{
+    struct virtio_buffer *buffers;  ///< array of virtio_buffers
+    uint16_t size;                  ///< number of buffers in this allocator
+    uint16_t top;                   ///< pointer to the top slot
+    struct capref cap;              ///< frame capability backing this allocator
+    struct virtqueue *queue;        ///< the virtqueue this allocator belongs to
+};
+
+/**
+ * \brief   initializes the buffer allocator and allocates memory for the
+ *          buffers
+ *
+ * \param   alloc   the allocator struct to initialize
+ * \param   nbufs   number of buffers to allocate
+ * \param   bufsz   size of each buffer to allocate
+ *
+ * \return  SYS_ERR_OK on success
+ */
+errval_t virtio_buffer_alloc_init(struct virtio_buffer_allocator *alloc,
+                                  size_t nbufs,
+                                  size_t bufsz);
+
+/**
+ * \brief   destroys a buffer allocator by freeing up all the resources used
+ *          by the buffers
+ *
+ * \param   alloc   the allocator to destroy
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_buffer_alloc_destroy(struct virtio_buffer_allocator *alloc);
+
+
+struct virtio_buffer *virtio_buffer_alloc(struct virtio_buffer_allocator *alloc);
+
+/**
+ * \brief   frees up a unused buffer by returning it to the allocator
+ *
+ * \param   buf     the buffer to be freed
+ */
+errval_t virtio_buffer_free(struct virtio_buffer_allocator *alloc,
+                            struct virtio_buffer *buf);
+
+/**
+ * \brief   returns the backing frame capability of a buffer allocator
+ */
+errval_t virtio_buffer_alloc_get_cap(struct virtio_buffer_allocator *alloc,
+                                     struct capref *ret_cap);
+
+
+#endif // VIRTIO_VIRTIO_BUFFER_H
similarity index 64%
copy from usr/drivers/virtio/net/main.c
copy to lib/virtio/virtio_device.c
index 11da963..c49f441 100644 (file)
@@ -1,8 +1,3 @@
-/**
- * \file
- * \brief Driver for booting the Xeon Phi Coprocessor card on a Barrelfish Host
- */
-
 /*
  * Copyright (c) 2014 ETH Zurich.
  * All rights reserved.
@@ -12,4 +7,13 @@
  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
  */
 
+#include <barrelfish/barrelfish.h>
+
+#include <virtio/virtio.h>
+#include <virtio/virtio_device.h>
+
+#include "backends/virtio_mmio.h"
+#include "backends/virtio_pci.h"
+
+
 
index bd7f604..03a20d2 100644 (file)
 #include <virtio/virtio_ring.h>
 
 
-
+/*
+ * We layout the vring structure in memory as follows:
+ *
+ * struct vring {
+ *      // The actual descriptors (16 bytes each)
+ *      struct vring_desc desc[num];
+ *
+ *      // A ring of available descriptor heads with free-running index.
+ *      uint16_t avail_flags;
+ *      uint16_t avail_idx;
+ *      uint16_t available[num];
+ *      uint16_t used_event_idx;
+ *
+ *      // Padding to the next align boundary.
+ *      char pad[];
+ *
+ *      // A ring of used descriptor heads with free-running index.
+ *      uint16_t used_flags;
+ *      uint16_t used_idx;
+ *      struct vring_used_elem used[num];
+ *      uint16_t avail_event_idx;
+ * };
+ */
 
 /**
- * \brief allocates a new vring structure
+ * \brief Maps the given capability and initializes the vring on the memory
+ *        backed by the supplied capability
+ *
+ * \param vr    pointer to the vring structure to be initialized
+ * \param num   the number of elements in the ring
+ * \param align alignment constraints for the vring
+ * \param cap   frame capability used as backing memory for the structure
  *
- * \param vr    pointer to the vring structure
- * \param num   the number of queue elements
- * \param align the alignment constraints for the vring
+ * \return SYS_ERR_OK on success
+ *         errno      on failure
  */
-errval_t
-vring_alloc(struct vring *vr,
-            uint16_t num,
-            uintptr_t align)
+errval_t vring_init_from_cap(struct vring *vr,
+                             uint16_t num,
+                             uintptr_t align,
+                             struct capref cap)
 {
+    errval_t err;
+
+    /* num must be a power of two */
+    assert(((num != 0) && ((num & (~num + 1)) == num)));
+
+    size_t size = vring_size(num, align);
+
+    struct frame_identity id;
+    err = invoke_frame_identify(cap, &id);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_FRAME_IDENTIFY);
+    }
 
+    /* check if we have enough space in the given cap */
+    if ((1UL << id.bits) < size) {
+        return SYS_ERR_INVALID_SIZE_BITS;
+    }
 
+    void *addr;
+    err = vspace_map_one_frame(&addr, (1UL << id.bits), cap, NULL, NULL);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_VSPACE_MAP);
+    }
 
+    vring_init(vr, num, align, addr);
+
+    return SYS_ERR_OK;
 }
 
 /**
- * \brief frees the resources used by the vring structure
+ * \brief allocates a new vring structure
+ *
+ * \param vr        pointer to the vring structure
+ * \param num       the number of queue elements
+ * \param align     the alignment constraints for the vring
+ * \param ret_frame returned frame capability
+ *
+ * \return SYS_ERR_OK on success
+ *         errno      on failure
  */
-errval_t
-vring_free(struct vring *vr)
+errval_t vring_alloc(struct vring *vr,
+                     uint16_t num,
+                     uintptr_t align,
+                     struct capref *ret_frame)
 {
+    errval_t err;
+
+    /* num must be a power of two */
+    assert(((num != 0) && ((num & (~num + 1)) == num)));
 
+    size_t size = vring_size(num, align);
 
+    struct capref frame;
+    err = frame_alloc(&frame, size, &size);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    err = vring_init_from_cap(vr, num, align, frame);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    if (ret_frame) {
+        *ret_frame = frame;
+    }
+
+    return SYS_ERR_OK;
 }
 
 /**
- * \brief    Initializes a vring structure with the given caps
+ * \brief frees the resources used by the vring structure
  *
- * \param vr The vring to initialize
+ * \param vr the vring to be freed
  *
- * The capabilities must already been set in the vring structure. The caps
- * will be mapped into the vspace and the addresses set accordingly
+ * \return SYS_ERR_OK on success
+ *         errno      on failure
  */
-errval_t
-vring_init(struct vring *vr)
+errval_t vring_free(struct vring *vr)
 {
+    errval_t err;
 
+    err = vspace_unmap(vr->desc);
+    if (err_is_fail(err)) {
+        return err;
+    }
 
+    assert(!"NYI: returning the cap to the origin");
+    return SYS_ERR_OK;
 }
+
diff --git a/lib/virtio/virtqueue.c b/lib/virtio/virtqueue.c
new file mode 100644 (file)
index 0000000..0e4d961
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#include <string.h>
+
+#include <barrelfish/barrelfish.h>
+
+#include <virtio/virtio.h>
+#include <virtio/virtio_ring.h>
+#include <virtio/virtqueue.h>
+
+#include "debug.h"
+
+
+#define IS_POW2(num) (((num) != 0) && (((num) & (~(num) + 1)) == (num)))
+
+
+#define VIRTQUEUE_FLAG_INDIRECT  0x0001
+#define VIRTQUEUE_FLAG_EVENT_IDX 0x0002
+
+/**
+ * this data structure stores additional information to the descriptors
+ */
+struct vring_desc_info
+{
+    void *buf;          ///< virtual address of this descriptor
+    struct capref cap;  ///< capability of this descriptor
+    size_t size;        ///< the size of the capability in bytes
+    lpaddr_t paddr;     ///< physical address of this descriptor
+    lpaddr_t offset;    ///< offset into the capability for mapping
+};
+
+/**
+ * this data structure represents a VirtIO queue. It contains additional
+ * information not stored with the vring structure
+ */
+struct virtqueue
+{
+    /* device information */
+    struct virtio_device *device;       ///< pointer to to the virtio device
+    uint16_t              queue_index;  ///< index of this queue in the device
+    char name[VIRTQUEUE_NAME_SIZE];     ///< name of the queue for debugging
+
+    /* vring information */
+    struct vring vring;                 ///< vring data structure
+    uint16_t vring_ndesc;               ///< number of descriptors of this vring
+    uint32_t flags;                     ///< flags
+    uint16_t free_head;                 ///< head of the free descriptor chain
+    uint16_t free_count;                ///< number of available free descriptors
+    uint16_t used_tail;                 ///< last consumed descriptor used table
+    uint16_t used_count;                ///< number of queued used descriptors
+
+    /* vring memory information */
+    struct capref vring_cap;            ///< capability of the vring data structure
+    lvaddr_t vring_vaddr;               ///< virtual address of the vring in memory
+    lpaddr_t vring_paddr;               ///< physical address of the vring
+    size_t vring_size;                  ///< the size of the vring in memory
+    lvaddr_t vring_align;               ///< the alignment of the vring
+
+    /* interrupt handling */
+    virtq_intr_hander_t intr_handler;   ///< interrupt handler
+    void               *intr_arg;       ///< user argument for the handler
+
+    struct vring_desc_info vring_di[0]; ///< array of additional desc information
+#if 0
+    /* indirect descriptors */
+    uint16_t max_indirect;
+    size_t   indirect_size;
+    struct vq_desc_extra {
+            void          *cookie;  << virtual address?
+            struct vring_desc *indirect;
+            vm_paddr_t     indirect_paddr;
+            uint16_t       ndescs;
+        } vq_descx[0];
+#endif
+};
+
+/**
+ * \brief sets the interrupt threshold to num_desc processed descriptors
+ *
+ * \param vq        virtqueue to enable the interrupts
+ * \param num_desc  the interrupt threshold
+ *
+ * \returns 1 if the interrupts have been enabled
+ *          0 if the interrupts have not been enabled
+ */
+static bool virtqueue_interrupt_enable(struct virtqueue *vq,
+                                       uint16_t num_desc)
+{
+    if (vq->flags & VIRTQUEUE_FLAG_EVENT_IDX) {
+        uint16_t *used_event = vring_get_used_event(&vq->vring);
+        *used_event = vq->used_tail + num_desc;
+    } else {
+        vq->vring.avail->flags &= ~VIRTIO_RING_AVAIL_F_NO_INTERRUPT;
+    }
+
+    assert(!"NYI: memory barrier mb()");
+
+    if (virtio_virtqueue_get_num_used(vq) > num_desc) {
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/**
+ * \brief initializes the vring structure of the virtqueue
+ *
+ * \param vq virtqueue of the vring to initialize
+ */
+static void virtqueue_init_vring(struct virtqueue *vq)
+{
+    struct vring *vr = &vq->vring;
+
+    assert(vq);
+    assert(vq->vring_ndesc);
+    assert(vq->vring_vaddr);
+
+    /*
+     * initialize the vring structure in memory
+     */
+    vring_init(vr, vq->vring_ndesc, vq->vring_align, (void *)vq->vring_vaddr);
+
+    /*
+     * initialize the descriptor chains
+     */
+    uint32_t i;
+    for (i = 0; i < vq->vring_ndesc; ++i) {
+        vr->desc[i].next = i+1;
+    }
+    vr->desc[i].next = VIRTQUEUE_CHAIN_END;
+
+}
+
+
+/*
+ * ============================================================================
+ * Public Interface
+ * ============================================================================
+ */
+
+
+/*
+ * ----------------------------------------------------------------------------
+ *  Virtqueue Allocation / Deallocation
+ */
+
+/**
+ * \brief allocates and initiates a new virtqueue structure
+ *
+ * \param setup  pointer to the setup information
+ * \param vq     pointer where to store the new virtqueue pointer
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_virtqueue_alloc(struct virtqueue_setup *setup,
+                                struct virtqueue **vq)
+{
+    errval_t err;
+
+    assert(vq);
+
+    if (setup->vring_ndesc == 0 || !IS_POW2(setup->vring_ndesc)) {
+        VIRTIO_DEBUG_VQ("ERROR: invalid size: %u\n", setup->vring_ndesc);
+        return VIRTIO_ERR_SIZE_INVALID;
+    }
+
+    size_t size = vring_size(setup->vring_ndesc, setup->vring_align);
+    size = ROUND_UP(size, BASE_PAGE_SIZE);
+
+    struct capref vring_cap;
+    size_t framesize;
+    err = frame_alloc(&vring_cap, size, &framesize);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    VIRTIO_DEBUG_VQ("Allocated memory for vring: [%lx & %lx]",
+                    (uint64_t)size, (uint64_t)framesize);
+
+    err = virtio_virtqueue_alloc_with_caps(setup, vring_cap, vq);
+    if (err_is_fail(err)) {
+        cap_destroy(vring_cap);
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief allocates and initiates a new virtqueue structure
+ *
+ * \param setup     pointer to the setup information
+ * \param vring_cap capability to be used for the vring
+ * \param vq        pointer where to store the new virtqueue pointer
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_virtqueue_alloc_with_caps(struct virtqueue_setup *setup,
+                                          struct capref vring_cap,
+                                          struct virtqueue **ret_vq)
+{
+    errval_t err;
+
+    assert(ret_vq);
+
+    if (setup->vring_ndesc == 0 || !IS_POW2(setup->vring_ndesc)) {
+        VIRTIO_DEBUG_VQ("ERROR: invalid size: %u\n", setup->vring_ndesc);
+        return VIRTIO_ERR_SIZE_INVALID;
+    }
+
+    if (setup->max_indirect > VIRTIO_RING_MAX_INDIRECT) {
+        VIRTIO_DEBUG_VQ("ERROR: too many indirect descriptors requested: [%u / %u]\n", setup->vring_ndesc, VIRTIO_RING_MAX_INDIRECT);
+        return VIRTIO_ERR_MAX_INDIRECT;
+    }
+
+    assert(!capref_is_null(vring_cap));
+
+    struct frame_identity id;
+    err = invoke_frame_identify(vring_cap, &id);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    size_t vring_mem_size = vring_size(setup->vring_ndesc, setup->vring_align);
+    vring_mem_size = ROUND_UP(vring_mem_size, BASE_PAGE_SIZE);
+
+    if (vring_mem_size > (1UL << id.bits)) {
+        VIRTIO_DEBUG_VQ("ERROR: supplied cap was too small %lx, needed %lx\n",
+                        ((1UL << id.bits)), (uint64_t)vring_mem_size);
+        return VIRTIO_ERR_CAP_SIZE;
+    }
+
+    void *vring_addr;
+    err = vspace_map_one_frame(&vring_addr, vring_mem_size, vring_cap, NULL, NULL);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    struct virtqueue *vq = calloc(1, sizeof(struct virtqueue)
+                                  + (setup->vring_ndesc * sizeof(struct vring_desc_info)));
+    if (vq == NULL) {
+        vspace_unmap(vring_addr);
+        return LIB_ERR_MALLOC_FAIL;
+    }
+
+    vq->device = setup->device;
+    strncpy(vq->name, setup->name, sizeof(vq->name));
+    vq->queue_index = setup->queue_id;
+    vq->vring_ndesc = setup->vring_ndesc;
+    vq->vring_align = setup->vring_align;
+    vq->vring_size = vring_mem_size;
+    vq->vring_cap = vring_cap;
+    vq->vring_paddr = id.base;
+    vq->vring_vaddr = (lvaddr_t)vring_addr;
+    vq->free_count = setup->vring_ndesc;
+
+
+    vq->intr_handler = setup->intr_handler;
+    vq->intr_arg = setup->intr_arg;
+
+    if (setup->max_indirect > 0) {
+        /*
+         * TODO: initialize indirect descriptors
+         */
+    }
+
+#if 0
+    if (VIRTIO_BUS_WITH_FEATURE(dev, VIRTIO_RING_F_EVENT_IDX) != 0)
+        vq->vq_flags |= VIRTQUEUE_FLAG_EVENT_IDX;
+#endif
+
+    virtqueue_init_vring(vq);
+    virtio_virtqueue_intr_disable(vq);
+
+    if (ret_vq) {
+        *ret_vq = vq;
+    }
+
+    return SYS_ERR_OK;
+}
+
+
+/**
+ * \brief frees the resources of previously allocated virtqueues
+ *
+ * \param vq pointer to the virtqueue memory to be freed
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_virtqueue_free(struct virtqueue *vq)
+{
+    assert(!"NYI: virtio_virtqueue_free");
+
+    return SYS_ERR_OK;
+}
+
+
+/*
+ * ----------------------------------------------------------------------------
+ *  Virtqueue Getter Functions
+ */
+
+/**
+ * \brief Returns the physical address of the vring.
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns the physical address of the vring
+ */
+lpaddr_t virtio_virtqueue_get_vring_paddr(struct virtqueue *vq)
+{
+    return vq->vring_paddr;
+}
+
+/**
+ * \brief Returns the frame capability of the vring
+ *
+ * \param vq        pointer to the virtqueue structure
+ * \param ret_cap   memory location where to store the capref
+ */
+void virtio_virtqueue_get_vring_cap(struct virtqueue *vq,
+                                    struct capref *ret_cap)
+{
+    if (ret_cap) {
+        *ret_cap = vq->vring_cap;
+    }
+}
+
+/**
+ * \brief Returns the number of elements (number of descriptors)in the vring of
+ *        this virtqueue
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns number of elements in the vring
+ */
+uint16_t virtio_virtqueue_get_num_desc(struct virtqueue *vq)
+{
+    return vq->vring_ndesc;
+}
+
+/**
+ * \brief Checks if the virtqueue is empty
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns 0 the queue is not empty
+ *          1 the queue is empty
+ */
+bool virtio_virtqueue_is_empty(struct virtqueue *vq)
+{
+    return (vq->vring_ndesc == vq->free_count);
+}
+
+/**
+ * \brief Checks if the virtqueue is full
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns 0 the queue is not full
+ *          1 the queue is full
+ */
+bool virtio_virtqueue_is_full(struct virtqueue *vq)
+{
+    return (vq->free_count == 0);
+}
+
+/**
+ * \brief Calculates the number of used descriptors in this queue
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns number of used descriptors
+ */
+uint16_t virtio_virtqueue_get_num_used(struct virtqueue *vq)
+{
+    uint16_t num_used;
+
+    num_used = vq->vring.used->idx - vq->used_tail;
+
+    /* sanity check */
+    assert(num_used <= vq->vring_ndesc);
+
+    return num_used;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ *  Interrupt handling
+ */
+
+/**
+ * \brief checks if the interrupts can be disabled
+ *
+ * \param vq virtual queue to check
+ *
+ * \returns 1 if the interrupts have been disabled
+ *          0 if the interrupts are not changed
+ *
+ */
+bool virtio_virtqueue_intr_filter(struct virtqueue *vq)
+{
+    if (vq->used_tail == vq->vring.used->idx) {
+        return 0;
+    }
+
+    virtio_virtqueue_intr_disable(vq);
+
+    return 1;
+}
+
+/**
+ * \brief calls the interrupt handler for this virtqueue
+ *
+ * \param vq virtqueue to call the intr handler for
+ */
+void virtio_virtqueue_intr_handle(struct virtqueue *vq)
+{
+    if (vq->intr_handler == NULL) {
+        VIRTIO_DEBUG_VQ("Notice: Interrupt handler is not set\n");
+        return;
+    }
+    vq->intr_handler(vq, vq->intr_arg);
+}
+
+
+/**
+ * \brief enables the interrupts on the next descriptor processed
+ *
+ * \param vq the virtqueue to enable the interrupts
+ *
+ * \returns 1 if the interrupts have been enabled
+ *          0 if the interrupts have not been enabled
+ */
+bool virtio_virtqueue_intr_enable(struct virtqueue *vq)
+{
+    return virtqueue_interrupt_enable(vq, 0);
+}
+
+/**
+ * \brief postpones the interrupt to a later point of time
+ *
+ * \param vq the virtqueue to enable the interrupts
+ * \param
+ *
+ * \returns 1 if the interrupts have been enabled
+ *          0 if the interrupts have not been enabled
+ */
+bool virtio_virtqueue_intr_postpone(struct virtqueue *vq,
+                                    enum virtqueue_intr_postpone hint)
+{
+    uint16_t ndesc = vq->vring.avail->idx - vq->used_tail;
+
+    switch (hint) {
+        case VIRTQUEUE_INTR_POSTPONE_SHORT:
+            ndesc = ndesc / 4;
+            break;
+        case VIRTQUEUE_INTR_POSTPONE_LONG:
+            ndesc = (ndesc * 3) / 4;
+            break;
+        case VIRTQUEUE_INTR_POSTPONE_EMPTIED:
+            break;
+    }
+
+    return virtqueue_interrupt_enable(vq, ndesc);
+}
+
+
+/**
+ * \brief disables the interrupts for the given virtqueue
+ *
+ * \param vq        virtqueue to disable the interrupts
+ */
+void virtio_virtqueue_intr_disable(struct virtqueue *vq)
+{
+    if (vq->flags & VIRTQUEUE_FLAG_EVENT_IDX) {
+        uint16_t *used_event = vring_get_used_event(&vq->vring);
+        *used_event = vq->used_tail - vq->vring_ndesc - 1;
+    } else {
+        vq->vring.avail->flags |= VIRTIO_RING_AVAIL_F_NO_INTERRUPT;
+    }
+}
+
+/**
+ * \brief notifies the host about the new queued descriptors
+ *
+ * \param vq virtqueue to notify the host
+ */
+void virtio_virtqueue_notify_host(struct virtqueue *vq)
+{
+    assert(!"NYI: host notify");
+}
+
+
+/*
+ * ----------------------------------------------------------------------------
+ *  Queue Management
+ */
+
+#if 0
+
+/**
+ *
+ */
+errval_t virtio_virtqueue_desc_alloc(struct virtqueue *vq,
+                                     size_t )
+
+errval_t virtio_virtqueue_desc_enq(struct virtqueue *vq,
+                              )
+{
+    assert(!"NYI: virtio_virtqueue_enq");
+    return SYS_ERR_OK;
+}
+
+void *virtio_virtqueue_desc_deq(struct virtqueue *vq)
+{
+    return NULL;
+}
+
+
+
+void *virtio_virtqueue_poll(struct virtqueue *vq)
+{
+    return NULL;
+};
+
+#endif
+
diff --git a/usr/drivers/virtio/block/Hakefile b/usr/drivers/virtio/block/Hakefile
new file mode 100644 (file)
index 0000000..eef089a
--- /dev/null
@@ -0,0 +1,39 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2010, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /usr/drivers/virtio_net
+-- 
+--------------------------------------------------------------------------
+
+[ build application { target = "virtio_blk",
+                      cFiles = [ "main_guest.c"
+                                ],
+                      addLibraries = libDeps ["virtio"],
+                      --flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
+                      --flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi", "xeon_phi_messaging"],
+                      --flounderBindings = ["xeon_phi", "xeon_phi_messaging"],
+                      mackerelDevices = [ "virtio/virtio_blk" ],
+                      architectures= ["x86_64", "k1om"]
+                    },
+  build application { target = "virtio_blk_host",
+                      cFiles = [ "main_host.c"
+                                ],
+                      addLibraries = libDeps ["virtio"],
+                      --flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
+                      --flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi", "xeon_phi_messaging"],
+                      --flounderBindings = ["xeon_phi", "xeon_phi_messaging"],
+                      mackerelDevices = [ "virtio/virtio_blk" ],
+                      architectures= ["x86_64"]
+                      }              
+]
+
+
+      
+                      
+                      
+                          
\ No newline at end of file
similarity index 91%
copy from usr/drivers/virtio/net/main.c
copy to usr/drivers/virtio/block/main_guest.c
index 11da963..bbc3940 100644 (file)
@@ -13,3 +13,7 @@
  */
 
 
+int main(int argc, char *argv[])
+{
+
+}
diff --git a/usr/drivers/virtio/console/Hakefile b/usr/drivers/virtio/console/Hakefile
new file mode 100644 (file)
index 0000000..6bf688c
--- /dev/null
@@ -0,0 +1,41 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2010, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /usr/drivers/virtio_net
+-- 
+--------------------------------------------------------------------------
+
+[ build application { target = "virtio_console",
+                      cFiles = [ "main_guest.c"
+                                ],
+                      addLibraries = libDeps ["virtio"],
+                      --flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
+                      --flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi", "xeon_phi_messaging"],
+                      --flounderBindings = ["xeon_phi", "xeon_phi_messaging"],
+                      -- mackerelDevices = [ "xeon_phi/xeon_phi_apic" ],
+                      architectures= ["x86_64", "k1om"]
+                      
+                    },
+  build application { target = "virtio_console_host",
+                      cFiles = [ "main_host.c"
+                                ],
+                      addLibraries = libDeps ["virtio"],
+                      --flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
+                      --flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi", "xeon_phi_messaging"],
+                      --flounderBindings = ["xeon_phi", "xeon_phi_messaging"],
+                      -- mackerelDevices = [ "xeon_phi/xeon_phi_apic" ],
+                      architectures= ["x86_64"]
+                      
+                      }                     
+]
+
+
+      
+                      
+                      
+                          
\ No newline at end of file
diff --git a/usr/drivers/virtio/net/Hakefile b/usr/drivers/virtio/net/Hakefile
new file mode 100644 (file)
index 0000000..804016f
--- /dev/null
@@ -0,0 +1,39 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2010, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /usr/drivers/virtio_net
+-- 
+--------------------------------------------------------------------------
+
+[ build application { target = "virtio_net",
+                      cFiles = [ "main_guest.c"
+                                ],
+                      addLibraries = libDeps ["virtio"],
+                      --flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
+                      --flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi", "xeon_phi_messaging"],
+                      --flounderBindings = ["xeon_phi", "xeon_phi_messaging"],=
+                      -- mackerelDevices = [ "xeon_phi/xeon_phi_apic" ],
+                      architectures= ["x86_64", "k1om"] 
+                    },
+  build application { target = "virtio_net_host",
+                      cFiles = [ "main_host.c"
+                                ],
+                      addLibraries = libDeps ["virtio"],
+                      --flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
+                      --flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi", "xeon_phi_messaging"],
+                      --flounderBindings = ["xeon_phi", "xeon_phi_messaging"],
+                      -- mackerelDevices = [ "xeon_phi/xeon_phi_apic" ],     
+                      architectures= ["x86_64"]
+                      }                
+]
+
+
+      
+                      
+                      
+                          
\ No newline at end of file