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

UsbOcUpdateDxeLightningRidgeEXECB1

Function Table

Address Name Description
_ModuleEntryPoint
UsbOcGetConfig
IsHobListGuid
DebugPrint
DebugAssert
ReadUnaligned64
Static (Module-Level) Global Variables
Cached pointer to the EDK2 DebugLib protocol interface.
Initialized lazily by GetDebugProtocol(). Located via gBS->LocateProtocol()
against the DebugLib protocol GUID {36232936-0E76-31C8-A13A-3AF2FC1C3932}.
Stored at address 0xC70.
STATIC VOID *mDebugProtocol; // qword_C70 at 0xC70
Cached pointer to the HOB list.
Initialized lazily by GetHobList() by searching the system configuration
table for the EFI_HOB_LIST_GUID entry. Stored at address 0xC78.
STATIC VOID *mHobList; // qword_C78 at 0xC78
Cached CMOS debug level byte (at 0xC80).
Read from CMOS register 0x4B during debug output filtering.
STATIC UINT8 mCmosDebugLevel; // n3 at 0xC80
Constant Data (in .data section)
These are located in the .data section of the binary. They are referenced
by absolute address in the compiled code and are provided here for reference.
EFI_GUID mDebugLibProtocolGuid @ 0xB60
EDK2 DebugLib protocol GUID, used with gBS->LocateProtocol() in
EFI_GUID mUbaProtocolGuid @ 0xB70
UBA board-type protocol GUID (shared across all UBA variants).
EFI_GUID mUsbOcConfigGuid @ 0xB80
USB OC config protocol GUID for LightningRidgeEXECB1.
EFI_GUID mEfiHobListGuid @ 0xB90
Used for HOB list identification.
uint64 mUsbOcHobListFirstHalf @ 0xB90 (first 8 bytes)
uint64 mUsbOcHobListSecondHalf @ 0xB98 (second 8 bytes)
UBA_USBOC_PORT_MAP_ENTRY mUsbOcPortMap[3] @ 0xBA0
USB port that requires OC mapping configuration.
UBA_USBOC_CONFIG_DATA mUsbOcConfigHdr @ 0xBE0
Additional USB OC config data @ 0xBF0 (12 x UINT32):
Entry 0: {0x00000000, 0x00000001, 0x00000001, 0x00000002}
Entry 1: {0x00000003, 0x00000003, 0x00000008, 0x00000008}
Entry 2: {0x00000008, 0x00000008, 0x01020007, 0x01020007}
repeated pattern 0x01020007 (USB port descriptors) that extends through
USB OC port descriptor array @ 0xC18:
Repeated bytes: 07 00 02 01
Local (Forward) Function Declarations
Function Implementations
Cache ImageHandle with assertion check.
gImageHandle = ImageHandle;
Cache SystemTable with assertion check.
gST = SystemTable;
Cache BootServices from SystemTable with assertion check.
gBS = SystemTable->BootServices;
Cache RuntimeServices from SystemTable with assertion check.
gRT = SystemTable->RuntimeServices;
Locate the HOB list from the system configuration table.
This is required for subsequent HOB-based drivers.
GetHobList (ImageHandle);
Print debug banner indicating this driver is executing.
Interface = NULL;
Locate the UBA board-type protocol.
This protocol is shared across all UBA platform variants.
Status = gBS->LocateProtocol (
Call the board-type protocol's RegisterUsbOcConfig function at offset 0x10.
This registers the USB OC configuration protocol for LightningRidgeEXECB1.
Parameters passed to RegisterUsbOcConfig:
rcx = This (the protocol interface pointer)
rdx = ConfigGuid (&mUsbOcConfigGuid)
r8 = ConfigData (&mUsbOcConfigHdr = "PUSB" configuration header)
r9 = ConfigSize (16 = sizeof(UBA_USBOC_CONFIG_DATA))
return ((UBA_BOARD_TYPE_PROTOCOL *)Interface)->RegisterUsbOcConfig (
Return cached value if already resolved.
if (mHobList != NULL) {
Initialize HOB list pointer to NULL.
Get the number of configuration table entries.
gST + 0x68 = SystemTable->NumberOfTableEntries
TableCount = gST->NumberOfTableEntries;
If there are entries, scan them for EFI_HOB_LIST_GUID.
if (TableCount > 0) {
Get pointer to the configuration table array.
gST + 0x70 = SystemTable->ConfigurationTable
ConfigTable = gST->ConfigurationTable;
Iterate through configuration table entries.
Each iteration:
at offset 0x63d
advances v4 (rbp) by 0x18 (24 = sizeof(EFI_CONFIGURATION_TABLE))
for (Index = 0; Index < TableCount; Index++, ConfigTable++) {
Compare current entry's VendorGuid against EFI_HOB_LIST_GUID.
The comparison splits the 16-byte GUID into two 8-byte halves:
if (IsHobListGuid (ImageHandle, &ConfigTable->VendorGuid)) {
Found the HOB list entry. Extract the VendorTable pointer.
mHobList = ConfigTable->VendorTable;
HOB list GUID not found in configuration table.
Raise ASSERT_EFI_ERROR with EFI_NOT_FOUND (0x800000000000000E).
The EFI_NOT_FOUND high bit (63) ensures it's recognized as an error
by the EFI_ERROR() macro, and it's printed as the format argument
DebugPrint (EFI_NOT_FOUND, "\nASSERT_EFI_ERROR (Status = %r)\n");
If mHobList is still NULL after the search, raise another assertion.
This would indicate the HOB list GUID entry exists but has a NULL
table pointer, which is an unexpected condition.
if (mHobList == NULL) {
Compare first 8 bytes of the GUID.
These are at unk_B90 in the .data section (offset 0xB90).
The data at 0xB90 is the first 8 bytes of EFI_HOB_LIST_GUID:
As UINT64: 0x11D493D77739F24C
if (ReadUnaligned64 (&mUsbOcHobListFirstHalf) != ReadUnaligned64 (GuidPtr)) {
Compare second 8 bytes of the GUID.
These are at unk_B98 in the .data section (offset 0xB98).
The data at 0xB98 is the second 8 bytes of EFI_HOB_LIST_GUID:
As UINT64: 0x4DC13F2700903A9A
GuidPtr + 8 points to the second half of the 16-byte GUID structure.
In the SystemTable configuration table array, each entry is 24 bytes:
16 bytes for GUID followed by 8 bytes for VendorTable pointer.
So GuidPtr + 8 is the second half of the GUID, and GuidPtr + 16
would be the VendorTable pointer.
return ReadUnaligned64 (&mUsbOcHobListSecondHalf) == ReadUnaligned64 ((UINT8 *)GuidPtr + 8);
Get the DebugLib protocol interface (lazily resolved and cached).
DebugProtocol = GetDebugProtocol ();
Read debug level from CMOS register 0x4B.
Access RTC CMOS ports 0x70/0x71:
Port 0x70 = CMOS index/address register
Port 0x71 = CMOS data register
Step 1: Read current CMOS index register value.
This preserves the NMI enable (bit 7) from whatever was set
by the caller.
Step 2: Mask to preserve specific bits and set register address to 0x4B.
and al, 0xCB:
or al, 0x4B:
CmosValue = IoRead8 (RTC_INDEX_PORT);
Read the debug level value from CMOS data port 0x71.
DebugLevel = IoRead8 (RTC_DATA_PORT);
Determine the debug mask based on the CMOS debug level.
if (DebugLevel > 3) {
For values > 3, check the cached CMOS debug level from a previous
read (mCmosDebugLevel at 0xC80). This cached value may be stale
but avoids re-reading the CMOS port.
DebugLevel = mCmosDebugLevel;
If the cached level is 0, read the board configuration from
the MMIO register at 0xFDAF0490. This register contains
The **formula is: (register & 2) 1**
DebugLevel *= ((volatile UINT32 *)BOARD_CONFIG_MMIO_ADDR & 2) 1;**
Calculate the debug mask from the debug level.
The level must be >= 1 and <= 0xFE (since level-1 <= 0xFD).
Level 0xFF would underflow and fail the comparison.
if ((DebugLevel > 0) && ((DebugLevel - 1) <= 0xFD)) {
Level **1 -> mask = 0x80000004 (DEBUG_INIT DEBUG_INFO)**
Used for diagnostic output in release builds
Level **> 1 -> mask = 0x80000046 (DEBUG_INIT DEBUG_WARN DEBUG_ERROR DEBUG_INFO)**
Used for full debug output including warnings and errors
if (DebugLevel == 1) {
Check if the requested ErrorLevel is enabled by the debug mask.
If the bit set in ErrorLevel matches any bit in DebugMask
the output is enabled.
Common error levels:
0x80000000 = DEBUG_INFO (high bit = general debug)
0x00000040 = DEBUG_INIT
0x00000004 = DEBUG_WARN
0x00000002 = DEBUG_ERROR
if ((DebugMask & ErrorLevel) != 0) {
Call the DebugLib protocol's output function.
Protocol interface layout:
The output function takes:
rcx = ErrorLevel
rdx = Format string
r8 = VA_LIST (variable argument list from varargs)
where r9 = DebugProtocol (at offset 0x00 of protocol)
ReturnValue = ((DEBUGLIB_PROTOCOL *)DebugProtocol)->DebugPrint (
Call the DebugLib protocol's assertion handler at offset 0x08.
The assertion handler signature:
rcx = FileName
rdx = LineNumber
r8 = Description
Unlike DebugPrint which has a variable argument list, DebugAssert
has a fixed 3-argument signature, matched by this call.
Result = ((DEBUGLIB_PROTOCOL *)DebugProtocol)->DebugAssert (
if (mDebugProtocol != NULL) {
Allocate a small pool buffer (EfiBootServicesData = 31) and free it.
This is a UEFI environment validation check: if the allocation succeeds
and the buffer address is within a reasonable range (<= 0x10), it indicates
a properly functioning UEFI environment where boot services are available.
The allocation of Size=0 may seem unusual, but it serves as a probe:
a valid buffer address (even for size 0, some UEFI implementations
return a minimal allocation).
UEFI hardware-emulation or a simpler environment.
On minimal or non-UEFI environments, the allocation may behave differently
returning a very high address or failing.
The buffer size check suggests we are in a valid UEFI environment with
properly functioning boot services.
Locate the DebugLib protocol via gBS->LocateProtocol.
The DebugLib protocol GUID {36232936-0E76-31C8-A13A-3AF2FC1C3932}
is stored at address 0xB60 in the .data section.
On failure, clear the cached pointer.
if (EFI_ERROR (Status)) {
Buffer address exceeds 16 bytes - non-standard UEFI environment.
Return NULL, all debug output will be suppressed.
Check for NULL pointer.
if (Buffer == NULL) {
Perform a direct 64-bit read. On x86-64, unaligned memory accesses
are handled natively by the processor, so no special handling is
read exactly once.
return (volatile UINT64 )Buffer;

Generated by HR650X BIOS Decompilation Project