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

CpuArchDxe

Function Table

Address Name Description
Cpuid
ReadTsc
EnableInterrupts
DisableInterrupts
GetRflags
CpuHlt
CpuPause
ReadStr
ReadSldt
ReadIdtr
WriteIdtr
ReadGdtr
ReadMsr
WriteMsr
IoWrite16
IoRead32
BitFieldRead64
RShiftU64
LShiftU64
MultU64x32
DivU64x32
GetPowerOfTwo64
DivU64x64Remainder
BitFieldRead32
BitFieldOr64
InitializeFpuSse
DebugEnabled
AssertEnabled
DebugPrint
DebugAssert
EfiGetSystemConfigurationTable
AllocateZeroedPages
AllocatePool
FreePool
SetMem32
CopyMem
ZeroMem
Stall
GetMaxPhysicalAddress
MtrrSupported
GetVariableMtrrCount
GetEffectiveVariableMtrrCount
GetMtrrDefaultType
ReadAllVariableMtrrs
BuildMtrrDescriptorTable
MtrrGetMemoryAttribute
UefiBootServicesTableLibConstructor
UefiRuntimeServicesTableLibConstructor
DxeServicesTableLibConstructor
CpuArchDxeMain
DriverMainInit
ModuleEntryPoint
ProgramCpuFeatures
CacheTypeToMemoryAttribute
FindMemorySpaceMapEntry
SetMemorySpaceAttributesCpuArch
ProgramMemoryAttributes
InitExceptionHandlers
SetIdtEntry
GetExceptionTemplateInfo
SetupIdtTable
InitializeExternalInterruptHandlerTable
AcquireSpinLock
TryAcquireSpinLock
ReleaseSpinLock
MtrrSyncInit
RegisterMtrrNotify
GetPcdProtocol
DxeHobLibConstructor
GetPciExpressBase
PciExpressLibAddress
ResetColdSystem
MtrrReadDefaultType
WriteBackInvalidateCache
IsX2Apic
GetApicBase
ReadLocalApicReg
WriteLocalApicReg
GetApicMode
GetApicId
gImageHandle -- The EFI image handle for this driver.
qword_8E00 /// gST Pointer to EFI System Table.
qword_8DF0 /// gBS Pointer to EFI Boot Services Table.
qword_8DF8 /// gRT Pointer to EFI Runtime Services Table.
qword_8E08 /// gDS Pointer to DXE Services Table (located by GUID in .data).
qword_8E30 /// gPcdDb PCD database pointer (located by GUID).
qword_8E18 /// gHobList HOB list pointer (from DxeHobLib).
qword_8E20 /// gMmPciBase PCI Express MMIO base address.
qword_8E28 /// gPhysicalMax Maximum physical address (page-aligned, CPUID-based).
qword_8EA0 /// gPhysicalMaxRaw Raw maximum physical address.
qword_8EA8 /// gMtrrBuffer Allocated MTRR sync/state buffer (608 bytes).
qword_8EB0 /// gMtrrSyncLock Non-zero during MTRR sync.
byte_8EB8 /// gReservedVectors pointer to reserved exception vector table (22528 B).
qword_8E90 /// gExternalIntHandler pointer to external interrupt handler table.
qword_8E98 /// gVariableMtrrCountOffset difference: total - available variable MTRRs.
dword_8DE0 /*==========================================================================
Each entry: [Reserved, BaseAddress, StepSize]
Used in sub_1E40 to iterate through fixed MTRR ranges
merging adjacent ranges with the same memory type.
Used by sub_61F to determine the correct save slot index.
Registered during InstallMultipleProtocolInterfaces.
EFI_NOT_FOUND // gST->ConfigurationTable is at offset 112
MemoryType = 10 = EfiBootServicesData
Offset 40 in gBS vtable = AllocatePages
CPUID 0x80000000 to check max extended leaf
Check CPUID.01H:EDX[12] = MTRR support
IA32_MTRR_CAPABILITIES // Check VCNT (bits 7:0) != 0
Check FIXED (bit 8) == 1
Recover from pre-saved buffer (offset 80 + 2*i elements each)
IA32_MTRR_PHYSBASEi Mask = ReadMsr (0x201 + 2 * i); // IA32_MTRR_PHYSMASKi
Check MTRR_PHYS_MASK bit 11 (valid)
Descriptor layout (32 bytes each):
offset 0: Reserved (index)
offset 8: BaseAddress = a4 & (mask & base)
offset 16: Length = (a3 & ~(a4 & mask)) + 1
offset 24: MemoryType = bits[7:0] of base
offset 28: Attributes (0x0101 = valid + MSR pair)
Implementation based on MtrrLib algorithm // reads fixed MTRRs for sub-1MB addresses, then checks variable MTRRs
for addresses >= 1MB, then falls back to default type.
UC default
unk_77A0 table: 11 entries, 12 bytes each =
Read the 11 fixed MTRR MSRs
Get MSR address from internal table
Read variable MTRRs
Read MTRR default type MSR
GUID ptr at unk_8CC0 -> gDS
Save global services (sub_55DC equivalent)
Already done by constructor list
Initialize FPU + SSE (sub_410)
Initialize exception handlers (sub_12C0 / sub_4A88)
Determine if cache is enabled (sub_243C)
Load GDT (sub_8EC0)
Loads the OS-visible GDT descriptor
Get vector info from config table (sub_12C0)
Write back invalidate cache (sub_2460)
Install CPU Arch Protocol via gBS->InstallMultipleProtocolInterfaces
gBS call at [BootServices + 128]
Program GCD memory attributes based on current MTRR settings
Program CPU features (sub_3048)
Initialize MTRR sync (sub_1880)
Write back and invalidate cache
Call main entry
Process library constructor list
Call main entry wrapper (sub_DB0 -> sub_13A0)
On failure: process destructors (sub_DA0)
Program MSR 0x1D0 IA32_DEBUGCTL
Program MSR 0x3A0 IA32_MISC_ENABLE
Program MSR 0x3A1
UC case 1: return 2; // WC
WT case 5: return 0x1000; // WP
WB }
Descriptor layout at 56 bytes each:
Call GCD SetMemorySpaceAttributes from gDS
MP sync: sub_568C (1, 69639, 0, 0, 0)
Get max physical address
Get GCD memory space map via gDS
Read all MTRRs
Process GCD entries:
Process WB type entries (MTRR type 6)
sub_1C80 for each WB region
Merge adjacent ranges with same cache type in fixed MTRR region
Iterate through fixed MTRR ranges (dword_8D20 table: 11 entries x 3 DWORDs)
For each MTRR range within the fixed MTRR
If attribute changed, program the previous merged range
Flush the final merged range
Allocate 256 * 88 = 22528 bytes for reserved vector table
Process optional VectorInfo list
Store handler type in exception entry
Allocate external interrupt handler table (2048 bytes = 256 * 8)
Read current IDT limit
Allocate IDT table (4096 bytes)
Get exception stub template info
Allocate interrupt entry code
Copy stubs and set vector numbers
Set globals and install IDT
Install external interrupt handler table notification
Load new IDTR
Patch the MOV byte instruction encoding the vector number
Default stub header size = 16 bytes
Exception handler entry at 0x430 (CommonExceptionHandler)
APIC base (segment selector)
Use current CS from GDT
default stub size
Set IDT entry:
offset = EntryCode + i * StubSize
selector = CodeSegment
type = 0x8E (32-bit interrupt gate)
Initialize spin lock for exception handler
InterlockedCompareExchange64 (Lock, 2, 1) == 1
Try to exchange from 1 (free) to 2 (acquired)
Allocate MTRR sync buffer (608 = 0x260 bytes)
Register protocol notify (sub_29F8)
PCD GetPtr at offset 32 in vtable
Read CMOS status register A (0x4B)
Write CMOS status A with UIP bit set
Set bit 7 at the CMOS address
Get current RFLAGS, then disable interrupts
Check if interrupts were previously enabled
Read timer tick counter from IO port 0x508 (1288)
Read TSC for delay loop
Wait for ~357ms timer tick interval
Restore interrupt state
Cache was UC enable interrupts before WBINVD if needed
xAPIC mode MMIO access
xAPIC ApicBaseMsr = ReadMsr (0x1B);
Check bit 11 (EN) is set
Check bit 10 (EXTD) = x2APIC
xAPIC mode: CPUID.01H:EBX[31:24]
x2APIC mode: MSR 0x802 (x2APIC ID)

Generated by HR650X BIOS Decompilation Project