Как программно узнать частоту процессора через BIOS?

Тема в разделе "WASM.BEGINNERS", создана пользователем Mikl___, 21 дек 2019.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Частоту процессора программно можно получить через:
    1. реестр HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0
    2. cpuid /80000004h
    3. структуру PROCESSOR_POWER_INFORMATION
    4. rdtsc и Sleep
    5. rdtsc и SleepEx
    6. rdtsc и ACPI-таймер (QueryPerformanceFrequency и QueryPerformanceCounter)
    7. rdtsc и ACPI-таймер (ZwQueryPerformanceCounter)
    8. rdtsc и GetTickCount
    9. rdtsc и timeGetTime
    А как получить частоту процессора через BIOS и желательно в user mode?
     
  2. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    > через BIOS и желательно в user mode?
    Эм. Биос это реалмод\протектедмод. Не понятна задача. Да и смысл если есть Cpuid
     
  3. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Зачем изобретать велосипед?
    Есть же программы для получения информации о железе.
    Есть руткиты и антируткиты.
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    TermoSINteZ,
    кроме cpuid частоту я получил еще 8 способами. Понятно, что основная информация о процессоре в БИОС. Но для доступа к БИОСу не хотелось бы писать драйвер, поэтому я и написал про юзер мод
    Pavia,
    просто хотелось бы узнать новые способы получения частоты процессора...
     
  5. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.241
    Если венда, то в юзермоде есть WMI, в которой есть просто любая информация о железе, не особо понимаю при чем тут биос и юзермод.
     
    ormoulu, Mikl___ и f13nd нравится это.
  6. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Работающей ОС (условной венде) биос предоставляет некоторые функции, в частности уход в слип/стендбай, управление питанием, доступ к фичам cpu. Так что вопрос ТС вполне корректен, но подрбностей я не знаю/не помню, думаю если упорно гуглить это можно найти. Либо плясать от каких-то системных утилит, считывающих состояние процессора.
    --- Сообщение объединено, 21 дек 2019 ---
    UEFI runtime services/GetFirmwareEnvironmentVariable м.б. это то что нужно в случае efi, для legacy bios возможно есть какой-то аналог.
     
  7. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    Миликоличество операций разделить на милесекунды
     
  8. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Единственный правильный способ - через CallNtPowerInfiormation.
    Все остальные способы привязываются к TSC, который не зависит от энергосберегающих режимов и тикает с фиксированной частотой.
    Частота процессора хранится не в BIOS, а в соответствующих MSR-регистрах процессора, достучаться до которых "вручную" можно только из ядра (например, так определяет частоту CPU-Z). Для AMD и Intel эти регистры разные.
    Единственный способ получить эти значения из юзермода - дёргать CallNtPowerInformation. Она прочитает частоты из MSR для каждого ядра и вернёт в юзермод.
    Других способов нет.

    Для AMD:

    upload_2019-12-22_1-9-28.png


    Для Intel:
    upload_2019-12-22_1-13-18.png
     
    Последнее редактирование: 22 дек 2019
    Mikl___, Pavia, hiddy и ещё 1-му нравится это.
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    ~MHz" параметр в реестре, ядро его создаёт на основе частоты в nt!PCB. Судя по всему загрузка туда(w10) значения происходит не в самом ядре, может в хал хз. На младших версиях расчёт частоты был через тск.

    Код (Text):
    1.             // Determine the MHz for the processor
    2.             //
    3.  
    4.             KeGetCurrentPrcb()->MHz = 0;
    5.  
    6.             if (KeFeatureBits & KF_RDTSC) {
    7.  
    8.                 Index = 0;
    9.                 pSamp = Samples;
    10.  
    11.                 for (; ;) {
    12.  
    13.                     //
    14.                     // Collect a new sample
    15.                     // Delay the thread a "long" amount and time it with
    16.                     // a time source and RDTSC.
    17.                     //
    18.  
    19.                     CPUID (0, &Junk, &Junk, &Junk, &Junk);
    20.                     pSamp->PerfStart = KeQueryPerformanceCounter (NULL);
    21.                     pSamp->TSCStart = RDTSC();
    22.                     pSamp->PerfFreq.QuadPart = -50000;
    23.  
    24.                     KeDelayExecutionThread (KernelMode, FALSE, &pSamp->PerfFreq);
    25.  
    26.                     CPUID (0, &Junk, &Junk, &Junk, &Junk);
    27.                     pSamp->PerfEnd = KeQueryPerformanceCounter (&pSamp->PerfFreq);
    28.                     pSamp->TSCEnd = RDTSC();
    29.  
    30.                     //
    31.                     // Calculate processors MHz
    32.                     //
    33.  
    34.                     pSamp->PerfDelta = pSamp->PerfEnd.QuadPart - pSamp->PerfStart.QuadPart;
    35.                     pSamp->TSCDelta = pSamp->TSCEnd - pSamp->TSCStart;
    36.  
    37.                     pSamp->MHz = (ULONG) ((pSamp->TSCDelta * pSamp->PerfFreq.QuadPart + 500000L) /
    38.                                           (pSamp->PerfDelta * 1000000L));
    39.  
    40.  
    41.                     //
    42.                     // If last 2 samples matched within a MHz, done
    43.                     //
    44.  
    45.                     if (Index) {
    46.                         if (pSamp->MHz == pSamp[-1].MHz ||
    47.                             pSamp->MHz == pSamp[-1].MHz + 1 ||
    48.                             pSamp->MHz == pSamp[-1].MHz - 1) {
    49.                                 break;
    50.                         }
    51.                     }
    52.  
    53.                     //
    54.                     // Advance to next sample
    55.                     //
    56.  
    57.                     pSamp += 1;
    58.                     Index += 1;
    59.  
    60.                     //
    61.                     // If too many samples, then something is wrong
    62.                     //
    63.  
    64.                     if (Index >= MAX_ATTEMPTS) {
    65.  
    66. #if DBG
    67.                         //
    68.                         // Temp breakpoint to see where this is failing
    69.                         // and why
    70.                         //
    71.  
    72.                         DbgBreakPoint();
    73. #endif
    74.  
    75.                         Average = 0;
    76.                         for (Index = 0; Index < MAX_ATTEMPTS; Index++) {
    77.                             Average += Samples[Index].MHz;
    78.                         }
    79.                         pSamp[-1].MHz = Average / MAX_ATTEMPTS;
    80.                         break;
    81.                     }
    82.  
    83.                 }
    84.  
    85.                 KeGetCurrentPrcb()->MHz = (USHORT) pSamp[-1].MHz;
     
    Mikl___ нравится это.
  10. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Попалось это в сурках(wrk):

    Это одно упоминание, в енум сисинфо этого класса нет. В хал и нт XP-10 тегов speed" нет, нужно реверсить ядро что бы понять как это работает.
     
    Mikl___ нравится это.