Newer
Older
AMI-Aptio-BIOS-Reversed / PeiIpmiBmcInitialize / PeiIpmiBmcInitialize.md
@Ajax Dong Ajax Dong 2 days ago 10 KB Init

PeiIpmiBmcInitialize

Function Table

Address Name Description
GetReportStatusCode
ReportStatusCode
DebugAssert
IoRead32
IoRead16
ReadIdtr
ReadUnaligned64
ReadPcd32
GetPcd32
GetPcd32Plus
CmosRead8
PchGetSku
PchIsAccessibleByPcr
PchPcrWrite
PchGetDecodeRanges
MicroSecondDelay
MicroSecondDelayEx
BmcKcsWriteByte
BmcKcsReadByte
BmcKcsWaitForIbf
BmcKcsFlush
BmcKcsCheckWriteReady
BmcKcsWaitForObf
BmcKcsSendMessage
BmcKcsReceiveMessage
BmcKcsSendData
BmcKcsReadData
BmcKcsSendCommand
BmcKcsGetResponse
BmcDoIpmiCmd
BmcParseResponseCode
PchDecodeRangeSetup
PchDecodeRangeProg
PchDecodeRangeGet
PchDecodeRangeSet
CheckPowerFailure
DecodeBmcBaseAddress
ModuleEntryPoint
BmcProcessSoftErrorChar
BmcKcsBuildAndSend
BootGuardCheckTpm
BootGuardGetTpmRevision
ConstructorModule
LocatePcdPpi
External data references from .rdata / .data segments
extern UINT32 gPeiServicesIdt; // PPI GUID data
Setup variable GUID
PCH decode ranges array
PCH global reference data
Debug assert / report helper
STATIC UINT32
Report status code with debug message (ReportStatusCodeEx via PPI)
VOID ReportStatusCode (
Debug print macro using ReportStatusCode
STATIC VOID
Memory operations (from BaseMemoryLib)
Dst8 = (UINT8 *)DestinationBuffer + Length - 1;
Count = Length >> 2;
CopyMem wrapper (with bounds checks)
STATIC VOID *
ZeroMem with overflow check
IO Port access (abstracted)
Read 32-bit IO port (aligned check)
UINT32 IoRead32 (
Read 16-bit IO port (alignment check)
UINT16 IoRead16 (
INT16 IoWrite16 (
SIDT / PEI Services table pointer via IDT
HOB (Hand-Off Block) utilities
End of HOB list
Condition check placeholder
Compare GUID using ReadUnaligned64
Unaligned read of 64-bit
PCD (Platform Configuration Database) Access
PCD get wrappers
UINT32 GetPcd32 (
CMOS / RTC Debug Level
Get debug error level from CMOS
INTN GetDebugLevel (
PCH SKU Detection
PCH_SKU_DEFAULT UINT8
PCH PCR Register Access (MMIO)
PCH PCR PID 0xAF - LPC?
if (Sku == PCH_SKU_LBG) {
PCH PCR PID 0xAE
PCH PCR PID 0xAD
PCH PCR PID 0xAC
PCH PCR PID 0x90
PID 0xB1 - root?
Default case
PCR Write via MMIO or SBI
EFI_STATUS PchPcrWrite (
PCH Cycle Decoding - IPMI IO Range Configuration
Decode IPMI base from PCH cycle decode registers
STATIC EFI_STATUS
Read the 4 decode range registers from PCH
for (Index = 0; Index < PCH_DECODE_RANGE_COUNT; Index++) {
VOID MicroSecondDelay (
3579545 Hz prescale
Wait for ACPI timer delta to equal the requested microseconds
Start = MicroSeconds + (IoRead32 (0x508) & 0xFFFFFF);
Convert microseconds to ACPI timer ticks then call MicroSecondDelay
UINT32 MicroSecondDelayEx (
KCS BMC Interface Layer
KCS write byte: abstracted for IO vs memory mapped
VOID BmcKcsWriteByte (
KCS read byte: abstracted for IO vs memory mapped
UINT8 BmcKcsReadByte (
Wait for IBF (Input Buffer Full) to clear
EFI_STATUS BmcKcsWaitForIbf (
KCS Abort / Flush
EFI_STATUS BmcKcsFlush (
Wait for IBF to clear
while (TRUE) {
Write GET_STATUS to command register
BmcKcsWriteByte (BmcPrivate->InterfaceType, BmcPrivate->DataReg, IPMI_KCS_CTRL_GET_STATUS);
Read status from command register
if (BmcPrivate->InterfaceType == BMC_INTERFACE_TYPE_IO) {
Write 0 to command register (clear)
BmcKcsWriteByte (BmcPrivate->InterfaceType, BmcPrivate->CommandReg, 0);
Check status response
if ((Status & IPMI_KCS_STATUS_CD) == 0x40) {
Normal response: wait for OBF and read data
Timeout = BmcPrivate->Timeout;
Unexpected status - retry
if (++Retries >= BMC_MAX_RETRY) {
Wait for final OBF
Check KCS status for write readiness
EFI_STATUS BmcKcsCheckWriteReady (
IO mode: use DataReg / CommandReg directly
Check falls through to main KCS handler
Memory mapped: pointer in BmcPrivate->CommandReg
Wait for OBF (Output Buffer Full)
EFI_STATUS BmcKcsWaitForObf (
KCS Send Message (command phase)
EFI_STATUS BmcKcsSendMessage (
This function writes the KCS message body using the WRITE_START / WRITE_END protocol
A1 is the context pointer offset, CmdDataSize is the number of bytes to send
Implemented in BmcKcsSendData/BmcKcsSendCommand
KCS Receive Message (response phase)
EFI_STATUS BmcKcsReceiveMessage (
This function reads the KCS response using the READ protocol
This is called after WRITE_START to send data bytes, then WRITE_END to finalize
KCS Read data bytes from BMC
EFI_STATUS BmcKcsReadData (
Read response data bytes
BMC KCS Full Command/Response (NetFn/Lun/Cmd + data)
BMC KCS: Send command with data and get response
EFI_STATUS BmcKcsSendCommand (
BMC KCS Get Response
EFI_STATUS BmcKcsGetResponse (
BMC IPMI command via KCS
EFI_STATUS BmcDoIpmiCmd (
Parse completion code from KCS response (BMC-specific codepage char)
Called when completion code indicates a character that maps to a known error
Handle response code 0x7E-0xBF ranges for error parsing
PCH Decode Range Programming for IPMI IO Base
Setup IPMI IO decode range in PCH
EFI_STATUS PchDecodeRangeSetup (
Check if IPMI range (0xCA0) already decoded
Check if this range covers 0xCA0 or 0xCB0
if ((BaseIo <= IPMI_IO_BASE_DEFAULT &&
Found existing decode
Existing range found. Check if it fully covers IPMI IO.
if (BaseIo <= IPMI_IO_BASE_DEFAULT && DecodeSize >= 0x10) {
Need to extend or create new range.
Calculate decode size and base address.
DecodeSize = BaseIo + DecodeSize;
n16 = DecodeSize - BaseIo (adjusted)
Fall through to program the decode
No range found covering IPMI. Check if any free range available.
FreeIndex = PchDecodeFindFreeRange (Ranges);
Check for free slot by scanning (some ranges may not have base)
Check platform policy
if (MEMORY[PCH_PCR_LPC_IPMI_REG] >= 0) {
n144 **= n3232 (((n16 - 1) & 0xFC) << 16) 1**
16 bytes for IPMI
DecodeSize = (n16 - 1) & 0xFC
RangeValue **= BaseIo ((DecodeSize & 0xFC) << 16) 1**
Program the decode range register
Program via PCR
RangeValue **= BaseIo (((DecodeSize - 1) & 0xFC) << 16) 1**
Write to PCR decode register
Program the PCH decode range for IPMI
VOID PchDecodeRangeProg (
Determine index from base
Read PCH PCR cycle decode register
UINT32 PchDecodeRangeGet (
VOID PchDecodeRangeSet (
Get PCH register base
VOID *
Power Failure Detection
Decode BMC Base Address via PCH cycle decoding registers
PEIM Entry Point
Verify PEI Services revision
PeiServices = (PEI_SERVICES )GetPeiServices ();**
Check if PCD needs to be set up (bit 7 of byte 1024068)
if (((volatile INT8 )((UINTN)GetPeiPcdPpi () + 1024068) & 0x80) == 0) {
Locate setup variable PPI
Status = (*PeiServices)->LocatePpi (
Read ServerSetup variable
n1072 = 1072;
Allocate BMC private data structure
BmcPrivate = (BMC_PRIVATE_DATA *)AllocateZeroPoolCheck (336);
Call initialization functions from table
Index = 0;
Initialize BMC private structure
Initialize function pointers for IPMI KCS transport
Will be filled by init code
Continue initialization at address 0xFFE5B7EF
PEIM Init Function Table (referenced from .rdata at funcs_FFE5BB6C)
STATIC CONST
Initialize BMC decode
Terminator };
BMC Soft Error Character Handling
Process a character from the BMC response (soft error)
Table of known completion code characters
Encoded completion code characters
KCS Send Command: Build message and send via KCS
Build KCS command frame and send via KCS transport
EFI_STATUS BmcKcsBuildAndSend (
Boot Guard TPM Detection and Initialization
Check if Boot Guard TPM requires action
BOOLEAN BootGuardCheckTpm (
Get Boot Guard TPM revision
UINT8 BootGuardGetTpmRevision (
Module Constructor: ASSERT for PEIM entry point conditions
Module global PEI services pointer (from IDT-based lookup)
PEI_SERVICES **gPS;
PCD Access for PEI Phase (using PCD PPI)

Generated by HR650X BIOS Decompilation Project