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.


added initial VirtIO and symbiotic swap devices
Jack Lange [Thu, 23 Jul 2009 21:14:46 +0000 (16:14 -0500)]
moved the pci class/subclass IDs

palacios/build/Makefile
palacios/include/devices/lnx_virtio.h [new file with mode: 0644]
palacios/include/devices/pci.h
palacios/include/devices/pci_types.h
palacios/include/devices/sym_swap.h [new file with mode: 0644]
palacios/include/palacios/vmm.h
palacios/src/devices/lnx_virtio_blk.c [new file with mode: 0644]
palacios/src/devices/piix3.c
palacios/src/devices/sym_swap.c [new file with mode: 0644]

index 59dd8d9..44b6568 100644 (file)
@@ -347,6 +347,8 @@ DEVICES_OBJS := \
        devices/piix3.o \
        devices/net_cd.o \
        devices/net_hd.o \
+       devices/lnx_virtio_blk.o \
+       devices/sym_swap.o \
 
 #      devices/ne2k.o  \
 #      devices/cdrom.o \
diff --git a/palacios/include/devices/lnx_virtio.h b/palacios/include/devices/lnx_virtio.h
new file mode 100644 (file)
index 0000000..e50a1d1
--- /dev/null
@@ -0,0 +1,73 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __DEVICES_LNX_VIRTIO_H__
+#define __DEVICES_LNX_VIRTIO_H__
+
+#ifdef __V3VEE__
+
+#include <palacios/vm_dev.h>
+
+
+/* PCI Vendor IDs (from Qemu) */
+#define VIRTIO_VENDOR_ID    0x1af4 // Redhat/Qumranet
+#define VIRTIO_SUBVENDOR_ID 0x1af4 // Redhat/Qumranet
+#define VIRTIO_SUBDEVICE_ID 0x1100 // Qemu
+
+// PCI Device IDs
+#define VIRTIO_NET_DEV_ID         0x1000
+#define VIRTIO_BLOCK_DEV_ID       0x1001
+#define VIRTIO_BALLOON_DEV_ID     0x1002
+#define VIRTIO_CONSOLE_DEV_ID     0x1003
+
+#define VIRTIO_BLOCK_SUBDEVICE_ID 2
+
+/* The virtio configuration space is a hybrid io/memory mapped model 
+ * All IO is done via IO port accesses
+ * The IO ports access fields in a virtio data structure, and the base io port 
+ *    coincides with the base address of the in memory structure
+ * There is a standard virtio structure of 20 bytes, followed by a 
+ *    device specific structure of n bytes.
+ * 
+ */
+struct virtio_config {
+    uint32_t host_features;
+    uint32_t guest_features;
+    uint32_t vring_page_num;
+    uint16_t vring_ring_size;
+    uint16_t vring_queue_selector;
+    uint16_t vring_queue_notifier;
+    uint8_t status;
+    uint8_t pci_isr;
+} __attribute__((packed));
+
+
+
+struct vm_device * v3_create_virtio_blk();
+
+
+
+
+
+
+
+#endif
+
+#endif
index 8928a9e..23bdae7 100644 (file)
@@ -35,57 +35,7 @@ typedef enum {PCI_BAR_IO, PCI_BAR_MEM16, PCI_BAR_MEM32, PCI_BAR_MEM64_LOW, PCI_B
 
 typedef enum {PCI_STD_DEVICE, PCI_TO_PCI_BRIDGE, PCI_CARDBUS, PCI_MULTIFUNCTION} pci_device_type_t;
 
-typedef enum { PCI_CLASS_PRE2 = 0x00, 
-              PCI_CLASS_STORAGE = 0x01, 
-              PCI_CLASS_NETWORK = 0x02,
-              PCI_CLASS_DISPLAY = 0x03,
-              PCI_CLASS_MMEDIA = 0x04,
-              PCI_CLASS_MEMORY = 0x05,
-              PCI_CLASS_BRIDGE = 0x06,
-              PCI_CLASS_COMM_CTRL = 0x07,
-              PCI_CLASS_BASE_PERIPH = 0x08,
-              PCI_CLASS_INPUT = 0x09, 
-              PCI_CLASS_DOCK = 0x0a,
-              PCI_CLASS_PROC = 0x0b, 
-              PCI_CLASS_SERIAL = 0x0c,
-              PCI_CLASS_MISC = 0xff } pci_class_t;
-
-typedef enum { PCI_STORAGE_SUBCLASS_SCSI = 0x00,
-              PCI_STORAGE_SUBCLASS_IDE = 0x01,
-              PCI_STORAGE_SUBCLASS_FLOPPY = 0x02,
-              PCI_STORAGE_SUBCLASS_IPI = 0x03,
-              PCI_STORAGE_SUBCLASS_RAID = 0x04,
-              PCI_STORAGE_SUBCLASS_OTHER = 0x80 } pci_storage_subclass_t;
-
-
-
-typedef enum { PCI_NET_SUBCLASS_ETHER = 0x00,
-              PCI_NET_SUBCLASS_TOKRING = 0x01,
-              PCI_NET_SUBCLASS_FDDI = 0x02,
-              PCI_NET_SUBCLASS_ATM = 0x03,
-              PCI_NET_SUBCLASS_OTHER = 0x80 } pci_network_subclass_t;
-
-typedef enum { PCI_DISPLAY_SUBCLASS_VGA = 0x00,
-              PCI_DISPLAY_SUBCLASS_XGA = 0x01,
-              PCI_DISPLAY_SUBCLASS_OTHER = 0x80 } pci_display_subclass_t;
-
-typedef enum { PCI_MMEDIA_SUBCLASS_VIDEO = 0x00,
-              PCI_MMEDIA_SUBCLASS_AUDIO = 0x01,
-              PCI_MMEDIA_SUBCLASS_OTHER = 0x80 } pci_multimedia_subclass_t;
-              
-typedef enum { PCI_MEM_SUBCLASS_RAM = 0x00, 
-              PCI_MEM_SUBCLASS_FLASH = 0x01,
-              PCI_MEM_SUBCLASS_OTHER = 0x80 } pci_memory_subclass_t;
-
-typedef enum { PCI_BRIDGE_SUBCLASS_HOST_PCI = 0x00,
-              PCI_BRIDGE_SUBCLASS_PCI_ISA = 0x01,
-              PCI_BRIDGE_SUBCLASS_PCI_EISA = 0x02,
-              PCI_BRIDGE_SUBCLASS_PCI_MICRO = 0x03,
-              PCI_BRIDGE_SUBCLASS_PCI_PCI = 0x04,
-              PCI_BRIDGE_SUBCLASS_PCI_PCMCIA = 0x05,
-              PCI_BRIDGE_SUBCLASS_PCI_NUBUS = 0x06,
-              PCI_BRIDGE_SUBCLASS_PCI_CARDBUS = 0x07,
-              PCI_BRIDGE_SUBCLASS_PCI_OTHER = 0x80 } pci_bridge_subclass_t;
+
 
 // For the rest of the subclass codes see:
 // http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html
index e0d5237..c3cd4cb 100644 (file)
@@ -63,6 +63,62 @@ struct pci_config_header {
 } __attribute__((packed));
 
 
+typedef enum { PCI_CLASS_PRE2 = 0x00, 
+              PCI_CLASS_STORAGE = 0x01, 
+              PCI_CLASS_NETWORK = 0x02,
+              PCI_CLASS_DISPLAY = 0x03,
+              PCI_CLASS_MMEDIA = 0x04,
+              PCI_CLASS_MEMORY = 0x05,
+              PCI_CLASS_BRIDGE = 0x06,
+              PCI_CLASS_COMM_CTRL = 0x07,
+              PCI_CLASS_BASE_PERIPH = 0x08,
+              PCI_CLASS_INPUT = 0x09, 
+              PCI_CLASS_DOCK = 0x0a,
+              PCI_CLASS_PROC = 0x0b, 
+              PCI_CLASS_SERIAL = 0x0c,
+              PCI_CLASS_MISC = 0xff } pci_class_t;
+
+typedef enum { PCI_STORAGE_SUBCLASS_SCSI = 0x00,
+              PCI_STORAGE_SUBCLASS_IDE = 0x01,
+              PCI_STORAGE_SUBCLASS_FLOPPY = 0x02,
+              PCI_STORAGE_SUBCLASS_IPI = 0x03,
+              PCI_STORAGE_SUBCLASS_RAID = 0x04,
+              PCI_STORAGE_SUBCLASS_SATA = 0x06,
+              PCI_STORAGE_SUBCLASS_SAS = 0x07,
+              PCI_STORAGE_SUBCLASS_OTHER = 0x80 } pci_storage_subclass_t;
+
+
+
+typedef enum { PCI_NET_SUBCLASS_ETHER = 0x00,
+              PCI_NET_SUBCLASS_TOKRING = 0x01,
+              PCI_NET_SUBCLASS_FDDI = 0x02,
+              PCI_NET_SUBCLASS_ATM = 0x03,
+              PCI_NET_SUBCLASS_OTHER = 0x80 } pci_network_subclass_t;
+
+typedef enum { PCI_DISPLAY_SUBCLASS_VGA = 0x00,
+              PCI_DISPLAY_SUBCLASS_XGA = 0x01,
+              PCI_DISPLAY_SUBCLASS_OTHER = 0x80 } pci_display_subclass_t;
+
+typedef enum { PCI_MMEDIA_SUBCLASS_VIDEO = 0x00,
+              PCI_MMEDIA_SUBCLASS_AUDIO = 0x01,
+              PCI_MMEDIA_SUBCLASS_OTHER = 0x80 } pci_multimedia_subclass_t;
+              
+typedef enum { PCI_MEM_SUBCLASS_RAM = 0x00, 
+              PCI_MEM_SUBCLASS_FLASH = 0x01,
+              PCI_MEM_SUBCLASS_OTHER = 0x80 } pci_memory_subclass_t;
+
+typedef enum { PCI_BRIDGE_SUBCLASS_HOST_PCI = 0x00,
+              PCI_BRIDGE_SUBCLASS_PCI_ISA = 0x01,
+              PCI_BRIDGE_SUBCLASS_PCI_EISA = 0x02,
+              PCI_BRIDGE_SUBCLASS_PCI_MICRO = 0x03,
+              PCI_BRIDGE_SUBCLASS_PCI_PCI = 0x04,
+              PCI_BRIDGE_SUBCLASS_PCI_PCMCIA = 0x05,
+              PCI_BRIDGE_SUBCLASS_PCI_NUBUS = 0x06,
+              PCI_BRIDGE_SUBCLASS_PCI_CARDBUS = 0x07,
+              PCI_BRIDGE_SUBCLASS_PCI_OTHER = 0x80 } pci_bridge_subclass_t;
+
+
+
 /*
   struct pci_class_desc {
   uint16_t class;
diff --git a/palacios/include/devices/sym_swap.h b/palacios/include/devices/sym_swap.h
new file mode 100644 (file)
index 0000000..da66f20
--- /dev/null
@@ -0,0 +1,37 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+
+#ifndef __DEVICES_SYM_SWAP_H__
+#define __DEVICES_SYM_SWAP_H__
+
+#ifdef __V3VEE__
+
+#include <palacios/vm_dev.h>
+
+
+
+struct vm_device * v3_create_swap(struct vm_device * virtio_blk);
+
+
+
+#endif
+
+#endif
index 42c98c5..e1a883d 100644 (file)
@@ -269,7 +269,7 @@ struct v3_os_hooks {
 
 
 
-typedef enum {NONE, HARDDRIVE, CDROM} v3_disk_type_t;
+typedef enum {NONE, HARDDRIVE, CDROM, VIRTIO} v3_disk_type_t;
 typedef enum {RAM, NETWORK} v3_disk_connection_t;
 
 union v3_disk_info {
@@ -301,6 +301,8 @@ struct v3_vm_config {
 
     int enable_pci;
 
+    int enable_swap;
+
     v3_disk_type_t pri_disk_type;
     v3_disk_connection_t pri_disk_con;
     union v3_disk_info pri_disk_info;
diff --git a/palacios/src/devices/lnx_virtio_blk.c b/palacios/src/devices/lnx_virtio_blk.c
new file mode 100644 (file)
index 0000000..4e0c14c
--- /dev/null
@@ -0,0 +1,150 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+
+#include <devices/lnx_virtio.h>
+#include <devices/pci.h>
+
+
+
+struct blk_config {
+    uint64_t capacity;
+    uint32_t max_size;
+    uint32_t max_seg;
+    uint16_t cylinders;
+    uint8_t heads;
+    uint8_t sectors;
+} __attribute__((packed));
+
+struct blk_state {
+
+    struct blk_config cfg;
+
+    struct vm_device * pci_bus;
+};
+
+
+
+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;
+}
+
+static int virtio_init(struct vm_device * dev) {
+    struct blk_state * virtio = (struct blk_state *)(dev->private_data);
+
+    PrintDebug("Initializing VIRTIO Block device\n");
+
+    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);
+
+       if (num_ports  & ((num_ports_pow2 >> 1) - 1)) {
+           num_ports_pow2 >>= 1;
+       }
+
+
+       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].io_read = virtio_pci_read;
+       bars[0].io_write = virtio_pci_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);
+
+       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.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.max_latency = 1; // ?? (qemu does it...)
+    }
+
+
+
+    return -1;
+}
+
+static int virtio_deinit(struct vm_device * dev) {
+    return -1;
+}
+
+
+
+static struct vm_device_ops dev_ops = {
+    .init = virtio_init, 
+    .deinit = virtio_deinit,
+    .reset = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+
+struct vm_device * v3_create_virtio(struct vm_device * pci_bus) {
+    struct blk_state * virtio = NULL;
+
+    PrintDebug("Creating VirtIO Block device\n");
+
+    if (pci_bus == NULL) {
+       PrintError("VirtIO requires a PCI bus\n");
+       return NULL;
+    }
+
+
+    virtio = (struct blk_state *)V3_Malloc(sizeof(struct blk_state));
+
+    virtio->pci_bus = pci_bus;
+
+    return v3_create_device("VIRTIO_BLK", &dev_ops, virtio);
+}
index 7beb6dd..d20ad3c 100644 (file)
@@ -78,15 +78,15 @@ static int init_piix3(struct vm_device * dev) {
                                     0, -1, 0, 
                                     "PIIX3", bars, 
                                     NULL, NULL, NULL, dev);
-    if (!pci_dev) {
+    if (pci_dev == NULL) {
        PrintError("Could not register PCI Device for PIIX3\n");
        return -1;
     }
 
     pci_dev->config_header.vendor_id = 0x8086;
     pci_dev->config_header.device_id = 0x7000; // PIIX4 is 0x7001
-    pci_dev->config_header.subclass = 0x01; //  SubClass: host2pci
-    pci_dev->config_header.class = 0x06;    // Class: PCI bridge
+    pci_dev->config_header.class = PCI_CLASS_BRIDGE;
+    pci_dev->config_header.subclass = PCI_BRIDGE_SUBCLASS_PCI_ISA; 
 
     piix3->southbridge_pci = pci_dev;
 
diff --git a/palacios/src/devices/sym_swap.c b/palacios/src/devices/sym_swap.c
new file mode 100644 (file)
index 0000000..706d1c5
--- /dev/null
@@ -0,0 +1,70 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+
+#include <devices/sym_swap.h>
+#include <devices/lnx_virtio.h>
+
+
+
+struct swap_state {
+    
+    struct vm_device * blk_dev;
+
+};
+
+
+static int swap_init(struct vm_device * dev) {
+    return -1;
+}
+
+
+static int swap_deinit(struct vm_device * dev) {
+    return -1;
+}
+
+
+
+static struct vm_device_ops dev_ops = {
+    .init = swap_init, 
+    .deinit = swap_deinit,
+    .reset = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+
+struct vm_device * v3_create_swap(struct vm_device * virtio_blk) {
+    struct swap_state * swap = NULL;
+
+    PrintDebug("Creating Swap Device\n");
+
+    if (virtio_blk == NULL) {
+       PrintError("Swap device requires a virtio block device\n");
+       return NULL;
+    }
+
+    swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state));
+
+    swap->blk_dev = virtio_blk;
+
+    return v3_create_device("SYM_SWAP", &dev_ops, swap);
+}