VirtIO and Xeon Phi Messaging
authorReto Achermann <acreto@student.ethz.ch>
Tue, 10 Jun 2014 15:49:35 +0000 (17:49 +0200)
committerStefan Kaestle <stefan.kaestle@inf.ethz.ch>
Wed, 20 Aug 2014 20:09:19 +0000 (22:09 +0200)
Added a new message type for the xeon phi messaging subsystem to handle
addition of new ring buffer descriptors.

Extended the implementation of VirtIO. Refactoring of the internal and
external headers to match data encapsulation.

20 files changed:
devices/Hakefile
devices/virtio/virtio_io.dev [new file with mode: 0644]
devices/virtio/virtio_mmio.dev
devices/virtio/virtio_net.dev [new file with mode: 0644]
devices/virtio/virtio_pci.dev [new file with mode: 0644]
errors/errno.fugu
include/virtio/virtio.h
include/virtio/virtio_device.h
include/virtio/virtqueue.h
include/xeon_phi/xeon_phi_messaging.h
lib/virtio/Hakefile
lib/virtio/backends/virtio_device_io.c [new file with mode: 0644]
lib/virtio/backends/virtio_device_mmio.c
lib/virtio/backends/virtio_io.h [new file with mode: 0644]
lib/virtio/backends/virtio_mmio.h
lib/virtio/debug.h
lib/virtio/virtio_device.c
lib/virtio/virtio_device.h [new file with mode: 0644]
lib/virtio/virtqueue.c
tools/weever/mbi.c

index 9fa1681..6ede515 100644 (file)
@@ -91,6 +91,8 @@
            "omap/omap44xx_uart3",
            "virtio/virtio_blk",
            "virtio/virtio_mmio",
+           "virtio/virtio_pci",
+           "virtio/virtio_io",
            "xeon_phi/xeon_phi_serial",
            "xeon_phi/xeon_phi_boot",
            "xeon_phi/xeon_phi_apic",
