Newer
Older
AMI-Aptio-BIOS-Reversed / Volume_Top_File / Volume_Top_File.c
@Ajax Dong Ajax Dong 2 days ago 54 KB Init
/**
 * Volume_Top_File.c
 *
 * HR650X BIOS - Volume_Top_File PEI Module
 * Build: DEBUG_VS2015 IA32
 * Source: UefiCpuPkg/SecCore + various MdePkg libraries
 *
 * This module implements the SEC (Security) phase and early PEI
 * initialization for the Intel Purley (Xeon Scalable) platform.
 *
 * The SEC phase is the earliest executable code in the BIOS. It:
 *   1. Sets up cache-as-RAM (temporary RAM)
 *   2. Configures CPU MTRRs
 *   3. Sets up protected mode GDT and IDT with exception handlers
 *   4. Processes BIST (Built-In Self Test) results
 *   5. Locates and decompresses the PEI Core in the firmware volume
 *   6. Transfers control to the PEI Core
 *
 * All functions are organized by component/source file.
 */

#include "Volume_Top_File.h"

/*=============================================================================
 * Forward declarations
 *============================================================================*/

/* Memory operations */
static void* InternalCopyMem(void* dst, const void* src, unsigned int count);
static void* InternalZeroMem(void* buf, unsigned int count);

/* String/Print operations */
static unsigned int AsciiStrLen(const char* str);
static unsigned int AsciiStrnLen(const char* str, unsigned int maxlen);
static unsigned int AsciiStrLenWorker(const unsigned char* str);
static unsigned int AsciiSPrintWorker(unsigned char* buf, unsigned int bufsize, ...);
static int AsciiValueToString(...);
static int UnicodeValueToString(...);

/* PEI Core services */
static int PeiCoreEntryPoint(unsigned int fv_base, void** pei_core_entry);
static int FindPeiCore(unsigned int fv_base, int** pei32_ptr, int** te_ptr);
static char* PeCoffImageRelocate(char* image_base);
static int PeCoffGetEntryPoint(char* image_base, void** entry_point);
static char* PeCoffSearchImageBase(unsigned int address);

/* HOB services */
static int* GetHobList(void);
static void* GetNextHob(unsigned short type, void* hob_start);
static void* GetFirstHob(unsigned short type);
static void* GetHobByType(unsigned short type);
static void* CreateHobGuid(unsigned int guid, unsigned int data_len);
static void* BuildGuidHob(unsigned int guid, unsigned int data_len, unsigned int data);

/* SEC core entrypoint chain */
static int SecStartup(unsigned int stack_size, int temp_ram_base, int sec_core_data);
static int SecCoreEntryPoint(short* sec_core_data_params);
static int InstallSecPpi(void);
static int SecBist(void);
static int SecTemporaryRamStackInit(void);
static unsigned long long SecTemporaryRamSupport(unsigned int* registers);

/* CPU register helpers */
static void SecInitializeFpu(void);
static void SecInitializeBootMode(void);
static void SecReadSecCoreData(int sec_core_data);
static int SecReadIdtBase(void);
static int SecGetStackInfo(void);
static unsigned int SecReadPeiCoreEntry(void);
static void SecSetupGdt(int mtrr_index, int* gdt_value);
static void SecSetupExceptionHandlers(int mtrr_index, int idt_entry_value);
static void SecMtrrSetup(int unused, int config_table);
static unsigned int SecReadCr0(void);
static unsigned int SecReadCr2(void);
static unsigned int SecReadCr3(int mode, unsigned int* out, int unused);
static unsigned int SecReadCr4(void);
static void SecWriteCr0(unsigned int value);
static void SecWriteCr4(unsigned int value);
static void SecEnableSse(void);
static unsigned int SecReadEflags(void);
static int SecSwitchStack(void);
static unsigned int SecReadTemporaryRamStack(void);
static unsigned int SecGetTemporaryMemorySize(void);
static int SecSetIdtGateType(void);
static int SecSetIdtEntryOffset(void);
static int SecInitIdtEntry(void* handlers);

/* Exception handling */
static void SecExceptionDispatcher(void);
static unsigned int SecDefaultExceptionHandler(unsigned int exception_info);
static void NullExceptionHandler(void);
static void NullFunction(void);
static void ExceptionHandler0(void);
static void ExceptionHandler1(void);
static void ExceptionHandler3(void);
static void ExceptionHandler4(void);
static void ExceptionHandler5(void);
static void ExceptionHandler6(void);

/* PEI Service helpers */
static int* GetPeiServicesTablePointer(void);
static int PeiServiceLocatePpi(int pei_services, int guid, int notify, unsigned int* instance, unsigned long long* data);

/* Debug output */
static unsigned int Assert(int filename, unsigned int line, unsigned int msg);
static unsigned char DebugPrint(int error_level, const char* format, ...);

/* Serial / I/O */
static int SerialPortWrite(const unsigned char* buffer, int count);
static int CheckAsciiStrLen(void);
static unsigned int IoRead32(unsigned short port);
static void IoWrite32(unsigned short port, unsigned int value);
static int IoRead16(unsigned short port);
static int IoReadWrite8(int unused, unsigned short port);
static int PciCfgReadWrite(int unused, short bus_dev_func, char command, int access_type);

/* MSR helpers */
static void WriteMsr(unsigned int msr, unsigned int value);
static unsigned long long ReadMsr(unsigned int msr);

/* IDT/LDT wrappers */
static void LidtWrapper(unsigned short* limit);
static void SidtWrapper(unsigned short* limit_and_base);

/* Base library */
static char* CopyMem(char* dst, const char* src, unsigned int count);
static void* ZeroMem(int buf, unsigned int count);
static int CopyGuid(int dst, int src);
static int CompareGuid(int guid1, int guid2);
static unsigned long long ReadGuidAsU64Pairs(void* guid);
static unsigned long long WriteGuidAsU64Pairs(void* guid);
static int AsciiToUpper(int c);
static int CheckStringLen(const char* str);
static unsigned int CheckAsciiStrLen(const unsigned char* str);

/*=============================================================================
 * Module Entry Point
 *============================================================================*/

/**
 * _ModuleEntryPoint - Entry point from reset vector
 *
 * The reset vector jumps here. This is the first IA32 code executed.
 * It initializes the FPU and jumps to the actual SEC startup path.
 * The JUMPOUT goes to SecTemporaryRamSupport/SecStartup via the
 * BPDT (Boot Policy Dispatch Table) mechanism.
 */
EFI_STATUS __noreturn ModuleEntryPoint(
    EFI_HANDLE ImageHandle,
    EFI_SYSTEM_TABLE *SystemTable
)
{
    __asm { fninit }
    JUMPOUT(0x5BEA1375);
}

/**
 * ModuleEntryPointThunk - Handles PEI entry transition
 * Size: 0x0A bytes
 */
void ModuleEntryPointThunk(void)
{
    // Transition stub - handles call from _ModuleEntryPoint
}

/**
 * SecHandleSysCalls - SEC system call handler
 * Size: 0x0A bytes
 * This is a minimal handler that catches syscall/sysenter in SEC phase
 */
void SecHandleSysCalls(void)
{
    // System call handling placeholder
}

/**
 * NullStub - Returns NULL
 * Size: 0x03 bytes
 * Used as fallback when no PPI is installed
 */
void* NullStub(void)
{
    return 0;
}

/*=============================================================================
 * SEC Phase Initialization
 *============================================================================*/

/**
 * SecStartup - SEC phase startup
 *
 * This is the main entry point called after the reset vector initialization.
 * It validates the stack size, reads the boot mode, initializes the FPU,
 * sets up the IDT (Interrupt Descriptor Table) with exception handlers for
 * up to 32 IA32 exceptions, and launches SecCoreEntryPoint.
 *
 * @param PeiStackSize    Size of stack to reserve for PEI
 * @param TempRamBase     Base address of temporary RAM (cache-as-RAM)
 * @param SecCoreData     Pointer to SEC_PEI_CORE_DATA structure
 * @return Returns the result from SecCoreEntryPoint
 */
