Re: [PATCH] dm: add _CPC to guest ACPI when HWP is enabled


Victor Sun
 

Better to have a comment, that the patch has a pre-condition: host CPUID.06H:EAX.[7] can't be hidden by vCPUID of Service VM.

-----Original Message-----
From: acrn-dev@... <acrn-dev@...> On
Behalf Of Zhou, Wu
Sent: Monday, June 6, 2022 9:17 PM
To: acrn-dev@...
Subject: [acrn-dev] [PATCH] dm: add _CPC to guest ACPI when HWP is
enabled

When running WaaG, we need to enable HWP to boost performance in some
scenarios. But when HWP is enabled in BIOS, windows does not turn on HWP
driver automatically just like Linux does. It requires _CPC table in ACPI as well.

The _CPC table contains information about the HWP baseline registers.
Those regs are defined as architectural MSRs, so they should be the same on
different CPU models. Thus we can hard code the _CPC table.

When we turn off HWP in BIOS, windows's HWP driver will still be loaded
based on the _CPC table. This will cause the guest fail to boot.
So here we need read CPUID first, only add _CPC when HWP is enabled.

Tracked-On: #7695
Signed-off-by: Wu Zhou <wu.zhou@...>
---
devicemodel/hw/platform/acpi/acpi_pm.c | 57
++++++++++++++++++++++++++
1 file changed, 57 insertions(+)

diff --git a/devicemodel/hw/platform/acpi/acpi_pm.c
b/devicemodel/hw/platform/acpi/acpi_pm.c
index 5d953717ff..1e1a27b629 100644
--- a/devicemodel/hw/platform/acpi/acpi_pm.c
+++ b/devicemodel/hw/platform/acpi/acpi_pm.c
@@ -316,6 +316,51 @@ static int dsdt_write_pss(struct vmctx *ctx, int
vcpu_id)
return 0;
}

+/* _CPC: Continuous Performance Control
+ * Hard code a V3 CPC table, describing HWP register interface.
+ */
+static void dsdt_write_cpc(void)
+{
+ dsdt_line("");
+ dsdt_line(" Method (_CPC, 0, NotSerialized)");
+ dsdt_line(" {");
+ dsdt_line(" Return (Package (0x17)");
+ dsdt_line(" {");
+ dsdt_line(" 0x17,");
+ dsdt_line(" 0x03,");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x00, 0x0000000000000771, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x08, 0x00000000000000CE, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x10, 0x0000000000000771, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x18, 0x0000000000000771, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x08, 0x0000000000000771, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x10, 0x0000000000000774, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x00, 0x0000000000000774, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x08, 0x0000000000000774, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(SystemMemory, 0x00,
0x00, 0x0000000000000000, , )},");
+ dsdt_line(" ResourceTemplate() {Register(SystemMemory, 0x00,
0x00, 0x0000000000000000, , )},");
+ dsdt_line(" ResourceTemplate() {Register(SystemMemory, 0x00,
0x00, 0x0000000000000000, , )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x40,
0x00, 0x00000000000000E7, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x40,
0x00, 0x00000000000000E8, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x02,
0x01, 0x0000000000000777, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x01,
0x00, 0x0000000000000770, 0x04, )},");
+ dsdt_line(" One,");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x0A,
0x20, 0x0000000000000774, 0x04, )},");
+ dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08,
0x18, 0x0000000000000774, 0x04, )},");
+ dsdt_line(" Zero,");
+ dsdt_line(" Zero,");
+ dsdt_line(" Zero");
+ dsdt_line(" })");
+ dsdt_line(" }");
+}
+
+static bool is_hwp_enabled(void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ do_cpuid(0x6, 0, &eax, &ebx, &ecx, &edx);
+
+ return ((eax & (0x1U << 7)) != 0);
+}
+
void pm_write_dsdt(struct vmctx *ctx, int ncpu) {
int i;
@@ -364,6 +409,18 @@ void pm_write_dsdt(struct vmctx *ctx, int ncpu)
}
}

+ if (is_hwp_enabled()) {
+ if (i == 0) {
+ dsdt_write_cpc();
+ } else {
+ dsdt_line(" Method (_CPC, 0,
NotSerialized)");
+ dsdt_line(" {");
+ dsdt_line(" Return (^^PR00._CPC)");
+ dsdt_line(" }");
+ dsdt_line("");
+ }
+ }
+
dsdt_line(" }");
}
}





Join acrn-dev@lists.projectacrn.org to automatically receive all group messages.