如何从EFI棍子更改msr 0x199?

时间:2019-05-27 09:52:39

标签: c uefi msr refind

我有一个不带电池的macbookpro11,3。卸下电池后,固件会将CPU的速度降低一半。在Windows中,我可以使用Throttlestop来关闭BD PROCHOT,并将乘数设置为25。我想通过EFI进行此操作,以便引导和更新以正常速度运行。

基于rEFInd的源代码,它更新了0x3a寄存器,我编写了此程序,但是在引导到Windows后正确禁用BD PROCHOT的情况下却没有乘数。

#include "../include/tiano_includes.h"
static VOID DisablePROCHOT(VOID)
{
    UINT32 msr = 0x1FC;
    UINT32 low_bits = 0, high_bits = 0;

    __asm__ volatile ("rdmsr" : "=a" (low_bits), "=d" (high_bits) : "c" (msr));

    // lowest bit is BD PROCHOT 
    low_bits &= ~(1 << 0);

    __asm__ volatile ("wrmsr" : : "c" (msr), "a" (low_bits), "d" (high_bits));
} // VOID DisablePROCHOT()

static VOID SetMultiplier25(VOID)
{
    UINT32 msr = 0x199;
    UINT32 low_bits = 0, high_bits = 0;

    __asm__ volatile ("rdmsr" : "=a" (low_bits), "=d" (high_bits) : "c" (msr));

    // second lowest byte is multiplier
    // 25 is .... xxxxxxxx 00011001 xxxxxxxx 
    low_bits |= 1 << 8;
    low_bits &= ~(1 << 9);
    low_bits &= ~(1 << 10);
    low_bits |= 1 << 11;
    low_bits |= 1 << 12;
    low_bits &= ~(1 << 13);
    low_bits &= ~(1 << 14);
    low_bits &= ~(1 << 15);

    __asm__ volatile ("wrmsr" : : "c" (msr), "a" (low_bits), "d" (high_bits));
} // VOID SetMultiplier25()

EFI_STATUS
EFIAPI
efi_main (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  DisablePROCHOT();
  SetMultiplier25();

  return EFI_SUCCESS;
}

从EFI中使用rdmsr读取寄存器似乎表明两者均已正确设置,但是当引导至Windows且正确设置了0x1FC的位0时,存储在0x199中的乘数与默认值12保持不变,而我希望它是25

默认值

这些是标准启动进入Windows后的值(从RWEverything)

Standard boot

调用程序后的结果

在调用Windows启动加载程序 bootmgfw.efi

之前,已从EFI Shell调用了程序。

0x1FC已更新,0x199未更新。

Boot after calling program

在Windows中使用RWEverything更新0x199会正确更改乘数,因此我很确定它是正确的寄存器。

因为这是我的第一个EFI(或C)程序,所以我可能忽略了一些琐碎的事情。

1 个答案:

答案 0 :(得分:1)

您必须创建一个循环,并在每次循环中更改处理器关联。然后,每次通过循环对每个线程(CPU1,CPU2,CPU3,CPU4)执行wrmsr。在Windows中,您可以使用此功能。

https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setthreadaffinitymask

启动后,Windows会立即更改MSR 0x199中的值,因此启动后查看MSR 0x199中的值不会证明任何事情。

为简化起见,您可以在SetMultiplier中进行此操作,

low_bits = 0x1900