int SecStartup(
    unsigned int PeiStackSize,
    int TempRamBase,
    int SecCoreData)
{
    int BootMode;
    char* Dst;
    int Index34;
    unsigned int StackSize;
    unsigned int IdtEntryCount;
    short* IdtrPtr;
    unsigned int i;
    char* Dst2;
    short Limit271;
    short Limit36;
    unsigned short IdtLimitAndBase[1];
    int SecCoreDataCopy[11];
    void* ExceptionHandlers[5];
    unsigned char IdtTemplate[272];

    // Validate: PeiStackSize must be < SizeOfRam / 2
    if (PeiStackSize >> 1 >= PeiStackSize) {
        Assert("e:\\hs\\UefiCpuPkg\\SecCore\\SecMain.c", 0x8F,
               "PeiStackSize < SizeOfRam");
    }

    // Read boot mode from CMOS
    BootMode = SecInitializeBootMode();
    if (BootMode < 0) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", BootMode);
        Assert("e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\IA32\\"
               "UefiCpuPkg\\SecCore\\SecCore\\DEBUG\\AutoGen.c",
               0x1AB, "!EFI_ERROR (Status)");
    }

    // Initialize FPU
    SecInitializeFpu();

    // Copy default IDT entry template from .data section
    Dst = IdtTemplate;
    Index34 = 34;
    do {
        CopyMem(Dst, gIdtTemplateSource, 8);
        Dst += 8;
        --Index34;
    } while (Index34);

    // Save current IDTR
    Dst2 = IdtTemplate;
    Limit271 = 271;
    LidtWrapper(&Limit271);
    SidtWrapper(IdtLimitAndBase);

    // Calculate how many IDT entries we need (max 32)
    StackSize = PeiStackSize;
    IdtEntryCount = (IdtLimitAndBase[0] + 1) >> 3;
    if (IdtEntryCount > 0x20)
        IdtEntryCount = 32;

    // Initialize IDT entries with exception gate type 0x8E
    SecInitIdtEntry(ExceptionHandlers);
    if (IdtEntryCount) {
        short* IdtEntry = (short*)(IdtLimitAndBase[1] + 6);
        i = 0;
        do {
            *(IdtEntry - 2) = 0x08;  // CS segment selector
            char* HandlerAddr = (char*)ExceptionHandlers[0] + i * (unsigned int)ExceptionHandlers[1];
            *(IdtEntry - 3) = (short)HandlerAddr;
            *IdtEntry = (unsigned short)((unsigned int)HandlerAddr >> 16);
            IdtEntry += 4;
            *((unsigned char*)IdtEntry - 9) = 0x8E;  // 32-bit interrupt gate
            ++i;
        } while (i < IdtEntryCount);
        StackSize = PeiStackSize;
    }

    // Build SecCoreData structure
    Limit36 = 36;  // Number of fields in SecCoreData
    SecCoreDataCopy[2] = SecCoreData;
    SecCoreDataCopy[3] = -SecCoreData;
    SecCoreDataCopy[5] = StackSize;
    unsigned int HalfRam = StackSize - (PeiStackSize >> 1);
    SecCoreDataCopy[4] = TempRamBase;
    SecCoreDataCopy[6] = TempRamBase;
    SecCoreDataCopy[8] = HalfRam + TempRamBase;
    SecCoreDataCopy[7] = HalfRam;
    SecCoreDataCopy[9] = PeiStackSize >> 1;

    return SecCoreEntryPoint((short*)&Limit36);
}

/**
 * SecCoreEntryPoint - Core SEC entry after basic initialization
 *
 * This function:
 *   - Calls PeiCoreEntryPoint to find the PEI Core in the firmware volume
 *   - If PPI descriptors are provided by PEI Core, copies them
 *   - Builds the final PEI handoff data
 *   - Transfers control to PeiCoreEntryPoint with full SEC_PEI_CORE_DATA
 *
 * @param p_n36    Pointer to SEC_PEI_CORE_DATA structure fields
 * @return Never returns (transfers to PEI Core)
 */
int SecCoreEntryPoint(short* p_n36)
{
    char* Dst;
    int (*PeiCoreEntry)(short*, char*);
    int n3;
    char* Src;
    int n3_2;
    unsigned int DescriptorSize;
    char* SecCoreDataArea;
    int Index;
    int v12;

    Dst = (char*)*((unsigned int*)p_n36 + 5);

    // Find PEI Core entry point
    PeiCoreEntryPoint(*((unsigned int*)p_n36 + 1),
                      (void**)&PeiCoreEntry);
    if (!PeiCoreEntry) {
        Index = 0;
        while (1) ;  // Hang
    }

    // Check for PPI descriptors (NullStub returns 0 if none)
    Src = (char*)NullStub();
    if (Src) {
        // Copy PPIs - first descriptor at Dst (24 bytes)
        CopyMem(Dst, " ", 0x24);
        *((unsigned int*)Dst + 6) &= ~0x80000000;

        // Copy remaining descriptors from PEI Core
        if (*(int*)Src >= 0) {
            char* Dst_1 = Dst + 36;
            n3_2 = 3;
            do {
                CopyMem(Dst_1, Src, 0x0C);
                Src += 12;
                ++n3_2;
                Dst_1 += 12;
            } while (*(int*)Src >= 0);
            n3 = n3_2;
        } else {
            n3 = 3;
        }
        CopyMem(&Dst[12 * n3], Src, 0x0C);

        // Update PEI temporary RAM usage
        DescriptorSize = 12 * (n3 + 1);
        if (*((unsigned int*)p_n36 + 6) <= DescriptorSize) {
            Assert("e:\\hs\\UefiCpuPkg\\SecCore\\SecMain.c", 0x114,
                   "SecCoreData->PeiTemporaryRamSize > "
                   "Index * sizeof (EFI_PEI_PPI_DESCRIPTOR)");
        }
        *((unsigned int*)p_n36 + 5) = (DescriptorSize +
                                        *((unsigned int*)p_n36 + 5) + 7) & 0xFFFFFFF8;
        *((unsigned int*)p_n36 + 6) = (*((unsigned int*)p_n36 + 6) - DescriptorSize) & 0xFFFFFFF8;
    } else {
        Dst = " ";  // Empty PPI descriptor
    }

    DebugPrint(64, "%a() Stack Base: 0x%p, Stack Size: 0x%x\n",
               "SecStartupPhase2",
               (void*)*((unsigned int*)p_n36 + 7),
               *((unsigned int*)p_n36 + 8));

    if (!PeiCoreEntry) {
        Assert("e:\\hs\\UefiCpuPkg\\SecCore\\SecMain.c", 0x137,
               "PeiCoreEntryPoint != ((void *) 0)");
    }

    return PeiCoreEntry(p_n36, Dst);
}

/**
 * InstallSecPpi - Install SEC PPIs (PEI-to-PEI Interfaces)
 *
 * Called early in SEC initialization to install platform PPIs.
 * Calls BIST handler, enables/disables interrupts based on EFLAGS.
 */
int InstallSecPpi(void)
{
    unsigned short Eflags;

    SecBist();

    Eflags = __readeflags();
    _disable();

    SecTemporaryRamStackInit();

    if ((Eflags & 0x200) != 0)  // IF flag
        _enable();
    else
        _disable();

    return 0;
}

/*=============================================================================
 * PEI Core Discovery
 *============================================================================*/

