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

OpromUpdateDxeLightningRidgeEXECB3

Function Table

Address Name Description
_ModuleEntryPoint
DebugPrint
DebugAssert
IsHobListGuid
ReadUnaligned64
IsPcieSlotConfigured
OpromGetConfigA
OpromGetConfigB
OpromGetConfigC
OpromSetSlotNumber
UEFI standard protocol pointer caches (set by _ModuleEntryPoint)
Image addr 0xF30: gST
Image addr 0xF38: gBS
Image addr 0xF40: gImageHandle
Image addr 0xF48: gRT
EFI_SYSTEM_TABLE *gST = NULL;
Cached protocol/hand-off block pointers (resolved lazily)
Image addr 0xF50: gOpromProtocol (UBA DebugLib protocol cache)
Image addr 0xF58: gHobList (HOB list pointer cache)
UBA_DEBUG_LIB_PROTOCOL *gOpromProtocol = NULL;
Step 1: Cache UEFI standard protocol pointers.
These are also set by the library constructors in
UefiBootServicesTableLib and UefiRuntimeServicesTableLib
but we cache them explicitly here for robustness.
gImageHandle = ImageHandle;
Step 2: Resolve the HOB (Hand-Off Block) list.
This walks SystemTable->ConfigurationTable[] looking for the entry
with VendorGuid == EFI_HOB_LIST_GUID ({7739F24C-...}).
The associated VendorTable pointer is the HOB list header.
Result is cached in gHobList (image addr 0xF58).
GetHobList ();
Step 3: Print the platform identification banner.
ErrorLevel 0x80000000 is the UBA-specific debug severity mask.
DebugPrint (0x80000000, "UBA:OpromUpdate-TypeLightningRidgeEXECB3\n");
Step 4: Locate the UBA_CONFIG_PROTOCOL.
GUID {E03E0D46-5263-4845-B0A4-58D57B3177E2} identifies the
ConfigBuffer = 0;
Step 5: Call the protocol's RegisterConfig function.
The function pointer is at vtable index 2 (offset 0x10).
EFI_STATUS (*RegisterConfig)(
VOID *This
CONST EFI_GUID *ConfigGuid
CONST VOID *ConfigData
UINTN ConfigDataSize
ConfigGuid = &gOpromUpdateConfigDataGuid
ConfigData = &mOpromUpdateConfig (PBDS structure, 48 bytes)
DataSize = 48 (sizeof(OPROM_UPDATE_CONFIG))
UbaConfigProtocol = (VOID *)ConfigBuffer;
Return cached pointer if already resolved.
if (gOpromProtocol != NULL) {
Check available pool size by allocating and immediately freeing.
Type 31 is EfiBootServicesData in this platform's memory map.
If only <= 0x10 bytes available, return NULL.
Resolve the UBA DebugLib protocol.
Resolve the DebugLib protocol (lazy initialization).
Protocol = GetDebugLibProtocol ();
Read CMOS register 0x4B to determine the board platform type.
CMOS access sequence:
PlatformType = IoRead8 (0x70); / Save NMI state /
If CMOS returned > 3 and == 0, the register is uninitialized.
Fall back to MMIO at 0xFDAF0490 (GPIO or strapping register).
Extract bit 1, OR with 1 to get platform type 1 or 3.
if (PlatformType > 3) {
Select debug mask based on platform type.
if (PlatformType == 1) {
Check if the error level matches the platform debug mask.
If no bits match, suppress the output.
if ((DebugMask & ErrorLevel) == 0) {
Call the protocol's DebugPrint function at vtable offset 0x00.
The protocol's DebugPrint uses VA_LIST, not variadic args.
VA_START (VaList, Format);
Call the protocol's assertion handler at vtable offset 0x08.
if (gHobList != NULL) {
Access the configuration table array from the system table.
SystemTable + 0x68 = NumberOfTableEntries (UINTN)
SystemTable + 0x70 = ConfigurationTable (EFI_CONFIGURATION_TABLE *)
TableCount = gST->NumberOfTableEntries;
Iterate through the configuration table entries to find the HOB list.
Each entry is 24 bytes: 16-byte VendorGuid + 8-byte VendorTable pointer.
We compare the first 8 bytes and next 8 bytes separately via
ReadUnaligned64 against the reference GUID halves.
if (ConfigTable != NULL) {
Found the HOB list GUID. The associated VendorTable pointer
is the HOB list (PHIT HOB header).
gHobList = (VOID *)ConfigTable[Index].VendorTable;
If we didn't find the GUID in any table entry, trigger an ASSERT.
if (gHobList == NULL) {
If the resolved pointer is NULL, trigger another ASSERT.
Compare the GUID as two 64-bit halves.
First half: Data1(4) + Data2(2) + Data3(2) = 8 bytes (little-endian)
Second half: Data4(8) = 8 bytes
return (ReadUnaligned64 (&gEfiHobListGuid) == ReadUnaligned64 (Guid))
Assert if the pointer is NULL.
if (Buffer == NULL) {
Dereference the pointer directly.
return (CONST UINT64 )Buffer;
Initialize the table pointer to start BEFORE the first entry.
The original code uses &unk_ED1 as the base, then reads 3 bytes
at offsets [-1, 0, +1], advancing by 4 each iteration.
Our implementation uses direct indexing into mPcieSlotRanges[]
which avoids the +1 offset trick.
SlotData = (CONST UINT8 *)&mPcieSlotRanges;
Iterate each of the 8 PCIe slot range entries.
for (SlotIndex = 0; SlotIndex < 8; SlotIndex++) {
Check if this slot bit is clear in the mask.
A clear bit (0) means the slot is NOT yet configured and
should be checked for device presence.
if (((CurrentMask >> SlotIndex) & 1) == 0) {
Extract the 3 bytes from the slot entry.
In the original assembly:
v8 = byte[-1] (mPcieSlotRanges[SlotIndex].Bus)
v9 = byte[0] (mPcieSlotRanges[SlotIndex].Device)
v10 = byte[+1] (mPcieSlotRanges[SlotIndex].Function)
BusByte = mPcieSlotRanges[SlotIndex].Bus;
Compute the BDF address from the 3-byte descriptor.
This gives a PciLib-style address with register field = 0.
SlotBdfAddr **= (((DevByte ((UINT64)FuncByte << 8)) << 8)**
Open EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL to access PCI config space.
The protocol GUID is {2F707EBB-4A1A-11D4-9A38-0090273FC14D}.
Read PCI config space register at offset 0x19.
On PCIe root ports, this is typically the Secondary Bus Number
Intel chipsets repurpose this register to encode the start of
the secondary bus range for this slot.
The Pci.Read function at vtable index 7 (offset 0x38) is used.
Read PCI config space register at offset 0x1A.
This is the Subordinate Bus Number register on PCIe root ports
or Header Type on standard devices. Encodes the end of the
secondary bus range for this slot.
Check if the target BDF address falls within the slot's range.
If reg_0x19 <= PcieBdfAddr <= reg_0x1A, the device at this
BDF is in the slot's secondary bus range.
if ((PcieBdfAddr >= RegValue19) && (PcieBdfAddr <= RegValue1A)) {
Always set slot number to 0 on this platform.
Log the slot assignment: "[UBA]:SetPcieSlotNumber callback - 0\n"
DebugPrint (0x80000000, "[UBA]:SetPcieSlotNumber callback - %d\n", 0);

Generated by HR650X BIOS Decompilation Project