c - 如何从 EFI 棒更改 msr 0x199?

标签 c uefi msr refind

我有一台没有电池的 macbookpro11,3。当电池被移除时,固件将 CPU 节流到一半速度。在 Windows 中,我可以使用 Throttlestop 覆盖它以关闭 BD PROCHOT 并将乘数设置为 25。我想从 EFI 执行此操作,以便启动和更新以正常速度运行。

基于 rEFInd 的来源它更新了我编写的这个程序的 0x3a 寄存器,但是当 BD PROCHOT 在引导进入 Windows 后被正确禁用时,乘数却没有。

#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;
}

使用 rdmsr 从 EFI 读取寄存器似乎显示两者都已正确设置,但是当启动到 Windows 时,0x1FC 的位 0 被正确设置,存储在 0x199 中的乘数与默认值 12 没有变化,而我预计它是 25 .

默认值

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

Standard boot

调用程序后的结果

程序在调用 Windows 引导加载程序之前从 EFI shell 调用 bootmgfw.efi

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

Boot after calling program

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

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

最佳答案

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

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

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

为了简化事情,您可以在 SetMultiplier 中执行此操作,

低位 = 0x1900

关于c - 如何从 EFI 棒更改 msr 0x199?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56323657/

相关文章:

c - Vim 的理想 C 设置

c - 在 Linux 中使用 pcap 获取接口(interface)的 IP 地址

io - UEFI中通过I/O空间和MMIO访问intel显卡寄存器

encryption - MSR DUKPT 的 MAC 变体?

intel - Haswell 微架构在性能中没有停滞周期后端

c - 在 if 比较中将 + 识别为 '+' 的问题

x86-64 - 在 x64 上从 64 位长模式切换到 32 位兼容模式

c - 将完整操作系统编写为 UEFI 应用程序的现实性

x86 - x86 MSR 名称的 IA32 与 MSR 前缀

C预处理器初始化数组