UEFI Application for CPU Voltage/Frquency and Power Management adjustment. Great for undervolting.

Overview

Reduce CPU Power Waste and Gain Performance. Greener and Meaner!

   ______                            ______                 _
  (_____ \                          |  ___ \               | |
   _____) )___   _ _ _   ____   ___ | | _ | |  ___   ____  | |  _  ____  _   _
  |  ____// _ \ | | | | / _  ) / __)| || || | / _ \ |  _ \ | | / )/ _  )| | | |
  | |    | |_| || | | |( (/ / | |   | || || || |_| || | | || |< (( (/ / | |_| |
  |_|     \___/  \____| \____)|_|   |_||_||_| \___/ |_| |_||_| \_)\____) \__  |
                                                                        (____/
  Copyright (C) 2021 Ivan Dimkovic. All rights reserved.
  
  WARNING: This code is a proof of concept for educative purposes. It can
  modify internal computer configuration parameters and cause malfunctions or
  even permanent damage. It has been tested on a limited range of target CPUs
  and has minimal built-in failsafe mechanisms, thus making it unsuitable for
  recommended use by users not skilled in the art. Use it at your own risk.

What is PowerMonkey?

Background

By the 2020s, everybody knows what 'overclocking' is: bringing the system to its limits by increasing its working frequency, voltage or both. This process used to be very error-prone but it got perfected in the meantime, with even some big-name systems coming “factory overclocked” out of the box.

However, much fewer people have heard about its cousin: undervolting. Undervolting is, in a way, an opposite process from overclocking: reducing CPU voltage to the point, CPU consumes much less power and generates way less heat.

Intriguingly, doing this to the thermally limited system such as a notebook or SFF (small form factor) PC will both reduce heat AND improve performance! Magic? No, physics! There is only so much heat a notebook cooling system can evacuate, and once this route becomes exhausted, there is no other option but to throttle the CPU to prevent catastrophic failure. Reducing voltage at high frequencies significantly decreases power and heat output thus making the system cooler and faster.

Challenges

Sadly, it has become increasingly difficult to optimize a typical notebook. First, undervolting became mostly locked-by-default by OEMs. This problem can be mitigated by “unlocking” the firmware settings so that excellent applications like ThrottleStop can do their job (unless the platform is fully locked).

But new problems are in sight: Hypervisors such as Microsoft Hyper-V are now used even by end-user applications like WSL2 (Windows Subsystem for Linux). Because Hypervisor does not allow a Virtual Machine to modify most of the host hardware registers, applications like ThrottleStop or Intel’s XTU cannot adjust voltages.

When application attempts to write to a hardware register, Hypervisor traps this attempt and does not perform the actual writing. It is heoretically possible that Hypervisor vendor implements writing, but highly unlikely. This has created new barriers for undervolting and similar types of hardware tweaks.

Nothing above would be a problem if OEMs allowed customers to adjust the settings in the firmware setup. However, most notebooks come with minimal configuration options, locking the owner of being able to adjust their hardware. PowerMonkey POC intends to fix precisely this problem, and this repository is the first “proof-of-concept” showing viability of such an approach.

How does PowerMonkey work?

This proof-of-concept is using ability of UEFI firmwares to execute so-called "applications" before OS bootoader is invoked. At that moment (providing that the firmware did not lock) it is possible to (almost) fully adjust CPU frequency and voltages as well as power management configuration. This is later in the boot process (see below) as opposed to how OEM would do it, but since "advanced setup" is not an option, this is actually the second best place.

NOTE: PowerMonkey is fully usable only with systems using S0iX ("Connected Standby" / "Modern Standby" / "S0 Standby") modes. Systems using legacy S3 sleep will revert to the platform-hardcoded settings upon resuming from S3 sleep. Since UEFI DXE drivers/applications are not reloaded during S3 resume flow, no overrides could be applied before Hypervisor resumes.

Below picture explains where PowerMonkey.efi POC resides:

EfiGood

Who is the target user of PowerMonkey?

PowerMonkey.efi is currently proof-of-concept for expert users who have systems that do not allow Voltage/Frequency override configuration in their firmware setup modules, yet firmware is either OC/CFG unlocked or can be made so by some means (e.g. NVRAM EFI variable editing). Primary purpose of PowerMonkey.efi is to allow V/F overrides on such systems when usage of Hypervisor is also desired.

Enabled Features

NOTE: PowerMonkey is a POC and is not tested on anything other than few CML (10th Gen) systems. At this stage, usage is recommended only to developers and experts under precautions. There are no checks for CPU compatibility so crashes could occur. It can brick computers or cause them to fail in all kinds of ways!

Feature Configurable
Voltage / Frequency Overrides
Voltage Override for entire VF Curve YES
Targetted voltage mode YES
Interpolative voltage mode YES
Voltage offset YES
Voltage adjustment on individual VF Curve Points YES (Preview)
IccMax
Programmable IccMax for all domains (OC Mailbox) YES
RKL/TGL/ICL+ Unlimited IccMax TBD
Turbo Bins
Max. Turbo Ratio for all turbo configurations YES
Invididual (per # cores) turbo ratio configuration TBD
Power Limits
Enable/Disable/Lock PL1/PL2/PL3/PL4/PP0/... YES
Power and Time Limits adjustment (where possible) YES
Package and Platform (PSys) Domains YES
MSR and MMIO Control YES
Power Control
Race to Halt YES
Energy Efficient Turbo YES
Lockdown
Optional Overclocking Lockdown YES
Fine-grained Lockdown of different Power registers YES
Stability Testing
After-programming Stress Tester TBD

Getting Started

Configuration

All relevant configuration options are stored in the file CONFIGURATION.c where the entire configuration interface and options reside. Configuration process is exactly the same for all build methods and does not depend on the choice of build toolchain. Simply edit CONFIGURATION.c with your overrides and build the PowerMonkey.efi executable afterwards!

Note: this guide is not 'Undervolting HowTo' - it is assumed you already know the optimal settings for your system. If not, please check some of the excellent guides like ThrottleStop guide or Guide on NotebookReview Forums

Build the binaries

Because PowerMonkey is in the "proof-of-concept" stage right now. It is also necessary to adjust the CPU voltage/frequency/power override parameters to match your CPU. It is essential to build PowerMonkey from the source code.

  1. Clone PowerMoneky repository (this repository)

  2. Decide if you want to build PowerMonkey.efi using 'official' UEFI EDK (TianoCore), or if you wish to handle everything in Visual Studio?

Building - "Visual Studio" route:

This route is based on Alex Ionescu's excellent VisualUEFI project. The advantage of this approach is that you do not need to deal with the EDK2 build system and its config files.

  1. Fetch VisualUEFI from https://github.com/ionescu007/VisualUefi and build its prerequisites (follow the instructions)

  2. Store PowerMonkey directory (and its subdirectories) directly in the root of the cloned VisualUEFI repo:

    VisualUEFI
    ├── debugger/
    ├── EDK-II/
    ├── edk2/
    ├── openssl/
    ├── PowerMonkey/                           <––– Our Workspace
    │   ├── PowerMonkeyApp/                    <--- Source code
    │   │   ├── CONFIGURATION.c                <--- This is where settings are
    │   │   └── ...
    │   ├── LICENSE
    │   ├── PmWorkspace.default.props
    │   ├── PmWorkspace.props
    │   ├── PmWorksspace.sln                   <--- Visual Studio Solution File
    │   └── README.MD
    ├── Samples/
    └── ...
  3. Open PmWorkspace.sln and build the project directly in Visual Studio. This process shall generate no warnings or errors. The result should be an EFI executable /PowerMonkey/x64/Release/PowerMonkey.efi

Building - EDK2 route:

  1. Download EDK2 source from https://github.com/tianocore/edk2 - ideally, the EDK2 version shall match your computer firmware “baseline EDK2 version” in case your UEFI firmware is based on TianoCore.

  2. Store PowerMonkeyApp directory (and its subdirectories) in the /MdeModulePkg/Application subdirectory of EDK2 workspace. The result shall look something like this (there will be more directories):

    EDK
    ├── BaseTools/
    ├── Conf/
    ├── MdeModulePkg/
    │   ├── Application/
    │   │   ├── BootManagerMenuApp/
    │   │   ├── CapsuleApp/
    │   │   ├── PowerMonkeyApp/         <––– Our Project
    │   │   │   ├── CONFIGURATION.c     <--- This is where settings are
    │   │   │   └── ...
    │   │   └── UiApp/
    │   ├── Include/
    │   └── Library/
    ├── UefiCpuPkg/
    ├── edksetup.bat
    └── ...
  3. Edit the /MdeModulePkg/MdeModulePkg.dsc file, and add PowerMonkey project inside:

    [Components]
    MdeModulePkg/Application/PowerMonkeyApp/PowerMonkey.inf
  4. Building process that follows is identical as for any other EDK2 project (edksetup.bat, build, ...).

Deployment

The easiest way, and the recommended route during testing is to copy PowerMonkey.efi to your EFI system partition and test it from UEFI shell. Once you are sure the settings work and are stable, you can add PowerMonkey.efi to the UEFI boot manager and set it to load first, before the OS bootloader (if supported by youur platform firmware). If direct loading by firmware is not possible, you can use boot manager scripting to load before OS bootloader.

Testing

In order to prevent reboot-loops it is highly advisable to first test PowerMonkey.efi by loading it from EFI shell or from a separate Booltloader entry (such as GRUB2). This way it is easy to revert back to original settings.

PowerMonkey.efi shall be executed before OS Bootloader. This can be achieved in many ways, the most obvious and least automated would be invocation through EFI shell. Executing PowerMonkey.efi shall result in something like this:

In case of failure, you will probably either see a crash information or a frozen computer. If everything worked, the view from the EFI shell should look like this:

EfiGood

Emergency Exit

PowerMonkey has an "Emergency Exit" feature enabled by default: it waits 3 seconds before programming starts allowing user to press ESC key to abort programming. This option is useful when PowerMonkey.efi is installed as Transient Boot Loader - executing before OS bootloader. If ESC key is pressed, CPU is not programmed and the response looks like this:

Aborted

If the computer is still alive and not frozen, you might proceed to your OS of choice to confirm that the settings have been applied. Do not forget to disable Hypervisor first, as one enabled, you will not be able to actually see the voltages from a VM. Settingfs form the CONFIGURATION.c applied to my CPU result in the following (pictures of ThrottleStop and XTU just reading the values from the CPU):

Intel XTU:

EfiGood

ThrottleStop:

EfiGood

This confirms that our settings have been applied including the locks (we locked the configuration so that it cannot be changed until the next reset). Before we go further, we shall check how much of a performance impact this has on our system.

Cinebench R23

Cinebench is one of the quickest showcases of how effective undervolting can be. Its workload is CPU-heavy, solving a real-world problem (rendering) and not some artificial stressor designed solely to waste CPU cycles in a way no actual application would do. As a bonus, Cinebench results immediately show if PowerMonkey settings were applied or not.

Without further ado, the results:

cinebench

TL;DR - By setting few knobs and dropping the voltage by 125 mV, we just made the laptop 23% faster. We did not "overclock" anything (although we did remove boost limits), CPU's own power management circuitry did it for us!

Things become even more interesting if one logs the data and checks what has CPU been doing while running Cinebench benchmark:

DESCRIPTION FACTORY SETTINGS POWERMONKEY -125mV
Cinebench R23 (Multi Core) 8299 10219 (+23.1%)
Avg. all-core clock in test 3.35 GHz 3.99 GHz (+19.1%)
Total energy spent during test 1.35 (Rel) 1.0 (Rel)

So, we gained 0.64 GHz in sustained 100% load, all while becoming 35% more energy efficient! Like like an advertisement, but this IS what is going on* 😊

(*) OK, it has to be told that -125 mV is considered a very aggressive undervolt for an average Comet Lake H CPU specimen. Mine seems happy, but there is much more to this story that I will cover some other time. For now, let me state that observation has led me to believe that it is something else that makes these settings reported not stable, and that problem already has a fix (albeit just for fully unlocked 'OC' models atm.).

THis particular CML-H model could theoretically sustain 4.2 GHz all-core load, as this is what it has been fused with as maximum. Looking at ThrottleStop logs it shows that now we are thermally limited. This particular laptop does look like it could benefit from re-pasting so maybe sustaining 4.2 GHz is doable.

But... HOW?

Extra 650 MHz and energy saved? Where is the catch?

There is no catch, just laws of physics. Notebook CPU is encased inside the scorching environment that cannot evacuate heat as effectively as, say, a server could.

Just looking at the dimensions of notebook parts (esp. the thermal solution,) it becomes apparent that we will not be pushing out hundreds of watts out of that space. The test system used here can deal with ~100-110W (internal measurements), if you are OK with your computer sounding like a jet engine. So this is our limit, but reasonable people would dial that down to 70-80W if they value their hearing.

CPU usually gets part of that budget (sometimes dynamic), so it would typically get 45-60W. And then, its power management circuit has to stay within these bounds with some well-defined and very short-term exceptions.

If we stayed with the original voltages, the power draw is significantly higher (remember, this is non-linear scaling!). So, the only thing a CPU could do is to dial its frequency down to stay within the power / thermal budget.

Another point is the temperature. When undervolted, the number of times CPU must temporarily freeze its execution to cool down (“throttle”) is much lower or even zero. This also significantly boosts real-world speed.

And that is all to it (complications aside): if you manage to drop CPU power draw, its PMC will thank you with higher operating points.

Moving onto Hyper-V

Now that we know undervolting works as intended, we are ready to switch Hyper-V back and see how much (if anything) we would gain in WSL2 tasks. To be continued. For now, please find very preliminary results testing Linux kernel compilation (Linux kernel is WSL2 + extra config flags and modules):

Things become even more interesting if one logs the data and checks what has CPU been doing while running Cinebench benchmark:

DESCRIPTION FACTORY SETTINGS POWERMONKEY -125mV
WSL2 Custom Linux Kernel Build
Total Build Time 18m18.203s 17m21.769s

Differences are less drastic compared to Cinebench, which is to be expected as Linux kernel build is not so CPU-heavy. Still, it is almost a minute faster and, as originally intended: serves to prove that custom CPU settings are active under Hyper-V.

Comments
  • New error in gcc edk2

    New error in gcc edk2

    Tried the new build getting a new error ubuntu 21.10 gcc 10

    /home/alan/src/edk2/MdeModulePkg/Application/PowerMonkeyApp/DelayX86.c:36: error: ignoring ‘#pragma intrinsic ’ [-Werror=unknown-pragmas]
       36 | #pragma intrinsic(__rdtsc)                // At this point, code will look so
          |
    /home/alan/src/edk2/MdeModulePkg/Application/PowerMonkeyApp/DelayX86.c:37: error: ignoring ‘#pragma intrinsic ’ [-Werror=unknown-pragmas]
       37 | #pragma intrinsic(_mm_pause)              // fugly that writing it in pure SMM
          |
    /home/alan/src/edk2/MdeModulePkg/Application/PowerMonkeyApp/DelayX86.c: In function ‘StallCpu’:
    /home/alan/src/edk2/MdeModulePkg/Application/PowerMonkeyApp/DelayX86.c:110:21: error: implicit declaration of function ‘__rdtsc’ [-Werror=implicit-function-declaration]
      110 |   UINT64 endTicks = __rdtsc() + ticks;
          |                     ^~~~~~~
    
    
    opened by alanpi 13
  • How to troubleshoot PowerMonkey.efi freezing.

    How to troubleshoot PowerMonkey.efi freezing.

    What's the best way to go about troubleshooting a freezing issue while executing PowerMonkey.efi?

    My Core i9-9980HK CPU is stable undervolting with Throtllestop to -125 for both CPU core and cache. Executing PowerMonkey.efi with a configuration of -90 causes a freeze when MSR programming starts. Are there any debug options that can be enabled to troubleshoot the cause of the freeze? The Configuration.c file (built via EDK2) is referenced below.

    /*******************************************************************************
    *  ______                            ______                 _
    * (_____ \                          |  ___ \               | |
    *  _____) )___   _ _ _   ____   ___ | | _ | |  ___   ____  | |  _  ____  _   _
    * |  ____// _ \ | | | | / _  ) / __)| || || | / _ \ |  _ \ | | / )/ _  )| | | |
    * | |    | |_| || | | |( (/ / | |   | || || || |_| || | | || |< (( (/ / | |_| |
    * |_|     \___/  \____| \____)|_|   |_||_||_| \___/ |_| |_||_| \_)\____) \__  |
    *                                                                       (____/
    * Copyright (C) 2021 Ivan Dimkovic. All rights reserved.
    *
    * All trademarks, logos and brand names are the property of their respective
    * owners. All company, product and service names used are for identification
    * purposes only. Use of these names, trademarks and brands does not imply
    * endorsement.
    *
    * SPDX-License-Identifier: Apache-2.0
    * Full text of the license is available in project root directory (LICENSE)
    *
    * WARNING: This code is a proof of concept for educative purposes. It can
    * modify internal computer configuration parameters and cause malfunctions or
    * even permanent damage. It has been tested on a limited range of target CPUs
    * and has minimal built-in failsafe mechanisms, thus making it unsuitable for
    * recommended use by users not skilled in the art. Use it at your own risk.
    *
    *******************************************************************************/
    
    #include "Platform.h"
    
    /*******************************************************************************
     *                   !!! WARNING - ACHTUNG - VNIMANIE !!!
     *     PROCEED IF YOU ARE AN EXPERT ONLY - DO NOT RANDOMLY "PUSH BUTTONS"!
     * 
     * You need to roll-your-own EFI binary by compiling this code. Here are some
     * basic steps to keep in mind before compiling and running:
     *
     * 1.   This POC was tested on mobile CML-H (Comet Lake) CPUs. It >should< work 
     *      on RKL/TGL/ICL, but it was not tested, so YMMV. It could also run on KBL
     *      /CFL and SKL platforms without V/F point overrides, but none of those 
     *      systems are tested as of now.
     *
     *      In any case, you must ensure that the programming (MSRs, etc.) are sane
     *      for your system. What is good for one system is not necessarily working
     *      on other. Settings used here are for example purposes only.
     *
     * 2.   Please review this file, adjust values appropriately (and check MSRs)
     *
     * 3.   Never test on production systems! Please consider using debugging rig 
     *      testing.  While it is not expected to end up with a brick whatever you 
     *      enter, it is always recommended to have either a board with brick-proof 
     *      emergency firmware recovery (that works) OR a hardware flash programmer
     * 
     * 4.   If you plan to use the settings as sticky in production, please make 
     *      sure you tested the system under stress to confirm stability!
     ******************************************************************************/
    
    /*******************************************************************************
     * Global Application Settings
     ******************************************************************************/
    
    ///
    /// Enable / Disable "Emergency Exit"
    /// Enabling this option adds 3 second delay with possibility to abort
    /// by pressing ESC key. Disable it only if you are absolutely sure that your
    /// configuration is stable and you want to save 3 seconds of boot time
    ///
    
    UINT8 gEmergencyExit = 1;
    
    ///
    /// Enable safer hardware probing (default: 1)
    /// If PowerMonkey.efi cannot start but hangs your system, try disabling this 
    /// flag as its mechanism is involving low-level hooking of system interrupts
    /// and could trip some paranoid firmware
    ///
    
    UINT8 gEnableSaferAsm = 1;
    
    ///
    /// Disable UEFI watchdog timer
    /// Will be useful once stress testing is fully implemented 
    /// 
    
    UINT8 gDisableFirwmareWDT = 0;
    
    ///
    /// SELF TEST (STRESS TEST) - MAX RUNS
    /// Set this to a value higher than 0 to enable stress self-testing
    /// Typical values: 0 (no stress testing); 10 (very short); 100+ (longer)
    
    UINT64 gSelfTestMaxRuns = 0; /// DO NOT ENABLE YET (WIP)
    
    /*******************************************************************************
     * ApplyComputerOwnersPolicy()
     * 
     * This is where it is done. With no external config. Party like it's 1979.
     * 
     * NOTE: Voltage offsets are limited to +/- 250 mV. Please see VoltTables.c
     * if you wish to do more dangerous volt-mod, you will need to adapt the code
     ******************************************************************************/
    
    /*******************************************************************************
     * Settings here are for a particular Core i7 10850H (mine) and need to be
     * adjusted for your CPU(s). Please do not just "run" the code but check your
     * values (e.g. run ThrottleStop if you use Windows) and change accordingly.
     * What you see below is an EXAMPLE ONLY.
     ******************************************************************************/
    
    VOID ApplyComputerOwnersPolicy(IN PLATFORM* sys)
    {
      //
      // We will loop through all packages (processor sockets)
      // and override (program) things we like changed.
    
      for (UINTN pidx = 0; pidx < sys->PkgCnt; pidx++) {
        
        PACKAGE* pk = sys->packages + pidx;
    
        /////////////////////////////////////
        /// Voltage / Frequency Overrides ///
        /////////////////////////////////////
    
        //
        // Select which domains are to be programmed
        
        pk->Program_VF_Overrides[IACORE] =    1;    // Enable programming of VF
                                                    // Overrides for IA Cores
    
        pk->Program_VF_Overrides[RING] =      1;    // Enable programming of VF
                                                    // Overrides for Ring / Cache
    
        pk->Program_VF_Overrides[UNCORE] =    0;    // Enable programming of VF
                                                    // Overrides for Uncore (SA)
    
        pk->Program_VF_Overrides[GTSLICE] =   0;    // Enable programming of VF
                                                    // Overrides for GT Slice
    
        pk->Program_VF_Overrides[GTUNSLICE] = 0;    // Enable programming of VF
                                                    // Overrides for GT Unslice
    
        ///
        /// V/F OVERRIDES FOR DOMAIN: CORE
        ///
        
        pk->Domain[IACORE].VoltMode = V_IPOLATIVE;  // V_IPOLATIVE = Interpolate
                                                    // V_OVERRIDE =  Override
    
        pk->Domain[IACORE].TargetVolts =  0;        // in mV (absolute)
        pk->Domain[IACORE].OffsetVolts = -90;      // in mV (negative = undervolt)
    
        ///
        /// V/F OVERRIDES FOR DOMAIN: RING
        ///
    
        // Note: some domains are sharing the same voltage plane! Check yours!
        // 
        // E.g.: for CML-H, IACORE (CPU cores) and RING (cache) share a common VR
        // if you don't program both linked domains to exactly the same voltage, 
        // CPU's pcode will take one (higher, which means less undervolt!) and
        // apply it to both domains - but without adjusting values submitted by the 
        // user so it appears everything went as planned. Some might believe they 
        // won the 'chip lottery' seeing their CPU seemingly undervolt to -250 mV 
        // or smth. while in reality pcode is doing exactly nothing because cache
        // is programmed to 0 mV offset. Don't be that guy (or girl)!
    
        pk->Domain[RING].VoltMode = V_IPOLATIVE;   // V_IPOLATIVE = Interpolate
                                                   // V_OVERRIDE  = Override
    
        pk->Domain[RING].TargetVolts = 0;          // in mV (absolute)
        pk->Domain[RING].OffsetVolts = -90;       // in mV (negative = undervolt)
    
    
        ///
        /// V/F OVERRIDES FOR DOMAIN: SA
        ///
        
        // Add your adjustments here if needed    
    
        ///
        /// V/F OVERRIDES FOR DOMAIN: GT SLICE
        ///
    
        // Add your adjustments here if needed
    
        ///
        /// V/F OVERRIDES FOR DOMAIN: GT UNSLICE
        ///
    
        // Add your adjustments here if needed
    
        ///////////////////////////
        /// V/F Curve Adjustment //
        ///////////////////////////
        
        ///
        /// VF Curve Point (VF Point) Adjustment has been introduced in CML
        /// This feature does not work in older generations. At the moment, only
        /// "OC Unlocked" parts allow adjusting (or even just reading!) of VF
        /// curve points. You can program VF curve here, or use setting of "2"
        /// to just print the current VF curve. There are up to 15 VF points
        /// and you need to probe the CPU to see how many points your has and
        /// what are the frequencies (ratios) of each point.
        /// 
        /// You cannot modify the ratios (they are read-only) and the only allowed
        /// voltage format is "offset mode".
        ///
        /// VF Curve Adjustment is only supported by CORE and RING domains
        /// and for CML and RKL (at least) you must ensure that the same values
        /// are programmed for both domains! (they are sharing the same VR)
    
        pk->Program_VF_Points = 0;                      // 0 - Do not program
                                                        // 1 - Program
                                                        // 2 - Print current values
                                                        //     (2 does not program)
    
        ///
        /// Change to your CPU config!
        /// NOTE: VF Points here are ZERO INDEXED and can go from VP[0] to VP[14] !
        /// 
        /// Uncomment below block (lines 220/224)
    /*
        pk->Domain[IACORE].vfPoint[0].OffsetVolts =
          pk->Domain[RING].vfPoint[0].OffsetVolts = 0;      // 800 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[1].OffsetVolts =
          pk->Domain[RING].vfPoint[1].OffsetVolts = -50;    // 2500 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[2].OffsetVolts =
          pk->Domain[RING].vfPoint[2].OffsetVolts = -100;   // 3500 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[3].OffsetVolts =
          pk->Domain[RING].vfPoint[3].OffsetVolts = -130;   // 4300 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[4].OffsetVolts =
          pk->Domain[RING].vfPoint[4].OffsetVolts = -110;   // 4800 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[5].OffsetVolts =
          pk->Domain[RING].vfPoint[5].OffsetVolts = -100;   // 5100 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[6].OffsetVolts =
          pk->Domain[RING].vfPoint[6].OffsetVolts = -100;   // 5200 MHz (Example)
    
        pk->Domain[IACORE].vfPoint[7].OffsetVolts =
          pk->Domain[RING].vfPoint[7].OffsetVolts = -100;   // 5200 MHz (Example)
     */
     
        /////////////
        // ICC Max //
        /////////////
    
        //
        // Note: check the capabilities of your CPU
        // Do not program too high value as damage might occur!
    
        /*
        pk->Program_IccMax[RING] =      0;  // Enable IccMax override for Ring/$
        pk->Program_IccMax[IACORE] =    0;  // Enable IccMax override for IA Cores
        pk->Program_IccMax[UNCORE] =    0;  // Enable IccMax override for SA/Uncore
        pk->Program_IccMax[GTSLICE] =   0;  // Enable IccMax override for GT Slice
        pk->Program_IccMax[GTUNSLICE] = 0;  // Enable IccMax override for GT Unslice
        */
    
        //
        // IccMax Values
        
        //pk->Domain[IACORE].IccMax = 
        //  pk->Domain[RING].IccMax = MAX_AMPS;      // 1/4 Amps Unit or MAX_AMPS
    
        ////////////////////
        /// Turbo Ratios ///
        ////////////////////
        
        // 
        // Enable this to program "max ratio" for all turbo core counts
        // (e.g. 1C, 2C, 4C, 8C, = use this ratio). Remove or set to 0
        // if you do not wish to set it
    
        //pk->ForcedRatioForAllCoreCounts = 51;
    
        /////////////////////
        /// Power Control ///
        /////////////////////
        
        //pk->ProgramPowerControl = 1;                // Enable programing of power
                                                    // control knobs
    
        //pk->EnableEETurbo = 1;                      // Energy Efficient Turbo
                                                    // (0=disable, 1=enable)
    
        //pk->EnableRaceToHalt = 1;                   // Race To Halt
                                                    // (0=disable, 1=enable)
    
        ////////////////////
        /// Power Limits ///
        ////////////////////
        
        //
        // Modify settings below only if you believe your, e.g.notebook, is over
        // aggressively limiting power(e.g.in 'desk' mode on AC).Please note
        // that many notebooks are very nicely configured, or their cooling system
        // cannot take more heat.Also, just because some value is higher (say,
        // 135W instead of 68W), this doesn't mean you will end up with more 
        // performance, as the CPU might end up in throttle - fest due to thermal
        // overloading of the cooling system or just reaching CPU's fused limits.
    
        // If you want to do this properly, you need to set up a benchmark script
        // simulating your workloads and carefully tweak the PLx values until you
        // hit the best scores. New systems also have more flexibility, such as
        // "dual Tau boost" that add more control levels and possibly make your
        // system >actually< faster at the end.Once you are done with benchmarking
        // and testing, PowerMonkey will happily set those values for you before 
        // OS or Hypervisor kick in.
    
        // Note: MAX_POWAH constant will still respect maximum PLx as reported by
        // the firmware.Some firmware(e.g.mine) report 0 instead, in which case
        // one will end up with programmed values like "4095 Watts".If you do not
        // like the checks done, you need to modify the code.But in that case, the
        // firmware might still refuse to program too high of a setting.
    
        // Bonus special : once there used to be one set of limits, you could
        // configure using an MSR.Then, vendors started introducing moar PLs(pkg,
        // platform, etc.) and also more ways to program(MSR, MMIO).Then, someone
        // had the great idea to use more than one record(say, MSRand MMIO) and
        // combine them into a more flexible config space.Of course, OEMs also
        // need more control(PL3, PL4, ...) and in the case of a notebook, say,
        // you wish OEM to have the final say so that EC can override anything with
        // emergency values.That would save you from melting your notebook, or
        // worse.There is no guide here to deal with this - please consult forums
        // if you do not have access to the relevant BWG doc.Or ignore all this
        // noise and set everything to MAX_POWAH as many will promptly do).
        // 
        // MAX_POWAH is a dummy value indicating to the policy updater that the
        // user prefers to set the value to "maximum allowed range". Useful for 
        // isolating sources of throttling. But it will not magically allow your
        // 13"-thin-and-light notebook to generate 500W of heat. Finding optimal
        // PLx values is much better idea. MAX_POWAH can also be dangerous when
        // platform does not have PECI-enforced failsafe (one could configure PLs
        // to be unsafe electrically and damage the system physically or worse)
    
        //
        // Select which parameters you want to program
        // If ProgramXXX flag is set to 0, entire knob will not be touched
        // This is also true for lock bits (if you wish to lock PL1, you need
        // to set ProgramPL12xx to 1)
    
        //pk->ProgramPL12_MSR =  1;               // Program MSR PL1/2
        //pk->ProgramPL12_MMIO = 1;               // Program MMIO PL1/2
        //pk->ProgramPL12_PSys = 1;               // Program Platform PLs
        //pk->ProgramPL3 = 1;                     // Program PL3
        //pk->ProgramPL4 = 1;                     // Program PL4
        //pk->ProgramPP0 = 1;                     // Program PP0
    
        //////////////
        // Settings //
        //////////////
    
        //
        // Configurable TDP (cTDP)
    
        //pk->MaxCTDPLevel =  0;                  // 0 = disables cTDP
        //pk->TdpControLock = 1;                  // Locks TDP config
    
        //
        // Package PL1/PL2 (MSR)
        /*
        
        pk->EnableMsrPkgPL1 = 1;                // Enable PL1 
        pk->EnableMsrPkgPL2 = 1;                // Enable PL2
        pk->MsrPkgPL1_Power = MAX_POWAH;        // PL1 in mW or MAX_POWAH
        pk->MsrPkgPL2_Power = MAX_POWAH;        // PL2 in mW or MAX_POWAH
        pk->MsrPkgPL_Time =   MAX_POWAH;        // Tau in ms or MAX_POWAH
        pk->ClampMsrPkgPL =   1;                // Allow clamping
        pk->LockMsrPkgPL12 =  1;                // Lock after programming
    
        //
        // Package PL1/PL2 (MMIO)
    
        pk->EnableMmioPkgPL1 = 1;               // Enable MMIO PL1
        pk->EnableMmioPkgPL2 = 1;               // Enable MMIO PL2
        pk->MmioPkgPL1_Power = MAX_POWAH;       // MMIO PL1 in mW or MAX_POWAH
        pk->MmioPkgPL2_Power = MAX_POWAH;       // MMIO PL2 in mW or MAX_POWAH
        pk->MmioPkgPL_Time   = MAX_POWAH;       // Tau in ms or MAX_POWAH
        pk->ClampMmioPkgPL =   1;               // Allow clamping
        pk->LockMmioPkgPL12 =  1;               // Lock after programming
    
        //
        // Platform (PSys) PL1/PL2 
    
        pk->EnablePlatformPL1 = 1;              // Enable PSys PL1 
        pk->EnablePlatformPL2 = 1;              // Enable PSys PL2
        pk->PlatformPL1_Power = MAX_POWAH;      // PSys PL1 in mW or MAX_POWAH
        pk->PlatformPL_Time =   MAX_POWAH;      // RAW VALUE 0-127 (or MAX_POWAH)
        pk->PlatformPL2_Power = MAX_POWAH;      // PSys PL2 in mW or MAX_POWAH
        pk->ClampPlatformPL =   1;              // Allow clamping
        pk->LockPlatformPL =    1;              // Lock after programming
    
        //
        // Package PL3
    
        pk->EnableMsrPkgPL3 = 1;                // Enable MSR PL4
        pk->MsrPkgPL3_Power = MAX_POWAH;        // PL3 in mW or MAX_POWAH
        pk->MsrPkgPL3_Time  = MAX_POWAH;        // Tau in ms or MAX_POWAH
        pk->LockMsrPkgPL3 =   1;                // Lock PL1 after programming
    
        //
        // Package PL4
        //
        // Note: I do not recommend pushing this setting up. It sits near the
        // end of possible strategies to avoid power escalation. Setting it too
        // high might bring your system so out of spec that physical damage can
        // occur. While some systems have additional protections, one should not
        // test this damage can be irreversible. I'd consider changing this only
        // if I have strong reason to suspect it is too low (seeing CPU reporting
        // too many throttling events)
    
        pk->EnableMsrPkgPL4 = 1;                // Enable PL4
        pk->MsrPkgPL4_Current = MAX_POWAH;      // MSR PL4 Amperes or MAX_POWAH
        pk->LockMsrPkgPL4 = 1;                  // Lock PL4 after programming
    
        //
        // PP0
    
        pk->EnableMsrPkgPP0 = 1;                // Enable MSR PP0
        pk->MsrPkgPP0_Power = MAX_POWAH;        // Power in mW or MAX_POWAH
        pk->MsrPkgPP0_Time =  MAX_POWAH;        // Time in ms or MAX_POWAH
        pk->ClampMsrPP0 =     1;                // Allow clamping
        pk->LockMsrPP0 =      1;                // Lock after programming
        */
      }
    }
    
    opened by jhigh2000 8
  • Failed to build on wsl2

    Failed to build on wsl2

    [-Werror=unknown-pragmas] and error: implicit declaration of function ‘__cpuid’ [-Werror=implicit-function-declaration]

    I think I may be using the wrong gcc version to compile, I followed the instructions on the edk2 for linux compilations. I also tried to compile it using gcc7

    opened by yliam73 2
  • Error building

    Error building

    Hello, I came across this project recently, and I am trying to use it, but i am getting an error when trying to compile.

    Using Visual studio 2022, installed nasm.

    Error	MSB3721	The command ""nasm.exe" -o "C:\Users\Henrikas\Desktop\VisualUefi\PowerMonkey\x64\Release\obj\PowerMonkey\ComboHell_AVX2.obj" -fwin64 -g -I"C:\Users\Henrikas\Desktop\VisualUefi\PowerMonkey\..\edk2\MdePkg" -I"C:\Users\Henrikas\Desktop\VisualUefi\PowerMonkey\..\edk2\MdePkg\Include" -I"C:\Users\Henrikas\Desktop\VisualUefi\PowerMonkey\..\edk2\MdePkg\Library\BaseLib\X64" -I"C:\Users\Henrikas\Desktop\VisualUefi\PowerMonkey\..\edk2\MdePkg\Include\X64"  "C:\Users\Henrikas\Desktop\VisualUefi\PowerMonkey\PowerMonkeyApp\ASMx64\ComboHell_AVX2.nasm"" exited with code 1.
    

    EDIT (extra details): used "Visual Studio" route and i cloned https://github.com/ionescu007/VisualUefi with all submodules

    opened by Henris3330 1
  • Issue WSL, Sandbox, Virtual Machine, Hypervisor Platform

    Issue WSL, Sandbox, Virtual Machine, Hypervisor Platform

    I created powermonkey.efi successfully with parameter: Core: -160mV Ring (Cache): -80mV Intel GPU: -40mV iGPU Unslice: -40mV

    In BIOS 10875h Secure Boot: Disable Virtual: Enable

    Everything is ok before I install components: WSL, Sandbox, Virtual Machine, Hypervisor Platform. Windows 11 restricted undervolt.

    Please help.

    opened by ghost 1
  • missing CpuDataVR.h

    missing CpuDataVR.h

    Itried to build it with the EDK2 route but iam getting a error

    build.py... /home/alan/src/edk2/MdeModulePkg/Application/PowerMonkeyApp/PowerMonkey.inf(56): error 000E: File/directory not found in workspace /home/alan/src/edk2/MdeModulePkg/Application/PowerMonkeyApp/CpuDataVR.h

    • Failed -
    opened by alanpi 1
  • will powermonkey update new cpu support

    will powermonkey update new cpu support

    i copy the alder lake setting and modify to a raptor lake cpu,it seems no error,but i'm not sure it's the correct way because i'm not familiar with this area. will you continue update for new cpus? { {6, 183, 1} , "RaptorLake", 0, 11, 1, 1, &vcfg_q_alderlake_client }

    opened by scarletfantasy 0
  • Compile error cannot find “UefiApplicationEntryPoint.lib”

    Compile error cannot find “UefiApplicationEntryPoint.lib”

    I’ve been experiencing this issue when using visualuefi. If anyone has a compiled efi with core and ring -103 and gtslice and unslice -103, please share it.

    opened by Super8733 0
  • Unable to program CPU

    Unable to program CPU

    So I'm not sure if its just not possible in the first place or not, but I tried to use PowerMonkey on a mobile platform with an intel i7-12700H. I tried countless build configurations with small voltage offsets (-10mv to -50mv), including one where I commented out most of the code below the legacy offset.

    I saw that the VF points are only available for "unlocked" CPUs, so I disabled them and used only the legacy (Entire VF) offset, but while PM would load, it never actually programmed the CPU. Here is a picture of the result just before the system went to the normal windows boot manager: image

    opened by Hexonoid 3
  • Non turbo core gets locked to ratio 22 instead of 26

    Non turbo core gets locked to ratio 22 instead of 26

    Title. Basically setup to boot powermonkey before windows it applies undervolt and everything, but when turbo is disabled max ratio is 22 instead of 26 normally for my i7-9750hf

    configuration.c: https://pastebin.com/RpWWZvM5

    opened by Henris3330 1
Releases(V0.2.1)
Owner
null
Make Epsilon Great again - Project Mu UEFI Firmware for Surface Duo (First Generation) Devices

Project Mu UEFI Implementation for Surface Duo Build Quick notes for building: Use Ubuntu 20.04 x64 Generate ACPI tables with IASL Follow this quick d

WOA Project 99 Dec 22, 2022
Windows 10 interface adjustment tool supports automatic switching of light and dark modes, automatic switching of themes and transparent setting of taskbar

win10_tools Windows 10 interface adjustment tool supports automatic switching of light and dark modes, automatic switching of themes and transparent s

Simon 1 Dec 3, 2021
OSC Calibrator and High Voltage Fuse Resetter for 8-Pin ATtinys

TinyCalibrator - OSC Calibrator and High-Voltage Fuse Resetter Because the 8-pin ATtinys only have a few GPIO pins available, they are usually operate

Stefan Wagner 41 Dec 30, 2022
Voltage Controlled Digital Core Multimode Oscillator using Mozzi library on Arduino

Arduino-VDCO Voltage Controlled Digital Core Multimode Oscillator using Mozzi library on Arduino Its a digital Oscillator/Voice for the Eurorack Stand

null 47 Dec 12, 2022
Tutorials on how the UEFI works

Step by Step Tutorials on how to use the UEFI for OS Development from scratch THIS IS WINDOWS BASED TUTS, BUT CODE SHOULD WORK IN LINUX AND MAC. NOTE

ThatOSDev 7 Dec 28, 2022
⚡ Kernel written for NeticOS (UEFI bootloader)

AirKernel ⚡ Kernel written for NeticOS (UEFI bootloader) Report bug | Request a feature ❗️ Requirements Debian/Debian-based sudo apt install gcc g++ q

null 7 Dec 3, 2022
Very minimalistic UEFI boot menu / Stivale2 bootloader

Tosaithe Tosaithe is a minimalistic UEFI-firmware menu/bootloader. It can chain-load other EFI programs and loaders, including Linux kernels, and has

Davin McCall 12 Dec 8, 2022
Getting started with uefi

Hello UEFI 此项目是uefi入门实践指导,因为我也是一路踩坑踩过来,所以想要记录一下。 UEFI开发环境搭建非常的复杂。 linux和windows和其他操作系统上都可以编译,这里主要讲windows。 此项目完成的效果仅仅是使用我们开发的uefi模块,在vmware上测试,并在shell

0000000000 2 Nov 8, 2021
Avocado Bootloader is an Advanced X86 - X86_64 BIOS/UEFI multiprotocol bootloader.

Avocado Bootloader What is avocado? Avocado is a modern, advanced x86/x86_64 BIOS/UEFI multiprotocol bootloader used as the reference implementation f

Weida32 2 Jan 3, 2022
For Beginners, students and developers this is a great opportunity to learn and contribute to open source.

Hacktoberfest 2021 For Beginners, students and developers this is great opportunity to learn and contribute to open source. Link To HacktoberFest 2021

Srinidh 23 Aug 17, 2022
For Beginners, students and developers this is a great opportunity to learn and contribute to open source.

Hacktoberfest 2021 For Beginners, students and developers this is great opportunity to learn and contribute to open source. Link To HacktoberFest 2021

null 79 Dec 27, 2022
Vimb - the vim like browser is a webkit based web browser that behaves like the vimperator plugin for the firefox and usage paradigms from the great editor vim.

Vimb - the vim like browser is a webkit based web browser that behaves like the vimperator plugin for the firefox and usage paradigms from the great editor vim. The goal of vimb is to build a completely keyboard-driven, efficient and pleasurable browsing-experience.

Daniel Carl 1.2k Dec 30, 2022
Repository of some great classical and Advanced cryptosystems

CryptoSystems ?? Repository of some great classical and Advanced cryptosystems Every C file here contains one of the most popular Cryptosystem in hist

Abhilash Datta 3 Nov 8, 2022
The great software for some game that exploiting anime girls (and boys).

Akebi GC The great software for some game that exploiting anime girls (and boys). Getting Started Building from source It is reccomended to use Visual

Akebi Group 1.6k Sep 17, 2022
让Etwhook再次伟大! Make InfinityHook Great Again!

MakeInfinityHookGreatAgain Make InfinityHook Great Again 图片测试(2004系统两个小时): 怎么做 https://key08.com/index.php/2021/06/23/1170.html windows 20h1 x64 18个小时

Huoji's 99 Nov 19, 2022
A collection of services with great free tiers for developers on a budget. Sponsored by Mockoon, the best mock API tool.

A collection of services with great free tiers for developers on a budget. Sponsored by Mockoon, the best mock API tool.

Guillaume 11.4k Jan 4, 2023
💉This is the ultimate great source code for building the best injectable Exec on FiveM.

FiveM Lua Executor This is the ultimate great source code for building the best injectable Exec on FiveM. I'm not going to tell you how to create a pr

Sarnax 44 Dec 25, 2022
Example-application - Example out-of-tree application that is also a module

Zephyr Example Application This repository contains a Zephyr example application. The main purpose of this repository is to serve as a reference on ho

Zephyr Project 82 Dec 13, 2022
The Vulkan Profiles Tools are a collection of tools delivered with the Vulkan SDK for Vulkan application developers to leverage Vulkan Profiles while developing a Vulkan application

Copyright © 2021-2022 LunarG, Inc. Vulkan Profiles Tools (BETA) The Vulkan Profiles Tools are a collection of tools delivered with the Vulkan SDK for

The Khronos Group 73 Dec 25, 2022