/**
 * FindPeiCore - Locate PEI Core in the firmware volume
 *
 * Parses the Firmware Volume (FV) pointed to by FV base address.
 * The FV contains a series of FFS (Firmware File System) files.
 * This function walks the FV looking for files of type PEIM (3)
 * or FV_PEIM (4), and within them finds sections of type PE32
 * (16) or TE (18) that contain the PEI Core image.
 *
 * @param FvBase     Base address of the firmware volume
 * @param Pei32Ptr   Output: pointer to PE32 image section
 * @param TePtr      Output: pointer to TE image section
 * @return EFI_STATUS: 0 = success, negative = error
 */
int FindPeiCore(
    unsigned int FvBase,
    int** Pei32Ptr,
    int** TePtr)
{
    unsigned long long FvEnd;
    int FfsHeaderOffset;
    unsigned int Current_hi;
    unsigned int Current;
    unsigned int Next_hi;
    unsigned int Next;
    unsigned int FfsSize;
    unsigned int n;
    unsigned char FileType;
    unsigned long long SecOffset;
    int* SecHeader;
    unsigned int SecSize;
    unsigned char SecType;
    int* FileHeader;

    FvEnd = *(unsigned long long*)(FvBase + 32) + FvBase;
    FfsHeaderOffset = *(unsigned short*)(FvBase + 48);

    *Pei32Ptr = 0;
    *(Pei32Ptr + 1) = 0;
    *TePtr = 0;
    *(TePtr + 1) = 0;

    // Walk through FFS files in the firmware volume
    for (Current = FvBase + FfsHeaderOffset; ; Current = Next) {
        Next = (Current + 7) & 0xFFFFFFF8;
        if (Next + (unsigned long long)0 > FvEnd)
            break;

        // Handle extended FFS header
        if ((*(unsigned char*)(Next + 19) & 1) != 0) {
            FfsSize = *(unsigned int*)(Next + 24);
            if (FfsSize <= 0xFFFFFF)
                return -2147483634;  // EFI_NOT_FOUND
        } else {
            FfsSize = *(unsigned int*)(Next + 20) & 0xFFFFFF;
            if (FfsSize < 0x18)
                return -2147483634;  // EFI_NOT_FOUND
        }

        Next = Next + FfsSize;

        if (Next > (unsigned long long)FvEnd)
            break;

        // Check file type: PEIM (3) or FV_PEIM (4)
        FileType = *(unsigned char*)(Next + 18);
        if (FileType == 3 || FileType == 4) {
            // Walk sections within this PEIM file
            SecOffset = Next + 24;
            if ((*(unsigned char*)(Next + 19) & 1) != 0)
                SecOffset = Next + 32;  // Extended header

            while (1) {
                SecHeader = (int*)((SecOffset + 3) & 0xFFFFFFFC);
                SecSize = *SecHeader & 0xFFFFFF;
                if (SecSize == 0xFFFFFF) {
                    SecSize = *(SecHeader + 1);
                    if (SecSize <= 0xFFFFFF)
                        return -2147483634;
                } else if (SecSize < 4) {
                    return -2147483634;
                }

                SecOffset = (unsigned long long)((unsigned int)SecHeader) + SecSize;
                if (SecOffset > (unsigned long long)Next)
                    return -2147483634;

                SecType = *((unsigned char*)SecHeader + 3);

                // PE32 section (16) or TE section (18)
                if (SecType == 16 || SecType == 18) {
                    int SectionRawData = *SecHeader;
                    int* SectionAddr;

                    if (FileType == 3) {
                        // PEIM: record PE32 section pointer
                        if ((SectionRawData & 0xFFFFFF) == 0xFFFFFF)
                            SectionAddr = SecHeader + 2;
                        else
                            SectionAddr = SecHeader + 1;
                        *Pei32Ptr = SectionAddr;
                    } else {
                        // FV_PEIM: record TE section pointer
                        if ((SectionRawData & 0xFFFFFF) == 0xFFFFFF)
                            SectionAddr = SecHeader + 2;
                        else
                            SectionAddr = SecHeader + 1;
                        *TePtr = SectionAddr;
                    }

                    // Found both PE32 and TE entry points
                    if (*(unsigned long long*)Pei32Ptr &&
                        *(unsigned long long*)TePtr) {
                        return 0;  // EFI_SUCCESS
                    }
                    break;
                }
            }
        }
    }
    return -2147483634;  // EFI_NOT_FOUND
}

/**
 * PeiCoreEntryPoint - Find and relocate the PEI Core
 *
 * After FindPeiCore locates the PEI Core images in the FV,
 * this function relocates both the PE32 and TE images, then
 * returns the entry point address.
 *
 * @param FvBase     Firmware volume base address
 * @param EntryPoint Output: PEI Core entry point
 * @return EFI_STATUS from PeCoffGetEntryPoint
 */
int PeiCoreEntryPoint(
    unsigned int FvBase,
    unsigned int** EntryPoint)
{
    int Status;
    int PeiCoreStatus;
    int* Pei32Data[2];
    int* TeData[2];
    char* RelocatedPe32;
    char* RelocatedTe;
    struct {
        int* Pei32Ptr;
        int* TePtrLen;
        char* RelocatedPe32Ptr;
        char* Reserved[10];
    } Buffer;

    // Find PEI Core in FV
    Status = FindPeiCore(FvBase, Pei32Data, TeData);
    if (Status < 0) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        Assert("e:\\hs\\UefiCpuPkg\\SecCore\\FindPeiCore.c",
               0xAC, "!EFI_ERROR (Status)");
    }

    // Zero the buffer and relocate PE32 image
    ZeroMem((int)&Buffer, 0x70);
    Buffer.Pei32Ptr = Pei32Data[0];
    Buffer.TePtrLen = Pei32Data[1];
    RelocatedPe32 = PeCoffImageRelocate((char*)Pei32Data[0]);

    // Relocate TE image
    RelocatedTe = (char*)TeData[0];
    Buffer.Pei32Ptr = TeData[0];
    Buffer.TePtrLen = TeData[1];
    Buffer.RelocatedPe32Ptr = PeCoffImageRelocate((char*)TeData[0]);

    // Get entry point from PEI Core
    PeiCoreStatus = PeCoffGetEntryPoint(RelocatedTe, EntryPoint);
    if (PeiCoreStatus < 0)
        *EntryPoint = 0;

    return PeiCoreStatus;
}

/*=============================================================================
 * BIST (Built-In Self Test) Handling
 *============================================================================*/

/**
 * SecBist - Handle BIST (Built-In Self Test) results
 *
 * Reads BIST results from each processor via the PEI Services
 * LocatePpi mechanism. If BIST data is available, creates a
 * GUID HOB with the BIST data and installs a notification PPI.
 * Falls back to an alternate GUID if the primary isn't found.
 *
 * Built from: UefiCpuPkg/SecCore/SecBist.c
 */
int SecBist(void)
{
    int PeiServicesTablePointer;
    int Result;
    int PpiDescriptor;
    int BistInstance;
    unsigned int BistData[2];
    int BistPpiNotify;

    PeiServicesTablePointer = GetPeiServicesTablePointer();

    // Try to locate primary BIST PPI
    Result = PeiServiceLocatePpi(PeiServicesTablePointer,
                                 (int)&gEfiSecBistGuid,
                                 (int)&BistPpiNotify,
                                 &BistInstance,
                                 (unsigned long long*)BistData);
    if (!Result) {
        BuildGuidHob((int)&gEfiBistHobGuid, BistInstance, BistData[0]);
        int NotifyPpi = BistPpiNotify;
        int Services = GetPeiServicesTablePointer();
        Result = (*(int (**)(int, int, void*))(*(unsigned int*)Services + 28))(
                     Services, NotifyPpi, &gEfiPeiNotifyPpiDone);
    }

    // Fallback: alternate BIST GUID
    if (Result == -2147483634) {  // EFI_NOT_FOUND
        Result = PeiServiceLocatePpi(PeiServicesTablePointer,
                                     (int)&gEfiSecBistGuidAlt,
                                     (int)&BistPpiNotify,
                                     &BistInstance,
                                     (unsigned long long*)BistData);
        if (!Result) {
            BuildGuidHob((int)&gEfiBistHobGuid, BistInstance, BistData[0]);
            int NotifyPpi_2 = BistPpiNotify;
            int Services2 = GetPeiServicesTablePointer();
            Result = (*(int (**)(int, int, void*))(*(unsigned int*)Services2 + 28))(
                         Services2, NotifyPpi_2, &gEfiPeiNotifyPpiDoneAlt);
        }
    }

    if (Result < 0) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Result);
        return Assert("e:\\hs\\UefiCpuPkg\\SecCore\\SecBist.c",
                      0x10D, "!EFI_ERROR (Status)");
    }
    return Result;
}

