diff --git a/PowerMonkeyApp/ASMx64/SaferAsm.nasm b/PowerMonkeyApp/ASMx64/SaferAsm.nasm index a0d6254c..c42d7e96 100644 --- a/PowerMonkeyApp/ASMx64/SaferAsm.nasm +++ b/PowerMonkeyApp/ASMx64/SaferAsm.nasm @@ -877,15 +877,19 @@ smo_done: mov r10, rdx mov eax, ecx + xor ecx, ecx + push rax cpuid - mov dword [r10], eax - mov dword [r10+4 ], ebx - mov dword [r10+8 ], ecx - mov dword [r10+12], edx + mov [r10], eax + mov [r10+4 ], ebx + mov [r10+8 ], ecx + mov [r10+12], edx + pop rax pop rbx + ret ;------------------------------------------------------------------------------ @@ -900,18 +904,19 @@ smo_done: global _pm_cpuid_ex _pm_cpuid_ex: - push rbx - + push rbx mov eax, ecx mov ecx, edx + push rax cpuid - mov dword [r8], eax - mov dword [r8+4 ], ebx - mov dword [r8+8 ], ecx - mov dword [r8+12], edx + mov [r8], eax + mov [r8+4 ], ebx + mov [r8+8 ], ecx + mov [r8+12], edx + pop rax pop rbx ret diff --git a/PowerMonkeyApp/CONFIGURATION.c b/PowerMonkeyApp/CONFIGURATION.c index d54049be..04cd4e72 100644 --- a/PowerMonkeyApp/CONFIGURATION.c +++ b/PowerMonkeyApp/CONFIGURATION.c @@ -196,8 +196,9 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) /// NOTE: Legacy V/F overrides >will not apply< if you chose to program /// individual V/F points. - // - // Legacy (will be ignored in vfpoints are used) + /////////////////////////////// + // Legacy (entire VF curve) // + /////////////////////////////// pk->planes[IACORE].VoltMode = pk->planes[RING].VoltMode = V_IPOLATIVE; // V_IPOLATIVE = Interpolate @@ -206,9 +207,8 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) pk->planes[RING].TargetVolts = 0; // in mV (absolute) pk->planes[IACORE].OffsetVolts = - pk->planes[RING].OffsetVolts = -50; // in mV + pk->planes[RING].OffsetVolts = 0;// -50; // in mV // (negative = undervolt) - /// /// V/F OVERRIDES FOR DOMAIN: E-Core (ADL & Co. only) @@ -229,7 +229,7 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) // V_OVERRIDE = Override pk->planes[UNCORE].TargetVolts = 0; // in mV (absolute) - pk->planes[UNCORE].OffsetVolts = -35; // in mV (negative = undervolt) + pk->planes[UNCORE].OffsetVolts = 0;// -35; // in mV (negative = undervolt) // Add your adjustments here if needed @@ -272,15 +272,14 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) /// SVID, then you must program the same voltage adjustment for both pk->Program_VF_Points[IACORE] = // 0 - Do not program - pk->Program_VF_Points[RING] = 0; // 1 - Program + pk->Program_VF_Points[RING] = 1; // 1 - Program // 2 - Print current values // (2 does not program) - // // Hybrid Architectures (Alder Lake +): E-Cores // 1 - Program - pk->Program_VF_Points[ECORE] = 0; // 0 - Do not program + pk->Program_VF_Points[ECORE] = 1; // 0 - Do not program // 2 - Print current values // (2 does not program) @@ -333,6 +332,8 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) /// /// CPU: Alder Lake-S 12900K PRQ /// Autotune script: prime95_ultrashort + /// E-Cores: Disabled + /// AVX-512: Enabled /// /// Crash offsets (in mV) per VF point: /// @@ -340,7 +341,7 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) /// AVX512: N/A -244 -238 -225 -235 -190 -158 N/A /// AVX2 N/A -240 -230 -214 -230 -170 -144 N/A /// SSE N/A -250 -246 -232 -238 -186 -172 N/A - + pk->planes[IACORE].vfPoint[0].VOffset = pk->planes[RING].vfPoint[0].VOffset = 0; // V_Offset @ 800 MHz (mV) @@ -371,7 +372,6 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) pk->planes[IACORE].vfPoint[9].VOffset = pk->planes[RING].vfPoint[9].VOffset = 0; // V_Offset @ 5300 MHz (mV) - ///////////////////////////// // E-Cores - bogus values, // ///////////////////////////// @@ -381,6 +381,8 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) pk->planes[ECORE].vfPoint[2].VOffset = 0; pk->planes[ECORE].vfPoint[3].VOffset = 0; pk->planes[ECORE].vfPoint[4].VOffset = 0; + pk->planes[ECORE].vfPoint[5].VOffset = 0; + pk->planes[ECORE].vfPoint[6].VOffset = 0; #endif @@ -429,20 +431,27 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) // (e.g. 1C, 2C, 4C, 8C, = use this ratio). Remove or set to 0 // if you do not wish to set it - pk->ForcedRatioForAllCoreCounts = 51; + pk->ForcedRatioForPCoreCounts = 51; // Pre ADL-S/H/P: All cores + // ADL_S/H/P and newer: P-Cores + // 0 = "do not change - leave as=is" + - ///////////////////// - /// Power Control /// - ///////////////////// + pk->ForcedRatioForECoreCounts = 0; // Pre ADL-S/H/P: not applicable + // ADL_S and newer: E-Cores + + + //////////////////// + /// Power Tweaks /// + //////////////////// - pk->ProgramPowerControl = 1; // Enable programing of power - // control knobs + pk->ProgramPowerTweaks = 1; // Enable programing of power + // control knobs - pk->EnableEETurbo = 1; // Energy Efficient Turbo - // (0=disable, 1=enable) + pk->EnableEETurbo = 1; // Energy Efficient Turbo + // (0=disable, 1=enable) - pk->EnableRaceToHalt = 1; // Race To Halt - // (0=disable, 1=enable) + pk->EnableRaceToHalt = 1; // Race To Halt + // (0=disable, 1=enable) //////////////////// /// Power Limits /// @@ -530,8 +539,8 @@ VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys) pk->EnableMmioPkgPL1 = 1; // Enable MMIO PL1 pk->EnableMmioPkgPL2 = 1; // Enable MMIO PL2 - pk->MmioPkgPL1_Power = MAX_POWAH; // MMIO PL1 in mW or MAX_POWAH - pk->MmioPkgPL2_Power = MAX_POWAH; // MMIO PL2 in mW or MAX_POWAH + pk->MmioPkgPL1_Power = MAX_POWAH; // MMIO PL1 in mW or MAX_POWAH + pk->MmioPkgPL2_Power = MAX_POWAH; // MMIO PL2 in mW or MAX_POWAH pk->MmioPkgPL_Time = MAX_POWAH; // Tau in ms or MAX_POWAH pk->ClampMmioPkgPL = 1; // Allow clamping pk->LockMmioPkgPL12 = 1; // Lock after programming diff --git a/PowerMonkeyApp/CpuData.c b/PowerMonkeyApp/CpuData.c index 6079620c..7df8ef04 100644 --- a/PowerMonkeyApp/CpuData.c +++ b/PowerMonkeyApp/CpuData.c @@ -31,6 +31,7 @@ #include "CpuData.h" #include "OcMailbox.h" #include "MiniLog.h" +#include "SaferAsmHdr.h" CPUINFO gCpuInfo = { 0 }; @@ -143,13 +144,19 @@ CPUCONFIGTABLE gCpuConfigTable[] = { { {6, 165, 4} , "CometLake", 0, 10, 1, 0, &vcfg_q_xyzlake_client }, { {6, 165, 5} , "CometLake-S", 0, 10, 1, 0, &vcfg_q_xyzlake_client }, { {6, 166, 0} , "CometLake", 0, 10, 1, 0, &vcfg_q_xyzlake_client }, + { {6, 167, 0} , "RocketLake", 0, 10, 1, 0, &vcfg_q_xyzlake_client }, // RKL-S ES { {6, 167, 1} , "RocketLake", 0, 10, 1, 0, &vcfg_q_xyzlake_client }, // RKL-S QS/PRQ - { {6, 151, 2} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S QS/PRQ - { {6, 151, 4} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S - { {6, 151, 5} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S - { {6, 154, 2} , "AlderLake-P", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-P - { {6, 154, 3} , "AlderLake-P", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-P + + { {6, 151, 0} , "AlderLake", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // (90670) + { {6, 151, 1} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S ES2 (90671) + { {6, 151, 2} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S QS/PRQ (90672) + { {6, 151, 4} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S (90674) + { {6, 151, 5} , "AlderLake-S", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-S QS/PRQ (90675) + { {6, 154, 2} , "AlderLake-H/P", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-H/P (906A2) + { {6, 154, 3} , "AlderLake-H/P", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-H/P (906A3) + { {6, 154, 4} , "AlderLake-H/P", 0, 11, 1, 1, &vcfg_q_alderlake_client }, // ADL-H/P (906A4) + { {6, 154, 1} , "AlderLake", 0, 11, 1, 1, &vcfg_q_alderlake_client }, }; @@ -170,6 +177,20 @@ BOOLEAN DetectCpu() GetCpuInfo(&gCpuInfo); + // + // Detect BIOS-limited maximum CPUID input value + // as it would interfere with our ability to detect features + + if (gCpuInfo.maxf <= 2) + { + AsciiPrint("WARNING: possible maximum CPUID input value limitation detected!\n"); + AsciiPrint("This condition can interfere with CPU feature detection.\n"); + AsciiPrint("For ensuring correct operation, it is advisable to disable CPUID limit.\n"); + AsciiPrint("This is typically done in BIOS Setup.\n"); + AsciiPrint("\n"); + } + + // // BCLK diff --git a/PowerMonkeyApp/CpuInfo.c b/PowerMonkeyApp/CpuInfo.c index 8e06c9d4..7d296803 100644 --- a/PowerMonkeyApp/CpuInfo.c +++ b/PowerMonkeyApp/CpuInfo.c @@ -30,6 +30,15 @@ #include "CpuInfo.h" #include "Constants.h" +/******************************************************************************* + * + ******************************************************************************/ + +#define CPUID_EAX 0 +#define CPUID_EBX 1 +#define CPUID_ECX 2 +#define CPUID_EDX 3 + /******************************************************************************* * ******************************************************************************/ @@ -44,7 +53,6 @@ void GetCpuInfo(CPUINFO* ci) { memset(ci, 0, sizeof(CPUINFO)); - ////////////////// // Brand String // ////////////////// @@ -60,63 +68,46 @@ void GetCpuInfo(CPUINFO* ci) // Vendor String // /////////////////// - UINT32 args[4] = {0}; + UINT32 regs[4] = {0}; - _pm_cpuid(0, args); + _pm_cpuid(0, regs); - UINT32 hscall = ci->maxf = args[0]; + UINT32 hscall = ci->maxf = regs[CPUID_EAX]; - brandstr[0] = args[1]; - brandstr[1] = args[3]; - brandstr[2] = args[2]; - - memset(args, 0, sizeof(args)); - - _pm_cpuid(0x01, args); + brandstr[0] = regs[CPUID_EBX]; + brandstr[1] = regs[CPUID_EDX]; + brandstr[2] = regs[CPUID_ECX]; + + _pm_cpuid(0x01, regs); - ci->f1 = args[0]; - ci->stepping = args[0] & 0x0000000F; - ci->family = (UINT32)(args[0] & 0x00000F00) >> 8; - ci->model = (UINT32)(args[0] & 0x000000F0) >> 4; + ci->f1 = regs[CPUID_EAX]; + ci->stepping = regs[CPUID_EAX] & 0x0000000F; + ci->family = (UINT32)(regs[CPUID_EAX] & 0x00000F00) >> 8; + ci->model = (UINT32)(regs[CPUID_EAX] & 0x000000F0) >> 4; if ((ci->family == 0xF) || (ci->family == 0x6)) { - ci->model |= (UINT32)((args[0] & 0x0000F0000) >> 12); - ci->family |= (UINT32)((args[0] & 0x00FF00000) >> 16); + ci->model |= (UINT32)((regs[CPUID_EAX] & 0x0000F0000) >> 12); + ci->family |= (UINT32)((regs[CPUID_EAX] & 0x00FF00000) >> 16); } - /////////////////////////////////// // Hybrid Architecture Detection // /////////////////////////////////// - - memset(args, 0, sizeof(args)); - _pm_cpuid(0x7, args); + _pm_cpuid(0x7, regs); - ci->HybridArch = (args[3] & bit15u32) ? 1 : 0; + ci->ECore = 0; + ci->HybridArch = ((regs[CPUID_EDX] & bit15u32)) ? 1 : 0; if (ci->HybridArch) { + if (hscall >= 0x1A) { + _pm_cpuid(0x1A, regs); - if (hscall >= 0x1A) { - - memset(args, 0, sizeof(args)); - - _pm_cpuid(0x1A, args); - - UINT32 ct = ((args[0] & 0xFF000000) >> 24); + UINT32 ct = ((regs[CPUID_EAX] & 0xFF000000) >> 24); if (ct == 0x20) { ci->ECore = 1; - ci->PCore = 0; - } - else { - ci->ECore = 0; - ci->PCore = 1; - } + } } } - else { - ci->ECore = 0; - ci->PCore = 1; - } } \ No newline at end of file diff --git a/PowerMonkeyApp/CpuInfo.h b/PowerMonkeyApp/CpuInfo.h index 3b78b380..b4d79a3c 100644 --- a/PowerMonkeyApp/CpuInfo.h +++ b/PowerMonkeyApp/CpuInfo.h @@ -41,10 +41,8 @@ typedef struct _CPUINFO UINT32 model; UINT32 stepping; - BOOLEAN HybridArch; - + BOOLEAN HybridArch; BOOLEAN ECore; - BOOLEAN PCore; } CPUINFO; diff --git a/PowerMonkeyApp/DelayX86.c b/PowerMonkeyApp/DelayX86.c index 8f36ddfb..5f83ae89 100644 --- a/PowerMonkeyApp/DelayX86.c +++ b/PowerMonkeyApp/DelayX86.c @@ -31,7 +31,10 @@ #include "CpuInfo.h" #include "CpuData.h" #include "SaferAsmHdr.h" + +#if defined(__clang__) #include +#endif #if defined(__GNUC__) && !defined(__clang__) #include diff --git a/PowerMonkeyApp/LowLevel.c b/PowerMonkeyApp/LowLevel.c index af5e89a5..1307e269 100644 --- a/PowerMonkeyApp/LowLevel.c +++ b/PowerMonkeyApp/LowLevel.c @@ -27,7 +27,10 @@ #include #include #include + +#if defined(__clang__) #include +#endif #include "SaferAsmHdr.h" #include "LowLevel.h" @@ -41,6 +44,16 @@ #pragma warning( disable : 4090 ) #endif +#if defined(__GNUC__) && !defined(__clang__) +#include +#else + +#pragma intrinsic(__rdtsc) // At this point, code will look so +#pragma intrinsic(_mm_pause) // fugly that writing it in pure SMM + // ASM would count as an improvement +#endif + + /******************************************************************************* * Globals ******************************************************************************/ diff --git a/PowerMonkeyApp/MiniLog.c b/PowerMonkeyApp/MiniLog.c index 722f21a7..55bf5e7c 100644 --- a/PowerMonkeyApp/MiniLog.c +++ b/PowerMonkeyApp/MiniLog.c @@ -36,7 +36,10 @@ #include #include #include + +#if defined(__clang__) #include +#endif #include "CONFIGURATION.h" #include "MiniLog.h" diff --git a/PowerMonkeyApp/MpDispatcher.c b/PowerMonkeyApp/MpDispatcher.c index 2e176b24..c0fcd32e 100644 --- a/PowerMonkeyApp/MpDispatcher.c +++ b/PowerMonkeyApp/MpDispatcher.c @@ -88,26 +88,30 @@ VOID EFIAPI ProcessorIgnite(VOID* params) SetCpuGSBase(coreStructAddr); /// - /// Populate CPU-specific info + /// Populate CPU core-specific info /// CPUCORE* core = (CPUCORE*)coreStructAddr; + GetCpuInfo(&core->CpuInfo); + core->IsECore = core->CpuInfo.ECore; - if (core->CpuInfo.HybridArch) { - core->IsECore = core->CpuInfo.ECore; - core->IsPerfCore = core->CpuInfo.PCore; - } - else { - core->IsECore = 0; - core->IsPerfCore = 1; - } + // + // Debug + { + UINTN processorNumber = 0; + gMpServices->WhoAmI(gMpServices, &processorNumber); + core->ValidateIdx = (UINT32)processorNumber; + } - /// - /// Execute user's call - /// + if (pic->userProc) { + + /// + /// Execute user's call (if supplied) + /// - pic->userProc(pic->userParam); + pic->userProc(pic->userParam); + } } diff --git a/PowerMonkeyApp/Platform.c b/PowerMonkeyApp/Platform.c index 50acee03..bd439caa 100644 --- a/PowerMonkeyApp/Platform.c +++ b/PowerMonkeyApp/Platform.c @@ -61,8 +61,8 @@ extern PLATFORM* gPlatform; ******************************************************************************/ UINTN gNumCores = 0; -VOID* CoreIdxMap[MAX_CORES * MAX_PACKAGES] = { 0 }; -UINTN CoreApicIDs[MAX_CORES * MAX_PACKAGES] = { 0 }; +VOID* gCorePtrs[MAX_CORES * MAX_PACKAGES] = { 0 }; +UINTN gCoreApicIDs[MAX_CORES * MAX_PACKAGES] = { 0 }; /******************************************************************************* * ApicIdToCoreNumber @@ -71,7 +71,7 @@ UINTN CoreApicIDs[MAX_CORES * MAX_PACKAGES] = { 0 }; UINTN ApicIdToCoreNumber(const UINTN ApicID) { for (UINTN ccount = 0; ccount < gNumCores; ccount++) { - if (CoreApicIDs[ccount] == ApicID) { + if (gCoreApicIDs[ccount] == ApicID) { return ccount; } } @@ -198,17 +198,13 @@ EFI_STATUS EFIAPI ProbePackage(IN OUT PACKAGE* pkg) { EFI_STATUS status = EFI_SUCCESS; - /////////// - // CPUID // - /////////// - if (pkg->probed != 1) { - - GetCpuInfo(&pkg->CpuInfo); - AsmCpuid(0x01, - &pkg->CpuID, - NULL, NULL, NULL); + /////////// + // CPUID // + /////////// + + GetCpuInfo(&pkg->CpuInfo); ////////////////////////// // Discover VR Topology // @@ -266,19 +262,31 @@ EFI_STATUS EFIAPI ProbePackage(IN OUT PACKAGE* pkg) } /******************************************************************************* - * ProgramPackageOrCore + * ProgramVFOverridesAndOCRatios ******************************************************************************/ -EFI_STATUS EFIAPI ProgramPackageOrCore(IN OUT PACKAGE* pkg) +EFI_STATUS EFIAPI ProgramVFOverridesAndOCRatios() { EFI_STATUS status = EFI_SUCCESS; // - // Force max ratio for all turbo core counts - // (if requested) + // We will locate our core and package using + // per-CPU Local Storage + + CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); + PACKAGE* pkg = (PACKAGE*)core->parent; + + // + // Forced turbo ratios + + if (pkg->ForcedRatioForPCoreCounts) { + IAPERF_ProgramMaxTurboRatios(pkg->ForcedRatioForPCoreCounts); + } - if (pkg->ForcedRatioForAllCoreCounts) { - IAPERF_ProgramMaxTurboRatios(pkg->ForcedRatioForAllCoreCounts); + if (gCpuInfo.HybridArch) { + if (pkg->ForcedRatioForECoreCounts) { + IAPERF_ProgramMaxTurboRatios_ECORE(pkg->ForcedRatioForECoreCounts); + } } // @@ -295,6 +303,24 @@ EFI_STATUS EFIAPI ProgramPackageOrCore(IN OUT PACKAGE* pkg) } } + return status; +} + +/******************************************************************************* + * ProgramPowerLimits + ******************************************************************************/ + +EFI_STATUS EFIAPI ProgramPowerLimits() +{ + EFI_STATUS status = EFI_SUCCESS; + + // + // We will locate our core and package using + // per-CPU Local Storage + + CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); + PACKAGE* pkg = (PACKAGE*)core->parent; + // // Program Config TDP Params // with no lock @@ -368,18 +394,33 @@ EFI_STATUS EFIAPI ProgramPackageOrCore(IN OUT PACKAGE* pkg) } + // + // Power Control + + if (pkg->ProgramPowerTweaks) { + ProgramPowerCtl(pkg->EnableEETurbo, pkg->EnableRaceToHalt); + } + + return status; } /******************************************************************************* - * ProgramPackage_Stage2 + * ProgramPackageLocks_Stage2 * Program package locks in the separate stage, after everything else is done ******************************************************************************/ -EFI_STATUS EFIAPI ProgramPackage_Stage2(IN OUT PACKAGE* pkg) +EFI_STATUS EFIAPI ProgramPackageLocks_Stage2() { EFI_STATUS status = EFI_SUCCESS; + // + // We will locate our core and package using + // per-CPU Local Storage + + CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); + PACKAGE* pkg = (PACKAGE*)core->parent; + // // Power Limits MMIO Lock @@ -391,13 +432,20 @@ EFI_STATUS EFIAPI ProgramPackage_Stage2(IN OUT PACKAGE* pkg) } /******************************************************************************* - * ProgramPackage_Stage1 + * ProgramPowerLimits_Stage2 ******************************************************************************/ -EFI_STATUS EFIAPI ProgramPackage_Stage1(IN OUT PACKAGE* pkg) +EFI_STATUS EFIAPI ProgramPowerLimits_Stage2() { EFI_STATUS status = EFI_SUCCESS; + // + // We will locate our core and package using + // per-CPU Local Storage + + CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); + PACKAGE* pkg = (PACKAGE*)core->parent; + // // MMIO // @@ -454,9 +502,8 @@ EFI_STATUS DetectPackages(IN OUT PLATFORM* psys) UINTN nPackages = 0; UINTN nThreadsTotal = 0; - UINTN nCoresTotal = 0; - UINTN localCoreOrThreadCount = 0; + UINTN localCoreCount = 0; pac->parent = psys; @@ -468,31 +515,62 @@ EFI_STATUS DetectPackages(IN OUT PLATFORM* psys) for (UINTN tidx = 0; tidx < psys->LogicalProcessors; tidx++) { - EFI_PROCESSOR_INFORMATION pi; + EFI_PROCESSOR_INFORMATION pi = {0}; +#if 0 + + // + // Extended topology + + gMpServices->GetProcessorInfo(gMpServices, tidx | CPU_V2_EXTENDED_TOPOLOGY, &pi); + +// UINT32 *ppi_core = &pi.ExtendedInformation.Location2.Core; + UINT32 *ppi_thread = &pi.ExtendedInformation.Location2.Thread; + UINT32 *ppi_package = &pi.ExtendedInformation.Location2.Package; + +#else + + // + // Basic topology + gMpServices->GetProcessorInfo(gMpServices, tidx, &pi); +// UINT32 *ppi_core = &pi.Location.Core; + UINT32 *ppi_thread = &pi.Location.Thread; + UINT32 *ppi_package = &pi.Location.Package; + +#endif + if (prevPackage == 0xFFFFFFFF) - prevPackage = pi.Location.Package; + prevPackage = *ppi_package; - CPUCORE* core = &pac->Core[localCoreOrThreadCount]; + CPUCORE* core = &pac->Core[localCoreCount]; - core->LocalIdx = (UINT8) localCoreOrThreadCount; + core->LocalIdx = (UINT8) localCoreCount; core->ApicID = pi.ProcessorId; core->AbsIdx = tidx; - core->parent = (VOID*)pac; + core->parent = (VOID*) pac; core->PkgIdx = (UINT8) nPackages; - pac->idx = (UINT64)nPackages; + pac->idx = (UINT64) nPackages; - CoreIdxMap[tidx] = (VOID*)&pac->Core[localCoreOrThreadCount]; - CoreApicIDs[tidx] = pac->Core[localCoreOrThreadCount].ApicID; + gCorePtrs[tidx] = (VOID*)&pac->Core[localCoreCount]; + gCoreApicIDs[tidx] = pac->Core[localCoreCount].ApicID; - const BOOLEAN physCore = (pi.Location.Thread == 0) ? 1 : 0; + // + // ALDER LAKE HACK! + // some systems will keep returning pi.location.core as 0, and keep + // increasing thread idx instead + // because of these systems, we need to go back to old ugly hack + + //const BOOLEAN physCore = (*ppi_thread == 0) ? 1 : 0; + + const BOOLEAN physCore = (((*ppi_thread == 0)||((*ppi_thread > 0) && + (*ppi_thread % 2 == 0)))) ? 1 : 0; // will not work for N>2-way SMT pac->LogicalCores += 1; pac->PhysicalCores += (physCore) ? 1 : 0; - pac->Core[localCoreOrThreadCount].IsPhysical = physCore; + pac->Core[localCoreCount].IsPhysical = physCore; if (pac->FirstCoreApicID == 0xFFFFFFFF) { pac->FirstCoreApicID = pi.ProcessorId; @@ -503,22 +581,31 @@ EFI_STATUS DetectPackages(IN OUT PLATFORM* psys) } nThreadsTotal++; - localCoreOrThreadCount++; - nCoresTotal += (pi.Location.Thread == 0) ? 1 : 0; + localCoreCount++; + +#if 0 - //AsciiPrint("[Tidx %u] apic id: %lu, abs idx: %lu, pkg idx: %u\n", tidx, core->ApicID, core->AbsIdx, core->PkgIdx); + AsciiPrint("[Tidx %lu] pi.loc.core: %u, pi.loc.package: %u, pi.loc.thread: %u, physical: %u, abs idx: %lu, pkg idx: %u\n", + tidx, + *ppi_core, + *ppi_package, + *ppi_thread, + (UINT32) core->IsPhysical, + (UINT32) core->AbsIdx, + (UINT32) core->PkgIdx); - if (pi.Location.Package != prevPackage) +#endif + + if (*ppi_package != prevPackage) { // // New package detected pac->parent = (VOID*)psys; - nPackages++; - prevPackage = pi.Location.Package; - localCoreOrThreadCount = 0; + prevPackage = *ppi_package; + localCoreCount = 0; pac++; } } @@ -538,12 +625,15 @@ EFI_STATUS EFIAPI ProbePackages(IN OUT PLATFORM* ppd) EFI_STATUS status = EFI_SUCCESS; // - // Probe each package in its own context + // For each package for (UINTN pidx = 0; pidx < ppd->PkgCnt; pidx++) { PACKAGE* pac = ppd->packages + pidx; + // + // Run on 1st core + status = RunOnPackageOrCore(ppd, pac->FirstCoreNumber, (EFI_AP_PROCEDURE)ProbePackage, pac); if (EFI_ERROR(status)) { @@ -558,6 +648,55 @@ EFI_STATUS EFIAPI ProbePackages(IN OUT PLATFORM* ppd) return status; } +/******************************************************************************* + * ProbeCores + * Probes information from each and every CPU core + ******************************************************************************/ + +EFI_STATUS EFIAPI ProbeCores(IN OUT PLATFORM* ppd) +{ + EFI_STATUS status = EFI_SUCCESS; + + // + // Probe each package in its own context + + for (UINTN pidx = 0; pidx < ppd->PkgCnt; pidx++) + { + PACKAGE* pac = ppd->packages + pidx; + + for (UINTN cidx = 0; cidx < pac->LogicalCores; cidx++) + { + CPUCORE* core = &pac->Core[cidx]; + + /* if (core->IsPhysical) */ { + + // + // Note: we use NULL instead of a real callback, because only data + // being collected per-core is going to be collected by the MP dispatch + // "Ignite" call itself. Once we need more data from each core, there + // will be separate callback to do so + + status = RunOnPackageOrCore(ppd, + core->AbsIdx, + (EFI_AP_PROCEDURE)NULL, + pac + ); + + if (EFI_ERROR(status)) { + Print(L"[ERROR] CPU package %u, status code: 0x%x\n", + pac->FirstCoreNumber, + status); + + return status; + } + } + } + } + + return status; +} + + /******************************************************************************* * DiscoverPlatform ******************************************************************************/ @@ -606,7 +745,22 @@ EFI_STATUS EFIAPI DiscoverPlatform(IN OUT PLATFORM** ppsys) ppd->PkgCnt = 1; // Boot Processor + // + // Identify CPU packages + // and their respective CPU cores + DetectPackages(ppd); + + // + // Collect information specific + // to each CPU core - currently only hybrid architecture CPUs need this + + /*if (gCpuInfo->HybridArch)*/ { // <-- remove when necessary + ProbeCores(ppd); + } + + // + // Probe each detected package and collect info ProbePackages(ppd); @@ -627,20 +781,16 @@ VOID PrintPlatformInfo(IN PLATFORM* psys) * ProgramCoreLocks ******************************************************************************/ -EFI_STATUS EFIAPI ProgramCoreKnobs(PLATFORM* psys) +EFI_STATUS EFIAPI ProgramCoreLocks() { // - // Hack - assuming all packages are the same!!!! + // We will locate our core and package using + // per-CPU Local Storage - PACKAGE* pk = &psys->packages[0]; + CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); + PACKAGE* pk = (PACKAGE*)core->parent; - // - // Power Control - if (pk->ProgramPowerControl) { - ProgramPowerCtl(pk->EnableEETurbo, pk->EnableRaceToHalt); - } - // // PL1/2 Lock (MSR) @@ -713,6 +863,7 @@ StartupPlatformInit( PLATFORM* sys = *Platform; PrintPlatformInfo(sys); + //PrintCoreInfo(); return status; } @@ -734,6 +885,11 @@ EFI_STATUS EFIAPI ApplyPolicy(IN EFI_SYSTEM_TABLE* SystemTable, ApplyComputerOwnersPolicy(sys); + /////////////////// + // VF Overrides // + // and OC ratios // + /////////////////// + // // Strictly speaking, we do not need to program every core // Performing programming once per package would be sufficient (except for @@ -743,31 +899,37 @@ EFI_STATUS EFIAPI ApplyPolicy(IN EFI_SYSTEM_TABLE* SystemTable, // // So we will program every core, for the sake of completeness... - for (UINTN pidx = 0; pidx < sys->PkgCnt; pidx++) - { + for (UINTN pidx = 0; pidx < sys->PkgCnt; pidx++) { + PACKAGE* pk = sys->packages + pidx; - //for (INTN cidx = pk->LogicalCores; cidx >= 0; --cidx) for (UINTN cidx = 0; cidx < pk->LogicalCores; cidx++) { CPUCORE* core = pk->Core + cidx; - RunOnPackageOrCore(sys, core->AbsIdx, (EFI_AP_PROCEDURE)ProgramPackageOrCore, pk); + RunOnPackageOrCore(sys, core->AbsIdx, (EFI_AP_PROCEDURE)ProgramVFOverridesAndOCRatios, NULL); } } - ////////// - // MISC // - ////////// - - // - // Power Limits (MMIO) + ////////////////// + // Power Limits // + ////////////////// for (UINTN pidx = 0; pidx < sys->PkgCnt; pidx++) { PACKAGE* pk = sys->packages + pidx; - RunOnPackageOrCore(sys, pk->FirstCoreNumber, (EFI_AP_PROCEDURE)ProgramPackage_Stage1, pk); + + // + // cTDP, MSR PL1/PL2, ... + + RunOnPackageOrCore(sys, pk->FirstCoreNumber, (EFI_AP_PROCEDURE)ProgramPowerLimits, NULL); + + // + // MMIO, PSys, ... + + RunOnPackageOrCore(sys, pk->FirstCoreNumber, (EFI_AP_PROCEDURE)ProgramPowerLimits_Stage2, NULL); } + ///////////////// // Apply LOCKS // ///////////////// @@ -775,7 +937,7 @@ EFI_STATUS EFIAPI ApplyPolicy(IN EFI_SYSTEM_TABLE* SystemTable, // // MSR Locks - RunOnAllProcessors((EFI_AP_PROCEDURE)ProgramCoreKnobs, FALSE, (void *)sys); + RunOnAllProcessors((EFI_AP_PROCEDURE)ProgramCoreLocks, FALSE, (void *)sys); // // MMIO locks @@ -783,7 +945,7 @@ EFI_STATUS EFIAPI ApplyPolicy(IN EFI_SYSTEM_TABLE* SystemTable, for (UINTN pidx = 0; pidx < sys->PkgCnt; pidx++) { PACKAGE* pk = sys->packages + pidx; - RunOnPackageOrCore(sys, pk->FirstCoreNumber, (EFI_AP_PROCEDURE)ProgramPackage_Stage2, pk); + RunOnPackageOrCore(sys, pk->FirstCoreNumber, (EFI_AP_PROCEDURE)ProgramPackageLocks_Stage2, pk); } //////////////////// @@ -809,6 +971,6 @@ VOID* GetCpuDataBlock() { UINTN processorNumber; gMpServices->WhoAmI(gMpServices, &processorNumber); - VOID* coreStructAddr = CoreIdxMap[processorNumber]; + VOID* coreStructAddr = gCorePtrs[processorNumber]; return coreStructAddr; } diff --git a/PowerMonkeyApp/Platform.h b/PowerMonkeyApp/Platform.h index 1cbd37f8..cb8208f1 100644 --- a/PowerMonkeyApp/Platform.h +++ b/PowerMonkeyApp/Platform.h @@ -48,8 +48,8 @@ ******************************************************************************/ extern UINTN gNumCores; -extern VOID* CoreIdxMap[MAX_CORES * MAX_PACKAGES]; -extern UINTN CoreApicIDs[MAX_CORES * MAX_PACKAGES]; +extern VOID* gCorePtrs[MAX_CORES * MAX_PACKAGES]; +extern UINTN gCoreApicIDs[MAX_CORES * MAX_PACKAGES]; UINTN ApicIdToCoreNumber(const UINTN ApicID); @@ -158,15 +158,16 @@ typedef struct _CPUCORE UINTN AbsIdx; UINT8 LocalIdx; - UINT32 CpuID; - BOOLEAN IsPhysical; - BOOLEAN IsPerfCore; BOOLEAN IsECore; VOID *parent; UINT8 PkgIdx; + // + // Debug + + UINT32 ValidateIdx; } CPUCORE; @@ -194,9 +195,16 @@ typedef struct _PACKAGE UINT64 TurboRatioLimits; // [READ] MSR_TURBO_RATIO_LIMIT - UINT8 ForcedRatioForAllCoreCounts; // [WRITE] If != 0, we will + UINT8 ForcedRatioForPCoreCounts; // [WRITE] If != 0, we will // program this ratio for all - // core-counts + // core-counts. Note: for Alder + // lake and newer: this excludes + // E-Cores, see below. + + UINT8 ForcedRatioForECoreCounts; // Same as above, but for E-cores + // ignored if the CPU is not hyb. + + ////////////////// // Power limits // ////////////////// @@ -221,7 +229,7 @@ typedef struct _PACKAGE // // Power Control - UINT8 ProgramPowerControl; // Enable Programming of PowCtl + UINT8 ProgramPowerTweaks; // Enable Programming of PowCtl UINT8 EnableEETurbo; // Enable Energy Efficient Turbo UINT8 EnableRaceToHalt; // Enable Race To Halt diff --git a/PowerMonkeyApp/PowerMonkey.c b/PowerMonkeyApp/PowerMonkey.c index 3ddc7dd5..6be82297 100644 --- a/PowerMonkeyApp/PowerMonkey.c +++ b/PowerMonkeyApp/PowerMonkey.c @@ -262,7 +262,7 @@ VOID PrintBanner(VOID) " | ____// _ \\ | | | | / _ ) / __)| || || | / _ \\ | _ \\ | | / )/ _ )| | | |\n" " | | | |_| || | | |( (/ / | | | || || || |_| || | | || |< (( (/ / | |_| |\n" " |_| \\___/ \\____| \\____)|_| |_||_||_| \\___/ |_| |_||_| \\_)\\____) \\__ |\n" - " Version 0.2.0 (____/\n" + " Version 0.2.1 (____/\n" ); AsciiPrint( @@ -357,7 +357,6 @@ EFI_STATUS EFIAPI UefiMain( ApplyPolicy(SystemTable, gPlatform); - /// /// Self test /// diff --git a/PowerMonkeyApp/PrintStats.c b/PowerMonkeyApp/PrintStats.c index 6b50325e..4f21ffc2 100644 --- a/PowerMonkeyApp/PrintStats.c +++ b/PowerMonkeyApp/PrintStats.c @@ -78,6 +78,30 @@ UINT16 voltModeColStr[2][11] = { {L" Override "}, }; +/******************************************************************************* + * PrintCoreInfo + ******************************************************************************/ + +VOID PrintCoreInfo() +{ + for (UINTN cidx = 0; cidx < gNumCores; cidx++) + { + CPUCORE* core = (CPUCORE*) gCorePtrs[cidx]; + + AsciiPrint("Core %u, apic id: %u, physical: %u, hyb arch: %u, E-core: %u, pkg idx: %u, v: %u\n", + cidx, + core->ApicID, + core->IsPhysical, + core->CpuInfo.HybridArch, + core->IsECore, + core->PkgIdx, + core->ValidateIdx + ); + } + + AsciiPrint("\n"); +} + /******************************************************************************* * PrintVFPoints ******************************************************************************/ @@ -131,7 +155,7 @@ VOID PrintPlatformSettings(IN PLATFORM* psys) PACKAGE* pac = psys->packages + pidx; Print( - L"+---------------------------------------------------------------------+\n" + L"+---------------------------------------------------+\n" ); Print(L"| Package %u | ", pidx); @@ -141,9 +165,9 @@ VOID PrintPlatformSettings(IN PLATFORM* psys) Print( - L"+-----------+------+------+--------+----------+-----------+----------+\n" - L"| Vt Domain | VR | SVID | IccMax | VoltMode | Vtarget | Voffset |\n" - L"|-----------|------|------|--------|----------|-----------|----------|\n" + L"+-----------+-----------+-------+--------+----------+\n" + L"| Vt Domain | VR Addr | SVID? | IccMax | VoltMode |\n" + L"|-----------|-----------|-------|--------|----------|\n" ); for (UINTN didx = 0; didx < MAX_DOMAINS; didx++) { @@ -153,8 +177,8 @@ VOID PrintPlatformSettings(IN PLATFORM* psys) if (dom->VRaddr != INVALID_VR_ADDR) { Print( (dom->OffsetVolts < 0) ? - L"|%s| 0x%02x |%s| %03u A |%s| %04u mV | %04d mV |\n" : - L"|%s| 0x%02x |%s| %03u A |%s| %04u mV | %03d mV |\n", + L"|%s| 0x%02x | %s| %03u A |%s|\n" : + L"|%s| 0x%02x | %s| %03u A |%s|\n", vrDomainColStr[didx & 0x7], @@ -163,17 +187,14 @@ VOID PrintPlatformSettings(IN PLATFORM* psys) &svidColStr[dom->VRtype & 0x1][0], (dom->IccMax) ? dom->IccMax >> 2 : 0, - &voltModeColStr[dom->VoltMode & 0x1][0], - - (UINT32)dom->TargetVolts, - (INT32)dom->OffsetVolts + &voltModeColStr[dom->VoltMode & 0x1][0] ); } } } Print( - L"+-----------+------+------+--------+----------+-----------+----------+\n" + L"+-----------+-----------+-------+--------+----------+\n" L"\n"); } } diff --git a/PowerMonkeyApp/PrintStats.h b/PowerMonkeyApp/PrintStats.h index 3b594fab..8b081a99 100644 --- a/PowerMonkeyApp/PrintStats.h +++ b/PowerMonkeyApp/PrintStats.h @@ -37,3 +37,9 @@ VOID PrintVFPoints(IN PLATFORM* psys); ******************************************************************************/ VOID PrintPlatformSettings(IN PLATFORM* psys); + +/******************************************************************************* + * PrintCoreInfo + ******************************************************************************/ + +VOID PrintCoreInfo(); \ No newline at end of file diff --git a/PowerMonkeyApp/SaferAsmHdr.h b/PowerMonkeyApp/SaferAsmHdr.h index f24a72d2..e523cdda 100644 --- a/PowerMonkeyApp/SaferAsmHdr.h +++ b/PowerMonkeyApp/SaferAsmHdr.h @@ -87,8 +87,8 @@ VOID EFIAPI get_current_idtr(VOID* pidtr); // // CPUID -VOID EFIAPI _pm_cpuid(const UINT32 func, UINT32 *regs); -VOID EFIAPI _pm_cpuid_ex(const UINT32 func, const UINT32 subfunc, UINT32 *regs); +UINT32 EFIAPI _pm_cpuid(UINT32 func, UINT32 *regs); +UINT32 EFIAPI _pm_cpuid_ex(UINT32 func, UINT32 subfunc, UINT32 *regs); UINT32 EFIAPI get_pciex_base_addr(VOID); diff --git a/PowerMonkeyApp/TurboRatioLimits.c b/PowerMonkeyApp/TurboRatioLimits.c index 46764736..ad1a27bb 100644 --- a/PowerMonkeyApp/TurboRatioLimits.c +++ b/PowerMonkeyApp/TurboRatioLimits.c @@ -77,6 +77,16 @@ UINT64 GetTurboRatioLimits(VOID) return pm_rdmsr64(MSR_TURBO_RATIO_LIMIT); } +/******************************************************************************* + * GetTurboRatioLimits_ECORE + ******************************************************************************/ + +UINT64 GetTurboRatioLimits_ECORE(VOID) +{ + return pm_rdmsr64(MSR_TURBO_RATIO_LIMIT_ECORE); +} + + /******************************************************************************* * SetTurboRatioLimits ******************************************************************************/ @@ -96,6 +106,26 @@ EFI_STATUS SetTurboRatioLimits(const UINT64 val) return EFI_SUCCESS; } +/******************************************************************************* + * SetTurboRatioLimits_ECORE + ******************************************************************************/ + +EFI_STATUS SetTurboRatioLimits_ECORE(const UINT64 val) +{ + pm_wrmsr64(MSR_TURBO_RATIO_LIMIT_ECORE, val); + + MicroStall(10); + + UINT64 msr = pm_rdmsr64(MSR_TURBO_RATIO_LIMIT_ECORE); + + if (msr != val) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + + /******************************************************************************* * ProgramMaxTurboRatios ******************************************************************************/ @@ -120,4 +150,31 @@ EFI_STATUS IAPERF_ProgramMaxTurboRatios(const UINT8 maxRatio) MiniTraceEx("Setting all-core max turbo ratio to: %ux", maxRatio); return SetTurboRatioLimits(msr); +} + + +/******************************************************************************* + * ProgramMaxTurboRatios_ECORE + ******************************************************************************/ + +EFI_STATUS IAPERF_ProgramMaxTurboRatios_ECORE(const UINT8 maxRatio) +{ + UINT64 msr = GetTurboRatioLimits_ECORE(); + UINT8* msr8 = (UINT8*)&msr; + + // + // Adjust max ratios for seemingly valid blocks + + for (UINT8 blkidx = 0; blkidx < 8; blkidx++) { + if ((msr8[blkidx]) && (msr8[blkidx] != 0xFF)) { + msr8[blkidx] = maxRatio; + } + } + + // + // Program the new values + + MiniTraceEx("Setting all-core max ECORE turbo ratio to: %ux", maxRatio); + + return SetTurboRatioLimits_ECORE(msr); } \ No newline at end of file diff --git a/PowerMonkeyApp/TurboRatioLimits.h b/PowerMonkeyApp/TurboRatioLimits.h index 46411271..992597a3 100644 --- a/PowerMonkeyApp/TurboRatioLimits.h +++ b/PowerMonkeyApp/TurboRatioLimits.h @@ -31,15 +31,18 @@ ******************************************************************************/ UINT64 GetTurboRatioLimits(VOID); +UINT64 GetTurboRatioLimits_ECORE(VOID); /******************************************************************************* * SetTurboRatioLimits ******************************************************************************/ EFI_STATUS SetTurboRatioLimits(const UINT64 val); +EFI_STATUS SetTurboRatioLimits_ECORE(const UINT64 val); /******************************************************************************* * ProgramMaxTurboRatios ******************************************************************************/ -EFI_STATUS IAPERF_ProgramMaxTurboRatios(const UINT8 maxRatio); \ No newline at end of file +EFI_STATUS IAPERF_ProgramMaxTurboRatios(const UINT8 maxRatio); +EFI_STATUS IAPERF_ProgramMaxTurboRatios_ECORE(const UINT8 maxRatio); \ No newline at end of file diff --git a/PowerMonkeyApp/VFTuning.c b/PowerMonkeyApp/VFTuning.c index c3cfdcd1..700e03cf 100644 --- a/PowerMonkeyApp/VFTuning.c +++ b/PowerMonkeyApp/VFTuning.c @@ -65,14 +65,15 @@ EFI_STATUS EFIAPI IAPERF_ProbeDomainVF(IN const UINT8 domIdx, OUT DOMAIN* dom) // // Alderlake: if we are running on E-Core, skip other domains + +// CPUCORE *core = (CPUCORE *)GetCpuDataBlock(); - CPUCORE *core = (CPUCORE *)GetCpuDataBlock(); - - if (core->CpuInfo.HybridArch && core->IsECore) { - if (domIdx != ECORE) { - return status; - } - } +// +// if (core->IsECore) { +// if (domIdx != ECORE) { +// return EFI_SUCCESS; +// } +// } OcMailbox_InitializeAsMSR(&box); @@ -162,17 +163,13 @@ EFI_STATUS EFIAPI IAPERF_ProbeDomainVF(IN const UINT8 domIdx, OUT DOMAIN* dom) vp->VOffset = cvrt_offsetvolts_fxto_i16(voltOffsetFx); vp->IsValid = 1; - dom->nVfPoints++; - } - - if (box.status == 0) { - VF_POINT* vp = &dom->vfPoint[dom->nVfPoints - 1]; - MiniTraceEx("VF Pt. found, #%u, mult: %ux, voffset: %d mV, dom: 0x%x", dom->nVfPoints, vp->FusedRatio, vp->VOffset, domIdx); + + dom->nVfPoints++; } pidx++; @@ -199,13 +196,12 @@ EFI_STATUS EFIAPI IAPERF_ProgramDomainVF( IN const UINT8 domIdx, // // Alderlake: if we are running on E-Core, skip other domains - CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); - - if (core->CpuInfo.HybridArch && core->IsECore) { - if (domIdx != ECORE) { - return EFI_SUCCESS; - } - } +// CPUCORE* core = (CPUCORE*)GetCpuDataBlock(); +// if (core->CpuInfo.HybridArch && core->IsECore) { +// if (domIdx != ECORE) { +// return EFI_SUCCESS; +// } +// } // // Use OC Mailbox MSR @@ -263,7 +259,8 @@ EFI_STATUS EFIAPI IAPERF_ProgramDomainVF( IN const UINT8 domIdx, // Do not perform legacy programming // if user has chosen to program individual VF points - if ((programVfPoints == 0) || (!gActiveCpuData->VfPointsExposed)) { + //if ((programVfPoints == 0) || (!gActiveCpuData->VfPointsExposed)) + { // // Convert the desired voltages in OC Mailbox format @@ -278,9 +275,11 @@ EFI_STATUS EFIAPI IAPERF_ProgramDomainVF( IN const UINT8 domIdx, // Compose the command for the OC mailbox data = dom->MaxRatio; - data |= ((UINT32)(targetVoltsFx)) << 8; - data |= ((UINT32)(dom->VoltMode & bit1u8)) << 20; data |= (offsetVoltsFx) << 21; + data |= ((UINT32)(dom->VoltMode & bit1u8)) << 20; + data |= ((UINT32)(targetVoltsFx)) << 8; + + cmd = OcMailbox_BuildInterface(0x11, domIdx, 0x0); MiniTraceEx("Dom: 0x%x programming: max %ux, vmode: %u, voff: %d, vtgt: %u", domIdx, @@ -289,11 +288,6 @@ EFI_STATUS EFIAPI IAPERF_ProgramDomainVF( IN const UINT8 domIdx, dom->OffsetVolts, dom->TargetVolts); - cmd = OcMailbox_BuildInterface(0x11, domIdx, 0x0); - - // - // Send our VF override request to the OC Mailbox - if (EFI_ERROR(OcMailbox_ReadWrite(cmd, data, &box))) { // @@ -302,8 +296,7 @@ EFI_STATUS EFIAPI IAPERF_ProgramDomainVF( IN const UINT8 domIdx, return EFI_ABORTED; } - } - + } /////////////// // VF Points // diff --git a/PowerMonkeyApp/VFTuning.h b/PowerMonkeyApp/VFTuning.h index 283cb5ca..5cc32d41 100644 --- a/PowerMonkeyApp/VFTuning.h +++ b/PowerMonkeyApp/VFTuning.h @@ -35,6 +35,7 @@ #define MSR_OC_MAILBOX 0x150 #define MSR_FLEX_RATIO 0x194 #define MSR_TURBO_RATIO_LIMIT 0x1AD +#define MSR_TURBO_RATIO_LIMIT_ECORE 0x650 #define MSR_POWER_CONTROL 0x1FC #define MSR_VR_CURRENT_CONFIG 0x601 #define MSR_PACKAGE_POWER_SKU_UNIT 0x606