Newer
Older
AMI-Aptio-BIOS-Reversed / PurleyPlatPkg / Platform / Dxe / PlatformCpuPolicy / PlatformCpuPolicy.md
@Ajax Dong Ajax Dong 2 days ago 10 KB Full restructure

PlatformCpuPolicy

Function Table

Address Name Description
SerialPortSetBaudRate
SerialPortWrite
ZeroMem
InternalZeroMem
MsrReadRange
IoWrite8
IoRead8
IoRead16
IoWrite16
PlatformCpuPolicyEntryPoint
DetectAndSetUartBaudRate
PlatformCpuPolicyInit
GetPcdValue
SetPcdValue
GetConfigTable
ConfigureSocketIdInfo
AllocateIedTraceBuffer
SetupPpmStructures
InstallPlatformCpuPolicy
TlsAuthConfigExtractConfig
TlsCaCertificateRouteConfig
TlsCaCertificateCallback
GetSetupVariables
DebugPrint
AssertHandler
AsciiStrCpyS
AsciiStrLen
AsciiVSPrint
AsciiSPrint
Global Data (stored in .data section)
Protocol interface pointers (populated by PlatformCpuPolicyInit)
EFI_HANDLE gImageHandle = NULL;
EFI_BOOT_SERVICES ptr
Lazily located protocol pointers
VOID *mPcdProtocol = NULL; // PCD protocol
MM PCI USRA protocol
HOB list pointer
SetupLib initialized flag
SMM ctl hook protocol
Platform policy data (from HOB + PCD)
UINT64 gCpuPolicyData; // Base address of CPU policy data
BMC register interface ptr
Socket topology and configuration arrays
CHAR16 *gSocketNameTable[4]; // Socket name table for debug
Socket ID map (2 per socket)
Number of active sockets
Raw socket configuration val
UINT64 gPpmBuffer;
PCD token space GUID structure
UINT64 gPcdTokenSpace;
Forward declarations for internal helpers
Library wrapper functions (linked from BaseLib)
rep stosb sequence on Buffer with Size count.
This is a leaf function (no callees), 0x20 bytes.
0x2E0 -- accesses MSR via PCI or direct rdmsr
Wraps to a protocol call depending on socket.
Module Entry Point
Phase 1: Initialize globals, locate protocols
PlatformCpuPolicyInit (ImageHandle, SystemTable);
Phase 2: Install CPU platform policy
return InstallPlatformCpuPolicy ();
Driver Initialization
Read CMOS high byte of baud configuration
__outbyte (RTC_INDEX_PORT, CMOS_BAUD_HIGH);
Decode baud rate from CMOS nibble
switch (CmosByte) {
Calculate divisor: 0x1C200 / BaudRate
Divisor = 115200 / BaudRate;
Determine UART base: check if COM1 (0x3F8) or COM2 (0x2F8)
CMOS offset 0x5C bit 0 selects COM2 if set.
UartBase = UART_BASE_PORT;
Check if UART is already configured for the correct divisor
LcrShadow = __inbyte (UartBase + 3); // LCR
set DLAB
restore LCR
Only reconfigure if the divisor doesn't match AND the UART is
detected (LSR bits 6 and 5 indicate THR/TEMT empty)
if **(CurrentDivisor != (UINT16)Divisor (LcrShadow & 0x3F) != 3) {**
Wait for UART to be ready
while ((__inbyte (UartBase + 5) & 0x60) != 0x60);
Program new divisor
__outbyte (UartBase + 3, 0x80); // set DLAB
MSB __outbyte (UartBase, (UINT8)Divisor); // LSB
clear FCR
enable FIFO
clear MCR
Save UEFI global pointers
gImageHandle = ImageHandle;
Initialize UART debug output (detect and set baud rate)
DetectAndSetUartBaudRate ();
Locate the EFI_DS (Driver Services) protocol via config table
Status = GetConfigTable (&gEfiDsGuid, (VOID )&gBootServices);**
Locate the PCD protocol (required for platform configuration)
mPcdProtocol = GetPcdProtocol ();
Locate the MM PCI USRA protocol for PCI config space access
Status = gBS->LocateProtocol (
Get the HOB list
Get the SMM Ctl Hook protocol pointer
mPcdProtocol = GetPcdProtocol (); // reuse for token space reference
Store CPU policy MSR value (token 5 -> qword_5B00)
gCpuPolicyData = GetPcdProtocol ()->GetPcdValue (5);
PCD Protocol Access
Configuration Table / HOB Lookup
Socket ID Configuration
DEBUG ((DEBUG_INFO, "::SocketCount %08x\n", MAX_SOCKET_COUNT));
Read the CPU_SOCKET_ID_INFO PCD
Copy socket ID data into platform policy structure
Map socket IDs: for each socket that is present, copy its PPIN
to the socket ID table; otherwise mark as -1 (disabled socket).
for (SocketIndex = 0; SocketIndex < MAX_SOCKET_COUNT; SocketIndex++) {
Read socket configuration from MSR 11
MsrReadRange (CPU_POLICY_MSR_11, 1, &gSocketConfig, 0, 0, 0);
Apply topology-based encoding to socket ID table
socket not present
Need more information — can't determine mask
DEBUG ((DEBUG_INFO, "::Need more info to make sure we can support!!!\n"));
IED Trace Buffer Allocation
Validate the IED trace size
ASSERT (
do {
Allocation failed — halve the size and retry
AllocateSize >>= 1;
Align the buffer to a 2 MB boundary
if ((BufferAddress & 0x100000) != 0) {
Zero the allocated buffer and tag it as "INTEL RSVD"
Program the IED base address and size into the system address map
for each present socket
Write IED base (in MB units) to system address map register
Write IED size (in MB units) to system address map register
PPM (Processor Power Management) Structure Setup
Locate CPU policy HOB
HobList = GetHobList ();
Get socket count from the CPU policy protocol
Allocate socket name table (array of CHAR16 pointers for debug)
SocketNameBuffer = AllocatePool (SocketCount sizeof (CHAR16 ));
Allocate PPM data buffers (8 bytes per socket)
SocketPpmBuffer = AllocatePool (SocketCount * 8);
Free the name buffer and report out-of-resources
DEBUG ((DEBUG_ERROR, "\nEFI_OUT_OF_RESOURCES!!! AllocatePool() returned NULL pointer.\n"));
Initialize socket name table
for (Index = 0; Index < SocketCount; Index++) {
Fill in the name from a static table:
PPM data: set to "UNKNOWN" initially
simplified - was L"CPU1" etc
Register PPM buffers with PCD system
DEBUG ((
Main Platform CPU Policy Installation
Locate the CPU policy HOB
Get PCD protocol interface
Determine IED trace size from PCD or HOB
IedTraceSize = Policy->IedTraceSize;
4 MB default
Allocate IED trace buffer for socket 0 (BSP)
IedTraceAddress = AllocateIedTraceBuffer (IedTraceSize);
Status = SetupPpmStructures ();
AypScratchpad = (UINT32)(AsmReadMsr64 (0x13FE) >> 32); // AYP debug scratchpad7
CPU stepping
Is2lm = (Policy->MemoryMode == 2LM_MODE);
Disable MONITOR/MWAIT via MSR or CPU policy register
if (Policy->NmFwEfficientBoot) {
Write Efficient Boot frequency MSR
AsmWriteMsr64 (MSR_NM_FW_EFFICIENT_BOOST, Policy->EfficientBootFrequency);
Write Performance Boot frequency MSR
AsmWriteMsr64 (MSR_NM_FW_PERF_BOOST, Policy->PerformanceBootFrequency);
Read current per-socket HWPM/PBF values from MSR
HwpmPbfHighPriCoreMap = AsmReadMsr64 (MSR_HWPM_PBF_CONFIG);
PbfEnabled = Policy->PbfEnabled;
CpuPolicyEx1 = Policy->PolicyEx1;
Store the final MSR value for the CPU policy
AsmWriteMsr64 (MSR_CPU_POLICY_EX1, CpuPolicyEx1);
Read the current TlsCaCertificate variable
VariableSize = 0;
Convert the binary variable data to an HII config string
and return via Results
if (VariableData != NULL) {
Route config implementation
UEFI Variable Setup for NVRAM storage
Locate the SetupLib protocol interface
Initialize the combined variable buffer
ZeroMem (&gVariableStorage, sizeof (gVariableStorage));
Walk the static variable table and read each variable
VarTable = &gSetupVariableTable;
Status = ((SETUP_PROTOCOL *)SetupProtocol)->GetVariable (
Use UEFI Runtime Services GetVariable directly
Buffer = AllocatePool (VarSize);
Status = gRT->SetVariable (
if (SetupLibReady) {
TotalBufferSize += VarSize;
Debug Output Helpers
Read BIOS debug level from CMOS 0x4B
Port70 = __inbyte (0x70);
BiosDebugLevel *= ((UINT8 *)0xFDAF0490 & 2) 1;**
switch (BiosDebugLevel) {
if ((DebugLevel & ErrorLevel) != 0) {
Format the string
AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaList);
Write to serial port
BufferSize = AsciiStrLen (Buffer);
while (TRUE) {
Poll until THR (Transmitter Holding Register) is empty
while ((__inbyte (UART_BASE_PORT + 5) & 0x20) == 0);
__outbyte (UART_BASE_PORT, Buffer[Index]);
Library functions imported from BaseLib / BaseMemoryLib
InternalVSPrint (StartOfBuffer, BufferSize, FormatString, VaList);
Static variable table for setup
Variable definitions table for GetSetupVariables
STATIC SETUP_VARIABLE mSetupVariableTable[] = {
IED Trace buffer size
PBF configuration
Turbo //
Combined global variable storage
STATIC UINT8 mGlobalVariableStorage[0x2A3B];

Generated by HR650X BIOS Decompilation Project