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.


PCI updates
Jack Lange [Sat, 14 Mar 2009 05:19:23 +0000 (00:19 -0500)]
palacios/build/Makefile
palacios/include/devices/pci.h
palacios/include/devices/pci_types.h
palacios/src/devices/pci.c
palacios/src/palacios/vmm_config.c

index ed91e6d..d90715c 100644 (file)
@@ -320,7 +320,7 @@ DEVICES_OBJS := \
        devices/os_debug.o \
        devices/apic.o  \
        devices/io_apic.o \
-       devices/vpci.o \
+       devices/pci.o \
        devices/para_net.o \
 
 #      devices/vnic.o \
index a646232..5f58120 100644 (file)
@@ -61,10 +61,8 @@ struct pci_device {
 
 struct vm_device * v3_create_pci();
 
-struct pci_bus * v3_get_pcibus(struct guest_info *vm, int bus_no);
-
 struct pci_device * 
-v3_pci_register_device(struct vm_device * dev,
+v3_pci_register_device(struct vm_device * pci,
                       uint_t bus_num,
                       const char * name,
                       int dev_num,
index 05fcf1c..2f6882d 100644 (file)
@@ -138,51 +138,49 @@ struct pci_config_header {
 
 
 /*
-struct pci_class_desc {
-    uint16_t class;
-    const char * desc;
-};
-
-static struct pci_class_desc pci_class_descriptions[] = {
-    { 0x0100, "SCSI controller"},
-    { 0x0101, "IDE controller"},
-    { 0x0102, "Floppy controller"},
-    { 0x0103, "IPI controller"},
-    { 0x0104, "RAID controller"},
-    { 0x0106, "SATA controller"},
-    { 0x0107, "SAS controller"},
-    { 0x0180, "Storage controller"},
-    { 0x0200, "Ethernet controller"},
-    { 0x0201, "Token Ring controller"},
-    { 0x0202, "FDDI controller"},
-    { 0x0203, "ATM controller"},
-    { 0x0280, "Network controller"},
-    { 0x0300, "VGA controller"},
-    { 0x0301, "XGA controller"},
-    { 0x0302, "3D controller"},
-    { 0x0380, "Display controller"},
-    { 0x0400, "Video controller"},
-    { 0x0401, "Audio controller"},
-    { 0x0402, "Phone"},
-    { 0x0480, "Multimedia controller"},
-    { 0x0500, "RAM controller"},
-    { 0x0501, "Flash controller"},
-    { 0x0580, "Memory controller"},
-    { 0x0600, "Host bridge"},
-    { 0x0601, "ISA bridge"},
-    { 0x0602, "EISA bridge"},
-    { 0x0603, "MC bridge"},
-    { 0x0604, "PCI bridge"},
-    { 0x0605, "PCMCIA bridge"},
-    { 0x0606, "NUBUS bridge"},
-    { 0x0607, "CARDBUS bridge"},
-    { 0x0608, "RACEWAY bridge"},
-    { 0x0680, "Bridge"},
-    { 0x0c03, "USB controller"},
-    { 0, NULL}
-};
-
-
+  struct pci_class_desc {
+  uint16_t class;
+  const char * desc;
+  };
+  
+  static struct pci_class_desc pci_class_descriptions[] = {
+  { 0x0100, "SCSI controller"},
+  { 0x0101, "IDE controller"},
+  { 0x0102, "Floppy controller"},
+  { 0x0103, "IPI controller"},
+  { 0x0104, "RAID controller"},
+  { 0x0106, "SATA controller"},
+  { 0x0107, "SAS controller"},
+  { 0x0180, "Storage controller"},
+  { 0x0200, "Ethernet controller"},
+  { 0x0201, "Token Ring controller"},
+  { 0x0202, "FDDI controller"},
+  { 0x0203, "ATM controller"},
+  { 0x0280, "Network controller"},
+  { 0x0300, "VGA controller"},
+  { 0x0301, "XGA controller"},
+  { 0x0302, "3D controller"},
+  { 0x0380, "Display controller"},
+  { 0x0400, "Video controller"},
+  { 0x0401, "Audio controller"},
+  { 0x0402, "Phone"},
+  { 0x0480, "Multimedia controller"},
+  { 0x0500, "RAM controller"},
+  { 0x0501, "Flash controller"},
+  { 0x0580, "Memory controller"},
+  { 0x0600, "Host bridge"},
+  { 0x0601, "ISA bridge"},
+  { 0x0602, "EISA bridge"},
+  { 0x0603, "MC bridge"},
+  { 0x0604, "PCI bridge"},
+  { 0x0605, "PCMCIA bridge"},
+  { 0x0606, "NUBUS bridge"},
+  { 0x0607, "CARDBUS bridge"},
+  { 0x0608, "RACEWAY bridge"},
+  { 0x0680, "Bridge"},
+  { 0x0c03, "USB controller"},
+  { 0, NULL}
+  };
 */
 
 #endif
index 44b0e9c..148a038 100644 (file)
@@ -227,14 +227,30 @@ static int write_pci_header(struct pci_device * pci_dev, int reg_num, void * src
 
 static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
     struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
-    
-    if (length != 4) {
+    int reg_offset = port & 0x3;
+    uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
+
+    PrintDebug("Reading PCI Address Port (%x): %x\n", port, pci_state->addr_reg.val);
+
+    if (length == 4) {
+       if (reg_offset != 0) {
+           PrintError("Invalid Address Port Read\n");
+           return -1;
+       }
+       *(uint32_t *)dst = *(uint32_t *)reg_addr;
+    } else if (length == 2) {
+       if (reg_offset > 2) {
+           PrintError("Invalid Address Port Read\n");
+           return -1;
+       }
+       *(uint16_t *)dst = *(uint16_t *)reg_addr;
+    } else if (length == 1) {
+       *(uint8_t *)dst = *(uint8_t *)reg_addr;
+    } else {
        PrintError("Invalid read length (%d) for PCI address register\n", length);
        return -1;
     }
     
-    PrintDebug("Reading PCI Address Port: %x\n", pci_state->addr_reg.val);
-    *(uint32_t *)dst = pci_state->addr_reg.val;
 
     return length;
 }
@@ -242,14 +258,32 @@ static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_de
 
 static int addr_port_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
     struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
+    int reg_offset = port & 0x3; 
+    uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
 
-    if (length != 4) {
+    if (length == 4) {
+       if (reg_offset != 0) {
+           PrintError("Invalid Address Port Write\n");
+           return -1;
+       }
+
+       *(uint32_t *)reg_addr = *(uint32_t *)src;
+    } else if (length == 2) {
+       if (reg_offset > 2) {
+           PrintError("Invalid Address Port Write\n");
+           return -1;
+       }
+
+       *(uint16_t *)reg_addr = *(uint16_t *)src;
+    } else if (length == 1) {
+       *(uint8_t *)reg_addr = *(uint8_t *)src;
+    } else {
        PrintError("Invalid write length (%d) for PCI address register\n", length);
        return -1;
     }
 
-    pci_state->addr_reg.val = *(uint32_t *)src;
-    PrintDebug("Writing PCI Address Port: %x\n", pci_state->addr_reg.val);    
+    PrintDebug("Writing PCI Address Port(%x): %x\n", port, pci_state->addr_reg.val);    
+
 
     return length;
 }
@@ -267,6 +301,11 @@ static int data_port_read(ushort_t port, void * dst, uint_t length, struct vm_de
               reg_num);
 
     
+    if (port != CONFIG_DATA_PORT) {
+       PrintError("Weird Data port Read: %x\n", port);
+       return -1;
+    }
+
     pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num);
     
     if (pci_dev == NULL) {
@@ -314,6 +353,12 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d
               pci_state->addr_reg.dev_num, 
               reg_num);
 
+    if (port != CONFIG_DATA_PORT) {
+       PrintError("Weird Data port Write: %x\n", port);
+       return -1;
+    }
+
+
     pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num);
     
     if (pci_dev == NULL) {
@@ -382,23 +427,22 @@ static int pci_deinit_device(struct vm_device * dev) {
 
 
 
-static int init_i440fx(struct pci_internal * pci_state) {
-
-    struct pci_device * dev = v3_pci_register_device(NULL, 0, "i440FX", 0, 
-                                                    NULL, NULL, NULL, NULL);
+static int init_i440fx(struct vm_device * dev) {
+    struct pci_device * pci_dev = v3_pci_register_device(dev, 0, "i440FX", 0, 
+                                                        NULL, NULL, NULL, NULL);
     
-    if (!dev) {
+    if (!pci_dev) {
        return -1;
     }
     
-    dev->header.vendor_id = 0x8086;
-    dev->header.device_id = 0x1237;
-    dev->header.revision = 0x0002;
-    dev->header.subclass = 0x00; //  SubClass: host2pci
-    dev->header.class = 0x06;    // Class: PCI bridge
-    dev->header.header_type = 0x00;
-
-    dev->bus_num = 0;
+    pci_dev->header.vendor_id = 0x8086;
+    pci_dev->header.device_id = 0x1237;
+    pci_dev->header.revision = 0x0002;
+    pci_dev->header.subclass = 0x00; //  SubClass: host2pci
+    pci_dev->header.class = 0x06;    // Class: PCI bridge
+    pci_dev->header.header_type = 0x00;
+
+    pci_dev->bus_num = 0;
     
     return 0;
 }
@@ -430,7 +474,7 @@ static int pci_init_device(struct vm_device * dev) {
 
     init_pci_busses(pci_state);
 
-    if (init_i440fx(pci_state) == -1) {
+    if (init_i440fx(dev) == -1) {
        PrintError("Could not intialize i440fx\n");
        return -1;
     }
@@ -467,30 +511,8 @@ struct vm_device * v3_create_pci() {
 
 
 
-/* JRL: TODO This needs to be completely rethought... */
-struct pci_bus * v3_get_pcibus(struct guest_info * vm, int bus_no) {
-    //    struct pci_internal * pci_state = NULL;
-
-    /*
-      if (vm->pci == NULL) {
-      PrintError("There is no PCI bus in guest %p\n", vm);
-      return NULL;
-      }
-      
-      pci_state = (struct pci_internal *)vm->pci->private_data;
-      
-      if ((bus_no >= 0) && (bus_no < PCI_BUS_COUNT)) {
-      return &(pci_state->bus_list[bus_no]);
-      }
-    */
-    return NULL;
-}
-
-
-
-
 // if dev_num == -1, auto assign 
-struct pci_device * v3_pci_register_device(struct vm_device * dev,
+struct pci_device * v3_pci_register_device(struct vm_device * pci,
                                           uint_t bus_num,
                                           const char * name,
                                           int dev_num,
@@ -499,7 +521,7 @@ struct pci_device * v3_pci_register_device(struct vm_device * dev,
                                           int (*bar_update)(struct pci_device * pci_dev, uint_t bar_reg, uint32_t val),
                                           void * private_data) {
 
-    struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
+    struct pci_internal * pci_state = (struct pci_internal *)pci->private_data;
     struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
     struct pci_device * pci_dev = NULL;
 
@@ -535,7 +557,7 @@ struct pci_device * v3_pci_register_device(struct vm_device * dev,
     pci_dev->dev_num = dev_num;
 
     strncpy(pci_dev->name, name, sizeof(pci_dev->name));
-    pci_dev->vm_dev = dev;
+    pci_dev->vm_dev = pci;
 
     pci_dev->config_read = config_read;
     pci_dev->config_write = config_write;
index db9aa8b..9c8d73a 100644 (file)
@@ -40,6 +40,7 @@
 #include <devices/apic.h>
 #include <devices/io_apic.h>
 #include <devices/para_net.h>
+#include <devices/pci.h>
 
 
 
@@ -278,6 +279,7 @@ static int setup_memory_map(struct guest_info * info, struct v3_vm_config * conf
 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
     struct vm_device * ramdisk = NULL;
     struct vm_device * cdrom = NULL;
+    struct vm_device * pci = v3_create_pci();
     struct vm_device * nvram = v3_create_nvram();
     //struct vm_device * timer = v3_create_timer();
     struct vm_device * pic = v3_create_pic();
@@ -307,6 +309,7 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
        generic = configure_generic(info, config_ptr);
     }
 
+    v3_attach_device(info, pci);
 
     v3_attach_device(info, nvram);
     //v3_attach_device(info, timer);