Parsing Bit flag data from Intel CPU MSR registers.

I am troubleshooting CPU prochot issues and using powershell to gather data when throttling occurs, using the Intel PCM tool, pcm-msr.exe to read specific registers such as : IA32_THERM_STATUS. 0x19c

sample command :
psm-msc.exe 0x19c
Read value 0x883d2800 from MSR 0x19c on core 0

I then have to look up the hex value 0x883d2800 in the bit field table listed here https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3b-part-2-manual.pdf page 14.10 Vol 3B.

Never having done anything like this I search for “Powershell bit field” and found one example that uses flags

Based on the example this example : Managing Bit Flags (Part 1) - Power Tips - Power Tips - IDERA Community

I created the following :

[Flags()]
enum IA32_THERM_STATUS
{
Reading_Valid = 2147483648
Resolution_in_Deg_Celsius = 2013265920
Digital_Readout = 4161536
Cross_domain_Limit_Log = 16384
Cross_domain_Limit_Status= 8192
Current_Limit_Log = 4096
Current_Limit_Status = 2048
Power_Limit_Notification_Log = 1024
Power_Limit_Notification_Status = 512
Thermal_Threshold_2_Log = 265
Thermal_Threshold_2_Status = 128
Thermal_Threshold_1_Log = 64
Thermal_Threshold_1_Status = 32
Critical_Temperature_Log = 16
Critical_Temperature_Status = 8
PROCHOT_or_FORCEPR_Log = 4
PROCHOT_or_FORCEPR_Event = 2
Thermal_Status_Log = 1
Thermal_Status = 0
}

$MSRHex = ((cmd /c C:\ProgramData\Util\PCM\pcm-msr.exe 0x19c 2>1 $null ) -match “Read Value”).split(" “)[3]
$MSRDec = [Convert]::ToInt64(”$MSRHex", 16)

[IA32_THERM_STATUS]$flags = $MSRDec
$flags

1St problem I have is I don’t know how to define the Resolution_in_Deg_Celsius and Digital_readout , values as they cover multiple positions here is how I arrived a the values : I’m not good in math but based on the example I found I have get the number for column B and for the items that span multiple rows I add the row and take the total.

to run my code, you can set the $MSRHex = 0x883d2800 and see if that converts.

I get errors. Not surprising as some of the value are simple flags but digital Readout and Resolution are going to values I want to capture and convert back to dec temp readings. No clue on how I should do this ?

Testing, I have tried to update this thread 15 times in the last two days, trying a simple post. All updated never make it.

I finally was able to progress after a colleague from work wrote some C# code that was able to load in powershell, after fiddling around I was able to a pure powershell verison.

here is an example :
step 1 build an enum C# style, that a 100% copy past from the C# code. 1st issue I had the original code was defining General_Flag_IA32_therm_status as UInt64, powershell would not accept this value I has to change to a ulong, But this means that I could not create bitmask for more than 32 bits, yet some of the intel MSR can use up to 64 bits ?

Add-Type -TypeDefinition @“
[System.Flags]
public enum General_Flag_IA32_THERM_STATUS : ulong
{
THERMAL_STATUS = 1,
THERMAL_STATUS_LOG = 1 << 1,
PROCHOT_OR_FORCEPR_EVENT = 1 << 2,
PROCHOT_OR_FORCEPR_LOG = 1 << 3,
CRITICAL_TEMPERATURE_STATUS = 1 << 4,
CRITICAL_TEMPERATURE_LOG = 1 << 5,
THERMAL_THRESHOLD_1_STATUS = 1 << 6,
THERMAL_THRESHOLD_1_LOG = 1 << 7,
THERMAL_THRESHOLD_2_STATUS = 1 << 8,
THERMAL_THRESHOLD_2_LOG = 1 << 9,
POWER_LIMIT_NOTIFICATION_STATUS = 1 << 10,
POWER_LIMIT_NOTIFICATION_LOG = 1 << 11,
CURRENT_LIMIT_STATUS = 1 << 12,
CURRENT_LIMIT_LOG = 1 << 13,
CROSS_DOMAIN_LIMIT_STATUS = 1 << 14,
CROSS_DOMAIN_LIMIT_LOG = 1 << 15,
READING_VALID = 1ul << 31
}
”@

Next : this line runs the intel PCM tool pcm-msr.exe reads MSR value for IA32_THERM_STATUS = 0x19c There is bunch of output in this line I just capture the hex value as a string.$MSRstring0x19c = ((cmd /c C:\ProgramData\PCM\pcm-msr.exe 0x19c 2>1 $null ) -match “Read Value”).split(" ")[3]

Next that string $MSRstring0x19c is still a string so

[uint32]$MSRstring

makes it a Uint32

My biggest headache, how do I use this enum object ?

foreach ($i in [Enum]::GetValues(‘General_Flag_IA32_THERM_STATUS’)) {
if ([uint32]$MSRstring0x19c -band $i.value__ ) {write-host “$i : 1”} else {write-host "$i : 0 "}
}

Ok took me a while to get this, we loop through the enum table, asking if on every line the bit-value is present in the number we are checking.

So when I supply hex value : 0x882d2000 the loop shows me which bits are present :

THERMAL_STATUS : 0
THERMAL_STATUS_LOG : 0
PROCHOT_OR_FORCEPR_EVENT : 0
PROCHOT_OR_FORCEPR_LOG : 0
CRITICAL_TEMPERATURE_STATUS : 0
CRITICAL_TEMPERATURE_LOG : 0
THERMAL_THRESHOLD_1_STATUS : 0
THERMAL_THRESHOLD_1_LOG : 0
THERMAL_THRESHOLD_2_STATUS : 0
THERMAL_THRESHOLD_2_LOG : 0
POWER_LIMIT_NOTIFICATION_STATUS : 0
POWER_LIMIT_NOTIFICATION_LOG : 0
CURRENT_LIMIT_STATUS : 0
CURRENT_LIMIT_LOG : 1
CROSS_DOMAIN_LIMIT_STATUS : 0
CROSS_DOMAIN_LIMIT_LOG : 0
READING_VALID : 1

The only thing left to do is extract the temp fields out of the IA32_THERM_STATUS.

they are at positions 22:16 (Digital Readout ) and 30:27 (Resolution in Dgrees cel.).

extract the hex values, convert to a temperature reading, and display. No idea on how do this this part.

Wow interested in Intel MSR CPU registers, this person built a very cool utility for Linux. wish this could ported to Powershell

https://github.com/kzawad1/intel-reg-pp

Really sorry for the post being hidden. Those were considered as spam, probably because of the way how the code was formatted. The best way to format code in the forums is mentioned in below post

https://powershell.org/forums/topic/read-me-before-posting-youll-be-glad-you-did/