PowerMonkey - Undervolting UEFI Tool (for Hyper-V users, etc.)

Discussion in 'Hardware Components and Aftermarket Upgrades' started by psyq321, Sep 12, 2021.

  1. psyq321

    psyq321 Notebook Evangelist

    Reputations:
    210
    Messages:
    420
    Likes Received:
    16
    Trophy Points:
    31
    I was quite annoyed when new Windows features using Hyper-V broke ThrottleStop (WSL2/WSLG).

    Since I do not expect Microsoft to allow MSR poking from HV guests, I wrote a small UEFI tool called PowerMonkey, which performs programming of CPU voltage/frequency overrides, power limits, etc. Also, more features using HV are coming (Android Studio is using it already, mandatory for WSLG, etc.) so this issue needs a solution.

    Get PowerMonkey from here: https://github.com/psyq321/PowerMonkey

    Important Notes

    1. This is not a replacement for ThrottleStop - it is a tool that applies settings once known
    2. Proof-of-Concept state: recommended for experts only
    3. Due to UEFI hideously limited environment, all settings are in CONFIGURATION.c file
    4. Source-code only due to #2 - you must edit the configuration and build your own PowerMonkey.efi
    5. No feature availability testing, so please be careful: some unsupported features might hang the system
    6. Tested only on handful Comet Lake CPUs (I will test RKL and TGL soon)
    7. No support due to POC stage
    8. Bricking potential! Please make sure you understand what you are doing before attempting!!!

    Supported Features

    * V/F Overrides Programming: Voltage (Offset/Override), Frequency (Ratio)
    * Individual V/F Curve Point Overrides (Voltage offset for each point, when supported by CPU)
    * IccMax Adjustment for each voltage domain (via OC Mailbox, supported SKUs only)
    * Power Limits Adjustments (Package PL1/PL2/PL3/PL4, Platform PL1/2/3/4, PP0; MSR and MMIO)
    * Power Control Knobs (Race-to-Halt, Energy Efficient Turbo)
    * Turbo Bins (partial for now, only setting of single value for all turbo configurations)
    * Lockdown (OC Lock, Power Limit Locks)

    How does it work?

    PowerMonkey.efi works as "Transient Bootloader" (TSL) and performs configuration before OS is loaded and just before UEFI firmware transitions from "Boot Services" to "Runtime" (OS) phase. This way, we avoid the problem of locked MSRs and also we can use locking to prevent any other software including OS itself from touching our config. Here is the visual representation of the boot flow with Hypervisor ON:

    pmbootflow.png


    How to use

    1. Go to https://github.com/psyq321/PowerMonkey
    2. Clone the repo
    3. Study README.MD
     
    Last edited: Sep 12, 2021
    4W4K3, Vasudev, downloads and 4 others like this.
  2. psyq321

    psyq321 Notebook Evangelist

    Reputations:
    210
    Messages:
    420
    Likes Received:
    16
    Trophy Points:
    31
    I just added support for IccMax adjustment as well (via OC Mailbox)
     
    Vasudev and tilleroftheearth like this.
  3. Vasudev

    Vasudev Notebook Nobel Laureate

    Reputations:
    11,655
    Messages:
    11,199
    Likes Received:
    8,693
    Trophy Points:
    931
    Can it unlock voltage offsets if OEM/vendors have disabled access through latest uCodes?
    Will be a must-have tool when I try out WSL2. Loss of undervolt and slower performance made me take a route of install Linux side by side but I removed it after being frustrated with nvidia display driver.
     
  4. psyq321

    psyq321 Notebook Evangelist

    Reputations:
    210
    Messages:
    420
    Likes Received:
    16
    Trophy Points:
    31
    Actually, uCode (microcode) has nothing to do with it.

    What happened is, after the discovery of INTEL-SA-00289, Intel increased the security of the platform Reference Code / Firmware Support Package (FSP) by locking out voltage modification after BIOS initialization by default. This is actually how it should be! Good security design prevents these kind of modifications w/o user consent. For us (advanced users) this would be also OK provided that OEM, of course, allows end-user to unlock this at their will.

    Unfortunately, in many cases, this is NOT what happened. Many notebooks have no interface allowing CFG lock/unlock in their Setup UI (leave alone voltage control or OC), so many users ended up simply without undervolting - feature effectively removed :(

    There is a separate issue of Intel XTU completely disabling undervolting modifications - but this has nothing to do with the above, it is Intel's decision and it is hardcoded in XTU.

    So, personally, I would not blame Intel - having firmware CFG unlocked without user knowledge >is< dangerous. I just need to be able to poke MSR 0x150 to do all kinds of damage - all miscreants need is either root access or some vulnerable driver/system component. It did not help that the damage could affect SGX code (which, by the way, is a ridiculous argument against undervolting for the end-user systems). That had the effect to damage Intel's standing in enterprise markets so.. yeah, UV by default had to go :(

    Since then, Intel silently de-featured client CPUs removing SGX and added more proactive checks in SGX so hopefully UV itself is not such a big deal anymore.

    --

    This is the history, now how to fix it?

    Your system needs to be "CFG unlocked" and "OC unlocked" in order to be able to fiddle with the OC Mailbox (MSR 0x150).

    The main effect of Intel's update to FSP and reference code is "Locked-by-Default" BIOS - you cannot touch OC Mailbox for V/F overriding without unlocking this first.

    How to do it:

    1. Easy way: go to BIOS setup, advanced menu, do it there --> yeah, we know, this is not possible
    2. Medium way: dump UEFI, extract setup binary, extract IFR and find the following:

    Code:
    CFG Lock, VarStoreInfo (VarOffset/VarName): [b]0xXX[/b], VarStore: [b]0xY[/b], QuestionId: 0xDoesNotMatter, Size: 1, Min: 0x0, Max 0x1
    Overclocking Lock, VarStoreInfo (VarOffset/VarName): [b]0xZZ[/b], VarStore: [b]0xW[/b], QuestionId: 0xDoesNotMatter, Size: 1, Min: 0x0, Max 0x1
    
    Then, find the var store name for 0xY and 0xW (typically 'CpuSetup') and finally, modify those NVRAM variables e.g with modified GRUB, ChipSec or RU, here using CpuSetup as example and GRUB:

    Code:
    setup_var CpuSetup 0xXX 0x0
    setup_var CpuSetup 0xZZ 0x0
    
    Reboot, and you're done - after this, your firmware is CFG/OC unlocked and you can modify things, use OC mailbox, etc.

    My advice is to re-lock it again using ThrottleStop / PowerMonkey options again so after undervolting nobody else could reprogram your CPU voltage.

    ---

    3. Hard way: If your firmware is so locked even 2. is impossible, options become progressively harder at this point: Hardware firmware flashing (with chip programming) with possible SoC replacement (you need PCH with unfused OEM key if BootGuard is enabled which, it probably is - in this case) or good-old hacking, which would somehow enable you to get CPU to warm reset and load patched firmware (and doing this is well beyond this tutorial).

    Hope it helps.
     
    Vasudev likes this.
  5. Vasudev

    Vasudev Notebook Nobel Laureate

    Reputations:
    11,655
    Messages:
    11,199
    Likes Received:
    8,693
    Trophy Points:
    931
    Thanks.
    I tried that MSR OC mailbox and unlocked BIOS long time ago and PC was soft bricked and had to use SPI programer to flash stock BIOS + MEI FW.
     
  6. psyq321

    psyq321 Notebook Evangelist

    Reputations:
    210
    Messages:
    420
    Likes Received:
    16
    Trophy Points:
    31
    Sorry to hear that.

    You can try running PM without anything but if your FIVR settings are grayed out in ThrottleStop, that means system is CFG/OC locked, so the only way further is to unlock it somehow.

    For really brave: if your laptop vendor did not use "null" OC library (most of the vendors get FSP as binary, so this should NOT be the case) you can actually program undervolting directly using NVRAM method.

    This is very risky if there is no easy method to erase those settings, so please be careful.

    Example (addresses are only for my system - they vary!):

    Code:
    Core Voltage Offset, VarStoreInfo (VarOffset/VarName): 0x1BD, VarStore: 0x3, QuestionId: 0x1EC, Size: 2, Min: 0x0, Max 0x3E8, Step: 0x1
    
    Offset Prefix, VarStoreInfo (VarOffset/VarName): 0x1BF, VarStore: 0x3
        One Of Option: +, Value (8 bit): 0x0 (default)
        One Of Option: -, Value (8 bit): 0x1
    
    So, by setting 0x1BF to 0x1 and 0x1BD-0x1BE (16-bits) to the right voltage - we configured the override.

    0x1BD - 0x1BE is 16-bit integer in little endian, storing voltage offset in mV.

    So undervolting -125mv means undervolting with offset prefix -; value 0x7D (125 decimal) - which shall be stored as:

    Value: 7D00 (which is little endian for 0x007D)

    [0x1BD] 0x7D
    [0x1BE] 0x00

    Again, 0x1BD/0x1BE and 0x1BF are specific to my system - you need to check the IFR of setup executable for yours.

    --

    However, if the BIOS has NULL OC lib, it will just ignore these values. Also, if you put too much it is not predictable how it will behave. Normally it shall trigger WDT (watchdog timer) and BIOS should revert to safe values - but since the platform is not designed for OC, it might end up being unusable.
     
    Vasudev likes this.
Loading...

Share This Page