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

OpromUpdateDxeLightningRidgeEXECB1

Function Table

Address Name Description
__inbyte
__outbyte
OpromGetConfigA
OpromGetConfigB
OpromGetConfigC
OpromSetSlotNumber
DebugPrint
DebugAssert
IsHobListGuid
IsPcieSlotConfigured
ReadUnaligned64
_ModuleEntryPoint
NULL // ============================================================================
Platform I/O Intrinsics (MSVC inbyte / outbyte replacements)
Embedded Binary Data (PCIe Configuration Tables and GUIDs)
GUID storage block at 0xCE0 in .rdata.
Contains four GUIDs used by the driver.
static CONST UINT8 GuidBlock[0x80] = {
OpROM update protocol interface data block (at 0xF00 in original image).
This structure serves as the registered protocol interface.
It starts with a signature/header ("PBDS") followed by callbacks.
static CONST UINT8 OpromUpdateProtocolData[0x38] = {
Version = 1
Size = 0x048C
Function pointers (offsets 0x10-0x28) - set to 0 in data section;
in the actual binary these are relocation entries that get fixed up
by the DXE dispatcher to point to the actual function addresses.
Null terminator
PCIe configuration table A (at address 0xD20 in original image).
Contains PCIe root port and device configuration entries.
static CONST UINT8 PcieConfigTableA[0xE6]; // Content documented below
PCIe configuration table B (at address 0xD60 in original image).
6 entries of OpROM update PCIe config data.
static CONST UINT8 PcieConfigTableB[0x150]; // Content documented below
PCIe configuration table C (at address 0xE60 in original image).
static CONST UINT8 PcieConfigTableC[0x70]; // Content documented below
Slot configuration table (at address 0xED1 in original image).
8 entries, each 4 bytes, defining PCIe slot BDF addresses.
static CONST UINT8 PcieSlotConfigTable[0x20] = {
Slot 0: B=0x03 D=0x00 F=0x00
Slot 1: B=0x01 D=0x80 F=0x00 (Dev=16, Func=0)
Slot 2: B=0x02 D=0x80 F=0x00 extra=0x02
Slot 3: B=0x03 D=0x80 F=0x00
Slot 4: B=0x02 D=0x00 F=0x00
Slot 5: B=0x01 D=0x00 F=0x00 extra=0x05
Slot 6: B=0x1C D=0x00 F=0x00 (extended)
Slot 7: B=0x03 D=0x80 F=0x00 extra=0x9C
Global Variables (.data segment)
Cached pointer to the OpROM update protocol interface.
Resolved once by GetDebugLibProtocol() and reused thereafter.
static VOID *gOpromUpdateProtocol = NULL;
Cached pointer to the HOB (Hand-Off Block) list.
Resolved once by GetHobList() and reused thereafter.
VOID *gHobList = NULL;
Callback Implementations
Log debug message: "[UBA]:SetPcieSlotNumber callback - %d\n"
with the slot number value (always 0 on this platform).
DebugPrint (DEBUG_INFO, "[UBA]:SetPcieSlotNumber callback - %d\n", 0);
Protocol Resolution
Check if protocol was already resolved.
if (gOpromUpdateProtocol != NULL) {
Allocate pool for the protocol interface.
The pool type used corresponds to memory type 31 (implementation-specific
allocation type for UBA protocol interfaces).
AllocatePool signature: (PoolType, Size, Buffer).
Initialize the protocol interface with callback pointers.
The interface is initialized by setting up the internal callback table
with the four platform-specific functions.
Locate the DebugLib protocol using gBS->LocateProtocol().
If the protocol cannot be located (e.g., not yet installed), set the
cached pointer to NULL so the caller can handle gracefully.
LocateProtocol signature: (Protocol, Registration, Interface).
if (EFI_ERROR((*gBS->LocateProtocol)(&GuidBlock[0x20], NULL, &gOpromUpdateProtocol))) {
Debug Output
Resolve the DebugLib/OpROM protocol interface.
Protocol = GetDebugLibProtocol ();
Determine platform type from CMOS register 0x4B.
Read the CMOS register using port I/O instructions.
CmosValue = __inbyte (RTC_INDEX_PORT);
Validate platform type. If > 3, use as-is.
If == 0, fall back to MMIO register at 0xFDAF0490.
if (PlatformType > 3) {
PlatformType is valid as-is
Platform type 1..3 = valid
Check if the platform type matches the Lightning Ridge EXEC B1 type.
if ((PlatformType - 1) <= 0xFD) {
Build the error mask for this platform:
if (PlatformType == OPROM_PLATFORM_TYPE_LIGHTNING_RIDGE) {
If the requested ErrorLevel matches the platform's error mask
call the DebugLib protocol's output function (at offset 0x00).
if ((ErrorMask & ErrorLevel) != 0) {
Invoke the debug output function.
directly pointing to the stack location after Format. In the actual
UEFI DebugLib implementation, this is the DebugVPrint function.
Assertion Handler
Resolve the DebugLib protocol interface.
Call the assertion handler function at offset 0x08 in the
protocol interface. The assertion handler is accessed via pointer
arithmetic on the raw protocol interface.
HOB List Management
Return cached value if already resolved.
if (gHobList != NULL) {
Initialize and iterate through configuration tables.
gHobList = NULL;
Walk the configuration table array.
Each entry is 24 bytes (sizeof(EFI_CONFIGURATION_TABLE)).
for (Index = 0; Index < TableCount; Index++) {
Check if this table's VendorGuid matches EFI_HOB_LIST_GUID.
if (IsHobListGuid (NULL, &ConfigTable[Index].VendorGuid)) {
If no HOB list was found, trigger assertion failure.
if (gHobList == NULL) {
Read the expected GUID halves from the GUID storage block.
The EFI_HOB_LIST_GUID is stored at GuidBlock + 0x10.
ExpectedFirstHalf = ReadUnaligned64 (&GuidBlock[0x10]);
Read the target GUID as two 64-bit halves.
GuidFirstHalf = ReadUnaligned64 (GuidPtr);
Both halves must match.
return (GuidFirstHalf == ExpectedFirstHalf) && (GuidSecondHalf == ExpectedSecondHalf);
Slot Population Detection
Locate the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
The protocol GUID is stored at GuidBlock + 0x00.
Status = (*gBS->LocateProtocol) (&GuidBlock[0x00], NULL, (VOID )&RootBridgeIo);**
Iterate through 8 slot entries in the slot configuration table.
Each entry is 4 bytes.
SlotEntry = PcieSlotConfigTable;
Extract slot PCI address from the configuration table:
SlotPrevExtra = byte3 of PREVIOUS entry (or 0 for first entry
since the byte before the table is 0)
SlotBus = byte0 of CURRENT entry
SlotDevice = byte1 of CURRENT entry
If Index == 0, SlotPrevExtra is read from the byte preceding
the slot configuration table (which is 0x00).
if (Index == 0) {
byte3 of previous entry
byte0 SlotDevice = SlotEntry[1]; // byte1
Check if this slot's BDF matches the target BDF address.
If the slot's bit in 'flags' is not set, skip this slot.
if ((Reserved & (1 << Index)) == 0) {
Build the PCI config space address for this slot:
SlotBdfAddress **= (SlotPrevExtra << 8) (SlotBus << 16) (SlotDevice << 24)**
SlotBdfAddress = ((UINT64)SlotPrevExtra << 8)
Read registers at offsets 0x19 (BIST) and 0x1A (Header Type)
via the PciRootBridgeIo protocol. The PCI Read function is at
offset 0x38 (56) within the protocol interface structure.
EfiPciWidthUint8 **SlotBdfAddress PCI_REG_BIST**
EfiPciWidthUint8 **SlotBdfAddress PCI_REG_HEADER_TYPE**
Check if the target BDF address falls within the range defined by
this slot. The BIST value is the lower bound and Header Type is
the upper bound.
if (BdfAddress >= BistValue && BdfAddress <= HeaderTypeValue) {
Advance to the next slot entry (4 bytes per entry).
SlotEntry += 4;
Utility Functions
Validate Buffer is not NULL.
if (Buffer == NULL) {
Read 8 bytes from the buffer as a 64-bit value.
Cast to volatile to prevent compiler optimizations from re-ordering
or combining the access.
return (CONST UINT64 )Buffer;
Module Entry Point
Validate input parameters.
if (ImageHandle == NULL) {
Cache global pointers.
gImageHandle = ImageHandle;
Locate HOB list (ensures PCI enumeration data is available).
Initializes gHobList for use by the UBA framework.
GetHobList (ImageHandle);
Log debug banner indicating this is the OpROM Update driver for
the Lightning Ridge EXEC B1 platform.
DebugPrint (DEBUG_INFO, "UBA:OpromUpdate-TypeLightningRidgeEXECB1\n");
Locate the UBA Lightning Ridge EXEC B1 board-type protocol.
The protocol GUID is stored at GuidBlock + 0x40.
If the UBA protocol was found, register the OpROM update configuration.
The registration function is at offset 0x10 in the protocol interface.
if (!EFI_ERROR (Status)) {
Same GUID as protocol
0x30 bytes

Generated by HR650X BIOS Decompilation Project