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

RuntimeSmm Module

Overview

RuntimeSmm is a minimal UEFI SMM runtime driver (DXE_SMM_DRIVER) from AmiModulePkg\RuntimeSmm\RuntimeSmm.c that bridges boot-time and runtime SMM services. It initializes global pointers to the UEFI Boot Services, Runtime Services, and System Table, locates SmmBase2 protocol to obtain the SMM Services Table (gSmst), and registers a protocol notification handler for the SMM Runtime Services Table protocol. The driver uses SetJump/LongJump for error recovery, wrapping the main entry logic in a try/except-style pattern, and ultimately installs a GUIDed protocol event handler via SmmRegisterProtocolNotify.

Address Range

0x300 - 0xC40 (17 functions)

Key Functions

Address Name Purpose
0x300 sub_300 SetJump() implementation: captures callee-saved registers (GP + XMM) and MXCSR into a buffer, returns via computed goto
0x3A0 sub_3A0 LongJump() implementation: restores MXCSR from buffer, jumps to saved return address
0x420 _ModuleEntryPoint Module entry point, calls init then main dispatch
0x44C sub_44C UEFI boot/runtime service table initialization: caches gImageHandle, gST, gBS, gRT, locates SmmBase2 protocol, retrieves gSmst
0x58C sub_58C Main module dispatch: calls SetJump for error recovery, invokes sub_768 (init), cleans up with LongJump, reaches unreachable ASSERT
0x640 sub_640 Stub function returning EFI_UNSUPPORTED (0x8000000000000003)
0x64C sub_64C Allocates buffer, copies protocol GUID data, fills entries with sub_640, calls SmmRegisterProtocolNotify to register protocol callback
0x768 sub_768 Driver init: caches SystemTable/BootServices/RuntimeServices, locates a protocol (unk_12E0), calls its callback, optionally replaces RuntimeServices from SMM, invokes sub_9F8/sub_A80 protocol registrations, calls sub_64C
0x888 sub_888 Gets DebugLib ReportStatusCode protocol via Smst->LocateProtocol (gEfiStatusCodeRuntimeProtocolGuid)
0x8D8 sub_8D8 ASSERT handler: checks DebugLib protocol, checks severity mask via sub_960, calls ReportStatusCode if mask matches
0x920 sub_920 ASSERT expression printer: obtains DebugLib protocol and calls its ReportStatusCodeEx with file/line/expression
0x960 sub_960 Reads CMOS index 0x4C via IO ports 0x70/0x71, interprets byte 0xFDAF0490 for runtime detection, returns EFI_STATUS code indicating boot mode
0x9B0 sub_9B0 SetJump validation: asserts JumpBuffer is non-null and 8-byte aligned
0x9F8 sub_9F8 Protocol registration for Runtime Services: in SMM mode locates via Smst; in boot mode locates via gBS->LocateProtocol
0xA80 sub_A80 Protocol registration for status code protocol: in SMM mode uses Smst; in boot mode allocates pool and uses gBS->LocateProtocol
0xB64 sub_B64 Searches SMM system table entries for a matching protocol GUID (unk_12B0) and returns its associated handler pointer
0xBD4 sub_BD4 Memory comparison function: byte-level and 8-byte-aligned compare against reference buffer (unk_12B0), returns difference

Entry Points (Public API)

  • 0x420 _ModuleEntryPoint: Called by SMM core on driver load. Calls sub_44C() to initialize service table globals, then sub_58C() as the main dispatch routine.

Internal Helpers

  • 0x300 sub_300: SetJump -- saves full register context (15 GP regs, 10 XMM regs, MXCSR) into a 248-byte jump buffer (unk_1380), returns via return v21().
  • 0x3A0 sub_3A0: LongJump -- restores MXCSR from jump buffer and jumps to saved return address at buffer+72.
  • 0x640 sub_640: Stub returning 0x8000000000000003 (EFI_UNSUPPORTED). Used as a default protocol notify handler in the registration table.
  • 0x888 sub_888: Debug library support -- lazily locates gEfiStatusCodeRuntimeProtocolGuid via gSmst->LocateProtocol.
  • 0x8D8 sub_8D8: ASSERT_EFI_ERROR handler -- checks DebugLib protocol and severity mask before calling ReportStatusCode.
  • 0x920 sub_920: Debug ASSERT -- calls ReportStatusCodeEx on the DebugLib protocol with file/line/expression.
  • 0x960 sub_960: CMOS-based runtime detection -- reads NVRAM byte at CMOS index 0x4C, checks boot mode (returns 0x80000004 for normal, 0x80000002 for S3 resume).
  • 0x9B0 sub_9B0: SetJump buffer validation -- asserts non-null and 8-byte aligned.
  • 0xBD4 sub_BD4: CompareMem against reference GUID unk_12B0 (little-endian aligned compare with tail handling).

State Management

Global Variables (.data segment)

