Newer
Older
AMI-Aptio-BIOS-Reversed / LenovoServerPkg / POSTDataTransfer / POSTDataTransfer.md
@Ajax Dong Ajax Dong 2 days ago 5 KB Full restructure

POSTDataTransfer

Function Table

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