/**
* MemRas.c - Memory RAS (Reliability, Availability, Serviceability) Driver
* PurleySktPkg/Dxe/MemRas/MemRas
*
* Entry point and protocol installation for the Purley platform memory RAS
* subsystem. This driver handles memory error correction, sparing,
* address translation, patrol scrubbing, and S3 boot script save/restore.
*
* ============================================================================
* Initialization Sequence
* ============================================================================
*
* ModuleEntryPoint() [0x5CC]
* |
* +-> MemRasInitGlobals() [MemRasInitGlobals, 0xAF90]
* | Allocates global context, calls ~23 sub-initializers in sequence
* |
* +-> MemRasDriverEntry() [MemRasDriverEntry, 0xB724]
* | Allocates protocol structures, populates function table,
* | reads platform config, installs protocol, registers events
* | Calls: MemRasS3SaveRegister() (S3 save events) + InitializeVLSInfo() (VLS init)
* |
* +-> MemRasSecondaryInit() [MemRasSecondaryInit, 0xB6AC]
* Calls MemRasDriverEntry() if context not already initialized
* Sets global status to 0x8000000000000001 if failed
*
* On failure (entry point):
* +-> MemRasFallbackInit() [0xB56C]
* Calls PlatformRasInit() + RegisterMemoryErrorEvents() + S3BootScriptSaveInit()
*
* ============================================================================
* Memory Layout
* ============================================================================
*
* All allocations use BootServices->AllocatePool (PoolType=6=EfiBootServicesData):
* 1. Context structure: 24 bytes (qword_CD8B0)
* 2. Protocol structure: 568 bytes (qword_27818)
* 3. Socket config buffer: 32768 bytes (qword_CD740) in .data
* 4. Scratch/work buffer: 25037 bytes (allocated at runtime)
* 5. Error log buffer: 1643 bytes (qword_CD748)
*
* ============================================================================
* Protocol Function Table (at qword_27818, populated at offsets 160-424)
* ============================================================================
*
* Offset Function Description
* ------ ----------- -----------------------------------------------
* 0x0A0 Init Init - per-socket initialization
* 0x0A8 Init2 Init2 - stub (returns success)
* 0x0B0 SpareRank SpareRank - start sparing on rank
* 0x0B8 SpareRank2 Alternate spare rank path
* 0x0C0 SpareCopy SpareCopy - handle spare copy done
* 0x0E0 GetFailedDimmErrorInfo
* 0x108 CheckAndHandleNewRankSparingEvent
* 0x110 HandlePatrolCompleteEventForNode
* 0x118 HandleSpareRankUCEvent
* 0x120 SpareCopyDone SpareCopyDone handler
* 0x130 S3BootScriptSave
* 0x138 CompareGuidOrSimilar Compare GUID / HOB lookup
* 0x140 CheckRankState Check rank state
* 0x148 ForEachChannel ForEachChannel - iterate channels
* 0x150 CheckRankStatePerMC Check rank state per MC
* 0x158 CheckRankStatePerCh Check rank state per channel (stub)
* 0x160 GetSystemAddress GetSystemAddress (channel addr -> sys addr)
* 0x168 GetChannelAddress GetChannelAddress (rank addr -> channel addr)
* 0x170 AddressTranslation Address translation
* 0x178 GetRankAddress GetRankAddress
* 0x180 ReverseAddressTranslate ReverseAddressTranslate
* 0x0F0 DisableMemoryMigration DisableMemoryMigration
* 0x0F8 SetupMemoryMigration SetupMemoryMigration
* 0x190 TranslateRIR TranslateRIR (Rank Interleave Registers)
* 0x198 GetErrorLogSysAddr GetErrorLogSysAddr
* 0x0E8 StubInit StubInit (same as Init2)
* 0x0C8 ForwardAddrTranslate ForwardAddrTranslate
* 0x0D0 McChToLogChId McChToLogChId (MC channel to logical channel)
* 0x0D8 TadId2SadId TadId2SadId (TAD to SAD index translation)
* 0x100 GetDDRTSystemAddress GetDDRTSystemAddress
* 0x188 ForEachSocket ForEachSocket - iterate sockets
* 0x1A0 TranslateSAD TranslateSAD (System Address Decoder)
* 0x1A8 TranslateDDRTTad TranslateDDRTTad (DDRT TAD translation)
*
* ============================================================================
* Address Translation Pipeline
* ============================================================================
*
* Forward (System Address -> Physical):
* 1. TranslateSAD - System Address Decoder routing
* SAD maps system address -> socket/MC/channel via interleave rules
* 2. TadId2SadId - Find SAD entry from TAD index
* 3. AddressTranslation - Target Address Decoder
* TAD provides per-channel offset/limit translations
* 4. GetChannelAddress - Channel address calculation
* 5. TranslateRIR - Rank Interleave Register
* RIR maps channel address -> physical rank via interleave registers
* 6. ADDDCSupportForAddrTrans - ADDDC lockstep rank handling
* 7. RankSpareSupportForAddrTrans - Rank spare mapping
* 8. TranslateRankAddress - Row/Column/Bank/BankGroup extraction
* 9. TranslateDDRTTad - DDRT-specific translation (2LM/PMEM)
*
* Reverse (Physical -> System Address):
* 1. ReverseAddressTranslate
* 2. GetDDRTSystemAddress - DDRT-specific reverse
* 3. GetSystemAddress - channel addr -> system addr
*
* ============================================================================
* Error Handling / Sparing State Machine
* ============================================================================
*
* Global bitmaps (dword_23680, dword_23684):
* - mEventProgressBitmap[dword_23680]: Bit per NodeId, set when error
* handling is in progress
* - mEventPendingBitmap[dword_23684]: Bit per NodeId, set when error
* handling is pending (deferred)
*
* Rank states (per rank state machine):
* available -> scrubbing -> do_spare_copying -> spare_copy_done -> try_do_tag
*
* ============================================================================
* Key Global Variables (.data section, 0x22AC0-0xEE920)
* ============================================================================
*
* qword_23658 (0x23658): RAS status code
* dword_23680 (0x23680): mEventProgressBitmap
* dword_23684 (0x23684): mEventPendingBitmap
* word_2367C (0x2367C): Error threshold
* qword_23670 (0x23670): Scratch buffer pointer
* byte_63AEC (0x63AEC): Platform config byte 1
* byte_65ED2 (0x65ED2): Platform config byte 2
* dword_63B24 (0x63B24): Platform config (number of sockets)
* dword_63C4C (0x63C4C): Platform config (memory base address)
* qword_26650 (0x26650): S3 save context
* qword_27828 (0x27828): System memory size
* qword_27830 (0x27830): Memory type / node info
* qword_27838 (0x27838): Number of sockets config
* qword_27840 (0x27840): Number of channels config
* qword_27848 (0x27848): Memory range end
* qword_27850 (0x27850): Memory range start
* byte_27858 (0x27858): Channel mode (lockstep/non-lockstep)
*/
// Include auto-generated UEFI header from AutoGen.c
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>
// Protocol GUIDs (referenced in .rdata section as unk_22B*)
// unk_22BB0: gEfiMemRasProtocolGuid - Memory RAS protocol
// unk_22B20: Platform RAS policy protocol
// unk_22B40: CPU CSR access protocol
// unk_22B90: Additional platform protocol
// unk_22BA0: Additional platform protocol
// unk_22B30: Protocol interface GUID for InstallProtocolInterface
// unk_22B60: Event protocol for S3 boot script
// unk_22B80: SMM communication protocol
// unk_22BC0: Variable access protocol
#include "MemRas.h"
//
// ============================================================================
// Module-Level Global Variables
// ============================================================================
//
// These are populated from HOBs and platform policy protocols at init time.
//
// Configuration read from HOB at offset 1677
UINT8 ChannelMode; // byte_27858 - 0=non-lockstep, 1=lockstep
// Configuration from platform policy protocol
UINT8 VlsEnabled; // byte_63AEC
UINT8 SpareMode; // byte_65ED2
UINT32 NumSockets; // dword_63B24
UINT32 MemoryBase; // dword_63C4C
// Memory configuration from HOB
UINT64 MemoryRangeStart; // qword_27850
UINT64 MemoryRangeEnd; // qword_27848
UINT32 SystemMemorySize; // qword_27840
UINT32 NumChannels; // qword_27838
UINT32 MemoryType; // qword_27830
UINT32 MemoryGranularity; // qword_27828
//
// ============================================================================
// _ModuleEntryPoint [0x5CC]
// ============================================================================
//
// UEFI DXE driver entry point. Called by DXE dispatcher.
//
// Flow:
// 1. MemRasInitGlobals() - Allocate and initialize global state
// 2. MemRasDriverEntry() - Protocol installation (primary path)
// 3. On failure, MemRasFallbackInit() tries secondary path
//
EFI_STATUS
EFIAPI
ModuleEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Phase 1: Allocate and initialize global context.
// Allocates socket configuration buffer, protocol structure,
// scratch buffers, and error log buffer.
//
MemRasInitGlobals();
//
// Phase 2: Primary driver entry - allocate protocol, populate
// function table, read platform config from HOB and policy protocols,
// install protocol interface, register S3 save events,
// initialize VLS (Virtual Lockstep) info.
//
Status = MemRasDriverEntry(ImageHandle, SystemTable);
if (EFI_ERROR(Status)) {
//
// Phase 3 (fallback): On failure, attempt secondary initialization.
// Calls memory initialization, event registration, S3 boot script.
//
Status = MemRasFallbackInit(ImageHandle, SystemTable);
}
return Status;
}
//
// ============================================================================
// MemRasInitGlobals() [MemRasInitGlobals, 0xAF90]
// ============================================================================
//
// Called first from ModuleEntryPoint. Allocates and initializes all
// module-level buffers and structures.
//
// Init sequence (23 sub-initializers):
// 1. MemRasInitGlobalsLock - Global lock/state initialization
// 2. MemRasInitContext - BaseLib setjmp/longjmp context init
// 3. MemRasInitServiceTables - UEFI boot/runtime service table init
// 4. MemRasInitEntryLibraries - Driver binding/entry point library init
// 5. MemRasInitStub - [stub] returns success
// 6. MemRasInitMemoryLibraries - Memory allocation library init
// 7. MemRasInitHobLibraries - HOB list library init
// 8. MemRasInitPciLibraries - PCI Express library init
// 9. MemRasInitStub - [stub] returns success
// 10. MemRasInitS3Libraries - SMM LockBox / S3 boot script library init
// 11. MemRasInitTimerLibraries - Timer library init
// 12. MemRasInitAcpiLibraries - ACPI timer lib / decompress lib / services table
// 13. MemRasInitMcaHooks - MCE/MCA platform hooks / MP sync data lib init
// 14. MemRasInitStub - [stub] returns success
// 15. MemRasInitSmmInterfaces - SMM communication / variable protocol init
// 16. MemRasInitErrorReporting - IPMI / error reporting library init
// 17. MemRasInitOemRas - OemRasLib init
// 18. MemRasInitPlatformRas - Platform-specific RAS init
//
EFI_STATUS
MemRasInitGlobals(
VOID
)
{
//
// Each sub-initializer is a library constructor from the
// linked static libraries. They are called sequentially.
// On debug builds, each failure triggers ASSERT via
// _ASSERT(!EFI_ERROR(Status)) pattern.
//
// The pattern for each call is:
//
// Status = LibraryConstructor();
// ASSERT_EFI_ERROR(Status);
//
// Phase 1: Core library initialization
// 0x6BC - BaseLib / lock init
// 0x758 - UefiBootServicesTableLib constructor
// 0x794 - UefiRuntimeServicesTableLib constructor
//
// Phase 2: Driver support libraries
// 0x10AC - UefiDriverEntryPoint / UefiLib constructors
// 0x1430 - [stub, returns success]
// 0x163C - Memory allocation library
// 0x1928 - HOB library (mHobList initialization)
// 0x1AB8 - SmmMmPciBaseLib constructor
// 0x1BC8 - [stub, returns success]
// 0x1C7C - S3BootScriptLib / SmmLockBoxSmmLib constructor
// 0x1FB4 - AcpiTimerLib constructor
// 0x20CC - DxeServicesTableLib + TianoCustomDecompressLib
//
// Phase 3: Platform-specific RAS libraries
// 0x35D4 - mpsyncdatalib + emcaplatformhookslib init
// 0x43A0 - [stub, returns success]
// 0x51A8 - SmmLnvSendIpmiCmdLib / SmmVariable protocol
// 0x552C - AmiErrReportingLib init
// 0x5FB4 - OemRasLib init
// 0x6C00 - Platform-specific RAS init
//
return EFI_SUCCESS;
}
//
// ============================================================================
// MemRasDriverEntry() [MemRasDriverEntry, 0xB724]
// ============================================================================
//
// Core driver entry. Allocates protocol structure, reads HOB data,
// populates function pointer table, installs protocol interface,
// and sets up event handlers.
//
EFI_STATUS
EFIAPI
MemRasDriverEntry(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
MEM_RAS_PROTOCOL *Protocol;
VOID *ContextBuffer;
VOID *PlatformPolicy;
VOID *CpuCsrAccess;
VOID *PlatformProtocol;
UINT8 *HobData;
//
// Step 1: Allocate context structure (24 bytes) and zero it.
// qword_CD8B0 -> ContextBuffer (sizeof=24)
//
Status = gBS->AllocatePool(EfiBootServicesData, 24, &ContextBuffer);
ASSERT_EFI_ERROR(Status);
ZeroMem(ContextBuffer, 24);
//
// Step 2: Allocate protocol structure (568 bytes) and zero it.
// qword_27818 -> Protocol (MEM_RAS_PROTOCOL)
//
Status = gBS->AllocatePool(EfiBootServicesData, 568, &Protocol);
ASSERT_EFI_ERROR(Status);
ZeroMem(Protocol, 568);
// Link protocol to context
*(MEM_RAS_PROTOCOL **)((UINT8 *)ContextBuffer + 16) = Protocol;
//
// Step 3: Allocate socket configuration buffer (32768 bytes).
// qword_CD740 -> SocketConfig
// Stored in .data section (global variable)
//
Status = gBS->AllocatePool(EfiBootServicesData, 0x8000, &gSocketConfig);
ASSERT_EFI_ERROR(Status);
ZeroMem(gSocketConfig, 0x8000);
// Initialize scratch buffer tracking
gScratchBuffer = gSocketConfig + 32760;
//
// Step 4: Allocate scratch buffer (25037 bytes).
// First 8 bytes of protocol structure stores pointer to this.
//
Status = gBS->AllocatePool(EfiBootServicesData, 25037, &Protocol[0]);
ASSERT_EFI_ERROR(Status);
ZeroMem(Protocol, 25037);
//
// Step 5: Allocate error log buffer (1643 bytes).
// qword_CD748 -> gErrorLogBuffer
//
Status = gBS->AllocatePool(EfiBootServicesData, 1643, &gErrorLogBuffer);
ASSERT_EFI_ERROR(Status);
ZeroMem(gErrorLogBuffer, 1643);
//
// Step 6: Locate PlatformRasPolicy protocol (unk_22BB0).
// This provides platform RAS configuration data.
//
Status = gBS->LocateProtocol(&gPlatformRasPolicyGuid, NULL, &PlatformPolicy);
ASSERT_EFI_ERROR(Status);
//
// Step 7: Initialize protocol signature.
// Initial: 0x12345678 (temporary)
// Final: 0x4D495053 ("MIPS")
//
*(UINT32 *)ContextBuffer = 0x12345678;
MemRasSocketInit(Protocol);
*(UINT32 *)ContextBuffer = 0x4D495053;
*(MEM_RAS_PROTOCOL **)ContextBuffer = &gProtocolContext;
//
// Step 8: Populate function pointer table.
// All function pointers are installed at their respective
// offsets within the protocol structure.
//
Protocol->Init = Init;
Protocol->Init2 = Init2; // stub
Protocol->SpareRank = SpareRank;
Protocol->SpareRank2 = SpareRank2;
Protocol->SpareCopy = SpareCopy;
Protocol->GetFailedDimmErrorInfo = GetFailedDimmErrorInfo;
Protocol->CheckAndHandleNewRankSparingEvent = CheckAndHandleNewRankSparingEvent;
Protocol->HandlePatrolCompleteEventForNode = HandlePatrolCompleteEventForNode;
Protocol->HandleSpareRankUCEvent = HandleSpareRankUCEvent;
Protocol->SpareCopyDone = SpareCopyDone;
Protocol->S3BootScriptSave = S3BootScriptSave;
Protocol->CompareGuidOrSimilar = CompareGuidOrSimilar;
Protocol->CheckRankState = CheckRankState;
Protocol->ForEachChannel = ForEachChannel;
Protocol->CheckRankStatePerMC = CheckRankStatePerMC;
Protocol->CheckRankStatePerCh = CheckRankStatePerCh;
Protocol->GetSystemAddress = GetSystemAddress;
Protocol->GetChannelAddress = GetChannelAddress;
Protocol->AddressTranslation = AddressTranslation;
Protocol->GetRankAddress = GetRankAddress;
Protocol->ReverseAddressTranslate = ReverseAddressTranslate;
Protocol->DisableMemoryMigration = DisableMemoryMigration;
Protocol->SetupMemoryMigration = SetupMemoryMigration;
Protocol->TranslateRIR = TranslateRIR;
Protocol->GetErrorLogSysAddr = GetErrorLogSysAddr;
Protocol->StubInit = StubInit; // stub
Protocol->ForwardAddrTranslate = ForwardAddrTranslate;
Protocol->McChToLogChId = McChToLogChId;
Protocol->TadId2SadId = TadId2SadId;
Protocol->GetDDRTSystemAddress = GetDDRTSystemAddress;
Protocol->ForEachSocket = ForEachSocket;
Protocol->TranslateSAD = TranslateSAD;
Protocol->TranslateDDRTTad = TranslateDDRTTad;
//
// Step 9: Locate platform RAS policy protocol (unk_22B20).
// Returns the HOB list pointer with system configuration.
//
Status = gBS->LocateProtocol(&gPlatformRasHobGuid, NULL, (VOID **)&PlatformPolicy);
ASSERT_EFI_ERROR(Status);
//
// Step 10: Locate CPU CSR access and additional protocol.
//
Status = gBS->LocateProtocol(&gCpuCsrAccessGuid, NULL, (VOID **)&CpuCsrAccess);
ASSERT_EFI_ERROR(Status);
Status = gBS->LocateProtocol(&gPlatformProtocolGuid, NULL, &PlatformProtocol);
ASSERT_EFI_ERROR(Status);
//
// Step 11: Read platform configuration from policy protocol.
// Offset 1677: Channel mode (lockstep bit)
// Offset 1780: VLS enable flag
// Offset 1782: Spare mode
// Offset 1777: RAS mode (0=SDDC, 1=ADDDC, etc.)
// Offset 2067: Number of sockets
// Offset 280: Memory base address / range
// Offset 4: System memory size
// Offset 8: Number of channels
// Offset 12: Memory type
// Offset 20: Memory granularity
//
HobData = (UINT8 *)*(UINTN *)PlatformPolicy;
ChannelMode = HobData[1677];
VlsEnabled = HobData[1780];
SpareMode = HobData[1782];
NumSockets = *(UINT32 *)(HobData + 2067);
MemoryBase = *(UINT32 *)(HobData + 280);
MemoryRangeStart = *(UINT64 *)(HobData + 280);
MemoryRangeEnd = MemoryRangeStart + *(UINT32 *)(HobData + 288);
SystemMemorySize = *(UINT32 *)(HobData + 4);
NumChannels = *(UINT32 *)(HobData + 8);
MemoryType = *(UINT32 *)(HobData + 12);
MemoryGranularity = *(UINT32 *)(HobData + 20);
//
// Step 12: Initialize 4 socket entries in scratch buffer.
// Sets byte at offset 1606 to 1 for each socket.
//
for (UINT32 Socket = 0; Socket < 4; Socket++) {
HobData[1606 + 119 * Socket] = 1;
}
//
// Step 13: Install MemRas protocol interface.
// GUID: gEfiMemRasProtocolGuid (unk_22B30)
// Context data: Protocol structure (MEM_RAS_PROTOCOL *)
//
*(UINT64 *)((UINT8 *)ContextBuffer + 8) = 0; // Protocol handle init
Status = gBS->InstallProtocolInterface(
(EFI_HANDLE *)((UINT8 *)ContextBuffer + 8),
&gEfiMemRasProtocolGuid,
EFI_NATIVE_INTERFACE,
ContextBuffer + 16 // points to MEM_RAS_PROTOCOL *
);
ASSERT_EFI_ERROR(Status);
gMemRasProtocolHandle = *(EFI_HANDLE *)((UINT8 *)ContextBuffer + 8);
//
// Step 14: Register S3 boot script save handler.
// MemRasS3SaveRegister() - Allocates context, sets event type=3,
// registers the ready-to-boot callback for gEfiEventReadyToBootGuid,
// installs protocol for gEfiMemRasS3SaveProtocolGuid.
//
MemRasS3SaveRegister();
//
// Step 15: Initialize VLS (Virtual Lockstep) state.
// InitializeVLSInfo() - Sets VLS variable "VLSEstablished" to known GUID.
// If variable doesn't exist, creates it. Locates VariableArchProtocol
// and reads back "VLSEstablished" to verify.
//
InitializeVLSInfo();
//
// Step 16: Initialize spare copy done handler.
// SpareCopyDone()
//
Protocol->SpareCopyDone();
//
// Step 17: Initialize rank sparing event handler.
// CheckAndHandleNewRankSparingEvent()
//
Protocol->CheckAndHandleNewRankSparingEvent();
//
// Step 18: Conditionally initialize patrol scrub.
// If NumSockets >= 3 or NumSockets <= 1, start patrol scrub.
// HandlePatrolCompleteEventForNode()
//
if (NumSockets >= 3 || NumSockets <= 1) {
Protocol->HandlePatrolCompleteEventForNode();
}
//
// Step 19: Initialize alternate spare rank path.
// Alternate spare rank path is handled elsewhere in the protocol flow.
//
//
// Step 20: Register per-socket MCE events (if configured).
// If platform config byte (offset 35) has bits 2 and 4 set,
// register the MCE callback for event groups at
// unk_22C40 and unk_22C50.
//
if ((HobData[35] & 0x14) == 0x14) {
gBS->CreateEventEx(
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
MemRasMceEventNotify,
NULL,
&gEventGroupGuid1,
&Event1
);
gBS->CreateEventEx(
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
MemRasMceEventNotify,
NULL,
&gEventGroupGuid2,
&Event2
);
}
return EFI_SUCCESS;
}
//
// ============================================================================
// MemRasSecondaryInit() [MemRasSecondaryInit, 0xB6AC]
// ============================================================================
//
// Called from ModuleEntryPoint when MemRasInitGlobals() succeeds.
// If unk_23560 context is valid, calls MemRasDriverEntry().
// Otherwise sets global status to indicate failure.
//
EFI_STATUS
EFIAPI
MemRasSecondaryInit(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
//
// Global status initialized to error (0x8000000000000001)
//
gRasStatus = 0x8000000000000001uLL;
//
// Check if context (unk_23560) has setjmp/longjmp already set up.
// SetupAcpiSmmJumpRecovery performs a setjmp(context) - returns 0 on success.
//
if (!SetupAcpiSmmJumpRecovery(&unk_23560)) {
//
// Context was not initialized, so this is first entry.
// Call the full driver entry.
//
EFI_STATUS Status;
Status = MemRasDriverEntry(ImageHandle, SystemTable);
MemRasStatusUpdate(Status);
//
// Should never reach here - ASSERT failure.
//
ASSERT(FALSE);
}
return gRasStatus;
}
//
// ============================================================================
// MemRasFallbackInit() [MemRasFallbackInit, 0xB56C]
// ============================================================================
//
// Called when MemRasDriverEntry() returns an error.
// Provides alternative initialization path for error recovery.
//
// Initialization steps:
// 1. PlatformRasInit() - Platform-specific RAS initialization (925 bytes)
// 2. RegisterMemoryErrorEvents() - Memory error event registration
// 3. S3BootScriptSaveInit() - S3 boot script save (23 bytes, stub)
//
EFI_STATUS
EFIAPI
MemRasFallbackInit(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = PlatformRasInit();
ASSERT_EFI_ERROR(Status);
Status = RegisterMemoryErrorEvents(ImageHandle, SystemTable);
ASSERT_EFI_ERROR(Status);
Status = S3BootScriptSaveInit(ImageHandle, SystemTable);
ASSERT_EFI_ERROR(Status);
return Status;
}
//
// ============================================================================
// GetOrSetErrorHandlingStatus() [GetOrSetErrorHandlingStatus, 0xD7A0]
// ============================================================================
//
// Manages the per-node error handling progress and pending bitmaps.
//
// Operations:
// 0 (RAS_ERROR_PROGRESS):
// 0 = Clear Progress bit for NodeId
// 1 = Set Progress bit for NodeId (must have Pending bit set)
// 2 = Get Progress status
//
// 1 (RAS_ERROR_PENDING):
// 0 = Clear Pending bit for NodeId
// 1 = Set Pending bit for NodeId (must have Pending bit clear)
// 2 = Get Pending status
//
// 2 (RAS_ERROR_GET_STATUS):
// 2 = Get Progress status (via dword_23680)
// 3 = Get Pending status (via dword_23684)
//
//EFI_STATUS
//GetOrSetErrorHandlingStatus(
// IN UINT8 NodeId,
// IN UINT32 Operation,
// OUT UINT32 *Status OPTIONAL
// )
//{
// switch (Operation) {
// case 0: // Progress
// switch (*Status) {
// case 0: // Clear
// mEventProgressBitmap &= ~(1 << NodeId);
// DEBUG((DEBUG_INFO, "Clear Event Progress Node%d\n", NodeId));
// return EFI_SUCCESS;
// case 1: // Set
// ASSERT((mEventPendingBitmap & (1 << NodeId)) != 0);
// mEventProgressBitmap |= (1 << NodeId);
// DEBUG((DEBUG_INFO, "Set Event Progress Node%d\n", NodeId));
// return EFI_SUCCESS;
// default:
// ASSERT(FALSE);
// return EFI_INVALID_PARAMETER;
// }
//
// case 1: // Pending
// switch (*Status) {
// case 0: // Clear
// mEventPendingBitmap &= ~(1 << NodeId);
// DEBUG((DEBUG_INFO, "Clear Event Pending Node%d\n", NodeId));
// return EFI_SUCCESS;
// case 1: // Set
// ASSERT((mEventPendingBitmap & (1 << NodeId)) == 0);
// mEventPendingBitmap |= (1 << NodeId);
// DEBUG((DEBUG_INFO, "Set Event Pending Node%d\n", NodeId));
// return EFI_SUCCESS;
// default:
// ASSERT(FALSE);
// return EFI_INVALID_PARAMETER;
// }
//
// case 2: // Get - return Progress bitmap
// *Status = (mEventProgressBitmap >> NodeId) & 1;
// DEBUG((DEBUG_INFO, "Get Progress Node%d = %d\n", NodeId, *Status));
// return EFI_SUCCESS;
//
// case 3: // Get - return Pending bitmap
// *Status = (mEventPendingBitmap >> NodeId) & 1;
// DEBUG((DEBUG_INFO, "Get Pending Node%d = %d\n", NodeId, *Status));
// return EFI_SUCCESS;
//
// default:
// ASSERT(FALSE);
// return EFI_INVALID_PARAMETER;
// }
//}