diff --git a/public/bin/RyzenAdjServiceTask.xml.template b/public/bin/RyzenAdjServiceTask.xml.template new file mode 100644 index 0000000..296dcd5 --- /dev/null +++ b/public/bin/RyzenAdjServiceTask.xml.template @@ -0,0 +1,43 @@ + + + + + true + + + + + InteractiveToken + HighestAvailable + + + + IgnoreNew + false + false + true + false + false + + false + false + + true + true + false + false + false + PT0S + 7 + + PT60M + 10 + + + + + powershell + -WindowStyle hidden -ExecutionPolicy Bypass -file "###SCRIPTPATH###" + + + diff --git a/public/bin/auto-start-ryzen-controller.bat b/public/bin/auto-start-ryzen-controller.bat deleted file mode 100644 index 80fccf5..0000000 --- a/public/bin/auto-start-ryzen-controller.bat +++ /dev/null @@ -1 +0,0 @@ -"%~dp0..\..\..\elevate.exe" "%~dp0..\..\..\..\Ryzen Controller.exe" diff --git a/public/bin/demo.bat b/public/bin/demo.bat index 12a3ecc..5bcf94c 100644 --- a/public/bin/demo.bat +++ b/public/bin/demo.bat @@ -1,2 +1,2 @@ -%~dp0\ryzenadj.exe --stapm-limit=40000 --fast-limit=45000 --slow-limit=45000 --tctl-temp=90 -pause \ No newline at end of file +%~dp0\ryzenadj.exe --stapm-limit=40000 --fast-limit=45000 --slow-limit=45000 --tctl-temp=90 +pause diff --git a/public/bin/inpoutx64.dll b/public/bin/inpoutx64.dll new file mode 100644 index 0000000..82c343f Binary files /dev/null and b/public/bin/inpoutx64.dll differ diff --git a/public/bin/installServiceTask.bat b/public/bin/installServiceTask.bat new file mode 100644 index 0000000..02df30e --- /dev/null +++ b/public/bin/installServiceTask.bat @@ -0,0 +1,39 @@ +@echo off +NET FILE 1>NUL 2>NUL +if %errorlevel% NEQ 0 ( + echo Installation need be run as Administrator to install a Task + pause + exit /B 0 +) + +cd /D "%~dp0" +choice /C YN /M "Do you want to install Service based on directory %~dp0? It can not be changed after installation." +if %ERRORLEVEL% NEQ 1 exit /B 1 + +for %%f in (RyzenAdjServiceTask.xml.template readjustService.ps1 libryzenadj.dll WinRing0x64.dll WinRing0x64.sys inpoutx64.dll) do ( + if not exist %%f echo %%f is missing && goto failed +) + +echo Please configure RyzenAdjService by adding your prefered values in the top section of the powershell script. +timeout /t 2 > NUL +notepad "%~dp0\readjustService.ps1" + +powershell -Command "(gc '%~dp0RyzenAdjServiceTask.xml.template') -replace '###SCRIPTPATH###', '%~dp0readjustService.ps1' | Out-File -encoding ASCII '%~dp0RyzenAdjServiceTask.xml'" + +SCHTASKS /Create /TN "AMD\RyzenAdj" /XML "%~dp0RyzenAdjServiceTask.xml" /F || goto failed + +SCHTASKS /run /TN "AMD\RyzenAdj" || goto failed + +timeout /t 2 > NUL + +SCHTASKS /query /TN "AMD\RyzenAdj" || goto failed + +echo. +echo Installation successfull +pause +exit /B 0 + +:FAILED +echo Installation failed +pause +exit /B 1 diff --git a/public/bin/libryzenadj.dll b/public/bin/libryzenadj.dll index f8fa949..e2d76b2 100644 Binary files a/public/bin/libryzenadj.dll and b/public/bin/libryzenadj.dll differ diff --git a/public/bin/libryzenadj.exp b/public/bin/libryzenadj.exp deleted file mode 100644 index 788cb0f..0000000 Binary files a/public/bin/libryzenadj.exp and /dev/null differ diff --git a/public/bin/libryzenadj.lib b/public/bin/libryzenadj.lib deleted file mode 100644 index 3aa28f7..0000000 Binary files a/public/bin/libryzenadj.lib and /dev/null differ diff --git a/public/bin/pmtable-example.py b/public/bin/pmtable-example.py new file mode 100644 index 0000000..ec269a6 --- /dev/null +++ b/public/bin/pmtable-example.py @@ -0,0 +1,59 @@ +import os, sys, time +from ctypes import * +from shutil import copyfile + +lib_path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(lib_path) + +if sys.platform == 'win32' or sys.platform == 'cygwin': + try: + os.add_dll_directory(lib_path) + except AttributeError: + pass #not needed for old python version + + winring0_driver_file_path = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), 'WinRing0x64.sys') + if not os.path.isfile(winring0_driver_file_path): + copyfile(os.path.join(lib_path, 'WinRing0x64.sys'), winring0_driver_file_path) + + lib = cdll.LoadLibrary('libryzenadj') +else: + lib = cdll.LoadLibrary('libryzenadj.so') + +# define ctype mappings for types which can not be mapped automatically +lib.init_ryzenadj.restype = c_void_p +lib.get_table_ver.argtypes = [c_void_p] +lib.get_table_size.argtypes = [c_void_p] +lib.get_table_values.restype = POINTER(c_float) +lib.get_table_values.argtypes = [c_void_p] +lib.refresh_table.argtypes = [c_void_p] + +ry = lib.init_ryzenadj() + +if not ry: + sys.exit("RyzenAdj could not get initialized") + +print("pmtable version: {:x}".format(lib.get_table_ver(ry))) + +input("Press any key to show all pmtable values...") + +pmtable_size = lib.get_table_size(ry) // 4 +pmtable = lib.get_table_values(ry) + +while True: + lib.refresh_table(ry) + columns, lines = os.get_terminal_size() + table_columns = columns // 16 # 16 chars per table entry + os.system('cls' if sys.platform == 'win32' else 'clear') + table_rows = 0 + for index in (range(pmtable_size)): + sys.stdout.write("{:3d}:{:8.2f}\t".format(index, pmtable[index])) + if index % table_columns == table_columns - 1: + sys.stdout.write('\n') + table_rows += 1 + if table_rows >= lines - 1: + sys.stdout.write('{:d} More entries ...'.format(pmtable_size - 1 - index)) + break + + if index % table_columns != table_columns - 1: sys.stdout.write('\n') + sys.stdout.flush() + time.sleep(1) diff --git a/public/bin/readjust.py b/public/bin/readjust.py new file mode 100644 index 0000000..856dcc6 --- /dev/null +++ b/public/bin/readjust.py @@ -0,0 +1,70 @@ +import os, sys, time +from ctypes import * +from shutil import copyfile + +lib_path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(lib_path) + +if sys.platform == 'win32' or sys.platform == 'cygwin': + try: + os.add_dll_directory(lib_path) + except AttributeError: + pass #not needed for old python version + + winring0_driver_file_path = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), 'WinRing0x64.sys') + if not os.path.isfile(winring0_driver_file_path): + copyfile(os.path.join(lib_path, 'WinRing0x64.sys'), winring0_driver_file_path) + + lib = cdll.LoadLibrary('libryzenadj') +else: + lib = cdll.LoadLibrary('libryzenadj.so') + +# define ctype mappings for types which can not be mapped automatically +lib.init_ryzenadj.restype = c_void_p +lib.refresh_table.argtypes = [c_void_p] +lib.get_fast_limit.restype = c_float +lib.get_fast_limit.argtypes = [c_void_p] + +ry = lib.init_ryzenadj() + +if not ry: + sys.exit("RyzenAdj could not get initialized") + +error_messages = { + -1: "{:s} is not supported on this family\n", + -3: "{:s} is not supported on this SMU\n", + -4: "{:s} is rejected by SMU\n" +} + +def adjust(field, value): + function_name = "set_" + field + adjust_func = lib.__getattr__(function_name) + adjust_func.argtypes = [c_void_p, c_ulong] + res = adjust_func(ry, value) + if res: + error = error_messages.get(res, "{:s} did fail with {:d}\n") + sys.stderr.write(error.format(function_name, res)); + +def enable(field): + function_name = "set_" + field + adjust_func = lib.__getattr__(function_name) + adjust_func.argtypes = [c_void_p] + res = adjust_func(ry) + if res: + error = error_messages.get(res, "{:s} did fail with {:d}\n") + sys.stderr.write(error.format(function_name, res)); + +print("Monitor if fast limit is not 35W") +while True: + lib.refresh_table(ry) + limit = round(lib.get_fast_limit(ry)) + if limit != 35: + print("reapply limits, because old limit was {:d}".format(limit)) + adjust("fast_limit", 35000) + adjust("slow_limit", 22000) + adjust("slow_time", 30) + adjust("tctl_temp", 97) + adjust("apu_skin_temp_limit", 50) + adjust("vrmmax_current", 100000) + enable("max_performance") + time.sleep(3) diff --git a/public/bin/readjustService.ps1 b/public/bin/readjustService.ps1 new file mode 100644 index 0000000..812cf47 --- /dev/null +++ b/public/bin/readjustService.ps1 @@ -0,0 +1,450 @@ +<# +.SYNOPSIS + Automates ryzenAdj calls based on custom conditions +.DESCRIPTION + This script is designed to provide maximum flexibility to the user. For that reason it does not use parameters. + Instead of parameters, you need to populate the functions in the configuration section with your custom adjustments and additional custom code. +.NOTES + SPDX-License-Identifier: LGPL + Falco Schaffrath +#> + +Param([Parameter(Mandatory=$false)][switch]$noGUI) +$Error.Clear() +################################################################################ +#### Configuration Start +################################################################################ +# WARNING: Use at your own risk! + +$pathToRyzenAdjDlls = Split-Path -Parent $PSCommandPath #script path is DLL path, needs to be absolut path if you define something else + +$showErrorPopupsDuringInit = $true +# debug mode prints adjust success messages too instead of errorss only +$debugMode = $false +# if monitorField is set, this script does only adjust values if something did revert your monitored value. Clear monitorField String to disable monitoring +# This needs to be an value which actually gets overwritten by your device firmware/software if no changes get detected, your settings will not reapplied +$monitorField = "fast_limit" +# Does reapply adjustments if power slider did change position, check $Script:acSlider or $Script:dcSlider to apply slider specific values +$monitorPowerSlider = $true +# HWiNFO needs to be restartet after this script did run the first time with this option +$updateHWINFOSensors = $false +# some Zen3 devices have a locked STAPM limit, this workarround resets the stapm timer to have unlimited stapm. Use max stapm_limit and stapm_time (usually 500) to triger as less resets as possible +$resetSTAPMUsage = $false + +function doAdjust_ACmode { + $Script:repeatWaitTimeSeconds = 1 #only use values below 5s if you are using $monitorField + adjust "fast_limit" 46000 + adjust "slow_limit" 25000 + #adjust "slow_time" 30 + #adjust "tctl_temp" 93 + #adjust "apu_skin_temp_limit" 50 + #adjust "vrmmax_current" 100000 + #replace any_other_field with additional adjustments. Name is equal to RyzenAdj options but it uses _ instead of - + #adjust "any_other_field" 1234 + + #custom code, for example set fan controll back to auto + #values (WriteRegister: 47, FanSpeedResetValue:128) extracted from similar devices at https://github.com/hirschmann/nbfc/blob/master/Configs/ + #Start-Process -NoNewWindow -Wait -filePath "C:\Program Files (x86)\NoteBook FanControl\ec-probe.exe" -ArgumentList("write", "47", "128") + + if($Script:acSlider -eq $Script:betterBattery){ + #put adjustments for energie saving slider position here: + enable "power_saving" #add 10s boost delay for usage on cable to reduce idle power consumtion + } +} + +function doAdjust_BatteryMode { + $Script:repeatWaitTimeSeconds = 10 #do less reapplies and less HWiNFO updates to save power + adjust "fast_limit" 26000 + adjust "slow_limit" 10000 + #adjust "any_other_field" 1234 + + if($Script:dcSlider -eq $Script:betterBattery){ + #put adjustments for energie saving slider position here: for example disable fan to save power + #Start-Process -NoNewWindow -Wait -filePath "C:\Program Files (x86)\NoteBook FanControl\ec-probe.exe" -ArgumentList("write", "47", "0") + } + + if($Script:dcSlider -eq $Script:bestPerformance){ + #put adjustments for highest performance slider position here: + enable "max_performance" #removes 10s boost delay on battery + doAdjust_ACmode #set limits from cable mode on battery + } +} +################################################################################ +#### Configuration End +################################################################################ + +$env:PATH += ";$pathToRyzenAdjDlls" +$NL = $([System.Environment]::NewLine); + +if($noGUI){ $showErrorPopupsDuringInit = $false } + +$apiHeader = @' +[DllImport("libryzenadj.dll")] public static extern IntPtr init_ryzenadj(); +[DllImport("libryzenadj.dll")] public static extern int set_stapm_limit(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_fast_limit(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_slow_limit(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_slow_time(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_stapm_time(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_tctl_temp(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_vrm_current(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_vrmsoc_current(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_vrmmax_current(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_vrmsocmax_current(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_psi0_current(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_psi0soc_current(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_max_gfxclk_freq(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_min_gfxclk_freq(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_max_socclk_freq(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_min_socclk_freq(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_max_fclk_freq(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_min_fclk_freq(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_max_vcn(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_min_vcn(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_max_lclk(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_min_lclk(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_prochot_deassertion_ramp(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_apu_skin_temp_limit(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_dgpu_skin_temp_limit(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_apu_slow_limit(IntPtr ry, [In]uint value); +[DllImport("libryzenadj.dll")] public static extern int set_power_saving(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern int set_max_performance(IntPtr ry); + +[DllImport("libryzenadj.dll")] public static extern int refresh_table(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern IntPtr get_table_values(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_stapm_limit(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_stapm_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_stapm_time(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_fast_limit(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_fast_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_slow_limit(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_slow_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_apu_slow_limit(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_apu_slow_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrm_current(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrm_current_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrmsoc_current(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrmsoc_current_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrmmax_current(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrmmax_current_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrmsocmax_current(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_vrmsocmax_current_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_tctl_temp(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_tctl_temp_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_apu_skin_temp_limit(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_apu_skin_temp_value(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_dgpu_skin_temp_limit(IntPtr ry); +[DllImport("libryzenadj.dll")] public static extern float get_dgpu_skin_temp_value(IntPtr ry); + +[DllImport("kernel32.dll")] public static extern uint GetModuleFileName(IntPtr hModule, [Out]StringBuilder lpFilename, [In]int nSize); +[DllImport("kernel32.dll")] public static extern Boolean GetSystemPowerStatus(out SystemPowerStatus sps); +public struct SystemPowerStatus { + public Byte ACLineStatus; + public Byte BatteryFlag; + public Byte BatteryLifePercent; + public Byte Reserved1; + public Int32 BatteryLifeTime; + public Int32 BatteryFullLifeTime; +} + +public static String getExpectedWinRing0DriverFilepath(){ + StringBuilder fileName = new StringBuilder(255); + GetModuleFileName(IntPtr.Zero, fileName, fileName.Capacity); + return Path.GetDirectoryName(fileName.ToString()) + "\\WinRing0x64.sys"; +} + +public static String getDllImportErrors(){ + try { + Marshal.PrelinkAll(typeof(adj)); + } catch (Exception e) { + return e.Message; + } + return ""; +} +'@ + +if(-not ([System.Management.Automation.PSTypeName]'ryzen.adj').Type){ + Add-Type -MemberDefinition $apiHeader -Namespace 'ryzen' -Name 'adj' -UsingNamespace ('System.Text', 'System.IO') +} + +Add-Type -AssemblyName System.Windows.Forms +function showErrorMsg ([String] $msg){ + if($showErrorPopupsDuringInit){ + [void][System.Windows.Forms.MessageBox]::Show($msg, $PSCommandPath, + [System.Windows.Forms.MessageBoxButtons]::OK, + [System.Windows.Forms.MessageBoxIcon]::Error) + } +} + +$dllImportErrors = [ryzen.adj]::getDllImportErrors(); +if($dllImportErrors -or $Error){ + Write-Error $dllImportErrors + showErrorMsg "Problem with using libryzenadj.dll$NL$NL$($Error -join $NL)" + exit 1 +} + +$winring0DriverFilepath = [ryzen.adj]::getExpectedWinRing0DriverFilepath() +if(!(Test-Path $winring0DriverFilepath)) { Copy-Item -Path $pathToRyzenAdjDlls\WinRing0x64.sys -Destination $winring0DriverFilepath } + +$ry = [ryzen.adj]::init_ryzenadj() +if($ry -eq 0){ + $msg = "RyzenAdj could not get initialized.$($NL)Reason can be found inside Powershell$($NL)" + if($psISE) { $msg += "It is not possible to see the error reason inside ISE, you need to test it in PowerShell Console" } + showErrorMsg "$msg$NL$NL$($Error -join $NL)" + exit 1 +} + +function adjust ([String] $fieldName, [uInt32] $value) { + if($fieldName -eq $Script:monitorField) { + $newTargetValue = [math]::round($value * 0.001, 3, 0) + if($Script:monitorFieldAdjTarget -ne $newTargetValue){ + $Script:monitorFieldAdjTarget = $newTargetValue + Write-Host "set new monitoring target $fieldName to $newTargetValue" + } + } + $res = Invoke-Expression "[ryzen.adj]::set_$fieldName($ry, $value)" + switch ($res) { + 0 { + if($debugMode) { Write-Host "set $fieldName to $value" } + return + } + -1 { Write-Error "set_$fieldName is not supported on this family"} + -3 { Write-Error "set_$fieldName is not supported on this SMU"} + -4 { Write-Error "set_$fieldName is rejected by SMU"} + default { Write-Error "set_$fieldName did fail with $res"} + } +} + +function enable ([String] $fieldName) { + $res = Invoke-Expression "[ryzen.adj]::set_$fieldName($ry)" + switch ($res) { + 0 { + if($debugMode) { Write-Host "enable $fieldName"} + return + } + -1 { Write-Error "set_$fieldName is not supported on this family"} + -3 { Write-Error "set_$fieldName is not supported on this SMU"} + -4 { Write-Error "set_$fieldName is rejected by SMU"} + default { Write-Error "set_$fieldName did fail with $res"} + } +} + +function testMonitorField { + if($monitorField -and $Script:monitorFieldAdjTarget -eq 0){ + Write-Error ("You forgot to set $monitorField in your profile.$NL$NL" + + "If you ignore it, the script will apply values unnessasary often.$NL") + } +} + +function updateMonitorFieldAdjResult { + if($monitorField){ + [void][ryzen.adj]::refresh_table($ry) + $Script:monitorFieldAdjResult = [math]::round((getMonitorValue), 3, 0) + if($Script:monitorFieldAdjTarget -ne $Script:monitorFieldAdjResult){ + Write-Host ("Warning - $monitorField adjust result $Script:monitorFieldAdjResult does not match target value $Script:monitorFieldAdjTarget. Value $Script:monitorFieldAdjResult will be used for monitoring") + } + } +} + +function testConfiguration { + Write-Host "Test Adjustments" + if($Script:systemPowerStatus.ACLineStatus){ + doAdjust_BatteryMode + testMonitorField + $Script:monitorFieldAdjTarget = 0 + doAdjust_ACmode + } else { + doAdjust_ACmode + testMonitorField + $Script:monitorFieldAdjTarget = 0 + doAdjust_BatteryMode + } + testMonitorField + updateMonitorFieldAdjResult + + if($resetSTAPMUsage -and [ryzen.adj]::get_stapm_time($ry) -eq 1) { + Write-Error "resetSTAPMUsage function does only work on devices with active STAPM control and don't do anything on devices with enabled STT control." + } + + if($Error -and $showErrorPopupsDuringInit){ + $answer = [System.Windows.Forms.MessageBox]::Show("Your Adjustment configuration did not work.$NL$NL$($Error -join $NL)", $PSCommandPath, + [System.Windows.Forms.MessageBoxButtons]::AbortRetryIgnore, + [System.Windows.Forms.MessageBoxIcon]::Warning) + $Error.Clear() + if($answer -eq "Abort"){ exit 1 } + if($answer -eq "Retry"){ testConfiguration } + } +} + +function getMonitorValue { + if($monitorField){ + return Invoke-Expression "[ryzen.adj]::get_$monitorField($ry)" + } + return 0 +} + +function createOrDeleteHWINFOSensors { + if($updateHWINFOSensors){ + New-Item -Path HKCU:\Software\HWiNFO64\Sensors\Custom -Name RyzenAdj -Force > $null + 'Key,Name,Value + Power0,STAPM Limit + Power1,STAPM + Power2,PPT FAST Limit + Power3,PPT FAST + Power4,PPT SLOW Limit + Power5,PPT SLOW + Power6,APU SLOW Limit + Power7,APU SLOW + Current0,TDC VRM Limit + Current1,TDC VRM + Current2,TDC VRM SoC Limit + Current3,TDC VRM SoC + Current4,EDC VRM Max Limit + Current5,EDC VRM Max + Current6,EDC VRM SoC Max Limit + Current7,EDC VRM SoC Max + Temp0,TCTL Temp Limit + Temp1,TCTL Temp + Temp2,SST APU Skin Temp Limit + Temp3,SST APU Skin Temp + Temp4,SST dGPU Skin Temp Limit + Temp5,SST dGPU Skin Temp + Usage0,STAPM Limit Usage, ("STAPM" / "STAPM Limit") * 100 + Usage1,PPT FAST Limit Usage, ("PPT FAST" / "PPT FAST Limit") * 100 + Usage2,PPT SLOW Limit Usage, ("PPT SLOW" / "PPT SLOW Limit") * 100 + Usage3,APU SLOW Limit Usage, ("APU SLOW" / "APU SLOW Limit") * 100 + Usage4,TDC VRM Limit Usage, ("TDC VRM" / "TDC VRM Limit") * 100 + Usage5,TDC VRM SoC Limit Usage, ("TDC VRM SoC" / "TDC VRM SoC Limit") * 100 + Usage6,EDC VRM Max Limit Usage, ("EDC VRM Max" / "EDC VRM Max Limit") * 100 + Usage7,EDC VRM SoC Max Limit Usage, ("EDC VRM SoC Max" / "EDC VRM SoC Max Limit") * 100 + Usage8,TCTL Temp Limit Usage, ("TCTL Temp" / "TCTL Temp Limit") * 100 + Usage9,SST APU Skin Temp Limit Usage, ("SST APU Skin Temp" / "SST APU Skin Temp Limit") * 100 + Usage10,SST dGPU Skin Temp Limit Usage, ("SST dGPU Skin Temp" / "SST dGPU Skin Temp Limit") * 100' | ConvertFrom-Csv -outvariable hwinfo_keys > $null + $hwinfo_keys | ForEach-Object {New-item -Path HKCU:\Software\HWiNFO64\Sensors\Custom\RyzenAdj -Name $_.Key -Force} > $null + $hwinfo_keys | ForEach-Object {[Microsoft.Win32.Registry]::SetValue("HKEY_CURRENT_USER\Software\HWiNFO64\Sensors\Custom\RyzenAdj\" + $_.Key,"Name",$_.Name)} > $null + $hwinfo_keys | Where Value -ne $null | ForEach-Object {[Microsoft.Win32.Registry]::SetValue("HKEY_CURRENT_USER\Software\HWiNFO64\Sensors\Custom\RyzenAdj\" + $_.Key,"Value",$_.Value)} > $null + } else { + Remove-Item HKCU:\Software\HWiNFO64\Sensors\Custom\RyzenAdj -Recurse -ErrorAction:Ignore + } +} + +function setHWINFOValue ([String] $name, [float] $value) { + if(![float]::IsNaN($value)){ [Microsoft.Win32.Registry]::SetValue("HKEY_CURRENT_USER\Software\HWiNFO64\Sensors\Custom\RyzenAdj\" + $name,"Value",[String]$value) } +} + +function updateHWINFOSensors { + setHWINFOValue Power0 ([ryzen.adj]::get_stapm_limit($ry)) + setHWINFOValue Power1 ([ryzen.adj]::get_stapm_value($ry)) + setHWINFOValue Power2 ([ryzen.adj]::get_fast_limit($ry)) + setHWINFOValue Power3 ([ryzen.adj]::get_fast_value($ry)) + setHWINFOValue Power4 ([ryzen.adj]::get_slow_limit($ry)) + setHWINFOValue Power5 ([ryzen.adj]::get_slow_value($ry)) + setHWINFOValue Power6 ([ryzen.adj]::get_apu_slow_limit($ry)) + setHWINFOValue Power7 ([ryzen.adj]::get_apu_slow_value($ry)) + setHWINFOValue Current0 ([ryzen.adj]::get_vrm_current($ry)) + setHWINFOValue Current1 ([ryzen.adj]::get_vrm_current_value($ry)) + setHWINFOValue Current2 ([ryzen.adj]::get_vrmsoc_current($ry)) + setHWINFOValue Current3 ([ryzen.adj]::get_vrmsoc_current_value($ry)) + setHWINFOValue Current4 ([ryzen.adj]::get_vrmmax_current($ry)) + setHWINFOValue Current5 ([ryzen.adj]::get_vrmmax_current_value($ry)) + setHWINFOValue Current6 ([ryzen.adj]::get_vrmsocmax_current($ry)) + setHWINFOValue Current7 ([ryzen.adj]::get_vrmsocmax_current_value($ry)) + setHWINFOValue Temp0 ([ryzen.adj]::get_tctl_temp($ry)) + setHWINFOValue Temp1 ([ryzen.adj]::get_tctl_temp_value($ry)) + setHWINFOValue Temp2 ([ryzen.adj]::get_apu_skin_temp_limit($ry)) + setHWINFOValue Temp3 ([ryzen.adj]::get_apu_skin_temp_value($ry)) + setHWINFOValue Temp4 ([ryzen.adj]::get_dgpu_skin_temp_limit($ry)) + setHWINFOValue Temp5 ([ryzen.adj]::get_dgpu_skin_temp_value($ry)) + #setHWINFOValue Usage11 $pmTable[546] +} + +function resetSTAPMIfNeeded { + $stapm_limit = [ryzen.adj]::get_stapm_limit($ry) + $stapm_value = [ryzen.adj]::get_stapm_value($ry) + $stapm_hysteresis = 1 #Throttling starts arround ~0.9W before limit + + if ($stapm_value -gt ($stapm_limit - $stapm_hysteresis)) { + $stapm_time = [ryzen.adj]::get_stapm_time($ry) + $reduced_stapm_limit = ($stapm_limit - 5) #reduce stapm by 5W + Write-Host "[STAPM_RESET] stapm_value ($stapm_value) nearing stapm_limit ($stapm_limit), resetting..." + [void][ryzen.adj]::set_stapm_limit($ry, ($reduced_stapm_limit) * 1000) + [void][ryzen.adj]::set_stapm_time($ry, 0) + [Threading.Thread]::Sleep(10) #10ms is usually enough time + [void][ryzen.adj]::set_stapm_time($ry, $stapm_time) + [void][ryzen.adj]::set_stapm_limit($ry, $stapm_limit * 1250) # add 25% STAPM limit in case we are at battery saving mode where applied values get reduced by 10% or 20% + } +} + +if(-not $Script:repeatWaitTimeSeconds) { $Script:repeatWaitTimeSeconds = 5 } +$Script:monitorFieldAdjResult = 0; #adjust result will be used for monitoring because SMU may only set 90% and 80% of your value +$Script:monitorFieldAdjTarget = 0; +$powerkey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SYSTEM\ControlSet001\Control\Power\User\PowerSchemes\") +$Script:betterBattery = "961cc777-2547-4f9d-8174-7d86181b8a7a" +$Script:betterPerformance = "00000000-0000-0000-0000-000000000000" +$Script:bestPerformance = "ded574b5-45a0-4f42-8737-46345c09c238" +$Script:acSlider = $powerkey.GetValue("ActiveOverlayACPowerScheme") +$Script:dcSlider = $powerkey.GetValue("ActiveOverlayDCPowerScheme") + +$systemPowerStatus = New-Object ryzen.adj+SystemPowerStatus +[void][ryzen.adj]::GetSystemPowerStatus([ref]$systemPowerStatus) + +testConfiguration + +<# Example how to get 560 lines of ptable +$pmTable = [float[]]::new(560) +$tablePtr = [ryzen.adj]::get_table_values($ry); +[System.Runtime.InteropServices.Marshal]::Copy($tablePtr, $pmTable, 0, 560); +#> +createOrDeleteHWINFOSensors + +$mtxtArray = @() +if($monitorField){$mtxtArray += "$monitorField changes"} +if($monitorPowerSlider){$mtxtArray += "PowerSlider changes"} +if($mtxtArray.Length){ + $processType = "Monitor " + ($mtxtArray -join " and ") +} else { + $processType = "Apply Settings" +} +Write-Host "$processType every $Script:repeatWaitTimeSeconds seconds..." +while($true) { + $doAdjust = !$monitorField -and !$monitorPowerSlider + if($monitorField -or $updateHWINFOSensors -or $resetSTAPMUsage) { + [void][ryzen.adj]::refresh_table($ry) + #[System.Runtime.InteropServices.Marshal]::Copy($tablePtr, $pmTable, 0, 560); + } + + if($updateHWINFOSensors){ + updateHWINFOSensors + } + + if($monitorPowerSlider -and ($Script:acSlider -ne $powerkey.GetValue("ActiveOverlayACPowerScheme") -or $Script:dcSlider -ne $powerkey.GetValue("ActiveOverlayDCPowerScheme"))){ + Write-Host "Power Slider changed" + $Script:acSlider = $powerkey.GetValue("ActiveOverlayACPowerScheme") + $Script:dcSlider = $powerkey.GetValue("ActiveOverlayDCPowerScheme") + $doAdjust = $true + } + if($monitorField){ + $monitorValue = getMonitorValue + if($Script:monitorFieldAdjResult -ne [math]::round($monitorValue, 3, 0)){ + Write-Host "$monitorField value unexpectedly changed from $Script:monitorFieldAdjResult to $monitorValue" + $doAdjust = $true + } + } + + if($resetSTAPMUsage){ + resetSTAPMIfNeeded + } + + if($doAdjust){ + [void][ryzen.adj]::GetSystemPowerStatus([ref]$systemPowerStatus) + $oldWait = $Script:repeatWaitTimeSeconds + if($systemPowerStatus.ACLineStatus){ + doAdjust_ACmode + } else { + doAdjust_BatteryMode + } + updateMonitorFieldAdjResult + if($oldWait -ne $Script:repeatWaitTimeSeconds ) { Write-Host "$processType every $Script:repeatWaitTimeSeconds seconds..." } + } + + sleep $Script:repeatWaitTimeSeconds +} diff --git a/public/bin/ryzenadj.exe b/public/bin/ryzenadj.exe index 7eb7071..ea689f2 100644 Binary files a/public/bin/ryzenadj.exe and b/public/bin/ryzenadj.exe differ diff --git a/public/bin/ryzenadj.h b/public/bin/ryzenadj.h deleted file mode 100644 index 5eb2eb1..0000000 --- a/public/bin/ryzenadj.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: LGPL */ -/* Copyright (C) 2019 Jiaxun Yang */ -/* RyzenAdj API */ - -#ifndef RYZENADJ_H -#define RYZENADJ_H -#ifdef __cplusplus -extern "C" { -#endif -#include "nb_smu_ops.h" - -#ifdef _WIN32 -#define EXP __declspec(dllexport) -#define CALL __stdcall -#else -#define EXP -#define CALL -#endif - -#define RYZENADJ_VER 5 - -typedef struct { - nb_t nb; - pci_obj_t pci_obj; - smu_t mp1_smu; - smu_t psmu; -} *ryzen_access; - -EXP ryzen_access CALL init_ryzenadj(); - -EXP void CALL cleanup_ryzenadj(ryzen_access ry); - -EXP int CALL set_stapm_limit(ryzen_access, uint32_t value); -EXP int CALL set_fast_limit(ryzen_access, uint32_t value); -EXP int CALL set_slow_limit(ryzen_access, uint32_t value); -EXP int CALL set_slow_time(ryzen_access, uint32_t value); -EXP int CALL set_stapm_time(ryzen_access, uint32_t value); -EXP int CALL set_tctl_temp(ryzen_access, uint32_t value); -EXP int CALL set_vrm_current(ryzen_access, uint32_t value); -EXP int CALL set_vrmsoc_current(ryzen_access, uint32_t value); -EXP int CALL set_vrmmax_current(ryzen_access, uint32_t value); -EXP int CALL set_vrmsocmax_current(ryzen_access, uint32_t value); -EXP int CALL set_psi0_current(ryzen_access, uint32_t value); -EXP int CALL set_psi0soc_current(ryzen_access, uint32_t value); -EXP int CALL set_max_gfxclk_freq(ryzen_access, uint32_t value); -EXP int CALL set_min_gfxclk_freq(ryzen_access, uint32_t value); -EXP int CALL set_max_socclk_freq(ryzen_access, uint32_t value); -EXP int CALL set_min_socclk_freq(ryzen_access, uint32_t value); -EXP int CALL set_max_fclk_freq(ryzen_access, uint32_t value); -EXP int CALL set_min_fclk_freq(ryzen_access, uint32_t value); -EXP int CALL set_max_vcn(ryzen_access, uint32_t value); -EXP int CALL set_min_vcn(ryzen_access, uint32_t value); -EXP int CALL set_max_lclk(ryzen_access, uint32_t value); -EXP int CALL set_min_lclk(ryzen_access, uint32_t value); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/public/bin/uninstallServiceTask.bat b/public/bin/uninstallServiceTask.bat new file mode 100644 index 0000000..6973e10 --- /dev/null +++ b/public/bin/uninstallServiceTask.bat @@ -0,0 +1,23 @@ +@echo off +NET FILE 1>NUL 2>NUL +if %errorlevel% NEQ 0 ( + echo Deinstallation need to be run as Administrator to delete your Scheduled Task + pause + exit /B 0 +) + +reg query HKCU\Software\HWiNFO64\Sensors\Custom\RyzenAdj 2>NUL +if %errorlevel% EQU 0 reg delete HKCU\Software\HWiNFO64\Sensors\Custom\RyzenAdj + +SCHTASKS /query /TN "AMD\RyzenAdj" 2>NUL + +if %errorlevel% NEQ 0 ( + echo RyzenAdj Service Task is not installed + pause + exit /B 0 +) + +SCHTASKS /delete /TN "AMD\RyzenAdj" 2>NUL + +pause +exit /B 0