Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


updates to virtio device framework
[palacios.git] / palacios / src / devices / lnx_virtio_blk.c
index f44d616..5b40144 100644 (file)
 
 #include <palacios/vmm.h>
 
-#include <devices/lnx_virtio.h>
-#include <devices/pci.h>
+#include <devices/lnx_virtio_pci.h>
+
 
+#include <devices/pci.h>
 
 
 struct blk_config {
@@ -33,23 +34,32 @@ struct blk_config {
     uint8_t sectors;
 } __attribute__((packed));
 
-struct blk_state {
 
-    struct blk_config cfg;
+
+
+/* Host Feature flags */
+#define VIRTIO_BARRIER       0x01       /* Does host support barriers? */
+#define VIRTIO_SIZE_MAX      0x02       /* Indicates maximum segment size */
+#define VIRTIO_SEG_MAX       0x04       /* Indicates maximum # of segments */
+#define VIRTIO_LEGACY_GEOM   0x10       /* Indicates support of legacy geometry */
+
+
+
+struct virtio_blk_state {
+    struct blk_config block_cfg;
+    struct virtio_config virtio_cfg;
 
     struct vm_device * pci_bus;
-};
+    struct pci_device * pci_dev;
 
+    struct virtio_device * virtio_dev; // the virtio device struction for _this_ device
+    
 
+    int io_range_size;
+};
 
-static int virtio_pci_write(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
-    return -1;
-}
 
 
-static int virtio_pci_read(uint16_t port, void * dst, uint_t length, struct vm_device * dev) {
-    return -1;
-}
 
 
 
@@ -59,6 +69,7 @@ static int virtio_free(struct vm_device * dev) {
 
 
 
+
 static struct v3_device_ops dev_ops = {
     .free = virtio_free,
     .reset = NULL,
@@ -70,86 +81,98 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int virtio_init(struct guest_info * vm, void * cfg_data) {
-    struct blk_state * virtio = NULL;
-    struct vm_device * pci_bus = (struct vm_device *)cfg_data;
 
+static int virtio_init(struct guest_info * vm, void * cfg_data) {
+    struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+    struct virtio_blk_state * virtio_state = NULL;
+    struct pci_device * pci_dev = NULL;
 
     PrintDebug("Initializing VIRTIO Block device\n");
 
     if (pci_bus == NULL) {
-       PrintError("VirtIO requires a PCI bus\n");
+       PrintError("VirtIO devices require a PCI Bus");
        return -1;
     }
 
-    virtio = (struct blk_state *)V3_Malloc(sizeof(struct blk_state));
+    
+    virtio_state  = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state));
+    memset(virtio_state, 0, sizeof(struct virtio_blk_state));
 
-    virtio->pci_bus = pci_bus;
 
-    struct vm_device * dev = v3_allocate_device("VIRTIO_BLK", &dev_ops, virtio);
+
+
+    struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_BLK", &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", "LNX_VIRTIO_BLK");
        return -1;
     }
 
+    struct v3_pci_bar bars[6];
+    int num_ports = sizeof(struct virtio_config) + sizeof(struct blk_config);
+    int tmp_ports = num_ports;
+    int i;
 
 
-    if (virtio->pci_bus != NULL) {
-       struct v3_pci_bar bars[6];
-       struct pci_device * pci_dev = NULL;
-       int i;
-       int num_ports_pow2 = 1;
-       int num_ports = sizeof(struct virtio_config) + sizeof(struct blk_config);
-       
 
-       // This gets the number of ports, rounded up to a power of 2
-       while (num_ports > 0) {
-           num_ports >>= 1;
-           num_ports_pow2 <<= 1;
-       }
-       
-       // reset num_ports 
-       num_ports = sizeof(struct virtio_config) + sizeof(struct blk_config);
+    // This gets the number of ports, rounded up to a power of 2
+    virtio_state->io_range_size = 1; // must be a power of 2
 
-       if (num_ports  & ((num_ports_pow2 >> 1) - 1)) {
-           num_ports_pow2 >>= 1;
-       }
+    while (tmp_ports > 0) {
+       tmp_ports >>= 1;
+       virtio_state->io_range_size <<= 1;
+    }
+       
+    // this is to account for any low order bits being set in num_ports
+    // if there are none, then num_ports was already a power of 2 so we shift right to reset it
+    if ((num_ports & ((virtio_state->io_range_size >> 1) - 1)) == 0) {
+       virtio_state->io_range_size >>= 1;
+    }
 
 
-       for (i = 0; i < 6; i++) {
-           bars[i].type = PCI_BAR_NONE;
-       }
+    for (i = 0; i < 6; i++) {
+       bars[i].type = PCI_BAR_NONE;
+    }
 
-       bars[0].type = PCI_BAR_IO;
-       bars[0].default_base_port = -1;
-       bars[0].num_ports = num_ports_pow2;
+    bars[0].type = PCI_BAR_IO;
+    bars[0].default_base_port = -1;
+    bars[0].num_ports = virtio_state->io_range_size;
 
-       bars[0].io_read = virtio_pci_read;
-       bars[0].io_write = virtio_pci_write;
+    //    bars[0].io_read = virtio_io_read;
+    //  bars[0].io_write = virtio_io_write;
 
-       pci_dev = v3_pci_register_device(virtio->pci_bus, PCI_STD_DEVICE, 
-                                        0, PCI_AUTO_DEV_NUM, 0,
-                                        "VIRTIO-BLK", bars,
-                                        NULL, NULL, NULL, dev);
+    pci_dev = v3_pci_register_device(pci_bus, PCI_STD_DEVICE, 
+                                    0, PCI_AUTO_DEV_NUM, 0,
+                                    "LNX_VIRTIO_BLK", bars,
+                                    NULL, NULL, NULL, dev);
 
-       if (!pci_dev) {
-           PrintError("Could not register PCI Device\n");
-           return -1;
-       }
+    if (!pci_dev) {
+       PrintError("Could not register PCI Device\n");
+       return -1;
+    }
+       
+    pci_dev->config_header.vendor_id = VIRTIO_VENDOR_ID;
+    pci_dev->config_header.subsystem_vendor_id = VIRTIO_SUBVENDOR_ID;
        
-       pci_dev->config_header.vendor_id = VIRTIO_VENDOR_ID;
-       pci_dev->config_header.device_id = VIRTIO_BLOCK_DEV_ID;
-       pci_dev->config_header.class = PCI_CLASS_STORAGE;
-       pci_dev->config_header.subclass = PCI_STORAGE_SUBCLASS_OTHER;
 
-       pci_dev->config_header.subsystem_vendor_id = VIRTIO_SUBVENDOR_ID;
-       pci_dev->config_header.subsystem_id = VIRTIO_BLOCK_SUBDEVICE_ID;
+    pci_dev->config_header.device_id = VIRTIO_BLOCK_DEV_ID;
+    pci_dev->config_header.class = PCI_CLASS_STORAGE;
+    pci_dev->config_header.subclass = PCI_STORAGE_SUBCLASS_OTHER;
+    
+    pci_dev->config_header.subsystem_id = VIRTIO_BLOCK_SUBDEVICE_ID;
 
-       pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
-    }
 
+    pci_dev->config_header.intr_pin = 1;
+
+    pci_dev->config_header.max_latency = 1; // ?? (qemu does it...)
+
+
+    virtio_state->pci_dev = pci_dev;
+    virtio_state->pci_bus = pci_bus;
+
+    /* Block configuration */
 
 
+    
     return -1;
 }