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