From 4f50ed900713acc14c971c07165fa83670d3f2b8 Mon Sep 17 00:00:00 2001 From: Keqian Zhu Date: Mon, 13 Jan 2020 19:02:20 +0800 Subject: [PATCH] acpi/madt: Factor out the building of MADT GICC struct To realize CPU hotplug, the cpus aml within ACPI DSDT should contain _MAT mathod, which is equal to the GICC struct in ACPI MADT. Factor out the GICC building code from ACPI MADT and reuse it in build_cpus_aml. Signed-off-by: Keqian Zhu Signed-off-by: Salil Mehta --- hw/arm/virt-acpi-build.c | 77 ++++++++++++++++++++++------------------ include/hw/arm/virt.h | 4 +++ 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 1ca705654b..64b1ed8672 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -771,6 +771,48 @@ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size) build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */ } +void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i, + const CPUArchIdList *possible_cpus, GArray *table_data, + bool force_enabled) +{ + VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine()); + const MemMapEntry *memmap = vms->memmap; + ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); + uint64_t physical_base_address = 0, gich = 0, gicv = 0; + uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0; + uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ? + PPI(VIRTUAL_PMU_IRQ) : 0; + + if (vms->gic_version == 2) { + physical_base_address = memmap[VIRT_GIC_CPU].base; + gicv = memmap[VIRT_GIC_VCPU].base; + gich = memmap[VIRT_GIC_HYP].base; + } + + /* 5.2.12.14 GIC Structure */ + build_append_int_noprefix(table_data, 0xB, 1); /* Type */ + build_append_int_noprefix(table_data, 76, 1); /* Length */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + build_append_int_noprefix(table_data, i, 4); /* GIC ID */ + build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ + /* Flags */ + build_append_int_noprefix(table_data, 1, 4); /* Enabled */ + /* Parking Protocol Version */ + build_append_int_noprefix(table_data, 0, 4); + /* Performance Interrupt GSIV */ + build_append_int_noprefix(table_data, pmu_interrupt, 4); + build_append_int_noprefix(table_data, 0, 8); /* Parked Address */ + /* Physical Base Address */ + build_append_int_noprefix(table_data, physical_base_address, 8); + build_append_int_noprefix(table_data, gicv, 8); /* GICV */ + build_append_int_noprefix(table_data, gich, 8); /* GICH */ + /* VGIC Maintenance interrupt */ + build_append_int_noprefix(table_data, vgic_interrupt, 4); + build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/ + /* MPIDR */ + build_append_int_noprefix(table_data, armcpu->mp_affinity, 8); +} + static void build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { @@ -798,40 +840,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) build_append_int_noprefix(table_data, 0, 3); /* Reserved */ for (i = 0; i < MACHINE(vms)->smp.cpus; i++) { - ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); - uint64_t physical_base_address = 0, gich = 0, gicv = 0; - uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0; - uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ? - PPI(VIRTUAL_PMU_IRQ) : 0; - - if (vms->gic_version == 2) { - physical_base_address = memmap[VIRT_GIC_CPU].base; - gicv = memmap[VIRT_GIC_VCPU].base; - gich = memmap[VIRT_GIC_HYP].base; - } - - /* 5.2.12.14 GIC Structure */ - build_append_int_noprefix(table_data, 0xB, 1); /* Type */ - build_append_int_noprefix(table_data, 76, 1); /* Length */ - build_append_int_noprefix(table_data, 0, 2); /* Reserved */ - build_append_int_noprefix(table_data, i, 4); /* GIC ID */ - build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ - /* Flags */ - build_append_int_noprefix(table_data, 1, 4); /* Enabled */ - /* Parking Protocol Version */ - build_append_int_noprefix(table_data, 0, 4); - /* Performance Interrupt GSIV */ - build_append_int_noprefix(table_data, pmu_interrupt, 4); - build_append_int_noprefix(table_data, 0, 8); /* Parked Address */ - /* Physical Base Address */ - build_append_int_noprefix(table_data, physical_base_address, 8); - build_append_int_noprefix(table_data, gicv, 8); /* GICV */ - build_append_int_noprefix(table_data, gich, 8); /* GICH */ - /* VGIC Maintenance interrupt */ - build_append_int_noprefix(table_data, vgic_interrupt, 4); - build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/ - /* MPIDR */ - build_append_int_noprefix(table_data, armcpu->mp_affinity, 8); + virt_madt_cpu_entry(NULL, i, NULL, table_data, false); } if (vms->gic_version == 3) { diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index a4356cf736..36639e8d3e 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -38,6 +38,7 @@ #include "sysemu/kvm.h" #include "hw/intc/arm_gicv3_common.h" #include "qom/object.h" +#include "hw/acpi/acpi_dev_interface.h" #define NUM_GICV2M_SPIS 64 #define NUM_VIRTIO_TRANSPORTS 32 @@ -181,6 +182,9 @@ OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) void virt_acpi_setup(VirtMachineState *vms); bool virt_is_acpi_enabled(VirtMachineState *vms); +void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid, + const CPUArchIdList *cpu_list, GArray *entry, + bool force_enabled); /* Return the number of used redistributor regions */ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms) -- 2.27.0