mirror of https://github.com/xqemu/xqemu.git
pc, pci, virtio: features, fixes, cleanups
A bunch of fixes, cleanus and new features all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJaV8NpAAoJECgfDbjSjVRpve8IAMuT4Na9gn0SGZnzarF5Bn4H D7oIOHCVkJPFZXD4Eqv39JFJJbDKPszSSHuoYt8zqXd4N6ZOBiV39cVhUCV1f/7H /gzfTGr+s1NzxKKhdjh4jNM0RgUQR5j11Dz3G4wbTtx2LA2kYm/zWsnqNJwYo4tX SbwmU7RHa/5O3aJQ1LQgWJ7uPwuIuc84gWciKKRiYa3f7WNu+5j1dLhKtop5Boww AlK63tLfLyQczo1k+PUak1j5kD2v6dNZX1wRS6QZkA1Bj0GnHlE5bBycu8l4B88F mBYCLVBY4bOhweKSzxM2a90Q3uz+HffMl04M4drPnaEqltbsYDrSwiC8RJqMIjo= =Jkdo -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pc, pci, virtio: features, fixes, cleanups A bunch of fixes, cleanus and new features all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Thu 11 Jan 2018 20:04:57 GMT # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: (23 commits) smbus: do not immediately complete commands dump-guest-memory.py: fix "You can't do that without a process to debug" virtio-pci: Don't force Subsystem Vendor ID = Vendor ID intel_iommu: fix error param in string intel_iommu: remove X86_IOMMU_PCI_DEVFN_MAX vhost-user: document memory accesses vhost-user: fix indentation in protocol specification hw/pci-host/xilinx: QOM'ify the AXI-PCIe host bridge hw/pci-host/piix: QOM'ify the IGD Passthrough host bridge tests/pxe-test: Add some extra tests tests/pxe-test: Test net booting over IPv6 in some cases tests/pxe-test: Use table of testcases rather than open-coding tests/pxe-test: Remove unnecessary special case test functions virtio_error: don't invoke status callbacks pci: Eliminate pci_find_primary_bus() pci: Eliminate redundant PCIDevice::bus pointer pci: Add pci_dev_bus_num() helper pci: Move bridge data structures from pci_bus.h to pci_bridge.h pci: Rename root bus initialization functions for clarity tests: add test to check VirtQueue object ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
36b5e43af8
|
@ -66,11 +66,14 @@ Depending on the request type, payload can be:
|
||||||
|
|
||||||
Index: a 32-bit vring index
|
Index: a 32-bit vring index
|
||||||
Flags: a 32-bit vring flags
|
Flags: a 32-bit vring flags
|
||||||
Descriptor: a 64-bit user address of the vring descriptor table
|
Descriptor: a 64-bit ring address of the vring descriptor table
|
||||||
Used: a 64-bit user address of the vring used ring
|
Used: a 64-bit ring address of the vring used ring
|
||||||
Available: a 64-bit user address of the vring available ring
|
Available: a 64-bit ring address of the vring available ring
|
||||||
Log: a 64-bit guest address for logging
|
Log: a 64-bit guest address for logging
|
||||||
|
|
||||||
|
Note that a ring address is an IOVA if VIRTIO_F_IOMMU_PLATFORM has been
|
||||||
|
negotiated. Otherwise it is a user address.
|
||||||
|
|
||||||
* Memory regions description
|
* Memory regions description
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
| num regions | padding | region0 | ... | region7 |
|
| num regions | padding | region0 | ... | region7 |
|
||||||
|
@ -273,6 +276,30 @@ Once the source has finished migration, rings will be stopped by
|
||||||
the source. No further update must be done before rings are
|
the source. No further update must be done before rings are
|
||||||
restarted.
|
restarted.
|
||||||
|
|
||||||
|
Memory access
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The master sends a list of vhost memory regions to the slave using the
|
||||||
|
VHOST_USER_SET_MEM_TABLE message. Each region has two base addresses: a guest
|
||||||
|
address and a user address.
|
||||||
|
|
||||||
|
Messages contain guest addresses and/or user addresses to reference locations
|
||||||
|
within the shared memory. The mapping of these addresses works as follows.
|
||||||
|
|
||||||
|
User addresses map to the vhost memory region containing that user address.
|
||||||
|
|
||||||
|
When the VIRTIO_F_IOMMU_PLATFORM feature has not been negotiated:
|
||||||
|
|
||||||
|
* Guest addresses map to the vhost memory region containing that guest
|
||||||
|
address.
|
||||||
|
|
||||||
|
When the VIRTIO_F_IOMMU_PLATFORM feature has been negotiated:
|
||||||
|
|
||||||
|
* Guest addresses are also called I/O virtual addresses (IOVAs). They are
|
||||||
|
translated to user addresses via the IOTLB.
|
||||||
|
|
||||||
|
* The vhost memory region guest address is not used.
|
||||||
|
|
||||||
IOMMU support
|
IOMMU support
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||||
{
|
{
|
||||||
PCIDevice *pdev = PCI_DEVICE(dev);
|
PCIDevice *pdev = PCI_DEVICE(dev);
|
||||||
int slot = PCI_SLOT(pdev->devfn);
|
int slot = PCI_SLOT(pdev->devfn);
|
||||||
int bsel = acpi_pcihp_get_bsel(pdev->bus);
|
int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
|
||||||
if (bsel < 0) {
|
if (bsel < 0) {
|
||||||
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
|
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
|
||||||
ACPI_PCIHP_PROP_BSEL "' set");
|
ACPI_PCIHP_PROP_BSEL "' set");
|
||||||
|
@ -246,7 +246,7 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||||
{
|
{
|
||||||
PCIDevice *pdev = PCI_DEVICE(dev);
|
PCIDevice *pdev = PCI_DEVICE(dev);
|
||||||
int slot = PCI_SLOT(pdev->devfn);
|
int slot = PCI_SLOT(pdev->devfn);
|
||||||
int bsel = acpi_pcihp_get_bsel(pdev->bus);
|
int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
|
||||||
if (bsel < 0) {
|
if (bsel < 0) {
|
||||||
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
|
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
|
||||||
ACPI_PCIHP_PROP_BSEL "' set");
|
ACPI_PCIHP_PROP_BSEL "' set");
|
||||||
|
|
|
@ -460,9 +460,9 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
|
||||||
(memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
|
(memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
|
||||||
|
|
||||||
if (s->use_acpi_pci_hotplug) {
|
if (s->use_acpi_pci_hotplug) {
|
||||||
pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
|
pci_for_each_bus(pci_get_bus(d), piix4_update_bus_hotplug, s);
|
||||||
} else {
|
} else {
|
||||||
piix4_update_bus_hotplug(d->bus, s);
|
piix4_update_bus_hotplug(pci_get_bus(d), s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +535,8 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
|
||||||
qemu_add_machine_init_done_notifier(&s->machine_ready);
|
qemu_add_machine_init_done_notifier(&s->machine_ready);
|
||||||
qemu_register_reset(piix4_reset, s);
|
qemu_register_reset(piix4_reset, s);
|
||||||
|
|
||||||
piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
|
piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
|
||||||
|
pci_get_bus(dev), s);
|
||||||
|
|
||||||
piix4_pm_add_propeties(s);
|
piix4_pm_add_propeties(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,21 +162,6 @@ static void vmgenid_update_guest(VmGenIdState *vms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmgenid_set_guid(Object *obj, const char *value, Error **errp)
|
|
||||||
{
|
|
||||||
VmGenIdState *vms = VMGENID(obj);
|
|
||||||
|
|
||||||
if (!strcmp(value, "auto")) {
|
|
||||||
qemu_uuid_generate(&vms->guid);
|
|
||||||
} else if (qemu_uuid_parse(value, &vms->guid) < 0) {
|
|
||||||
error_setg(errp, "'%s. %s': Failed to parse GUID string: %s",
|
|
||||||
object_get_typename(OBJECT(vms)), VMGENID_GUID, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vmgenid_update_guest(vms);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After restoring an image, we need to update the guest memory and notify
|
/* After restoring an image, we need to update the guest memory and notify
|
||||||
* it of a potential change to VM Generation ID
|
* it of a potential change to VM Generation ID
|
||||||
*/
|
*/
|
||||||
|
@ -224,23 +209,24 @@ static void vmgenid_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_register_reset(vmgenid_handle_reset, vms);
|
qemu_register_reset(vmgenid_handle_reset, vms);
|
||||||
|
|
||||||
|
vmgenid_update_guest(vms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Property vmgenid_device_properties[] = {
|
||||||
|
DEFINE_PROP_UUID(VMGENID_GUID, VmGenIdState, guid),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
static void vmgenid_device_class_init(ObjectClass *klass, void *data)
|
static void vmgenid_device_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
dc->vmsd = &vmstate_vmgenid;
|
dc->vmsd = &vmstate_vmgenid;
|
||||||
dc->realize = vmgenid_realize;
|
dc->realize = vmgenid_realize;
|
||||||
|
dc->props = vmgenid_device_properties;
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||||
|
|
||||||
object_class_property_add_str(klass, VMGENID_GUID, NULL,
|
|
||||||
vmgenid_set_guid, NULL);
|
|
||||||
object_class_property_set_description(klass, VMGENID_GUID,
|
|
||||||
"Set Global Unique Identifier "
|
|
||||||
"(big-endian) or auto for random value",
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo vmgenid_device_info = {
|
static const TypeInfo vmgenid_device_info = {
|
||||||
|
|
|
@ -881,7 +881,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
|
||||||
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
|
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
|
||||||
&s->pchip.reg_io);
|
&s->pchip.reg_io);
|
||||||
|
|
||||||
b = pci_register_bus(dev, "pci",
|
b = pci_register_root_bus(dev, "pci",
|
||||||
typhoon_set_irq, sys_map_irq, s,
|
typhoon_set_irq, sys_map_irq, s,
|
||||||
&s->pchip.reg_mem, &s->pchip.reg_io,
|
&s->pchip.reg_mem, &s->pchip.reg_io,
|
||||||
0, 64, TYPE_PCI_BUS);
|
0, 64, TYPE_PCI_BUS);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "net/hub.h"
|
#include "net/hub.h"
|
||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
#include "chardev/char.h"
|
#include "chardev/char.h"
|
||||||
|
#include "qemu/uuid.h"
|
||||||
|
|
||||||
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
|
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
|
@ -883,6 +884,66 @@ const PropertyInfo qdev_prop_pci_host_devaddr = {
|
||||||
.set = set_pci_host_devaddr,
|
.set = set_pci_host_devaddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* --- UUID --- */
|
||||||
|
|
||||||
|
static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
DeviceState *dev = DEVICE(obj);
|
||||||
|
Property *prop = opaque;
|
||||||
|
QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
|
||||||
|
char buffer[UUID_FMT_LEN + 1];
|
||||||
|
char *p = buffer;
|
||||||
|
|
||||||
|
qemu_uuid_unparse(uuid, buffer);
|
||||||
|
|
||||||
|
visit_type_str(v, name, &p, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UUID_VALUE_AUTO "auto"
|
||||||
|
|
||||||
|
static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
DeviceState *dev = DEVICE(obj);
|
||||||
|
Property *prop = opaque;
|
||||||
|
QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if (dev->realized) {
|
||||||
|
qdev_prop_set_after_realize(dev, name, errp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit_type_str(v, name, &str, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(str, UUID_VALUE_AUTO)) {
|
||||||
|
qemu_uuid_generate(uuid);
|
||||||
|
} else if (qemu_uuid_parse(str, uuid) < 0) {
|
||||||
|
error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
|
||||||
|
}
|
||||||
|
g_free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_default_uuid_auto(Object *obj, const Property *prop)
|
||||||
|
{
|
||||||
|
object_property_set_str(obj, UUID_VALUE_AUTO, prop->name, &error_abort);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PropertyInfo qdev_prop_uuid = {
|
||||||
|
.name = "str",
|
||||||
|
.description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
|
||||||
|
"\" for random value (default)",
|
||||||
|
.get = get_uuid,
|
||||||
|
.set = set_uuid,
|
||||||
|
.set_default_value = set_default_uuid_auto,
|
||||||
|
};
|
||||||
|
|
||||||
/* --- support for array properties --- */
|
/* --- support for array properties --- */
|
||||||
|
|
||||||
/* Used as an opaque for the object properties we add for each
|
/* Used as an opaque for the object properties we add for each
|
||||||
|
|
|
@ -62,6 +62,9 @@ static void smb_transaction(PMSMBus *s)
|
||||||
I2CBus *bus = s->smbus;
|
I2CBus *bus = s->smbus;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
assert(s->smb_stat & STS_HOST_BUSY);
|
||||||
|
s->smb_stat &= ~STS_HOST_BUSY;
|
||||||
|
|
||||||
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
|
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
|
||||||
/* Transaction isn't exec if STS_DEV_ERR bit set */
|
/* Transaction isn't exec if STS_DEV_ERR bit set */
|
||||||
if ((s->smb_stat & STS_DEV_ERR) != 0) {
|
if ((s->smb_stat & STS_DEV_ERR) != 0) {
|
||||||
|
@ -134,6 +137,13 @@ error:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smb_transaction_start(PMSMBus *s)
|
||||||
|
{
|
||||||
|
/* Do not execute immediately the command ; it will be
|
||||||
|
* executed when guest will read SMB_STAT register */
|
||||||
|
s->smb_stat |= STS_HOST_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
|
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
|
||||||
unsigned width)
|
unsigned width)
|
||||||
{
|
{
|
||||||
|
@ -149,7 +159,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
|
||||||
case SMBHSTCNT:
|
case SMBHSTCNT:
|
||||||
s->smb_ctl = val;
|
s->smb_ctl = val;
|
||||||
if (val & 0x40)
|
if (val & 0x40)
|
||||||
smb_transaction(s);
|
smb_transaction_start(s);
|
||||||
break;
|
break;
|
||||||
case SMBHSTCMD:
|
case SMBHSTCMD:
|
||||||
s->smb_cmd = val;
|
s->smb_cmd = val;
|
||||||
|
@ -181,6 +191,10 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case SMBHSTSTS:
|
case SMBHSTSTS:
|
||||||
val = s->smb_stat;
|
val = s->smb_stat;
|
||||||
|
if (s->smb_stat & STS_HOST_BUSY) {
|
||||||
|
/* execute command now */
|
||||||
|
smb_transaction(s);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SMBHSTCNT:
|
case SMBHSTCNT:
|
||||||
s->smb_index = 0;
|
s->smb_index = 0;
|
||||||
|
|
|
@ -186,7 +186,7 @@ static void vtd_reset_context_cache(IntelIOMMUState *s)
|
||||||
g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);
|
g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);
|
||||||
|
|
||||||
while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
|
while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
|
||||||
for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
|
for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
|
||||||
vtd_as = vtd_bus->dev_as[devfn_it];
|
vtd_as = vtd_bus->dev_as[devfn_it];
|
||||||
if (!vtd_as) {
|
if (!vtd_as) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1002,7 +1002,7 @@ static void vtd_switch_address_space_all(IntelIOMMUState *s)
|
||||||
|
|
||||||
g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
|
g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
|
||||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
|
while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
|
||||||
for (i = 0; i < X86_IOMMU_PCI_DEVFN_MAX; i++) {
|
for (i = 0; i < PCI_DEVFN_MAX; i++) {
|
||||||
if (!vtd_bus->dev_as[i]) {
|
if (!vtd_bus->dev_as[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1294,7 +1294,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
|
||||||
vtd_bus = vtd_find_as_from_bus_num(s, bus_n);
|
vtd_bus = vtd_find_as_from_bus_num(s, bus_n);
|
||||||
if (vtd_bus) {
|
if (vtd_bus) {
|
||||||
devfn = VTD_SID_TO_DEVFN(source_id);
|
devfn = VTD_SID_TO_DEVFN(source_id);
|
||||||
for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
|
for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
|
||||||
vtd_as = vtd_bus->dev_as[devfn_it];
|
vtd_as = vtd_bus->dev_as[devfn_it];
|
||||||
if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
|
if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
|
||||||
trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it),
|
trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it),
|
||||||
|
@ -2327,7 +2327,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||||
IntelIOMMUNotifierNode *next_node = NULL;
|
IntelIOMMUNotifierNode *next_node = NULL;
|
||||||
|
|
||||||
if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
|
if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
|
||||||
error_report("We need to set cache_mode=1 for intel-iommu to enable "
|
error_report("We need to set caching-mode=1 for intel-iommu to enable "
|
||||||
"device assignment with IOMMU protection.");
|
"device assignment with IOMMU protection.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -2699,7 +2699,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
|
||||||
*new_key = (uintptr_t)bus;
|
*new_key = (uintptr_t)bus;
|
||||||
/* No corresponding free() */
|
/* No corresponding free() */
|
||||||
vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
|
vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
|
||||||
X86_IOMMU_PCI_DEVFN_MAX);
|
PCI_DEVFN_MAX);
|
||||||
vtd_bus->bus = bus;
|
vtd_bus->bus = bus;
|
||||||
g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
|
g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
|
||||||
}
|
}
|
||||||
|
@ -2982,7 +2982,7 @@ static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
||||||
IntelIOMMUState *s = opaque;
|
IntelIOMMUState *s = opaque;
|
||||||
VTDAddressSpace *vtd_as;
|
VTDAddressSpace *vtd_as;
|
||||||
|
|
||||||
assert(0 <= devfn && devfn < X86_IOMMU_PCI_DEVFN_MAX);
|
assert(0 <= devfn && devfn < PCI_DEVFN_MAX);
|
||||||
|
|
||||||
vtd_as = vtd_find_add_as(s, bus, devfn);
|
vtd_as = vtd_find_add_as(s, bus, devfn);
|
||||||
return &vtd_as->as;
|
return &vtd_as->as;
|
||||||
|
|
|
@ -394,7 +394,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
|
||||||
|
|
||||||
static void pc_xen_hvm_init(MachineState *machine)
|
static void pc_xen_hvm_init(MachineState *machine)
|
||||||
{
|
{
|
||||||
PCIBus *bus;
|
PCMachineState *pcms = PC_MACHINE(machine);
|
||||||
|
|
||||||
if (!xen_enabled()) {
|
if (!xen_enabled()) {
|
||||||
error_report("xenfv machine requires the xen accelerator");
|
error_report("xenfv machine requires the xen accelerator");
|
||||||
|
@ -402,11 +402,7 @@ static void pc_xen_hvm_init(MachineState *machine)
|
||||||
}
|
}
|
||||||
|
|
||||||
pc_xen_hvm_init_pci(machine);
|
pc_xen_hvm_init_pci(machine);
|
||||||
|
pci_create_simple(pcms->bus, -1, "xen-platform");
|
||||||
bus = pci_find_primary_bus();
|
|
||||||
if (bus != NULL) {
|
|
||||||
pci_create_simple(bus, -1, "xen-platform");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -185,11 +185,11 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
|
||||||
if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
|
if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
|
||||||
UNPLUG_NVME_DISKS)) {
|
UNPLUG_NVME_DISKS)) {
|
||||||
DPRINTF("unplug disks\n");
|
DPRINTF("unplug disks\n");
|
||||||
pci_unplug_disks(pci_dev->bus, val);
|
pci_unplug_disks(pci_get_bus(pci_dev), val);
|
||||||
}
|
}
|
||||||
if (val & UNPLUG_ALL_NICS) {
|
if (val & UNPLUG_ALL_NICS) {
|
||||||
DPRINTF("unplug nics\n");
|
DPRINTF("unplug nics\n");
|
||||||
pci_unplug_nics(pci_dev->bus);
|
pci_unplug_nics(pci_get_bus(pci_dev));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -371,17 +371,17 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
|
||||||
* If VMDP was to control both disk and LAN it would use 4.
|
* If VMDP was to control both disk and LAN it would use 4.
|
||||||
* If it controlled just disk or just LAN, it would use 8 below.
|
* If it controlled just disk or just LAN, it would use 8 below.
|
||||||
*/
|
*/
|
||||||
pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
|
pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
|
||||||
pci_unplug_nics(pci_dev->bus);
|
pci_unplug_nics(pci_get_bus(pci_dev));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 1:
|
case 1:
|
||||||
pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
|
pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
pci_unplug_nics(pci_dev->bus);
|
pci_unplug_nics(pci_get_bus(pci_dev));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_writeb(s, (uint32_t)val);
|
log_writeb(s, (uint32_t)val);
|
||||||
|
|
|
@ -162,7 +162,7 @@ static void ich9_cc_write(void *opaque, hwaddr addr,
|
||||||
|
|
||||||
ich9_cc_addr_len(&addr, &len);
|
ich9_cc_addr_len(&addr, &len);
|
||||||
memcpy(lpc->chip_config + addr, &val, len);
|
memcpy(lpc->chip_config + addr, &val, len);
|
||||||
pci_bus_fire_intx_routing_notifier(lpc->d.bus);
|
pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
|
||||||
ich9_cc_update(lpc);
|
ich9_cc_update(lpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi)
|
||||||
int tmp_dis;
|
int tmp_dis;
|
||||||
ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
|
ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
|
||||||
if (!tmp_dis && tmp_irq == gsi) {
|
if (!tmp_dis && tmp_irq == gsi) {
|
||||||
pic_level |= pci_bus_get_irq_level(lpc->d.bus, i);
|
pic_level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gsi == lpc->sci_gsi) {
|
if (gsi == lpc->sci_gsi) {
|
||||||
|
@ -246,7 +246,7 @@ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
|
||||||
|
|
||||||
assert(gsi >= ICH9_LPC_PIC_NUM_PINS);
|
assert(gsi >= ICH9_LPC_PIC_NUM_PINS);
|
||||||
|
|
||||||
level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
|
level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), ich9_gsi_to_pirq(gsi));
|
||||||
if (gsi == lpc->sci_gsi) {
|
if (gsi == lpc->sci_gsi) {
|
||||||
level |= lpc->sci_level;
|
level |= lpc->sci_level;
|
||||||
}
|
}
|
||||||
|
@ -524,10 +524,10 @@ static void ich9_lpc_config_write(PCIDevice *d,
|
||||||
ich9_lpc_rcba_update(lpc, rcba_old);
|
ich9_lpc_rcba_update(lpc, rcba_old);
|
||||||
}
|
}
|
||||||
if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
|
if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
|
||||||
pci_bus_fire_intx_routing_notifier(lpc->d.bus);
|
pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
|
||||||
}
|
}
|
||||||
if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
|
if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
|
||||||
pci_bus_fire_intx_routing_notifier(lpc->d.bus);
|
pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
|
||||||
}
|
}
|
||||||
if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
|
if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
|
||||||
ich9_lpc_pmcon_update(lpc);
|
ich9_lpc_pmcon_update(lpc);
|
||||||
|
|
|
@ -1171,7 +1171,7 @@ PCIBus *gt64120_register(qemu_irq *pic)
|
||||||
phb = PCI_HOST_BRIDGE(dev);
|
phb = PCI_HOST_BRIDGE(dev);
|
||||||
memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX);
|
memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX);
|
||||||
address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
|
address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
|
||||||
phb->bus = pci_register_bus(dev, "pci",
|
phb->bus = pci_register_root_bus(dev, "pci",
|
||||||
gt64120_pci_set_irq, gt64120_pci_map_irq,
|
gt64120_pci_set_irq, gt64120_pci_map_irq,
|
||||||
pic,
|
pic,
|
||||||
&d->pci0_mem,
|
&d->pci0_mem,
|
||||||
|
|
|
@ -2356,7 +2356,7 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
vmxnet3_net_init(s);
|
vmxnet3_net_init(s);
|
||||||
|
|
||||||
if (pci_is_express(pci_dev)) {
|
if (pci_is_express(pci_dev)) {
|
||||||
if (pci_bus_is_express(pci_dev->bus)) {
|
if (pci_bus_is_express(pci_get_bus(pci_dev))) {
|
||||||
pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);
|
pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,8 @@ typedef struct PXBDev {
|
||||||
|
|
||||||
static PXBDev *convert_to_pxb(PCIDevice *dev)
|
static PXBDev *convert_to_pxb(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
return pci_bus_is_express(dev->bus) ? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
|
return pci_bus_is_express(pci_get_bus(dev))
|
||||||
|
? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *pxb_dev_list;
|
static GList *pxb_dev_list;
|
||||||
|
@ -165,7 +166,7 @@ static const TypeInfo pxb_host_info = {
|
||||||
*/
|
*/
|
||||||
static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
|
static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
|
||||||
{
|
{
|
||||||
PCIBus *bus = dev->bus;
|
PCIBus *bus = pci_get_bus(dev);
|
||||||
int pxb_bus_num = pci_bus_num(pxb_bus);
|
int pxb_bus_num = pci_bus_num(pxb_bus);
|
||||||
|
|
||||||
if (bus->parent_dev) {
|
if (bus->parent_dev) {
|
||||||
|
@ -179,12 +180,12 @@ static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QLIST_INSERT_HEAD(&dev->bus->child, pxb_bus, sibling);
|
QLIST_INSERT_HEAD(&pci_get_bus(dev)->child, pxb_bus, sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
|
static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
|
||||||
{
|
{
|
||||||
PCIDevice *pxb = pci_dev->bus->parent_dev;
|
PCIDevice *pxb = pci_get_bus(pci_dev)->parent_dev;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The bios does not index the pxb slot number when
|
* The bios does not index the pxb slot number when
|
||||||
|
@ -229,9 +230,9 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
|
||||||
|
|
||||||
ds = qdev_create(NULL, TYPE_PXB_HOST);
|
ds = qdev_create(NULL, TYPE_PXB_HOST);
|
||||||
if (pcie) {
|
if (pcie) {
|
||||||
bus = pci_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
|
bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
|
||||||
} else {
|
} else {
|
||||||
bus = pci_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
|
bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
|
||||||
bds = qdev_create(BUS(bus), "pci-bridge");
|
bds = qdev_create(BUS(bus), "pci-bridge");
|
||||||
bds->id = dev_name;
|
bds->id = dev_name;
|
||||||
qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
|
qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
|
||||||
|
@ -239,8 +240,8 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
bus->parent_dev = dev;
|
bus->parent_dev = dev;
|
||||||
bus->address_space_mem = dev->bus->address_space_mem;
|
bus->address_space_mem = pci_get_bus(dev)->address_space_mem;
|
||||||
bus->address_space_io = dev->bus->address_space_io;
|
bus->address_space_io = pci_get_bus(dev)->address_space_io;
|
||||||
bus->map_irq = pxb_map_irq_fn;
|
bus->map_irq = pxb_map_irq_fn;
|
||||||
|
|
||||||
PCI_HOST_BRIDGE(ds)->bus = bus;
|
PCI_HOST_BRIDGE(ds)->bus = bus;
|
||||||
|
@ -271,7 +272,7 @@ err_register_bus:
|
||||||
|
|
||||||
static void pxb_dev_realize(PCIDevice *dev, Error **errp)
|
static void pxb_dev_realize(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
if (pci_bus_is_express(dev->bus)) {
|
if (pci_bus_is_express(pci_get_bus(dev))) {
|
||||||
error_setg(errp, "pxb devices cannot reside on a PCIe bus");
|
error_setg(errp, "pxb devices cannot reside on a PCIe bus");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -323,7 +324,7 @@ static const TypeInfo pxb_dev_info = {
|
||||||
|
|
||||||
static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
|
static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
if (!pci_bus_is_express(dev->bus)) {
|
if (!pci_bus_is_express(pci_get_bus(dev))) {
|
||||||
error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
|
error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,7 +433,7 @@ static void pci_pbm_realize(DeviceState *dev, Error **errp)
|
||||||
memory_region_add_subregion(get_system_memory(), s->mem_base,
|
memory_region_add_subregion(get_system_memory(), s->mem_base,
|
||||||
&s->pci_mmio);
|
&s->pci_mmio);
|
||||||
|
|
||||||
phb->bus = pci_register_bus(dev, "pci",
|
phb->bus = pci_register_root_bus(dev, "pci",
|
||||||
pci_apb_set_irq, pci_apb_map_irq, s,
|
pci_apb_set_irq, pci_apb_map_irq, s,
|
||||||
&s->pci_mmio,
|
&s->pci_mmio,
|
||||||
&s->pci_ioport,
|
&s->pci_ioport,
|
||||||
|
|
|
@ -714,9 +714,9 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
|
||||||
{
|
{
|
||||||
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
|
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
|
||||||
|
|
||||||
phb->bus = pci_register_bus(DEVICE(dev), "pci",
|
phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
|
||||||
pci_bonito_set_irq, pci_bonito_map_irq, dev,
|
pci_bonito_set_irq, pci_bonito_map_irq,
|
||||||
get_system_memory(), get_system_io(),
|
dev, get_system_memory(), get_system_io(),
|
||||||
0x28, 32, TYPE_PCI_BUS);
|
0x28, 32, TYPE_PCI_BUS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -89,7 +89,7 @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
|
||||||
s->irq_num[i] = -1;
|
s->irq_num[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci->bus = pci_register_bus(dev, "pcie.0", gpex_set_irq,
|
pci->bus = pci_register_root_bus(dev, "pcie.0", gpex_set_irq,
|
||||||
pci_swizzle_map_irq_fn, s, &s->io_mmio,
|
pci_swizzle_map_irq_fn, s, &s->io_mmio,
|
||||||
&s->io_ioport, 0, 4, TYPE_PCIE_BUS);
|
&s->io_ioport, 0, 4, TYPE_PCIE_BUS);
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
|
||||||
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
|
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
|
||||||
&d->pci_hole);
|
&d->pci_hole);
|
||||||
|
|
||||||
phb->bus = pci_register_bus(dev, NULL,
|
phb->bus = pci_register_root_bus(dev, NULL,
|
||||||
pci_grackle_set_irq,
|
pci_grackle_set_irq,
|
||||||
pci_grackle_map_irq,
|
pci_grackle_map_irq,
|
||||||
pic,
|
pic,
|
||||||
|
|
|
@ -361,7 +361,7 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
|
||||||
|
|
||||||
dev = qdev_create(NULL, host_type);
|
dev = qdev_create(NULL, host_type);
|
||||||
s = PCI_HOST_BRIDGE(dev);
|
s = PCI_HOST_BRIDGE(dev);
|
||||||
b = pci_bus_new(dev, NULL, pci_address_space,
|
b = pci_root_bus_new(dev, NULL, pci_address_space,
|
||||||
address_space_io, 0, TYPE_PCI_BUS);
|
address_space_io, 0, TYPE_PCI_BUS);
|
||||||
s->bus = b;
|
s->bus = b;
|
||||||
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
|
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
|
||||||
|
@ -512,12 +512,12 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
|
||||||
/* irq routing is changed. so rebuild bitmap */
|
/* irq routing is changed. so rebuild bitmap */
|
||||||
static void piix3_update_irq_levels(PIIX3State *piix3)
|
static void piix3_update_irq_levels(PIIX3State *piix3)
|
||||||
{
|
{
|
||||||
|
PCIBus *bus = pci_get_bus(&piix3->dev);
|
||||||
int pirq;
|
int pirq;
|
||||||
|
|
||||||
piix3->pic_levels = 0;
|
piix3->pic_levels = 0;
|
||||||
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
|
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
|
||||||
piix3_set_irq_level(piix3, pirq,
|
piix3_set_irq_level(piix3, pirq, pci_bus_get_irq_level(bus, pirq));
|
||||||
pci_bus_get_irq_level(piix3->dev.bus, pirq));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ static void piix3_write_config(PCIDevice *dev,
|
||||||
PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
|
PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
|
||||||
int pic_irq;
|
int pic_irq;
|
||||||
|
|
||||||
pci_bus_fire_intx_routing_notifier(piix3->dev.bus);
|
pci_bus_fire_intx_routing_notifier(pci_get_bus(&piix3->dev));
|
||||||
piix3_update_irq_levels(piix3);
|
piix3_update_irq_levels(piix3);
|
||||||
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
|
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
|
||||||
piix3_set_irq_pic(piix3, pic_irq);
|
piix3_set_irq_pic(piix3, pic_irq);
|
||||||
|
@ -601,7 +601,7 @@ static int piix3_post_load(void *opaque, int version_id)
|
||||||
piix3->pic_levels = 0;
|
piix3->pic_levels = 0;
|
||||||
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
|
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
|
||||||
piix3_set_irq_level_internal(piix3, pirq,
|
piix3_set_irq_level_internal(piix3, pirq,
|
||||||
pci_bus_get_irq_level(piix3->dev.bus, pirq));
|
pci_bus_get_irq_level(pci_get_bus(&piix3->dev), pirq));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +613,7 @@ static int piix3_pre_save(void *opaque)
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
|
for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
|
||||||
piix3->pci_irq_levels_vmstate[i] =
|
piix3->pci_irq_levels_vmstate[i] =
|
||||||
pci_bus_get_irq_level(piix3->dev.bus, i);
|
pci_bus_get_irq_level(pci_get_bus(&piix3->dev), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -804,60 +804,55 @@ static const IGDHostInfo igd_host_bridge_infos[] = {
|
||||||
{0xa8, 4}, /* SNB: base of GTT stolen memory */
|
{0xa8, 4}, /* SNB: base of GTT stolen memory */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int host_pci_config_read(int pos, int len, uint32_t *val)
|
static void host_pci_config_read(int pos, int len, uint32_t *val, Error **errp)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
int rc, config_fd;
|
||||||
int config_fd;
|
|
||||||
ssize_t size = sizeof(path);
|
|
||||||
/* Access real host bridge. */
|
/* Access real host bridge. */
|
||||||
int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
|
char *path = g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
|
||||||
0, 0, 0, 0, "config");
|
0, 0, 0, 0, "config");
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (rc >= size || rc < 0) {
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_fd = open(path, O_RDWR);
|
config_fd = open(path, O_RDWR);
|
||||||
if (config_fd < 0) {
|
if (config_fd < 0) {
|
||||||
return -ENODEV;
|
error_setg_errno(errp, errno, "Failed to open: %s", path);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lseek(config_fd, pos, SEEK_SET) != pos) {
|
if (lseek(config_fd, pos, SEEK_SET) != pos) {
|
||||||
ret = -errno;
|
error_setg_errno(errp, errno, "Failed to seek: %s", path);
|
||||||
goto out;
|
goto out_close_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = read(config_fd, (uint8_t *)val, len);
|
rc = read(config_fd, (uint8_t *)val, len);
|
||||||
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
|
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
|
||||||
if (rc != len) {
|
if (rc != len) {
|
||||||
ret = -errno;
|
error_setg_errno(errp, errno, "Failed to read: %s", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out_close_fd:
|
||||||
close(config_fd);
|
close(config_fd);
|
||||||
return ret;
|
out:
|
||||||
|
g_free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
|
static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
{
|
{
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
int rc, i, num;
|
int i, num;
|
||||||
int pos, len;
|
int pos, len;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
num = ARRAY_SIZE(igd_host_bridge_infos);
|
num = ARRAY_SIZE(igd_host_bridge_infos);
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
pos = igd_host_bridge_infos[i].offset;
|
pos = igd_host_bridge_infos[i].offset;
|
||||||
len = igd_host_bridge_infos[i].len;
|
len = igd_host_bridge_infos[i].len;
|
||||||
rc = host_pci_config_read(pos, len, &val);
|
host_pci_config_read(pos, len, &val, &local_err);
|
||||||
if (rc) {
|
if (local_err) {
|
||||||
return -ENODEV;
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
pci_default_write_config(pci_dev, pos, val, len);
|
pci_default_write_config(pci_dev, pos, val, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
|
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
|
||||||
|
@ -865,7 +860,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->init = igd_pt_i440fx_initfn;
|
k->realize = igd_pt_i440fx_realize;
|
||||||
dc->desc = "IGD Passthrough Host bridge";
|
dc->desc = "IGD Passthrough Host bridge";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -460,7 +460,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
|
||||||
/* PIO lives at the bottom of our bus space */
|
/* PIO lives at the bottom of our bus space */
|
||||||
memory_region_add_subregion_overlap(&s->busmem, 0, &s->pio, -2);
|
memory_region_add_subregion_overlap(&s->busmem, 0, &s->pio, -2);
|
||||||
|
|
||||||
b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
|
b = pci_register_root_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
|
||||||
mpc85xx_pci_map_irq, s, &s->busmem, &s->pio,
|
mpc85xx_pci_map_irq, s, &s->busmem, &s->pio,
|
||||||
PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
|
PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
|
||||||
h->bus = b;
|
h->bus = b;
|
||||||
|
|
|
@ -269,7 +269,7 @@ static void raven_pcihost_initfn(Object *obj)
|
||||||
memory_region_add_subregion_overlap(address_space_mem, 0x80000000,
|
memory_region_add_subregion_overlap(address_space_mem, 0x80000000,
|
||||||
&s->pci_io_non_contiguous, 1);
|
&s->pci_io_non_contiguous, 1);
|
||||||
memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
|
memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
|
||||||
pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
|
pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
|
||||||
&s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
|
&s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
|
||||||
|
|
||||||
/* Bus master address space */
|
/* Bus master address space */
|
||||||
|
|
|
@ -51,8 +51,9 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
|
||||||
sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
|
sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
|
||||||
sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
|
sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
|
||||||
|
|
||||||
pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
|
pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
|
||||||
s->mch.pci_address_space, s->mch.address_space_io,
|
s->mch.pci_address_space,
|
||||||
|
s->mch.address_space_io,
|
||||||
0, TYPE_PCIE_BUS);
|
0, TYPE_PCIE_BUS);
|
||||||
PC_MACHINE(qdev_get_machine())->bus = pci->bus;
|
PC_MACHINE(qdev_get_machine())->bus = pci->bus;
|
||||||
qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
|
qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
|
||||||
|
|
|
@ -233,7 +233,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
|
||||||
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
|
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
|
||||||
&d->pci_hole);
|
&d->pci_hole);
|
||||||
|
|
||||||
h->bus = pci_register_bus(dev, NULL,
|
h->bus = pci_register_root_bus(dev, NULL,
|
||||||
pci_unin_set_irq, pci_unin_map_irq,
|
pci_unin_set_irq, pci_unin_map_irq,
|
||||||
pic,
|
pic,
|
||||||
&d->pci_mmio,
|
&d->pci_mmio,
|
||||||
|
@ -299,7 +299,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
|
||||||
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
|
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
|
||||||
&d->pci_hole);
|
&d->pci_hole);
|
||||||
|
|
||||||
h->bus = pci_register_bus(dev, NULL,
|
h->bus = pci_register_root_bus(dev, NULL,
|
||||||
pci_unin_set_irq, pci_unin_map_irq,
|
pci_unin_set_irq, pci_unin_map_irq,
|
||||||
pic,
|
pic,
|
||||||
&d->pci_mmio,
|
&d->pci_mmio,
|
||||||
|
|
|
@ -311,7 +311,7 @@ static const MemoryRegionOps pci_vpb_config_ops = {
|
||||||
|
|
||||||
static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
|
static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
|
||||||
{
|
{
|
||||||
PCIVPBState *s = container_of(d->bus, PCIVPBState, pci_bus);
|
PCIVPBState *s = container_of(pci_get_bus(d), PCIVPBState, pci_bus);
|
||||||
|
|
||||||
if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) {
|
if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) {
|
||||||
/* Legacy broken IRQ mapping for compatibility with old and
|
/* Legacy broken IRQ mapping for compatibility with old and
|
||||||
|
@ -399,7 +399,7 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
|
||||||
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
|
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
|
||||||
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
|
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
|
||||||
|
|
||||||
pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
|
pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
|
||||||
&s->pci_mem_space, &s->pci_io_space,
|
&s->pci_mem_space, &s->pci_io_space,
|
||||||
PCI_DEVFN(11, 0), TYPE_PCI_BUS);
|
PCI_DEVFN(11, 0), TYPE_PCI_BUS);
|
||||||
h->bus = &s->pci_bus;
|
h->bus = &s->pci_bus;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "hw/pci/pci_bridge.h"
|
#include "hw/pci/pci_bridge.h"
|
||||||
#include "hw/pci-host/xilinx-pcie.h"
|
#include "hw/pci-host/xilinx-pcie.h"
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ static void xilinx_pcie_host_realize(DeviceState *dev, Error **errp)
|
||||||
sysbus_init_mmio(sbd, &pex->mmio);
|
sysbus_init_mmio(sbd, &pex->mmio);
|
||||||
sysbus_init_mmio(sbd, &s->mmio);
|
sysbus_init_mmio(sbd, &s->mmio);
|
||||||
|
|
||||||
pci->bus = pci_register_bus(dev, s->name, xilinx_pcie_set_irq,
|
pci->bus = pci_register_root_bus(dev, s->name, xilinx_pcie_set_irq,
|
||||||
pci_swizzle_map_irq_fn, s, &s->mmio,
|
pci_swizzle_map_irq_fn, s, &s->mmio,
|
||||||
&s->io, 0, 4, TYPE_PCIE_BUS);
|
&s->io, 0, 4, TYPE_PCIE_BUS);
|
||||||
|
|
||||||
|
@ -267,24 +268,22 @@ static void xilinx_pcie_root_config_write(PCIDevice *d, uint32_t address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xilinx_pcie_root_init(PCIDevice *dev)
|
static void xilinx_pcie_root_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
{
|
{
|
||||||
BusState *bus = qdev_get_parent_bus(DEVICE(dev));
|
BusState *bus = qdev_get_parent_bus(DEVICE(pci_dev));
|
||||||
XilinxPCIEHost *s = XILINX_PCIE_HOST(bus->parent);
|
XilinxPCIEHost *s = XILINX_PCIE_HOST(bus->parent);
|
||||||
|
|
||||||
pci_set_word(dev->config + PCI_COMMAND,
|
pci_set_word(pci_dev->config + PCI_COMMAND,
|
||||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
||||||
pci_set_word(dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
|
pci_set_word(pci_dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
|
||||||
pci_set_word(dev->config + PCI_MEMORY_LIMIT,
|
pci_set_word(pci_dev->config + PCI_MEMORY_LIMIT,
|
||||||
((s->mmio_base + s->mmio_size - 1) >> 16) & 0xfff0);
|
((s->mmio_base + s->mmio_size - 1) >> 16) & 0xfff0);
|
||||||
|
|
||||||
pci_bridge_initfn(dev, TYPE_PCI_BUS);
|
pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
|
||||||
|
|
||||||
if (pcie_endpoint_cap_v1_init(dev, 0x80) < 0) {
|
if (pcie_endpoint_cap_v1_init(pci_dev, 0x80) < 0) {
|
||||||
hw_error("Failed to initialize PCIe capability");
|
error_setg(errp, "Failed to initialize PCIe capability");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
|
static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
|
||||||
|
@ -300,7 +299,7 @@ static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
|
||||||
k->class_id = PCI_CLASS_BRIDGE_HOST;
|
k->class_id = PCI_CLASS_BRIDGE_HOST;
|
||||||
k->is_express = true;
|
k->is_express = true;
|
||||||
k->is_bridge = true;
|
k->is_bridge = true;
|
||||||
k->init = xilinx_pcie_root_init;
|
k->realize = xilinx_pcie_root_realize;
|
||||||
k->exit = pci_bridge_exitfn;
|
k->exit = pci_bridge_exitfn;
|
||||||
dc->reset = pci_bridge_reset;
|
dc->reset = pci_bridge_reset;
|
||||||
k->config_read = xilinx_pcie_root_config_read;
|
k->config_read = xilinx_pcie_root_config_read;
|
||||||
|
|
107
hw/pci/pci.c
107
hw/pci/pci.c
|
@ -222,7 +222,7 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
|
||||||
{
|
{
|
||||||
PCIBus *bus;
|
PCIBus *bus;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bus = pci_dev->bus;
|
bus = pci_get_bus(pci_dev);
|
||||||
irq_num = bus->map_irq(pci_dev, irq_num);
|
irq_num = bus->map_irq(pci_dev, irq_num);
|
||||||
if (bus->set_irq)
|
if (bus->set_irq)
|
||||||
break;
|
break;
|
||||||
|
@ -331,31 +331,15 @@ static void pci_host_bus_register(DeviceState *host)
|
||||||
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
|
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIBus *pci_find_primary_bus(void)
|
|
||||||
{
|
|
||||||
PCIBus *primary_bus = NULL;
|
|
||||||
PCIHostState *host;
|
|
||||||
|
|
||||||
QLIST_FOREACH(host, &pci_host_bridges, next) {
|
|
||||||
if (primary_bus) {
|
|
||||||
/* We have multiple root buses, refuse to select a primary */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
primary_bus = host->bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
return primary_bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCIBus *pci_device_root_bus(const PCIDevice *d)
|
PCIBus *pci_device_root_bus(const PCIDevice *d)
|
||||||
{
|
{
|
||||||
PCIBus *bus = d->bus;
|
PCIBus *bus = pci_get_bus(d);
|
||||||
|
|
||||||
while (!pci_bus_is_root(bus)) {
|
while (!pci_bus_is_root(bus)) {
|
||||||
d = bus->parent_dev;
|
d = bus->parent_dev;
|
||||||
assert(d != NULL);
|
assert(d != NULL);
|
||||||
|
|
||||||
bus = d->bus;
|
bus = pci_get_bus(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bus;
|
return bus;
|
||||||
|
@ -376,7 +360,7 @@ const char *pci_root_bus_path(PCIDevice *dev)
|
||||||
return rootbus->qbus.name;
|
return rootbus->qbus.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_bus_init(PCIBus *bus, DeviceState *parent,
|
static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min)
|
uint8_t devfn_min)
|
||||||
|
@ -403,17 +387,18 @@ bool pci_bus_is_root(PCIBus *bus)
|
||||||
return PCI_BUS_GET_CLASS(bus)->is_root(bus);
|
return PCI_BUS_GET_CLASS(bus)->is_root(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
|
void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
|
||||||
const char *name,
|
const char *name,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min, const char *typename)
|
uint8_t devfn_min, const char *typename)
|
||||||
{
|
{
|
||||||
qbus_create_inplace(bus, bus_size, typename, parent, name);
|
qbus_create_inplace(bus, bus_size, typename, parent, name);
|
||||||
pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
|
pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
|
||||||
|
devfn_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIBus *pci_bus_new(DeviceState *parent, const char *name,
|
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min, const char *typename)
|
uint8_t devfn_min, const char *typename)
|
||||||
|
@ -421,7 +406,8 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,
|
||||||
PCIBus *bus;
|
PCIBus *bus;
|
||||||
|
|
||||||
bus = PCI_BUS(qbus_create(typename, parent, name));
|
bus = PCI_BUS(qbus_create(typename, parent, name));
|
||||||
pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
|
pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
|
||||||
|
devfn_min);
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,16 +421,17 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
||||||
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
|
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
|
PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
|
||||||
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
||||||
void *irq_opaque,
|
void *irq_opaque,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min, int nirq, const char *typename)
|
uint8_t devfn_min, int nirq,
|
||||||
|
const char *typename)
|
||||||
{
|
{
|
||||||
PCIBus *bus;
|
PCIBus *bus;
|
||||||
|
|
||||||
bus = pci_bus_new(parent, name, address_space_mem,
|
bus = pci_root_bus_new(parent, name, address_space_mem,
|
||||||
address_space_io, devfn_min, typename);
|
address_space_io, devfn_min, typename);
|
||||||
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
|
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
|
||||||
return bus;
|
return bus;
|
||||||
|
@ -879,7 +866,7 @@ static void pci_config_free(PCIDevice *pci_dev)
|
||||||
|
|
||||||
static void do_pci_unregister_device(PCIDevice *pci_dev)
|
static void do_pci_unregister_device(PCIDevice *pci_dev)
|
||||||
{
|
{
|
||||||
pci_dev->bus->devices[pci_dev->devfn] = NULL;
|
pci_get_bus(pci_dev)->devices[pci_dev->devfn] = NULL;
|
||||||
pci_config_free(pci_dev);
|
pci_config_free(pci_dev);
|
||||||
|
|
||||||
if (memory_region_is_mapped(&pci_dev->bus_master_enable_region)) {
|
if (memory_region_is_mapped(&pci_dev->bus_master_enable_region)) {
|
||||||
|
@ -900,7 +887,7 @@ static uint16_t pci_req_id_cache_extract(PCIReqIDCache *cache)
|
||||||
result = pci_get_bdf(cache->dev);
|
result = pci_get_bdf(cache->dev);
|
||||||
break;
|
break;
|
||||||
case PCI_REQ_ID_SECONDARY_BUS:
|
case PCI_REQ_ID_SECONDARY_BUS:
|
||||||
bus_n = pci_bus_num(cache->dev->bus);
|
bus_n = pci_dev_bus_num(cache->dev);
|
||||||
result = PCI_BUILD_BDF(bus_n, 0);
|
result = PCI_BUILD_BDF(bus_n, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -930,9 +917,9 @@ static PCIReqIDCache pci_req_id_cache_get(PCIDevice *dev)
|
||||||
.type = PCI_REQ_ID_BDF,
|
.type = PCI_REQ_ID_BDF,
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!pci_bus_is_root(dev->bus)) {
|
while (!pci_bus_is_root(pci_get_bus(dev))) {
|
||||||
/* We are under PCI/PCIe bridges */
|
/* We are under PCI/PCIe bridges */
|
||||||
parent = dev->bus->parent_dev;
|
parent = pci_get_bus(dev)->parent_dev;
|
||||||
if (pci_is_express(parent)) {
|
if (pci_is_express(parent)) {
|
||||||
if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
|
if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
|
||||||
/* When we pass through PCIe-to-PCI/PCIX bridges, we
|
/* When we pass through PCIe-to-PCI/PCIX bridges, we
|
||||||
|
@ -975,7 +962,7 @@ static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -1 for devfn means auto assign */
|
/* -1 for devfn means auto assign */
|
||||||
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
|
||||||
const char *name, int devfn,
|
const char *name, int devfn,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -984,8 +971,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
||||||
PCIConfigWriteFunc *config_write = pc->config_write;
|
PCIConfigWriteFunc *config_write = pc->config_write;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
DeviceState *dev = DEVICE(pci_dev);
|
DeviceState *dev = DEVICE(pci_dev);
|
||||||
|
PCIBus *bus = pci_get_bus(pci_dev);
|
||||||
|
|
||||||
pci_dev->bus = bus;
|
|
||||||
/* Only pci bridges can be attached to extra PCI root buses */
|
/* Only pci bridges can be attached to extra PCI root buses */
|
||||||
if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
|
if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
|
||||||
error_setg(errp,
|
error_setg(errp,
|
||||||
|
@ -1139,8 +1126,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
|
||||||
r->type = type;
|
r->type = type;
|
||||||
r->memory = memory;
|
r->memory = memory;
|
||||||
r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
|
r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
|
||||||
? pci_dev->bus->address_space_io
|
? pci_get_bus(pci_dev)->address_space_io
|
||||||
: pci_dev->bus->address_space_mem;
|
: pci_get_bus(pci_dev)->address_space_mem;
|
||||||
|
|
||||||
wmask = ~(size - 1);
|
wmask = ~(size - 1);
|
||||||
if (region_num == PCI_ROM_SLOT) {
|
if (region_num == PCI_ROM_SLOT) {
|
||||||
|
@ -1182,21 +1169,23 @@ static void pci_update_vga(PCIDevice *pci_dev)
|
||||||
void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
|
void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
|
||||||
MemoryRegion *io_lo, MemoryRegion *io_hi)
|
MemoryRegion *io_lo, MemoryRegion *io_hi)
|
||||||
{
|
{
|
||||||
|
PCIBus *bus = pci_get_bus(pci_dev);
|
||||||
|
|
||||||
assert(!pci_dev->has_vga);
|
assert(!pci_dev->has_vga);
|
||||||
|
|
||||||
assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
|
assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
|
||||||
pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
|
pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
|
||||||
memory_region_add_subregion_overlap(pci_dev->bus->address_space_mem,
|
memory_region_add_subregion_overlap(bus->address_space_mem,
|
||||||
QEMU_PCI_VGA_MEM_BASE, mem, 1);
|
QEMU_PCI_VGA_MEM_BASE, mem, 1);
|
||||||
|
|
||||||
assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
|
assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
|
||||||
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
|
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
|
||||||
memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
|
memory_region_add_subregion_overlap(bus->address_space_io,
|
||||||
QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);
|
QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);
|
||||||
|
|
||||||
assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
|
assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
|
||||||
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
|
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
|
||||||
memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
|
memory_region_add_subregion_overlap(bus->address_space_io,
|
||||||
QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
|
QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
|
||||||
pci_dev->has_vga = true;
|
pci_dev->has_vga = true;
|
||||||
|
|
||||||
|
@ -1205,15 +1194,17 @@ void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
|
||||||
|
|
||||||
void pci_unregister_vga(PCIDevice *pci_dev)
|
void pci_unregister_vga(PCIDevice *pci_dev)
|
||||||
{
|
{
|
||||||
|
PCIBus *bus = pci_get_bus(pci_dev);
|
||||||
|
|
||||||
if (!pci_dev->has_vga) {
|
if (!pci_dev->has_vga) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_del_subregion(pci_dev->bus->address_space_mem,
|
memory_region_del_subregion(bus->address_space_mem,
|
||||||
pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
|
pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
|
||||||
memory_region_del_subregion(pci_dev->bus->address_space_io,
|
memory_region_del_subregion(bus->address_space_io,
|
||||||
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
|
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
|
||||||
memory_region_del_subregion(pci_dev->bus->address_space_io,
|
memory_region_del_subregion(bus->address_space_io,
|
||||||
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
|
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
|
||||||
pci_dev->has_vga = false;
|
pci_dev->has_vga = false;
|
||||||
}
|
}
|
||||||
|
@ -1316,7 +1307,7 @@ static void pci_update_mappings(PCIDevice *d)
|
||||||
|
|
||||||
/* now do the real mapping */
|
/* now do the real mapping */
|
||||||
if (r->addr != PCI_BAR_UNMAPPED) {
|
if (r->addr != PCI_BAR_UNMAPPED) {
|
||||||
trace_pci_update_mappings_del(d, pci_bus_num(d->bus),
|
trace_pci_update_mappings_del(d, pci_dev_bus_num(d),
|
||||||
PCI_SLOT(d->devfn),
|
PCI_SLOT(d->devfn),
|
||||||
PCI_FUNC(d->devfn),
|
PCI_FUNC(d->devfn),
|
||||||
i, r->addr, r->size);
|
i, r->addr, r->size);
|
||||||
|
@ -1324,7 +1315,7 @@ static void pci_update_mappings(PCIDevice *d)
|
||||||
}
|
}
|
||||||
r->addr = new_addr;
|
r->addr = new_addr;
|
||||||
if (r->addr != PCI_BAR_UNMAPPED) {
|
if (r->addr != PCI_BAR_UNMAPPED) {
|
||||||
trace_pci_update_mappings_add(d, pci_bus_num(d->bus),
|
trace_pci_update_mappings_add(d, pci_dev_bus_num(d),
|
||||||
PCI_SLOT(d->devfn),
|
PCI_SLOT(d->devfn),
|
||||||
PCI_FUNC(d->devfn),
|
PCI_FUNC(d->devfn),
|
||||||
i, r->addr, r->size);
|
i, r->addr, r->size);
|
||||||
|
@ -1443,7 +1434,7 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
|
||||||
PCIBus *bus;
|
PCIBus *bus;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bus = dev->bus;
|
bus = pci_get_bus(dev);
|
||||||
pin = bus->map_irq(dev, pin);
|
pin = bus->map_irq(dev, pin);
|
||||||
dev = bus->parent_dev;
|
dev = bus->parent_dev;
|
||||||
} while (dev);
|
} while (dev);
|
||||||
|
@ -2015,7 +2006,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
|
||||||
PCIDevice *pci_dev = (PCIDevice *)qdev;
|
PCIDevice *pci_dev = (PCIDevice *)qdev;
|
||||||
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
|
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
PCIBus *bus;
|
|
||||||
bool is_default_rom;
|
bool is_default_rom;
|
||||||
|
|
||||||
/* initialize cap_present for pci_is_express() and pci_config_size() */
|
/* initialize cap_present for pci_is_express() and pci_config_size() */
|
||||||
|
@ -2023,8 +2013,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
|
||||||
pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
|
pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bus = PCI_BUS(qdev_get_parent_bus(qdev));
|
pci_dev = do_pci_register_device(pci_dev,
|
||||||
pci_dev = do_pci_register_device(pci_dev, bus,
|
|
||||||
object_get_typename(OBJECT(qdev)),
|
object_get_typename(OBJECT(qdev)),
|
||||||
pci_dev->devfn, errp);
|
pci_dev->devfn, errp);
|
||||||
if (pci_dev == NULL)
|
if (pci_dev == NULL)
|
||||||
|
@ -2317,7 +2306,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
|
||||||
error_setg(errp, "%s:%02x:%02x.%x "
|
error_setg(errp, "%s:%02x:%02x.%x "
|
||||||
"Attempt to add PCI capability %x at offset "
|
"Attempt to add PCI capability %x at offset "
|
||||||
"%x overlaps existing capability %x at offset %x",
|
"%x overlaps existing capability %x at offset %x",
|
||||||
pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
|
pci_root_bus_path(pdev), pci_dev_bus_num(pdev),
|
||||||
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
|
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
|
||||||
cap_id, offset, overlapping_cap, i);
|
cap_id, offset, overlapping_cap, i);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -2381,7 +2370,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
|
||||||
|
|
||||||
monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
|
monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
|
||||||
"pci id %04x:%04x (sub %04x:%04x)\n",
|
"pci id %04x:%04x (sub %04x:%04x)\n",
|
||||||
indent, "", ctxt, pci_bus_num(d->bus),
|
indent, "", ctxt, pci_dev_bus_num(d),
|
||||||
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
|
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
|
||||||
pci_get_word(d->config + PCI_VENDOR_ID),
|
pci_get_word(d->config + PCI_VENDOR_ID),
|
||||||
pci_get_word(d->config + PCI_DEVICE_ID),
|
pci_get_word(d->config + PCI_DEVICE_ID),
|
||||||
|
@ -2464,7 +2453,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
|
||||||
|
|
||||||
/* Calculate # of slots on path between device and root. */;
|
/* Calculate # of slots on path between device and root. */;
|
||||||
slot_depth = 0;
|
slot_depth = 0;
|
||||||
for (t = d; t; t = t->bus->parent_dev) {
|
for (t = d; t; t = pci_get_bus(t)->parent_dev) {
|
||||||
++slot_depth;
|
++slot_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2479,7 +2468,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
|
||||||
/* Fill in slot numbers. We walk up from device to root, so need to print
|
/* Fill in slot numbers. We walk up from device to root, so need to print
|
||||||
* them in the reverse order, last to first. */
|
* them in the reverse order, last to first. */
|
||||||
p = path + path_len;
|
p = path + path_len;
|
||||||
for (t = d; t; t = t->bus->parent_dev) {
|
for (t = d; t; t = pci_get_bus(t)->parent_dev) {
|
||||||
p -= slot_len;
|
p -= slot_len;
|
||||||
s = snprintf(slot, sizeof slot, ":%02x.%x",
|
s = snprintf(slot, sizeof slot, ":%02x.%x",
|
||||||
PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
|
PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
|
||||||
|
@ -2527,12 +2516,12 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
|
||||||
|
|
||||||
MemoryRegion *pci_address_space(PCIDevice *dev)
|
MemoryRegion *pci_address_space(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
return dev->bus->address_space_mem;
|
return pci_get_bus(dev)->address_space_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryRegion *pci_address_space_io(PCIDevice *dev)
|
MemoryRegion *pci_address_space_io(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
return dev->bus->address_space_io;
|
return pci_get_bus(dev)->address_space_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_device_class_init(ObjectClass *klass, void *data)
|
static void pci_device_class_init(ObjectClass *klass, void *data)
|
||||||
|
@ -2560,11 +2549,11 @@ static void pci_device_class_base_init(ObjectClass *klass, void *data)
|
||||||
|
|
||||||
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
|
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
PCIBus *bus = PCI_BUS(dev->bus);
|
PCIBus *bus = pci_get_bus(dev);
|
||||||
PCIBus *iommu_bus = bus;
|
PCIBus *iommu_bus = bus;
|
||||||
|
|
||||||
while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
|
while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
|
||||||
iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
|
iommu_bus = pci_get_bus(iommu_bus->parent_dev);
|
||||||
}
|
}
|
||||||
if (iommu_bus && iommu_bus->iommu_fn) {
|
if (iommu_bus && iommu_bus->iommu_fn) {
|
||||||
return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
|
return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
|
||||||
|
@ -2635,7 +2624,7 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
|
||||||
|
|
||||||
static bool pcie_has_upstream_port(PCIDevice *dev)
|
static bool pcie_has_upstream_port(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
|
PCIDevice *parent_dev = pci_bridge_get_device(pci_get_bus(dev));
|
||||||
|
|
||||||
/* Device associated with an upstream port.
|
/* Device associated with an upstream port.
|
||||||
* As there are several types of these, it's easier to check the
|
* As there are several types of these, it's easier to check the
|
||||||
|
@ -2651,12 +2640,14 @@ static bool pcie_has_upstream_port(PCIDevice *dev)
|
||||||
|
|
||||||
PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
|
PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
|
||||||
{
|
{
|
||||||
|
PCIBus *bus = pci_get_bus(pci_dev);
|
||||||
|
|
||||||
if(pcie_has_upstream_port(pci_dev)) {
|
if(pcie_has_upstream_port(pci_dev)) {
|
||||||
/* With an upstream PCIe port, we only support 1 device at slot 0 */
|
/* With an upstream PCIe port, we only support 1 device at slot 0 */
|
||||||
return pci_dev->bus->devices[0];
|
return bus->devices[0];
|
||||||
} else {
|
} else {
|
||||||
/* Other bus types might support multiple devices at slots 0-31 */
|
/* Other bus types might support multiple devices at slots 0-31 */
|
||||||
return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
|
return bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
|
||||||
static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
|
static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
|
||||||
{
|
{
|
||||||
PCIDevice *pd = PCI_DEVICE(br);
|
PCIDevice *pd = PCI_DEVICE(br);
|
||||||
PCIBus *parent = pd->bus;
|
PCIBus *parent = pci_get_bus(pd);
|
||||||
PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
|
PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
|
||||||
uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
|
uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
|
||||||
static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
|
static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
|
||||||
{
|
{
|
||||||
PCIDevice *pd = PCI_DEVICE(br);
|
PCIDevice *pd = PCI_DEVICE(br);
|
||||||
PCIBus *parent = pd->bus;
|
PCIBus *parent = pci_get_bus(pd);
|
||||||
|
|
||||||
memory_region_del_subregion(parent->address_space_io, &w->alias_io);
|
memory_region_del_subregion(parent->address_space_io, &w->alias_io);
|
||||||
memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
|
memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
|
||||||
|
@ -339,7 +339,7 @@ void pci_bridge_reset(DeviceState *qdev)
|
||||||
/* default qdev initialization function for PCI-to-PCI bridge */
|
/* default qdev initialization function for PCI-to-PCI bridge */
|
||||||
void pci_bridge_initfn(PCIDevice *dev, const char *typename)
|
void pci_bridge_initfn(PCIDevice *dev, const char *typename)
|
||||||
{
|
{
|
||||||
PCIBus *parent = dev->bus;
|
PCIBus *parent = pci_get_bus(dev);
|
||||||
PCIBridge *br = PCI_BRIDGE(dev);
|
PCIBridge *br = PCI_BRIDGE(dev);
|
||||||
PCIBus *sec_bus = &br->sec_bus;
|
PCIBus *sec_bus = &br->sec_bus;
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,8 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
|
||||||
* a regular Endpoint type is exposed on a root complex. These
|
* a regular Endpoint type is exposed on a root complex. These
|
||||||
* should instead be Root Complex Integrated Endpoints.
|
* should instead be Root Complex Integrated Endpoints.
|
||||||
*/
|
*/
|
||||||
if (pci_bus_is_express(dev->bus) && pci_bus_is_root(dev->bus)) {
|
if (pci_bus_is_express(pci_get_bus(dev))
|
||||||
|
&& pci_bus_is_root(pci_get_bus(dev))) {
|
||||||
type = PCI_EXP_TYPE_RC_END;
|
type = PCI_EXP_TYPE_RC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +370,7 @@ void pcie_cap_slot_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||||
{
|
{
|
||||||
uint8_t *exp_cap;
|
uint8_t *exp_cap;
|
||||||
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||||
PCIBus *bus = pci_dev->bus;
|
PCIBus *bus = pci_get_bus(pci_dev);
|
||||||
|
|
||||||
pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
|
pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
|
||||||
|
|
||||||
|
|
|
@ -409,7 +409,7 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dev = pci_bridge_get_device(dev->bus);
|
dev = pci_bridge_get_device(pci_get_bus(dev));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,7 +1025,7 @@ static int do_pcie_aer_inject_error(Monitor *mon,
|
||||||
}
|
}
|
||||||
details->id = id;
|
details->id = id;
|
||||||
details->root_bus = pci_root_bus_path(dev);
|
details->root_bus = pci_root_bus_path(dev);
|
||||||
details->bus = pci_bus_num(dev->bus);
|
details->bus = pci_dev_bus_num(dev);
|
||||||
details->devfn = dev->devfn;
|
details->devfn = dev->devfn;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -314,7 +314,7 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
|
||||||
sysbus_init_irq(dev, &s->irq[i]);
|
sysbus_init_irq(dev, &s->irq[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
b = pci_register_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
|
b = pci_register_root_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
|
||||||
ppc4xx_pci_map_irq, s->irq, get_system_memory(),
|
ppc4xx_pci_map_irq, s->irq, get_system_memory(),
|
||||||
get_system_io(), 0, 4, TYPE_PCI_BUS);
|
get_system_io(), 0, 4, TYPE_PCI_BUS);
|
||||||
h->bus = b;
|
h->bus = b;
|
||||||
|
|
|
@ -505,7 +505,7 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtas_st(rets, 1, (pci_bus_num(pdev->bus) << 16) + 1);
|
rtas_st(rets, 1, (pci_bus_num(pci_get_bus(pdev)) << 16) + 1);
|
||||||
break;
|
break;
|
||||||
case RTAS_GET_PE_MODE:
|
case RTAS_GET_PE_MODE:
|
||||||
rtas_st(rets, 1, RTAS_PE_MODE_SHARED);
|
rtas_st(rets, 1, RTAS_PE_MODE_SHARED);
|
||||||
|
@ -1621,7 +1621,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
|
||||||
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
|
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
|
||||||
&sphb->iowindow);
|
&sphb->iowindow);
|
||||||
|
|
||||||
bus = pci_register_bus(dev, NULL,
|
bus = pci_register_root_bus(dev, NULL,
|
||||||
pci_spapr_set_irq, pci_spapr_map_irq, sphb,
|
pci_spapr_set_irq, pci_spapr_map_irq, sphb,
|
||||||
&sphb->memspace, &sphb->iospace,
|
&sphb->memspace, &sphb->iospace,
|
||||||
PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
|
PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
|
||||||
|
|
|
@ -554,7 +554,7 @@ static int s390_pcihost_init(SysBusDevice *dev)
|
||||||
|
|
||||||
DPRINTF("host_init\n");
|
DPRINTF("host_init\n");
|
||||||
|
|
||||||
b = pci_register_bus(DEVICE(dev), NULL,
|
b = pci_register_root_bus(DEVICE(dev), NULL,
|
||||||
s390_pci_set_irq, s390_pci_map_irq, NULL,
|
s390_pci_set_irq, s390_pci_map_irq, NULL,
|
||||||
get_system_memory(), get_system_io(), 0, 64,
|
get_system_memory(), get_system_io(), 0, 64,
|
||||||
TYPE_PCI_BUS);
|
TYPE_PCI_BUS);
|
||||||
|
@ -680,10 +680,10 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
|
||||||
s->bus_no += 1;
|
s->bus_no += 1;
|
||||||
pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
|
pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
|
||||||
do {
|
do {
|
||||||
pdev = pdev->bus->parent_dev;
|
pdev = pci_get_bus(pdev)->parent_dev;
|
||||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS,
|
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS,
|
||||||
s->bus_no, 1);
|
s->bus_no, 1);
|
||||||
} while (pdev->bus && pci_bus_num(pdev->bus));
|
} while (pci_get_bus(pdev) && pci_dev_bus_num(pdev));
|
||||||
}
|
}
|
||||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||||
pdev = PCI_DEVICE(dev);
|
pdev = PCI_DEVICE(dev);
|
||||||
|
@ -692,7 +692,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
|
||||||
/* In the case the PCI device does not define an id */
|
/* In the case the PCI device does not define an id */
|
||||||
/* we generate one based on the PCI address */
|
/* we generate one based on the PCI address */
|
||||||
dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
|
dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
|
||||||
pci_bus_num(pdev->bus),
|
pci_dev_bus_num(pdev),
|
||||||
PCI_SLOT(pdev->devfn),
|
PCI_SLOT(pdev->devfn),
|
||||||
PCI_FUNC(pdev->devfn));
|
PCI_FUNC(pdev->devfn));
|
||||||
}
|
}
|
||||||
|
@ -713,7 +713,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
pbdev->pdev = pdev;
|
pbdev->pdev = pdev;
|
||||||
pbdev->iommu = s390_pci_get_iommu(s, pdev->bus, pdev->devfn);
|
pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
|
||||||
pbdev->iommu->pbdev = pbdev;
|
pbdev->iommu->pbdev = pbdev;
|
||||||
pbdev->state = ZPCI_FS_DISABLED;
|
pbdev->state = ZPCI_FS_DISABLED;
|
||||||
|
|
||||||
|
@ -807,7 +807,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
|
||||||
|
|
||||||
s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
|
s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
|
||||||
pbdev->fh, pbdev->fid);
|
pbdev->fh, pbdev->fid);
|
||||||
bus = pci_dev->bus;
|
bus = pci_get_bus(pci_dev);
|
||||||
devfn = pci_dev->devfn;
|
devfn = pci_dev->devfn;
|
||||||
object_unparent(OBJECT(pci_dev));
|
object_unparent(OBJECT(pci_dev));
|
||||||
s390_pci_msix_free(pbdev);
|
s390_pci_msix_free(pbdev);
|
||||||
|
|
|
@ -2372,7 +2372,7 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
|
||||||
if (!s->sas_addr) {
|
if (!s->sas_addr) {
|
||||||
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
|
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
|
||||||
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
|
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
|
||||||
s->sas_addr |= (pci_bus_num(dev->bus) << 16);
|
s->sas_addr |= (pci_dev_bus_num(dev) << 16);
|
||||||
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
|
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
|
||||||
s->sas_addr |= PCI_FUNC(dev->devfn);
|
s->sas_addr |= PCI_FUNC(dev->devfn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1312,7 +1312,7 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
|
||||||
if (!s->sas_addr) {
|
if (!s->sas_addr) {
|
||||||
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
|
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
|
||||||
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
|
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
|
||||||
s->sas_addr |= (pci_bus_num(dev->bus) << 16);
|
s->sas_addr |= (pci_dev_bus_num(dev) << 16);
|
||||||
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
|
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
|
||||||
s->sas_addr |= PCI_FUNC(dev->devfn);
|
s->sas_addr |= PCI_FUNC(dev->devfn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1133,7 +1133,7 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
|
||||||
|
|
||||||
pvscsi_init_msi(s);
|
pvscsi_init_msi(s);
|
||||||
|
|
||||||
if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) {
|
if (pci_is_express(pci_dev) && pci_bus_is_express(pci_get_bus(pci_dev))) {
|
||||||
pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
|
pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ static int sh_pci_device_init(SysBusDevice *dev)
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
sysbus_init_irq(dev, &s->irq[i]);
|
sysbus_init_irq(dev, &s->irq[i]);
|
||||||
}
|
}
|
||||||
phb->bus = pci_register_bus(DEVICE(dev), "pci",
|
phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
|
||||||
sh_pci_set_irq, sh_pci_map_irq,
|
sh_pci_set_irq, sh_pci_map_irq,
|
||||||
s->irq,
|
s->irq,
|
||||||
get_system_memory(),
|
get_system_memory(),
|
||||||
|
|
|
@ -95,6 +95,11 @@ static struct {
|
||||||
const char *sock_pfx, *manufacturer, *version, *serial, *asset, *part;
|
const char *sock_pfx, *manufacturer, *version, *serial, *asset, *part;
|
||||||
} type4;
|
} type4;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
size_t nvalues;
|
||||||
|
const char **values;
|
||||||
|
} type11;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *loc_pfx, *bank, *manufacturer, *serial, *asset, *part;
|
const char *loc_pfx, *bank, *manufacturer, *serial, *asset, *part;
|
||||||
uint16_t speed;
|
uint16_t speed;
|
||||||
|
@ -282,6 +287,14 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const QemuOptDesc qemu_smbios_type11_opts[] = {
|
||||||
|
{
|
||||||
|
.name = "value",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "OEM string data",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static const QemuOptDesc qemu_smbios_type17_opts[] = {
|
static const QemuOptDesc qemu_smbios_type17_opts[] = {
|
||||||
{
|
{
|
||||||
.name = "type",
|
.name = "type",
|
||||||
|
@ -590,6 +603,27 @@ static void smbios_build_type_4_table(unsigned instance)
|
||||||
smbios_type4_count++;
|
smbios_type4_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smbios_build_type_11_table(void)
|
||||||
|
{
|
||||||
|
char count_str[128];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (type11.nvalues == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMBIOS_BUILD_TABLE_PRE(11, 0xe00, true); /* required */
|
||||||
|
|
||||||
|
snprintf(count_str, sizeof(count_str), "%zu", type11.nvalues);
|
||||||
|
t->count = type11.nvalues;
|
||||||
|
|
||||||
|
for (i = 0; i < type11.nvalues; i++) {
|
||||||
|
SMBIOS_TABLE_SET_STR_LIST(11, type11.values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SMBIOS_BUILD_TABLE_POST;
|
||||||
|
}
|
||||||
|
|
||||||
#define ONE_KB ((ram_addr_t)1 << 10)
|
#define ONE_KB ((ram_addr_t)1 << 10)
|
||||||
#define ONE_MB ((ram_addr_t)1 << 20)
|
#define ONE_MB ((ram_addr_t)1 << 20)
|
||||||
#define ONE_GB ((ram_addr_t)1 << 30)
|
#define ONE_GB ((ram_addr_t)1 << 30)
|
||||||
|
@ -832,6 +866,8 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
|
||||||
smbios_build_type_4_table(i);
|
smbios_build_type_4_table(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smbios_build_type_11_table();
|
||||||
|
|
||||||
#define MAX_DIMM_SZ (16ll * ONE_GB)
|
#define MAX_DIMM_SZ (16ll * ONE_GB)
|
||||||
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
|
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
|
||||||
: ((ram_size - 1) % MAX_DIMM_SZ) + 1)
|
: ((ram_size - 1) % MAX_DIMM_SZ) + 1)
|
||||||
|
@ -882,6 +918,38 @@ static void save_opt(const char **dest, QemuOpts *opts, const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct opt_list {
|
||||||
|
const char *name;
|
||||||
|
size_t *ndest;
|
||||||
|
const char ***dest;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int save_opt_one(void *opaque,
|
||||||
|
const char *name, const char *value,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
struct opt_list *opt = opaque;
|
||||||
|
|
||||||
|
if (!g_str_equal(name, opt->name)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*opt->dest = g_renew(const char *, *opt->dest, (*opt->ndest) + 1);
|
||||||
|
(*opt->dest)[*opt->ndest] = value;
|
||||||
|
(*opt->ndest)++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void save_opt_list(size_t *ndest, const char ***dest,
|
||||||
|
QemuOpts *opts, const char *name)
|
||||||
|
{
|
||||||
|
struct opt_list opt = {
|
||||||
|
name, ndest, dest,
|
||||||
|
};
|
||||||
|
qemu_opt_foreach(opts, save_opt_one, &opt, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void smbios_entry_add(QemuOpts *opts, Error **errp)
|
void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
const char *val;
|
const char *val;
|
||||||
|
@ -1035,6 +1103,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||||
save_opt(&type4.asset, opts, "asset");
|
save_opt(&type4.asset, opts, "asset");
|
||||||
save_opt(&type4.part, opts, "part");
|
save_opt(&type4.part, opts, "part");
|
||||||
return;
|
return;
|
||||||
|
case 11:
|
||||||
|
qemu_opts_validate(opts, qemu_smbios_type11_opts, &error_fatal);
|
||||||
|
save_opt_list(&type11.nvalues, &type11.values, opts, "value");
|
||||||
|
return;
|
||||||
case 17:
|
case 17:
|
||||||
qemu_opts_validate(opts, qemu_smbios_type17_opts, &error_fatal);
|
qemu_opts_validate(opts, qemu_smbios_type17_opts, &error_fatal);
|
||||||
save_opt(&type17.loc_pfx, opts, "loc_pfx");
|
save_opt(&type17.loc_pfx, opts, "loc_pfx");
|
||||||
|
|
|
@ -63,6 +63,18 @@ extern unsigned smbios_table_cnt;
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value) \
|
||||||
|
do { \
|
||||||
|
int len = (value != NULL) ? strlen(value) + 1 : 0; \
|
||||||
|
if (len > 1) { \
|
||||||
|
smbios_tables = g_realloc(smbios_tables, \
|
||||||
|
smbios_tables_len + len); \
|
||||||
|
memcpy(smbios_tables + smbios_tables_len, value, len); \
|
||||||
|
smbios_tables_len += len; \
|
||||||
|
++str_index; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define SMBIOS_BUILD_TABLE_POST \
|
#define SMBIOS_BUILD_TABLE_POST \
|
||||||
do { \
|
do { \
|
||||||
size_t term_cnt, t_size; \
|
size_t term_cnt, t_size; \
|
||||||
|
|
|
@ -3416,7 +3416,7 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
|
||||||
PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
|
PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
|
||||||
&xhci->mem);
|
&xhci->mem);
|
||||||
|
|
||||||
if (pci_bus_is_express(dev->bus) ||
|
if (pci_bus_is_express(pci_get_bus(dev)) ||
|
||||||
xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
|
xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
|
||||||
ret = pcie_endpoint_cap_init(dev, 0xa0);
|
ret = pcie_endpoint_cap_init(dev, 0xa0);
|
||||||
assert(ret > 0);
|
assert(ret > 0);
|
||||||
|
|
|
@ -1654,8 +1654,8 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pci_bus_is_express(vdev->pdev.bus)) {
|
if (!pci_bus_is_express(pci_get_bus(&vdev->pdev))) {
|
||||||
PCIBus *bus = vdev->pdev.bus;
|
PCIBus *bus = pci_get_bus(&vdev->pdev);
|
||||||
PCIDevice *bridge;
|
PCIDevice *bridge;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1680,14 +1680,14 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
|
||||||
*/
|
*/
|
||||||
while (!pci_bus_is_root(bus)) {
|
while (!pci_bus_is_root(bus)) {
|
||||||
bridge = pci_bridge_get_device(bus);
|
bridge = pci_bridge_get_device(bus);
|
||||||
bus = bridge->bus;
|
bus = pci_get_bus(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_bus_is_express(bus)) {
|
if (pci_bus_is_express(bus)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pci_bus_is_root(vdev->pdev.bus)) {
|
} else if (pci_bus_is_root(pci_get_bus(&vdev->pdev))) {
|
||||||
/*
|
/*
|
||||||
* On a Root Complex bus Endpoints become Root Complex Integrated
|
* On a Root Complex bus Endpoints become Root Complex Integrated
|
||||||
* Endpoints, which changes the type and clears the LNK & LNK2 fields.
|
* Endpoints, which changes the type and clears the LNK & LNK2 fields.
|
||||||
|
@ -1890,7 +1890,7 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
|
||||||
uint8_t *config;
|
uint8_t *config;
|
||||||
|
|
||||||
/* Only add extended caps if we have them and the guest can see them */
|
/* Only add extended caps if we have them and the guest can see them */
|
||||||
if (!pci_is_express(pdev) || !pci_bus_is_express(pdev->bus) ||
|
if (!pci_is_express(pdev) || !pci_bus_is_express(pci_get_bus(pdev)) ||
|
||||||
!pci_get_long(pdev->config + PCI_CONFIG_SPACE_SIZE)) {
|
!pci_get_long(pdev->config + PCI_CONFIG_SPACE_SIZE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1588,9 +1588,11 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
|
||||||
"neither legacy nor transitional device.");
|
"neither legacy nor transitional device.");
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
/* legacy and transitional */
|
/*
|
||||||
pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
|
* Legacy and transitional devices use specific subsystem IDs.
|
||||||
pci_get_word(config + PCI_VENDOR_ID));
|
* Note that the subsystem vendor ID (config + PCI_SUBSYSTEM_VENDOR_ID)
|
||||||
|
* is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default.
|
||||||
|
*/
|
||||||
pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
|
pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
|
||||||
} else {
|
} else {
|
||||||
/* pure virtio-1.0 */
|
/* pure virtio-1.0 */
|
||||||
|
@ -1708,8 +1710,8 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
|
VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
|
||||||
VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
|
VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
|
||||||
bool pcie_port = pci_bus_is_express(pci_dev->bus) &&
|
bool pcie_port = pci_bus_is_express(pci_get_bus(pci_dev)) &&
|
||||||
!pci_bus_is_root(pci_dev->bus);
|
!pci_bus_is_root(pci_get_bus(pci_dev));
|
||||||
|
|
||||||
if (kvm_enabled() && !kvm_has_many_ioeventfds()) {
|
if (kvm_enabled() && !kvm_has_many_ioeventfds()) {
|
||||||
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
|
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
|
||||||
|
|
|
@ -2469,7 +2469,7 @@ void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, ...)
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
|
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
|
||||||
virtio_set_status(vdev, vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET);
|
vdev->status = vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET;
|
||||||
virtio_notify_config(vdev);
|
virtio_notify_config(vdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...)
|
||||||
|
|
||||||
va_start(ap, f);
|
va_start(ap, f);
|
||||||
if (d) {
|
if (d) {
|
||||||
fprintf(stderr, "[%02x:%02x.%d] ", pci_bus_num(d->bus),
|
fprintf(stderr, "[%02x:%02x.%d] ", pci_dev_bus_num(d),
|
||||||
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
|
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
|
||||||
}
|
}
|
||||||
vfprintf(stderr, f, ap);
|
vfprintf(stderr, f, ap);
|
||||||
|
@ -602,7 +602,7 @@ static void xen_pt_region_update(XenPCIPassthroughState *s,
|
||||||
}
|
}
|
||||||
|
|
||||||
args.type = d->io_regions[bar].type;
|
args.type = d->io_regions[bar].type;
|
||||||
pci_for_each_device(d->bus, pci_bus_num(d->bus),
|
pci_for_each_device(pci_get_bus(d), pci_dev_bus_num(d),
|
||||||
xen_pt_check_bar_overlap, &args);
|
xen_pt_check_bar_overlap, &args);
|
||||||
if (args.rc) {
|
if (args.rc) {
|
||||||
XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
|
XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
|
||||||
|
@ -695,7 +695,7 @@ xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
|
||||||
PCIDevice *d = &s->dev;
|
PCIDevice *d = &s->dev;
|
||||||
|
|
||||||
gpu_dev_id = dev->device_id;
|
gpu_dev_id = dev->device_id;
|
||||||
igd_passthrough_isa_bridge_create(d->bus, gpu_dev_id);
|
igd_passthrough_isa_bridge_create(pci_get_bus(d), gpu_dev_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* destroy. */
|
/* destroy. */
|
||||||
|
@ -711,7 +711,7 @@ static void xen_pt_destroy(PCIDevice *d) {
|
||||||
intx = xen_pt_pci_intx(s);
|
intx = xen_pt_pci_intx(s);
|
||||||
rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq,
|
rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq,
|
||||||
PT_IRQ_TYPE_PCI,
|
PT_IRQ_TYPE_PCI,
|
||||||
pci_bus_num(d->bus),
|
pci_dev_bus_num(d),
|
||||||
PCI_SLOT(s->dev.devfn),
|
PCI_SLOT(s->dev.devfn),
|
||||||
intx,
|
intx,
|
||||||
0 /* isa_irq */);
|
0 /* isa_irq */);
|
||||||
|
@ -867,7 +867,7 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
|
||||||
uint8_t e_intx = xen_pt_pci_intx(s);
|
uint8_t e_intx = xen_pt_pci_intx(s);
|
||||||
|
|
||||||
rc = xc_domain_bind_pt_pci_irq(xen_xc, xen_domid, machine_irq,
|
rc = xc_domain_bind_pt_pci_irq(xen_xc, xen_domid, machine_irq,
|
||||||
pci_bus_num(d->bus),
|
pci_dev_bus_num(d),
|
||||||
PCI_SLOT(d->devfn),
|
PCI_SLOT(d->devfn),
|
||||||
e_intx);
|
e_intx);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#define X86_IOMMU_GET_CLASS(obj) \
|
#define X86_IOMMU_GET_CLASS(obj) \
|
||||||
OBJECT_GET_CLASS(X86IOMMUClass, obj, TYPE_X86_IOMMU_DEVICE)
|
OBJECT_GET_CLASS(X86IOMMUClass, obj, TYPE_X86_IOMMU_DEVICE)
|
||||||
|
|
||||||
#define X86_IOMMU_PCI_DEVFN_MAX 256
|
|
||||||
#define X86_IOMMU_SID_INVALID (0xffff)
|
#define X86_IOMMU_SID_INVALID (0xffff)
|
||||||
|
|
||||||
typedef struct X86IOMMUState X86IOMMUState;
|
typedef struct X86IOMMUState X86IOMMUState;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "hw/pci/pci_bus.h"
|
#include "hw/pci/pci_bridge.h"
|
||||||
#include "hw/pci/pcie_host.h"
|
#include "hw/pci/pcie_host.h"
|
||||||
|
|
||||||
#define TYPE_XILINX_PCIE_HOST "xilinx-pcie-host"
|
#define TYPE_XILINX_PCIE_HOST "xilinx-pcie-host"
|
||||||
|
|
|
@ -285,7 +285,6 @@ struct PCIDevice {
|
||||||
uint8_t *used;
|
uint8_t *used;
|
||||||
|
|
||||||
/* the following fields are read only */
|
/* the following fields are read only */
|
||||||
PCIBus *bus;
|
|
||||||
int32_t devfn;
|
int32_t devfn;
|
||||||
/* Cached device to fetch requester ID from, to avoid the PCI
|
/* Cached device to fetch requester ID from, to avoid the PCI
|
||||||
* tree walking every time we invoke PCI request (e.g.,
|
* tree walking every time we invoke PCI request (e.g.,
|
||||||
|
@ -400,12 +399,12 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
|
||||||
|
|
||||||
bool pci_bus_is_express(PCIBus *bus);
|
bool pci_bus_is_express(PCIBus *bus);
|
||||||
bool pci_bus_is_root(PCIBus *bus);
|
bool pci_bus_is_root(PCIBus *bus);
|
||||||
void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
|
void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
|
||||||
const char *name,
|
const char *name,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min, const char *typename);
|
uint8_t devfn_min, const char *typename);
|
||||||
PCIBus *pci_bus_new(DeviceState *parent, const char *name,
|
PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min, const char *typename);
|
uint8_t devfn_min, const char *typename);
|
||||||
|
@ -414,12 +413,13 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
||||||
int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
|
int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
|
||||||
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
|
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
|
||||||
int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin);
|
int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin);
|
||||||
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
|
PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
|
||||||
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
||||||
void *irq_opaque,
|
void *irq_opaque,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
uint8_t devfn_min, int nirq, const char *typename);
|
uint8_t devfn_min, int nirq,
|
||||||
|
const char *typename);
|
||||||
void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn);
|
void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn);
|
||||||
PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin);
|
PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin);
|
||||||
bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new);
|
bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new);
|
||||||
|
@ -434,7 +434,16 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
|
||||||
|
|
||||||
PCIDevice *pci_vga_init(PCIBus *bus);
|
PCIDevice *pci_vga_init(PCIBus *bus);
|
||||||
|
|
||||||
|
static inline PCIBus *pci_get_bus(const PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return PCI_BUS(qdev_get_parent_bus(DEVICE(dev)));
|
||||||
|
}
|
||||||
int pci_bus_num(PCIBus *s);
|
int pci_bus_num(PCIBus *s);
|
||||||
|
static inline int pci_dev_bus_num(const PCIDevice *dev)
|
||||||
|
{
|
||||||
|
return pci_bus_num(pci_get_bus(dev));
|
||||||
|
}
|
||||||
|
|
||||||
int pci_bus_numa_node(PCIBus *bus);
|
int pci_bus_numa_node(PCIBus *bus);
|
||||||
void pci_for_each_device(PCIBus *bus, int bus_num,
|
void pci_for_each_device(PCIBus *bus, int bus_num,
|
||||||
void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque),
|
void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque),
|
||||||
|
@ -458,7 +467,6 @@ void pci_for_each_bus(PCIBus *bus,
|
||||||
pci_for_each_bus_depth_first(bus, NULL, fn, opaque);
|
pci_for_each_bus_depth_first(bus, NULL, fn, opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIBus *pci_find_primary_bus(void);
|
|
||||||
PCIBus *pci_device_root_bus(const PCIDevice *d);
|
PCIBus *pci_device_root_bus(const PCIDevice *d);
|
||||||
const char *pci_root_bus_path(PCIDevice *dev);
|
const char *pci_root_bus_path(PCIDevice *dev);
|
||||||
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);
|
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);
|
||||||
|
@ -739,7 +747,7 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
|
||||||
|
|
||||||
static inline uint16_t pci_get_bdf(PCIDevice *dev)
|
static inline uint16_t pci_get_bdf(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
|
return PCI_BUILD_BDF(pci_bus_num(pci_get_bus(dev)), dev->devfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t pci_requester_id(PCIDevice *dev);
|
uint16_t pci_requester_id(PCIDevice *dev);
|
||||||
|
|
|
@ -27,6 +27,54 @@
|
||||||
#define QEMU_PCI_BRIDGE_H
|
#define QEMU_PCI_BRIDGE_H
|
||||||
|
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
|
#include "hw/pci/pci_bus.h"
|
||||||
|
|
||||||
|
typedef struct PCIBridgeWindows PCIBridgeWindows;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Aliases for each of the address space windows that the bridge
|
||||||
|
* can forward. Mapped into the bridge's parent's address space,
|
||||||
|
* as subregions.
|
||||||
|
*/
|
||||||
|
struct PCIBridgeWindows {
|
||||||
|
MemoryRegion alias_pref_mem;
|
||||||
|
MemoryRegion alias_mem;
|
||||||
|
MemoryRegion alias_io;
|
||||||
|
/*
|
||||||
|
* When bridge control VGA forwarding is enabled, bridges will
|
||||||
|
* provide positive decode on the PCI VGA defined I/O port and
|
||||||
|
* MMIO ranges. When enabled forwarding is only qualified on the
|
||||||
|
* I/O and memory enable bits in the bridge command register.
|
||||||
|
*/
|
||||||
|
MemoryRegion alias_vga[QEMU_PCI_VGA_NUM_REGIONS];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TYPE_PCI_BRIDGE "base-pci-bridge"
|
||||||
|
#define PCI_BRIDGE(obj) OBJECT_CHECK(PCIBridge, (obj), TYPE_PCI_BRIDGE)
|
||||||
|
|
||||||
|
struct PCIBridge {
|
||||||
|
/*< private >*/
|
||||||
|
PCIDevice parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
/* private member */
|
||||||
|
PCIBus sec_bus;
|
||||||
|
/*
|
||||||
|
* Memory regions for the bridge's address spaces. These regions are not
|
||||||
|
* directly added to system_memory/system_io or its descendants.
|
||||||
|
* Bridge's secondary bus points to these, so that devices
|
||||||
|
* under the bridge see these regions as its address spaces.
|
||||||
|
* The regions are as large as the entire address space -
|
||||||
|
* they don't take into account any windows.
|
||||||
|
*/
|
||||||
|
MemoryRegion address_space_mem;
|
||||||
|
MemoryRegion address_space_io;
|
||||||
|
|
||||||
|
PCIBridgeWindows *windows;
|
||||||
|
|
||||||
|
pci_map_irq_fn map_irq;
|
||||||
|
const char *bus_name;
|
||||||
|
};
|
||||||
|
|
||||||
#define PCI_BRIDGE_DEV_PROP_CHASSIS_NR "chassis_nr"
|
#define PCI_BRIDGE_DEV_PROP_CHASSIS_NR "chassis_nr"
|
||||||
#define PCI_BRIDGE_DEV_PROP_MSI "msi"
|
#define PCI_BRIDGE_DEV_PROP_MSI "msi"
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
#define QEMU_PCI_BUS_H
|
#define QEMU_PCI_BUS_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PCI Bus and Bridge datastructures.
|
* PCI Bus datastructures.
|
||||||
*
|
*
|
||||||
* Do not access the following members directly;
|
* Do not access the following members directly;
|
||||||
* use accessor functions in pci.h, pci_bridge.h
|
* use accessor functions in pci.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct PCIBusClass {
|
typedef struct PCIBusClass {
|
||||||
|
@ -44,51 +44,4 @@ struct PCIBus {
|
||||||
Notifier machine_done;
|
Notifier machine_done;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct PCIBridgeWindows PCIBridgeWindows;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Aliases for each of the address space windows that the bridge
|
|
||||||
* can forward. Mapped into the bridge's parent's address space,
|
|
||||||
* as subregions.
|
|
||||||
*/
|
|
||||||
struct PCIBridgeWindows {
|
|
||||||
MemoryRegion alias_pref_mem;
|
|
||||||
MemoryRegion alias_mem;
|
|
||||||
MemoryRegion alias_io;
|
|
||||||
/*
|
|
||||||
* When bridge control VGA forwarding is enabled, bridges will
|
|
||||||
* provide positive decode on the PCI VGA defined I/O port and
|
|
||||||
* MMIO ranges. When enabled forwarding is only qualified on the
|
|
||||||
* I/O and memory enable bits in the bridge command register.
|
|
||||||
*/
|
|
||||||
MemoryRegion alias_vga[QEMU_PCI_VGA_NUM_REGIONS];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TYPE_PCI_BRIDGE "base-pci-bridge"
|
|
||||||
#define PCI_BRIDGE(obj) OBJECT_CHECK(PCIBridge, (obj), TYPE_PCI_BRIDGE)
|
|
||||||
|
|
||||||
struct PCIBridge {
|
|
||||||
/*< private >*/
|
|
||||||
PCIDevice parent_obj;
|
|
||||||
/*< public >*/
|
|
||||||
|
|
||||||
/* private member */
|
|
||||||
PCIBus sec_bus;
|
|
||||||
/*
|
|
||||||
* Memory regions for the bridge's address spaces. These regions are not
|
|
||||||
* directly added to system_memory/system_io or its descendants.
|
|
||||||
* Bridge's secondary bus points to these, so that devices
|
|
||||||
* under the bridge see these regions as its address spaces.
|
|
||||||
* The regions are as large as the entire address space -
|
|
||||||
* they don't take into account any windows.
|
|
||||||
*/
|
|
||||||
MemoryRegion address_space_mem;
|
|
||||||
MemoryRegion address_space_io;
|
|
||||||
|
|
||||||
PCIBridgeWindows *windows;
|
|
||||||
|
|
||||||
pci_map_irq_fn map_irq;
|
|
||||||
const char *bus_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* QEMU_PCI_BUS_H */
|
#endif /* QEMU_PCI_BUS_H */
|
||||||
|
|
|
@ -31,6 +31,7 @@ extern const PropertyInfo qdev_prop_vlan;
|
||||||
extern const PropertyInfo qdev_prop_pci_devfn;
|
extern const PropertyInfo qdev_prop_pci_devfn;
|
||||||
extern const PropertyInfo qdev_prop_blocksize;
|
extern const PropertyInfo qdev_prop_blocksize;
|
||||||
extern const PropertyInfo qdev_prop_pci_host_devaddr;
|
extern const PropertyInfo qdev_prop_pci_host_devaddr;
|
||||||
|
extern const PropertyInfo qdev_prop_uuid;
|
||||||
extern const PropertyInfo qdev_prop_arraylen;
|
extern const PropertyInfo qdev_prop_arraylen;
|
||||||
extern const PropertyInfo qdev_prop_link;
|
extern const PropertyInfo qdev_prop_link;
|
||||||
|
|
||||||
|
@ -214,6 +215,14 @@ extern const PropertyInfo qdev_prop_link;
|
||||||
#define DEFINE_PROP_MEMORY_REGION(_n, _s, _f) \
|
#define DEFINE_PROP_MEMORY_REGION(_n, _s, _f) \
|
||||||
DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, MemoryRegion *)
|
DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, MemoryRegion *)
|
||||||
|
|
||||||
|
#define DEFINE_PROP_UUID(_name, _state, _field) { \
|
||||||
|
.name = (_name), \
|
||||||
|
.info = &qdev_prop_uuid, \
|
||||||
|
.offset = offsetof(_state, _field) \
|
||||||
|
+ type_check(QemuUUID, typeof_field(_state, _field)), \
|
||||||
|
.set_default = true, \
|
||||||
|
}
|
||||||
|
|
||||||
#define DEFINE_PROP_END_OF_LIST() \
|
#define DEFINE_PROP_END_OF_LIST() \
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,12 @@ struct smbios_type_4 {
|
||||||
uint16_t processor_family2;
|
uint16_t processor_family2;
|
||||||
} QEMU_PACKED;
|
} QEMU_PACKED;
|
||||||
|
|
||||||
|
/* SMBIOS type 11 - OEM strings */
|
||||||
|
struct smbios_type_11 {
|
||||||
|
struct smbios_structure_header header;
|
||||||
|
uint8_t count;
|
||||||
|
} QEMU_PACKED;
|
||||||
|
|
||||||
/* SMBIOS type 16 - Physical Memory Array (v2.7) */
|
/* SMBIOS type 16 - Physical Memory Array (v2.7) */
|
||||||
struct smbios_type_16 {
|
struct smbios_type_16 {
|
||||||
struct smbios_structure_header header;
|
struct smbios_structure_header header;
|
||||||
|
|
|
@ -542,10 +542,10 @@ static inline void xen_map_pcidev(domid_t dom,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_xen_map_pcidev(ioservid, pci_bus_num(pci_dev->bus),
|
trace_xen_map_pcidev(ioservid, pci_dev_bus_num(pci_dev),
|
||||||
PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
|
PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
|
||||||
xendevicemodel_map_pcidev_to_ioreq_server(xen_dmod, dom, ioservid, 0,
|
xendevicemodel_map_pcidev_to_ioreq_server(xen_dmod, dom, ioservid, 0,
|
||||||
pci_bus_num(pci_dev->bus),
|
pci_dev_bus_num(pci_dev),
|
||||||
PCI_SLOT(pci_dev->devfn),
|
PCI_SLOT(pci_dev->devfn),
|
||||||
PCI_FUNC(pci_dev->devfn));
|
PCI_FUNC(pci_dev->devfn));
|
||||||
}
|
}
|
||||||
|
@ -558,10 +558,10 @@ static inline void xen_unmap_pcidev(domid_t dom,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_xen_unmap_pcidev(ioservid, pci_bus_num(pci_dev->bus),
|
trace_xen_unmap_pcidev(ioservid, pci_dev_bus_num(pci_dev),
|
||||||
PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
|
PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
|
||||||
xendevicemodel_unmap_pcidev_from_ioreq_server(xen_dmod, dom, ioservid, 0,
|
xendevicemodel_unmap_pcidev_from_ioreq_server(xen_dmod, dom, ioservid, 0,
|
||||||
pci_bus_num(pci_dev->bus),
|
pci_dev_bus_num(pci_dev),
|
||||||
PCI_SLOT(pci_dev->devfn),
|
PCI_SLOT(pci_dev->devfn),
|
||||||
PCI_FUNC(pci_dev->devfn));
|
PCI_FUNC(pci_dev->devfn));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,53 @@
|
||||||
|
|
||||||
static char disk[] = "tests/pxe-test-disk-XXXXXX";
|
static char disk[] = "tests/pxe-test-disk-XXXXXX";
|
||||||
|
|
||||||
static void test_pxe_one(const char *params, bool ipv6)
|
typedef struct testdef {
|
||||||
|
const char *machine; /* Machine type */
|
||||||
|
const char *model; /* NIC device model */
|
||||||
|
} testdef_t;
|
||||||
|
|
||||||
|
static testdef_t x86_tests[] = {
|
||||||
|
{ "pc", "e1000" },
|
||||||
|
{ "pc", "virtio-net-pci" },
|
||||||
|
{ "q35", "e1000e" },
|
||||||
|
{ "q35", "virtio-net-pci", },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static testdef_t x86_tests_slow[] = {
|
||||||
|
{ "pc", "ne2k_pci", },
|
||||||
|
{ "pc", "i82550", },
|
||||||
|
{ "pc", "rtl8139" },
|
||||||
|
{ "pc", "vmxnet3" },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static testdef_t ppc64_tests[] = {
|
||||||
|
{ "pseries", "spapr-vlan" },
|
||||||
|
{ "pseries", "virtio-net-pci", },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static testdef_t ppc64_tests_slow[] = {
|
||||||
|
{ "pseries", "e1000" },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static testdef_t s390x_tests[] = {
|
||||||
|
{ "s390-ccw-virtio", "virtio-net-ccw" },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_pxe_one(const testdef_t *test, bool ipv6)
|
||||||
{
|
{
|
||||||
char *args;
|
char *args;
|
||||||
|
|
||||||
args = g_strdup_printf("-machine accel=kvm:tcg -nodefaults -boot order=n "
|
args = g_strdup_printf(
|
||||||
"-netdev user,id=" NETNAME ",tftp=./,bootfile=%s,"
|
"-machine %s,accel=kvm:tcg -nodefaults -boot order=n "
|
||||||
"ipv4=%s,ipv6=%s %s", disk, ipv6 ? "off" : "on",
|
"-netdev user,id=" NETNAME ",tftp=./,bootfile=%s,ipv4=%s,ipv6=%s "
|
||||||
ipv6 ? "on" : "off", params);
|
"-device %s,bootindex=1,netdev=" NETNAME,
|
||||||
|
test->machine, disk, ipv6 ? "off" : "on", ipv6 ? "on" : "off",
|
||||||
|
test->model);
|
||||||
|
|
||||||
qtest_start(args);
|
qtest_start(args);
|
||||||
boot_sector_test();
|
boot_sector_test();
|
||||||
|
@ -39,22 +78,38 @@ static void test_pxe_one(const char *params, bool ipv6)
|
||||||
|
|
||||||
static void test_pxe_ipv4(gconstpointer data)
|
static void test_pxe_ipv4(gconstpointer data)
|
||||||
{
|
{
|
||||||
const char *model = data;
|
const testdef_t *test = data;
|
||||||
char *dev_arg;
|
|
||||||
|
|
||||||
dev_arg = g_strdup_printf("-device %s,netdev=" NETNAME, model);
|
test_pxe_one(test, false);
|
||||||
test_pxe_one(dev_arg, false);
|
|
||||||
g_free(dev_arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_pxe_spapr_vlan(void)
|
static void test_pxe_ipv6(gconstpointer data)
|
||||||
{
|
{
|
||||||
test_pxe_one("-device spapr-vlan,netdev=" NETNAME, true);
|
const testdef_t *test = data;
|
||||||
|
|
||||||
|
test_pxe_one(test, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_pxe_virtio_ccw(void)
|
static void test_batch(const testdef_t *tests, bool ipv6)
|
||||||
{
|
{
|
||||||
test_pxe_one("-device virtio-net-ccw,bootindex=1,netdev=" NETNAME, false);
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; tests[i].machine; i++) {
|
||||||
|
const testdef_t *test = &tests[i];
|
||||||
|
char *testname;
|
||||||
|
|
||||||
|
testname = g_strdup_printf("pxe/ipv4/%s/%s",
|
||||||
|
test->machine, test->model);
|
||||||
|
qtest_add_data_func(testname, test, test_pxe_ipv4);
|
||||||
|
g_free(testname);
|
||||||
|
|
||||||
|
if (ipv6) {
|
||||||
|
testname = g_strdup_printf("pxe/ipv6/%s/%s",
|
||||||
|
test->machine, test->model);
|
||||||
|
qtest_add_data_func(testname, test, test_pxe_ipv6);
|
||||||
|
g_free(testname);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -69,23 +124,17 @@ int main(int argc, char *argv[])
|
||||||
g_test_init(&argc, &argv, NULL);
|
g_test_init(&argc, &argv, NULL);
|
||||||
|
|
||||||
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
|
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
|
||||||
qtest_add_data_func("pxe/e1000", "e1000", test_pxe_ipv4);
|
test_batch(x86_tests, false);
|
||||||
qtest_add_data_func("pxe/virtio", "virtio-net-pci", test_pxe_ipv4);
|
|
||||||
if (g_test_slow()) {
|
if (g_test_slow()) {
|
||||||
qtest_add_data_func("pxe/ne2000", "ne2k_pci", test_pxe_ipv4);
|
test_batch(x86_tests_slow, false);
|
||||||
qtest_add_data_func("pxe/eepro100", "i82550", test_pxe_ipv4);
|
|
||||||
qtest_add_data_func("pxe/pcnet", "pcnet", test_pxe_ipv4);
|
|
||||||
qtest_add_data_func("pxe/rtl8139", "rtl8139", test_pxe_ipv4);
|
|
||||||
qtest_add_data_func("pxe/vmxnet3", "vmxnet3", test_pxe_ipv4);
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(arch, "ppc64") == 0) {
|
} else if (strcmp(arch, "ppc64") == 0) {
|
||||||
qtest_add_func("pxe/spapr-vlan", test_pxe_spapr_vlan);
|
test_batch(ppc64_tests, g_test_slow());
|
||||||
if (g_test_slow()) {
|
if (g_test_slow()) {
|
||||||
qtest_add_data_func("pxe/virtio", "virtio-net-pci", test_pxe_ipv4);
|
test_batch(ppc64_tests_slow, true);
|
||||||
qtest_add_data_func("pxe/e1000", "e1000", test_pxe_ipv4);
|
|
||||||
}
|
}
|
||||||
} else if (g_str_equal(arch, "s390x")) {
|
} else if (g_str_equal(arch, "s390x")) {
|
||||||
qtest_add_func("pxe/virtio-ccw", test_pxe_virtio_ccw);
|
test_batch(s390x_tests, g_test_slow());
|
||||||
}
|
}
|
||||||
ret = g_test_run();
|
ret = g_test_run();
|
||||||
boot_sector_cleanup(disk);
|
boot_sector_cleanup(disk);
|
||||||
|
|
|
@ -674,6 +674,30 @@ static void pci_hotplug(void)
|
||||||
qtest_shutdown(qs);
|
qtest_shutdown(qs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that setting the vring addr on a non-existent virtqueue does
|
||||||
|
* not crash.
|
||||||
|
*/
|
||||||
|
static void test_nonexistent_virtqueue(void)
|
||||||
|
{
|
||||||
|
QPCIBar bar0;
|
||||||
|
QOSState *qs;
|
||||||
|
QPCIDevice *dev;
|
||||||
|
|
||||||
|
qs = pci_test_start();
|
||||||
|
dev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4, 0));
|
||||||
|
g_assert(dev != NULL);
|
||||||
|
|
||||||
|
qpci_device_enable(dev);
|
||||||
|
bar0 = qpci_iomap(dev, 0, NULL);
|
||||||
|
|
||||||
|
qpci_io_writeb(dev, bar0, VIRTIO_PCI_QUEUE_SEL, 2);
|
||||||
|
qpci_io_writel(dev, bar0, VIRTIO_PCI_QUEUE_PFN, 1);
|
||||||
|
|
||||||
|
g_free(dev);
|
||||||
|
qtest_shutdown(qs);
|
||||||
|
}
|
||||||
|
|
||||||
static void mmio_basic(void)
|
static void mmio_basic(void)
|
||||||
{
|
{
|
||||||
QVirtioMMIODevice *dev;
|
QVirtioMMIODevice *dev;
|
||||||
|
@ -724,6 +748,7 @@ int main(int argc, char **argv)
|
||||||
qtest_add_func("/virtio/blk/pci/basic", pci_basic);
|
qtest_add_func("/virtio/blk/pci/basic", pci_basic);
|
||||||
qtest_add_func("/virtio/blk/pci/indirect", pci_indirect);
|
qtest_add_func("/virtio/blk/pci/indirect", pci_indirect);
|
||||||
qtest_add_func("/virtio/blk/pci/config", pci_config);
|
qtest_add_func("/virtio/blk/pci/config", pci_config);
|
||||||
|
qtest_add_func("/virtio/blk/pci/nxvirtq", test_nonexistent_virtqueue);
|
||||||
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
|
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
|
||||||
qtest_add_func("/virtio/blk/pci/msix", pci_msix);
|
qtest_add_func("/virtio/blk/pci/msix", pci_msix);
|
||||||
qtest_add_func("/virtio/blk/pci/idx", pci_idx);
|
qtest_add_func("/virtio/blk/pci/idx", pci_idx);
|
||||||
|
|
Loading…
Reference in New Issue