# GetCpuInfo

## Function Table

| 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*