aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorShannon Zhao <shannon.zhao@linaro.org>2015-11-03 13:49:42 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-11-03 13:49:42 +0000
commitf2fbfacec024d1e78c10fc8498f3126557c21ed8 (patch)
tree898f300ae2ba2361cf845a18e94b565de6ecbf9d /hw
parentbc64b96c984abfe84f43562ca7480bb4f2af0613 (diff)
hw/arm/virt-acpi-build: Add GICC ACPI subtable for GICv3
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> Message-id: 1446131773-5018-1-git-send-email-shannon.zhao@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/virt-acpi-build.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 1430125885..b170dfa3e2 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -449,6 +449,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);
@@ -458,20 +474,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);