diff mbox

hw/arm/virt-acpi-build: Add GICC ACPI subtable for GICv3

Message ID 1446131773-5018-1-git-send-email-shannon.zhao@linaro.org
State Accepted
Commit f2fbfacec024d1e78c10fc8498f3126557c21ed8
Headers show

Commit Message

Shannon Zhao Oct. 29, 2015, 3:16 p.m. UTC
When booting VM with GICv3, the kernel needs GICC ACPI subtable to
initialize the CPUs, e.g. MPIDR information. This adds GICC ACPI
subtable for GICv3, but set GICC base address only when gic_version == 2
since it donesn't need GICC base address for GICv3.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

---
 hw/arm/virt-acpi-build.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

-- 
2.1.0

Comments

Peter Maydell Nov. 3, 2015, 1:31 p.m. UTC | #1
On 29 October 2015 at 15:16, Shannon Zhao <shannon.zhao@linaro.org> wrote:
> When booting VM with GICv3, the kernel needs GICC ACPI subtable to

> initialize the CPUs, e.g. MPIDR information. This adds GICC ACPI

> subtable for GICv3, but set GICC base address only when gic_version == 2

> since it donesn't need GICC base address for GICv3.

>

> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

> ---

>  hw/arm/virt-acpi-build.c | 30 ++++++++++++++++--------------

>  1 file changed, 16 insertions(+), 14 deletions(-)





Applied to target-arm.next, thanks.

-- PMM
diff mbox

Patch

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 1aaff1f..29a1980 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -448,6 +448,22 @@  build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
     gicd->length = sizeof(*gicd);
     gicd->base_address = memmap[VIRT_GIC_DIST].base;
 
+    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);
+        if (guest_info->gic_version == 2) {
+            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);
+        }
+    }
+
     if (guest_info->gic_version == 3) {
         AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
                                                          sizeof *gicr);
@@ -457,20 +473,6 @@  build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
         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);