On Mon, Jun 06, 2022 at 01:16:50PM +0000, Zhou, Wu wrote: 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, )},"); Please add comments to explain the detailed fields of each MSR like like IA32_HWP_CAP(771H), MSR_PLATFORM_INFO, IA32_MPERF, etc. + 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); Please define macros for 0x6, and (0x1U << 7) It is hard to understand w/o checking spec. +} + 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(""); + } + } Let's print a log by pr_info to shows the HWP is enabled or disabled. + dsdt_line(" }"); } }
|