/*=============================================================================
 * Temporary RAM (Cache-as-RAM) Support
 *============================================================================*/

/**
 * SecTemporaryRamStackInit - Initialize cache-as-RAM (CAR)
 *
 * Disables all cache, configures MTRRs to set up the temporary RAM
 * (cache-as-RAM) region. Uses MSR 0x2FF (MTRR_DEF_TYPE) and
 * MSR 0x2E0 (MTRR_PHYS_BASE_0 / MTRR_PHYS_MASK_0) to
 * configure the MTRRs for CAR operation.
 *
 * @return Previous MTRR_DEF_TYPE value
 */
unsigned long long SecTemporaryRamRamStackInit(void)
{
    unsigned long long MtrrDefType;
    unsigned long long MtrrPhysBase;

    __asm { invd }  // Invalidate cache

    // Save and disable MTRR_DEF_TYPE
    MtrrDefType = __readmsr(0x2FF);
    __writemsr(0x2FF, MtrrDefType & 0xFFFFFFFFFFFFF00LL);

    // Clear MTRR_PHYS_BASE_0 valid bit and set type
    MtrrPhysBase = __readmsr(0x2E0);
    __writemsr(0x2E0, MtrrPhysBase & 0xFFFFFFFFFFFFFFFDLL);
    __writemsr(0x2E0, MtrrPhysBase & 0xFFFFFFFFFFFFFFFCLL);

    // Restore MTRR_DEF_TYPE
    __writemsr(0x2FF, MtrrDefType);

    return MtrrDefType;
}

/**
 * SecTemporaryRamSupport - Dump CPU register state on exception
 *
 * This function is normally the temporary RAM support callback.
 * However, in this build it has been repurposed as the IA32
 * exception dump function - it prints all CPU register state
 * when an unrecoverable exception occurs in SEC/PEI.
 *
 * @param a1    Pointer to exception context / register dump
 * @return Length of dump output
 */
int SecTemporaryRamSupport(unsigned int* a1)
{
    const char* Reserved;
    unsigned int PeiCoreEntry;
    int v6;

    PeiCoreEntry = SecReadPeiCoreEntry();

    // Print exception type and APIC ID
    if (/* n14 >= 0x15 */ 0)
        Reserved = "Reserved";
    else
        Reserved = (const char*)(4 * /* n14 */ 0 - 3256);

    AsciiStrLen("!!!! IA32 Exception Type - %02x(%a)  CPU Apic ID - %08x !!!!\n",
                /* n14 */ 0, Reserved, PeiCoreEntry);

    // Exception data (for page faults etc)
    if (((1 << /* n14 */ 0) & 0x27D00) != 0) {
        AsciiStrLen("ExceptionData - %08x", *a1);
        if (/* n14 */ 0 == 14) {  // Page fault
            AsciiStrLen("  I:%x R:%x U:%x W:%x P:%x PK:%x S:%x",
                        (*a1 >> 4) & 1, (*a1 >> 3) & 1,
                        (*a1 >> 2) & 1, (*a1 >> 1) & 1,
                        *a1 & 1, (*a1 >> 5) & 1,
                        (*a1 >> 15) & 1);
        }
        AsciiStrLen("\n");
    }

    // Dump all CPU registers
    AsciiStrLen("EIP  - %08x, CS  - %08x, EFLAGS - %08x\n",
                a1[147], a1[152], a1[140]);
    AsciiStrLen("EAX  - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",
                a1[161], a1[160], a1[159], a1[158]);
    AsciiStrLen("ESP  - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
                a1[157], a1[156], a1[155], a1[154]);
    AsciiStrLen("DS   - %08x, ES  - %08x, FS  - %08x, GS  - %08x, SS - %08x\n",
                a1[151], a1[150], a1[149], a1[148], a1[153]);
    AsciiStrLen("CR0  - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
                a1[135], a1[137], a1[138], a1[139]);
    AsciiStrLen("DR0  - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
                a1[129], a1[130], a1[131], a1[132]);
    AsciiStrLen("DR6  - %08x, DR7 - %08x\n", a1[133], a1[134]);
    AsciiStrLen("GDTR - %08x %08x, IDTR - %08x %08x\n",
                a1[143], a1[144], a1[145], a1[146]);
    AsciiStrLen("LDTR - %08x, TR - %08x\n", a1[141], a1[142]);

    return AsciiStrLen("FXSAVE_STATE - %08x\n", a1 + 1);
}

/**
 * SecReadTemporaryRamStack - Read current temporary RAM stack value
 * Size: 0x4E bytes
 */
unsigned int SecReadTemporaryRamStack(void)
{
    // Read the current temporary RAM stack pointer
    unsigned int value;
    return value;
}

/**
 * SecGetTemporaryMemorySize - Get temporary memory size
 * Size: 0x2F bytes
 */
unsigned int SecGetTemporaryMemorySize(void)
{
    return 0;  // Platform-specific
}

/*=============================================================================
 * PEI Services
 *============================================================================*/

/**
 * PeiServiceLocatePpi - Locate a PPI in the PEI database
 *
 * Walks the PEI Services table to:
 *   1. Register a notification callback for the requested GUID
 *   2. Wait for the callback to fire
 *   3. Retrieve the PPI instance via PEI Services
 *
 * @param PeiServicesTablePointer  PEI Services table
 * @param Guid                     GUID of the PPI to locate
 * @param Notify                   Notification descriptor
 * @param Instance                 Output: PPI instance
 * @param Data                     Output: PPI data (optional)
 * @return EFI_STATUS
 */
int PeiServiceLocatePpi(
    int PeiServicesTablePointer,
    int Guid,
    int Notify,
    unsigned int* Instance,
    unsigned long long* Data)
{
    int Result;
    int (*NotifyCallback)(int, int*, int);

    // Register PPI notification
    int PeiServices = GetPeiServicesTablePointer();
    Result = (*(int (**)(int, int, unsigned int, int,
                         int (***)(int, int*, int)))
              (*(unsigned int*)PeiServices + 32))(
                  PeiServices, Guid, 0, Notify, &NotifyCallback);
    if (Result == -2147483634)  // EFI_NOT_FOUND
        return -2147483634;
    if (Result)
        return -2147483641;  // EFI_INVALID_PARAMETER

    // Wait for callback
    int Descriptor = 0;
    unsigned long long DescriptorExt = 0;
    int PpiAddress = 0;

    if ((*NotifyCallback)(PeiServicesTablePointer, &Descriptor, 0) != -2147483643)
        return -2147483641;

    int PpiDescriptor = Descriptor;
    int Services = GetPeiServicesTablePointer();
    if ((*(int (**)(int, int, int*))(*(unsigned int*)Services + 76))(
             Services, PpiDescriptor, &PpiAddress) ||
        (*NotifyCallback)(PeiServicesTablePointer, &Descriptor, PpiAddress)) {
        return -2147483641;
    }

    *Instance = PpiAddress;
    if (Data) {
        *Data = Descriptor;
        *(Data + 1) = DescriptorExt;
    }
    return 0;
}

/*=============================================================================
 * PEI Services Table Pointer
 *============================================================================*/

