Skip to content

Commit c136a19

Browse files
committed
r0.6
1 parent 358df55 commit c136a19

File tree

11 files changed

+193
-83
lines changed

11 files changed

+193
-83
lines changed

AMD Power Gadget/Base.lproj/Main.storyboard

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,14 +1025,11 @@
10251025
</connections>
10261026
</button>
10271027
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="arp-oH-qjj">
1028-
<rect key="frame" x="24" y="43" width="520" height="192"/>
1028+
<rect key="frame" x="24" y="153" width="520" height="84"/>
10291029
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
10301030
<textFieldCell key="cell" allowsUndo="NO" alignment="left" id="AIb-f9-EZB">
10311031
<font key="font" size="12" name="HelveticaNeue"/>
1032-
<string key="title">When enabled, your processor speed will be adjusted automatically based on a demand value calculated by AMDRyzenCPUPowerManagement. Switching down processor speed will lower its enegry consumption and reduce noise generated by cooling devices.
1033-

This options serves as a temporary solution to CPU power management due to no active solution are currently available. Comparing to a true active power managment implementation, this option works in a passive way which results in less sensitivity, accuracy and a slow down in performance. For safety reason, this options is disabled after every reboot and need to be enabled manually from this appliation. You don't need to keep this application open for PM to work.
1034-
1035-
A better solution is still in development.</string>
1032+
<mutableString key="title">When enabled, your processor speed will increase automatically on demand, and decrease after a short period of low activity. Lower amount of enegry will be consumed when processor running at a lower speed; SMCAMDProcessor will always optimze how your processor idle to save enegry.
This option is enabled by default since release version 0.6.</mutableString>
10361033
<color key="textColor" red="1" green="1" blue="1" alpha="0.54901960780000003" colorSpace="custom" customColorSpace="sRGB"/>
10371034
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
10381035
</textFieldCell>
@@ -1049,6 +1046,26 @@ A better solution is still in development.</string>
10491046
<segue destination="arI-oH-4xY" kind="sheet" id="PaB-YQ-pfi"/>
10501047
</connections>
10511048
</button>
1049+
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LSo-sk-viM">
1050+
<rect key="frame" x="24" y="129" width="167" height="18"/>
1051+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
1052+
<buttonCell key="cell" type="check" title="Enable Low Power State" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="zPp-Te-Sg9">
1053+
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
1054+
<font key="font" metaFont="system"/>
1055+
</buttonCell>
1056+
<connections>
1057+
<action selector="onLPM:" target="rDh-aT-nig" id="bR7-Os-YPD"/>
1058+
</connections>
1059+
</button>
1060+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B1h-CU-8OF">
1061+
<rect key="frame" x="24" y="100" width="520" height="28"/>
1062+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
1063+
<textFieldCell key="cell" allowsUndo="NO" alignment="left" title="Allow automatically shifting down to a low power state that may introduce performance issue." id="uqh-lv-7ht">
1064+
<font key="font" size="12" name="HelveticaNeue"/>
1065+
<color key="textColor" red="1" green="1" blue="1" alpha="0.54901960780000003" colorSpace="custom" customColorSpace="sRGB"/>
1066+
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
1067+
</textFieldCell>
1068+
</textField>
10521069
</subviews>
10531070
</view>
10541071
</tabViewItem>
@@ -1136,6 +1153,7 @@ A better solution is still in development.</string>
11361153
<outlet property="cpbEnabledBox" destination="hck-n7-ZB8" id="9Wm-qW-Otj"/>
11371154
<outlet property="cpbSupportedBox" destination="XVJ-1V-MPd" id="GbR-et-p38"/>
11381155
<outlet property="cpuFreqGraph" destination="5PL-lX-mWT" id="va5-5g-BLH"/>
1156+
<outlet property="lpmBox" destination="LSo-sk-viM" id="Ru9-2s-WAS"/>
11391157
<outlet property="overviewSpeedShift" destination="LRK-w5-6Kx" id="sBA-SR-DsA"/>
11401158
<outlet property="topLabel1" destination="VGI-us-87W" id="OQ9-dq-3xk"/>
11411159
<outlet property="topLabel2" destination="f05-q5-Exd" id="QDN-jE-Rag"/>

AMD Power Gadget/Power Tool/CPUSpeedShiftView.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ class CPUSpeedShiftView: NSControl {
8383
drawGrid(in: dirtyRect, ctx: context)
8484
}
8585

