summary refs log tree commit diff stats
path: root/hw/arm/virt-acpi-build.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/virt-acpi-build.c')
-rw-r--r--hw/arm/virt-acpi-build.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 9088248c3a..1aaff1f662 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -114,7 +114,7 @@ static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
     Aml *dev, *crs;
     hwaddr base = flash_memmap->base;
-    hwaddr size = flash_memmap->size;
+    hwaddr size = flash_memmap->size / 2;
 
     dev = aml_device("FLS0");
     aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
@@ -443,33 +443,43 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
 
     madt = acpi_data_push(table_data, sizeof *madt);
 
-    for (i = 0; i < guest_info->smp_cpus; i++) {
-        AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
-                                                     sizeof *gicc);
-        gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
-        gicc->length = sizeof(*gicc);
-        gicc->base_address = memmap[VIRT_GIC_CPU].base;
-        gicc->cpu_interface_number = i;
-        gicc->arm_mpidr = i;
-        gicc->uid = i;
-        if (test_bit(i, cpuinfo->found_cpus)) {
-            gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
-        }
-    }
-
     gicd = acpi_data_push(table_data, sizeof *gicd);
     gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
     gicd->length = sizeof(*gicd);
     gicd->base_address = memmap[VIRT_GIC_DIST].base;
 
-    gic_msi = acpi_data_push(table_data, sizeof *gic_msi);
-    gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;
-    gic_msi->length = sizeof(*gic_msi);
-    gic_msi->gic_msi_frame_id = 0;
-    gic_msi->base_address = cpu_to_le64(memmap[VIRT_GIC_V2M].base);
-    gic_msi->flags = cpu_to_le32(1);
-    gic_msi->spi_count = cpu_to_le16(NUM_GICV2M_SPIS);
-    gic_msi->spi_base = cpu_to_le16(irqmap[VIRT_GIC_V2M] + ARM_SPI_BASE);
+    if (guest_info->gic_version == 3) {
+        AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
+                                                         sizeof *gicr);
+
+        gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
+        gicr->length = sizeof(*gicr);
+        gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
+        gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
+    } else {
+        for (i = 0; i < guest_info->smp_cpus; i++) {
+            AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
+                                                         sizeof *gicc);
+            gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
+            gicc->length = sizeof(*gicc);
+            gicc->base_address = memmap[VIRT_GIC_CPU].base;
+            gicc->cpu_interface_number = i;
+            gicc->arm_mpidr = i;
+            gicc->uid = i;
+            if (test_bit(i, cpuinfo->found_cpus)) {
+                gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
+            }
+        }
+
+        gic_msi = acpi_data_push(table_data, sizeof *gic_msi);
+        gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;
+        gic_msi->length = sizeof(*gic_msi);
+        gic_msi->gic_msi_frame_id = 0;
+        gic_msi->base_address = cpu_to_le64(memmap[VIRT_GIC_V2M].base);
+        gic_msi->flags = cpu_to_le32(1);
+        gic_msi->spi_count = cpu_to_le16(NUM_GICV2M_SPIS);
+        gic_msi->spi_base = cpu_to_le16(irqmap[VIRT_GIC_V2M] + ARM_SPI_BASE);
+    }
 
     build_header(linker, table_data,
                  (void *)(table_data->data + madt_start), "APIC",