Как внести изменения в msr 0x199 с флешки EFI? - PullRequest
1 голос
/ 27 мая 2019

У меня есть macbookpro11,3 без батареи. Когда батарея извлечена, микропрограмма дросселирует процессор до половины скорости. В 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, когда бит 0 0x1FC правильно установлен, множитель, сохраненный в 0x199, не изменяется по умолчанию из 12, когда я ожидаю, что он будет 25 .

Значения по умолчанию

Это значения после стандартной загрузки в Windows (из RWEverything)

Standard boot

Результаты после вызова программы

Программа была вызвана из оболочки EFI перед вызовом загрузчика Windows bootmgfw.efi

0x1FC обновлено, 0x199 - нет.

Boot after calling program

Обновление 0x199 с помощью RWEverything изнутри Windows правильно меняет множитель, поэтому я вполне уверен, что это правильный регистр.

Поскольку это моя первая программа EFI (или C), возможно, я упустил что-то тривиальное.

1 Ответ

1 голос
/ 27 мая 2019

Вы должны создавать цикл и изменять сродство процессора каждый раз через цикл. Затем вы выполняете wrmsr для каждого потока (CPU1, CPU2, CPU3, CPU4) каждый раз в цикле. В Windows вы используете эту функцию.

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

Как только вы загружаетесь, Windows меняет значения в MSR 0x199, поэтому проверка значений MSR 0x199 после загрузки ничего не доказывает.

Чтобы упростить вещи, вы можете сделать это в SetMultiplier,

low_bits = 0x1900

...