Newer
Older
AMI-Aptio-BIOS-Reversed / PurleyPlatPkg / Acpi / Dxe / AcpiVTD / AcpiVTD.md
@Ajax Dong Ajax Dong 2 days ago 8 KB Full restructure

AcpiVTD

Function Table

Address Name Description
GetDxeServicesTable
GetHobList
CompareGuid
DebugPrintErrorLevel
LocateProtocol
ParseDmarSubTableType
InsertDmaRemap
SortDmarSubTables
GetDmarTable
InstallDmarTable
ReadSetupVariableByte
AcpiVtdDriverEntryPoint
UefiMain
Global data (BSS, initialized at driver load)
UEFI handle and table pointers
EFI_HANDLE gImageHandle = NULL; // 0x2450
0x2440 EFI_BOOT_SERVICES *gBootServices = NULL; // 0x2448
0x2458 VOID *gDsServicesTable = NULL; // 0x2478 (DXE Services Table)
0x2470 (HOB List)
Protocol pointers (lazy-located)
VOID *gPcdProtocol = NULL; // 0x2460 (PCD protocol)
0x2490 (ACPI table protocol)
0x2488 VOID *gSetupProtocol = NULL; // 0x2480 (Setup protocol)
DMAR table construction globals
DMA_REMAP_CONTAINER *mDmarContainer = NULL; // 0x24C8 (primary container pointer)
0x24D0 (= mDmarContainer + 2048)
0x24A0 = 'DMAR' (0x52414D44)
Platform configuration values (read from setup/PCD)
UINT16 mDmarFlags; // 0x24B0 (DMAR flags word: HAW + INTR_REMAP)
0x24B2 //
Function pointer table for DMAR sub-table construction callbacks
These entries come from the setup variable configuration describing
typedef struct {
GUID identifying the variable (or sub-table type)
Pointer to platform data for this sub-table
Size in bytes of the variable data
Index 0: DRHD hardware unit definitions
Index 1: RMRR region definitions
Index 2: ATSR device definitions
Terminator };
Helper functions (library-level, inlined in original binary)
Forward copy (non-overlapping or src > dst)
Count = Length >> 3;
Backward copy to handle overlapping regions
Dst8 = (UINT8 *)Destination + Length - 1;
Protocol / table location helpers
UEFI setup variable reading
Read CMOS register 0x4B to determine debug configuration
CmosData = IoRead8 (0x70);
EFI_D_ERROR if (CmosData == 1) {
EFI_D_INFO }
Forward to the debug protocol if installed
Result = (BOOLEAN)DEBUG (ErrorLevel, Format);
DMAR sub-table type parsing
SubType 0 + No flag = DRHD entry
This is actually subtype 1 (RMRR) because SubType=0 but IsDmarUnit=TRUE
means the first byte was 0x00 and the second byte 0x01 = LE value 0x0100 = 256.
Real DMAR sub-tables don't have type 256, this is RMRR.
Type 0: (UINT32 )v8 = 0x100000 -> bytes 00 00 10
Type 1: (UINT32 )v8 = 0x180001 -> byte 01 00 18
So for sorting: type 0 has WORD=0, type 1 has WORD=1 (but is checked
in the binary via the n2 flag, not the actual WORD).
The ReadDmarSubTableType function in the original checks:
DMAR sub-table construction (InsertDmaRemap)
Validate container pointer
if (DmaRemap == NULL) {
Write cursor: points to the current end of the container data
WriteCursor = (UINT8 *)DmaRemap + DmaRemap->Length;
DRHD - DMA-Remapping Hardware Unit Definition
Write DRHD header: Type=0, Flags, Segment, BaseAddress
INCLUDE_PCI_ALL flag
Append device scope entries
CurrentLength = (UINT16 )(WriteCursor + 2);
Write device scope type and bus number
Device type
Minimum length (header)
Copy initial 2 bytes of PCI path data
for (Index = 0; Index < 2; Index++) {
Append additional PCI path entries until terminator (0xFF)
ScopeSource = (UINT8 )SubTableData + (UINT64 )((UINT8 )SubTableData + 24)
RMRR - Reserved Memory Region Reporting
Write RMRR header: Type=1, Segment, BaseAddress, EndAddress
Write device scope header data
Type ScopeEntry[5] = ScopeSource[2]; // Enumeration data
Minimum length
Append PCI path entries
ScopeSource = (UINT8 )SubTableData + (UINT64 )((UINT8 )SubTableData + 32)
ATSR - Address Translation Services Reporting
Write ATSR header: Type=2, Flags, Segment
Type WriteCursor[4] = Atsr->Flags;
Minimum length of 8 bytes
Append device scope entries (only for ATS-capable devices)
for (DeviceScopeIndex = 0, ScopeDataOffset = 0;
Check ATS capability mask at SubTableData[16] (UINT32)
if ((((UINT32 )((UINT8 *)SubTableData + 16) >> DeviceScopeIndex) & 1) == 0) {
Write device scope header
ScopeSource += 16;
RHSA - Remapping Hardware Status Affinity
Write RHSA header: Type=3, ProximityDomain, BaseAddress
Type WriteCursor[16] = (UINT8)(Rhsa->ProximityDomain & 0xFF);
Total length: 20 bytes
Validate DMAR table size does not exceed 2KB limit
if (DmaRemap->Length >= 2 * 1024) {
DMAR sub-table sorting (SortDmarSubTables)
Skip DMAR header copy
Start after header
Sorted output area
Total container length
Pass 1: Copy DRHD entries (type 0 where IsDmarUnit is set)
while (SrcOffset < SrcLength) {
Pass 2: Copy RMRR entries (type 0 where IsDmarUnit is NOT set)
In the binary, these are the "type 0 entries with !n2 && n21" flag
SrcOffset = DMAR_HEADER_LENGTH;
Pass 3: Copy RMRR entries (type 1 where IsDmarUnit is NOT set)
This handles the type-1 entries (actual RMRR)
Pass 4: Copy ATSR entries (type 2 where IsDmarUnit is NOT set)
Pass 5: Copy RHSA entries (type 3)
Get DMAR Table (GetDmarTable)
Check if container has sub-table data
if ((UINT32 )((UINT8 *)mDmarContainer + 4) <= DMAR_HEADER_LENGTH) {
Sort sub-tables and return pointer to sorted output
SortDmarSubTables ();
DMAR table installation (InstallDmarTable)
Allocate DMAR table buffer (6 KB = 0x1800)
DmarBuffer = AllocateZeroPool (DMAR_TABLE_BUFFER_SIZE);
Initialize the DMAR table header:
DmarSignature = DMAR_SIGNATURE;
48 at offset 4
Revision at offset 8
DmarUnitCount at offset 24
DeviceScopeCount at offset 28
Internal scope count at offset 36
Read host address width from PCD protocol
if (GetPcdProtocol () != NULL) {
PCD protocol offset +32 = Get32 method
PCD protocol offset +40 = GetN method (returns UINTN)
These are used to query platform VT-d capability:
PcdVTdHostAddressWidth -> determines address width field in DMAR
PcdVTdInterruptRemap -> determines INTR_REMAP flag
PcdValue32 = ((PCD_PROTOCOL *)gPcdProtocol)->Get32 (PcdVTdHostAddressWidth);
Encode the address width and interrupt remap capability
into the DMAR table header fields at offset 10-24
InternalCopyMemChecked (
Install the DMAR ACPI table via gBS->InstallAcpiTable
This corresponds to BootServices[128] (InstallAcpiTable)
with the registered protocol handle via LocateProtocol(&gAcpiTableGuid)
Signature used for registration:
Status = gBootServices->InstallAcpiTable (
Platform configuration reading (sub_1620 / variable read)
Read the setup variable
Buffer = ReadSetupVariable (
Copy one byte from the buffer
InternalCopyMemChecked (Variable, Buffer + Offset, 1);
Free the variable buffer
if (gAcpiTableProtocolReady) {
Driver initialization (sub_398 / module entry prologue)
Save ImageHandle, SystemTable, BootServices, RuntimeServices
gImageHandle = ImageHandle;
Initialize HOB list pointer (needed for DMAR table construction)
Status = GetHobList (&gHobList);
Initialize DXE Services Table pointer
Status = GetDxeServicesTable (&gDsServicesTable);
Build and install the DMAR table
return InstallDmarTable ();
Module entry point (UefiMain)

Generated by HR650X BIOS Decompilation Project