| Address | Name | Description |
|---|---|---|
| GetCpuInfoEntryPoint | ||
| CpuInfoDriverEntry | ||
| CpuInfoCollection | ||
| CpuInfoDisplayForm | ||
| CpuInfoDelayMicro | ||
| GetPlatformLanguage | ||
| CpuIdEx | ||
| AsmReadMsr64 | ||
| AsmWriteMsr64 | ||
| CpuInfoReadAll | ||
| CpuInfoLocatePcdProtocol | ||
| CpuInfoGetProcessorCountFromHob | ||
| CpuInfoFreeAllBuffers | ||
| HiiFreeOpCodeHandle | ||
| GLOBAL | VARIABLES (.data section, 0x3D30 - 0x3DF0) | |
| EFI_HANDLE | gImageHandle; ///< 0x3D40 | |
| GUID | DEFINITIONS (.rdata section) | |
| The | GUIDs are defined externally in the PE/COFF .rdata section: | |
| unk_3B00 | = EFI_CPU_ARCH_PROTOCOL_GUID | |
| unk_3B10 | = gEfiRuntimeServicesTableGuid | |
| unk_3B30 | = HII package list GUID for VFR | |
| unk_3B40 | = gEfiPcdProtocolGuid | |
| unk_3B50 | = PackageListGuid for HII string packages | |
| unk_3C08 | = gEfiHiiStringProtocolGuid | |
| unk_3C18 | = gEfiHiiConfigRoutingProtocolGuid | |
| unk_3C28 | = gEfiHiiPackageListProtocolGuid | |
| unk_3C38 | = gEfiHiiDatabaseProtocolGuid | |
| unk_3C48 | = gEfiHobListGuid | |
| unk_3C58 | = gEfiHiiConfigAccessProtocolGuid | |
| unk_3C68 | = CPU Info formset GUID | |
| unk_3C80 | = CPU Info form GUID (VFR binary data) | |
| FORWARD | DECLARATIONS | |
| EFI_STATUS | EFIAPI | |
| CPUID | / MSR / I/O HELPERS (inlined wrappers) | |
| MODULE | ENTRY POINT | |
| Call | the actual driver entry | |
| return | CpuInfoDriverEntry (ImageHandle, SystemTable); | |
| Step | 1: Save UEFI handles | |
| gImageHandle | = ImageHandle; | |
| Step | 2: Initialize HOB list | |
| GetHobList | (); | |
| Step | 3: Get PCD for PCI Express base address (lazy init via PCD protocol) | |
| Step | 4: Locate HII protocols | |
| Status | = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, &gHiiDatabase); | |
| Step | 5: Check and enable platform language via PCI config | |
| PcdAddress | = 1024068; // Offset 0xF4244 from PciExpressBaseAddress | |
| Write | to IO port to enable | |
| CpuInfoEnablePlatformLanguage | (PcdAddress - 4); // 0xF4240 | |
| Step | 6: Read platform type from IO port 0x80 | |
| PlatformType | = IoRead32 (IO_PORT_0x80); | |
| Step | 7: Wait for IO completion by polling port 0x508 | |
| do | { | |
| Small | delay via IO port read | |
| Step | 8: Return based on setup mode | |
| if | (SetupMode) { | |
| CPU | INFORMATION COLLECTION | |
| Step | 1: PCD enable check | |
| if | (!PcdGetBool (PcdCpuInfoDisplayEnable)) { | |
| Step | 2: Locate CPU Architecture Protocol | |
| CpuProtocol | = CpuInfoLocateCpuProtocol (); | |
| Step | 3: Get number of processors from HOB | |
| ProcessorNumber | = CpuInfoGetProcessorCountFromHob (); | |
| Step | 4: Allocate per-processor string buffers | |
| gAllCpuInfoString | = AllocateZeroPool (CPU_INFO_STRING_SIZE * ProcessorNumber); | |
| Step | 5: Build header string "Total CPU Number: %d\n" | |
| UnicodeSPrint | ( | |
| Step | 6: Initialize per-processor label strings | |
| for | (Index = 0; Index < ProcessorNumber; Index++) { | |
| Step | 7: Collect actual CPU data from all processors | |
| Step | 8: Register callback for form update | |
| Step | 9: Create and display HII form | |
| HiiHandle | = CpuInfoRegisterPackageList ( | |
| Step | 10: Free buffers | |
| Max | width for number formatting | |
| UnicodeValueToString | (Buffer, 0, Index, 4); | |
| AsmCpuid | (CPUID_VERSION_INFO, &Eax, &Ebx, &Ecx, &Edx); | |
| Stepping | (EAX[3:0]) | |
| CPUID | (EAX full, printed as hex) | |
| PlatformIdMsr | = AsmReadMsr64 (MSR_IA32_PLATFORM_ID); | |
| then | read MSR 0x8B[63:32]. | |
| AsmWriteMsr64 | (MSR_IA32_BIOS_SIGN_ID, 0); | |
| MSR_PLATFORM_INFO | (0xCE) byte 1 is the Maximum Efficiency Ratio. | |
| Core | frequency = ratio * 100 MHz (bus frequency). | |
| MaxEfficiencyRatio | = AsmReadMsr64 (MSR_PLATFORM_INFO); | |
| Uses | the MPERF (MSR 0xE7) and APERF (MSR 0xE8) ratio method: | |
| if | (gMaxTurboRatio == 0) { | |
| freq | = (ratio CoreFreq 100) / 10000 | |
| MeasuredRatio | = DivU64xU64 (MultU64xU64 (AperfValue, 100), gMaxTurboRatio); | |
| actual | MHz = (ratio MaxEfficiencyRatio 100) / 100 | |
| ActualFrequency | = DivU64xU64 ( | |
| Format | and append | |
| UnicodeValueToString | (Buffer, 0, ActualFrequency / 100, 8); | |
| UTILITY | FUNCTIONS | |
| These | magic values represent GUID comparison data | |
| They | are precomputed from the CPU-info HOB GUID | |
| Walk | through HOBs looking for CPU info | |
| while | (GuidHob != NULL) { | |
| Compare | GUID to the expected CPU-info HOB GUID | |
| if | (CompareGuid (HobDataGuid, (EFI_GUID *)MagicCheck)) { | |
| Found | CPU info HOB | extract processor count |
| CpuCount | = (UINT32 )((UINT8 *)GuidHob + sizeof (EFI_HOB_GUID_TYPE)); | |
| Move | to next HOB | |
| GuidHob | = GetNextGuidHob ( | |
| Wait | for previous I/O to complete by polling port 0x508 | |
| while | (((AddressRemainder + (IoRead32 (IO_PORT_0x508) & 0xFFFFFF) | |
| Delay | via IO read | |
| After | first iteration, always use max remainder for remaining | |
| shifted | counts | |
| AddressRemainder | = 0x400000; | |
| Status | = gRT->GetVariable ( | |
| HII | FORM DISPLAY | |
| Allocate | op-code handles | |
| StartOpCodeHandle | = HiiAllocateOpCodeHandle (); | |
| Create | form header and end markers | |
| HiiCreateFormOpCode | (StartOpCodeHandle, FORM_CPU_INFO_ID, 0); | |
| Add | "Total CPU Number" header text | |
| Add | per-processor data lines (7 fields each) | |
| for | (Index = 0; Index < gNumberOfProcessors; Index++) { | |
| Update | the form via HII Database | |
| Status | = ((EFI_HII_DATABASE_PROTOCOL *)gHiiDatabase)->UpdateForm ( | |
| Clean | up | |
| HiiFreeOpCodeHandle | (StartOpCodeHandle); | |
| Calculate | total size of all packages | |
| Package | = VA_ARG (Args, VOID *); | |
| Build | the package list header | |
| CopyGuid | (&PackageListHeader->PackageListGuid, PackageListGuid); | |
| Register | with HII Database | |
| Status | = ((EFI_HII_PACKAGE_LIST_PROTOCOL *)gHiiPackageList)->NewPackageList ( |
Generated by HR650X BIOS Decompilation Project