News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How to read a Model-Specific Register?

Started by SAK, January 25, 2007, 08:51:04 AM

Previous topic - Next topic

SAK

I need to read the value of a MSR on an Intel Conroe (Core 2 Duo) CPU.  After smacking my head against the wall for two days I think I have come to the conclusion that it has to be done with some in-line assembly code inserted into my C++ application.  Unfortunately, I have prectically no experience with asm and am hoping for some assistance with a few questions:

1)  Is assembly truly the only way to access a MSR?
2)  If so, is reading the value of the MSR and passing it back to my C++ application a difficult task to code?
3)  If not, could anyone throw me a bone and help point me in the right direction?

While flailing around for a solution I did learn about the instruction "rdmsr" documented in http://www.cs.inf.ethz.ch/stricker/lab/doc/intel-part1.pdf and it looks like it would do exactly what I want.  However, I tried using it but I believe I am hitting a protected mode exception because my code isn't running at privilege level 0 and I don't think running at level 0 is an option.

From what (very) little I know, it seems like directly reading a register would be about as simple a task as you can get in assembly but at this point I may as well try to speak Swahili.  If it helps any, I am trying to read the register at address 19CH hex (412 decimal).

Thanks in advance for your patience and any assistance you can provide...

Steve

hutch--

SAK,

What you need to find out is the privelege level required to access the instruction. If its ring0 you will need to write a driver for it that is specific to the OS version you are running.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

SAK

Thank you for responding Hutch, I appreciate it.  Since the rdmsr instruction must be run in Ring0, I have blundered into the same conclusion and I was just reading about writing device drivers at OSROnline.  Would the idea basically be to write an ultra-simple driver with a function that invokes the rdmsr instruction and returns the information to a calling application?  Is it really that simple?

Thanks again for taking the time to help!

Steve

uziq

I know bumping old threads is frowned upon, but this topic is exactly what I'm trying to do: read MSR 19CH (412 dec) - IA32_THERM_STATUS. My end goal is to get the CPU temperature. I'm assuming reading that register (via RDMSR) is the way to do it, unless someone has a better idea?

Does anyone have any advice on creating the driver? Is there a simple MASM example that I could easily modify?

I'm guessing I need a 64-bit driver since I use 64-bit. I've downloaded the WDK and browsed around but it's a bit over my head.

hutch--

uzig,

I think you are in trouble there, you will need 64 bit drivers for a 64 bit OS version and from memory they must be digitally signed to run in 64 bit. Is there an existing system driver that will do what you are after ?
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

uziq

There may be a driver available.. I'm not entirely sure. The signing issue can be overcome by disabling signed driver enforcement; F8 each boot, or via this command: bcdedit /set loadoptions DDISABLE_INTEGRITY_CHECKS

It's not ideal, but it works. Anyway, I'm just exploring the possiblity of coding/compiling this myself. It seems odd that it's so difficult to read the CPU temp.

sinsi

If you are trying to get an intel cpu's temperature, you are in for a battle (something about tjunction? or tdelta?).
They finally released some info, but it only applied to core2 cpu's.  ::)

edit: I think that cpuz has a dll api you can use. There is also winio but I think it's for 32-bit.
Light travels faster than sound, that's why some people seem bright until you hear them.

uziq

Reading the register seems to be the hardest part since it requires a driver. The math/logic looks to be fairly straight-forward.

This link explains it a bit:
http://www.alcpu.com/CoreTemp/howitworks.html

I'll have to look into the various CPU monitoring progs to see what their redistribution rules are, since I may eventually want to share it with others (non-profit).

ChillyWilly

i never tried using the dll in my app from http://www.alcpu.com/CoreTemp/main_data/GetCoreTempInfo.zip , even though they include the .lib im not sure if i can use in my project

this what i have so far:
invoke LoadLibrary,CTEXT("GetCoreTempInfo.dll")
.if eax==NULL
invoke MessageBox,hWin,CTEXT("no worky"),CTEXT("Fail."),0
.else
invoke MessageBox,hWin,CTEXT("it worked."),CTEXT("yay!"),0
invoke GetProcAddress, eax,CTEXT("fnGetCoreTempInfo")
mov GetCoreTempInfo, eax
.endif

how do i call the rest to get the cpu temp etc

qWord

Quote from: ChillyWilly on September 26, 2009, 10:53:52 PM
how do i call the rest to get the cpu temp etc
It seems like it only works if the program "Core Temp.exe" runs. If it runs (some time it crash!) the temperatures are the same as shown in the program it self ("Core Temp.exe"). Here is my try:

include masm32rt.inc

CORE_TEMP_SHARED_DATA struct
    uiLoad          DWORD 256 dup (?)
    uiTjMax         DWORD 128 dup (?)
    uiCoreCnt       DWORD ?
    uiCPUCnt        DWORD ?
    fTemp           REAL4 256 dup (?)
    fVID            REAL4 ?
    fCPUSpeed       REAL4 ?
    fFSBSpeed       REAL4 ?
    fMultipier      REAL4 ?
    sCPUName        BYTE  100 dup (?)
    ucFahrenheit    BYTE ?
    ucDeltaToTjMax  BYTE ?
CORE_TEMP_SHARED_DATA ends

prc1 typedef PROTO  C :DWORD
pfnGetCoreTempInfo typedef ptr prc1

.data?
    hMod                dd ?
    hFileMap            dd ?
    fnGetCoreTempInfo   pfnGetCoreTempInfo ?
    core0               real4 ?
.code
start:
    mov hMod,rv(LoadLibrary,"GetCoreTempInfo.dll")
    mov fnGetCoreTempInfo,rv(GetProcAddress,hMod,"fnGetCoreTempInfo")
   
    mov hFileMap,rv(CreateFileMapping,-1,0,PAGE_READWRITE or SEC_COMMIT,0,SIZEOF CORE_TEMP_SHARED_DATA,"CoreTempMappingObject")
    invoke MapViewOfFile,hFileMap,FILE_MAP_WRITE or FILE_MAP_READ,0,0,SIZEOF CORE_TEMP_SHARED_DATA
    push eax
        invoke fnGetCoreTempInfo,eax
        mov eax,DWORD ptr [esp]
        assume eax: ptr CORE_TEMP_SHARED_DATA
        m2m core0,[eax].fTemp
        fn MessageBox,0,real4$(core0),"core0",MB_OK
    pop eax

    invoke UnmapViewOfFile,eax
    invoke CloseHandle,hFileMap
    invoke ExitProcess,0
end start
FPU in a trice: SmplMath
It's that simple!