86-
func setOptions(newOptions : [String], selection : Int){
87-
options = newOptions
86+
func setOptions(newOptions : [String]?, selection : Int){
87+
if newOptions != nil{
88+
options = newOptions!
89+
}
8890
selectedItem = selection
8991
setNeedsDisplay(bounds)
9092
}

AMD Power Gadget/Power Tool/PowerToolViewController.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,17 @@ class PowerToolViewController: NSViewController, NSWindowDelegate {
5757
@IBOutlet weak var asaBox: NSButton!
5858
@IBAction func onASA(_ sender: Any) {
5959
ProcessorModel.shared.setPPM(enabled: asaBox.state == .on)
60+
61+
overviewSpeedShift.setOptions(newOptions: nil, selection: asaBox.state == .on ? -1 : 0)
62+
6063
updateASA()
6164
}
6265

66+
@IBOutlet weak var lpmBox: NSButton!
67+
@IBAction func onLPM(_ sender: Any) {
68+
ProcessorModel.shared.setLPM(enabled: lpmBox.state == .on)
69+
updateLPM()
70+
}
6371

6472
@IBOutlet weak var topLabel1: NSTextField!
6573
@IBOutlet weak var topLabel2: NSTextField!
@@ -131,6 +139,7 @@ class PowerToolViewController: NSViewController, NSWindowDelegate {
131139
instDelta += a.reduce(0, +)
132140

133141
if sumCount >= Int(1 / updateTime) {
142+
134143
topLabel1.stringValue = String(format: "%.1f Ghz", freqMax * 0.001)
135144
topLabel2.stringValue = suffixNumber(number: NSNumber(value: instDelta))
136145

@@ -144,7 +153,9 @@ class PowerToolViewController: NSViewController, NSWindowDelegate {
144153
}
145154

146155
@IBAction func onOverviewSpeedStep(_ sender: Any) {
156+
ProcessorModel.shared.setPPM(enabled: false)
147157
ProcessorModel.shared.setPState(state: overviewSpeedShift.selectedItem)
158+
updateASA()
148159
}
149160

150161
func setupOverview() {
@@ -171,7 +182,7 @@ class PowerToolViewController: NSViewController, NSWindowDelegate {
171182
macOS Version: \(ProcessorModel.shared.systemConfig["os"]!)
172183
AMDRyzenCPUPowerManagement:
173184
Version: \(ProcessorModel.shared.AMDRyzenCPUPowerManagementVersion), CPU Supported: \(supported)
174-
185+
175186
"""
176187
if ProcessorModel.shared.boardValid {
177188
boardHelpButton.removeFromSuperview()
@@ -182,9 +193,9 @@ class PowerToolViewController: NSViewController, NSWindowDelegate {
182193
ProcessorModel.shared.refreshPStateDef()
183194
vaildStatesClock = ProcessorModel.shared.getVaildPStateClocks()
184195
let pstateCur = ProcessorModel.shared.getPState()
185-
196+
let s = ProcessorModel.shared.getPPM()
186197
let pdt = vaildStatesClock.map{ "\(Int($0))Mhz" }
187-
overviewSpeedShift.setOptions(newOptions: pdt, selection: pstateCur)
198+
overviewSpeedShift.setOptions(newOptions: pdt, selection: s ? -1 : pstateCur)
188199
}
189200

190201
func updateCPB() {
@@ -198,6 +209,15 @@ class PowerToolViewController: NSViewController, NSWindowDelegate {
198209
let s = ProcessorModel.shared.getPPM()
199210

200211
asaBox.state = s ? NSControl.StateValue.on : NSControl.StateValue.off
212+
updateLPM()
213+
}
214+
215+
func updateLPM() {
216+
lpmBox.isEnabled = ProcessorModel.shared.getPPM()
217+
218+
let s = ProcessorModel.shared.getLPM()
219+
220+
lpmBox.state = s ? NSControl.StateValue.on : NSControl.StateValue.off
201221
}
202222

203223
@IBAction func openGithub(_ sender: Any) {

AMD Power Gadget/ProcessorModel.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class ProcessorModel {
7777
NSApplication.shared.terminate(self)
7878
}
7979

80-
// fetchSupportedProcessor()
80+
fetchSupportedProcessor()
8181
}
8282

8383
func initDriver() -> Bool {
@@ -225,6 +225,11 @@ class ProcessorModel {
225225
loadPStateDefClock()
226226
}
227227

228+
func getHPCpus() -> Int{
229+
let o = kernelGetUInt64(count: 1, selector: 17)
230+
return Int(o[0])
231+
}
232+
228233
func setPState(state : Int) {
229234
var input: [UInt64] = [UInt64(state)]
230235
let res = IOConnectCallMethod(connect, 10, &input, 1, nil, 0,
@@ -299,6 +304,23 @@ class ProcessorModel {
299304
}
300305
}
301306

307+
func getLPM() -> Bool {
308+
let o = kernelGetUInt64(count: 1, selector: 18)
309+
return o[0] == 0 ? false : true
310+
}
311+
312+
func setLPM(enabled : Bool){
313+
var input: [UInt64] = [UInt64(enabled ? 1 : 0)]
314+
let res = IOConnectCallMethod(connect, 19, &input, 1, nil, 0,
315+
nil, nil,
316+
nil, nil)
317+
318+
if res != KERN_SUCCESS {
319+
print(String(cString: mach_error_string(res)))
320+
return
321+
}
322+
}
323+
302324
func getInstructionDelta() -> [UInt64]{
303325
let o = kernelGetUInt64(count: 1, selector: 5)
304326
return [o[0]]

AMDRyzenCPUPowerManagement/AMDRyzenCPUPMUserClient.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ IOReturn AMDRyzenCPUPMUserClient::externalMethod(uint32_t selector, IOExternalMe
303303

304304
uint64_t *dataOut = (uint64_t*) arguments->structureOutput;
305305

306-
dataOut[0] = (uint64_t)fProvider->PPMEnabled;
306+
dataOut[0] = (uint64_t)(fProvider->getPMPStateLimit() == 0 ? 0 : 1);
307307
break;
308308
}
309309

@@ -315,12 +315,9 @@ IOReturn AMDRyzenCPUPMUserClient::externalMethod(uint32_t selector, IOExternalMe
315315
if(arguments->scalarInputCount != 1)
316316
return kIOReturnBadArgument;
317317

318-
fProvider->PPMEnabled = arguments->scalarInput[0]==1?true:false;
318+
boolean_t enabled = arguments->scalarInput[0]==1?true:false;
319319

320-
if(!fProvider->PPMEnabled){
321-
fProvider->PStateCtl = 0;
322-
fProvider->applyPowerControl();
323-
}
320+
fProvider->setPMPStateLimit(enabled ? 1 : 0);
324321

325322
break;
326323
}
@@ -363,6 +360,44 @@ IOReturn AMDRyzenCPUPMUserClient::externalMethod(uint32_t selector, IOExternalMe
363360
break;
364361
}
365362

363+
case 17: {
364+
arguments->scalarOutputCount = 0;
365+
366+
arguments->structureOutputSize = 1 * sizeof(uint64_t);
367+
368+
uint64_t *dataOut = (uint64_t*) arguments->structureOutput;
369+
370+
dataOut[0] = (uint64_t)(fProvider->getHPcpus());
371+
break;
372+
}
373+
374+
//Get LPM
375+
case 18: {
376+
arguments->scalarOutputCount = 0;
377+
378+
arguments->structureOutputSize = 1 * sizeof(uint64_t);
379+
380+
uint64_t *dataOut = (uint64_t*) arguments->structureOutput;
381+
382+
dataOut[0] = (uint64_t)(fProvider->getPMPStateLimit() == 2 ? 1 : 0);
383+
break;
384+
}
385+
386+
//Set LPM
387+
case 19: {
388+
arguments->scalarOutputCount = 0;
389+
arguments->structureOutputSize = 0;
390+
391+
if(arguments->scalarInputCount != 1)
392+
return kIOReturnBadArgument;
393+
394+
boolean_t enabled = arguments->scalarInput[0]==1?true:false;
395+
396+
fProvider->setPMPStateLimit(enabled ? 2 : 1);
397+
398+
break;
399+
}
400+
366401
default: {
367402
IOLog("AMDCPUSupportUserClient::externalMethod: invalid method.\n");
368403
break;

AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,6 @@ bool AMDRyzenCPUPowerManagement::start(IOService *provider){
293293
provider->calculateEffectiveFrequency(physical);
294294

295295
}, provider);
296-
297-
if(provider->PPMEnabled) provider->updatePowerControl();
298296

299297
//Read stats from package.
300298
provider->updatePackageTemp();
@@ -314,7 +312,7 @@ bool AMDRyzenCPUPowerManagement::start(IOService *provider){
314312

315313
provider->actualUpdateTimeInterval = now - provider->timeOfLastUpdate;
316314
provider->timeOfLastUpdate = now;
317-
provider->updateTimeInterval = min(provider->PPMEnabled? 320 : 1200, max(50, newInt));
315+
provider->updateTimeInterval = min(1200, max(50, newInt));
318316

319317
provider->timerEventSource->setTimeoutMS(provider->updateTimeInterval);
320318
// IOLog("est time: %d\n", provider->estimatedRequestTimeInterval);
@@ -485,7 +483,7 @@ void AMDRyzenCPUPowerManagement::updateInstructionDelta(uint8_t cpu_num){
485483
//Skip if overflowed
486484
if(lastInstructionDelta_perCore[cpu_num] > insCount) return;
487485

488-
uint64_t delta = insCount - lastInstructionDelta_perCore[cpu_num];
486+
// uint64_t delta = insCount - lastInstructionDelta_perCore[cpu_num];
489487
instructionDelta_PerCore[cpu_num] = insCount - lastInstructionDelta_perCore[cpu_num];
490488

491489
lastInstructionDelta_perCore[cpu_num] = insCount;
@@ -509,30 +507,6 @@ void AMDRyzenCPUPowerManagement::applyPowerControl(){
509507
}, nullptr, this);
510508
}
511509

512-
void AMDRyzenCPUPowerManagement::updatePowerControl(){
513-
//Passive PM
514-
float loadMax = 0;
515-
bool inc = false;
516-
int shouldStep = PStateCtl;
517-
for (int i = 0; i < totalNumberOfPhysicalCores; i++) {
518-
if(loadIndex_PerCore[i] >= PStateStepUpRatio){
519-
shouldStep = max(shouldStep - 1, 0);
520-
inc = true;
521-
break;
522-
}
523-
524-
loadMax = max(loadMax, loadIndex_PerCore[i]);
525-
}
526-
if(!inc && loadMax <= PStateStepDownRatio)
527-
shouldStep = min(PStateCtl + 1, PStateEnabledLen-1);
528-
529-
if(shouldStep == PStateCtl) return;
530-
531-
PStateCtl = shouldStep;
532-
533-
applyPowerControl();
534-
}
535-
536510
void AMDRyzenCPUPowerManagement::setCPBState(bool enabled){
537511
if(!cpbSupported) return;
538512

@@ -654,7 +628,6 @@ void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){
654628
//A bit hacky but at least works for now.
655629
void* args[] = {this, (void*)buf};
656630

657-
658631

659632
mp_rendezvous(nullptr, [](void *obj) {
660633
auto v = static_cast<uint64_t*>(((uint64_t**)obj)[1]);
@@ -680,6 +653,21 @@ void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){
680653

681654
}
682655

656+
uint32_t AMDRyzenCPUPowerManagement::getPMPStateLimit(){
657+
return pmRyzen_pstatelimit;
658+
}
659+
660+
void AMDRyzenCPUPowerManagement::setPMPStateLimit(uint32_t state){
661+
pmRyzen_pstatelimit = min(2, state);
662+
if(state > 0){
663+
pmRyzen_PState_reset();
664+
}
665+
}
666+
667+
uint32_t AMDRyzenCPUPowerManagement::getHPcpus(){
668+
return pmRyzen_hpcpus;
669+
}
670+
683671
EXPORT extern "C" kern_return_t ADDPR(kern_start)(kmod_info_t *, void *) {
684672
// Report success but actually do not start and let I/O Kit unload us.
685673
// This works better and increases boot speed in some cases.

AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ class AMDRyzenCPUPowerManagement : public IOService {
134134
void calculateEffectiveFrequency(uint8_t physical);
135135
void updateInstructionDelta(uint8_t physical);
136136
void applyPowerControl();
137-
void updatePowerControl();
138137

139138
void setCPBState(bool enabled);
140139
bool getCPBState();
@@ -147,6 +146,11 @@ class AMDRyzenCPUPowerManagement : public IOService {
147146
void dumpPstate();
148147
void writePstate(const uint64_t *buf);
149148

149+
uint32_t getPMPStateLimit();
150+
void setPMPStateLimit(uint32_t);
151+
152+
uint32_t getHPcpus();
153+
150154
uint32_t totalNumberOfPhysicalCores;
151155
uint32_t totalNumberOfLogicalCores;
152156

@@ -182,7 +186,6 @@ class AMDRyzenCPUPowerManagement : public IOService {
182186

183187
float loadIndex_PerCore[CPUInfo::MaxCpus];
184188

185-
bool PPMEnabled = false;
186189
float PStateStepUpRatio = 0.36;
187190
float PStateStepDownRatio = 0.05;
188191

0 commit comments

Comments
 (0)