hw/loongarch/virt: Update the ACPI table for hotplug cpu

On LoongArch virt machine, ACPI GED hardware is used for CPU hotplug
handler, here CPU hotplug support feature is added based on GED handler,
also CPU scan and reject method is added about CPU device in DSDT table.

Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
This commit is contained in:
Bibo Mao 2025-02-10 16:47:00 +08:00
parent ab9935d299
commit 25cdac981f
4 changed files with 44 additions and 3 deletions

View file

@ -47,6 +47,22 @@
#define ACPI_BUILD_DPRINTF(fmt, ...)
#endif
static void virt_madt_cpu_entry(int uid,
const CPUArchIdList *apic_ids,
GArray *entry, bool force_enabled)
{
uint32_t flags, apic_id = apic_ids->cpus[uid].arch_id;
flags = apic_ids->cpus[uid].cpu || force_enabled ? 1 /* Enabled */ : 0;
/* Rev 1.0b, Table 5-13 Processor Local APIC Structure */
build_append_int_noprefix(entry, 0, 1); /* Type */
build_append_int_noprefix(entry, 8, 1); /* Length */
build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */
build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */
build_append_int_noprefix(entry, flags, 4); /* Flags */
}
/* build FADT */
static void init_common_fadt_data(AcpiFadtData *data)
{
@ -112,7 +128,7 @@ build_madt(GArray *table_data, BIOSLinker *linker,
MachineState *ms = MACHINE(lvms);
MachineClass *mc = MACHINE_GET_CLASS(ms);
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
int i, arch_id;
int i, arch_id, flags;
AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lvms->oem_id,
.oem_table_id = lvms->oem_table_id };
@ -125,13 +141,13 @@ build_madt(GArray *table_data, BIOSLinker *linker,
for (i = 0; i < arch_ids->len; i++) {
/* Processor Core Interrupt Controller Structure */
arch_id = arch_ids->cpus[i].arch_id;
flags = arch_ids->cpus[i].cpu ? 1 : 0;
build_append_int_noprefix(table_data, 17, 1); /* Type */
build_append_int_noprefix(table_data, 15, 1); /* Length */
build_append_int_noprefix(table_data, 1, 1); /* Version */
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor ID */
build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */
build_append_int_noprefix(table_data, 1, 4); /* Flags */
build_append_int_noprefix(table_data, flags, 4); /* Flags */
}
/* Extend I/O Interrupt Controller Structure */
@ -338,6 +354,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
{
uint32_t event;
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
CPUHotplugFeatures opts;
build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
HOTPLUG_HANDLER(lvms->acpi_ged),
@ -350,6 +367,18 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
AML_SYSTEM_MEMORY,
VIRT_GED_MEM_ADDR);
}
if (event & ACPI_GED_CPU_HOTPLUG_EVT) {
opts.acpi_1_compatible = false;
opts.has_legacy_cphp = false;
opts.fw_unplugs_cpu = false;
opts.smi_path = NULL;
build_cpus_aml(dsdt, machine, opts, virt_madt_cpu_entry,
VIRT_GED_CPUHP_ADDR, "\\_SB",
AML_GED_EVT_CPU_SCAN_METHOD, AML_SYSTEM_MEMORY);
}
acpi_dsdt_add_power_button(dsdt);
}