diff options
Diffstat (limited to 'hw/acpi/pcihp.c')
-rw-r--r-- | hw/acpi/pcihp.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index c420a388ea..7da51c0569 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -75,6 +75,43 @@ static int acpi_pcihp_get_bsel(PCIBus *bus) } } +/* Assign BSEL property to all buses. In the future, this can be changed + * to only assign to buses that support hotplug. + */ +static void *acpi_set_bsel(PCIBus *bus, void *opaque) +{ + unsigned *bsel_alloc = opaque; + unsigned *bus_bsel; + + if (qbus_is_hotpluggable(BUS(bus))) { + bus_bsel = g_malloc(sizeof *bus_bsel); + + *bus_bsel = (*bsel_alloc)++; + object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, + bus_bsel, &error_abort); + } + + return bsel_alloc; +} + +static void acpi_set_pci_info(void) +{ + static bool bsel_is_set; + PCIBus *bus; + unsigned bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT; + + if (bsel_is_set) { + return; + } + bsel_is_set = true; + + bus = find_i440fx(); /* TODO: Q35 support */ + if (bus) { + /* Scan all PCI buses. Set property to enable acpi based hotplug. */ + pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc); + } +} + static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque) { AcpiPciHpFind *find = opaque; @@ -177,6 +214,7 @@ static void acpi_pcihp_update(AcpiPciHpState *s) void acpi_pcihp_reset(AcpiPciHpState *s) { + acpi_set_pci_info(); acpi_pcihp_update(s); } @@ -273,7 +311,7 @@ static void pci_write(void *opaque, hwaddr addr, uint64_t data, addr, data); break; case PCI_SEL_BASE: - s->hotplug_select = data; + s->hotplug_select = s->legacy_piix ? ACPI_PCIHP_BSEL_DEFAULT : data; ACPI_PCIHP_DPRINTF("pcisel write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, data); default: |