/**
* S3SaveStateDxe.h
* Lenovo HR650X BIOS - S3 Save State DXE Driver
*
* This DXE driver is responsible for:
* 1. Saving ACPI S3 context (FACS table, IDTR profile, page tables, boot script stack)
* into the SMM LockBox for use during S3 resume.
* 2. Providing the EFI S3 Boot Script protocol for recording boot script entries
* (I/O, memory, PCI config, etc.) that are replayed during S3 resume.
* 3. Managing the boot script buffer (allocation, growth, synchronization with SMM).
*
* Module: S3SaveStateDxe.efi
* Image: 0288_S3SaveStateDxe_807650fb83eb
* SHA256: 807650fb83ebcd72a3d8c5b2c4e201dbcf5af25150a6d0fe62296f1030255b8e
* Arch: X64
* Base: 0x0
* Size: 0x5AA0
*/
#ifndef __S3SAVESTATEDXE_H__
#define __S3SAVESTATEDXE_H__
#include <Uefi.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/S3SaveState.h>
#include <Protocol/S3SmmSaveState.h>
// ---------------------------------------------------------------------------
// GUID Definitions (from .rdata references)
// ---------------------------------------------------------------------------
// unk_52C0 - gEfiSmmCommunicationRegionTableGuid
// unk_52D0 - gEfiDebugPortProtocolGuid (used by DebugLib)
// unk_52E0 - gEfiSmmCommunicationProtocolGuid
// unk_52F0 - LockBox GUID: ACPI S3 Context
// unk_5300 - gEfiDxeSmmReadyToLockProtocolGuid
// unk_5310 - gEfiLockBoxProtocolGuid
// unk_5320 - gEfiPcdProtocolGuid
// unk_5330 - Protocol notify for SmmReadyToLock
// unk_5340 - Protocol notify for S3 Save State (DXE->SMM)
// unk_5350 - ACPI table GUID #1 for FACS lookup
// unk_5360 - LockBox GUID: ACPI S3 Context (for SetAttributes)
// unk_5370 - Protocol GUID for S3 Save State
// unk_5380 - LockBox GUID: S3 Boot Script
// unk_5390 - Protocol notify for S3 SMM Save State
// unk_53A0 - gEfiHobListGuid
// unk_53B0 - ACPI table GUID #2 for FACS lookup
// unk_53D0 - SMM Communication protocol instance
// unk_53E0 - EFI S3 Save State protocol notification
// unk_5400 - LockBox GUID: ACPI S3 Context (for SaveLockBox/SetAttributes)
// qword_5410 - LockBox GUID: Boot Script data (for Save/SetAttributes)
// unk_5420 - LockBox GUID: Boot Script (for Restore)
// qword_5430 - LockBox GUID: BootScriptMemory (for Save)
// qword_5440 - LockBox GUID: S3 Boot Script Table
// unk_5450 - S3 Save State protocol instance
//
// NOTE: These entries correspond to 16-byte EFI_GUID structures
// stored in the .rdata segment. Exact GUID values can be extracted
// from the raw bytes at each address.
// ---------------------------------------------------------------------------
// Global Variables (from .data section)
// ---------------------------------------------------------------------------
// Address Name Size Description
// ------- ---- ---- -----------
// 0x5458 gSystemTable 8 EFI System Table pointer
// 0x5460 gBootServices ^ ^(duplicated with BootServices) -> actually this is gBS
// 0x5468 gImageHandle 8 Driver image handle
// 0x5470 gRuntimeServices 8 EFI Runtime Services pointer
// 0x5478 gDebugPortProtocol 8 Cached DebugPort protocol (used by DebugLib)
// 0x5480 gPcdProtocol 8 Cached PCD protocol
// 0x5488 gHobList 8 Cached HOB list pointer
// 0x5490 gPciExpressBaseAddress 8 Cached PCI Express MMIO base
// 0x5498 gSmmCommRegion 8 Cached SMM communication region
// 0x54A0 gSmmCommunication 8 Cached SMM Communication protocol
// 0x54A8 gS3SaveStateNotify 8 S3 Save State registration
// 0x54B0 gBootScriptInSmm 1 Boot script buffer in SMM flag
// 0x54B8 mEventDxeSmmReadyToLock 8 SMM Ready To Lock event
// 0x54C0 gS3SmmSaveState 8 S3 SMM Save State protocol
// 0x54C8 gS3SaveStateReg 8 S3 Save State registration
// 0x54D0 gS3SmmSaveStateReg 8 S3 SMM Save State registration
// 0x54D8 gBootScriptInSmm2 1 Boot script in SMM flag #2
// 0x54E0 gS3BootScriptTable 8 Boot script table context pointer
// 0x54E8 gBootScriptCurrent 8 Current (SMM) boot script table
// ---------------------------------------------------------------------------
// Boot Script Entry Header
// ---------------------------------------------------------------------------
#pragma pack(push, 1)
//
// An S3 boot script entry has a variable-length format:
//
// +0 UINT16 EntryType (0x0000=I/O, 0x0001=Mem, 0x0002=PCI, etc.)
// +2 UINT8 EntryLength (total length of this entry including header)
// +3 ... Data (type-dependent payload)
//
// Entry types:
// 0 EFI_BOOT_SCRIPT_IO_WRITE (ScriptIoWriteEntry)
// 1 EFI_BOOT_SCRIPT_IO_READ_WRITE (ScriptIoReadWriteEntry)
// 2 EFI_BOOT_SCRIPT_MEM_WRITE (ScriptMemWriteEntry)
// 3 EFI_BOOT_SCRIPT_MEM_READ_WRITE (ScriptMemReadWriteEntry)
// 4 EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE (ScriptPciCfgWriteEntry)
// 5 EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE (ScriptPciCfgReadWriteEntry)
// 6 EFI_BOOT_SCRIPT_SMBUS_EXECUTE (ScriptSmbusExecuteEntry)
// 7 EFI_BOOT_SCRIPT_STALL (ScriptStallEntry)
// 8 EFI_BOOT_SCRIPT_DISPATCH (ScriptDispatchEntry)
// 9 EFI_BOOT_SCRIPT_INFORMATION (ScriptInformationEntry)
// 10 EFI_BOOT_SCRIPT_PCI_CFG2_WRITE (ScriptPciCfg2WriteEntry)
// 11 EFI_BOOT_SCRIPT_PCI_CFG2_READ_WRITE (ScriptPciCfg2ReadWriteEntry)
// 12 EFI_BOOT_SCRIPT_MEM2_WRITE (ScriptMem2WriteEntry)
// 13 EFI_BOOT_SCRIPT_MEM2_READ_WRITE (ScriptMem2ReadWriteEntry)
// 14 EFI_BOOT_SCRIPT_IO2_WRITE (ScriptIo2WriteEntry)
// 15 EFI_BOOT_SCRIPT_IO2_READ_WRITE (ScriptIo2ReadWriteEntry)
// 16 EFI_BOOT_SCRIPT_DISPATCH_2 (ScriptDispatch2Entry)
//
// Common boot script entry prefix:
//
typedef struct {
UINT16 Type; // 0x0000-0x0010
UINT8 Length; // total entry length
// Followed by type-specific data...
} BOOT_SCRIPT_ENTRY_HEADER;
//
// S3 Boot Script Table descriptor (qword_54E0 / qword_54E8 points here):
//
typedef struct {
UINT64 BufferAddress; // +0x00: Physical address of boot script buffer
UINT32 CurrentOffset; // +0x08: Current write offset into buffer
UINT16 BufferPages; // +0x0C: Buffer size in 4K pages
UINT8 Field0E; // +0x0E: Unknown (copy flag)
UINT8 Field0F; // +0x0F: Unknown (closed flag)
UINT32 TotalLength; // +0x10: Total length (including terminator)
UINT8 Padding[3]; // +0x14-0x16
UINT8 SmmReadyLock; // +0x17: SMM ready-to-lock flag (field 0x17)
UINT8 Field18; // +0x18
UINT8 Reserved[7];
} BOOT_SCRIPT_TABLE;
//
// ACPI S3 Context structure (AcpiS3Context)
//
typedef struct {
UINT64 AcpiFacsTable; // +0x00: FACS table address
UINT64 IdtrProfile; // +0x08: IDTR profile buffer
UINT64 S3NvsPageTableAddress; // +0x10: S3 NVS page table
UINT64 BootScriptStackBase; // +0x18: Boot script stack base address
UINT32 BootScriptStackSize; // +0x20: Stack size (0x8000)
UINT32 Reserved1;
UINT64 S3DebugBufferAddress; // +0x28: Debug buffer (4KB cleared, set to 0xFF)
} ACPI_S3_CONTEXT;
#pragma pack(pop)
// ---------------------------------------------------------------------------
// Function Prototypes
// ---------------------------------------------------------------------------
//
// Driver Entry / Initialization
//
EFI_STATUS
EFIAPI
DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
//
// ACPI S3 Context Save functions (from AcpiS3ContextSave.c)
//
EFI_STATUS
AcpiS3ContextInitialize (
VOID
);
VOID *
AllocatePagesOrCrash (
IN UINTN Size
);
UINT64
AllocateS3NvsPageTable (
IN BOOLEAN EnableNX
);
UINTN
LocateAcpiFacsTable (
IN EFI_GUID *TableGuid
);
UINTN
GetSystemConfigurationTable (
IN EFI_GUID *TableGuid,
OUT VOID **Table
);
//
// Boot Script Save Library (from PiDxeS3BootScriptLib)
//
EFI_STATUS
BootScriptTableInit (
VOID
);
VOID *
ScriptAllocateEntry (
IN UINT8 EntrySize
);
VOID
ScriptFinalizeEntry (
IN VOID *Entry
);
EFI_STATUS
ScriptSaveLockBox (
IN EFI_GUID *Guid,
IN VOID *Buffer,
IN UINTN Length
);
EFI_STATUS
ScriptSetLockBoxAttributes (
IN EFI_GUID *Guid,
IN UINT64 Attributes
);
EFI_STATUS
ScriptUpdateLockBox (
IN EFI_GUID *Guid,
IN UINTN Offset,
IN VOID *Buffer,
IN UINTN Length
);
EFI_STATUS
ScriptRestoreLockBox (
IN EFI_GUID *Guid,
IN VOID *Buffer,
IN OUT UINTN *Length
);
VOID
ScriptNotifySmmReady (
VOID
);
VOID
ScriptNotifyBootScriptDone (
VOID
);
//
// SMM Communication wrappers
//
EFI_STATUS
SmmCommunicationSend (
IN UINTN Function,
IN VOID *CommBuffer,
IN UINTN CommSize
);
VOID *
SmmCommunicationGetBuffer (
VOID
);
//
// Misc library helpers wrapped in this module
//
VOID
PciExpressWrite16 (
IN UINTN Address,
IN UINT16 Value
);
UINT32
IoRead32 (
IN UINT16 Port
);
//
// Boot Script write dispatchers
//
EFI_STATUS
EFIAPI
S3BootScriptWrite (
IN UINT16 Type,
...
);
EFI_STATUS
EFIAPI
S3BootScriptWriteThenPoll (
IN UINT16 Type,
...
);
//
// Internal boot script entry writers (typed):
//
EFI_STATUS
ScriptIoWrite (
IN EFI_BOOT_SCRIPT_IO_WRITE_PARAMS *Params
);
EFI_STATUS
ScriptIoReadWrite (
IN EFI_BOOT_SCRIPT_IO_READ_WRITE_PARAMS *Params
);
EFI_STATUS
ScriptPciCfgWrite (
IN EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_PARAMS *Params
);
EFI_STATUS
ScriptSmbusExecute (
IN EFI_BOOT_SCRIPT_SMBUS_EXECUTE_PARAMS *Params
);
EFI_STATUS
ScriptStall (
IN EFI_BOOT_SCRIPT_STALL_PARAMS *Params
);
//
// Boot script buffer management
//
VOID
ScriptCloseTable (
VOID
);
#endif // __S3SAVESTATEDXE_H__