diff --git a/hw/acpi/viot.c b/hw/acpi/viot.c index 5dafcbf5ef..c32bbdd180 100644 --- a/hw/acpi/viot.c +++ b/hw/acpi/viot.c @@ -10,10 +10,9 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" -struct viot_pci_ranges { - GArray *blob; - size_t count; - uint16_t output_node; +struct viot_pci_host_range { + int min_bus; + int max_bus; }; static void build_pci_host_range(GArray *table_data, int min_bus, int max_bus, @@ -44,8 +43,7 @@ static void build_pci_host_range(GArray *table_data, int min_bus, int max_bus, /* Build PCI range for a given PCI host bridge */ static int enumerate_pci_host_bridges(Object *obj, void *opaque) { - struct viot_pci_ranges *pci_ranges = opaque; - GArray *blob = pci_ranges->blob; + GArray *pci_host_ranges = opaque; if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) { PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus; @@ -55,9 +53,11 @@ static int enumerate_pci_host_bridges(Object *obj, void *opaque) pci_bus_range(bus, &min_bus, &max_bus); - build_pci_host_range(blob, min_bus, max_bus, - pci_ranges->output_node); - pci_ranges->count++; + const struct viot_pci_host_range pci_host_range = { + .min_bus = min_bus, + .max_bus = max_bus, + }; + g_array_append_val(pci_host_ranges, pci_host_range); } } @@ -78,19 +78,19 @@ void build_viot(MachineState *ms, GArray *table_data, BIOSLinker *linker, int viommu_off = 48; AcpiTable table = { .sig = "VIOT", .rev = 0, .oem_id = oem_id, .oem_table_id = oem_table_id }; - struct viot_pci_ranges pci_ranges = { - .output_node = viommu_off, - .blob = g_array_new(false, true /* clear */, 1), - }; + GArray *pci_host_ranges = g_array_new(false, true, + sizeof(struct viot_pci_host_range)); + struct viot_pci_host_range *pci_host_range; + int i; /* Build the list of PCI ranges that this viommu manages */ object_child_foreach_recursive(OBJECT(ms), enumerate_pci_host_bridges, - &pci_ranges); + pci_host_ranges); /* ACPI table header */ acpi_table_begin(&table, table_data); /* Node count */ - build_append_int_noprefix(table_data, pci_ranges.count + 1, 2); + build_append_int_noprefix(table_data, pci_host_ranges->len + 1, 2); /* Node offset */ build_append_int_noprefix(table_data, viommu_off, 2); /* Reserved */ @@ -111,9 +111,15 @@ void build_viot(MachineState *ms, GArray *table_data, BIOSLinker *linker, build_append_int_noprefix(table_data, 0, 8); /* PCI ranges found above */ - g_array_append_vals(table_data, pci_ranges.blob->data, - pci_ranges.blob->len); - g_array_free(pci_ranges.blob, true); + for (i = 0; i < pci_host_ranges->len; i++) { + pci_host_range = &g_array_index(pci_host_ranges, + struct viot_pci_host_range, i); + + build_pci_host_range(table_data, pci_host_range->min_bus, + pci_host_range->max_bus, viommu_off); + } + + g_array_free(pci_host_ranges, true); acpi_table_end(linker, &table); }