Skip to contentSkip to conversation

pci: add default pci subsystem id for all devices.

PATCH Applied Gerd Hoffmann 4 participants 6 messages Dec 11, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 pci: add default pci subsystem id for all devices.

Hi,

Has been a while since the last submission. Meanwhile the ID allocation has been sorted and documented (see pci-ids.txt added by the patch), so I hope there are no outstanding issues any more.

please apply,
Gerd

Quoted 1 line

From 2643e6a1314ae23e2d9757d782acc9f75bd22ece Mon Sep 17 00:00:00 2001

From: Gerd Hoffmann <[email protected]>
Date: Tue, 26 Aug 2008 12:34:42 +0200
Subject: [PATCH] pci: add default pci subsystem id for all devices.

This sets a default PCI subsystem ID for all emulated PCI devices. PCI specs require this, so do it.

Some background info:

Each PCI device has a PCI ID. It should also have a PCI Subsystem ID. The PCI subsystem ID wasn't mandatory in early PCI spec revisions, IIRC 2.0 added that requirement. Thats why you usually get away without a PCI subsystem ID, although it isn't correct.

Both IDs have a 16bit vendor and a 16bit device part. The vendor IDs are handed out by the PCI SIG. The device IDs are assigned by the vendor owning the vendor ID.

The PCI ID tells you which PCI chip is used, whereas the the PCI Subsystem ID identifies the actual device (created using the PCI chip).

Example #1: TV cards. All TV cards using the bt878 chipset (first and only one on the market for a few years in the 90-ies) have the same PCI ID, the one of the bt878 chip. But each TV card has different PCI Subsystem IDs, which can be used to figure what the actual TV card is.

Example #2: Laptops. It is quite common to find the PCI Subsytem ID pointing to the laptop vendor and model. So the PCI ID says 'this is a intel ich7 ide controller', whereas the the PCI Subsystem ID says 'this ich7 sits in a lenovo thinkpad', like this:

--------- cut here ----------
[root@zweiblum ~]# lspci -vs1f.1
00:1f.1 IDE interface: Intel Corporation 82801G (ICH7 Family) IDE Controller (rev 02) (prog-if 8a [Master SecP PriP])
Subsystem: Lenovo ThinkPad T60/R60 series
[ ... more stuff snipped ... ]
--------- cut here ----------

In many cases it is enougth to know the PCI ID to handle a device correctly. Sometimes a device driver must identify the exact piece of hardware (via PCI Subsystem ID) though.

What does this patch to qemu devices:

Right now the emulated PCI devices have no PCI subsystem ID, only the PCI ID. The discussed patch sets a default PCI subsystem ID for all emulated devices. Which will make the qemu devices look pretty much like in the laptop case: all PCI subsystem IDs will point to qemu by default.

If a driver emulates a very specific piece of hardware where it has to emulate more than just the PCI chip, it can overwrite the PCI subsystem ID without problems. The es1370 driver does that for example.

---
 hw/pci.c    |   13 +++++++++++++
 hw/pci.h    |   12 ++++++++++++
 pci-ids.txt |   30 ++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 0 deletions(-)
 create mode 100644 pci-ids.txt
hw/pci.c +13 -0
index c48a75e..0689529 100644
@@ -50,6 +50,8 @@ static void pci_update_mappings(PCIDevice *d);
 static void pci_set_irq(void *opaque, int irq_num, int level);
 
 target_phys_addr_t pci_mem_base;
+static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
+static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
 static int pci_irq_index;
 static PCIBus *first_bus;
 
@@ -145,6 +147,16 @@ int pci_device_load(PCIDevice *s, QEMUFile *f)
     return 0;
 }
 
+static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
+{
+    uint16_t *id;
+
+    id = (void*)(&pci_dev->config[PCI_SUBVENDOR_ID]);
+    id[0] = cpu_to_le16(pci_default_sub_vendor_id);
+    id[1] = cpu_to_le16(pci_default_sub_device_id);
+    return 0;
+}
+
 /* -1 for devfn means auto assign */
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,
@@ -171,6 +183,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
     pci_dev->devfn = devfn;
     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
     memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
+    pci_set_default_subsystem_id(pci_dev);
 
     if (!config_read)
         config_read = pci_default_read_config;
hw/pci.h +12 -0
index ae5f8d3..669703e 100644
@@ -8,6 +8,15 @@
 
 extern target_phys_addr_t pci_mem_base;
 
+/* see pci-ids.txt */
+#define PCI_VENDOR_ID_REDHAT_QUMRANET    0x1af4
+#define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
+#define PCI_SUBDEVICE_ID_QEMU            0x1100
+
+#define PCI_DEVICE_ID_VIRTIO_NET         0x1000
+#define PCI_DEVICE_ID_VIRTIO_BLOCK       0x1001
+#define PCI_DEVICE_ID_VIRTIO_BALLOON     0x1002
+
 typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
                                 uint32_t address, uint32_t data, int len);
 typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
