The LegacyRegion2 DXE driver manages read/write/execute permissions for the
legacy memory region (0xC0000 - 0xFFFFF) on Intel Purley/Purley Refresh
platforms. It controls PAM (Programmable Attribute Map) registers in the
chipset's PCI-to-LPC bridge to enable or disable decode of legacy VGA BIOS
and option ROM regions.
This driver is the LegacyRegion2 protocol producer. It consumes the
LegacyRegion protocol (from the CSM / Legacy Platform Driver) to access
the low-level PAM I/O ports, and publishes the LegacyRegion2 protocol
with enhanced locking semantics over the original LegacyRegion interface.
| Property | Value |
|---|---|
| Module | LegacyRegion2.efi (0322) |
| Source | PurleyPlatPkg\Legacy\Dxe\LegacyRegion\LegacyRegion.c |
| PDB | LegacyRegion2.pdb |
| Arch | x86-64 |
| Image Size | 0x12A0 (4768 bytes) |
| Entry Point | 0x350 |
| Build Env | VS2015 DEBUG, HR6N0XMLK platform |
| SHA-256 | 84f4964291f0d5788882eb7801452ff5fe6b58a5a50cd1e481917127e615d800 |
| Segment | Start | End | Size | Permissions | Contents |
|---|---|---|---|---|---|
| HEADER | 0x0000 | 0x0280 | 0x0280 | --- | PE/COFF header |
| .text | 0x0280 | 0x0C40 | 0x09C0 | rx | Executable code |
| .rdata | 0x0C40 | 0x1000 | 0x03C0 | r | Strings, debug info |
| .data | 0x1000 | 0x1180 | 0x0180 | rw | GUIDs, globals, region descriptor tbl |
| seg004 | 0x1180 | 0x1220 | 0x00A0 | r | BSS (zeroed) |
| .xdata | 0x1220 | 0x12A0 | 0x0080 | r | Exception handler data |
| Address | GUID | Purpose |
|---|---|---|
| 0x1000 | {36232936-0E76-31C8-A13A-3AF2FC1C3932} |
Custom HOB data GUID (in HOB library) |
| 0x1010 | {0067835F-9A50-433A-8CBB-852078197814} |
Vendor GUID (sub-protocol) |
| 0x1020 | {A7CED760-C71C-4E1A-ACB1-89604D5216CB} |
EFI_LEGACY_REGION2_PROTOCOL |
| 0x1030 | {AF1E1070-0085-440C-B356-8EE36FEF24F0} |
Protocol GUID for installed interface |
| 0x1040 | {7739F24C-93D7-11D4-9A3A-0090273FC14D} |
HOB List GUID (in System Config Table) |
The PAM attribute map divides the 0xC0000-0xFFFFF range into 13 sub-regions:
| Entry | Base | Size | End | Type | Description |
|---|---|---|---|---|---|
| 0 | 0xF0000 | 0x10000 | 0xFFFFF | 0 | BIOS segment F (64K) |
| 1 | 0xC0000 | 0x4000 | 0xC3FFF | 1 | VGA BIOS segment 0 |
| 2 | 0xC4000 | 0x4000 | 0xC7FFF | 2 | VGA BIOS segment 1 |
| 3 | 0xC8000 | 0x4000 | 0xCBFFF | 3 | VGA BIOS segment 2 |
| 4 | 0xCC000 | 0x4000 | 0xCFFFF | 4 | VGA BIOS segment 3 |
| 5 | 0xD0000 | 0x4000 | 0xD3FFF | 5 | VGA BIOS segment 4 |
| 6 | 0xD4000 | 0x4000 | 0xD7FFF | 6 | VGA BIOS segment 5 |
| 7 | 0xD8000 | 0x4000 | 0xDBFFF | 7 | VGA BIOS segment 6 |
| 8 | 0xDC000 | 0x4000 | 0xDFFFF | 8 | VGA BIOS segment 7 |
| 9 | 0xE0000 | 0x4000 | 0xE3FFF | 9 | VGA BIOS segment 8 |
| 10 | 0xE4000 | 0x4000 | 0xE7FFF | 10 | VGA BIOS segment 9 |
| 11 | 0xE8000 | 0x4000 | 0xEBFFF | 11 | VGA BIOS segment 10 |
| 12 | 0xEC000 | 0x4000 | 0xEFFFF | 12 | VGA BIOS segment 11 |
Type values map to PAM register bit positions (each 2-bit field = read-enable + write-enable).
Each PAM register packs 4 region attributes (types N..N+3) into a 32-bit value:
Bit 31 30 29 28 27 26 25 24 ... 7 6 5 4 3 2 1 0
Field [A3] [A2] [A1] [A0]
2 bits 2 bits 2 bits 2 bits
Each 2-bit field:
Types 0-6: attributes in the "read port" PAM register (I/O 0x30000C0).
Types 7-12: attributes in the "write port" PAM register (I/O 0x30000C4).
ModuleEntryPoint (0x350)
+-> Save gImageHandle, gST, gBS, gRT (lib constructors)
+-> GetHobList (0xAC4)
+-> Scan gST->ConfigurationTable for HOB_LIST_GUID
+-> Return cached HOB list pointer
+-> WheaSupportEntry (0x408)
+-> gBS->LocateProtocol(LEGACY_REGION_PROTOCOL)
+-> gBS->LocateProtocol(LEGACY_REGION2_PROTOCOL)
+-> Read gPamCapabilities
+-> InstallMultipleProtocolInterfaces(LEGACY_REGION2_PROTOCOL)
| Address | Size | Original | Renamed Name | Purpose |
|---|---|---|---|---|
| 0x0350 | 184 | sub_350 | ModuleEntryPoint |
DXE driver entry point |
| 0x0408 | 383 | sub_408 | WheaSupportEntry |
Main init: locate protocols + install |
| 0x0588 | 11 | sub_588 | LegacyRegion2GetMaxSize |
Return 0 max size (stub) |
| 0x0594 | 771 | sub_594 | ProgramPamRegisters |
Core PAM register programming |
| 0x0898 | 36 | sub_898 | LegacyRegion2Decode |
Validate region range |
| 0x08BC | 114 | sub_8BC | LegacyRegion2Program |
Program region attributes |
| 0x0930 | 73 | sub_930 | LegacyRegion2ProgramLock |
Program with lock override |
| 0x097C | 127 | sub_97C | GetHobListCache |
Return cached HOB list |
| 0x09FC | 136 | sub_9FC | DebugAssertPrint |
Debug assertion print (DebugLib) |
| 0x0A84 | 62 | sub_A84 | DebugAssert |
Debug assertion handler (DebugLib) |
| 0x0AC4 | 214 | sub_AC4 | GetHobList |
Find HOB list via config table |
| 0x0B9C | 110 | sub_B9C | IsHobListConfigEntry |
Compare config table entry GUID |
| 0x0C0C | 47 | sub_C0C | ReadUnaligned64 |
Unaligned 64-bit read (BaseLib) |
Driver initialisation. Locates LegacyRegion and LegacyRegion2 protocols,
reads PAM capabilities from the LegacyRegion2 protocol's internal state,
builds the protocol function table, and installs it.
The core PAM programming routine. Iterates the 13-entry region descriptor
table, detects overlaps with the requested range, reads current PAM register
values via the LegacyRegion protocol's I/O abstractions, modifies the 2-bit
attribute fields, and writes them back. Handles both "low" (types 0-6) and
"high" (types 7-12) PAM registers with bit position mapping.
Validates that [StartAddress, StartAddress+Length) falls within 0xC0000-0xFFFFF.
Returns EFI_INVALID_PARAMETER if the range extends beyond these boundaries.
Programs PAM attributes for the given range. Checks LegacyRegion2 internal
write-disable state (at offsets +0x06F4 and +0x06F1) to decide whether to
force write-enable. Delegates to ProgramPamRegisters.
Like Program but always passes LegacyDecode=2 (override). Checks the same
write-disable state before calling ProgramPamRegisters.
Scans the System Table's Configuration Table for an entry whose VendorGuid
matches {7739F24C-93D7-11D4-9A3A-0090273FC14D}. Returns the associated
VendorTable pointer, which is the HOB list used by DxeHobLib.
BaseLib helper: reads 8 bytes from any address (may be unaligned).
Debug library wrappers. DebugAssertPrint checks CMOS register 0x4B for
platform type and routes to the appropriate debug output.
| Address | Size | Name | Description |
|---|---|---|---|
| 0x10E0 | 8 | gST |
EFI System Table pointer |
| 0x10E8 | 8 | gBS |
EFI Boot Services table pointer |
| 0x10F0 | 8 | gImageHandle |
Image handle (from entry) |
| 0x10F8 | 8 | gRT |
EFI Runtime Services table pointer |
| 0x1100 | 8 | unused | Debug library internal |
| 0x1108 | 8 | gHobList |
Cached HOB list pointer |
| 0x1120 | 4 | gLegacyRegion2Signature |
Signature 'INIT' (0x4E495449) |
| 0x1128 | 8 | gLegacyRegion2ProtocolHandle |
Protocol handle for installed interface |
| 0x1130 | 8 | gLegacyRegion2Protocol.Decode |
Function pointer: Decode |
| 0x1138 | 8 | gLegacyRegion2Protocol.Program |
Function pointer: Program |
| 0x1140 | 8 | gLegacyRegion2Protocol.ProgramLock |
Function pointer: ProgramLock |
| 0x1148 | 8 | gLegacyRegion2Protocol.GetMaxSize |
Function pointer: GetMaxSize |
| 0x1150 | 8 | gLegacyRegion2Protocol.GetMaxSize2 |
Duplicate GetMaxSize (unused) |
| 0x1158 | 8 | gImageHandleSaved |
Saved ImageHandle for init |
| 0x1160 | 4 | gPamCapabilities |
PAM capabilities bitmask |
| 0x1168 | 8 | gLegacyRegion2 |
Located LegacyRegion2 protocol |
| 0x1170 | 8 | gLegacyRegion |
Located LegacyRegion protocol |
All strings reside in .rdata:
| Address | String |
|---|---|
| 0xC40 | \nASSERT_EFI_ERROR (Status = %r)\n (format string) |
| 0xC68 | !EFI_ERROR (Status) |
| 0xC80 | e:\hs\PurleyPlatPkg\Legacy\Dxe\LegacyRegion\LegacyRegion.c |
| 0xCC0 | gImageHandle != ((void *) 0) |
| 0xCE0 | e:\hs\MdePkg\Library\UefiBootServicesTableLib\UefiBootServicesTableLib.c |
| 0xD30 | gST != ((void *) 0) |
| 0xD48 | gBS != ((void *) 0) |
| 0xD60 | gRT != ((void *) 0) |
| 0xD80 | e:\hs\MdePkg\Library\UefiRuntimeServicesTableLib\UefiRuntimeServicesTableLib.c |
| 0xDD0 | Buffer != ((void *) 0) |
| 0xDE8 | e:\hs\MdePkg\Library\DxeHobLib\HobLib.c |
| 0xE10 | mHobList != ((void *) 0) |
| 0xE30 | e:\hs\MdePkg\Library\BaseLib\Unaligned.c |
ModuleEntryPoint (0x350)
+-> DebugAssert (0xA84) [called for each NULL check]
+-> GetHobListCache (0x97C) [lazy init]
+-> GetHobList (0xAC4)
+-> IsHobListConfigEntry (0xB9C)
| +-> ReadUnaligned64 (0xC0C) [x4]
+-> DebugAssertPrint (0x9FC)
+-> DebugAssert (0xA84)
+-> WheaSupportEntry (0x408)
+-> DebugAssertPrint (0x9FC)
+-> GetHobListCache (0x97C)
+-> DebugAssert (0xA84)
+-> gBS->LocateProtocol (x2)
+-> gBS->InstallMultipleProtocolInterfaces
| Ordinal | Function | Library |
|---|---|---|
| 320 | LocateProtocol |
gBS |
| 128 | InstallMultipleProtocolInterfaces |
gBS |
| 24 | GetNextMonotonicCount |
gBS |
| 32 | Stall |
gBS |
The HOB list GUID {7739F24C-93D7-11D4-9A3A-0090273FC14D} is not a standard
UEFI specification GUID (standard is gEfiDxeServicesTableGuid). This is a
platform-specific GUID published by the DXE firmware during boot.
The driver contains embedded CmosDebugLib logic that reads CMOS register
0x4B through I/O ports 0x70/0x71 to determine platform type (IPMI/BMC mode)
before routing debug output.
PAM register ports 0x30000C0 and 0x30000C4 are chipset-specific PCIe
configuration space registers in the P2SB (Primary-to-Sideband) bridge.
The original source file path indicates this is fromPurleyPlatPkg\Legacy\Dxe\LegacyRegion\LegacyRegion.c -- the single source
file builds both the LegacyRegion (SMM) and LegacyRegion2 (DXE) drivers
via compile-time flags.
All assertion strings reference EDK2 MdePkg library paths, confirming
this uses standard EDK2 DebugLib, BaseLib, and HobLib implementations
with PurleyPlatPkg-specific platform overrides.