diff --git a/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp b/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp index 7f9b67e..96c0838 100644 --- a/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp +++ b/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp @@ -145,7 +145,7 @@ void AMDRyzenCPUPowerManagement::startWorkLoop() { //Read PStateDef generated by EFI. if(pmRyzen_cpu_is_master(cpu_num)) - provider->dumpPstate(); + provider->dumpPstate(nullptr); if(!pmRyzen_cpu_primary_in_core(cpu_num)) return; @@ -390,12 +390,17 @@ IOReturn AMDRyzenCPUPowerManagement::setPowerState(unsigned long powerStateOrdin if (0 == powerStateOrdinal) { // Going to sleep IOLog("AMDCPUSupport::setPowerState preparing for sleep\n"); - wentToSleep = true; + sleepState.sleep = true; + sleepState.cpb = getCPBState(); + dumpPstate(sleepState.pstate); + stopWorkLoop(); - } else if (1 == powerStateOrdinal && wentToSleep) { + } else if (1 == powerStateOrdinal && sleepState.sleep) { // Waking up IOLog("AMDCPUSupport::setPowerState preparing for wakeup\n"); - wentToSleep = false; + sleepState.sleep = false; + setCPBState(sleepState.cpb); + writePstate(sleepState.pstate); startWorkLoop(); } @@ -633,9 +638,8 @@ void AMDRyzenCPUPowerManagement::updatePackageEnergy(){ pwrLastTSC = rdtsc64(); } -void AMDRyzenCPUPowerManagement::dumpPstate(){ +void AMDRyzenCPUPowerManagement::dumpPstate(uint64_t buf[8]){ - uint8_t len = 0; for (uint32_t i = 0; i < kMSR_PSTATE_LEN; i++) { uint64_t msr_value_buf = 0; bool err = !read_msr(kMSR_PSTATE_0 + i, &msr_value_buf); @@ -654,17 +658,12 @@ void AMDRyzenCPUPowerManagement::dumpPstate(){ PStateDef_perCore[i] = msr_value_buf; PStateDefClock_perCore[i] = clock; - if(msr_value_buf & ((uint64_t)1 << 63)) len++; - // IOLog("a: %llu", msr_value_buf); - } - - PStateEnabledLen = max(PStateEnabledLen, len); + if(buf != nullptr) buf[i] = msr_value_buf; + }; } void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){ - PStateEnabledLen = 0; - //A bit hacky but at least works for now. void* args[] = {this, (void*)buf}; @@ -687,7 +686,7 @@ void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){ if(!pmRyzen_cpu_is_master(cpu_number())) return; - provider->dumpPstate(); + provider->dumpPstate(nullptr); }, nullptr, args); diff --git a/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp b/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp index 109319f..29d7ad9 100644 --- a/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp +++ b/AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp @@ -78,6 +78,12 @@ typedef struct tctl_offset { int offset; } TempOffset; +typedef struct sleep_state { + bool sleep; + bool cpb; + uint64_t pstate[8]; +} SleepState; + static IOPMPowerState powerStates[kNrOfPowerStates] = { {1, kIOPMPowerOff, kIOPMPowerOff, kIOPMPowerOff, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -159,7 +165,7 @@ class AMDRyzenCPUPowerManagement : public IOService { void registerRequest(); - void dumpPstate(); + void dumpPstate(uint64_t buf[8]); void writePstate(const uint64_t *buf); bool initSuperIO(uint16_t* chipIntel); @@ -209,7 +215,6 @@ class AMDRyzenCPUPowerManagement : public IOService { uint8_t PStateCur_perCore[CPUInfo::MaxCpus]; uint8_t PStateCtl = 0; uint64_t PStateDef_perCore[8]; - uint8_t PStateEnabledLen = 0; float PStateDefClock_perCore[8]; bool cpbSupported; @@ -260,7 +265,8 @@ class AMDRyzenCPUPowerManagement : public IOService { KernelPatcher *liluKernelPatcher; bool getPCIService(); - bool wentToSleep; + + SleepState sleepState; void startWorkLoop(); void stopWorkLoop();