Parsing Bit flag data from Intel CPU MSR registers.

Welcome Forums General PowerShell Q&A Parsing Bit flag data from Intel CPU MSR registers.

Viewing 4 reply threads
  • Author
    Posts
    • #178215
      Participant
      Topics: 3
      Replies: 5
      Points: 59
      Rank: Member

      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.
      IA32_THERM_STATUS

      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 : https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/managing-bit-flags-part-1

      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.

      bit table

      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 ?

    • #179439
      Participant
      Topics: 3
      Replies: 5
      Points: 59
      Rank: Member

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

    • #179454
      Participant
      Topics: 3
      Replies: 5
      Points: 59
      Rank: Member

      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.

    • #179559
      Participant
      Topics: 3
      Replies: 5
      Points: 59
      Rank: Member

      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

    • #179577
      Senior Moderator
      Topics: 8
      Replies: 1155
      Points: 4,019
      Helping Hand
      Rank: Community Hero

      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/

Viewing 4 reply threads
  • The topic ‘Parsing Bit flag data from Intel CPU MSR registers.’ is closed to new replies.