129 lines
4.4 KiB
Diff
129 lines
4.4 KiB
Diff
|
|
From c5dfec0bfd78f7e8f84a527a1aa73896f69b2367 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Salil Mehta <salil.mehta@huawei.com>
|
||
|
|
Date: Thu, 10 Aug 2023 01:15:31 +0000
|
||
|
|
Subject: [PATCH] hw/arm: Support hotplug capability check using _OSC method
|
||
|
|
|
||
|
|
Physical CPU hotplug results in (un)setting of ACPI _STA.Present bit. AARCH64
|
||
|
|
platforms do not support physical CPU hotplug. Virtual CPU hotplug support being
|
||
|
|
implemented toggles ACPI _STA.Enabled Bit to achieve hotplug functionality. This
|
||
|
|
is not same as physical CPU hotplug support.
|
||
|
|
|
||
|
|
In future, if ARM architecture supports physical CPU hotplug then the current
|
||
|
|
design of virtual CPU hotplug can be used unchanged. Hence, there is a need for
|
||
|
|
firmware/VMM/Qemu to support evaluation of platform wide capabilitiy related to
|
||
|
|
the *type* of CPU hotplug support present on the platform. OSPM might need this
|
||
|
|
during boot time to correctly initialize the CPUs and other related components
|
||
|
|
in the kernel.
|
||
|
|
|
||
|
|
NOTE: This implementation will be improved to add the support of *query* in the
|
||
|
|
subsequent versions. This is very minimal support to assist kernel.
|
||
|
|
|
||
|
|
ASL for the implemented _OSC method:
|
||
|
|
|
||
|
|
Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
|
||
|
|
{
|
||
|
|
CreateDWordField (Arg3, Zero, CDW1)
|
||
|
|
If ((Arg0 == ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48") /* Platform-wide Capabilities */))
|
||
|
|
{
|
||
|
|
CreateDWordField (Arg3, 0x04, CDW2)
|
||
|
|
Local0 = CDW2 /* \_SB_._OSC.CDW2 */
|
||
|
|
If ((Arg1 != One))
|
||
|
|
{
|
||
|
|
CDW1 |= 0x08
|
||
|
|
}
|
||
|
|
|
||
|
|
Local0 &= 0x00800000
|
||
|
|
If ((CDW2 != Local0))
|
||
|
|
{
|
||
|
|
CDW1 |= 0x10
|
||
|
|
}
|
||
|
|
|
||
|
|
CDW2 = Local0
|
||
|
|
}
|
||
|
|
Else
|
||
|
|
{
|
||
|
|
CDW1 |= 0x04
|
||
|
|
}
|
||
|
|
|
||
|
|
Return (Arg3)
|
||
|
|
}
|
||
|
|
|
||
|
|
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||
|
|
---
|
||
|
|
hw/arm/virt-acpi-build.c | 52 ++++++++++++++++++++++++++++++++++++++++
|
||
|
|
1 file changed, 52 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||
|
|
index 2870c1ec5a..c402e102c4 100644
|
||
|
|
--- a/hw/arm/virt-acpi-build.c
|
||
|
|
+++ b/hw/arm/virt-acpi-build.c
|
||
|
|
@@ -940,6 +940,55 @@ static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
|
||
|
|
build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id);
|
||
|
|
}
|
||
|
|
|
||
|
|
+static void build_virt_osc_method(Aml *scope, VirtMachineState *vms)
|
||
|
|
+{
|
||
|
|
+ Aml *if_uuid, *else_uuid, *if_rev, *if_caps_masked, *method;
|
||
|
|
+ Aml *a_cdw1 = aml_name("CDW1");
|
||
|
|
+ Aml *a_cdw2 = aml_local(0);
|
||
|
|
+
|
||
|
|
+ method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
|
||
|
|
+ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
|
||
|
|
+
|
||
|
|
+ /* match UUID */
|
||
|
|
+ if_uuid = aml_if(aml_equal(
|
||
|
|
+ aml_arg(0), aml_touuid("0811B06E-4A27-44F9-8D60-3CBBC22E7B48")));
|
||
|
|
+
|
||
|
|
+ aml_append(if_uuid, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
|
||
|
|
+ aml_append(if_uuid, aml_store(aml_name("CDW2"), a_cdw2));
|
||
|
|
+
|
||
|
|
+ /* check unknown revision in arg(1) */
|
||
|
|
+ if_rev = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
|
||
|
|
+ /* set revision error bits, DWORD1 Bit[3] */
|
||
|
|
+ aml_append(if_rev, aml_or(a_cdw1, aml_int(0x08), a_cdw1));
|
||
|
|
+ aml_append(if_uuid, if_rev);
|
||
|
|
+
|
||
|
|
+ /*
|
||
|
|
+ * check support for vCPU hotplug type(=enabled) platform-wide capability
|
||
|
|
+ * in DWORD2 as sepcified in the below ACPI Specification ECR,
|
||
|
|
+ * # https://bugzilla.tianocore.org/show_bug.cgi?id=4481
|
||
|
|
+ */
|
||
|
|
+ if (vms->acpi_dev) {
|
||
|
|
+ aml_append(if_uuid, aml_and(a_cdw2, aml_int(0x800000), a_cdw2));
|
||
|
|
+ /* check if OSPM specified hotplug capability bits were masked */
|
||
|
|
+ if_caps_masked = aml_if(aml_lnot(aml_equal(aml_name("CDW2"), a_cdw2)));
|
||
|
|
+ aml_append(if_caps_masked, aml_or(a_cdw1, aml_int(0x10), a_cdw1));
|
||
|
|
+ aml_append(if_uuid, if_caps_masked);
|
||
|
|
+ }
|
||
|
|
+ aml_append(if_uuid, aml_store(a_cdw2, aml_name("CDW2")));
|
||
|
|
+
|
||
|
|
+ aml_append(method, if_uuid);
|
||
|
|
+ else_uuid = aml_else();
|
||
|
|
+
|
||
|
|
+ /* set unrecognized UUID error bits, DWORD1 Bit[2] */
|
||
|
|
+ aml_append(else_uuid, aml_or(a_cdw1, aml_int(4), a_cdw1));
|
||
|
|
+ aml_append(method, else_uuid);
|
||
|
|
+
|
||
|
|
+ aml_append(method, aml_return(aml_arg(3)));
|
||
|
|
+ aml_append(scope, method);
|
||
|
|
+
|
||
|
|
+ return;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/* DSDT */
|
||
|
|
static void
|
||
|
|
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||
|
|
@@ -974,6 +1023,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||
|
|
} else {
|
||
|
|
acpi_dsdt_add_cpus(scope, vms);
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+ build_virt_osc_method(scope, vms);
|
||
|
|
+
|
||
|
|
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
|
||
|
|
(irqmap[VIRT_UART] + ARM_SPI_BASE));
|
||
|
|
if (vmc->acpi_expose_flash) {
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|