Newer
Older
AMI-Aptio-BIOS-Reversed / MdeModulePkg / Universal / CapsulePei / Common / CapsuleX64 / CapsuleX64.h
@Ajax Dong Ajax Dong 2 days ago 9 KB Restructure the repo
#ifndef __CAPSULEX64_H__
#define __

#include "../uefi_headers/Uefi.h"
CAPSULEX64_H__

/*=============================================================================
 *  CapsuleX64.efi - Capsule PEI X64 Module
 *  MD5:   f20dc2f52ef47aa5bb67065361900b0a
 *  SHA256: f375c4b961d442295e12bd69e7648e2f45cf4a0d5c35f1795b611656107dbfcc
 *
 *  Source: MdeModulePkg/Universal/CapsulePei/X64/
 *  PEI module for x64 capsule update support. Handles page fault
 *  management during long-mode capsule coalescing, capsule descriptor
 *  validation/relocation, and the transition back to 32-bit mode via
 *  DisablePaging64.
 *============================================================================*/

#pragma pack(push, 1)

/*=============================================================================
 *  EFI Basic Types
 *============================================================================*/
typedef unsigned char       UINT8;
typedef unsigned short      UINT16;
typedef unsigned int        UINT32;
typedef unsigned long long  UINT64;
typedef signed char         INT8;
typedef short               INT16;
typedef int                 INT32;
typedef long long           INT64;
typedef long long           INTN;
typedef unsigned long long  UINTN;
typedef unsigned char       BOOLEAN;
typedef unsigned long long  EFI_STATUS;
typedef void *              EFI_HANDLE;
typedef UINT64              EFI_PHYSICAL_ADDRESS;
typedef UINT64              EFI_VIRTUAL_ADDRESS;
typedef struct __va_list_tag va_list;

#define TRUE                            1
#define FALSE                           0

#define EFI_SUCCESS                    0ULL
#define EFI_INVALID_PARAMETER          0x8000000000000002ULL
#define EFI_BUFFER_TOO_SMALL           0x8000000000000005ULL
#define EFI_NOT_READY                  0x8000000000000006ULL
#define EFI_OUT_OF_RESOURCES           0x8000000000000009ULL
#define EFI_NOT_FOUND                  0x800000000000000EULL

/*=============================================================================
 *  EFI_GUID
 *============================================================================*/
typedef struct {
    UINT32  Data1;
    UINT16  Data2;
    UINT16  Data3;
    UINT8   Data4[8];
} EFI_GUID;

/*=============================================================================
 *  EFI_TABLE_HEADER
 *============================================================================*/
typedef struct {
    UINT64  Signature;
    UINT32  Revision;
    UINT32  HeaderSize;
    UINT32  CRC32;
    UINT32  Reserved;
} EFI_TABLE_HEADER;

/*=============================================================================
 *  EFI_SYSTEM_TABLE
 *============================================================================*/
typedef struct {
    EFI_TABLE_HEADER    Hdr;
    UINT16              *FirmwareVendor;
    UINT32              FirmwareRevision;
    UINT32              ConsoleInHandle;
    void                *ConIn;
    UINT32              ConsoleOutHandle;
    void                *ConOut;
    UINT32              StandardErrorHandle;
    void                *StdErr;
    void                *RuntimeServices;
    void                *BootServices;
    UINT64              NumberOfTableEntries;
    void                *ConfigurationTable;
} EFI_SYSTEM_TABLE;

/*=============================================================================
 *  IDTR / GDTR structures
 *============================================================================*/
typedef struct {
    UINT16  Limit;
    UINT64  Base;
} IDTR;

typedef struct {
    UINT16  Limit;
    UINT64  Base;
} GDTR;

/*=============================================================================
 *  EFI_CAPSULE_HEADER
 *============================================================================*/
typedef struct {
    EFI_GUID    CapsuleGuid;
    UINT32      HeaderSize;
    UINT32      Flags;
    UINT32      CapsuleImageSize;
} EFI_CAPSULE_HEADER;

/*=============================================================================
 *  EFI_CAPSULE_BLOCK_DESCRIPTOR
 *============================================================================*/
typedef struct {
    UINT64  Length;
    union {
        UINT64  DataBlock;
        UINT64  ContinuationPointer;
    } Union;
} EFI_CAPSULE_BLOCK_DESCRIPTOR;

/*=============================================================================
 *  Memory Resource Descriptor
 *============================================================================*/
typedef struct {
    UINT64  BaseAddress;
    UINT64  Length;
} MEMORY_RESOURCE_DESCRIPTOR;

/*=============================================================================
 *  Page table context (ring buffer for page allocation)
 *============================================================================*/
typedef struct {
    UINT64  PageTableStack[8];     /* Page pool ring buffer entries */
    UINT64  PageTableStackIndex;   /* Current index in ring buffer (0-7) */
    UINT64  PageMapLevel4Table;    /* PML4 address/mask */
    UINT64  PhysicalAddressBits;   /* Bits to mask for physical address */
} PAGE_TABLE_CONTEXT;