/**
 * GetPeiServicesTablePointer - Get PEI Services Table from IDT
 *
 * Reads the IDTR, then extracts the PEI Services Table pointer
 * from the last entries of the IDT. Each PEI phase module saves
 * its service table pointer in a reserved IDT entry.
 */
int* GetPeiServicesTablePointer(void)
{
    int* PeiServices;
    unsigned short IdtrBuffer[2];  // Limit + Base

    SidtWrapper(IdtrBuffer);

    PeiServices = (int*)(IdtrBuffer[1] + 4 * 8 + 24);
    if (PeiServices) {
        return (int*)*PeiServices;
    }
    return 0;
}

/*=============================================================================
 * CPU Initialization
 *============================================================================*/

/**
 * SecInitializeBootMode - Read boot mode from CMOS
 *
 * Reads CMOS registers 0x5C and 0x6C to determine the boot mode
 * (cold boot, warm boot, S3, etc.). Also initializes the serial
 * port baud rate based on the CMOS configuration byte.
 *
 * CMOS 0x6C encodes the serial baud rate:
 *   0xA7 = 115200  0xA6 = 57600  0xA5 = 38400
 *   0xA4 = 19200   0xA3 = 9600
 *
 * Built from: UefiCpuPkg/SecCore/SecMain.c
 */
int SecInitializeBootMode(void)
{
    int Result;
    unsigned char CmosByte;
    unsigned int BaudRate;
    unsigned int Divisor;
    short SerialPort;

    Result = SecReadSecCoreData();
    if (Result < 0)
        return Result;

    // Read CMOS byte at index 0x6C
    __outbyte(0x72, 0x5C);      // CMOS index
    __inbyte(0x73);              // Dummy read
    __outbyte(0x72, 0x6C);      // CMOS boot mode byte
    CmosByte = __inbyte(0x73);  // Read boot mode value

    // Decode baud rate
    switch (CmosByte) {
        case 0xA7: BaudRate = 115200; break;
        case 0xA6: BaudRate = 57600;  break;
        case 0xA5: BaudRate = 38400;  break;
        case 0xA4: BaudRate = 19200;  break;
        case 0xA3: BaudRate = 9600;   break;
        default:   BaudRate = 115200; break;
    }
    Divisor = 0x1C200 / BaudRate;  // 115200 / BaudRate

    // Initialize serial port if one is detected
    SerialPort = (short)CheckAsciiStrLen();
    if (SerialPort) {
        short PortBase = SerialPort + 3;
        unsigned char LineCtl = __inbyte(SerialPort + 3);
        unsigned char LatchByte;

        __outbyte(SerialPort + 3, __inbyte(SerialPort + 3) | 0x80);

        unsigned short DivisorLatch = (__inbyte(SerialPort + 1) << 8) | __inbyte(SerialPort);
        unsigned char NewLineCtl = __inbyte(SerialPort + 3);
        __outbyte(SerialPort + 3, NewLineCtl & 0x7F);

        // Only set if divisor value changed or line control not 3
        if (((LineCtl & 0x3F) == 3) & (unsigned char)((DivisorLatch != Divisor) - 1))
            return 0;

        // Wait for transmitter ready
        do {
            LatchByte = __inbyte(SerialPort + 5);
        } while ((LatchByte & 0x60) != 0x60);

        // Set divisor latch and baud rate
        __outbyte(PortBase, 0x80);
        __outbyte(SerialPort + 1, Divisor >> 8);
        __outbyte(SerialPort, Divisor);
        __outbyte(PortBase, 3);               // 8N1
        __outbyte(SerialPort + 2, 0);          // FIFO off
        __outbyte(SerialPort + 2, 1);          // FIFO on
        __outbyte(SerialPort + 4, 0);          // DTR/RTS off
    }

    return 0;
}

/**
 * SecInitializeFpu - Initialize the FPU
 *
 * Writes the FPU control word to set default precision and rounding.
 * Uses FINIT instruction then sets CW to standard mask value.
 */
void SecInitializeFpu(void)
{
    // Default FPU control word initialization
    __asm { fninit }
}

/**
 * SecReadSecCoreData - Read platform configuration data
 *
 * Detects the platform type (PCH vs IOH legacy) by reading
 * CMOS register 0x5C. Configures platform-specific MTRRs
 * and GDT/IDT exception handlers.
 */
int SecReadSecCoreData(int SecCoreData)
{
    unsigned char CfgByte;
    char* ConfigTable;
    int NumEntries;
    void* Entries;

    __outbyte(0x72, 0x5C);
    CfgByte = __inbyte(0x73);

    if (CfgByte == 33) {
        // Platform with IOH (3 config entries)
        ConfigTable = (char*)&gPlatformConfigIOH;
        NumEntries = 3;
        do {
            PciCfgReadWrite(SecCoreData,
                           *((short*)ConfigTable - 1),
                           *ConfigTable,
                           *(unsigned int*)(ConfigTable + 2));
            ConfigTable += 8;
            --NumEntries;
        } while (NumEntries);
        Entries = &gMtrrConfigIOH;
    } else {
        // Platform with PCH (2 config entries)
        ConfigTable = (char*)&gPlatformConfigPCH;
        NumEntries = 2;
        do {
            PciCfgReadWrite(SecCoreData,
                           *((short*)ConfigTable - 1),
                           *ConfigTable,
                           *(unsigned int*)(ConfigTable + 2));
            ConfigTable += 8;
            --NumEntries;
        } while (NumEntries);
        Entries = &gMtrrConfigPCH;
    }

    SecMtrrSetup(SecCoreData, (int)Entries);

    // Setup GDT and exception handlers for 6 entries (18 bytes / 3)
    unsigned int i;
    for (i = 0; i < 18; i += 3) {
        int MtrrType = (unsigned char)gMtrrTypeTable[i * 4] | 0x1E6E2000;
        int GdtValue;
        SecSetupGdt(MtrrType, &GdtValue);
        GdtValue = gMtrrValueTable[i] | GdtValue & gMtrrMaskTable[i];
        SecSetupExceptionHandlers(MtrrType, GdtValue);
    }

    return 0;
}

/**
 * SecSetupGdt - Write GDT entry via Chipset (IOH) register
 *
 * Programs one GDT descriptor via the chipset's configuration
 * mechanism. Uses I/O ports 0x2E/0x2F (LPC/SIO) to access
 * the chipset configuration space, then writes the 8-byte
 * GDT entry components (limit low 16:19, base 24:31).
 *
 * The GDT entry format:
 *   Bytes 0-1: Limit Low (bits 15:0)
 *   Bytes 2-3: Base Low (bits 23:16)
 *   Byte 4: Base Mid (bits 31:24)
 *   Byte 5: Attributes
 *   Byte 6: Limit High + Flags
 *   Byte 7: Base High
 */
char SecSetupGdt(int MtrrIndex, int* GdtValue)
{
    unsigned char v2, v3, v4, v5, v6, v7, v8, v9, v10;

    // Enter configuration mode
    __outbyte(0x2E, 0xA5);
    __outbyte(0x2E, 0xA5);
    __outbyte(0x2E, 7);
    __outbyte(0x2F, 0x0D);

    __outbyte(0x2E, 0x30);
    v2 = __inbyte(0x2F);
    __outbyte(0x2F, v2 | 1);

    // Write GDT entry base (4 bytes)
    __outbyte(0x2E, 0xF0);
    __outbyte(0x2F, (unsigned char)(MtrrIndex >> 24));
    __outbyte(0x2E, 0xF1);
    __outbyte(0x2F, (unsigned char)(MtrrIndex >> 16));
    __outbyte(0x2E, 0xF2);
    __outbyte(0x2F, (unsigned char)(MtrrIndex >> 8));
    __outbyte(0x2E, 0xF3);
    __outbyte(0x2F, (unsigned char)MtrrIndex);

    // Read current limit+flags, set to 2 (32-bit)
    __outbyte(0x2E, 0xF8);
    v3 = __inbyte(0x2F);
    __outbyte(0x2F, (v3 & 0xFC) | 2);

    // Flush configuration
    __outbyte(0x2E, 0xFE);
    __inbyte(0x2F);

    // Read back the 4-byte GDT value
    __outbyte(0x2E, 0xF4);
    v4 = __inbyte(0x2F);
    v5 = v4;
    __outbyte(0x2E, 0xF5);
    v6 = __inbyte(0x2F);
    v7 = v6;
    __outbyte(0x2E, 0xF6);
    v8 = __inbyte(0x2F);
    v9 = v8;
    __outbyte(0x2E, 0xF7);
    v10 = __inbyte(0x2F);
    *GdtValue = v10 | ((v9 | ((v7 | (v5 << 8)) << 8)) << 8);

    __outbyte(0x2E, 0xAA);  // Exit configuration mode
    return 0xAA;
}

