Power Management bug in Intel/AMI located?

I glanced over some of the Intel/AMI source code and found an interesting spot. This particular part of the source code triggered my attention:

  // For OC supported units configure Turbo Ratio as 0xFF (max possible P-State) on IVB C0 or later
  if (OverclockingBins != 0 
      && mProcessorFamilyModel == CPUID_FULL_FAMILY_MODEL_IVYBRIDGE
      && mProcessorStepping >= IVYBRIDGE_C0) {
    mTurboBusRatio  = 0xFF;
  } else {
    // Get Max Turbo Ratio from Turbo Ratio Limit MSR Bits [7:0]
    TempMsr.Qword    = AsmReadMsr64 (MSR_TURBO_RATIO_LIMIT);
    mTurboBusRatio  = (UINT16)(TempMsr.Dwords.Low & MAX_TURBO_RATIO_LIMIT_MASK);

The key value here is OverclockingBins since the else clause is fine for us, and thus I looked at the code that sets it. Here it is:

  FlexRatioMsr.Qword    = AsmReadMsr64 (MSR_FLEX_RATIO);
  OverclockingBins = (UINT8) RShiftU64((FlexRatioMsr.Dwords.Low & OVERCLOCKING_BINS), 17);

Then I used a modified version of AppleIntelCPUPowerManagementInfo.kext to get value of the bits (7 << 17) that OverclockingBins is being set to, which in my case is 7. That combined with the fact that I happen to have a Ivy Bridge C0 stepping processor, that simply means that mTurboBusRatio will be set to 0xff (255). This is also checked by Apple, but since there is no over clocking in the world of Apple… Err.

Next up is function VerifyAndFixCustomRatio:

VerifyAndFixCustomRatio (
  UINT8     CustomRatio

Routine Description:

  Verify and fix Custom Ratio values 
  Custom Ratio should be between MaxTurboFrequency and LFM

  CustomRatio     Custom Ratio value

  Verified Custom Ratio value


  if (CustomRatio > mTurboBusRatio) {
    // Use HFM as max value if Turbo is not supported
    if (mTurboBusRatio == 0) {
      CustomRatio = (UINT8)mMaxBusRatio;
    } else {
      CustomRatio = (UINT8)mTurboBusRatio;
  } else if (CustomRatio < mMinBusRatio) {
    // Use LFM as min value
    CustomRatio = (UINT8)mMinBusRatio;
  return (CustomRatio);

Now. Both CustomRatio and mMinBusRatio are of type UINT8, and since the latter is set to 0xff (in my case) this statement is bogus. I mean. Whatever value argument CustomRatio is, it cannot be greater than 0xff. And since there is no equal sign in the check, we end up in the else clause. That is when CustomRatio is less than mMinBusRatio otherwise it simply returns the value of CustomRatio. Normally this is fine, but what happens when mMinBusRatio isn’t set properly?

Let’s see what happens with this value. Yet another code snippet:

CustomConfigTdpTable[Index].CustomTurboActivationRatio = 
VerifyAndFixCustomRatio (PPMPolicy->pCustomCtdpSettings->CustomConfigTdpTable[Index].CustomTurboActivationRatio);

What this does is that it creates a custom TDP setting with lower ratio’s. And this is a new power management policy, introduced for Ivy Bridge processors, basically telling the Apple kexts that the processor is working in a restricted environment. With a limited TDP. I tell you that can’t be good, if this is true, because that way it won’t scale up to a higher P-State. Simply because OSPM thinks that something or someone is baking the CPU.

I’m not 100% sure that this is in fact a real problem, but it is certainly something that I like to investigate further. To rule out the slightest possibility that this is related to our little PM problem. I’ve also already located the source code that will help me to write a small SSDT.aml to help me with my next experiment… getting the values I am after.

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