Haswell Power Management Fix

Almost all UEFI BIOS versions lock MSR 0xE2. Not that it matters, because we know exactly what/where to look for. Something that has helped us to patch the BIOS before and we are about to do it again. This blog article however will show you the exact UEFI source code that locks BIT 15 of MSR 0xE2 (MSR_PMG_CST_CONFIG_CONTROL). Let’s start with the PowerManagement.inf

#  This file contains an 'Intel Peripheral Driver' and uniquely
#  identified as "Intel Reference Module" and is
#  licensed for Intel CPUs and chipsets under the terms of your
#  license agreement with Intel or your vendor.  This file may
#  be modified by the user, subject to additional terms of the
#  license agreement
#Copyright (c)  1999 - 2010 Intel Corporation. All rights reserved
#This software and associated documentation (if any) is furnished
#under a license and may only be used or copied in accordance
#with the terms of the license. Except as permitted by such
#license, no part of this software or documentation may be
#reproduced, stored in a retrieval system, or transmitted in any
#form or by any means without the express written consent of
#Intel Corporation.
#Module Name:
#  PowerManagement.inf
#  Component description file for Power Management module

BASE_NAME            = PowerManagement2
FILE_GUID            = f7731b4c-58a2-4df4-8980-5645d39ece58



# Edk II Glue Driver Entry Point




# Typically the sample code referenced will be available in the code base already
# So keep this include at the end to defer to the source base definition
# and only use the sample code definition if source base does not include these files.

# Edk II Glue Library, some hearder are included by R9 header so have to include





  IMAGE_ENTRY_POINT = _ModuleEntryPoint
  DPX_SOURCE        = $(PROCESSOR)\PowerManagement.dxs
# Module Entry Point
 C_FLAGS = $(C_FLAGS) /D__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePowerManagement
                      /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
                      /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
                      /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
                      /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
                      /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
                      /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__

This gives us the target GUID of the Power Management module aka F7731B4C-58A2-4DF4-8980-5645D39ECE58 which is also used for the filename in the iMac13,N EFI.
For example:


This should help you to locate the PM module. Next up. The actual locking code:

// Procedure:   DoCstateProgramming
// Description: Program C-state registers.
// Input:
//  IN VOID *SetupHandle
// Output:  VOID

VOID DoCstateProgramming(IN VOID *SetupHandle)
    UINT32 CpuSignature = GetCpuSignature();
    UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
    UINT8  CpuSigVer = CpuSignature & 0xf;
    BOOLEAN IsSandyBridge = CpuSigNoVer == SANDY_BRIDGE || CpuSigNoVer == JAKETOWN || CpuSigNoVer == IVY_BRIDGE || CpuSigNoVer == HASWELL;
	UINT8	CstRange;
    UINT8   PkgCstLimitProg;
    UINT32  PmgCstConfCntr;
	UINT32	RegEax, RegEbx, RegEcx, RegEdx;

    CPULib_CpuID(5, &RegEax, &RegEbx, &RegEcx, &RegEdx);

    //Check if C1E is available.
    if ((RegEdx & C1_SUB_STATES_MASK) > 0x10) {  //bits [7:4] are for C1
        //Enable C1E [1]
        ReadWriteMsr(MSR_POWER_CTL, BIT1, (UINT64)-1);   //0x1fc

    if (IsSandyBridge) {
        ReadWriteMsr(MSR_PKGC3_IRTL, 0x50 + (2 << 10) + BIT15, (UINT64)0xffffffffffffe00);
        ReadWriteMsr(MSR_PKGC6_IRTL, 0x68 + (2 << 10) + BIT15, (UINT64)0xffffffffffffe00);
        ReadWriteMsr(MSR_PKGC7_IRTL, 0x6d + (2 < 4 || CpuSigNoVer == JAKETOWN) {
            //Enable C1 and C3 Un-demotion and lock.
            PmgCstConfCntr |= BIT28 + BIT27 + BIT15;
    } else {
        PmgCstConfCntr |= BIT15;   //Lock CFG

    // Program IO-redirect as well as Package C State Limit
    ReadWriteMsr(MSR_PMG_CST_CONFIG_CONTROL, PmgCstConfCntr, (UINT64)-8);

    if(RegEdx & C7_SUB_STATES_MASK)         CstRange = 2;
    else if (RegEdx & C6_SUB_STATES_MASK)   CstRange = 1;
	else CstRange = 0;

	WriteMsr(MSR_PMG_IO_CAPTURE_ADDR, (CstRange << 16) + PM_BASE_ADDRESS + 0x14);	//0xe4 - C State IO Capture Base Address.

That is it. Nothing more to see. Problem located and ready to get patched!

Note: Intel® Corporation (legal) representatives are kindly asked to contact me per e-mail for the express written consent to publish this – to prevent DMCA take down notices.

5 thoughts on “Haswell Power Management Fix

  1. Well, l’m not a coder/programmer but I did a lot of reading and research. Tracing the code I “believe” this is the start of check for Cstates./Lock MSR_e2

    405: b9 e2 00 00 00 mov $0xe2,%ecx //move state of MSR_e2 >%ecx
    40a: 48 dec %eax
    40b: 8b 10 mov (%eax),%edx
    40d: 8b 7a 09 mov 0x9(%edx),%edi
    410: 8b df mov %edi,%ebx
    412: 83 e7 0f and $0xf,%edi
    415: 81 e3 f0 0f ff 0f and $0xfff0ff0,%ebx
    41b: f6 42 01 7a testb $0x7a,0x1(%edx) //bits [7:4] are for C1 //Enable C1E [1]
    41f: 75 19 jne 0x43a //checks flags if not Equal or 0x01jump?

    We want this to happen no matter what??

    So my question is: Am I on the right track? If not I’ll look deeper. There are only 2 other places where MSR_e2 is checked. But I believe this to be the JMP that need to be non conditional.

    • Don’t bother looking into this problem. The MSR 0xE2 is under control already. We also have a tool to patch BIOS files. The only problem left to solve is to flash a mod BIOS file, which certain motherboards reject with a security violation error.

  2. Pingback: Setting up MSI Z97i-AC motherboard (for running OS X) | mackonsti

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s