/*=============================================================================
 *  Function Prototypes
 *============================================================================*/

/* ---- Entry point ---- */
EFI_STATUS  ModuleEntryPoint(EFI_HANDLE ImageHandle,
                             EFI_SYSTEM_TABLE *SystemTable);
void        CapsuleX64Entry(UINT64 a1, UINT64 a2, UINT64 a3, UINT64 a4);

/* ---- Page fault and exception handling ---- */
void        PageFaultHandlerWrapper(UINT64 a1, UINT64 a2,
                                    UINT64 a3, UINT64 a4);
UINT64      PageFaultHandlerCore(void);
void        X64ExceptionHandler(UINT64 ExceptionType, UINT64 *ContextRecord);
void        SetPageFaultHandled(UINT8 Flag);
void        InitPageFaultHandler(void (**Table)());

/* ---- CPUID ---- */
UINT64      AsmCpuid(UINT32 Leaf, UINT32 *pEax, UINT32 *pEbx,
                     UINT32 *pEcx, UINT32 *pEdx);
UINT64      AsmCpuidEx(UINT32 Leaf, UINT32 Subleaf,
                       UINT32 *pEax, UINT32 *pEbx,
                       UINT32 *pEcx, UINT32 *pEdx);

/* ---- CR/segment ---- */
UINT64      AsmReadCr3(void);
UINT64      AsmReadCr2(void);
UINT16      AsmReadCs(void);
void        AsmReadIdtr(void *pIdtr);
void        AsmWriteIdtr(UINT16 *pLimit);
void        AsmDisablePaging64(UINT16 Signature, UINT64 EntryPoint,
                               EFI_HANDLE ImageHandle,
                               EFI_SYSTEM_TABLE *SystemTable,
                               UINT32 NewStack);

/* ---- Capsule operations ---- */
UINT64      ValidateCapsuleIntegrity(UINT64 BlockList,
                        MEMORY_RESOURCE_DESCRIPTOR *MemoryResources);
EFI_STATUS  GetCapsuleInfo(EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc,
                           UINT64 *CapsuleCount, UINT64 *TotalLength,
                           UINT64 *CapsuleNumber);
EFI_STATUS  CapsuleCoalesce(UINT64 ScratchSize,
                            UINT64 *BlockListBuffer,
                            UINT64 *MemoryResource,
                            UINT64 **BlockDescriptors,
                            UINT32 *CapsuleDescriptorCount);

/* ---- Page table management ---- */
UINT64      AllocatePageTablePage(PAGE_TABLE_CONTEXT *ptCtx,
                                  UINT64 *pPteAddr);
UINT64      BitFieldReadU64(UINT64 Value, UINT64 StartBit, UINT64 EndBit);
UINT64      InternalLShiftU64(UINT64 Value, UINT64 Count);

/* ---- Memory ---- */
void        *InternalZeroMem(void *Buffer, UINT64 Size);
void        *InternalCopyMem(void *Dest, const void *Src, UINT64 Count);
void        *ZeroMem(void *Buffer, UINT64 Size);
void        *CopyMem(void *Dest, const void *Src, UINT64 Count);

/* ---- Descriptor relocation ---- */
UINT64      *RelocateCapsuleDescriptors(
                EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc,
                UINT64 *FlatBuffer,
                UINT64 DescriptorCount,
                UINT64 *ScratchBuffer,
                UINT64 ScratchSize);
UINT64      *FindFreeMemoryInDescriptors(UINT64 *ResourceArray,
                                         UINT64 *Target,
                                         UINT64 Size,
                                         UINT64 SourceBase);
BOOLEAN     ValidateMemoryResource(MEMORY_RESOURCE_DESCRIPTOR *MemResources,
                                   UINT64 Address, UINT64 Size);

/* ---- Debug ---- */
UINT8       DebugPrint(UINT64 ErrorLevel, const char *Format, ...);
UINT64      AssertFail(UINT64 Filename, INT32 LineNumber,
                       UINT64 Expression);
UINT64      DebugPrintWorker(const char *Format, ...);

/* ---- String helpers ---- */
UINT64      AsciiStrLen(const char *String);
UINT64      InternalVSPrint(UINT8 *Buffer, UINT64 BufferSize,
                            UINT64 Flags, const char *Format,
                            va_list VaList);
UINT8       *InternalPrintPad(UINT8 *Buffer, UINT64 BufferSize,
                              UINT64 Count, UINT16 Char,
                              UINT64 CharWidth);

/* ---- Serial ---- */
UINT64      SerialPortWrite(UINT8 *Buffer, UINT64 Size);

/* ---- PE/COFF ---- */
char        *PeCoffGetPdbPath(char *Pe32Data);

/* ---- Image info ---- */
void        FindAndLogImageInfo(void *ExceptionType, UINT64 *ContextRecord);
UINT64      DumpExceptionContext(void *ExceptionType, UINT64 *ContextRecord);

/* ---- APIC ---- */
UINT64      GetApicId(void);

#pragma pack(pop)

#endif /* __CAPSULEX64_H__ */