@@ -36,7 +45,10 @@ typedef struct PCIIORegion {
 #define PCI_COMMAND		0x04	/* 16 bits */
 #define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
 #define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
+#define PCI_REVISION            0x08
 #define PCI_CLASS_DEVICE        0x0a    /* Device class */
+#define PCI_SUBVENDOR_ID	0x2c	/* 16 bits */
+#define PCI_SUBDEVICE_ID	0x2e	/* 16 bits */
 #define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
 #define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
 #define PCI_MIN_GNT		0x3e	/* 8 bits */
pci-ids.txt new file +30 -0
new file mode 100644
index 0000000..57d8175
@@ -0,0 +1,30 @@
+
+PCI IDs for qemu
+================
+
+Red Hat, Inc. donates a part of its device ID range to qemu, to be used for
+virtual devices.  The vendor ID is 1af4 (formerly Qumranet ID).
+
+The 1000 -> 10ff device ID range is used for VirtIO devices.
+
+The 1100 device ID is used as PCI Subsystem ID for existing hardware
+devices emulated by qemu.
+
+All other device IDs are reserved.
+
+
+VirtIO Device IDs
+-----------------
+
+1af4:1000  network device
+1af4:1001  block device
+1af4:1002  balloon device
+
+1af4:1003  Reserved.
+   to      Contact Gerd Hoffmann <[email protected]> to get a
+1af4:10ef  device ID assigned for your new virtio device.
+
+1af4:10f0  Available for experimental usage without registration.  Must get
+   to      official ID when the code leaves the test lab (i.e. when seeking
+1af4:10ff  upstream merge or shipping a distro/product) to avoid conflicts.
+
Signature · 1 line
1.5.6.5
#1 lore raw

Hi,

Quoted 4 lines · Gerd Hoffmann

Has been a while since the last submission. Meanwhile the ID allocation has been sorted and documented (see pci-ids.txt added by the patch), so I hope there are no outstanding issues any more.

Quoted 8 lines
Quoted 1 line

From 2643e6a1314ae23e2d9757d782acc9f75bd22ece Mon Sep 17 00:00:00 2001

From: Gerd Hoffmann <[email protected]>
Date: Tue, 26 Aug 2008 12:34:42 +0200
Subject: [PATCH] pci: add default pci subsystem id for all devices.

This sets a default PCI subsystem ID for all emulated PCI devices. PCI specs require this, so do it.

I know of lots of recent x86 hardware where the subsystem IDs are not set in hardware, but in the BIOS instead. That allows board vendors to set their own subsystem IDs (usually for chipset devices) in the BIOS even if the hardware is identical to that of other vendors. And since the OS will never see the PCI devices without a valid subsystem ID, I'd say setting the subsystem IDs in the BIOS is spec compliant as well.

Have you investigated setting the subsystem IDs in the Qemu BIOS?

Regards,
Carl-Daniel

Signature · 1 line
http://www.hailfinger.org/
#2 lore raw
Quoted 1 line · Carl-Daniel Hailfinger

Have you investigated setting the subsystem IDs in the Qemu BIOS?

No. Why should I? What would be the advantages of that approach?

cheers,
Gerd

#3 lore raw
Quoted 8 lines · Gerd Hoffmann
Quoted 2 lines · Carl-Daniel Hailfinger

Have you investigated setting the subsystem IDs in the Qemu BIOS?

No. Why should I? What would be the advantages of that approach?

You could set the IDs without having to recompile qemu just by changing the BIOS. I admit that benefit may be debatable. It's just that I wanted you to know about possible alternatives.

Regards,
Carl-Daniel

Signature · 1 line
http://www.hailfinger.org/
#4 lore raw
Quoted 9 lines · Carl-Daniel Hailfinger
Quoted 4 lines · Gerd Hoffmann
Quoted 1 line · Carl-Daniel Hailfinger

Have you investigated setting the subsystem IDs in the Qemu BIOS?

No. Why should I? What would be the advantages of that approach?

You could set the IDs without having to recompile qemu just by changing the BIOS. I admit that benefit may be debatable. It's just that I wanted you to know about possible alternatives.

Doesn't help for the machines that don't have a PCI bios.

Paul

#5 lore raw
In reply to Gerd Hoffmann
Quoted 9 lines · Gerd Hoffmann

Hi,

Has been a while since the last submission. Meanwhile the ID allocation has been sorted and documented (see pci-ids.txt added by the patch), so I hope there are no outstanding issues any more.

please apply,
Gerd

Applied. Thanks. The readme is a nice touch too.

Regards,

Anthony Liguori