# 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.