diff options
Diffstat (limited to 'hw')
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), @@ -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) @@ -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) @@ -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"); @@ -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(), @@ -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 */ } }, @@ -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 */ @@ -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 = { @@ -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), |