/**
 * SecSetupExceptionHandlers - Set IDT entry handler
 *
 * Programs the 8-byte IDT descriptor via chipset I/O.
 * Each IDT entry has:
 *   Bytes 0-1: Offset Low (handler address bits 15:0)
 *   Bytes 2-3: Segment Selector (CS)
 *   Byte 4: Reserved (bits 31:24 of handler for IA32e)
 *   Byte 5: Gate Type (0x8E = 32-bit interrupt gate)
 *   Bytes 6-7: Offset High (handler address bits 31:16)
 */
char SecSetupExceptionHandlers(int MtrrIndex, int IdtEntryValue)
{
    unsigned char v2, v3;

    // Enter configuration mode
    __outbyte(0x2E, 0xA5);
    __outbyte(0x2E, 0xA5);
    __outbyte(0x2E, 7);
    __outbyte(0x2F, 0x0D);

    __outbyte(0x2E, 0x30);
    v2 = __inbyte(0x2F);
    __outbyte(0x2F, v2 | 1);

    // Write handler address (4 bytes at 0xF0-0xF3)
    __outbyte(0x2E, 0xF0);
    __outbyte(0x2F, (unsigned char)(MtrrIndex >> 24));
    __outbyte(0x2E, 0xF1);
    __outbyte(0x2F, (unsigned char)(MtrrIndex >> 16));
    __outbyte(0x2E, 0xF2);
    __outbyte(0x2F, (unsigned char)(MtrrIndex >> 8));
    __outbyte(0x2E, 0xF3);
    __outbyte(0x2F, (unsigned char)MtrrIndex);

    // Write gate type & segment (4 bytes at 0xF4-0xF7)
    __outbyte(0x2E, 0xF4);
    __outbyte(0x2F, (unsigned char)(IdtEntryValue >> 24));
    __outbyte(0x2E, 0xF5);
    __outbyte(0x2F, (unsigned char)(IdtEntryValue >> 16));
    __outbyte(0x2E, 0xF6);
    __outbyte(0x2F, (unsigned char)(IdtEntryValue >> 8));
    __outbyte(0x2E, 0xF7);
    __outbyte(0x2F, (unsigned char)IdtEntryValue);

    // Set gate type = interrupt gate (bit 1 of byte 5)
    __outbyte(0x2E, 0xF8);
    v3 = __inbyte(0x2F);
    __outbyte(0x2F, (v3 & 0xFC) | 2);

    // Set segment selector = 0x08 (CS) at register FE
    __outbyte(0x2E, 0xFE);
    __outbyte(0x2F, 0xCF);
    __outbyte(0x2E, 0xAA);  // Exit configuration mode
    return 0xAA;
}

/**
 * SecMtrrSetup - Write MTRR configuration table
 *
 * Programs multiple chipset registers from a configuration table.
 * Each entry is a 4-byte structure: [port(2), mask(1), value(1)].
 * If mask is non-zero, performs read-modify-write; otherwise
 * just writes the value directly.
 */
unsigned char SecMtrrSetup(int unused, int ConfigTable)
{
    unsigned char* Entry = (unsigned char*)(ConfigTable + 3);
    int Count = 11;

    do {
        unsigned char Value;
        if (*(Entry - 1)) {
            // Read-modify-write
            unsigned char Current = __inbyte(*(short*)(Entry - 3));
            Value = *Entry | Current & *(Entry - 1);
        } else {
            // Direct write
            Value = *Entry;
        }
        __outbyte(*(short*)(Entry - 3), Value);
        Entry += 4;
        --Count;
    } while (Count);

    return *Entry;
}

/*=============================================================================
 * Exception Handling
 *============================================================================*/

/**
 * SecExceptionDispatcher - Platform exception handler
 *
 * Handles platform-specific exception recovery. Programs the
 * IOH/PCH to report MCE (Machine Check Exception) information.
 * Accesses PCI configuration space and MMIO registers to:
 *   1. Set up error reporting
 *   2. Configure IOH error handling
 *   3. Log MCE details via chipset registers
 */
int SecExceptionDispatcher(void)
{
    // IOH error configuration
    MEMORY[0x80000048] = -19857407;
    MEMORY[0x800F9010] = -50331648;
    MEMORY[0x800F9004] |= 2;

    // IOH PCI configuration for error logging
    __outdword(0xCF8, 0x8000FD10);
    __outdword(0xCFC, 0xFE010000);
    __outdword(0xCF8, 0x8000FD04);
    __outdword(0xCFC, 2);
    MEMORY[0x800FA040] = 1281;
    MEMORY[0xFDEF27B4] = 16516353;
    MEMORY[0xFDEF27B8] = 9128;
    __outdword(0xCF8, 0x8000FA48);
    __outdword(0xCFC, 0xFE000000);
    MEMORY[0xFDEF27AC] = -33489408;
    MEMORY[0xFDEF27B0] = -2147474520;
    MEMORY[0x800FA044] |= 0x180;
    MEMORY[0x800FC050] = 1025;
    MEMORY[0x800FC055] |= 1;
    MEMORY[0xFDEF2778] = 1027;
    MEMORY[0x800F9060] = 0x80;
    MEMORY[0xFED00108] = 0;
    MEMORY[0xFED0010C] = 0;
    MEMORY[0xFDC33400] |= 4;
    MEMORY[0xFDAF0480] |= 0x400;

    return MEMORY[0xFDAF0480];
}

/**
 * SecDefaultExceptionHandler - Default IA32 exception handler
 *
 * Reads MSR 0x300 (IA32_MCG_CAP) to determine the MCE bank count
 * and encodes the return value as exception information.
 * Dispatches to ExceptionHandler0 if MCG is valid.
 */
unsigned int SecDefaultExceptionHandler(unsigned int ExceptionInfo)
{
    unsigned long long McgCap = __readmsr(0x300);
    unsigned int BankInfo;

    if (McgCap >= 0) {
        ExceptionHandler0();
        if (/* v2 */ 0)
            BankInfo = 0x50403020100LL;
        else
            BankInfo = 0x151413121100LL;
    }

    BankInfo = McgCap;
    unsigned int n4 = (unsigned char)(ExceptionInfo >> 20);
    if (n4 >= 4) {
        n4 = n4 - 4;
        BankInfo = McgCap >> 32;
    }

    return ((unsigned char)(BankInfo >> (8 * n4)) << 20) | ExceptionInfo & 0xFFFFF;
}

/**
 * NullExceptionHandler - NOP exception handler (IRET)
 * Size: 2 bytes
 */
void NullExceptionHandler(void)
{
    // IRET - return from exception
}

/**
 * NullFunction - NOP function
 * Size: 1 byte
 */
void NullFunction(void)
{
    // RET
}

/**
 * Exception handlers (individual stubs)
 * These are short stubs that push exception info and jump to
 * the common dispatch handler.
 */