diff --git a/devices/virtio/virtio_io.dev b/devices/virtio/virtio_io.dev
new file mode 100644 (file)
index 0000000..f496f97
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+/*
+ * virtio_pci.dev
+ *
+ * 4.3 Virtio Over IO
+ */
+device virtio_io lsbfirst ( addr base, addr common ) "Virtio PCI Device Specification" {
+    constant vendor_id width(16) {
+        virtio = 0x1AF4;
+    };
+    
+    
+  
+ };
index 8e4cb95..320bcfd 100644 (file)
@@ -18,7 +18,7 @@
 device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification" {
 
     constants virtio_magic width(4) "Little Endian equivalent of the 'virt' string" {
-        value = 0x74726976;
+        magic_value = 0x74726976 "Little Endian equivalent of the 'virt' string";
     };
     
     register magic_value addr(base, 0x000) "Magic value for identifying the Virtio device" {
@@ -26,13 +26,14 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
     };
     
     constants virtio_version width(32) "Virtio MMIO Device Versions" {
-        invalid = 0x0 "Invalid Version.";
-        legacy  = 0x1 "The legacy interface is used.";
-        virtio1 = 0x2 "Virtio Version 1.0";
+        version_invalid = 0x0 "Invalid Version.";
+        version_legacy  = 0x1 "The legacy interface is used.";
+        version_virtio10 = 0x2 "Virtio Version 1.0";
     };
     
     register version addr(base, 0x004) "Device Version Number" {
-        version 32 "Virtio device interface version";        
+        version 8 "Virtio device interface version";
+        _       24 "Reserved";
     };
     
     constants virtio_deviceid width(32) "Virtio Device IDs" {
@@ -60,7 +61,8 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * addresses, assigning functions to them depending on user’s needs.
      */
     register deviceid addr(base, 0x008) "Virtio Subsystem Device ID" {
-        id 32 "Device ID";
+        id  8 "Device ID";
+        _  24 "Reserved";
     };
     
     register vendorid addr(base, 0x00C) "Virtio Subsystem Vendor ID" {
@@ -87,7 +89,9 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * by reading from DeviceFeatures.
      */
     register dev_features_sel addr(base, 0x014) "Device (host) features word selection." {
-        selector 32 "Virtio Feature Selector";
+        ready     1 "The host has loaded the dev_features register";
+        _        30 "Reserved";
+        selector  1 "Virtio Feature Selector";
     };
     
     /*
@@ -104,7 +108,10 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
     };
   
     register driv_features_sel addr(base, 0x024) "Activated (guest) features word selection" {
-        selector 32 "Virtio Feature Selector";
+        selector  1 "Virtio Feature Selector";
+        _        29 "Reserved";
+        ready     1 "signal the host that the values are ready";
+        ack       1 "the host has stored the values";
     };
     
     /*
@@ -114,7 +121,8 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * QueueUsedHigh apply to. The index number of the first queue is zero (0x0).
      */
     register queue_sel addr(base, 0x030) "Virtual queue index" {
-        selector 32 "Virtio Queue Selector";
+        selector 31 "Virtio Queue Selector";
+        ready     1 "the host has loaded the registers witht the values";
     };
     
     /*
@@ -123,7 +131,7 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * not available. This applies to the queue selected by writing to QueueSel.
      */
     register queue_max addr(base, 0x34) "Maximum virtual queue size" {
-        size 32 "Number ready to process";
+        size 16 "Number ready to process";
     };
     
     /*
@@ -145,7 +153,8 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      */
     register queue_ready addr(base, 0x044) "Virtual queue ready bit" {
         ready  1 "Queue ready bit";
-        _     31 "Reserved";
+        _     30 "Reserved";
+        ack    1 "the host has stored the queue data";        
     };
     
     constants queue width(1) "Queue Ready Bit Values" {
@@ -189,7 +198,7 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
     };    
     
     constants device_status width(8) "Reset value" {
-        reset = 0x0 "Reset the device";
+        device_reset = 0x0 "Reset the device";
     };
     
     /*
@@ -218,10 +227,10 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * higher 32 bits to QueueDescHigh) notifies the device about location of 
      * the Descriptor Table of the queue selected by writing to QueueSel register.
      */
-    register queue_desc_lo addr(base, 0x080) "Virtual queue’s Descriptor Table 64 bit long physical address" { 
+    register queue_desc_lo addr(base, 0x080) "Virtual queue Descriptor Table 64 bit long physical address" { 
         addr 32 "Address of Queue Descriptor Table";
     };
-    register queue_desc_hi addr(base, 0x084) "Virtual queue’s Descriptor Table 64 bit long physical address" { 
+    register queue_desc_hi addr(base, 0x084) "Virtual queue Descriptor Table 64 bit long physical address" { 
         addr 32 "Address of Queue Descriptor Table";
     };    
     
@@ -230,10 +239,10 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * QueueAvailLow, higher 32 bits to QueueAvailHigh) notifies the device 
      * about location of the Available Ring of the queue selected by writing to QueueSel.
      */
-    register queue_avail_lo addr(base, 0x090) "Virtual queue’s Available Ring 64 bit long physical address" { 
+    register queue_avail_lo addr(base, 0x090) "Virtual queue Available Ring 64 bit long physical address" { 
         addr 32 "Address of available ring";
     };
-    register queue_avail_hi addr(base, 0x094) "Virtual queue’s Available Ring 64 bit long physical address" { 
+    register queue_avail_hi addr(base, 0x094) "Virtual queue Available Ring 64 bit long physical address" { 
         addr 32 "Address of available ring";
     };
     
@@ -242,10 +251,10 @@ device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification"
      * QueueUsedLow, higher 32 bits to QueueUsedHigh) notifies the device about 
      * locationof the Used Ring of the queue selected by writing to QueueSel.
      */
-    register queue_used_lo addr(base, 0x0a0) "Virtual queue’s Used Ring 64 bit long physical address" { 
+    register queue_used_lo addr(base, 0x0a0) "Virtual queue Used Ring 64 bit long physical address" { 
         addr 32 "Address of used ring";
     };
-    register queue_used_hi addr(base, 0x0a4) "Virtual queue’s Used Ring 64 bit long physical address" { 
+    register queue_used_hi addr(base, 0x0a4) "Virtual queue Used Ring 64 bit long physical address" { 
         addr 32 "Address of used ring";
     };
     
diff --git a/devices/virtio/virtio_net.dev b/devices/virtio/virtio_net.dev
new file mode 100644 (file)
index 0000000..adf72d1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * virtio.dev
+ *
+ * The following structurs are taken from the Virtio Specification 1.0
+ *
+ */
+device virtio lsbfirst ( addr base ) "Virtio Device Specification" {
+    
+    /*
+     * 2.1 Device Status Field
+     */
+    constant device_status "Device status field values" {
+        reset = 0x00 "Reset the device status field";     
+    };
+    
+    datatype device_status lsbfirst "Device status field" {
+        acknowledge 1 "Guest OS has found the device and recognized it as a valid virtio device.";
+        driver      1 "Guest OS knows how to drive the device.";
+        driver_ok   1 "Driver is set up and ready to drive the device.";
+        features_ok 1 "Driver has acknowledged all the features it understands, and feature negotiation is complete.";
+        _           3 "Reserved";
+        failed      1 "Something went wrong in the guest, and it has given up on the device.";
+    };
+   
+ };
+          
\ No newline at end of file
diff --git a/devices/virtio/virtio_pci.dev b/devices/virtio/virtio_pci.dev
new file mode 100644 (file)
index 0000000..e872201
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+/*
+ * virtio_pci.dev
+ *
+ * 4.1 Virtio Over PCI Bus
+ */
+device virtio_pci lsbfirst ( addr base, addr common ) "Virtio PCI Device Specification" {
+    constants vendor_id width(4) "VirtIO PCI vendor" {
+        virtio_vendor = 0x1AF4;
+    };
+    /*
+     * cap_vndr 0x09;
+     */
+    register vendor addr(base, 0x0) "Identifies a vendor-specific capability." {
+        vndr     8 "Vendor ID";
+    };
+    
+    register next  addr(base, 0x1) "Next Pointer" {
+        next     8 "Link to next capability in the capability list." ;  
+    };
+    
+    register length addr(base, 0x2) "Length of this capability structure" {
+        len      8 "Length";
+    };
+    
+    constants config_type width(8) "Configuration types" {
+        common  = 1 "Common configuration";
+        notify  = 2 "Notifications";
+        isr     = 3 "ISR Status";
+        devspec  = 4 "Device specific configuration";
+        pci_cfg = 5 "PCI configuration access";
+        
+    };
+    
+    register config addr(base, 0x3) "identifies the structure" {
+        cfg_type 8 "configuration type";
+    };
+    
+    register bar addr(base, 0x4) "Base Address register (BAR) belonging to the function located beginning" {
+        bar 8 "Base Address register (BAR)";
+    };
+    
+    register offset addr(base, 0x8) "beginning of the structure relative to the base address" {
+        off 32 "Offset";
+    };
+    
+    register length2 addr(base, 0xC) "indicates the length of the structure." {
+        len 32 "Length";
+    };
+    
+    
+    register device_feature_select addr(common, 0x0) "" {
+       reg 32 "todo";
+    };
+    
+    register device_feature addr(common, 0x4) "" {
+    reg 32 "todo";
+    };
+    
+    register driver_feature_select addr(common, 0x8) "" {
+    reg 32 "todo";
+    };
+    
+    register driver addr(common, 0xC) "" {
+    reg 32 "todo";
+    };
+    
+    register msix_config addr(common, 0x10) {
+    reg 16 "todo";
+    };
+    
+    register num_queues addr(common, 0x12) {
+    reg 16 "todo";
+    };
+          
+    register device_status addr(common, 0x14) {
+    reg 8 "todo";
+    };
+    
+    register config_generation addr(common, 0x15) {
+    reg 8 "todo";
+    };
+
+          register queue_select addr(common, 0x16) {
+             val 16 "";
+          };
+          
+          register queue_size addr(common, 0x18){
+             val 16 "";
+          };
+          
+          register queue_msix_vector addr(common, 0x1A){
+             val 16 "";
+          };
+          
+          register queue_enable addr(common, 0x1C){
+             val 16 "";
+          };
+          
+          register queue_notify_off addr(common, 0x1E){
+             val 16 "";
+          };
+          
+          register queue_desc addr(common, 0x20){
+             val 64 "";
+          };
+          
+          register queue_avail addr(common, 0x28){
+             val 64 "";
+          };
+          
+          register queue_used addr(common, 0x30){
+             val 64 "";
+          };
+    
+  
+ };
index b44cd1d..9849bc2 100755 (executable)
@@ -1001,9 +1001,16 @@ 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",
+    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",
+    failure BACKEND              "Invalid backend",
+    failure DEVICE_REGISTER      "The device registers have not been mapped",
+    failure NOT_VIRTIO_DEVICE    "The device is not a VirtIO device",
+    failure VERSION_MISMATCH     "The VirtIO versions do mismatch",
+    failure DEVICE_STATUS        "VirtIO device has the wrong status",
+    failure QUEUE_ACTIVE         "The selected qeueue is already activated",
+    failure QUEUE_INVALID        "The selected queue does not exist",
 };
index 2f883c0..138b09c 100644 (file)
 #include <barrelfish/barrelfish.h>
 
 
+/// defines how we map the memory frames
+#define VIRTIO_VREGION_FLAGS_DEVICE VREGION_FLAGS_READ_WRITE
+#define VIRTIO_VREGION_FLAGS_RING VREGION_FLAGS_READ_WRITE
+
+
 /*
  * Generic Feature Bits
  */
index 7b888c2..7f4afb7 100644 (file)
@@ -96,6 +96,7 @@ enum virtio_device_backend {
     VIRTIO_DEVICE_BACKEND_INVALID,
     VIRTIO_DEVICE_BACKEND_PCI,
     VIRTIO_DEVICE_BACKEND_MMIO,
+    VIRTIO_DEVICE_BACKEND_IO,
 };
 
 /*
@@ -110,55 +111,70 @@ enum virtio_device_backend {
 #define VIRTIO_PCI_DEVICE_ID 0x1000
 #define VIRTIO_PCI_DEVICE_ID2 0x103F
 
+#define VIRTIO_DEVICE_NAME_MAX 32
 
 /**
  * contains necessary values for the device initialization process
  */
-struct virtio_device_init
+struct virtio_device_setup
 {
     uint8_t type;                           ///< expected type of the device
+    char name[VIRTIO_DEVICE_NAME_MAX];
     enum virtio_device_backend  backend;    ///< which backend to use
+    void *dev_reg;
+    size_t dev_reg_size;
+    errval_t (*feature_negotiate)(struct virtio_device *dev);
+    errval_t (*device_setup)(struct virtio_device *dev);
 };
 
-/**
- * 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
+ * \brief initializes a new VirtIO device based on the values passed with the
+ *        device init struct. The device registers have already to be mapped. *
  *
  * \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);
+                            struct virtio_device_setup *init);
 
 /**
- * \brief initializes the common part of the virtio device structure based on
- *        a supplied cap which gets mapped
+ * \brief initializes a new VirtIO device based on the values passed with the
+ *        device init struct. The supplied cap contains the memory range of the
+ *        device registers.
  *
  * \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 virtio_device_setup *init,
                                      struct capref dev_cap);
 
+/**
+ * \brief resets the virtio device
+ *
+ * \param dev   the device to reset
+ *
+ * \returns SYS_ERR_OK on success
+ */
+errval_t virtio_device_reset(struct virtio_device *dev);
+
+/**
+ * \brief
+ *
+ * \param
+ */
+errval_t virtio_device_set_status(struct virtio_device *dev,
+                                  uint8_t status);
+
+errval_t virtio_device_get_status(struct virtio_device *dev,
+                                  uint8_t *ret_status);
+
+errval_t virtio_device_feature_negotiate(struct virtio_device *dev);
+
+errval_t virtio_device_specific_setup(struct virtio_device *dev);
 
 #endif // VIRTIO_VIRTIO_DEVICE_H
index e12c554..dc87497 100644 (file)
@@ -133,6 +133,23 @@ lpaddr_t virtio_virtqueue_get_vring_paddr(struct virtqueue *vq);
 void virtio_virtqueue_get_vring_cap(struct virtqueue *vq,
                                     struct capref *ret_cap);
 
+/**
+ * \brief Returns the queue index of the virtqueue of the device
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns queue index
+ */
+uint16_t virtio_virtqueue_get_queue_index(struct virtqueue *vq);
+
+/**
+ * \brief returns the alignment of the vring
+ *
+ * \param the virtqueue to get the alignment from
+ *
+ * \returns vring alignment
+ */
+lvaddr_t virtio_virtqueue_get_vring_align(struct virtqueue *vq);
 
 /**
  * \brief Returns the number of elements (number of descriptors)in the vring of
index ea918a0..270f7ac 100644 (file)
@@ -37,6 +37,14 @@ struct xeon_phi_msg_open
     char iface[44];     ///< interface name (exported by the application)
 };
 
+struct xeon_phi_msg_virtq
+{
+    lpaddr_t base;     ///< physical address of the messaging frame
+    uint8_t  bits;     ///< size of the frame in bits
+    uint8_t  queueid;     ///< type of the channel
+    char iface[44];     ///< interface name (exported by the application)
+};
+
 
 struct xeon_phi_msg_spawn
 {
@@ -72,6 +80,8 @@ struct xeon_phi_messaging_cb
 {
     errval_t (*open)(struct capref msgframe, uint8_t chantype);
     errval_t (*open_iface)(struct capref msgframe, uint8_t chantype, char *iface);
+    errval_t (*add_virtq)(struct capref msgframe, uint16_t queue_id);
+    errval_t (*add_virtq_iface)(struct capref msgframe, uint16_t queue_id,char *iface);
     errval_t (*spawn)(coreid_t core, char *name);
 };
 
index 009059e..ef063dc 100644 (file)
                       cFiles = [ "virtio_ring.c", 
                                         "virtqueue.c", 
                                         "virtio_device.c",
+                                        "virtio_buffer.c",
                                         "backends/virtio_device_mmio.c",
                                         "backends/virtio_device_pci.c" ],
-                      mackerelDevices = [ "virtio/virtio_mmio" ]
+                      mackerelDevices = [ "virtio/virtio_mmio",
+                                          "virtio/virtio_pci" ]
                 }
 ]
diff --git a/lib/virtio/backends/virtio_device_io.c b/lib/virtio/backends/virtio_device_io.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;
+}
+
+
+
index e5e49d0..aa921b6 100644 (file)
 #include <barrelfish/barrelfish.h>
 
 #include <virtio/virtio.h>
-#include <virtio/virtio_device.h>
+#include <virtio/virtqueue.h>
+#include <virtio/virtio_ring.h>
 
+#include <dev/virtio/virtio_mmio_dev.h>
+
+#include "virtio_device.h"
 #include "backends/virtio_mmio.h"
+#include "debug.h"
+
+#define REG_WAIT_MAX 0xFFFF
+
 
 /**
- * \brief initializes and allocates a VirtIO device structure for the MMIO backend
+ * \brief   updates the device status field of the VirtIO device
+ *
+ * \param dev        device to set the status
+ * \param new_status the status to set the device to
+ *
+ * \returns SYS_ERR_OK on success
+ *          VIRTIO_ERR_DEVICE_STATUS if the status change does not make sense
  */
-errval_t virtio_device_mmio_init(struct virtio_device **dev,
-                                 struct virtio_device_init *info)
+static errval_t device_set_status(struct virtio_device *dev,
+                                  uint8_t new_status)
+{
+    struct virtio_device_mmio *mmio_dev = (struct virtio_device_mmio *)dev;
+
+    virtio_mmio_status_t status = virtio_mmio_status_default;
+
+    switch(new_status) {
+        case VIRTIO_DEVICE_STATUS_RESET:
+            virtio_mmio_reset_wr(&mmio_dev->regs, virtio_mmio_device_reset);
+            return SYS_ERR_OK;
+            break;
+        case VIRTIO_DEVICE_STATUS_FAILED:
+            status = virtio_mmio_status_failed_insert(status, 0x1);
+            break;
+        case VIRTIO_DEVICE_STATUS_ACKNOWLEDGE :
+            status = virtio_mmio_status_rd(&mmio_dev->regs);
+            if (status != 0x0) {
+                return VIRTIO_ERR_DEVICE_STATUS;
+            }
+            status = virtio_mmio_status_acknowledge_insert(status, 0x1);
+            break;
+        case VIRTIO_DEVICE_STATUS_DRIVER :
+            status = virtio_mmio_status_rd(&mmio_dev->regs);
+            if (!virtio_mmio_status_acknowledge_extract(status)) {
+                return VIRTIO_ERR_DEVICE_STATUS;
+            }
+            status = virtio_mmio_status_driver_insert(status, 0x1);
+            break;
+
+        case VIRTIO_DEVICE_STATUS_FEATURES_OK :
+            status = virtio_mmio_status_rd(&mmio_dev->regs);
+            if (!virtio_mmio_status_driver_extract(status)) {
+                return VIRTIO_ERR_DEVICE_STATUS;
+            }
+            status = virtio_mmio_status_features_ok_insert(status, 0x1);
+            break;
+
+        case VIRTIO_DEVICE_STATUS_DRIVER_OK :
+            status = virtio_mmio_status_rd(&mmio_dev->regs);
+            if (!virtio_mmio_status_features_ok_extract(status)) {
+                return VIRTIO_ERR_DEVICE_STATUS;
+            }
+            status = virtio_mmio_status_driver_ok_insert(status, 0x1);
+            break;
+    }
+
+    virtio_mmio_status_wr(&mmio_dev->regs, status);
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief resets the VirtIO deivces
+ *
+ * \param dev the device to reset
+ *
+ * \returns SYS_ERR_OK on success
+ */
+static errval_t device_reset(struct virtio_device *dev)
+{
+    /*
+     * TODO: is there some clean up needed ?
+     */
+    return device_set_status(dev, VIRTIO_DEVICE_STATUS_RESET);
+}
+
+
+static errval_t device_get_device_features(struct virtio_device *dev,
+                                           uint64_t *ret_features)
+{
+    struct virtio_device_mmio *mmio_dev = (struct virtio_device_mmio *)dev;
+
+    uint64_t features = 0;
+
+    virtio_mmio_dev_features_sel_wr(&mmio_dev->regs, 0x1);
+
+    uint32_t wait = REG_WAIT_MAX;
+    while (!virtio_mmio_dev_features_sel_ready_rdf(&mmio_dev->regs) && (--wait))
+        ;
+
+    features = virtio_mmio_dev_features_features_rdf(&mmio_dev->regs);
+
+    features <<= 32;
+
+    virtio_mmio_dev_features_sel_wr(&mmio_dev->regs, 0x0);
+
+    wait = REG_WAIT_MAX;
+    while (!virtio_mmio_dev_features_sel_ready_rdf(&mmio_dev->regs) && (--wait))
+            ;
+
+    /*
+     * TODO: when do we know when the new values in the features
+     *       are ready??
+     */
+    features |= virtio_mmio_dev_features_features_rdf(&mmio_dev->regs);
+
+    return SYS_ERR_OK;
+}
+
+static errval_t device_set_driver_features(struct virtio_device *dev,
+                                          uint64_t features)
+{
+    struct virtio_device_mmio *mmio_dev = (struct virtio_device_mmio *)dev;
+
+    virtio_mmio_driv_features_sel_wr(&mmio_dev->regs, 0x0);
+
+    uint32_t wait = REG_WAIT_MAX;
+    while (!virtio_mmio_driv_features_sel_ready_rdf(&mmio_dev->regs) && (--wait))
+         ;
+
+    virtio_mmio_driv_features_wr(&mmio_dev->regs, (uint32_t)(features));
+
+    wait = REG_WAIT_MAX;
+    while (!virtio_mmio_driv_features_sel_ack_rdf(&mmio_dev->regs) && (--wait))
+        ;
+
+    virtio_mmio_driv_features_sel_wr(&mmio_dev->regs, 0x1);
+    wait = REG_WAIT_MAX;
+    while (!virtio_mmio_driv_features_sel_ready_rdf(&mmio_dev->regs) && (--wait))
+        ;
+
+    virtio_mmio_driv_features_wr(&mmio_dev->regs, (uint32_t)(features >> 32));
+
+    wait = REG_WAIT_MAX;
+    while (!virtio_mmio_driv_features_sel_ack_rdf(&mmio_dev->regs) && (--wait))
+            ;
+
+    return SYS_ERR_OK;
+}
+
+static errval_t device_set_virtq(struct virtio_device *dev,
+                                 struct virtqueue *vq)
 {
+    struct virtio_device_mmio *mmio_dev = (struct virtio_device_mmio *)dev;
+
+    uint16_t queue_index = virtio_virtqueue_get_queue_index(vq);
+
+    /* todo: wait till the previous request has been seen... */
+    uint32_t wait = REG_WAIT_MAX;
+    while (!virtio_mmio_queue_ready_ack_rdf(&mmio_dev->regs) && (--wait))
+            ;
+
+    virtio_mmio_queue_sel_wr(&mmio_dev->regs, queue_index);
+    wait = REG_WAIT_MAX;
+    while (!virtio_mmio_queue_sel_ready_rdf(&mmio_dev->regs) && (--wait))
+        ;
+
+
+    /* TODO> wait till queue has been selected */
+
+    if (virtio_mmio_queue_ready_ready_rdf(&mmio_dev->regs)) {
+        /* queue has already been activated... */
+        return VIRTIO_ERR_QUEUE_ACTIVE;
+    }
+
+    if (virtio_mmio_queue_max_size_rdf(&mmio_dev->regs) == 0x0) {
+        /* the queue is not implemented */
+        return VIRTIO_ERR_QUEUE_INVALID;
+    }
+
+    uint16_t size = virtio_virtqueue_get_num_desc(vq);
+    virtio_mmio_queue_num_size_wrf(&mmio_dev->regs, size);
+
+    lpaddr_t paddr = virtio_virtqueue_get_vring_paddr(vq);
+    lpaddr_t align = virtio_virtqueue_get_vring_align(vq);
+
+
+    virtio_mmio_queue_desc_hi_addr_wrf(&mmio_dev->regs, (uint32_t)(paddr >> 32));
+    virtio_mmio_queue_desc_lo_addr_wrf(&mmio_dev->regs, (uint32_t)(paddr));
+
+    paddr += size * sizeof(struct vring_desc);
+
+    virtio_mmio_queue_used_hi_addr_wrf(&mmio_dev->regs, (uint32_t)(paddr >> 32));
+    virtio_mmio_queue_used_lo_addr_wrf(&mmio_dev->regs, (uint32_t)(paddr));
+
+    paddr += sizeof(uint16_t) * (2 + size + 1);
+    paddr = (paddr + align - 1) & ~(align - 1);
+
+    virtio_mmio_queue_avail_hi_addr_wrf(&mmio_dev->regs, (uint32_t)(paddr >> 32));
+    virtio_mmio_queue_avail_lo_addr_wrf(&mmio_dev->regs, (uint32_t)(paddr));
+
+    /* signal the host that the queue is ready */
+    virtio_mmio_queue_ready_ready_wrf(&mmio_dev->regs, 0x1);
+
     return SYS_ERR_OK;
 }
 
+static errval_t device_get_queue_num_max(struct virtio_device *dev,
+                                         uint16_t queue_index,
+                                         uint16_t *num_max)
+{
+    struct virtio_device_mmio *mmio_dev = (struct virtio_device_mmio *)dev;
+
+    virtio_mmio_queue_sel_selector_wrf(&mmio_dev->regs, queue_index);
+
+    /* TODO: wait till data ready */
+
+    uint16_t qmax = (uint16_t)virtio_mmio_queue_max_size_rdf(&mmio_dev->regs);
 
+    if (num_max) {
+        *num_max = qmax;
+    }
+
+    return SYS_ERR_OK;
+}
 
+static errval_t device_negotiate_features(struct virtio_device *dev,
+                                          uint64_t driver_features)
+{
+    uint64_t device_features = 0x0;
+    device_get_device_features(dev, &device_features);
+
+    driver_features &= device_features;
+
+    device_set_driver_features(dev, driver_features);
+
+    dev->features = driver_features;
+
+    return SYS_ERR_OK;
+}
+
+struct virtio_device_fn virtio_mmio_fn = {
+    .reset = device_reset,
+    .set_status = device_set_status,
+    .negotiate_features = device_negotiate_features,
+    .set_virtq = device_set_virtq,
+    .get_queue_num_max = device_get_queue_num_max
+};
+
+
+/**
+ * \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_setup *info)
+{
+    struct virtio_device_mmio *mmio_dev;
+    errval_t err;
+    mmio_dev = malloc(sizeof(*mmio_dev));
+    if (mmio_dev == NULL) {
+        return LIB_ERR_MALLOC_FAIL;
+    }
+
+    virtio_mmio_initialize(&mmio_dev->regs, (mackerel_addr_t) info->dev_reg);
+
+
+    /**
+     * 4.2.3.1.1 Driver Requirements: Device Initialization
+     * The driver MUST start the device initialization by reading and checking
+     * values from MagicValue and Version.
+     * If both values are valid, it MUST read DeviceID and if its value is zero
+     * (0x0) MUST abort initialization and MUST NOT access any other register.
+     */
+    if (virtio_mmio_magic_value_rd(&mmio_dev->regs) != virtio_mmio_magic_value) {
+        VIRTIO_DEBUG_DEV("Virtio Magic Value is invalid\n");
+        return VIRTIO_ERR_NOT_VIRTIO_DEVICE;
+    }
+
+    err = SYS_ERR_OK;
+    switch (virtio_mmio_version_rd(&mmio_dev->regs)) {
+        case virtio_mmio_version_legacy:
+            VIRTIO_DEBUG_DEV("Handling of legacy devices not supported.\n");
+            err = VIRTIO_ERR_VERSION_MISMATCH;
+            break;
+        case virtio_mmio_version_virtio10:
+            err = SYS_ERR_OK;
+            break;
+        default:
+            VIRTIO_DEBUG_DEV("Virtio version is invalid.\n");
+            err = VIRTIO_ERR_NOT_VIRTIO_DEVICE;
+            break;
+    }
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    virtio_mmio_deviceid_t devid = virtio_mmio_deviceid_rd(&mmio_dev->regs);
+    if (devid == 0) {
+        VIRTIO_DEBUG_DEV("Virtio device ID invalid.\n");
+        return VIRTIO_ERR_NOT_VIRTIO_DEVICE;
+    }
+
+    mmio_dev->dev.devid = devid;
+    mmio_dev->dev.backend = VIRTIO_DEVICE_BACKEND_MMIO;
+    mmio_dev->dev.f = &virtio_mmio_fn;
+    mmio_dev->dev.type = virtio_mmio_deviceid_id_rdf(&mmio_dev->regs);
+
+    return SYS_ERR_OK;
+}
diff --git a/lib/virtio/backends/virtio_io.h b/lib/virtio/backends/virtio_io.h
new file mode 100644 (file)
index 0000000..e9e29be
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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>
+
+
+
+#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
index e25a9eb..62f1e7a 100644 (file)
 #ifndef VIRTIO_VIRTIO_MMIO_H
 #define VIRTIO_VIRTIO_MMIO_H
 
-#include <barrelfish/barrelfish.h>
+#include <dev/virtio/virtio_mmio_dev.h>
 
-#include <virtio/virtio.h>
 #include <virtio/virtio_device.h>
 
 struct virtio_device_mmio
 {
     struct virtio_device dev;
+    virtio_mmio_t regs;
 
 };
 
@@ -30,6 +30,9 @@ struct virtio_device_mmio
  * \returns SYS_ERR_OK on success
  */
 errval_t virtio_device_mmio_init(struct virtio_device **dev,
-                                 struct virtio_device_init *info);
+                                 struct virtio_device_setup *info);
+
+
+
 
 #endif // VIRTIO_VIRTIO_MMIO_H
index 455ead2..2a90637 100644 (file)
@@ -12,6 +12,7 @@
 
 #define VIRTIO_DEBUG_ENABLED 1
 #define VIRTIO_DEBUG_VQ_ENABLED 1
+#define VIRTIO_DEBUG_DEV_ENABLED 1
 
 #if VIRTIO_DEBUG_ENABLED
 #define VIRTIO_DEBUG_PRINT(msg...) debug_printf(msg)
 #define VIRTIO_DEBUG_VQ(msg...)
 #endif
 
+#ifdef VIRTIO_DEBUG_DEV_ENABLED
+#define VIRTIO_DEBUG_DEV(msg...) VIRTIO_DEBUG_PRINT("[VIRTIO DEV] " msg)
+#else
+#define VIRTIO_DEBUG_DEV(msg...)
+#endif
+
 
 #endif /* VIRTIO_DEBUG_H_ */
index c49f441..72d3978 100644 (file)
 #include <virtio/virtio.h>
 #include <virtio/virtio_device.h>
 
+#include "virtio_device.h"
 #include "backends/virtio_mmio.h"
 #include "backends/virtio_pci.h"
 
+#include "debug.h"
 
+/**
+ * \brief initializes a new VirtIO device based on the values passed with the
+ *        device init struct. The device registers have already to be mapped. *
+ *
+ * \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_setup *init)
+{
+    errval_t err = SYS_ERR_OK;
+
+    if (init->dev_reg == NULL || init->dev_reg_size == 0) {
+        /*
+         * XXX: does this also hold for the PCI
+         */
+        return VIRTIO_ERR_DEVICE_REGISTER;
+    }
+
+    switch (init->backend) {
+        case VIRTIO_DEVICE_BACKEND_PCI:
+            /*
+             * TODO: intialize the PCI device backend
+             */
+            assert(!"NYI: handling of the PCI backend\n");
+            break;
+        case VIRTIO_DEVICE_BACKEND_MMIO:
+            err = virtio_device_mmio_init(dev, init);
+            break;
+        case VIRTIO_DEVICE_BACKEND_IO:
+            /*
+             * TODO: intialize the IO device backend
+             */
+            assert(!"NYI: handling of the IO backend\n");
+            break;
+        default:
+            err = VIRTIO_ERR_BACKEND;
+            break;
+    }
+
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    struct virtio_device *vdev = *dev;
+
+    /* 1. Reset the device. */
+    err = virtio_device_reset(vdev);
+    if (err_is_fail(err)) {
+        goto failed;
+    }
+
+    /* 2. Set the ACKNOWLEDGE status bit: the guest OS has notice the device.*/
+    err = virtio_device_set_status(vdev, VIRTIO_DEVICE_STATUS_ACKNOWLEDGE);
+    if (err_is_fail(err)) {
+        goto failed;
+    }
+
+    /* 3. Set the DRIVER status bit: the guest OS knows how to drive the device.*/
+    err = virtio_device_set_status(vdev, VIRTIO_DEVICE_STATUS_DRIVER);
+    if (err_is_fail(err)) {
+        goto failed;
+    }
+
+    /* 4. Read device feature bits, and write the subset of feature bits understood by the OS and driver to the
+     device. During this step the driver MAY read (but MUST NOT write) the device-specific configuration
+     fields to check that it can support the device before accepting it.*/
+    err = virtio_device_feature_negotiate(vdev);
+    if (err_is_fail(err)) {
+        goto failed;
+    }
+
+    /* 5. Set the FEATURES_OK status bit. The driver MUST not accept new feature bits after this step.*/
+    err = virtio_device_set_status(vdev, VIRTIO_DEVICE_STATUS_FEATURES_OK);
+    if (err_is_fail(err)) {
+        goto failed;
+    }
+
+    /* 6. Re-read device status to ensure the FEATURES_OK bit is still set: otherwise, the device does not
+     support our subset of features and the device is unusable.*/
+    uint8_t status;
+    err = virtio_device_get_status(vdev, &status);
+    assert(err_is_ok(err));
+
+    if (!virtio_mmio_status_features_ok_extract(status)) {
+        goto failed;
+    }
+
+    /* 7. Perform device-specific setup, including discovery of virtqueues for the device, optional per-bus setup,
+     reading and possibly writing the device’s virtio configuration space, and population of virtqueues.*/
+    err = virtio_device_specific_setup(vdev);
+    if (err_is_fail(err)) {
+        goto failed;
+    }
+    /* 8. Set the DRIVER_OK status bit. At this point the device is “live”. */
+    err = virtio_device_set_status(vdev, VIRTIO_DEVICE_STATUS_DRIVER_OK);
+    assert(err_is_ok(err));
+
+    if (init->device_setup) {
+        return init->device_setup(vdev);
+    }
+
+    return SYS_ERR_OK;
+
+    failed: virtio_device_set_status(vdev, VIRTIO_DEVICE_STATUS_FAILED);
+
+    return err;
+}
+
+/**
+ * \brief initializes a new VirtIO device based on the values passed with the
+ *        device init struct. The supplied cap contains the memory range of the
+ *        device registers.
+ *
+ * \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 virtio_device_setup *init,
+                                     struct capref dev_cap)
+{
+    errval_t err;
+
+    assert(!capref_is_null(dev_cap));
+
+    struct frame_identity id;
+    err = invoke_frame_identify(dev_cap, &id);
+    if (err_is_fail(err)) {
+        VIRTIO_DEBUG_DEV("ERROR: could not identify the device frame.\n");
+        return err;
+    }
+
+    init->dev_reg_size = (1UL << id.bits);
+
+    err = vspace_map_one_frame_attr(&init->dev_reg, (1UL << id.bits), dev_cap,
+    VIRTIO_VREGION_FLAGS_DEVICE,
+                                    NULL, NULL);
+    if (err_is_fail(err)) {
+        VIRTIO_DEBUG_DEV("ERROR: mapping the device register frame failed.\n");
+        init->dev_reg = NULL;
+        init->dev_reg_size = 0;
+        return err;
+    }
+
+    VIRTIO_DEBUG_DEV("mapped device registers: [0x%016lx] -> [0x%016lx]\n",
+                     id.base,
+                     (uintptr_t )init->dev_reg);
+
+    err = virtio_device_init(dev, init);
+    if (err_is_fail(err)) {
+        vspace_unmap(init->dev_reg);
+    }
 
+    return err;
+}
diff --git a/lib/virtio/virtio_device.h b/lib/virtio/virtio_device.h
new file mode 100644 (file)
index 0000000..6a6208a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_DEVICE_H
+#define VIRTIO_DEVICE_H
+
+#include <virtio/virtio_device.h>
+
+/**
+ * represents a virtio device
+ */
+struct virtio_device
+{
+    char name[VIRTIO_DEVICE_NAME_MAX];
+    uint32_t devid;
+    uint8_t type;
+    uint64_t features;
+    enum virtio_device_backend backend;
+    struct virtio_device_fn *f;
+    uint16_t num_queues;
+    struct virtqueue **queues;
+};
+
+/**
+ * contains function pointers to backend specific functions
+ */
+struct virtio_device_fn
+{
+    errval_t (*reset)(struct virtio_device *dev);
+    errval_t (*set_status)(struct virtio_device *dev, uint8_t status);
+    errval_t (*negotiate_features)(struct virtio_device *dev, uint64_t driv_features);
+    errval_t (*setup)(struct virtio_device *dev);
+    errval_t (*get_queue_num_max)(struct virtio_device *dev, uint16_t queue_index, uint16_t *num_max);
+    errval_t (*set_virtq)(struct virtio_device *dev, struct virtqueue *vq);
+};
+
+
+
+
+
+
+#endif // VIRTIO_VIRTIO_DEVICE_H
index 0e4d961..42d4de1 100644 (file)
@@ -301,7 +301,6 @@ errval_t virtio_virtqueue_free(struct virtqueue *vq)
     return SYS_ERR_OK;
 }
 
-
 /*
  * ----------------------------------------------------------------------------
  *  Virtqueue Getter Functions
@@ -320,6 +319,18 @@ lpaddr_t virtio_virtqueue_get_vring_paddr(struct virtqueue *vq)
 }
 
 /**
+ * \brief returns the alignment of the vring
+ *
+ * \param the virtqueue to get the alignment from
+ *
+ * \returns vring alignment
+ */
+lvaddr_t virtio_virtqueue_get_vring_align(struct virtqueue *vq)
+{
+    return vq->vring_align;
+}
+
+/**
  * \brief Returns the frame capability of the vring
  *
  * \param vq        pointer to the virtqueue structure
@@ -347,6 +358,19 @@ uint16_t virtio_virtqueue_get_num_desc(struct virtqueue *vq)
 }
 
 /**
+ * \brief Returns the queue index of the virtqueue of the device
+ *
+ * \param vq pointer to the virtqueue structure
+ *
+ * \returns queue index
+ */
+uint16_t virtio_virtqueue_get_queue_index(struct virtqueue *vq)
+{
+    return vq->queue_index;
+}
+
+
+/**
  * \brief Checks if the virtqueue is empty
  *
  * \param vq pointer to the virtqueue structure
index 3dac31e..58846cb 100644 (file)
@@ -11,7 +11,7 @@
 static uint64_t mbi_mmap0[] = {0x0, 0xfee00000, 1};
 static uint64_t mbi_mmap1[] = {0xfee00000, 0x120000, 3};
 static uint64_t mbi_mmap2[] = {0x100000000, 0x80000000, 1};
-static struct multiboot_modinfo mbi_mods[9];
+static struct multiboot_modinfo mbi_mods[10];
 static struct multiboot_mmap mbi_mmaps[3];
 static struct multiboot_info mbi;
 
@@ -21,35 +21,38 @@ struct multiboot_info *get_multiboot(void) {
   mbi.flags |= MULTIBOOT_INFO_FLAG_HAS_ELF_SYMS;
   mbi.flags |= MULTIBOOT_INFO_FLAG_HAS_MMAP;
   mbi.cmdline = (uint32_t)(uint64_t) "/k1om/sbin/cpu loglevel=4";
-  mbi.mods_count = 9;
+  mbi.mods_count = 10;
   mbi.mods_addr = (uint32_t)(uint64_t) mbi_mods;
   mbi_mods[0].mod_start = (uint32_t) 0x0;
-  mbi_mods[0].mod_end = (uint32_t) 0xf9506;
+  mbi_mods[0].mod_end = (uint32_t) 0xf99fe;
   mbi_mods[0].string = (uint32_t)(uint64_t) "/k1om/sbin/cpu loglevel=4";
   mbi_mods[1].mod_start = (uint32_t) 0xfa000;
-  mbi_mods[1].mod_end = (uint32_t) 0x6cf4dc;
+  mbi_mods[1].mod_end = (uint32_t) 0x6d1f3a;
   mbi_mods[1].string = (uint32_t)(uint64_t) "/k1om/sbin/init ";
-  mbi_mods[2].mod_start = (uint32_t) 0x6d0000;
-  mbi_mods[2].mod_end = (uint32_t) 0xc4cef9;
+  mbi_mods[2].mod_start = (uint32_t) 0x6d2000;
+  mbi_mods[2].mod_end = (uint32_t) 0xc5231f;
   mbi_mods[2].string = (uint32_t)(uint64_t) "/k1om/sbin/mem_serv ";
-  mbi_mods[3].mod_start = (uint32_t) 0xc4d000;
-  mbi_mods[3].mod_end = (uint32_t) 0x1420874;
+  mbi_mods[3].mod_start = (uint32_t) 0xc53000;
+  mbi_mods[3].mod_end = (uint32_t) 0x1429533;
   mbi_mods[3].string = (uint32_t)(uint64_t) "/k1om/sbin/monitor ";
-  mbi_mods[4].mod_start = (uint32_t) 0x1421000;
-  mbi_mods[4].mod_end = (uint32_t) 0x1a54e8f;
+  mbi_mods[4].mod_start = (uint32_t) 0x142a000;
+  mbi_mods[4].mod_end = (uint32_t) 0x1a5fcc5;
   mbi_mods[4].string = (uint32_t)(uint64_t) "/k1om/sbin/ramfsd boot";
-  mbi_mods[5].mod_start = (uint32_t) 0x1a55000;
-  mbi_mods[5].mod_end = (uint32_t) 0x2066023;
+  mbi_mods[5].mod_start = (uint32_t) 0x1a60000;
+  mbi_mods[5].mod_end = (uint32_t) 0x2073a19;
   mbi_mods[5].string = (uint32_t)(uint64_t) "/k1om/sbin/skb boot";
-  mbi_mods[6].mod_start = (uint32_t) 0x2067000;
-  mbi_mods[6].mod_end = (uint32_t) 0x25e130b;
-  mbi_mods[6].string = (uint32_t)(uint64_t) "/k1om/sbin/xeon_phi_mgr boot";
-  mbi_mods[7].mod_start = (uint32_t) 0x25e2000;
-  mbi_mods[7].mod_end = (uint32_t) 0x2f8f54f;
+  mbi_mods[6].mod_start = (uint32_t) 0x2074000;
+  mbi_mods[6].mod_end = (uint32_t) 0x261f215;
+  mbi_mods[6].string = (uint32_t)(uint64_t) "/k1om/sbin/xeon_phi boot";
+  mbi_mods[7].mod_start = (uint32_t) 0x2620000;
+  mbi_mods[7].mod_end = (uint32_t) 0x2fd108f;
   mbi_mods[7].string = (uint32_t)(uint64_t) "/k1om/sbin/spawnd boot bootk1om=0-3";
-  mbi_mods[8].mod_start = (uint32_t) 0x2f90000;
-  mbi_mods[8].mod_end = (uint32_t) 0x38b07e4;
+  mbi_mods[8].mod_start = (uint32_t) 0x2fd2000;
+  mbi_mods[8].mod_end = (uint32_t) 0x38f53e4;
   mbi_mods[8].string = (uint32_t)(uint64_t) "/k1om/sbin/startd boot";
+  mbi_mods[9].mod_start = (uint32_t) 0x38f6000;
+  mbi_mods[9].mod_end = (uint32_t) 0x3e89290;
+  mbi_mods[9].string = (uint32_t)(uint64_t) "/k1om/sbin/xeon_phi_test ";
   mbi.mmap_length = sizeof(mbi_mmaps);
   mbi.mmap_addr = (uint32_t)(uint64_t) mbi_mmaps;
   mbi_mmaps[0].size = sizeof(struct multiboot_mmap);