WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] PCI subsystem ids

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] PCI subsystem ids
From: Frank van der Linden <Frank.Vanderlinden@xxxxxxx>
Date: Wed, 20 Aug 2008 11:04:02 -0600
Delivery-date: Wed, 20 Aug 2008 10:04:28 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.14 (X11/20080616)
[sorry if you get this twice, I had an email hiccup sending this]

Hi folks,

In our SVVP testing, we noticed that the Microsoft HCT requires that PCI subsystem IDs are set for all PCI devices. Meaning that for Xen to be a compliant virtualization platform, qemu-dm must have these set for all devices.

A comment in tools/ioemu/hw/xen_platform.c notes that this is a known issue, and other source files show that the intent is to use the XenSource ID (0x5853) for the subsystem vendor ID, and 0x0001 for the subsystem id throughout.

But, this isn't done across the board (e.g. the PIIX bridge devices don't have these IDs). This makes the Microsoft HCT fail.

Attached is a patch that makes pci_register_device initialize these values with the 0x5853/0x0001 defaults, and removes the explicit inits of these values in the various devices.

A few issues that are worthy of discussion: since Windows use the subsystem IDs in its device tree, Windows systems will come up with 'found new hardware' after this patch. But, they will just reload the same driver, of course, and live happily ever after. Also, we considered using Sun PCI subsystem IDs (as we do on our actual hardware), but figured that it would be better to use the XenSource ids, so that all Xen-based products out there can use eachothers virtual machines with minimal hassle.

- Frank

Init PCI subsystem IDs consistently.

Store default values for the PCI subsystem IDs (offset 0x2c in config space)
in the PCIBus structure, and propagate them to all devices when they
are registered. Remove all explicit initialization of these values
in the various qemu devices.

Signed-off-by: Frank van der Linden <Frank.Vanderlinden@xxxxxxx>

diff --git a/tools/ioemu/hw/cirrus_vga.c b/tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c
+++ b/tools/ioemu/hw/cirrus_vga.c
@@ -3360,10 +3360,6 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
     pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
     pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
     pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
-    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-    pci_conf[0x2d] = 0x58;
-    pci_conf[0x2e] = 0x01; /* subsystem device */
-    pci_conf[0x2f] = 0x00;
 
     /* setup VGA */
     s = &d->cirrus_vga;
diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c
+++ b/tools/ioemu/hw/ide.c
@@ -2779,10 +2779,6 @@ void pci_piix_ide_init(PCIBus *bus, Bloc
     pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
     pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
     pci_conf[0x0e] = 0x00; // header_type
-    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-    pci_conf[0x2d] = 0x58;
-    pci_conf[0x2e] = 0x01; /* subsystem device */
-    pci_conf[0x2f] = 0x00;
 
     piix3_reset(d);
 
diff --git a/tools/ioemu/hw/ne2000.c b/tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c
+++ b/tools/ioemu/hw/ne2000.c
@@ -834,10 +834,6 @@ void pci_ne2000_init(PCIBus *bus, NICInf
     pci_conf[0x0a] = 0x00; // ethernet network controller 
     pci_conf[0x0b] = 0x02;
     pci_conf[0x0e] = 0x00; // header_type
-    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-    pci_conf[0x2d] = 0x58;
-    pci_conf[0x2e] = 0x01; /* subsystem device */
-    pci_conf[0x2f] = 0x00;
     pci_conf[0x3d] = 1; // interrupt pin 0
     
     pci_register_io_region(&d->dev, 0, 0x100, 
diff --git a/tools/ioemu/hw/pci.c b/tools/ioemu/hw/pci.c
--- a/tools/ioemu/hw/pci.c
+++ b/tools/ioemu/hw/pci.c
@@ -37,6 +37,7 @@ struct PCIBus {
     PCIDevice *devices[256];
     PCIDevice *parent_dev;
     PCIBus *next;
+    uint8_t subsys_config[4];  /* Defaults for devices on this bus */
     /* The bus IRQ state is the logical OR of the connected devices.
        Keep a count of the number of devices with raised IRQs.  */
     int irq_count[];
@@ -47,6 +48,29 @@ target_phys_addr_t pci_mem_base;
 target_phys_addr_t pci_mem_base;
 static int pci_irq_index;
 static PCIBus *first_bus;
+
+void pci_init_bus_subsysid(PCIBus *bus, uint16_t vendor_id, uint16_t device_id)
+{
+    PCIDevice *bd;
+    int i;
+
+    bus->subsys_config[0] = vendor_id & 0xff;
+    bus->subsys_config[1] = vendor_id >> 8;
+    bus->subsys_config[2] = device_id & 0xff;
+    bus->subsys_config[3] = device_id >> 8;
+
+    for (i = bus->devfn_min; i < 256; i++) {
+        bd = bus->devices[i];
+        if (bd == NULL)
+                continue;
+        pci_init_device_subsysid(bus, bd);
+    }
+}
+
+void pci_init_device_subsysid(PCIBus *bus, PCIDevice *d)
+{
+    memcpy(&d->config[0x2c], bus->subsys_config, 4);
+}
 
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *pic, int devfn_min, int nirq)
@@ -69,6 +93,7 @@ PCIBus *pci_register_secondary_bus(PCIDe
     bus->parent_dev = dev;
     bus->next = dev->bus->next;
     dev->bus->next = bus;
+    memcpy(bus->subsys_config,  &dev->config[0x2c], 4);
     return bus;
 }
 
@@ -129,6 +154,7 @@ PCIDevice *pci_register_device(PCIBus *b
     pci_dev->config_write = config_write;
     pci_dev->irq_index = pci_irq_index++;
     bus->devices[devfn] = pci_dev;
+    pci_init_device_subsysid(bus, pci_dev);
     return pci_dev;
 }
 
diff --git a/tools/ioemu/hw/rtl8139.c b/tools/ioemu/hw/rtl8139.c
--- a/tools/ioemu/hw/rtl8139.c
+++ b/tools/ioemu/hw/rtl8139.c
@@ -3449,10 +3449,6 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
     pci_conf[0x0e] = 0x00; /* header_type */
     pci_conf[0x3d] = 1;    /* interrupt pin 0 */
     pci_conf[0x34] = 0xdc;
-    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
-    pci_conf[0x2d] = 0x58;
-    pci_conf[0x2e] = 0x01; /* subsystem device */
-    pci_conf[0x2f] = 0x00;
 
     s = &d->rtl8139;
 
diff --git a/tools/ioemu/hw/xen_platform.c b/tools/ioemu/hw/xen_platform.c
--- a/tools/ioemu/hw/xen_platform.c
+++ b/tools/ioemu/hw/xen_platform.c
@@ -116,8 +116,9 @@ int xen_pci_load(QEMUFile *f, void *opaq
 
 void pci_xen_platform_init(PCIBus *bus)
 {
-    PCIDevice *d;
+    PCIDevice *d, *bd;
     struct pci_config_header *pch;
+    int i;
 
     printf("Register xen platform.\n");
     d = pci_register_device(bus, "xen-platform", sizeof(PCIDevice), -1, NULL,
@@ -133,10 +134,17 @@ void pci_xen_platform_init(PCIBus *bus)
     pch->header_type = 0;
     pch->interrupt_pin = 1;
 
-    /* Microsoft WHQL requires non-zero subsystem IDs. */
-    /* http://www.pcisig.com/reflector/msg02205.html.  */
-    pch->subsystem_vendor_id = pch->vendor_id; /* Duplicate vendor id.  */
-    pch->subsystem_id        = 0x0001;         /* Hardcode sub-id as 1. */
+    /*
+     * Microsoft WHQL requires non-zero subsystem IDs.
+     * http://www.pcisig.com/reflector/msg02205.html.
+     *
+     * Duplicate the XenSource 0x5853,0x0001 ids for all devices
+     * as the default.
+     *
+     * The init function for a device can override this.
+     */
+
+    pci_init_bus_subsysid(bus, pch->vendor_id, pch->device_id);
 
     pci_register_io_region(d, 0, 0x100, PCI_ADDRESS_SPACE_IO,
                            platform_ioport_map);
diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h
--- a/tools/ioemu/vl.h
+++ b/tools/ioemu/vl.h
@@ -831,6 +831,9 @@ void pci_register_io_region(PCIDevice *p
                             uint32_t size, int type, 
                             PCIMapIORegionFunc *map_func);
 
+void pci_init_bus_subsysid(PCIBus *, uint16_t, uint16_t);
+void pci_init_device_subsysid(PCIBus *, PCIDevice *);
+
 void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level);
 
 uint32_t pci_default_read_config(PCIDevice *d, 
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>