| 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