void ExceptionHandler0(void)  { /* jmp esi - transition */ }
void ExceptionHandler1(void)  { /* DE exception */ }
void ExceptionHandler3(void)  { /* BP exception */ }
void ExceptionHandler4(void)  { /* OF exception */ }
void ExceptionHandler5(void)  { /* BR exception */ }
void ExceptionHandler6(void)  { /* UD exception */ }

/*=============================================================================
 * PE/COFF Image Relocation
 *============================================================================*/

/**
 * PeCoffImageRelocate - Relocate a PE/COFF image
 *
 * Walks the PE/COFF relocation table for the image and applies
 * fixes. Returns a pointer to the entry point within the image.
 * Handles PE32+ images (magic 0x20B) both PE32 (0x10B) and
 * PE32+ (0x20B) as well as TE images (0x10A).
 *
 * Supports magic value IMAGE_REL_BASED_HIGH/LOW/HIGHLOW.
 */
char* PeCoffImageRelocate(char* ImageBase)
{
    // ... PE header parsing and relocation fixups
    // Returns entry point address within the relocated image
    return EntryPoint;
}

/**
 * PeCoffGetEntryPoint - Get entry point from PE/COFF image
 *
 * Walks the image headers to find the entry point, supporting
 * both PE32 and TE image formats.
 */
int PeCoffGetEntryPoint(char* ImageBase, void** EntryPoint)
{
    // ... header parsing
    return Status;
}

/**
 * PeCoffSearchImageBase - Search for a PE/COFF image header
 *
 * Given an address, searches backward for a valid PE/COFF
 * signature (MZ or PE). Used to locate image headers from
 * arbitrary addresses within a loaded image.
 */
short* PeCoffSearchImageBase(unsigned int Address)
{
    short* WordPtr = (short*)(Address & 0xFFFFFFFC);

    if ((Address & 0xFFFFFFFC) != 0) {
        do {
            if (*WordPtr == 0x5A4D) {  // "MZ"
                unsigned int* PeSig = (unsigned int*)((char*)WordPtr +
                    (unsigned short)WordPtr[30]);
                if ((unsigned int)PeSig > (unsigned int)WordPtr &&
                    (unsigned int)PeSig < Address) {
                    if (*PeSig == 0x00004550)  // "PE\0\0"
                        return WordPtr;
                }
            } else if (*WordPtr == 0x4550) {  // "PE" directly
                short Machine = WordPtr[1];
                if (Machine == 0x14C ||   // IA32
                    Machine == 0x200 ||   // IA64
                    Machine == 0xEC4 ||   // ARM7 ?
                    Machine == 0x8664 ||  // X64
                    Machine == 0xAA64)    // AARCH64
                    return WordPtr;
                if (Machine == 0x1C2)     // ARM
                    return WordPtr;
            }
            WordPtr -= 2;
        } while (WordPtr);
    }
    return WordPtr;
}

/*=============================================================================
 * Debug Output / Serial Port
 *============================================================================*/

/**
 * DebugPrint - Output debug message to serial port
 *
 * Checks the debug level against the current CMOS debug level
 * setting. If the message should be printed, formats it via
 * AsciiSPrintWorker and outputs via SerialPortWrite.
 *
 * The debug level is read from CMOS address 0x4A (RTC register).
 * Level 0xFF disables all debug, levels 1-3 enable based on
 * error level mask.
 */
unsigned char DebugPrint(int ErrorLevel, const char* Format, ...)
{
    unsigned char DebugLevel;
    unsigned char n3;
    int Result;

    Result = 0;

    if (!Format)
        Assert("e:\\hs\\MdePkg\\Library\\BaseDebugLibSerialPort\\DebugLib.c",
               0x4F, "Format != ((void *) 0)");

    // Read debug level from CMOS
    __outbyte(0x70, (__inbyte(0x70) & 0x80) | 0x4A);
    DebugLevel = __inbyte(0x71);

    if (DebugLevel <= 3) {
        if (!DebugLevel)
            DebugLevel = 0xFF;  // Disabled
        if (!DebugLevel)
            goto skip;
        DebugLevel = (unsigned char)(MEMORY[0xFDAF0490] & 2) | 1;
    }

    if (DebugLevel == 0xFF) {
        Result = 0;  // All debug disabled
    } else if (DebugLevel == 1) {
        Result = -2147483644;  // DP_ERROR
    } else {
        Result = -2147483578;  // DP_INFO
    }

    if (Result & ErrorLevel) {
        // Format and push to serial
        va_list va;
        va_start(va, Format);

        AsciiSPrintWorker(gDebugPrintBuffer, 0x100, 0, Format, (int)va);
        unsigned int Len = AsciiStrLenWorker(gDebugPrintBuffer);
        SerialPortWrite(gDebugPrintBuffer, Len);
    }

    return DebugLevel;
}

/**
 * Assert - Output assertion failure message
 *
 * Formats: "ASSERT [SecCore] file(line): message\n"
 * Outputs via UnicodeVSPrint, then sends to serial.
 */
int Assert(int Filename, unsigned int Line, unsigned int Message)
{
    unsigned char Buffer[256];

    UnicodeVSPrint((int)Buffer, 0x100,
                   "ASSERT [%a] %a(%d): %a\n",
                   "SecCore", Filename, Line, Message);

    unsigned int Len = AsciiStrLenWorker(Buffer);
    return SerialPortWrite(Buffer, Len);
}

/**
 * SerialPortWrite - Write data to serial port
 *
 * Writes buffer to the UART at the detected base port.
 * Uses the 16550 UART interface:
 *   - Checks line status (bit 6 = transmitter ready)
 *   - Writes at most 16 bytes per poll cycle
 *   - Waits for transmitter empty between chunks
 *
 * @param Buffer  Data to write
 * @param Count   Number of bytes to write
 * @return Number of bytes written, or 0 on error
 */
int SerialPortWrite(const unsigned char* Buffer, int Count)
{
    short SerialPort;
    int PollCount;

    SerialPort = (short)CheckAsciiStrLen();
    if (!SerialPort || !Buffer)
        return 0;

    if (!Count) {
        // Poll for transmitter ready (bit 6)
        PollCount = 0;
        do {
            if ((__inbyte(SerialPort + 5) & 0x60) == 0x60)
                break;
            ++PollCount;
        } while (PollCount != 0xFFFF);
        return 0;
    }

    int TotalWritten = Count;
    short Port5 = SerialPort + 5;

    while (Count) {
        // Wait for THR empty (bit 5)
        int Timeout = 0;
        while (1) {
            if ((__inbyte(Port5) & 0x40) != 0)
                break;
            if (++Timeout == 0xFFFF)
                return 0;
        }

        // Write up to 16 bytes
        int BatchSize = 0;
        while (Count) {
            __outbyte(SerialPort, *Buffer);
            ++Buffer;
            --Count;
            ++BatchSize;
            if (BatchSize >= 0x10) {
                if (Count) goto restart;
                return TotalWritten;
            }
        }
        break;
        restart: ;
    }
    return TotalWritten;
}

/*=============================================================================
 * x86 CPU Register Access
 *============================================================================*/

unsigned int SecReadCr0(void)    { /* MOV EAX, CR0 */ }
unsigned int SecReadCr2(void)    { /* MOV EAX, CR2 */ }
unsigned int SecReadCr3(int mode, unsigned int* out, int unused) { /* MOV EAX, CR3 */ }
unsigned int SecReadCr4(void)    { /* MOV EAX, CR4 */ }
void SecWriteCr0(unsigned int value)  { /* MOV CR0, value */ }
void SecWriteCr4(unsigned int value)  { /* MOV CR4, value */ }
void SecEnableSse(void)          { /* Set CR4.OSFXSR + CR4.OSXMMEXCPT */ }
unsigned int SecReadEflags(void) { /* PUSHFD */ }
int SecSwitchStack(void)         { /* Stack switch stub */ }
int SecReadIdtBase(void)         { /* SIDT + check mapping */ }
unsigned int SecReadPeiCoreEntry(void) { /* Read PEI Core entry from CAR */ }
unsigned int SecGetStackInfo(void) { /* Read stack info */ }
int SecInitIdtEntry(void* handlers) { /* Init IDT gate entries */ }

