| Address | Name | Description | |
|---|---|---|---|
| GetDebugInterface | |||
| DebugPrint | |||
| DebugAssert | |||
| UnalignedRead64 | |||
| GuidCompare | |||
| HobLocate | |||
| MmioPciExpressRead32 | |||
| PciExpressBaseAddr | |||
| PcdLocate | |||
| sub_39C | |||
| ProcessPci | |||
| ProcessSADTAD | |||
| CollectPOSTData | |||
| sub_1148 | |||
| ModuleEntryPoint | |||
| Global | variables | ||
| UINT64 | gImageHandle; | ||
| qword_2708 | UINT64 gIioUdsProtocol; // qword_2710 | ||
| qword_2740 | UINT64 gMtrrSettings; // qword_2748 | ||
| qword_2750 | UINT64 gPort80DebugValue; // qword_2758 | ||
| GUID | definitions (from UEFI spec / platform headers) | ||
| EFI_GUID | gEfiPciRootBridgeIoProtocolGuid = { 0x2F707EBB, 0x4A1A, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }; | ||
| Each | entry: { Bus, Device, Function, Register offset, Value mask } | ||
| 696 | entries (0x2B8 bytes), 5 bytes each | ||
| STATIC | CONST UINT8 mSadAdTopologyTable[696 * 5] = { 0 }; | ||
| Check | if we have enough buffer space (>= 16 bytes) | ||
| if | (gBS >= 0x10) { | ||
| GUID | not found: ASSERT and fall through | ||
| DebugPrint | (0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", 0x800000000000000E); | ||
| Validate | that the address fits within PCIe config space range | ||
| if | ((Address & ~0xFFFFFFF) != 0) { | ||
| Locate | all handles that support gEfiPciRootBridgeIoProtocolGuid | ||
| NumHandles | = 0; | ||
| Iterate | over all PCI root bridge handles | ||
| for | (HandleIndex = 0; HandleIndex < NumHandles; HandleIndex++) { | ||
| Get | the PCI Root Bridge IO protocol for this handle | ||
| PciRootBridgeIo | = NULL; | ||
| Get | resource list to determine bus range | ||
| Status | = (*(UINT64 (__fastcall )(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL , UINT64 ))(** | ||
| If | no resource list, do a full bus scan (0-255) | ||
| if | (ResourceList == 0) { | ||
| Set | initial bus range from resource list | ||
| Bus | = StartBus; | ||
| Scan | all buses, devices, functions | ||
| while | (Bus <= EndBus) { | ||
| Retry | up to 8 times on failure | ||
| Status | = PciRootBridgeIo->Pci.Read ( | ||
| Check | if device is present (VendorId != 0xFFFF) | ||
| if | (VendorId == 0xFFFF) { | ||
| Read | PCI header type | ||
| Read | full config space (64 bytes) | ||
| PciAddress | = PCI_EXPRESS_ADDRESS (Bus, Function, Device, 0); | ||
| Valid | PCI device (non-multifunction or function 0) | ||
| IpmiMsgType | = ConfigSpace[0x11]; // Subsystem Vendor ID (or similar) | ||
| DebugPrint | (0x80000000, "[%X/%X/%X] ", Bus, Device, Function); | ||
| if | *((ConfigSpace[BarIndex 4] & 2) != 0 | ** | |
| BarValue | = (UINT32 )&ConfigSpace[BarIndex * 4]; | ||
| Command | register backup | ||
| Disable | decoding by clearing command register bits | ||
| Calculate | PCI config space offset for the BAR | ||
| if | (IpmiDataReady) { | ||
| BarValueMask | = ~0ULL; | ||
| Restore | command register | ||
| Send | via IPMI | ||
| IpmiMsgType | = 4865; | ||
| Handle | multi-function devices | ||
| Process | resource list to find acpi (0x79) and pnp (0x02) descriptors | ||
| while | (ResourceList != 0) { | ||
| End | tag | ||
| Status | = 1; | ||
| Type | 2 descriptor (DWORD address space): extract bus range | ||
| StartBus | = (UINT16 )(ResourceList + 14); | ||
| Free | the handle buffer | ||
| if | (HandleBuffer != NULL) { | ||
| Locate | gEfiIioUdsProtocolGuid | ||
| Status | = (*(UINT64 (__fastcall )(VOID , UINT64, UINT64 ))(gBootServices + 320))(** | ||
| Locate | gEfiCpuCsrAccessGuid | ||
| Iterate | over 4 possible sockets | ||
| for | (Socket = 0; Socket < 4; Socket++) { | ||
| Socket | is present | ||
| Process | SAD/AD topology table (696 entries) | ||
| TableIndex | = 9 * Socket; | ||
| First | pass: read CPUBUSNO and CPUBUSNO1 for this socket | ||
| CpuBusNo | = (*(UINT32 (__fastcall )(UINT8, UINT32, UINT32))(gGpioCsrAccessProtocol + 8))(** | ||
| CPUBUSNO | CSR | ||
| Check | CPUBUSNO_VALID | ||
| Bus | information valid: store it | ||
| No | bus information for this socket; use default | ||
| DebugPrint | (0x80000000, "No Bus Information in Socket %x.", Socket); | ||
| Calculate | the full PCI address using the socket's bus number | ||
| BusNum | = gSocketBusInfo[Socket][1 + SadAdEntry[4]]; | ||
| Now | process CSR-based DIMM/DDRIO data for the 24 VCU/MC channels | ||
| for | (Index = 0; Index < 24; Index++) { | ||
| Write | selector register | ||
| Some | CSR selector | ||
| Read | the data register | ||
| Temp | = (*(UINT32 (__fastcall )(UINT8, UINT8, UINT32))(gGpioCsrAccessProtocol + 40))(** | ||
| Register | the boot services timer event | ||
| Ensure | IPMI transport protocol is available | ||
| if | (gIpmiTransport == 0) { | ||
| Collect | PCI data and SAD/AD data | ||
| ProcessPci | (); | ||
| Initialize | global variables (BootServices, SystemTable, etc.) | ||
| sub_39C | (ImageHandle, SystemTable); | ||
| Create | a timer event to collect POST data | ||
| Status | = (*(EFI_STATUS (__fastcall )(UINT64, UINT64, EFI_EVENT ))(gBootServices + 80))(* | ||
| TimerPeriodic | 16, // NotifyTpl |
Generated by HR650X BIOS Decompilation Project