aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/virtio-9p-device.c10
-rw-r--r--hw/ac97.c9
-rw-r--r--hw/acpi_piix4.c8
-rw-r--r--hw/apb_pci.c13
-rw-r--r--hw/bonito.c9
-rw-r--r--hw/cirrus_vga.c15
-rw-r--r--hw/dec_pci.c26
-rw-r--r--hw/e1000.c8
-rw-r--r--hw/eepro100.c74
-rw-r--r--hw/es1370.c24
-rw-r--r--hw/grackle_pci.c8
-rw-r--r--hw/gt64xxx.c8
-rw-r--r--hw/hw.h3
-rw-r--r--hw/ide/cmd646.c10
-rw-r--r--hw/ide/ich.c11
-rw-r--r--hw/ide/piix.c32
-rw-r--r--hw/ide/via.c8
-rw-r--r--hw/intel-hda.c8
-rw-r--r--hw/ioh3420.c7
-rw-r--r--hw/ivshmem.c8
-rw-r--r--hw/lsi53c895a.c15
-rw-r--r--hw/msi.c2
-rw-r--r--hw/msix.c40
-rw-r--r--hw/ne2000.c6
-rw-r--r--hw/pc.h1
-rw-r--r--hw/pc_piix.c58
-rw-r--r--hw/pci.c56
-rw-r--r--hw/pci.h7
-rw-r--r--hw/pci_ids.h2
-rw-r--r--hw/pci_regs.h60
-rw-r--r--hw/pcie_aer.c9
-rw-r--r--hw/pcnet-pci.c8
-rw-r--r--hw/piix4.c10
-rw-r--r--hw/piix_pci.c85
-rw-r--r--hw/ppce500_pci.c13
-rw-r--r--hw/qxl.c7
-rw-r--r--hw/rtl8139.c8
-rw-r--r--hw/sh_pci.c4
-rw-r--r--hw/sun4u.c8
-rw-r--r--hw/syborg_virtio.c4
-rw-r--r--hw/unin_pci.c33
-rw-r--r--hw/usb-ehci.c9
-rw-r--r--hw/usb-ohci.c7
-rw-r--r--hw/usb-uhci.c46
-rw-r--r--hw/versatile_pci.c8
-rw-r--r--hw/vga-pci.c11
-rw-r--r--hw/vhost_net.c8
-rw-r--r--hw/virtio-pci.c66
-rw-r--r--hw/virtio-pci.h8
-rw-r--r--hw/virtio.c97
-rw-r--r--hw/virtio.h9
-rw-r--r--hw/vmware_vga.c13
-rw-r--r--hw/vt82c686.c35
-rw-r--r--hw/wdt_i6300esb.c9
-rw-r--r--hw/xen_common.h14
-rw-r--r--hw/xen_platform.c340
-rw-r--r--hw/xio3130_downstream.c6
-rw-r--r--hw/xio3130_upstream.c6
58 files changed, 954 insertions, 473 deletions
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index a2b6acc408..f235236ea0 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -142,11 +142,7 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
vdev->nvectors = proxy->nvectors;
- virtio_init_pci(proxy, vdev,
- PCI_VENDOR_ID_REDHAT_QUMRANET,
- 0x1009,
- 0x2,
- 0x00);
+ virtio_init_pci(proxy, vdev);
/* make the actual value visible */
proxy->nvectors = vdev->nvectors;
return 0;
@@ -156,6 +152,10 @@ static PCIDeviceInfo virtio_9p_info = {
.qdev.name = "virtio-9p-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_9p_init_pci,
+ .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+ .device_id = 0x1009,
+ .revision = VIRTIO_PCI_ABI_VERSION,
+ .class_id = 0x2,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
diff --git a/hw/ac97.c b/hw/ac97.c
index a946c1a56a..0b59896fbb 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1277,9 +1277,6 @@ static int ac97_initfn (PCIDevice *dev)
AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev);
uint8_t *c = s->dev.config;
- pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */
- pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */
-
/* TODO: no need to override */
c[PCI_COMMAND] = 0x00; /* pcicmd pci command rw, ro */
c[PCI_COMMAND + 1] = 0x00;
@@ -1288,9 +1285,7 @@ static int ac97_initfn (PCIDevice *dev)
c[PCI_STATUS] = PCI_STATUS_FAST_BACK; /* pcists pci status rwc, ro */
c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
- c[PCI_REVISION_ID] = 0x01; /* rid revision ro */
c[PCI_CLASS_PROG] = 0x00; /* pi programming interface ro */
- pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO); /* ro */
/* TODO set when bar is registered. no need to override. */
/* nabmar native audio mixer base address rw */
@@ -1337,6 +1332,10 @@ static PCIDeviceInfo ac97_info = {
.qdev.size = sizeof (AC97LinkState),
.qdev.vmsd = &vmstate_ac97,
.init = ac97_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801AA_5,
+ .revision = 0x01,
+ .class_id = PCI_CLASS_MULTIMEDIA_AUDIO,
};
static void ac97_register (void)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 6c908ff00b..350558b859 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -317,13 +317,9 @@ static int piix4_pm_initfn(PCIDevice *dev)
uint8_t *pci_conf;
pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3);
pci_conf[0x06] = 0x80;
pci_conf[0x07] = 0x02;
- pci_conf[0x08] = 0x03; // revision number
pci_conf[0x09] = 0x00;
- pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
pci_conf[0x3d] = 0x01; // interrupt pin 1
pci_conf[0x40] = 0x01; /* PM io base read only bit */
@@ -394,6 +390,10 @@ static PCIDeviceInfo piix4_pm_info = {
.no_hotplug = 1,
.init = piix4_pm_initfn,
.config_write = pm_write_config,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371AB_3,
+ .revision = 0x03,
+ .class_id = PCI_CLASS_BRIDGE_OTHER,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 84e9af76a2..974c87a8ce 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -304,9 +304,6 @@ static int apb_pci_bridge_initfn(PCIDevice *dev)
return rc;
}
- pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_SUN);
- pci_config_set_device_id(dev->config, PCI_DEVICE_ID_SUN_SIMBA);
-
/*
* command register:
* According to PCI bridge spec, after reset
@@ -321,7 +318,6 @@ static int apb_pci_bridge_initfn(PCIDevice *dev)
pci_set_word(dev->config + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
PCI_STATUS_DEVSEL_MEDIUM);
- pci_set_byte(dev->config + PCI_REVISION_ID, 0x11);
return 0;
}
@@ -436,14 +432,11 @@ static int pci_pbm_init_device(SysBusDevice *dev)
static int pbm_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
pci_set_word(d->config + PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
pci_set_word(d->config + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
PCI_STATUS_DEVSEL_MEDIUM);
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
return 0;
}
@@ -451,6 +444,9 @@ static PCIDeviceInfo pbm_pci_host_info = {
.qdev.name = "pbm",
.qdev.size = sizeof(PCIDevice),
.init = pbm_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_SUN,
+ .device_id = PCI_DEVICE_ID_SUN_SABRE,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
.is_bridge = 1,
};
@@ -468,6 +464,9 @@ static PCIDeviceInfo pbm_pci_bridge_info = {
.qdev.reset = pci_bridge_reset,
.init = apb_pci_bridge_initfn,
.exit = pci_bridge_exitfn,
+ .vendor_id = PCI_VENDOR_ID_SUN,
+ .device_id = PCI_DEVICE_ID_SUN_SIMBA,
+ .revision = 0x11,
.config_write = pci_bridge_write_config,
.is_bridge = 1,
};
diff --git a/hw/bonito.c b/hw/bonito.c
index 65a4a637bf..e8c57a36ff 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -691,11 +691,7 @@ static int bonito_initfn(PCIDevice *dev)
PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev);
/* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */
- pci_config_set_vendor_id(dev->config, 0xdf53);
- pci_config_set_device_id(dev->config, 0x00d5);
- pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST);
pci_config_set_prog_interface(dev->config, 0x00);
- pci_config_set_revision(dev->config, 0x01);
/* set the north bridge register mapping */
s->bonito_reg_handle = cpu_register_io_memory(bonito_read, bonito_write, s,
@@ -796,6 +792,11 @@ static PCIDeviceInfo bonito_info = {
.qdev.vmsd = &vmstate_bonito,
.qdev.no_user = 1,
.init = bonito_initfn,
+ /*Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined"*/
+ .vendor_id = 0xdf53,
+ .device_id = 0x00d5,
+ .revision = 0x01,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static SysBusDeviceInfo bonito_pcihost_info = {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 722cac7544..f39d1f82ff 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3088,8 +3088,11 @@ static void pci_cirrus_write_config(PCIDevice *d,
CirrusVGAState *s = &pvs->cirrus_vga;
pci_default_write_config(d, address, val, len);
- if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED)
+ if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
s->vga.map_addr = 0;
+ s->vga.lfb_addr = 0;
+ s->vga.lfb_end = 0;
+ }
cirrus_update_memory_access(s);
}
@@ -3097,8 +3100,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
{
PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
CirrusVGAState *s = &d->cirrus_vga;
- uint8_t *pci_conf = d->dev.config;
- int device_id = CIRRUS_ID_CLGD5446;
+ PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->qdev.info);
+ int16_t device_id = info->device_id;
/* setup VGA */
vga_common_init(&s->vga, VGA_RAM_SIZE);
@@ -3108,9 +3111,6 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
&s->vga);
/* setup PCI */
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS);
- pci_config_set_device_id(pci_conf, device_id);
- pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
/* setup memory space */
/* memory #0 LFB */
@@ -3139,6 +3139,9 @@ static PCIDeviceInfo cirrus_vga_info = {
.init = pci_cirrus_vga_initfn,
.romfile = VGABIOS_CIRRUS_FILENAME,
.config_write = pci_cirrus_write_config,
+ .vendor_id = PCI_VENDOR_ID_CIRRUS,
+ .device_id = CIRRUS_ID_CLGD5446,
+ .class_id = PCI_CLASS_DISPLAY_VGA,
};
static void cirrus_vga_register(void)
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index bf88f2ac80..a35f382052 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -50,28 +50,16 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
return irq_num;
}
-static int dec_21154_initfn(PCIDevice *dev)
-{
- int rc;
-
- rc = pci_bridge_initfn(dev);
- if (rc < 0) {
- return rc;
- }
-
- pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_DEC);
- pci_config_set_device_id(dev->config, PCI_DEVICE_ID_DEC_21154);
- return 0;
-}
-
static PCIDeviceInfo dec_21154_pci_bridge_info = {
.qdev.name = "dec-21154-p2p-bridge",
.qdev.desc = "DEC 21154 PCI-PCI bridge",
.qdev.size = sizeof(PCIBridge),
.qdev.vmsd = &vmstate_pci_device,
.qdev.reset = pci_bridge_reset,
- .init = dec_21154_initfn,
+ .init = pci_bridge_initfn,
.exit = pci_bridge_exitfn,
+ .vendor_id = PCI_VENDOR_ID_DEC,
+ .device_id = PCI_DEVICE_ID_DEC_21154,
.config_write = pci_bridge_write_config,
.is_bridge = 1,
};
@@ -108,10 +96,6 @@ static int pci_dec_21154_init_device(SysBusDevice *dev)
static int dec_21154_pci_host_init(PCIDevice *d)
{
/* PCI2PCI bridge same values as PearPC - check this */
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154);
- pci_set_byte(d->config + PCI_REVISION_ID, 0x02);
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI);
return 0;
}
@@ -119,6 +103,10 @@ static PCIDeviceInfo dec_21154_pci_host_info = {
.qdev.name = "dec-21154",
.qdev.size = sizeof(PCIDevice),
.init = dec_21154_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_DEC,
+ .device_id = PCI_DEVICE_ID_DEC_21154,
+ .revision = 0x02,
+ .class_id = PCI_CLASS_BRIDGE_PCI,
.is_bridge = 1,
};
diff --git a/hw/e1000.c b/hw/e1000.c
index f160bfc2ab..96d84f91ae 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1164,12 +1164,8 @@ static int pci_e1000_init(PCIDevice *pci_dev)
pci_conf = d->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, E1000_DEVID);
/* TODO: we have no capabilities, so why is this bit set? */
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST);
- pci_conf[PCI_REVISION_ID] = 0x03;
- pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
/* TODO: RST# value should be 0, PCI spec 6.2.4 */
pci_conf[PCI_CACHE_LINE_SIZE] = 0x10;
@@ -1221,6 +1217,10 @@ static PCIDeviceInfo e1000_info = {
.init = pci_e1000_init,
.exit = pci_e1000_uninit,
.romfile = "pxe-e1000.rom",
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = E1000_DEVID,
+ .revision = 0x03,
+ .class_id = PCI_CLASS_NETWORK_ETHERNET,
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(E1000State, conf),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 9f16efd365..9b6f4a5cd8 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -129,8 +129,6 @@
typedef struct {
PCIDeviceInfo pci;
uint32_t device;
- uint16_t device_id;
- uint8_t revision;
uint8_t stats_size;
bool has_extended_tcb_support;
bool power_management;
@@ -526,16 +524,9 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
TRACE(OTHER, logout("%p\n", s));
- /* PCI Vendor ID */
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- /* PCI Device ID */
- pci_config_set_device_id(pci_conf, e100_device->device_id);
/* PCI Status */
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
PCI_STATUS_FAST_BACK);
- /* PCI Revision ID */
- pci_config_set_revision(pci_conf, e100_device->revision);
- pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
/* PCI Latency Timer */
pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20); /* latency timer = 32 clocks */
/* Capability Pointer is set by PCI framework. */
@@ -563,12 +554,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
case i82559ER:
case i82562:
case i82801:
- break;
case i82559C:
-#if EEPROM_SIZE > 0
- pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_INTEL);
- pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0040);
-#endif
break;
default:
logout("Device %X is undefined!\n", device);
@@ -2040,9 +2026,9 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.desc = "Intel i82550 Ethernet",
.device = i82550,
/* TODO: check device id. */
- .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
/* Revision ID: 0x0c, 0x0d, 0x0e. */
- .revision = 0x0e,
+ .pci.revision = 0x0e,
/* TODO: check size of statistical counters. */
.stats_size = 80,
/* TODO: check extended tcb support. */
@@ -2052,9 +2038,9 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82551",
.pci.qdev.desc = "Intel i82551 Ethernet",
.device = i82551,
- .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
/* Revision ID: 0x0f, 0x10. */
- .revision = 0x0f,
+ .pci.revision = 0x0f,
/* TODO: check size of statistical counters. */
.stats_size = 80,
.has_extended_tcb_support = true,
@@ -2063,29 +2049,29 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82557a",
.pci.qdev.desc = "Intel i82557A Ethernet",
.device = i82557A,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x01,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x01,
.power_management = false,
},{
.pci.qdev.name = "i82557b",
.pci.qdev.desc = "Intel i82557B Ethernet",
.device = i82557B,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x02,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x02,
.power_management = false,
},{
.pci.qdev.name = "i82557c",
.pci.qdev.desc = "Intel i82557C Ethernet",
.device = i82557C,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x03,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x03,
.power_management = false,
},{
.pci.qdev.name = "i82558a",
.pci.qdev.desc = "Intel i82558A Ethernet",
.device = i82558A,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x04,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x04,
.stats_size = 76,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2093,8 +2079,8 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82558b",
.pci.qdev.desc = "Intel i82558B Ethernet",
.device = i82558B,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x05,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x05,
.stats_size = 76,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2102,8 +2088,8 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82559a",
.pci.qdev.desc = "Intel i82559A Ethernet",
.device = i82559A,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x06,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x06,
.stats_size = 80,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2111,8 +2097,8 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82559b",
.pci.qdev.desc = "Intel i82559B Ethernet",
.device = i82559B,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
- .revision = 0x07,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.revision = 0x07,
.stats_size = 80,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2120,12 +2106,16 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82559c",
.pci.qdev.desc = "Intel i82559C Ethernet",
.device = i82559C,
- .device_id = PCI_DEVICE_ID_INTEL_82557,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
#if 0
- .revision = 0x08,
+ .pci.revision = 0x08,
#endif
/* TODO: Windows wants revision id 0x0c. */
- .revision = 0x0c,
+ .pci.revision = 0x0c,
+#if EEPROM_SIZE > 0
+ .pci.subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
+ .pci.subsystem_id = 0x0040,
+#endif
.stats_size = 80,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2133,8 +2123,8 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82559er",
.pci.qdev.desc = "Intel i82559ER Ethernet",
.device = i82559ER,
- .device_id = PCI_DEVICE_ID_INTEL_82551IT,
- .revision = 0x09,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+ .pci.revision = 0x09,
.stats_size = 80,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2143,9 +2133,9 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.desc = "Intel i82562 Ethernet",
.device = i82562,
/* TODO: check device id. */
- .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+ .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
/* TODO: wrong revision id. */
- .revision = 0x0e,
+ .pci.revision = 0x0e,
.stats_size = 80,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2154,8 +2144,8 @@ static E100PCIDeviceInfo e100_devices[] = {
.pci.qdev.name = "i82801",
.pci.qdev.desc = "Intel i82801 Ethernet",
.device = i82801,
- .device_id = 0x2449,
- .revision = 0x03,
+ .pci.device_id = 0x2449,
+ .pci.revision = 0x03,
.stats_size = 80,
.has_extended_tcb_support = true,
.power_management = true,
@@ -2174,6 +2164,8 @@ static void eepro100_register_devices(void)
PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
/* We use the same rom file for all device ids.
QEMU fixes the device id during rom load. */
+ pci_dev->vendor_id = PCI_VENDOR_ID_INTEL;
+ pci_dev->class_id = PCI_CLASS_NETWORK_ETHERNET;
pci_dev->romfile = "pxe-eepro100.rom";
pci_dev->init = e100_nic_init;
pci_dev->exit = pci_nic_uninit;
diff --git a/hw/es1370.c b/hw/es1370.c
index 40cb48cbb8..1ed62b7da3 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -998,21 +998,9 @@ static int es1370_initfn (PCIDevice *dev)
ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
uint8_t *c = s->dev.config;
- pci_config_set_vendor_id (c, PCI_VENDOR_ID_ENSONIQ);
- pci_config_set_device_id (c, PCI_DEVICE_ID_ENSONIQ_ES1370);
c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_SLOW >> 8;
- pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO);
-#if 1
- c[PCI_SUBSYSTEM_VENDOR_ID] = 0x42;
- c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x49;
- c[PCI_SUBSYSTEM_ID] = 0x4c;
- c[PCI_SUBSYSTEM_ID + 1] = 0x4c;
-#else
- c[PCI_SUBSYSTEM_VENDOR_ID] = 0x74;
- c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x12;
- c[PCI_SUBSYSTEM_ID] = 0x71;
- c[PCI_SUBSYSTEM_ID + 1] = 0x13;
+#if 0
c[PCI_CAPABILITY_LIST] = 0xdc;
c[PCI_INTERRUPT_LINE] = 10;
c[0xdc] = 0x00;
@@ -1043,6 +1031,16 @@ static PCIDeviceInfo es1370_info = {
.qdev.size = sizeof (ES1370State),
.qdev.vmsd = &vmstate_es1370,
.init = es1370_initfn,
+ .vendor_id = PCI_VENDOR_ID_ENSONIQ,
+ .device_id = PCI_DEVICE_ID_ENSONIQ_ES1370,
+ .class_id = PCI_CLASS_MULTIMEDIA_AUDIO,
+#if 1
+ .subsystem_vendor_id = 0x4942,
+ .subsystem_id = 0x4c4c,
+#else
+ .subsystem_vendor_id = 0x1274,
+ .subsystem_id = 0x1371,
+#endif
};
static void es1370_register (void)
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index d35701f4a5..cee07e06c7 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -104,11 +104,7 @@ static int pci_grackle_init_device(SysBusDevice *dev)
static int grackle_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_MPC106);
- d->config[0x08] = 0x00; // revision
d->config[0x09] = 0x01;
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
return 0;
}
@@ -116,6 +112,10 @@ static PCIDeviceInfo grackle_pci_host_info = {
.qdev.name = "grackle",
.qdev.size = sizeof(PCIDevice),
.init = grackle_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_MOTOROLA,
+ .device_id = PCI_DEVICE_ID_MOTOROLA_MPC106,
+ .revision = 0x00,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static void grackle_register_devices(void)
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index c66188f40e..8e1f6a069d 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1118,14 +1118,10 @@ static int gt64120_init(SysBusDevice *dev)
static int gt64120_pci_init(PCIDevice *d)
{
/* FIXME: Malta specific hw assumptions ahead */
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MARVELL);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_MARVELL_GT6412X);
pci_set_word(d->config + PCI_COMMAND, 0);
pci_set_word(d->config + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
- pci_set_byte(d->config + PCI_CLASS_REVISION, 0x10);
pci_config_set_prog_interface(d->config, 0);
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
pci_set_long(d->config + PCI_BASE_ADDRESS_0, 0x00000008);
pci_set_long(d->config + PCI_BASE_ADDRESS_1, 0x01000008);
pci_set_long(d->config + PCI_BASE_ADDRESS_2, 0x1c000000);
@@ -1141,6 +1137,10 @@ static PCIDeviceInfo gt64120_pci_info = {
.qdev.name = "gt64120_pci",
.qdev.size = sizeof(PCIDevice),
.init = gt64120_pci_init,
+ .vendor_id = PCI_VENDOR_ID_MARVELL,
+ .device_id = PCI_DEVICE_ID_MARVELL_GT6412X,
+ .revision = 0x10,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static void gt64120_pci_register_devices(void)
diff --git a/hw/hw.h b/hw/hw.h
index 56447a735d..9dd7096fc2 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -780,6 +780,9 @@ extern const VMStateDescription vmstate_ptimer;
#define VMSTATE_INT32_LE(_f, _s) \
VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
+#define VMSTATE_UINT8_TEST(_f, _s, _t) \
+ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
+
#define VMSTATE_UINT16_TEST(_f, _s, _t) \
VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 5d5464ae83..56302b5060 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -226,14 +226,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
qemu_irq *irq;
int i;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646);
-
- pci_conf[PCI_REVISION_ID] = 0x07; // IDE controller revision
pci_conf[PCI_CLASS_PROG] = 0x8f;
- pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
-
pci_conf[0x51] = 0x04; // enable IDE0
if (d->secondary) {
/* XXX: if not enabled, really disable the seconday IDE controller */
@@ -282,6 +276,10 @@ static PCIDeviceInfo cmd646_ide_info[] = {
.qdev.name = "cmd646-ide",
.qdev.size = sizeof(PCIIDEState),
.init = pci_cmd646_ide_initfn,
+ .vendor_id = PCI_VENDOR_ID_CMD,
+ .device_id = PCI_DEVICE_ID_CMD_646,
+ .revision = 0x07, // IDE controller revision
+ .class_id = PCI_CLASS_STORAGE_IDE,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 6150ce3343..054e0734e4 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -77,11 +77,8 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
struct AHCIPCIState *d;
d = DO_UPCAST(struct AHCIPCIState, card, dev);
- pci_config_set_vendor_id(d->card.config, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(d->card.config, PCI_DEVICE_ID_INTEL_82801IR);
+ ahci_init(&d->ahci, &dev->qdev, 6);
- pci_config_set_class(d->card.config, PCI_CLASS_STORAGE_SATA);
- pci_config_set_revision(d->card.config, 0x02);
pci_config_set_prog_interface(d->card.config, AHCI_PROGMODE_MAJOR_REV_1);
d->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
@@ -94,8 +91,6 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
qemu_register_reset(ahci_reset, d);
msi_init(dev, 0x50, 1, true, false);
-
- ahci_init(&d->ahci, &dev->qdev, 6);
d->ahci.irq = d->card.irq[0];
/* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
@@ -131,6 +126,10 @@ static PCIDeviceInfo ich_ahci_info[] = {
.init = pci_ich9_ahci_init,
.exit = pci_ich9_uninit,
.config_write = pci_ich9_write_config,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801IR,
+ .revision = 0x02,
+ .class_id = PCI_CLASS_STORAGE_SATA,
},{
/* end of list */
}
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c3496448c3..84f72b0a66 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -131,12 +131,12 @@ static void pci_piix_init_ports(PCIIDEState *d) {
}
}
-static int pci_piix_ide_initfn(PCIIDEState *d)
+static int pci_piix_ide_initfn(PCIDevice *dev)
{
+ PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
uint8_t *pci_conf = d->dev.config;
pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
- pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
qemu_register_reset(piix3_reset, d);
@@ -149,24 +149,6 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
return 0;
}
-static int pci_piix3_ide_initfn(PCIDevice *dev)
-{
- PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
-
- pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371SB_1);
- return pci_piix_ide_initfn(d);
-}
-
-static int pci_piix4_ide_initfn(PCIDevice *dev)
-{
- PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
-
- pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371AB);
- return pci_piix_ide_initfn(d);
-}
-
/* hd_table must contain 4 block drivers */
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
@@ -195,13 +177,19 @@ static PCIDeviceInfo piix_ide_info[] = {
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.no_hotplug = 1,
- .init = pci_piix3_ide_initfn,
+ .init = pci_piix_ide_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371SB_1,
+ .class_id = PCI_CLASS_STORAGE_IDE,
},{
.qdev.name = "piix4-ide",
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.no_hotplug = 1,
- .init = pci_piix4_ide_initfn,
+ .init = pci_piix_ide_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371AB,
+ .class_id = PCI_CLASS_STORAGE_IDE,
},{
/* end of list */
}
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 04f3290960..3474c37ff7 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -160,11 +160,7 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);;
uint8_t *pci_conf = d->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_IDE);
- pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */
- pci_config_set_revision(pci_conf,0x06); /* Revision 0.6 */
pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
qemu_register_reset(via_reset, d);
@@ -191,6 +187,10 @@ static PCIDeviceInfo via_ide_info = {
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.init = vt82c686b_ide_initfn,
+ .vendor_id = PCI_VENDOR_ID_VIA,
+ .device_id = PCI_DEVICE_ID_VIA_IDE,
+ .revision = 0x06,
+ .class_id = PCI_CLASS_STORAGE_IDE,
};
static void via_ide_register(void)
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 5485745e85..0ffffce90e 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1138,10 +1138,6 @@ static int intel_hda_init(PCIDevice *pci)
d->name = d->pci.qdev.info->name;
- pci_config_set_vendor_id(conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(conf, 0x2668);
- pci_config_set_revision(conf, 1);
- pci_config_set_class(conf, PCI_CLASS_MULTIMEDIA_HD_AUDIO);
pci_config_set_interrupt_pin(conf, 1);
/* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
@@ -1265,6 +1261,10 @@ static PCIDeviceInfo intel_hda_info = {
.init = intel_hda_init,
.exit = intel_hda_exit,
.config_write = intel_hda_write_config,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = 0x2668,
+ .revision = 1,
+ .class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index 95adf0978f..a6bfbb9173 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -104,12 +104,8 @@ static int ioh3420_initfn(PCIDevice *d)
return rc;
}
- d->config[PCI_REVISION_ID] = PCI_DEVICE_ID_IOH_REV;
pcie_port_init_reg(d);
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_IOH_EPORT);
-
rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET,
IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID);
if (rc < 0) {
@@ -217,6 +213,9 @@ static PCIDeviceInfo ioh3420_info = {
.config_write = ioh3420_write_config,
.init = ioh3420_initfn,
.exit = ioh3420_exitfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_IOH_EPORT,
+ .revision = PCI_DEVICE_ID_IOH_REV,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 7b19a81a47..3055dd2a50 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -706,12 +706,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
}
pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REDHAT_QUMRANET);
- pci_conf[0x02] = 0x10;
- pci_conf[0x03] = 0x11;
pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_RAM);
- pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
pci_config_set_interrupt_pin(pci_conf, 1);
@@ -809,6 +804,9 @@ static PCIDeviceInfo ivshmem_info = {
.qdev.reset = ivshmem_reset,
.init = pci_ivshmem_init,
.exit = pci_ivshmem_uninit,
+ .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+ .device_id = 0x1110,
+ .class_id = PCI_CLASS_MEMORY_RAM,
.qdev.props = (Property[]) {
DEFINE_PROP_CHR("chardev", IVShmemState, server_chr),
DEFINE_PROP_STRING("size", IVShmemState, sizearg),
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 83084b6b6a..940b43abfd 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -889,7 +889,6 @@ static void lsi_do_msgout(LSIState *s)
uint8_t msg;
int len;
uint32_t current_tag;
- SCSIDevice *current_dev;
lsi_request *current_req, *p, *p_next;
int id;
@@ -901,7 +900,6 @@ static void lsi_do_msgout(LSIState *s)
current_req = lsi_find_by_tag(s, current_tag);
}
id = (current_tag >> 8) & 0xf;
- current_dev = s->bus.devs[id];
DPRINTF("MSG out len=%d\n", s->dbc);
while (s->dbc) {
@@ -2258,15 +2256,6 @@ static int lsi_scsi_init(PCIDevice *dev)
pci_conf = s->dev.config;
- /* PCI Vendor ID (word) */
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_LSI_LOGIC);
- /* PCI device ID (word) */
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_LSI_53C895A);
- /* PCI base class code */
- pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_SCSI);
- /* PCI subsystem ID */
- pci_conf[PCI_SUBSYSTEM_ID] = 0x00;
- pci_conf[PCI_SUBSYSTEM_ID + 1] = 0x10;
/* PCI latency timer = 255 */
pci_conf[PCI_LATENCY_TIMER] = 0xff;
/* TODO: RST# value should be 0 */
@@ -2302,6 +2291,10 @@ static PCIDeviceInfo lsi_info = {
.qdev.vmsd = &vmstate_lsi_scsi,
.init = lsi_scsi_init,
.exit = lsi_scsi_uninit,
+ .vendor_id = PCI_VENDOR_ID_LSI_LOGIC,
+ .device_id = PCI_DEVICE_ID_LSI_53C895A,
+ .class_id = PCI_CLASS_STORAGE_SCSI,
+ .subsystem_id = 0x1000,
};
static void lsi53c895a_register_devices(void)
diff --git a/hw/msi.c b/hw/msi.c
index b087fe52bb..e8c56079aa 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -172,7 +172,7 @@ void msi_uninit(struct PCIDevice *dev)
}
flags = pci_get_word(dev->config + msi_flags_off(dev));
cap_size = msi_cap_sizeof(flags);
- pci_del_capability(dev, PCI_CAP_ID_MSIX, cap_size);
+ pci_del_capability(dev, PCI_CAP_ID_MSI, cap_size);
dev->cap_present &= ~QEMU_PCI_CAP_MSI;
MSI_DEV_PRINTF(dev, "uninit\n");
diff --git a/hw/msix.c b/hw/msix.c
index af40e266fe..03d7becaaf 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -16,9 +16,6 @@
#include "pci.h"
#include "range.h"
-/* MSI-X capability structure */
-#define MSIX_TABLE_OFFSET 4
-#define MSIX_PBA_OFFSET 8
#define MSIX_CAP_LENGTH 12
/* MSI enable bit and maskall bit are in byte 1 in FLAGS register */
@@ -26,14 +23,6 @@
#define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8)
#define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8)
-/* MSI-X table format */
-#define MSIX_MSG_ADDR 0
-#define MSIX_MSG_UPPER_ADDR 4
-#define MSIX_MSG_DATA 8
-#define MSIX_VECTOR_CTRL 12
-#define MSIX_ENTRY_SIZE 16
-#define MSIX_VECTOR_MASK 0x1
-
/* How much space does an MSIX table need. */
/* The spec requires giving the table structure
* a 4K aligned region all by itself. */
@@ -82,9 +71,9 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);
/* Table on top of BAR */
- pci_set_long(config + MSIX_TABLE_OFFSET, bar_size | bar_nr);
+ pci_set_long(config + PCI_MSIX_TABLE, bar_size | bar_nr);
/* Pending bits on top of that */
- pci_set_long(config + MSIX_PBA_OFFSET, (bar_size + MSIX_PAGE_PENDING) |
+ pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) |
bar_nr);
pdev->msix_cap = config_offset;
/* Make flags bit writable. */
@@ -140,9 +129,10 @@ static int msix_function_masked(PCIDevice *dev)
static int msix_is_masked(PCIDevice *dev, int vector)
{
- unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
+ unsigned offset =
+ vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
return msix_function_masked(dev) ||
- dev->msix_table_page[offset] & MSIX_VECTOR_MASK;
+ dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
}
static void msix_handle_mask_update(PCIDevice *dev, int vector)
@@ -184,7 +174,7 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
{
PCIDevice *dev = opaque;
unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
- int vector = offset / MSIX_ENTRY_SIZE;
+ int vector = offset / PCI_MSIX_ENTRY_SIZE;
pci_set_long(dev->msix_table_page + offset, val);
msix_handle_mask_update(dev, vector);
}
@@ -208,7 +198,7 @@ void msix_mmio_map(PCIDevice *d, int region_num,
pcibus_t addr, pcibus_t size, int type)
{
uint8_t *config = d->config + d->msix_cap;
- uint32_t table = pci_get_long(config + MSIX_TABLE_OFFSET);
+ uint32_t table = pci_get_long(config + PCI_MSIX_TABLE);
uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
/* TODO: for assigned devices, we'll want to make it possible to map
* pending bits separately in case they are in a separate bar. */
@@ -226,8 +216,9 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
{
int vector;
for (vector = 0; vector < nentries; ++vector) {
- unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
- dev->msix_table_page[offset] |= MSIX_VECTOR_MASK;
+ unsigned offset =
+ vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
+ dev->msix_table_page[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
}
}
@@ -313,7 +304,7 @@ void msix_save(PCIDevice *dev, QEMUFile *f)
return;
}
- qemu_put_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
+ qemu_put_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
}
@@ -327,7 +318,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
}
msix_free_irq_entries(dev);
- qemu_get_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
+ qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
}
@@ -355,7 +346,7 @@ uint32_t msix_bar_size(PCIDevice *dev)
/* Send an MSI-X message */
void msix_notify(PCIDevice *dev, unsigned vector)
{
- uint8_t *table_entry = dev->msix_table_page + vector * MSIX_ENTRY_SIZE;
+ uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE;
uint64_t address;
uint32_t data;
@@ -366,9 +357,8 @@ void msix_notify(PCIDevice *dev, unsigned vector)
return;
}
- address = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR);
- address = (address << 32) | pci_get_long(table_entry + MSIX_MSG_ADDR);
- data = pci_get_long(table_entry + MSIX_MSG_DATA);
+ address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
+ data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
stl_phys(address, data);
}
diff --git a/hw/ne2000.c b/hw/ne2000.c
index b668ad1070..f8acaaeeb6 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -721,9 +721,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
uint8_t *pci_conf;
pci_conf = d->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8029);
- pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
/* TODO: RST# value should be 0. PCI spec 6.2.4 */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
@@ -767,6 +764,9 @@ static PCIDeviceInfo ne2000_info = {
.qdev.vmsd = &vmstate_pci_ne2000,
.init = pci_ne2000_init,
.exit = pci_ne2000_exit,
+ .vendor_id = PCI_VENDOR_ID_REALTEK,
+ .device_id = PCI_DEVICE_ID_REALTEK_8029,
+ .class_id = PCI_CLASS_NETWORK_ETHERNET,
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/pc.h b/hw/pc.h
index 0dcbee7ca5..6d5730b26b 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -176,7 +176,6 @@ struct PCII440FXState;
typedef struct PCII440FXState PCII440FXState;
PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
-PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size);
void i440fx_init_memory_mappings(PCII440FXState *d);
/* piix4.c */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 9a22a8afc8..c5c16b4571 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -124,11 +124,7 @@ static void pc_init1(ram_addr_t ram_size,
isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
if (pci_enabled) {
- if (!xen_enabled()) {
- pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
- } else {
- pci_bus = i440fx_xen_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
- }
+ pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
} else {
pci_bus = NULL;
i440fx_state = NULL;
@@ -140,6 +136,10 @@ static void pc_init1(ram_addr_t ram_size,
pc_vga_init(pci_enabled? pci_bus: NULL);
+ if (xen_enabled()) {
+ pci_create_simple(pci_bus, -1, "xen-platform");
+ }
+
/* init basic PC hardware */
pc_basic_device_init(isa_irq, &rtc_state, xen_enabled());
@@ -288,6 +288,18 @@ static QEMUMachine pc_machine_v0_13 = {
.driver = "PCI",
.property = "command_serr_enable",
.value = "off",
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "event_idx",
+ .value = "off",
},
{ /* end of list */ }
},
@@ -319,6 +331,18 @@ static QEMUMachine pc_machine_v0_12 = {
.driver = "PCI",
.property = "command_serr_enable",
.value = "off",
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "event_idx",
+ .value = "off",
},
{ /* end of list */ }
}
@@ -358,6 +382,18 @@ static QEMUMachine pc_machine_v0_11 = {
.driver = "PCI",
.property = "command_serr_enable",
.value = "off",
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "event_idx",
+ .value = "off",
},
{ /* end of list */ }
}
@@ -409,6 +445,18 @@ static QEMUMachine pc_machine_v0_10 = {
.driver = "PCI",
.property = "command_serr_enable",
.value = "off",
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "event_idx",
+ .value = "off",
},
{ /* end of list */ }
},
diff --git a/hw/pci.c b/hw/pci.c
index 1d297d6c7c..b904a4ecb6 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -726,10 +726,11 @@ static void pci_config_free(PCIDevice *pci_dev)
/* -1 for devfn means auto assign */
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
const char *name, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write,
- bool is_bridge)
+ const PCIDeviceInfo *info)
{
+ PCIConfigReadFunc *config_read = info->config_read;
+ PCIConfigWriteFunc *config_write = info->config_write;
+
if (devfn < 0) {
for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
devfn += PCI_FUNC_MAX) {
@@ -750,13 +751,29 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
pci_dev->irq_state = 0;
pci_config_alloc(pci_dev);
- if (!is_bridge) {
- pci_set_default_subsystem_id(pci_dev);
+ pci_config_set_vendor_id(pci_dev->config, info->vendor_id);
+ pci_config_set_device_id(pci_dev->config, info->device_id);
+ pci_config_set_revision(pci_dev->config, info->revision);
+ pci_config_set_class(pci_dev->config, info->class_id);
+
+ if (!info->is_bridge) {
+ if (info->subsystem_vendor_id || info->subsystem_id) {
+ pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
+ info->subsystem_vendor_id);
+ pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
+ info->subsystem_id);
+ } else {
+ pci_set_default_subsystem_id(pci_dev);
+ }
+ } else {
+ /* subsystem_vendor_id/subsystem_id are only for header type 0 */
+ assert(!info->subsystem_vendor_id);
+ assert(!info->subsystem_id);
}
pci_init_cmask(pci_dev);
pci_init_wmask(pci_dev);
pci_init_w1cmask(pci_dev);
- if (is_bridge) {
+ if (info->is_bridge) {
pci_init_wmask_bridge(pci_dev);
}
if (pci_init_multifunction(bus, pci_dev)) {
@@ -783,17 +800,20 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
pci_config_free(pci_dev);
}
+/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
int instance_size, int devfn,
PCIConfigReadFunc *config_read,
PCIConfigWriteFunc *config_write)
{
PCIDevice *pci_dev;
+ PCIDeviceInfo info = {
+ .config_read = config_read,
+ .config_write = config_write,
+ };
pci_dev = qemu_mallocz(instance_size);
- pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
- config_read, config_write,
- PCI_HEADER_TYPE_NORMAL);
+ pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
if (pci_dev == NULL) {
hw_error("PCI: can't register device\n");
}
@@ -1643,7 +1663,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
PCIDevice *pci_dev = (PCIDevice *)qdev;
PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
PCIBus *bus;
- int devfn, rc;
+ int rc;
bool is_default_rom;
/* initialize cap_present for pci_is_express() and pci_config_size() */
@@ -1652,10 +1672,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
}
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
- devfn = pci_dev->devfn;
- pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
- info->config_read, info->config_write,
- info->is_bridge);
+ pci_dev = do_pci_register_device(pci_dev, bus, base->name,
+ pci_dev->devfn, info);
if (pci_dev == NULL)
return -1;
if (qdev->hotplugged && info->no_hotplug) {
@@ -1663,10 +1681,12 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
do_pci_unregister_device(pci_dev);
return -1;
}
- rc = info->init(pci_dev);
- if (rc != 0) {
- do_pci_unregister_device(pci_dev);
- return rc;
+ if (info->init) {
+ rc = info->init(pci_dev);
+ if (rc != 0) {
+ do_pci_unregister_device(pci_dev);
+ return rc;
+ }
}
/* rom loading */
diff --git a/hw/pci.h b/hw/pci.h
index 0d288ce000..c220745c98 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -433,6 +433,13 @@ typedef struct {
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
+ uint16_t vendor_id;
+ uint16_t device_id;
+ uint8_t revision;
+ uint16_t class_id;
+ uint16_t subsystem_vendor_id; /* only for header type = 0 */
+ uint16_t subsystem_id; /* only for header type = 0 */
+
/*
* pci-to-pci bridge or normal device.
* This doesn't mean pci host switch.
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index d9457ed3f4..d94578c87d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -109,3 +109,5 @@
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+
+#define PCI_VENDOR_ID_XENSOURCE 0x5853
diff --git a/hw/pci_regs.h b/hw/pci_regs.h
index 5a5ab89c7f..e8840964ac 100644
--- a/hw/pci_regs.h
+++ b/hw/pci_regs.h
@@ -300,12 +300,22 @@
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
#define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */
-/* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */
+/* MSI-X registers */
#define PCI_MSIX_FLAGS 2
#define PCI_MSIX_FLAGS_QSIZE 0x7FF
#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
#define PCI_MSIX_FLAGS_MASKALL (1 << 14)
-#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
+#define PCI_MSIX_TABLE 4
+#define PCI_MSIX_PBA 8
+#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
+
+/* MSI-X entry's format */
+#define PCI_MSIX_ENTRY_SIZE 16
+#define PCI_MSIX_ENTRY_LOWER_ADDR 0
+#define PCI_MSIX_ENTRY_UPPER_ADDR 4
+#define PCI_MSIX_ENTRY_DATA 8
+#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
+#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1
/* CompactPCI Hotswap Register */
@@ -365,6 +375,11 @@
#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
+/* PCI Bridge Subsystem ID registers */
+
+#define PCI_SSVID_VENDOR_ID 4 /* PCI-Bridge subsystem vendor id register */
+#define PCI_SSVID_DEVICE_ID 6 /* PCI-Bridge subsystem device id register */
+
/* PCI Express capability registers */
#define PCI_EXP_FLAGS 2 /* Capabilities register */
@@ -420,7 +435,7 @@
#define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */
#define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */
#define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* L1 Clock Power Management */
-#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Suprise Down Error Reporting Capable */
+#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */
#define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */
#define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */
#define PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */
@@ -437,7 +452,10 @@
#define PCI_EXP_LNKCTL_LABIE 0x0800 /* Lnk Autonomous Bandwidth Interrupt Enable */
#define PCI_EXP_LNKSTA 18 /* Link Status */
#define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */
+#define PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */
+#define PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */
#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */
+#define PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */
#define PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */
#define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */
#define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
@@ -486,10 +504,22 @@
#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
#define PCI_EXP_RTCAP 30 /* Root Capabilities */
#define PCI_EXP_RTSTA 32 /* Root Status */
+#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
+#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */
+#define PCI_EXP_DEVCAP2_LTR 0x800 /* Latency tolerance reporting */
+#define PCI_EXP_OBFF_MASK 0xc0000 /* OBFF support mechanism */
+#define PCI_EXP_OBFF_MSG 0x40000 /* New message signaling */
+#define PCI_EXP_OBFF_WAKE 0x80000 /* Re-use WAKE# for OBFF */
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */
+#define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */
+#define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */
+#define PCI_EXP_LTR_EN 0x400 /* Latency tolerance reporting */
+#define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */
+#define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */
+#define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */
#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */
#define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */
@@ -502,9 +532,12 @@
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
+#define PCI_EXT_CAP_ID_VNDR 11
+#define PCI_EXT_CAP_ID_ACS 13
#define PCI_EXT_CAP_ID_ARI 14
#define PCI_EXT_CAP_ID_ATS 15
#define PCI_EXT_CAP_ID_SRIOV 16
+#define PCI_EXT_CAP_ID_LTR 24
/* Advanced Error Reporting */
#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
@@ -556,8 +589,7 @@
#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */
#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */
#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */
-#define PCI_ERR_ROOT_COR_SRC 52
-#define PCI_ERR_ROOT_SRC 54
+#define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */
/* Virtual Channel */
#define PCI_VC_PORT_REG1 4
@@ -662,4 +694,22 @@
#define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */
#define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */
+#define PCI_LTR_MAX_SNOOP_LAT 0x4
+#define PCI_LTR_MAX_NOSNOOP_LAT 0x6
+#define PCI_LTR_VALUE_MASK 0x000003ff
+#define PCI_LTR_SCALE_MASK 0x00001c00
+#define PCI_LTR_SCALE_SHIFT 10
+
+/* Access Control Service */
+#define PCI_ACS_CAP 0x04 /* ACS Capability Register */
+#define PCI_ACS_SV 0x01 /* Source Validation */
+#define PCI_ACS_TB 0x02 /* Translation Blocking */
+#define PCI_ACS_RR 0x04 /* P2P Request Redirect */
+#define PCI_ACS_CR 0x08 /* P2P Completion Redirect */
+#define PCI_ACS_UF 0x10 /* Upstream Forwarding */
+#define PCI_ACS_EC 0x20 /* P2P Egress Control */
+#define PCI_ACS_DT 0x40 /* Direct Translated P2P */
+#define PCI_ACS_CTRL 0x06 /* ACS Control Register */
+#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */
+
#endif /* LINUX_PCI_REGS_H */
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index f08d3c79f3..be019c7c0a 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -38,6 +38,9 @@
#define PCIE_DEV_PRINTF(dev, fmt, ...) \
PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
+#define PCI_ERR_SRC_COR_OFFS 0
+#define PCI_ERR_SRC_UNCOR_OFFS 2
+
/* From 6.2.7 Error Listing and Rules. Table 6-2, 6-3 and 6-4 */
static uint32_t pcie_aer_uncor_default_severity(uint32_t status)
{
@@ -320,7 +323,8 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg)
if (root_status & PCI_ERR_ROOT_COR_RCV) {
root_status |= PCI_ERR_ROOT_MULTI_COR_RCV;
} else {
- pci_set_word(aer_cap + PCI_ERR_ROOT_COR_SRC, msg->source_id);
+ pci_set_word(aer_cap + PCI_ERR_ROOT_ERR_SRC + PCI_ERR_SRC_COR_OFFS,
+ msg->source_id);
}
root_status |= PCI_ERR_ROOT_COR_RCV;
break;
@@ -341,7 +345,8 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg)
if (root_status & PCI_ERR_ROOT_UNCOR_RCV) {
root_status |= PCI_ERR_ROOT_MULTI_UNCOR_RCV;
} else {
- pci_set_word(aer_cap + PCI_ERR_ROOT_SRC, msg->source_id);
+ pci_set_word(aer_cap + PCI_ERR_ROOT_ERR_SRC +
+ PCI_ERR_SRC_UNCOR_OFFS, msg->source_id);
}
root_status |= PCI_ERR_ROOT_UNCOR_RCV;
}
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 9415a1ecf5..216cf81492 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -265,12 +265,8 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
pci_conf = pci_dev->config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
pci_set_word(pci_conf + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
- pci_conf[PCI_REVISION_ID] = 0x10;
- pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0);
pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0);
@@ -318,6 +314,10 @@ static PCIDeviceInfo pcnet_info = {
.qdev.vmsd = &vmstate_pci_pcnet,
.init = pci_pcnet_init,
.exit = pci_pcnet_uninit,
+ .vendor_id = PCI_VENDOR_ID_AMD,
+ .device_id = PCI_DEVICE_ID_AMD_LANCE,
+ .revision = 0x10,
+ .class_id = PCI_CLASS_NETWORK_ETHERNET,
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/piix4.c b/hw/piix4.c
index 71f1f84dc0..9590e7b140 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -86,15 +86,8 @@ static const VMStateDescription vmstate_piix4 = {
static int piix4_initfn(PCIDevice *dev)
{
PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev);
- uint8_t *pci_conf;
isa_bus_new(&d->dev.qdev);
-
- pci_conf = d->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
- pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
-
piix4_dev = &d->dev;
qemu_register_reset(piix4_reset, d);
return 0;
@@ -117,6 +110,9 @@ static PCIDeviceInfo piix4_info[] = {
.qdev.no_user = 1,
.no_hotplug = 1,
.init = piix4_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371AB_0, // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
+ .class_id = PCI_CLASS_BRIDGE_ISA,
},{
/* end of list */
}
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 85a320e729..26ce90451a 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -40,6 +40,7 @@ typedef PCIHostState I440FXState;
#define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */
#define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */
+#define XEN_PIIX_NUM_PIRQS 128ULL
#define PIIX_PIRQC 0x60
typedef struct PIIX3State {
@@ -78,6 +79,8 @@ struct PCII440FXState {
#define I440FX_SMRAM 0x72
static void piix3_set_irq(void *opaque, int pirq, int level);
+static void piix3_write_config_xen(PCIDevice *dev,
+ uint32_t address, uint32_t val, int len);
/* return the global irq number corresponding to a given device irq
pin. We could also use the bus number to have a more precise
@@ -173,13 +176,6 @@ static void i440fx_write_config(PCIDevice *dev,
}
}
-static void i440fx_write_config_xen(PCIDevice *dev,
- uint32_t address, uint32_t val, int len)
-{
- xen_piix_pci_write_config_client(address, val, len);
- i440fx_write_config(dev, address, val, len);
-}
-
static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
{
PCII440FXState *d = opaque;
@@ -236,11 +232,6 @@ static int i440fx_initfn(PCIDevice *dev)
{
PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
- pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82441);
- d->dev.config[0x08] = 0x02; // revision
- pci_config_set_class(d->dev.config, PCI_CLASS_BRIDGE_HOST);
-
d->dev.config[I440FX_SMRAM] = 0x02;
cpu_smm_register(&i440fx_set_smm, d);
@@ -267,8 +258,21 @@ static PCIBus *i440fx_common_init(const char *device_name,
d = pci_create_simple(b, 0, device_name);
*pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
- piix3 = DO_UPCAST(PIIX3State, dev,
- pci_create_simple_multifunction(b, -1, true, "PIIX3"));
+ /* Xen supports additional interrupt routes from the PCI devices to
+ * the IOAPIC: the four pins of each PCI device on the bus are also
+ * connected to the IOAPIC directly.
+ * These additional routes can be discovered through ACPI. */
+ if (xen_enabled()) {
+ piix3 = DO_UPCAST(PIIX3State, dev,
+ pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
+ pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
+ piix3, XEN_PIIX_NUM_PIRQS);
+ } else {
+ piix3 = DO_UPCAST(PIIX3State, dev,
+ pci_create_simple_multifunction(b, -1, true, "PIIX3"));
+ pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
+ PIIX_NUM_PIRQS);
+ }
piix3->pic = pic;
(*pi440fx_state)->piix3 = piix3;
@@ -289,21 +293,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
PCIBus *b;
b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size);
- pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, (*pi440fx_state)->piix3,
- PIIX_NUM_PIRQS);
-
- return b;
-}
-
-PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
- qemu_irq *pic, ram_addr_t ram_size)
-{
- PCIBus *b;
-
- b = i440fx_common_init("i440FX-xen", pi440fx_state, piix3_devfn, pic, ram_size);
- pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
- (*pi440fx_state)->piix3, PIIX_NUM_PIRQS);
-
return b;
}
@@ -365,6 +354,13 @@ static void piix3_write_config(PCIDevice *dev,
}
}
+static void piix3_write_config_xen(PCIDevice *dev,
+ uint32_t address, uint32_t val, int len)
+{
+ xen_piix_pci_write_config_client(address, val, len);
+ piix3_write_config(dev, address, val, len);
+}
+
static void piix3_reset(void *opaque)
{
PIIX3State *d = opaque;
@@ -441,15 +437,8 @@ static const VMStateDescription vmstate_piix3 = {
static int piix3_initfn(PCIDevice *dev)
{
PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev);
- uint8_t *pci_conf;
isa_bus_new(&d->dev.qdev);
-
- pci_conf = d->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
- pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
-
qemu_register_reset(piix3_reset, d);
return 0;
}
@@ -464,14 +453,10 @@ static PCIDeviceInfo i440fx_info[] = {
.no_hotplug = 1,
.init = i440fx_initfn,
.config_write = i440fx_write_config,
- },{
- .qdev.name = "i440FX-xen",
- .qdev.desc = "Host bridge",
- .qdev.size = sizeof(PCII440FXState),
- .qdev.vmsd = &vmstate_i440fx,
- .qdev.no_user = 1,
- .init = i440fx_initfn,
- .config_write = i440fx_write_config_xen,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82441,
+ .revision = 0x02,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
},{
.qdev.name = "PIIX3",
.qdev.desc = "ISA bridge",
@@ -481,6 +466,18 @@ static PCIDeviceInfo i440fx_info[] = {
.no_hotplug = 1,
.init = piix3_initfn,
.config_write = piix3_write_config,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+ .class_id = PCI_CLASS_BRIDGE_ISA,
+ },{
+ .qdev.name = "PIIX3-xen",
+ .qdev.desc = "ISA bridge",
+ .qdev.size = sizeof(PIIX3State),
+ .qdev.vmsd = &vmstate_piix3,
+ .qdev.no_user = 1,
+ .no_hotplug = 1,
+ .init = piix3_initfn,
+ .config_write = piix3_write_config_xen,
},{
/* end of list */
}
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 069af9691a..fc11af4374 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -304,20 +304,13 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
return 0;
}
-static int e500_host_bridge_initfn(PCIDevice *dev)
-{
- pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_FREESCALE);
- pci_config_set_device_id(dev->config, PCI_DEVICE_ID_MPC8533E);
- pci_config_set_class(dev->config, PCI_CLASS_PROCESSOR_POWERPC);
-
- return 0;
-}
-
static PCIDeviceInfo e500_host_bridge_info = {
.qdev.name = "e500-host-bridge",
.qdev.desc = "Host bridge",
.qdev.size = sizeof(PCIDevice),
- .init = e500_host_bridge_initfn,
+ .vendor_id = PCI_VENDOR_ID_FREESCALE,
+ .device_id = PCI_DEVICE_ID_MPC8533E,
+ .class_id = PCI_CLASS_PROCESSOR_POWERPC,
};
static SysBusDeviceInfo e500_pcihost_info = {
diff --git a/hw/qxl.c b/hw/qxl.c
index 1906e84fab..16316f2bf5 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1231,7 +1231,6 @@ static int qxl_init_common(PCIQXLDevice *qxl)
break;
}
- pci_config_set_vendor_id(config, REDHAT_PCI_VENDOR_ID);
pci_config_set_device_id(config, pci_device_id);
pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
@@ -1311,7 +1310,6 @@ static int qxl_init_primary(PCIDevice *dev)
qxl0 = qxl;
register_displaychangelistener(vga->ds, &display_listener);
- pci_config_set_class(dev->config, PCI_CLASS_DISPLAY_VGA);
return qxl_init_common(qxl);
}
@@ -1331,7 +1329,6 @@ static int qxl_init_secondary(PCIDevice *dev)
qxl->vga.vram_size);
qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
- pci_config_set_class(dev->config, PCI_CLASS_DISPLAY_OTHER);
return qxl_init_common(qxl);
}
@@ -1494,6 +1491,8 @@ static PCIDeviceInfo qxl_info_primary = {
.init = qxl_init_primary,
.config_write = qxl_write_config,
.romfile = "vgabios-qxl.bin",
+ .vendor_id = REDHAT_PCI_VENDOR_ID,
+ .class_id = PCI_CLASS_DISPLAY_VGA,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
@@ -1512,6 +1511,8 @@ static PCIDeviceInfo qxl_info_secondary = {
.qdev.reset = qxl_reset_handler,
.qdev.vmsd = &qxl_vmstate,
.init = qxl_init_secondary,
+ .vendor_id = REDHAT_PCI_VENDOR_ID,
+ .class_id = PCI_CLASS_DISPLAY_OTHER,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 2f8db580d9..5214b8cb7c 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3457,10 +3457,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
uint8_t *pci_conf;
pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
- pci_conf[PCI_REVISION_ID] = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
- pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */
/* TODO: start of capability list, but no capability
* list bit in status register, and offset 0xdc seems unused. */
@@ -3514,6 +3510,10 @@ static PCIDeviceInfo rtl8139_info = {
.init = pci_rtl8139_init,
.exit = pci_rtl8139_uninit,
.romfile = "pxe-rtl8139.rom",
+ .vendor_id = PCI_VENDOR_ID_REALTEK,
+ .device_id = PCI_DEVICE_ID_REALTEK_8139,
+ .revision = RTL8139_PCI_REVID, /* >=0x20 is for 8139C+ */
+ .class_id = PCI_CLASS_NETWORK_ETHERNET,
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index e99d8dbfb5..a076cf2ff0 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -137,8 +137,6 @@ static int sh_pci_init_device(SysBusDevice *dev)
static int sh_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_HITACHI);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_HITACHI_SH7751R);
pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT);
pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST |
PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
@@ -149,6 +147,8 @@ static PCIDeviceInfo sh_pci_host_info = {
.qdev.name = "sh_pci_host",
.qdev.size = sizeof(PCIDevice),
.init = sh_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_HITACHI,
+ .device_id = PCI_DEVICE_ID_HITACHI_SH7751R,
};
static void sh_pci_register_devices(void)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 5eb38cf27d..d7dcaf007d 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -553,15 +553,11 @@ pci_ebus_init1(PCIDevice *s)
{
isa_bus_new(&s->qdev);
- pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN);
- pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS);
s->config[0x04] = 0x06; // command = bus master, pci mem
s->config[0x05] = 0x00;
s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
s->config[0x07] = 0x03; // status = medium devsel
- s->config[0x08] = 0x01; // revision
s->config[0x09] = 0x00; // programming i/f
- pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER);
s->config[0x0D] = 0x0a; // latency_timer
pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -575,6 +571,10 @@ static PCIDeviceInfo ebus_info = {
.qdev.name = "ebus",
.qdev.size = sizeof(PCIDevice),
.init = pci_ebus_init1,
+ .vendor_id = PCI_VENDOR_ID_SUN,
+ .device_id = PCI_DEVICE_ID_SUN_EBUS,
+ .revision = 0x01,
+ .class_id = PCI_CLASS_BRIDGE_OTHER,
};
static void pci_ebus_register(void)
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index 2f3e6da4e2..00c7be8c8f 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -146,7 +146,9 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset,
vdev->queue_sel = value;
break;
case SYBORG_VIRTIO_QUEUE_NOTIFY:
- virtio_queue_notify(vdev, value);
+ if (value < VIRTIO_PCI_QUEUE_MAX) {
+ virtio_queue_notify(vdev, value);
+ }
break;
case SYBORG_VIRTIO_STATUS:
virtio_set_status(vdev, value & 0xFF);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index c57c0a1ce3..d364daa53a 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -279,10 +279,6 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic)
static int unin_main_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_PCI);
- d->config[0x08] = 0x00; // revision
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
d->config[0x0C] = 0x08; // cache_line_size
d->config[0x0D] = 0x10; // latency_timer
d->config[0x34] = 0x00; // capabilities_pointer
@@ -291,10 +287,6 @@ static int unin_main_pci_host_init(PCIDevice *d)
static int unin_agp_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP);
- d->config[0x08] = 0x00; // revision
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
d->config[0x0C] = 0x08; // cache_line_size
d->config[0x0D] = 0x10; // latency_timer
// d->config[0x34] = 0x80; // capabilities_pointer
@@ -303,11 +295,6 @@ static int unin_agp_pci_host_init(PCIDevice *d)
static int u3_agp_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_U3_AGP);
- /* revision */
- d->config[0x08] = 0x00;
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
/* cache line size */
d->config[0x0C] = 0x08;
/* latency timer */
@@ -317,10 +304,6 @@ static int u3_agp_pci_host_init(PCIDevice *d)
static int unin_internal_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI);
- d->config[0x08] = 0x00; // revision
- pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
d->config[0x0C] = 0x08; // cache_line_size
d->config[0x0D] = 0x10; // latency_timer
d->config[0x34] = 0x00; // capabilities_pointer
@@ -331,24 +314,40 @@ static PCIDeviceInfo unin_main_pci_host_info = {
.qdev.name = "uni-north",
.qdev.size = sizeof(PCIDevice),
.init = unin_main_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_APPLE,
+ .device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI,
+ .revision = 0x00,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static PCIDeviceInfo u3_agp_pci_host_info = {
.qdev.name = "u3-agp",
.qdev.size = sizeof(PCIDevice),
.init = u3_agp_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_APPLE,
+ .device_id = PCI_DEVICE_ID_APPLE_U3_AGP,
+ .revision = 0x00,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static PCIDeviceInfo unin_agp_pci_host_info = {
.qdev.name = "uni-north-agp",
.qdev.size = sizeof(PCIDevice),
.init = unin_agp_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_APPLE,
+ .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
+ .revision = 0x00,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static PCIDeviceInfo unin_internal_pci_host_info = {
.qdev.name = "uni-north-pci",
.qdev.size = sizeof(PCIDevice),
.init = unin_internal_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_APPLE,
+ .device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI,
+ .revision = 0x00,
+ .class_id = PCI_CLASS_BRIDGE_HOST,
};
static void unin_register_devices(void)
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index c909127735..e33e546b43 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2142,6 +2142,10 @@ static PCIDeviceInfo ehci_info = {
.qdev.name = "usb-ehci",
.qdev.size = sizeof(EHCIState),
.init = usb_ehci_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801D,
+ .revision = 0x10,
+ .class_id = PCI_CLASS_SERIAL_USB,
};
static int usb_ehci_initfn(PCIDevice *dev)
@@ -2150,12 +2154,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
uint8_t *pci_conf = s->dev.config;
int i;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82801D);
- pci_set_byte(&pci_conf[PCI_REVISION_ID], 0x10);
pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20);
- pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
- pci_set_byte(&pci_conf[PCI_HEADER_TYPE], PCI_HEADER_TYPE_NORMAL);
/* capabilities pointer */
pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00);
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 832dcd688a..5d2ae01235 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1748,11 +1748,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
int num_ports = 3;
- pci_config_set_vendor_id(ohci->pci_dev.config, PCI_VENDOR_ID_APPLE);
- pci_config_set_device_id(ohci->pci_dev.config,
- PCI_DEVICE_ID_APPLE_IPID_USB);
ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
- pci_config_set_class(ohci->pci_dev.config, PCI_CLASS_SERIAL_USB);
/* TODO: RST# value should be 0. */
ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
@@ -1792,6 +1788,9 @@ static PCIDeviceInfo ohci_pci_info = {
.qdev.desc = "Apple USB Controller",
.qdev.size = sizeof(OHCIPCIState),
.init = usb_ohci_initfn_pci,
+ .vendor_id = PCI_VENDOR_ID_APPLE,
+ .device_id = PCI_DEVICE_ID_APPLE_IPID_USB,
+ .class_id = PCI_CLASS_SERIAL_USB,
};
static SysBusDeviceInfo ohci_sysbus_info = {
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 75cd231f81..405fa7b65e 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1114,14 +1114,13 @@ static USBBusOps uhci_bus_ops = {
.device_destroy = uhci_device_destroy,
};
-static int usb_uhci_common_initfn(UHCIState *s)
+static int usb_uhci_common_initfn(PCIDevice *dev)
{
+ UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
uint8_t *pci_conf = s->dev.config;
int i;
- pci_conf[PCI_REVISION_ID] = 0x01; // revision number
pci_conf[PCI_CLASS_PROG] = 0x00;
- pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
/* TODO: reset value should be 0. */
pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
@@ -1146,34 +1145,11 @@ static int usb_uhci_common_initfn(UHCIState *s)
return 0;
}
-static int usb_uhci_piix3_initfn(PCIDevice *dev)
-{
- UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
- uint8_t *pci_conf = s->dev.config;
-
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_2);
- return usb_uhci_common_initfn(s);
-}
-
-static int usb_uhci_piix4_initfn(PCIDevice *dev)
-{
- UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
- uint8_t *pci_conf = s->dev.config;
-
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_2);
- return usb_uhci_common_initfn(s);
-}
-
static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
{
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
uint8_t *pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
-
/* USB misc control 1/2 */
pci_set_long(pci_conf + 0x40,0x00001000);
/* PM capability */
@@ -1181,7 +1157,7 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
/* USB legacy support */
pci_set_long(pci_conf + 0xc0,0x00002000);
- return usb_uhci_common_initfn(s);
+ return usb_uhci_common_initfn(dev);
}
static PCIDeviceInfo uhci_info[] = {
@@ -1189,17 +1165,29 @@ static PCIDeviceInfo uhci_info[] = {
.qdev.name = "piix3-usb-uhci",
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
- .init = usb_uhci_piix3_initfn,
+ .init = usb_uhci_common_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
+ .revision = 0x01,
+ .class_id = PCI_CLASS_SERIAL_USB,
},{
.qdev.name = "piix4-usb-uhci",
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
- .init = usb_uhci_piix4_initfn,
+ .init = usb_uhci_common_initfn,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
+ .revision = 0x01,
+ .class_id = PCI_CLASS_SERIAL_USB,
},{
.qdev.name = "vt82c686b-usb-uhci",
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
.init = usb_uhci_vt82c686b_initfn,
+ .vendor_id = PCI_VENDOR_ID_VIA,
+ .device_id = PCI_DEVICE_ID_VIA_UHCI,
+ .revision = 0x01,
+ .class_id = PCI_CLASS_SERIAL_USB,
},{
/* end of list */
}
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 2fed8a00fd..8e75ffccfb 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -133,12 +133,8 @@ static int pci_realview_init(SysBusDevice *dev)
static int versatile_pci_host_init(PCIDevice *d)
{
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX);
- /* Both boards have the same device ID. Oh well. */
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30);
pci_set_word(d->config + PCI_STATUS,
PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
- pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO);
pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
return 0;
}
@@ -147,6 +143,10 @@ static PCIDeviceInfo versatile_pci_host_info = {
.qdev.name = "versatile_pci_host",
.qdev.size = sizeof(PCIDevice),
.init = versatile_pci_host_init,
+ .vendor_id = PCI_VENDOR_ID_XILINX,
+ /* Both boards have the same device ID. Oh well. */
+ .device_id = PCI_DEVICE_ID_XILINX_XC2VP30,
+ .class_id = PCI_CLASS_PROCESSOR_CO,
};
static void versatile_pci_register_devices(void)
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index ce9ec45777..481f448e3f 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -74,7 +74,6 @@ static int pci_vga_initfn(PCIDevice *dev)
{
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
VGACommonState *s = &d->vga;
- uint8_t *pci_conf = d->dev.config;
// vga + console init
vga_common_init(s, VGA_RAM_SIZE);
@@ -83,11 +82,6 @@ static int pci_vga_initfn(PCIDevice *dev)
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
- // dummy VGA (same as Bochs ID)
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_QEMU);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_QEMU_VGA);
- pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
-
/* XXX: VGA_RAM_SIZE must be a power of two */
pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
@@ -114,6 +108,11 @@ static PCIDeviceInfo vga_info = {
.init = pci_vga_initfn,
.config_write = pci_vga_write_config,
.romfile = "vgabios-stdvga.bin",
+
+ /* dummy VGA (same as Bochs ID) */
+ .vendor_id = PCI_VENDOR_ID_QEMU,
+ .device_id = PCI_DEVICE_ID_QEMU_VGA,
+ .class_id = PCI_CLASS_DISPLAY_VGA,
};
static void vga_register(void)
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index 420e05f112..b6dc592db0 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -15,6 +15,7 @@
#include "virtio-net.h"
#include "vhost_net.h"
+#include "qemu-error.h"
#include "config.h"
@@ -50,6 +51,9 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
}
+ if (!(net->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+ features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
+ }
if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) {
features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
}
@@ -65,6 +69,9 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned features)
if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) {
net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
}
+ if (features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+ net->dev.acked_features |= (1 << VIRTIO_RING_F_EVENT_IDX);
+ }
if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
}
@@ -197,6 +204,7 @@ void vhost_net_cleanup(struct vhost_net *net)
struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
bool force)
{
+ error_report("vhost-net support is not compiled in");
return NULL;
}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c018351095..b3e7ba5d12 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -75,9 +75,6 @@
VIRTIO_PCI_CONFIG_MSI : \
VIRTIO_PCI_CONFIG_NOMSI)
-/* Virtio ABI version, if we increment this, we break the guest driver. */
-#define VIRTIO_PCI_ABI_VERSION 0
-
/* How many bits to shift physical queue address written to QUEUE_PFN.
* 12 is historical, and due to x86 page size. */
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
@@ -328,7 +325,9 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
vdev->queue_sel = val;
break;
case VIRTIO_PCI_QUEUE_NOTIFY:
- virtio_queue_notify(vdev, val);
+ if (val < VIRTIO_PCI_QUEUE_MAX) {
+ virtio_queue_notify(vdev, val);
+ }
break;
case VIRTIO_PCI_STATUS:
if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
@@ -649,9 +648,7 @@ static const VirtIOBindings virtio_pci_bindings = {
.vmstate_change = virtio_pci_vmstate_change,
};
-void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
- uint16_t vendor, uint16_t device,
- uint16_t class_code, uint8_t pif)
+void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
{
uint8_t *config;
uint32_t size;
@@ -659,19 +656,12 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
proxy->vdev = vdev;
config = proxy->pci_dev.config;
- pci_config_set_vendor_id(config, vendor);
- pci_config_set_device_id(config, device);
-
- config[0x08] = VIRTIO_PCI_ABI_VERSION;
-
- config[0x09] = pif;
- pci_config_set_class(config, class_code);
-
- config[0x2c] = vendor & 0xFF;
- config[0x2d] = (vendor >> 8) & 0xFF;
- config[0x2e] = vdev->device_id & 0xFF;
- config[0x2f] = (vdev->device_id >> 8) & 0xFF;
+ if (proxy->class_code) {
+ pci_config_set_class(config, proxy->class_code);
+ }
+ pci_set_word(config + 0x2c, pci_get_word(config + PCI_VENDOR_ID));
+ pci_set_word(config + 0x2e, vdev->device_id);
config[0x3d] = 1;
if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
@@ -715,10 +705,7 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
return -1;
}
vdev->nvectors = proxy->nvectors;
- virtio_init_pci(proxy, vdev,
- PCI_VENDOR_ID_REDHAT_QUMRANET,
- PCI_DEVICE_ID_VIRTIO_BLOCK,
- proxy->class_code, 0x00);
+ virtio_init_pci(proxy, vdev);
/* make the actual value visible */
proxy->nvectors = vdev->nvectors;
return 0;
@@ -756,10 +743,7 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev)
vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
? proxy->serial.max_virtserial_ports + 1
: proxy->nvectors;
- virtio_init_pci(proxy, vdev,
- PCI_VENDOR_ID_REDHAT_QUMRANET,
- PCI_DEVICE_ID_VIRTIO_CONSOLE,
- proxy->class_code, 0x00);
+ virtio_init_pci(proxy, vdev);
proxy->nvectors = vdev->nvectors;
return 0;
}
@@ -781,11 +765,7 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
vdev->nvectors = proxy->nvectors;
- virtio_init_pci(proxy, vdev,
- PCI_VENDOR_ID_REDHAT_QUMRANET,
- PCI_DEVICE_ID_VIRTIO_NET,
- PCI_CLASS_NETWORK_ETHERNET,
- 0x00);
+ virtio_init_pci(proxy, vdev);
/* make the actual value visible */
proxy->nvectors = vdev->nvectors;
@@ -807,11 +787,7 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev)
VirtIODevice *vdev;
vdev = virtio_balloon_init(&pci_dev->qdev);
- virtio_init_pci(proxy, vdev,
- PCI_VENDOR_ID_REDHAT_QUMRANET,
- PCI_DEVICE_ID_VIRTIO_BALLOON,
- PCI_CLASS_MEMORY_RAM,
- 0x00);
+ virtio_init_pci(proxy, vdev);
return 0;
}
@@ -822,6 +798,10 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_blk_init_pci,
.exit = virtio_blk_exit_pci,
+ .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+ .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
+ .revision = VIRTIO_PCI_ABI_VERSION,
+ .class_id = PCI_CLASS_STORAGE_SCSI,
.qdev.props = (Property[]) {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
@@ -839,6 +819,10 @@ static PCIDeviceInfo virtio_info[] = {
.init = virtio_net_init_pci,
.exit = virtio_net_exit_pci,
.romfile = "pxe-virtio.rom",
+ .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+ .device_id = PCI_DEVICE_ID_VIRTIO_NET,
+ .revision = VIRTIO_PCI_ABI_VERSION,
+ .class_id = PCI_CLASS_NETWORK_ETHERNET,
.qdev.props = (Property[]) {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
@@ -859,6 +843,10 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_serial_init_pci,
.exit = virtio_serial_exit_pci,
+ .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+ .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
+ .revision = VIRTIO_PCI_ABI_VERSION,
+ .class_id = PCI_CLASS_COMMUNICATION_OTHER,
.qdev.props = (Property[]) {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
@@ -877,6 +865,10 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_balloon_init_pci,
.exit = virtio_exit_pci,
+ .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+ .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
+ .revision = VIRTIO_PCI_ABI_VERSION,
+ .class_id = PCI_CLASS_MEMORY_RAM,
.qdev.props = (Property[]) {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index a4b5fd30e1..b5189172de 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -37,7 +37,9 @@ typedef struct {
bool ioeventfd_started;
} VirtIOPCIProxy;
-extern void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
- uint16_t vendor, uint16_t device,
- uint16_t class_code, uint8_t pif);
+void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
+
+/* Virtio ABI version, if we increment this, we break the guest driver. */
+#define VIRTIO_PCI_ABI_VERSION 0
+
#endif
diff --git a/hw/virtio.c b/hw/virtio.c
index 6e8814cb64..e6043de827 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -71,7 +71,17 @@ struct VirtQueue
VRing vring;
target_phys_addr_t pa;
uint16_t last_avail_idx;
+ /* Last used index value we have signalled on */
+ uint16_t signalled_used;
+
+ /* Last used index value we have signalled on */
+ bool signalled_used_valid;
+
+ /* Notification enabled? */
+ bool notification;
+
int inuse;
+
uint16_t vector;
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
VirtIODevice *vdev;
@@ -140,6 +150,11 @@ static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
return lduw_phys(pa);
}
+static inline uint16_t vring_used_event(VirtQueue *vq)
+{
+ return vring_avail_ring(vq, vq->vring.num);
+}
+
static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
{
target_phys_addr_t pa;
@@ -161,11 +176,11 @@ static uint16_t vring_used_idx(VirtQueue *vq)
return lduw_phys(pa);
}
-static inline void vring_used_idx_increment(VirtQueue *vq, uint16_t val)
+static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val)
{
target_phys_addr_t pa;
pa = vq->vring.used + offsetof(VRingUsed, idx);
- stw_phys(pa, vring_used_idx(vq) + val);
+ stw_phys(pa, val);
}
static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
@@ -182,12 +197,26 @@ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask)
stw_phys(pa, lduw_phys(pa) & ~mask);
}
+static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
+{
+ target_phys_addr_t pa;
+ if (!vq->notification) {
+ return;
+ }
+ pa = vq->vring.used + offsetof(VRingUsed, ring[vq->vring.num]);
+ stw_phys(pa, val);
+}
+
void virtio_queue_set_notification(VirtQueue *vq, int enable)
{
- if (enable)
+ vq->notification = enable;
+ if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+ vring_avail_event(vq, vring_avail_idx(vq));
+ } else if (enable) {
vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
- else
+ } else {
vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY);
+ }
}
int virtio_queue_ready(VirtQueue *vq)
@@ -233,11 +262,16 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
void virtqueue_flush(VirtQueue *vq, unsigned int count)
{
+ uint16_t old, new;
/* Make sure buffer is written before we update index. */
wmb();
trace_virtqueue_flush(vq, count);
- vring_used_idx_increment(vq, count);
+ old = vring_used_idx(vq);
+ new = old + count;
+ vring_used_idx_set(vq, new);
vq->inuse -= count;
+ if (unlikely((int16_t)(new - vq->signalled_used) < (uint16_t)(new - old)))
+ vq->signalled_used_valid = false;
}
void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
@@ -394,6 +428,9 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
max = vq->vring.num;
i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
+ if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+ vring_avail_event(vq, vring_avail_idx(vq));
+ }
if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
@@ -477,6 +514,9 @@ void virtio_reset(void *opaque)
vdev->vq[i].last_avail_idx = 0;
vdev->vq[i].pa = 0;
vdev->vq[i].vector = VIRTIO_NO_VECTOR;
+ vdev->vq[i].signalled_used = 0;
+ vdev->vq[i].signalled_used_valid = false;
+ vdev->vq[i].notification = true;
}
}
@@ -585,9 +625,7 @@ void virtio_queue_notify_vq(VirtQueue *vq)
void virtio_queue_notify(VirtIODevice *vdev, int n)
{
- if (n < VIRTIO_PCI_QUEUE_MAX) {
- virtio_queue_notify_vq(&vdev->vq[n]);
- }
+ virtio_queue_notify_vq(&vdev->vq[n]);
}
uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
@@ -628,13 +666,45 @@ void virtio_irq(VirtQueue *vq)
virtio_notify_vector(vq->vdev, vq->vector);
}
-void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
+/* Assuming a given event_idx value from the other size, if
+ * we have just incremented index from old to new_idx,
+ * should we trigger an event? */
+static inline int vring_need_event(uint16_t event, uint16_t new, uint16_t old)
+{
+ /* Note: Xen has similar logic for notification hold-off
+ * in include/xen/interface/io/ring.h with req_event and req_prod
+ * corresponding to event_idx + 1 and new respectively.
+ * Note also that req_event and req_prod in Xen start at 1,
+ * event indexes in virtio start at 0. */
+ return (uint16_t)(new - event - 1) < (uint16_t)(new - old);
+}
+
+static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
{
+ uint16_t old, new;
+ bool v;
/* Always notify when queue is empty (when feature acknowledge) */
- if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
- (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
- (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
+ if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
+ !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
+ return true;
+ }
+
+ if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+ return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
+ }
+
+ v = vq->signalled_used_valid;
+ vq->signalled_used_valid = true;
+ old = vq->signalled_used;
+ new = vq->signalled_used = vring_used_idx(vq);
+ return !v || vring_need_event(vring_used_event(vq), new, old);
+}
+
+void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
+{
+ if (!vring_notify(vdev, vq)) {
return;
+ }
trace_virtio_notify(vdev, vq);
vdev->isr |= 0x01;
@@ -717,6 +787,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
vdev->vq[i].vring.num = qemu_get_be32(f);
vdev->vq[i].pa = qemu_get_be64(f);
qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+ vdev->vq[i].signalled_used_valid = false;
+ vdev->vq[i].notification = true;
if (vdev->vq[i].pa) {
uint16_t nheads;
@@ -789,6 +861,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
vdev->queue_sel = 0;
vdev->config_vector = VIRTIO_NO_VECTOR;
vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
+ vdev->vm_running = vm_running;
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
vdev->vq[i].vector = VIRTIO_NO_VECTOR;
vdev->vq[i].vdev = vdev;
diff --git a/hw/virtio.h b/hw/virtio.h
index bc722896c9..69e6bb1a4e 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -46,6 +46,11 @@
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
/* We support indirect buffer descriptors */
#define VIRTIO_RING_F_INDIRECT_DESC 28
+/* The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field. */
+/* The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field. */
+#define VIRTIO_RING_F_EVENT_IDX 29
/* A guest should never accept this. It implies negotiation is broken. */
#define VIRTIO_F_BAD_FEATURE 30
@@ -210,7 +215,9 @@ void virtio_serial_exit(VirtIODevice *vdev);
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
DEFINE_PROP_BIT("indirect_desc", _state, _field, \
- VIRTIO_RING_F_INDIRECT_DESC, true)
+ VIRTIO_RING_F_INDIRECT_DESC, true), \
+ DEFINE_PROP_BIT("event_idx", _state, _field, \
+ VIRTIO_RING_F_EVENT_IDX, true)
target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 4656767964..354c221720 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1280,15 +1280,8 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
struct pci_vmsvga_state_s *s =
DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
- pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE);
- pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID);
- pci_config_set_class(s->card.config, PCI_CLASS_DISPLAY_VGA);
s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */
- s->card.config[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_VMWARE & 0xff;
- s->card.config[PCI_SUBSYSTEM_VENDOR_ID + 1] = PCI_VENDOR_ID_VMWARE >> 8;
- s->card.config[PCI_SUBSYSTEM_ID] = SVGA_PCI_DEVICE_ID & 0xff;
- s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID >> 8;
s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */
pci_register_bar(&s->card, 0, 0x10,
@@ -1316,6 +1309,12 @@ static PCIDeviceInfo vmsvga_info = {
.no_hotplug = 1,
.init = pci_vmsvga_initfn,
.romfile = "vgabios-vmware.bin",
+
+ .vendor_id = PCI_VENDOR_ID_VMWARE,
+ .device_id = SVGA_PCI_DEVICE_ID,
+ .class_id = PCI_CLASS_DISPLAY_VGA,
+ .subsystem_vendor_id = PCI_VENDOR_ID_VMWARE,
+ .subsystem_id = SVGA_PCI_DEVICE_ID,
};
static void vmsvga_register(void)
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index ca8f826a07..5c973ed507 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -326,11 +326,6 @@ static int vt82c686b_ac97_initfn(PCIDevice *dev)
VT686AC97State *s = DO_UPCAST(VT686AC97State, dev, dev);
uint8_t *pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_AC97);
- pci_config_set_class(pci_conf, PCI_CLASS_MULTIMEDIA_AUDIO);
- pci_config_set_revision(pci_conf, 0x50);
-
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE |
PCI_COMMAND_PARITY);
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST |
@@ -353,6 +348,10 @@ static PCIDeviceInfo via_ac97_info = {
.qdev.desc = "AC97",
.qdev.size = sizeof(VT686AC97State),
.init = vt82c686b_ac97_initfn,
+ .vendor_id = PCI_VENDOR_ID_VIA,
+ .device_id = PCI_DEVICE_ID_VIA_AC97,
+ .revision = 0x50,
+ .class_id = PCI_CLASS_MULTIMEDIA_AUDIO,
};
static void vt82c686b_ac97_register(void)
@@ -367,11 +366,6 @@ static int vt82c686b_mc97_initfn(PCIDevice *dev)
VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev);
uint8_t *pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_MC97);
- pci_config_set_class(pci_conf, PCI_CLASS_COMMUNICATION_OTHER);
- pci_config_set_revision(pci_conf, 0x30);
-
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE |
PCI_COMMAND_VGA_PALETTE);
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
@@ -393,6 +387,10 @@ static PCIDeviceInfo via_mc97_info = {
.qdev.desc = "MC97",
.qdev.size = sizeof(VT686MC97State),
.init = vt82c686b_mc97_initfn,
+ .vendor_id = PCI_VENDOR_ID_VIA,
+ .device_id = PCI_DEVICE_ID_VIA_MC97,
+ .class_id = PCI_CLASS_COMMUNICATION_OTHER,
+ .revision = 0x30,
};
static void vt82c686b_mc97_register(void)
@@ -409,11 +407,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
uint8_t *pci_conf;
pci_conf = s->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ACPI);
- pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
- pci_config_set_revision(pci_conf, 0x40);
-
pci_set_word(pci_conf + PCI_COMMAND, 0);
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
PCI_STATUS_DEVSEL_MEDIUM);
@@ -462,6 +455,10 @@ static PCIDeviceInfo via_pm_info = {
.qdev.vmsd = &vmstate_acpi,
.init = vt82c686b_pm_initfn,
.config_write = pm_write_config,
+ .vendor_id = PCI_VENDOR_ID_VIA,
+ .device_id = PCI_DEVICE_ID_VIA_ACPI,
+ .class_id = PCI_CLASS_BRIDGE_OTHER,
+ .revision = 0x40,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
DEFINE_PROP_END_OF_LIST(),
@@ -496,11 +493,7 @@ static int vt82c686b_initfn(PCIDevice *d)
isa_bus_new(&d->qdev);
pci_conf = d->config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ISA_BRIDGE);
- pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
pci_config_set_prog_interface(pci_conf, 0x0);
- pci_config_set_revision(pci_conf,0x40); /* Revision 4.0 */
wmask = d->wmask;
for (i = 0x00; i < 0xff; i++) {
@@ -531,6 +524,10 @@ static PCIDeviceInfo via_info = {
.qdev.no_user = 1,
.init = vt82c686b_initfn,
.config_write = vt82c686b_write_config,
+ .vendor_id = PCI_VENDOR_ID_VIA,
+ .device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE,
+ .class_id = PCI_CLASS_BRIDGE_ISA,
+ .revision = 0x40,
};
static void vt82c686b_register(void)
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 07917212c3..53786ce8fa 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -381,7 +381,6 @@ static const VMStateDescription vmstate_i6300esb = {
static int i6300esb_init(PCIDevice *dev)
{
I6300State *d = DO_UPCAST(I6300State, dev, dev);
- uint8_t *pci_conf;
int io_mem;
static CPUReadMemoryFunc * const mem_read[3] = {
i6300esb_mem_readb,
@@ -399,11 +398,6 @@ static int i6300esb_init(PCIDevice *dev)
d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
d->previous_reboot_flag = 0;
- pci_conf = d->dev.config;
- pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
- pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9);
- pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER);
-
io_mem = cpu_register_io_memory(mem_read, mem_write, d,
DEVICE_NATIVE_ENDIAN);
pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem);
@@ -425,6 +419,9 @@ static PCIDeviceInfo i6300esb_info = {
.config_read = i6300esb_config_read,
.config_write = i6300esb_config_write,
.init = i6300esb_init,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_ESB_9,
+ .class_id = PCI_CLASS_SYSTEM_OTHER,
};
static void i6300esb_register_devices(void)
diff --git a/hw/xen_common.h b/hw/xen_common.h
index a1958a0af1..2c79af64d0 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -71,6 +71,20 @@ static inline int xc_domain_populate_physmap_exact
(xc_handle, domid, nr_extents, extent_order, mem_flags, extent_start);
}
+static inline int xc_domain_add_to_physmap(int xc_handle, uint32_t domid,
+ unsigned int space, unsigned long idx,
+ xen_pfn_t gpfn)
+{
+ struct xen_add_to_physmap xatp = {
+ .domid = domid,
+ .space = space,
+ .idx = idx,
+ .gpfn = gpfn,
+ };
+
+ return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
+}
+
/* Xen 4.1 */
#else
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
new file mode 100644
index 0000000000..b167eee1ff
--- /dev/null
+++ b/hw/xen_platform.c
@@ -0,0 +1,340 @@
+/*
+ * XEN platform pci device, formerly known as the event channel device
+ *
+ * Copyright (c) 2003-2004 Intel Corp.
+ * Copyright (c) 2006 XenSource
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "hw.h"
+#include "pc.h"
+#include "pci.h"
+#include "irq.h"
+#include "xen_common.h"
+#include "net.h"
+#include "xen_backend.h"
+#include "rwhandler.h"
+#include "trace.h"
+
+#include <xenguest.h>
+
+//#define DEBUG_PLATFORM
+
+#ifdef DEBUG_PLATFORM
+#define DPRINTF(fmt, ...) do { \
+ fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
+
+typedef struct PCIXenPlatformState {
+ PCIDevice pci_dev;
+ uint8_t flags; /* used only for version_id == 2 */
+ int drivers_blacklisted;
+ uint16_t driver_product_version;
+
+ /* Log from guest drivers */
+ char log_buffer[4096];
+ int log_buffer_off;
+} PCIXenPlatformState;
+
+#define XEN_PLATFORM_IOPORT 0x10
+
+/* Send bytes to syslog */
+static void log_writeb(PCIXenPlatformState *s, char val)
+{
+ if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
+ /* Flush buffer */
+ s->log_buffer[s->log_buffer_off] = 0;
+ trace_xen_platform_log(s->log_buffer);
+ s->log_buffer_off = 0;
+ } else {
+ s->log_buffer[s->log_buffer_off++] = val;
+ }
+}
+
+/* Xen Platform, Fixed IOPort */
+
+static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+ PCIXenPlatformState *s = opaque;
+
+ switch (addr - XEN_PLATFORM_IOPORT) {
+ case 0:
+ /* TODO: */
+ /* Unplug devices. Value is a bitmask of which devices to
+ unplug, with bit 0 the IDE devices, bit 1 the network
+ devices, and bit 2 the non-primary-master IDE devices. */
+ break;
+ case 2:
+ switch (val) {
+ case 1:
+ DPRINTF("Citrix Windows PV drivers loaded in guest\n");
+ break;
+ case 0:
+ DPRINTF("Guest claimed to be running PV product 0?\n");
+ break;
+ default:
+ DPRINTF("Unknown PV product %d loaded in guest\n", val);
+ break;
+ }
+ s->driver_product_version = val;
+ break;
+ }
+}
+
+static void platform_fixed_ioport_writel(void *opaque, uint32_t addr,
+ uint32_t val)
+{
+ switch (addr - XEN_PLATFORM_IOPORT) {
+ case 0:
+ /* PV driver version */
+ break;
+ }
+}
+
+static void platform_fixed_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ PCIXenPlatformState *s = opaque;
+
+ switch (addr - XEN_PLATFORM_IOPORT) {
+ case 0: /* Platform flags */ {
+ hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
+ HVMMEM_ram_ro : HVMMEM_ram_rw;
+ if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type, 0xc0, 0x40)) {
+ DPRINTF("unable to change ro/rw state of ROM memory area!\n");
+ } else {
+ s->flags = val & PFFLAG_ROM_LOCK;
+ DPRINTF("changed ro/rw state of ROM memory area. now is %s state.\n",
+ (mem_type == HVMMEM_ram_ro ? "ro":"rw"));
+ }
+ break;
+ }
+ case 2:
+ log_writeb(s, val);
+ break;
+ }
+}
+
+static uint32_t platform_fixed_ioport_readw(void *opaque, uint32_t addr)
+{
+ PCIXenPlatformState *s = opaque;
+
+ switch (addr - XEN_PLATFORM_IOPORT) {
+ case 0:
+ if (s->drivers_blacklisted) {
+ /* The drivers will recognise this magic number and refuse
+ * to do anything. */
+ return 0xd249;
+ } else {
+ /* Magic value so that you can identify the interface. */
+ return 0x49d2;
+ }
+ default:
+ return 0xffff;
+ }
+}
+
+static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
+{
+ PCIXenPlatformState *s = opaque;
+
+ switch (addr - XEN_PLATFORM_IOPORT) {
+ case 0:
+ /* Platform flags */
+ return s->flags;
+ case 2:
+ /* Version number */
+ return 1;
+ default:
+ return 0xff;
+ }
+}
+
+static void platform_fixed_ioport_reset(void *opaque)
+{
+ PCIXenPlatformState *s = opaque;
+
+ platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
+}
+
+static void platform_fixed_ioport_init(PCIXenPlatformState* s)
+{
+ register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
+ register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
+ register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
+ register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
+ register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+}
+
+/* Xen Platform PCI Device */
+
+static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+{
+ addr &= 0xff;
+
+ if (addr == 0) {
+ return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
+ } else {
+ return ~0u;
+ }
+}
+
+static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ PCIXenPlatformState *s = opaque;
+
+ addr &= 0xff;
+ val &= 0xff;
+
+ switch (addr) {
+ case 0: /* Platform flags */
+ platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
+ break;
+ case 8:
+ log_writeb(s, val);
+ break;
+ default:
+ break;
+ }
+}
+
+static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
+{
+ PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+
+ register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
+ register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+}
+
+static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+{
+ DPRINTF("Warning: attempted read from physical address "
+ "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
+
+ return 0;
+}
+
+static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
+ uint32_t val, int len)
+{
+ DPRINTF("Warning: attempted write of 0x%x to physical "
+ "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
+ val, addr);
+}
+
+static ReadWriteHandler platform_mmio_handler = {
+ .read = &platform_mmio_read,
+ .write = &platform_mmio_write,
+};
+
+static void platform_mmio_map(PCIDevice *d, int region_num,
+ pcibus_t addr, pcibus_t size, int type)
+{
+ int mmio_io_addr;
+
+ mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
+ DEVICE_NATIVE_ENDIAN);
+
+ cpu_register_physical_memory(addr, size, mmio_io_addr);
+}
+
+static int xen_platform_post_load(void *opaque, int version_id)
+{
+ PCIXenPlatformState *s = opaque;
+
+ platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, s->flags);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_xen_platform = {
+ .name = "platform",
+ .version_id = 4,
+ .minimum_version_id = 4,
+ .minimum_version_id_old = 4,
+ .post_load = xen_platform_post_load,
+ .fields = (VMStateField []) {
+ VMSTATE_PCI_DEVICE(pci_dev, PCIXenPlatformState),
+ VMSTATE_UINT8(flags, PCIXenPlatformState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static int xen_platform_initfn(PCIDevice *dev)
+{
+ PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, dev);
+ uint8_t *pci_conf;
+
+ pci_conf = d->pci_dev.config;
+
+ pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
+ pci_config_set_device_id(pci_conf, 0x0001);
+ pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
+ pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
+
+ pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+ pci_config_set_revision(pci_conf, 1);
+ pci_config_set_prog_interface(pci_conf, 0);
+
+ pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
+
+ pci_conf[PCI_INTERRUPT_PIN] = 1;
+
+ pci_register_bar(&d->pci_dev, 0, 0x100,
+ PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+
+ /* reserve 16MB mmio address for share memory*/
+ pci_register_bar(&d->pci_dev, 1, 0x1000000,
+ PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+
+ platform_fixed_ioport_init(d);
+
+ return 0;
+}
+
+static void platform_reset(DeviceState *dev)
+{
+ PCIXenPlatformState *s = DO_UPCAST(PCIXenPlatformState, pci_dev.qdev, dev);
+
+ platform_fixed_ioport_reset(s);
+}
+
+static PCIDeviceInfo xen_platform_info = {
+ .init = xen_platform_initfn,
+ .qdev.name = "xen-platform",
+ .qdev.desc = "XEN platform pci device",
+ .qdev.size = sizeof(PCIXenPlatformState),
+ .qdev.vmsd = &vmstate_xen_platform,
+ .qdev.reset = platform_reset,
+};
+
+static void xen_platform_register(void)
+{
+ pci_qdev_register(&xen_platform_info);
+}
+
+device_init(xen_platform_register);
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index 5aa6a6b149..d3c387d6cb 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -69,9 +69,6 @@ static int xio3130_downstream_initfn(PCIDevice *d)
}
pcie_port_init_reg(d);
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130D);
- d->config[PCI_REVISION_ID] = XIO3130_REVISION;
rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
@@ -182,6 +179,9 @@ static PCIDeviceInfo xio3130_downstream_info = {
.config_write = xio3130_downstream_write_config,
.init = xio3130_downstream_initfn,
.exit = xio3130_downstream_exitfn,
+ .vendor_id = PCI_VENDOR_ID_TI,
+ .device_id = PCI_DEVICE_ID_TI_XIO3130D,
+ .revision = XIO3130_REVISION,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index a7640f518a..82836958a4 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -65,9 +65,6 @@ static int xio3130_upstream_initfn(PCIDevice *d)
}
pcie_port_init_reg(d);
- pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI);
- pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130U);
- d->config[PCI_REVISION_ID] = XIO3130_REVISION;
rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
@@ -159,6 +156,9 @@ static PCIDeviceInfo xio3130_upstream_info = {
.config_write = xio3130_upstream_write_config,
.init = xio3130_upstream_initfn,
.exit = xio3130_upstream_exitfn,
+ .vendor_id = PCI_VENDOR_ID_TI,
+ .device_id = PCI_DEVICE_ID_TI_XIO3130U,
+ .revision = XIO3130_REVISION,
.qdev.props = (Property[]) {
DEFINE_PROP_UINT8("port", PCIEPort, port, 0),