Address Name Type Purpose
0x1280 unk_1280 GUID Protocol GUID for gEfiSmmStatusCodeProtocolGuid (used by sub_A80)
0x1290 unk_1290 GUID Protocol GUID -- same bytes as unk_12A0 (StatusCode runtime protocol)
0x12A0 unk_12A0 GUID SmmBase2 protocol GUID (SMM_SERVICES_TABLE_GUID)
0x12B0 unk_12B0 GUID Reference GUID for protocol comparison (sub_BD4, sub_64C -- Runtime SMM protocol notify)
0x12C0 unk_12C0 GUID Boot-time protocol GUID for Runtime Services (sub_9F8)
0x12D0 unk_12D0 GUID SMM-mode protocol GUID for Runtime Services (sub_9F8)
0x12E0 unk_12E0 GUID Protocol GUID for SMM Runtime Services Table (sub_768 locates via gBS->LocateProtocol)
0x12F0 qword_12F0 UINT64 gST (System Table)
0x1300 qword_1300 UINT64 gImageHandle
0x1308 qword_1308 UINT64 gRT (Runtime Services)
0x1310 qword_1310 UINT64 gSmst (SMM System Table)
0x1318 qword_1318 UINT64 DebugLib protocol pointer (cached lazily by sub_888)
0x1320 BootServices UINT64 gBS (Boot Services)
0x1328 RuntimeServices UINT64 gRT (cached Runtime Services pointer)
0x1330 qword_1330 UINT64 SMM System Table pointer (gSmst, set from SmmBase2)
0x1338 byte_1338 UINT8 SmmMode flag (1 = running in SMM)
0x1340 qword_1340 UINT64 SMM Runtime Services protocol pointer (sub_9F8)
0x1348 byte_1348 UINT8 InSmm flag (1 = in SMM, used by sub_9F8/sub_A80 protocol registration)
0x1350 qword_1350 UINT64 SMM Status Code protocol pointer (sub_A80)
0x1358 qword_1358 UINT64 Boot-time Runtime Services protocol pointer (sub_9F8)
0x1360 qword_1360 UINT64 SMM Runtime Services Table protocol pointer (sub_768)
0x1368 qword_1368 UINT64 Boot-time Status Code protocol pointer (sub_A80)
0x1370 SystemTable UINT64 gST (cached System Table pointer)
0x1378 n3 UINT8 CMOS byte read result (sub_960)
0x1380 unk_1380 248-byte buffer SetJump/LongJump context save area

Initialization Flow

  1. _ModuleEntryPoint (0x420) called by SMM core
  2. sub_44C (0x44C) caches gImageHandle, gST, gBS, gRT, locates SmmBase2 protocol, gets gSmst
  3. sub_58C (0x58C) saves SetJump context, calls sub_768 (driver init), restores via LongJump
  4. sub_768 (0x768) caches SystemTable/BootServices/RuntimeServices, locates SMM RST protocol, calls its callback, optionally swaps RuntimeServices with SMM version, registers protocol handlers via sub_9F8/sub_A80, calls sub_64C for protocol notify registration
  5. sub_64C (0x64C) allocates a 136-byte buffer, fills first 3 QWORDs from protocol GUID data and the remaining 14 with sub_640 stub, registers via SmmRegisterProtocolNotify

Data Structures

  • SetJump buffer at unk_1380 (248 bytes): Offset layout is 15 saved GP registers (0-64), return address (72), MXCSR value (80), 10 XMM registers (88-248). Used by sub_300/sub_3A0 for error recovery wrapping around sub_768.
  • Protocol notify buffer in sub_64C (136 bytes = 17 QWORDs): First 3 QWORDs are protocol GUID, remaining 14 QWORDs initialized to sub_640 function pointer, registered via SmmRegisterProtocolNotify.

Calling Patterns

  1. Try/Except pattern: SetJump(context) -> sub_768() [protected code] -> LongJump(context, status) -> check status -> unreachable ASSERT
  2. Protocol registration flow: Locate SMM Base2 -> Get SMM System Table -> Locate SMM Runtime Services Table Protocol -> Call protocol callback -> Register protocol notify -> Register status code protocol handlers

Dependencies

Consumed (this module calls)

  • SMM Services (gSmst): LocateProtocol (offset +208), SmmRegisterProtocolNotify (offset +40), SmmIoMemRead/protocol entry iteration (offset +152/+160 in SMM system table struct)
  • Boot Services (gBS): LocateProtocol (offset +320), AllocatePool (offset +24), FreePool (offset +32)
  • Hardware IO: CMOS NVRAM ports 0x70/0x71 (sub_960), fixed address 0xFDAF0490 (runtime detection byte)
  • DebugLib protocol: ReportStatusCode and ReportStatusCodeEx (via gSmst->LocateProtocol)

Consumed By (other modules call this)

  • SMM Core: Calls _ModuleEntryPoint (exported entry point)
  • SMM Runtime Services Table protocol consumer: The protocol notify handler registered via sub_64C is invoked by SMM core when the target protocol is installed
  • Callback from located protocol at 0x807: The protocol at qword_1360 is called with an Enable flag pointer; its second function (+8) provides the SMM system table

Notes

  • The module has NO imports -- all protocol interfaces are resolved internally via LocateProtocol through the system tables.
  • Strings reference build paths e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\... and e:\hs\AmiModulePkg\RuntimeSmm\RuntimeSmm.c, confirming this is a DEBUG VS2015 X64 build.
  • sub_640 is a 2-instruction leaf returning EFI_UNSUPPORTED -- used as a placeholder default handler in the protocol notify registration table.
  • sub_960's CMOS check at index 0x4C and the byte at 0xFDAF0490 are platform-specific runtime detection heuristics for distinguishing normal boot from S3 resume.
  • The double sub_920 call after LongJump in sub_58C is unreachable code (standard EDK2 AutoGen tail after infinite loop).
  • sub_BD4's alignment-sensitive comparison logic handles unaligned GUID comparison by byte-matching leading/trailing misaligned bytes.