Added new options:
--get-offsets-terse --get-physical-cores --set-pbo-scalar --get-pbo-scalar Presumably fixed compatibility with SKUs that have disabled physical cores Presumably have a "clean" exit if the program is run on an unsupported system
This commit is contained in:
parent
b2bf2571c6
commit
f177ffda80
@ -1,12 +1,29 @@
|
|||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using ZenStates.Core;
|
using ZenStates.Core;
|
||||||
|
using System.Security.Principal;
|
||||||
|
|
||||||
namespace ryzen_smu_cli
|
namespace ryzen_smu_cli
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
private static readonly Cpu ryzen = new();
|
private static readonly Cpu ryzen;
|
||||||
|
private static readonly Dictionary<int, int> mappedCores;
|
||||||
|
static Program()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ryzen = new Cpu();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error: {ex.Message}");
|
||||||
|
Console.WriteLine("If the previous message was unclear, for some reason, ZenStates-Core failed to initialize an instance of the CPU control object.");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedCores = MapLogicalCoresToPhysical();
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly string wmiAMDACPI = "AMD_ACPI";
|
private static readonly string wmiAMDACPI = "AMD_ACPI";
|
||||||
private static readonly string wmiScope = "root\\wmi";
|
private static readonly string wmiScope = "root\\wmi";
|
||||||
@ -19,19 +36,37 @@ namespace ryzen_smu_cli
|
|||||||
private static bool wmiPopulated = false;
|
private static bool wmiPopulated = false;
|
||||||
private static bool rebootFlag = false;
|
private static bool rebootFlag = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
|
if (!IsAdministrator())
|
||||||
|
{
|
||||||
|
Console.WriteLine("This application must be run as an administrator.");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
var rootCommand = new RootCommand("A CLI for the Ryzen SMU.");
|
var rootCommand = new RootCommand("A CLI for the Ryzen SMU.");
|
||||||
|
|
||||||
var pboOffset = new Option<string>("--offset", "Specify a zero-indexed core, or list of cores, and their PBO offset(s), in a fashion similar to taskset. e.g. 0:-10,1:5,2:-20,14:-25");
|
var pboOffset = new Option<string>("--offset", "Specify a zero-indexed logical core, or list of logical cores, and their PBO offset(s), in a fashion similar to taskset. e.g. 0:-10,1:5,2:-20,14:-25. These are the logical core IDs as they appear in your system, not the true IDs according to fused hardware disabled cores.");
|
||||||
var disableCores = new Option<string>("--disable-cores", "Specify a zero-indexed list of cores to disable. e.g. 0,1,4,7,12,15. This setting does not take into account any current core disablement. All cores you wish to disable must be specified. Any that are unspecified will be enabled. This option requires a reboot.");
|
var disableCores = new Option<string>("--disable-cores", "Specify a zero-indexed list of logical cores to disable. e.g. 0,1,4,7,12,15. This setting does not take into account any current core disablement. All cores you wish to disable must be specified. Any that are unspecified will be enabled. This option requires a reboot.");
|
||||||
var enableCores = new Option<bool>("--enable-all-cores", "Enable all cores.");
|
var enableCores = new Option<bool>("--enable-all-cores", "Enable all cores.");
|
||||||
|
//var toggleJson = new Option<bool>("--json", "Enable json format for informational outputs.");
|
||||||
|
var getCurrentPBOTerse = new Option<bool>("--get-offsets-terse", "Print a list of all PBO offsets on logical cores in a simple, comma-separated format, without core identifiers. e.g. -15,0,2,-20.");
|
||||||
|
var getPhysicalCores = new Option<bool>("--get-physical-cores", "Print a list of physical cores, to find out which ones are disabled in <8-core-per-CCD SKUs.");
|
||||||
|
var setPBOScalar = new Option<string>("--set-pbo-scalar", "Sets the PBO scalar. This is a whole number between 1 and 10.");
|
||||||
|
var getPBOScalar = new Option<bool>("--get-pbo-scalar", "Get the current PBO scalar.");
|
||||||
|
|
||||||
rootCommand.AddOption(pboOffset);
|
rootCommand.AddOption(pboOffset);
|
||||||
rootCommand.AddOption(disableCores);
|
rootCommand.AddOption(disableCores);
|
||||||
rootCommand.AddOption(enableCores);
|
rootCommand.AddOption(enableCores);
|
||||||
|
rootCommand.AddOption(getCurrentPBOTerse);
|
||||||
|
rootCommand.AddOption(getPhysicalCores);
|
||||||
|
rootCommand.AddOption(setPBOScalar);
|
||||||
|
rootCommand.AddOption(getPBOScalar);
|
||||||
|
|
||||||
rootCommand.SetHandler((offsetArgs, coreDisableArgs, enableAll) =>
|
rootCommand.SetHandler((offsetArgs, coreDisableArgs, enableAll, getCurrentPBOTerse, getPhysicalCores,
|
||||||
|
setPBOScalar, getPBOScalar) =>
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(offsetArgs)) ApplyPBOOffset(offsetArgs);
|
if (!string.IsNullOrEmpty(offsetArgs)) ApplyPBOOffset(offsetArgs);
|
||||||
|
|
||||||
@ -39,8 +74,35 @@ namespace ryzen_smu_cli
|
|||||||
|
|
||||||
if (enableAll) ApplyDisableCores();
|
if (enableAll) ApplyDisableCores();
|
||||||
|
|
||||||
|
if (getCurrentPBOTerse)
|
||||||
}, pboOffset, disableCores, enableCores);
|
{
|
||||||
|
Console.WriteLine("Current PBO offsets:");
|
||||||
|
string offsetLine = "";
|
||||||
|
for (int i = 0; i < mappedCores.Count; i++)
|
||||||
|
{
|
||||||
|
int mapIndex = i < 8 ? 0 : 1;
|
||||||
|
uint coreMask = ryzen.MakeCoreMask((uint)mappedCores[i]);
|
||||||
|
offsetLine += Convert.ToDecimal((int)ryzen.GetPsmMarginSingleCore((uint)(((mapIndex << 8) | ((mappedCores[i] % 8) & 0xF)) << 20)));
|
||||||
|
offsetLine += ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(offsetLine.TrimEnd(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getPhysicalCores)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Fused status of physical cores:");
|
||||||
|
for (var i = 0; i < ryzen.info.topology.physicalCores; i++)
|
||||||
|
{
|
||||||
|
int mapIndex = i < 8 ? 0 : 1;
|
||||||
|
if ((~ryzen.info.topology.coreDisableMap[mapIndex] >> i % 8 & 1) == 0) Console.WriteLine($"Core {i}: Disabled");
|
||||||
|
else Console.WriteLine($"Core {i}: Enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(setPBOScalar)) ryzen.SetPBOScalar(Convert.ToUInt32(setPBOScalar));
|
||||||
|
if (getPBOScalar) Console.WriteLine($"Current PBO scalar: {ryzen.GetPBOScalar()}");
|
||||||
|
}, pboOffset, disableCores, enableCores, getCurrentPBOTerse, getPhysicalCores, setPBOScalar, getPBOScalar);
|
||||||
|
|
||||||
if (args.Length == 0)
|
if (args.Length == 0)
|
||||||
{
|
{
|
||||||
@ -59,6 +121,25 @@ namespace ryzen_smu_cli
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Dictionary<int, int> MapLogicalCoresToPhysical()
|
||||||
|
{
|
||||||
|
Dictionary<int, int> mappedCores = [];
|
||||||
|
|
||||||
|
int logicalCoreIter = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < ryzen.info.topology.physicalCores; i++)
|
||||||
|
{
|
||||||
|
int mapIndex = i < 8 ? 0 : 1;
|
||||||
|
if ((~ryzen.info.topology.coreDisableMap[mapIndex] >> i % 8 & 1) != 0)
|
||||||
|
{
|
||||||
|
mappedCores.Add(logicalCoreIter, i);
|
||||||
|
logicalCoreIter += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedCores;
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetWmiInstanceName()
|
private static string GetWmiInstanceName()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -127,28 +208,27 @@ namespace ryzen_smu_cli
|
|||||||
|
|
||||||
private static void ApplyPBOOffset(string offsetArgs)
|
private static void ApplyPBOOffset(string offsetArgs)
|
||||||
{
|
{
|
||||||
string[] arg = offsetArgs.Split(',');
|
// This checks if the current SKU has a known register for writing PBO offsets
|
||||||
|
if (ryzen.smu.Rsmu.SMU_MSG_SetDldoPsmMargin != 0)
|
||||||
for (int i = 0; i < arg.Length; i++)
|
|
||||||
{
|
{
|
||||||
int core = Convert.ToInt32(arg[i].Split(':')[0]);
|
string[] arg = offsetArgs.Split(',');
|
||||||
int offset = Convert.ToInt32(arg[i].Split(':')[1]);
|
// var unavailableCoreMap = MapUnavailableCores();
|
||||||
|
|
||||||
// Magic numbers from SMUDebugTool
|
for (int i = 0; i < arg.Length; i++)
|
||||||
// This does some bitshifting calculations to get the mask for individual cores for chips with up to two CCDs
|
|
||||||
// I'm not sure if it would work with more, in theory. It's unclear to me based on the github issues.
|
|
||||||
int mapIndex = core < 8 ? 0 : 1;
|
|
||||||
if ((~ryzen.info.topology.coreDisableMap[mapIndex] >> core % 8 & 1) == 1)
|
|
||||||
{
|
{
|
||||||
ryzen.SetPsmMarginSingleCore((uint)(((mapIndex << 8) | core % 8 & 0xF) << 20), offset);
|
int core = Convert.ToInt32(arg[i].Split(':')[0]);
|
||||||
Console.WriteLine($"Set core {core} offset to {offset}!");
|
int offset = Convert.ToInt32(arg[i].Split(':')[1]);
|
||||||
}
|
|
||||||
|
|
||||||
else
|
// Magic numbers from SMUDebugTool
|
||||||
{
|
// This does some bitshifting calculations to get the mask for individual cores for chips with up to two CCDs
|
||||||
Console.WriteLine($"Unable to set offset on disabled core {core}.");
|
// Support for threadrippers/epyc is theoretically available, if the calculations were expanded, but are untested
|
||||||
|
int mapIndex = core < 8 ? 0 : 1;
|
||||||
|
ryzen.SetPsmMarginSingleCore((uint)(((mapIndex << 8) | mappedCores[core] % 8 & 0xF) << 20), offset);
|
||||||
|
Console.WriteLine($"Set logical core {core} offset to {offset}!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else Console.WriteLine("You have attempted to enable PBO offsets on a CPU that does not support them.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplyDisableCores(string coreArgs = "Enable")
|
private static void ApplyDisableCores(string coreArgs = "Enable")
|
||||||
@ -191,5 +271,14 @@ namespace ryzen_smu_cli
|
|||||||
Console.WriteLine("Something has gone terribly wrong, the downcore config option is not present.");
|
Console.WriteLine("Something has gone terribly wrong, the downcore config option is not present.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsAdministrator()
|
||||||
|
{
|
||||||
|
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
|
||||||
|
{
|
||||||
|
WindowsPrincipal principal = new WindowsPrincipal(identity);
|
||||||
|
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>ryzen_smu_cli</RootNamespace>
|
<RootNamespace>ryzen_smu_cli</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>0.0.2</Version>
|
<Version>0.1.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user