cocafe / msr-utility

Little CLI utility to control Model Specific Registers (MSRs) on Windows via WinRing0 driver, 64+ cores supported
73 stars 11 forks source link

Request: MMIO adjustments #2

Open Hyatice opened 2 years ago

Hyatice commented 2 years ago

Hi!

I'm not sure how possible this is, but with Windows cracking down on RWE, it would be nice to have a reliable tool to adjust MMIO values as well as MSR values.

A few of the things that I previously had to use RWE for:

PL1 and PL2 - these are written in multiple places, and depending on the manufacturer MSR-CMD is enough, though certain programs will still report the power limit as what is set in MMIO/BIOS.

GPU Max Clock Speed - these are written exclusively in MMIO, and are incredibly important for maximizing battery life for handheld/portable computers.

Thanks for any consideration and time you put into this.

cocafe commented 2 years ago

Hello,

PL1 and PL2 - these are written in multiple places, and depending on the manufacturer MSR-CMD is enough, though certain programs will still report the power limit as what is set in MMIO/BIOS.

Sure, definitely will give a try.

Actually I just brought a i9-19200H tablet few months ago, MMIO PL1/PL2 is exactly what I'm planning to experiment in next few days, since my full-time job is finishing soon.

But there may have some obstacles, I have googled a bit, it seems that we lack of opensource libs that can read/write mmio.

I found WinIO, but it is a legacy lib without proper signed driver, which means, windows had to run in debug mode (a debug string will appear at desktop) or disabling driver signing (not sure it still can be disabled on Win10/11). Anyway, will give it a try.

BTW, seems I can read/write address 0xfed15900 which describes on web and gen10/11 datasheet in RWE on my surface pro 7 (gen10 i5), but had no luck on i9-12900H, all FFFFFFFF displayed, not sure it's caused by OS or gen12 platform. Really appreciate it if you can share some more information about PL1/PL2. (Late night now, gonna google more or maybe try to disassemble ThrottleStop later...)

GPU Max Clock Speed - these are written exclusively in MMIO, and are incredibly important for maximizing battery life for handheld/portable computers.

It is Nvidia cards related? I'm interested too, googled but did not help. 👻

Hyatice commented 2 years ago

For what it's worth, it sounds like the Windows Debug Kit may have a semi-open-source method to modify MMIO/MSR that you could look into with rdmsr, wrmsr and devcon. From my super quick investigation into it, devcon.exe can run standalone without having to install the rest of the devkit.

I am at work currently, but I can definitely share all of my currently-used MSR-CMD and RW commands with some documentation on what they are/what portions of the keys do what. Granted, this is on intel 11th gen and below - I have not tested on 12th gen at all yet.

As for the GPU clocks, no this is actually for intel Xe. Surprisingly powerful, able to run new AAA games at 720p/medium-low settings, but has some exponential power draw at higher clock speeds and really likes to stretch its legs.

Control/God of War for example can run at 45 FPS using 1100Mhz at around 8-9W GPU power draw, but if you don't limit, it will use 1300Mhz-1400Mhz (depending on your chip) 14-19W and still only hit around 45 FPS.

ciphray commented 2 years ago

you can read the offset via rweverything via the following command rpci32 0 0 0 0x48

image

intel does have it documented, can also view it in cpuz

ciphray commented 2 years ago

image

output would look like this with tigerlake

which would mean writing to 0xfedc59a0 and 0xfedc59a4 to change pl1 and pl2 with tigerlake

image

cocafe commented 2 years ago

@Hyatice @ciphray

Really helpful info, thank you very much 👍

Here is a screenshot took on alder lake:

image

ciphray commented 2 years ago

https://github.com/namazso/physmem_drivers

think you'd get anywhere with any of these drivers?

the hwrwdrv seems to be used with a program similar to rweverything

https://github.com/Faintsnow/HE

unfortunately this one doesn't seem to accept external command line inputs

and the last one in the list the evga driver is used on one of my desktops to change tdp in mmio

cocafe commented 2 years ago

asmmap64.sys seems could be used.

I found some sample code:

https://github.com/branw/DonkeyKom/blob/3a7b90fc5d7ecf74e511e92da2e93baa148cf685/DonkeyKom/dk/driver.cpp#L110

gonna try it tomorrow

cocafe commented 2 years ago

@Hyatice just a quick report here, seems that it just worked. 👻

image

wkgcass commented 2 years ago

Hi, @ciphray I'm writing a program to adjust power limits. I saw your comment and I have two questions.

1

You use rw rpci32 0 0 0 0x48 to retrieve the MCHBAR. However the Intel doc says the MCHBAR base address register is a 64bits register. How does the rpci32 command read the 64bits data. How the data is cut so that we can use the result as an address, is this behavior documented somewhere?

2

The result of rpci command is 0xFEDC0001, and the doc says power limit is at offset 59A0H, why using using address 0xFDC59A0 instead of 0xFEDC0001 + 0x59A0 = 0xFEDC59A1?

I tried these commands and addresses, and they seem to be correct, but I still want to figure out what I'm missing.
Thanks in advance.

cocafe commented 2 years ago

Hi, @ciphray I'm writing a program to adjust power limits. I saw your comment and I have two questions.

1

You use rw rpci32 0 0 0 0x48 to retrieve the MCHBAR. However the Intel doc says the MCHBAR base address register is a 64bits register. How does the rpci32 command read the 64bits data. How the data is cut so that we can use the result as an address, is this behavior documented somewhere?

2

The result of rpci command is 0xFEDC0001, and the doc says power limit is at offset 59A0H, why using using address 0xFDC59A0 instead of 0xFEDC0001 + 0x59A0 = 0xFEDC59A1?

I tried these commands and addresses, and they seem to be correct, but I still want to figure out what I'm missing. Thanks in advance.

For question 2, address should be 4 aligned, aka, 0xFEDC0000 + 0x59A0.

The contents read from 0xFEDC0000 + 0x59A0 is exactly what ThrottleStop displayed.

wkgcass commented 2 years ago

@cocafe Thank you! Big help!

cocafe commented 2 years ago

@cocafe Thank you! Big help!

😉

cocafe commented 2 years ago

@Hyatice https://github.com/cocafe/physmem

Hyatice commented 2 years ago

@cocafe Thank you! I can't wait to give it a shot. And Thanks @ciphray for providing waaay more information than I have available to me.. I just know how I use the tool, not how the tool worked. :)

T-Troll commented 1 year ago

@Hyatice you can return RWE back into play - open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CI\Config, add/change DWORD VulnerableDriverBlocklistEnable with value 0, reboot.