| Address | Name | Description |
|---|---|---|
| ModuleEntryPoint | ||
| SmmStatusCodeDriverInit | ||
| SmmStatusCodeRegisterProtocols | ||
| SmmStatusCodeRegisterCallback | ||
| SmmStatusCodeUnregisterCallback | ||
| SmmStatusCodeDispatchCallbacks | ||
| SmmStatusCodeHandler | ||
| SmmStatusCodeAssertHandler | ||
| SmmStatusCodeProgress | ||
| StatusCodeFormatString | ||
| StatusCodeReportError | ||
| StatusCodeWriteSerial | ||
| StatusCodeReportToSerial | ||
| StatusCodeWritePort80 | ||
| StatusCodeCheckAndEnable | ||
| SMM | Status Code Reporting Driver | |
| Decompiled | and reconstructed from IDA Pro analysis of the | |
| Lenovo | HR650X BIOS UEFI firmware image. All functions have been | |
| identified | and renamed for clarity. | |
| This | SMM driver provides status code reporting infrastructure | |
| within | System Management Mode. It intercepts SMI events triggered | |
| by | status code writes and routes them to configurable output | |
| channels | (serial, port 80 POST codes) and registered callbacks. | |
| Global | variable storage | |
| EFI_HANDLE | gImageHandle; | |
| Static | data tables (defined in .rdata) | |
| Error | code lookup table. | |
| Each | entry: {UINT32 StatusCode, UINT32 StringOffset} | |
| Terminated | by {0, 0}. | |
| Correctable | memory error | |
| CPU | thermal error | |
| CPU | low voltage | |
| CPU | high voltage | |
| Correctable | CPU ECC error | |
| terminator | }; | |
| Module | Entry Point (_ModuleEntryPoint at 0x500) | |
| Standard | UEFI driver entry. Initializes SMM environment, registers | |
| SMI | handlers with error recovery via SetJump/LongJump. | |
| EFI_STATUS | EFIAPI | |
| These | ASSERTs fire only if LongJump fails (should never happen) | |
| SmmStatusCodeDriverInit | (0x5B4) | |
| Initializes | the SMM driver environment: | |
| VOID | SmmStatusCodeDriverInit ( | |
| Save | global pointers | |
| Locate | SMM Base2 protocol | |
| Locate | SMM Access2 protocol to get SMRAM sizes | |
| Read | PCI Express base address from PCD | |
| Locate | HOB list | |
| Configure | LPC serial port (if enabled) | |
| PCI | config address 0xFA004 = LPC command register (B0/D31/F0/Reg4) | |
| PCI | config address 0xFA000 = LPC vendor/device ID register | |
| Set | I/O base to 0x500 | |
| Enable | memory space (bit 1 of command register) | |
| Wait | for TCO timer to stabilize | |
| Port | 0x508 is the TCO I/O base register | |
| Restore | interrupt state | |
| SmmStatusCodeRegisterProtocols | (0xCD0) | |
| Registers | three SMM handlers: | |
| EFI_STATUS | SmmStatusCodeRegisterProtocols ( | |
| Handler | #1: Register SmmStatusCodeHandler via EFI_SMM_CPU_IO2_PROTOCOL | |
| This | causes the handler to fire on CPU I/O operations that generate | |
| status | code SMI events. | |
| via | gSmmStatusCodeHandlerPtr | |
| Handler | #2: Register callback management protocol | |
| Handler | #3: Register progress/status code protocol | |
| SmmStatusCodeRegisterCallback | (0x8F0) | |
| Registers | a callback function pointer in the callback table. | |
| Callbacks | are invoked when status code events occur. | |
| UINT64 | SmmStatusCodeRegisterCallback ( | |
| RETURN_INVALID_PARAMETER | } | |
| Reuse | empty slot | |
| SmmStatusCodeUnregisterCallback | (0x8A8) | |
| Removes | a callback function pointer from the callback table. | |
| UINT64 | SmmStatusCodeUnregisterCallback ( | |
| SmmStatusCodeDispatchCallbacks | (0x988) | |
| Iterates | all registered callback functions and invokes each with | |
| the | status code parameters. | |
| Uses | a reentrancy guard (gReentrancyGuard) to prevent recursive | |
| callback | dispatch. | |
| is | already in progress | |
| UINT64 | SmmStatusCodeDispatchCallbacks ( | |
| SmmStatusCodeHandler | (0xB84) | |
| The | main SMI status code handler. Called when a status code SMI | |
| dispatches | registered callbacks, and outputs to serial. | |
| VOID | SmmStatusCodeHandler ( | |
| Invoke | per-status-code callbacks | |
| SmmStatusCodeAssertHandler | (0xC24) | |
| Invoked | when an ASSERT condition fires in SMM. Formats the assert | |
| message | with file/line info, dispatches assert-specific callbacks | |
| and | outputs via serial. | |
| UINT64 | SmmStatusCodeAssertHandler ( | |
| Invoke | assert-specific callbacks | |
| SmmStatusCodeProgress | (0xA58) | |
| Handles | status code progress (type 1) and error (type 2) events. | |
| Dispatches | registered callbacks, runs enable/disable checks | |
| formats | the status string, outputs to serial, and handles | |
| For | EFI progress codes (type == 2), also queries a progress function | |
| table | for matching dispatch. | |
| UINT64 | SmmStatusCodeProgress ( | |
| Run | enable/disable filter check callbacks | |
| Run | progress-specific callbacks | |
| For | progress type 2, dispatch via progress function table | |
| StatusCodeFormatString | (0xE1C) | |
| Examines | the status code data GUID to determine its type and | |
| formats | the output string accordingly: | |
| Extracts | text from data payload, converts Unicode to ASCII | |
| Uses | format string from offset +120 and args from offset +24 | |
| Reads | line number and file/description from payload. | |
| Requires | type=2, class=0x90, subclass=7. | |
| Reads | line number at offset +60 and file at offset +80. | |
| No | GUID match + Type 2: delegates to StatusCodeReportError | |
| No | GUID match + other types: returns 0 (no output) | |
| UINT64 | StatusCodeFormatString ( | |
| Skip | header to get GUID | |
| Check | #1: Plain string data GUID | |
| Copy | string from payload | |
| Check | #2: Standard string type GUID | |
| Check | #3: AMI DataHub ASSERT GUID | |
| Check | #4: AMI ASSERT GUID | |
| Fall | through to FormatAssert | |
| StatusCodeReportError | (0xD94) | |
| Looks | up a status code in the known error code table (gErrorCodeTable). | |
| If | the code is found, formats "ERROR: %a" with the error description | |
| string | from the status code data payload. | |
| If | the code is not found (or table empty), formats the raw status | |
| code | as three hex fields: "ERROR: Class:%X; Subclass:%X; Operation: %X\n" | |
| UINT64 | StatusCodeReportError ( | |
| Found | in table - format with string from data payload | |
| Not | found - format raw hex values | |
| StatusCodeWriteSerial | (0xFE8) | |
| Writes | a string to the serial port with proper CR/LF handling. | |
| UINT64 | StatusCodeWriteSerial ( | |
| Bare | "\n" - flush accumulated prefix and emit "\r\n" | |
| StatusCodeReportToSerial | (0x105C) | |
| Dispatches | to StatusCodeWriteSerial (primary) and any additional | |
| output | handlers registered in the output callback table. | |
| UINT64 | StatusCodeReportToSerial ( | |
| Primary | serial output | |
| StatusCodeWritePort80 | (0x109C) | |
| Writes | a byte to the hardware POST code display port (0x80). | |
| Used | for debug POST cards or BMC POST code capture. | |
| UINT64 | StatusCodeWritePort80 ( | |
| StatusCodeCheckAndEnable | (0x10A8) | |
| For | type 1 (progress) and type 2 (error), looks up the status code | |
| value | in the enable/disable table. If the code is enabled, invokes | |
| the | port 80 write callbacks (including StatusCodeWritePort80). | |
| UINT64 | StatusCodeCheckAndEnable ( | |
| Walk | the enable table for this type | |
| These | are standard UEFI library implementations compiled into this | |
| module | by the build system (MdePkg BaseLib, BasePrintLib, etc.). | |
| They | are documented here for completeness. | |
| SetJump | (0x2C0) / LongJump (0x360) | |
| SetJump | saves: RBP, stack pointer, return address, XMM regs | |
| LongJump | restores context and jumps to the saved return point. | |
| SetJumpValidate | (0x1130) | |
| Validates | the jump buffer alignment (must be 8-byte aligned). | |
| DebugAssert | (0x132C) | |
| Formats | an ASSERT message string using AsciiSPrint. | |
| DebugAssertWorker | (0x1210) | |
| Callback | to the standard error interface (via protocol at 0x3ED0). | |
| If | the protocol is available, formats: file, line, message. | |
| GetStandardErrorInterface | (0x1178) | |
| Locates | the SMM standard error protocol (GUID at 0x3ED0) and caches | |
| it | in qword_4F68. | |
| DebugPrint | (0x11C8) | |
| Conditional | debug print: checks error level against current setting | |
| invokes | the standard error interface if enabled. | |
| GetDebugPrintErrorLevel | (0x2AC8) | |
| Reads | the debug print error level from CMOS offset 0x4C. | |
| If | the CMOS value is out of range, checks a memory-mapped | |
| location | (0xFDAF0490) for the BMC-preserved value. | |
| Returns | 0 (disabled), 0x80000004 (level 1), or 0x80000006 (level 2+). | |
| SerialPortWrite | (0x2A18) | |
| Detects | Super I/O type via SIO port 0x72/0x73: | |
| Writes | bytes to serial port data register at (base + 0). | |
| Waits | for THR empty (LSR bit 6). Bursts up to 16 bytes per | |
| AsciiSPrint | (0x1404) - ~3573 bytes (0xDF5) | |
| Full | UEFI AsciiSPrint implementation from BasePrintLib. | |
| Supports | format specifiers: | |
| String | length limited to 0xF4240 (1,000,000) characters. | |
| AsciiSPrintUnsafe | (0x2984) | |
| Thin | wrapper that va_start's and calls SPrint. | |
| SPrint | (0x2544) - Unicode-aware printf | |
| Full | SPrint implementation from PrintLibInternal.c supporting | |
| all | standard format specifiers documented above. | |
| StatusToString | (0x247C) | |
| Converts | EFI_STATUS value to human-readable string: | |
| EFI_SUCCESS | (0) -> "EFI_SUCCESS" | |
| Warning | codes (0x2xxxxxxx) -> "EFIWARN..." | |
| Error | codes (0x8xxxxxxx) -> various error strings | |
| Interrupt | codes (0xAxxxxxxx) -> "EFI_INTERRUPTPENDING..." | |
| Unrecognized | values -> NULL | |
| String | table is embedded in .rdata at known offsets. | |
| ValueToString | (0x2334) | |
| Converts | integer value to ASCII string in given base (10 or 16). | |
| Supports | negative values for base 10. | |
| AsciiStrDecimalToUintn | (0x23A8) | |
| Parses | a decimal string to UINTN. Skips leading whitespace | |
| handles | +/- sign. Supports hex digits a-f/A-F (returns base-10). | |
| AsciiStrSetChar | (0x1358) | |
| Fills | a buffer with repeated character (1-byte ASCII or 2-byte Unicode). | |
| Uint64ToAsciiString | (0x138C) | |
| Converts | UINT64 to ASCII hex string using LookupTable "0123456789ABCDEF". | |
| CompareMem | (0x29A4) | |
| Memory | compare. Compares byte-by-byte with qword optimization for | |
| aligned | sections. | |
| IsAddressInSmram | (0x1250) | |
| Checks | if an address falls within any known SMRAM descriptor range. | |
| SmmAllocatePool | (0x1294) | |
| Allocates | SMM pool memory via gSmst->SmmAllocatePool. | |
| SmmFreePool | (0x12C4) | |
| Frees | memory via gSmst->SmmFreePool if in SMRAM, or gBS->FreePool | |
| if | not. Used during module unload or error cleanup. | |
| IsHobGuidType | (0x2BF4) | |
| Checks | if a HOB entry matches a known GUID type by comparing | |
| the | Buffer_ and Buffer__0 GUIDs. | |
| GetHobList | (0x225C) | |
| Walks | the System Table firmware volume HOB entries to find the | |
| HOB | matching known GUIDs. Caches result in qword_4F78. | |
| GetPcdProtocol | (0x2CD4) | |
| Locates | the EFI_PCD_PROTOCOL (GUID {11B34006-...}) | |
| via | gBS->LocateProtocol. Caches result in qword_4F90. | |
| PciExpressGetAddress | (0x2220) | |
| Calculates | the MMIO address for a PCI config space register: | |
| result | = Address + gPciExpressBaseAddress | |
| Requires | Address < 0x10000000. | |
| PciExpressWrite8 | (0x21FC) | |
| Writes | a byte to PCI config space via the PCIe MMIO address window. | |
| Standard | UEFI BaseLib string utility functions. | |
| CpuPause | (0x3E0), ReadTsc (0x3F0) | |
| EnableInterrupts | (0x400), DisableInterrupts (0x410) | |
| GetCallerEflags | (0x420) | |
| Intrinsic | functions: | |
| CpuPause | = _mm_pause() | |
| ReadTsc | = __rdtsc() | |
| EnableInterrupts | = _enable() (STI) | |
| DisableInterrupts | = _disable() (CLI) | |
| GetCallerEflags | = __getcallerseflags() (PUSHFQ) | |
| IoWrite16 | (0x2C64) - Write 16-bit value to I/O port | |
| IoRead32 | (0x2CA4) - Read 32-bit value from I/O port | |
| ReadUnaligned16 | (0x2B18) - Read 16-bit from potentially unaligned addr | |
| ReadUnaligned64 | (0x2B48) - Read 64-bit from potentially unaligned addr | |
| StrLen | (0x2B78) - Unicode string length | |
| AsciiStrLen | (0x2BD0) - ASCII string length |
Generated by HR650X BIOS Decompilation Project