/*=============================================================================
 * MSR (Model-Specific Register) Access
 *============================================================================*/

void WriteMsr(unsigned int Msr, unsigned int Value)
{
    __writemsr(Msr, Value);
}

unsigned long long ReadMsr(unsigned int Msr)
{
    return __readmsr(Msr);
}

/*=============================================================================
 * IDT/LDT Wrappers
 *============================================================================*/

void LidtWrapper(unsigned short* Limit)
{
    __asm { lidt [Limit] }
}

void SidtWrapper(unsigned short* LimitAndBase)
{
    __asm { sidt [LimitAndBase] }
}

/*=============================================================================
 * I/O Port Access
 *============================================================================*/

unsigned int IoRead32(unsigned short Port)
{
    return __indword(Port);
}

void IoWrite32(unsigned short Port, unsigned int Value)
{
    __outdword(Port, Value);
}

int IoRead16(unsigned short Port)       { return __inword(Port); }
int IoReadWrite8(int unused, unsigned short Port) { return __inbyte(Port); }

/*=============================================================================
 * PCI Configuration Access (via CF8/CFC)
 *============================================================================*/

/**
 * PciCfgReadWrite - Configure PCI bus via configuration mechanism 1
 *
 * Access type 1 = I/O port config, 6 = PCI memory-mapped,
 * 7 = PCI I/O config, 8 = memory range config, 255 = platform-specific.
 *
 * Uses the IOH bridge registers at I/O ports 0xF8080/0xF8082
 * (PCI config mechanism) to program the PCIe root ports and
 * IIO (Integrated I/O) modules.
 */
int PciCfgReadWrite(int unused, short BusDevFunc, char Command, int AccessType)
{
    short ResultBus;
    short ResultDev;
    short ConfigSize;
    short ConfigValue;
    int RegAddr;
    short RegData[5];
    short IoPortData[2];

    // ... complex PCI config routing logic for
    // different IIO stacks (0-3) and PCI segments.
    // Sets values via IoRead32/IoWrite32 to 0xF8080/0xF8082.

    // Finalize: write config to IOH registers + MSRs
    // Read existing config from 0xF8080, modify, write back
    // Also mirror to MSRs 0xFDEF2770/0xFDEF2774

    return 0;
}

/*=============================================================================
 * Memory Operations
 *============================================================================*/

/**
 * InternalCopyMem - Copy memory, handling overlap
 *
 * If source overlaps destination, does a backward copy.
 * Otherwise uses qmemcpy (32-bit aligned copy).
 */
char* InternalCopyMem(char* Dst, const char* Src, unsigned int Count)
{
    if (Src < Dst && &Src[Count - 1] >= Dst) {
        // Overlapping: copy backward
        const char* SrcEnd = &Src[Count - 1];
        char* DstEnd = &Dst[Count - 1];
        qmemcpy(DstEnd, SrcEnd, Count & 3);
        qmemcpy(DstEnd - (Count & 3), SrcEnd - (Count & 3), 4 * (Count >> 2));
    } else {
        // Non-overlapping: forward copy in 32-bit words
        qmemcpy(Dst, Src, 4 * (Count >> 2));
        qmemcpy(&Dst[4 * (Count >> 2)], &Src[4 * (Count >> 2)], Count & 3);
    }
    return Dst;
}

/**
 * InternalZeroMem - Zero memory
 */
void* InternalZeroMem(void* Buf, unsigned int Count)
{
    memset(Buf, 0, Count);
    return Buf;
}

/**
 * CopyMem - Safe memory copy with bounds checking
 */
char* CopyMem(char* Dst, const char* Src, unsigned int Count)
{
    unsigned int DstEnd = 0xFFFFFFFF - (unsigned int)Dst;
    unsigned int SrcEnd = 0xFFFFFFFF - (unsigned int)Src;

    if (Count - 1 > DstEnd)
        Assert("e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
               0x38, "(Length - 1) <= (0xFFFFFFFF - (UINTN)DestinationBuffer)");
    if (Count - 1 > SrcEnd)
        Assert("e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
               0x39, "(Length - 1) <= (0xFFFFFFFF - (UINTN)SourceBuffer)");

    if (Dst == Src)
        return Dst;
    return InternalCopyMem(Dst, Src, Count);
}

/**
 * ZeroMem - Safe zero memory with bounds checking
 */
void* ZeroMem(int Buf, unsigned int Count)
{
    if (!Buf)
        Assert("e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
               0x35, "Buffer != ((void *) 0)");
    if (Count > (unsigned int)(0xFFFFFFFF - Buf + 1))
        Assert("e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
               0x36, "Length <= (0xFFFFFFFF - (UINTN)Buffer + 1)");

    return InternalZeroMem((void*)Buf, Count);
}

/*=============================================================================
 * HOB (Hand-Off Block) Services
 *============================================================================*/

/**
 * GetHobList - Get the HOB list pointer from PEI Services
 */
int* GetHobList(void)
{
    int PeiServices = GetPeiServicesTablePointer();
    int HobList;

    int Status = (*(int (**)(int, int*))(*(unsigned int*)PeiServices + 48))(
                     PeiServices, &HobList);
    if (Status < 0) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        Assert("e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
               0x32, "!EFI_ERROR (Status)");
    }

    if (!HobList)
        Assert("e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
               0x33, "HobList != ((void *) 0)");

    return (int*)HobList;
}

/**
 * GetNextHob - Get next HOB by type
 */
void* GetNextHob(unsigned short Type, void* HobStart)
{
    // Walk HOB chain looking for matching type
    return NextHob;
}

/**
 * GetFirstHob - Get first HOB of a given type
 */
void* GetFirstHob(unsigned short Type)
{
    return GetNextHob(Type, GetHobList());
}

/**
 * GetHobByType - Get HOB by type
 */
void* GetHobByType(unsigned short Type)
{
    return (void*)GetNextHob(Type, GetHobList());
}

/**
 * CreateHobGuid - Create a GUID HOB
 */
void* CreateHobGuid(unsigned int Guid, unsigned int DataLen)
{
    // Allocate HOB with GUID header + data
    return Hob;
}

/**
 * BuildGuidHob - Build a GUID HOB with data
 */
void* BuildGuidHob(unsigned int Guid, unsigned int DataLen, unsigned int Data)
{
    void* Hob = CreateHobGuid(Guid, DataLen);
    if (Hob)
        CopyMem((char*)Hob + sizeof(EFI_HOB_GUID_TYPE), &Data, DataLen);
    return Hob;
}

/*=============================================================================
 * String/Print Functions
 *============================================================================*/

/**
 * AsciiSPrintWorker - Format string with arguments
 *
 * The largest function in this module (0xC1E bytes).
 * Implements the core format string engine for ASCII output.
 * Supports: %s, %x, %d, %r (EFI status), %a, %p, %08x, etc.
 * Calls AsciiValueToString and UnicodeValueToString
 * for number-to-string conversion.
 *
 * Compiled from BasePrintLib.
 */
unsigned int AsciiSPrintWorker(
    unsigned char* Buffer,
    unsigned int BufferSize,
    unsigned short Flags,
    const unsigned char* Format,
    int VaArgs)
{
    // ... full format string processing
    // Handles width, precision, padding, type conversion
    return StringLength;
}

// Remaining functions follow standard UEFI library implementations:
// InternalSetMem, InternalSetMem32, AsciiStrLen, AsciiStrnLen,
// AsciiStrLenWorker, AsciiValueToString, UnicodeValueToString,
// AsciiToUpper, String length helpers, Guid read/write, etc.
// See Volume_Top_File.md for complete function list.