Newer
Older
AMI-Aptio-BIOS-Reversed / FlashDriver / FlashDriver.c
@Ajax Dong Ajax Dong 2 days ago 26 KB Init
/**
 * FlashDriver.c - AMI Flash Driver
 *
 * Module: FlashDriver.efi (0256)
 * Source: AmiModulePkg/FlashDriver/
 *
 * This is a UEFI DXE Runtime Driver that manages SPI flash programming
 * for BIOS flash chips. It detects flash devices, maps them to MMIO,
 * and provides a protocol interface for read/write/erase operations.
 *
 * Build environment: VS2015 DEBUG, X64
 * Source tree: e:\hs\
 */

#include "FlashDriver.h"

// ============================================================================
// Global Variables
// ============================================================================

EFI_HANDLE  ImageHandle;        // gImageHandle   0x7218
UINT64      SystemTable;        // gST            0x7208
UINT64      BootServices;       // gBS            0x7210
UINT64      RuntimeServices;    // gRT            0x7220
UINT64      RuntimeServices_0;  //                0x7228
UINT64      BootServices_0;     //                0x7240
UINT64      gDS;                // DxeServices    0x7250
UINT64      gPciUsra;           // MmPciBase      0x7258
UINT64      RuntimeServices_1;  //                0x73B8
UINT64      gPciExpressBaseAddress; //            0x7280

//
// PCIe Segment/Bus cache
//
UINTN       mPciExpressRegistration; //          0x7288
UINT64      mPcieSegBusTable;      // qword_7270  0x7270
UINT64      mPcieSegBusTableCount; // qword_7278  0x7278
BOOLEAN     mEfiGoneVirtual;        // byte_7268  0x7268

//
// Flash protocol & state
//
UINT64      FlashProtocolHandle;    // qword_72F8 0x72F8
UINT64      FlashProtocolNotify;    // qword_72F0 0x72F0
UINT64      FlashProtocolDb;        // qword_72E8 0x72E8
UINT64      FlashProtocolInterface; // qword_7290 0x7290

UINT64      FlashRegionTable;       // qword_7318 0x7318
UINT64      FlashRegionTableEnd;    // qword_7308 0x7308
UINT32      FlashRegionEntrySize;   // dword_7310 0x7310
UINT32      FlashRegionTableSize;   // dword_7300 0x7300

UINT64      FlashSpinelBase;        // qword_7338 0x7338
UINT8       FlashSpinelState;       // byte_7332  0x7332
UINT8       FlashSpinelIndex;       // byte_7331  0x7331

//
// Event notification handles
//
UINT64      VirtualAddressChangeEvent; // qword_7230 0x7230
UINT64      VirtualAddressChangeRelEvent; // qword_7238 0x7238
UINT64      RuntimeNotifyEventHandle;   // qword_73B0 0x73B0
UINT64      RuntimeNotifyEventHandle2;  // qword_73C0 0x73C0

//------------------------------------------------------------------------------
// Function Implementations
//------------------------------------------------------------------------------

/**
 * ModuleEntryPoint - Standard UEFI DXE entry point.
 */
EFI_STATUS
EFIAPI
ModuleEntryPoint (
    IN EFI_HANDLE        ImageHandle,
    IN EFI_SYSTEM_TABLE  *SystemTable
    )
{
    EFI_STATUS  Status;

    FlashDriverInit(ImageHandle, SystemTable);
    Status = FlashDriverEntry();
    if (EFI_ERROR(Status)) {
        FlashDriverUnload();
    }
    return Status;
}

/**
 * FlashDriverInit - Core initialization.
 *
 * Initializes all UEFI tables (gImageHandle, gST, gBS, gRT),
 * registers runtime virtual address change events,
 * locates the MM PCI Base protocol,
 * installs the Flash Protocol,
 * registers runtime notification.
 */
EFI_STATUS
EFIAPI
FlashDriverInit (
    IN EFI_HANDLE        ImageHandle,
    IN EFI_SYSTEM_TABLE  *SystemTable
    )
{
    gImageHandle = ImageHandle;
    if (ImageHandle == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
            51,
            "gImageHandle != ((void *) 0)");
    }

    gST = (UINT64)SystemTable;
    if (SystemTable == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
            57,
            "gST != ((void *) 0)");
    }

    gBS = (UINT64)SystemTable->BootServices;
    if (gBS == 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
            63,
            "gBS != ((void *) 0)");
    }

    RuntimeServices = (UINT64)SystemTable->RuntimeServices;
    if (RuntimeServices == 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c",
            47,
            "gRT != ((void *) 0)");
    }

    BootServices_0 = (UINT64)SystemTable->BootServices;
    RuntimeServices_0 = (UINT64)SystemTable->RuntimeServices;

    //
    // Register virtual address change notify events
    //
    gBS->CreateEvent(
        EVT_NOTIFY_VIRTUAL_ADDRESS_CHANGE,
        TPL_NOTIFY,
        NotifyVirtualAddressChangeNull,
        NULL,
        &VirtualAddressChangeEvent);

    gBS->CreateEvent(
        EVT_NOTIFY_SIGNAL_ALL,
        TPL_NOTIFY,
        NotifyVirtualAddressChangeRelease,
        NULL,
        &VirtualAddressChangeRelEvent);

    //
    // Locate DxeServicesTable
    //
    Status = EfiGetSystemConfigurationTable(&gEfiDxeServicesTableGuid, &gDS);
    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
            64,
            "!EFI_ERROR (Status)");
    }
    if (gDS == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\DxeServicesTableLib\\DxeServicesTableLib.c",
            65,
            "gDS != ((void *) 0)");
    }

    //
    // Locate MmPciBase protocol
    //
    if (gPciUsra == NULL) {
        Status = gBS->LocateProtocol(&gEfiMmPciBaseProtocolGuid, NULL, &gPciUsra);
        if (EFI_ERROR(Status)) {
            DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
            DebugAssert(
                "e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
                52,
                "!EFI_ERROR (Status)");
        }
        if (gPciUsra == NULL) {
            DebugAssert(
                "e:\\hs\\CpRcPkg\\Library\\DxeMmPciBaseLib\\DxeMmPciBaseLib.c",
                53,
                "mPciUsra != ((void *) 0)");
        }
    }

    FlashProtocolInstall();

    if (RuntimeServices == 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
            95,
            "gRT != ((void *) 0)");
    }

    if (gBS == 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
            96,
            "gBS != ((void *) 0)");
    }

    RuntimeNotifyEvent();

    gBS->SetTimer(RuntimeNotifyEventHandle, TimerPeriodic, 0);
    gBS->SetTimer(RuntimeNotifyEventHandle2, TimerPeriodic, 0);

    return EFI_SUCCESS;
}

/**
 * FlashDriverEntry - Driver entry.
 *
 * Creates notification events, installs Flash Protocol.
 */
EFI_STATUS
FlashDriverEntry (VOID)
{
    EFI_STATUS  Status;
    UINT64      Handle;
    EFI_GUID    FlashProtocolGuid = FLASH_PROTOCOL_GUID;

    Status = gBS->CreateEvent(
        EVT_NOTIFY_SIGNAL_ALL,
        TPL_NOTIFY,
        FlashSpinelHandler,
        NULL,
        &Handle);

    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\AmiModulePkg\\FlashDriver\\FlashDxe.c",
            63,
            "!EFI_ERROR (Status)");
    }

    if (CS_ != 0) {
        Status = 0x8000000000000009ULL;
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\AmiModulePkg\\FlashDriver\\Flash.c",
            715,
            "!EFI_ERROR (Status)");
    } else {
        aCs[4] = 0;
        CS_   = (UINT64)aCs;
        Status = EFI_SUCCESS;
        CS__0 = (UINT64)aCs;
    }

    qword_70C8 = -1;
    dword_7204 = 1;

    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\AmiModulePkg\\FlashDriver\\FlashDxe.c",
            66,
            "!EFI_ERROR (Status)");
    }

    Status = gBS->InstallMultipleProtocolInterfaces(
        &Handle,
        &FlashProtocolGuid,
        NULL,
        NULL);

    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\AmiModulePkg\\FlashDriver\\FlashDxe.c",
            69,
            "!EFI_ERROR (Status)");
    }

    return Status;
}

/**
 * FlashDriverUnload - Driver unload.
 *
 * Frees events, PCIe memory, flash regions.
 */
EFI_STATUS
FlashDriverUnload (VOID)
{
    EFI_STATUS  Status;

    Status = gBS->CloseEvent(VirtualAddressChangeEvent);
    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\AmiModulePkg\\FlashDriver\\FlashDriver\\DEBUG\\AutoGen.c",
            557,
            "!EFI_ERROR (Status)");
    }

    if (mPcieSegBusTable != 0) {
        FlashFreePciExpressMmio();
    }

    Status = gBS->CloseEvent(PciExpressNotifyEvent);
    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\DxeRuntimePciExpressLib\\PciExpressLib.c",
            178,
            "!EFI_ERROR (Status)");
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\AmiModulePkg\\FlashDriver\\FlashDriver\\DEBUG\\AutoGen.c",
            560,
            "!EFI_ERROR (Status)");
    }

    Status = gBS->CloseEvent(RuntimeNotifyEventHandle);
    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
            153,
            "!EFI_ERROR (Status)");
    }

    Status = gBS->CloseEvent(RuntimeNotifyEventHandle2);
    if (EFI_ERROR(Status)) {
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiRuntimeLib\\RuntimeLib.c",
            156,
            "!EFI_ERROR (Status)");
        DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
        DebugAssert(
            "e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\X64\\AmiModulePkg\\FlashDriver\\FlashDriver\\DEBUG\\AutoGen.c",
            563,
            "!EFI_ERROR (Status)");
    }

    gBS->CloseEvent(VirtualAddressChangeEvent);
    gBS->CloseEvent(VirtualAddressChangeRelEvent);

    return EFI_SUCCESS;
}

/**
 * FlashSpinelHandler - Spinel state machine callback.
 *
 * Notifies runtime services about completed flash operations.
 */
VOID
FlashSpinelHandler (VOID)
{
    for (i = 0; i < FlashSpinelIndex; i++) {
        gRT->ConvertPointer(0, &byte_73E0[16 * i]);
    }
    gRT->ConvertPointer(0, &CS__0);
}

/**
 * FlashProtocolInstall - Flash Protocol Implementation.
 *
 * Locates flash config descriptor (from HOB or system config table),
 * allocates region entries, installs the Flash Protocol.
 */
EFI_STATUS
EFIAPI
FlashProtocolInstall (
    IN EFI_HANDLE        ImageHandle,
    IN EFI_SYSTEM_TABLE  *SystemTable,
    ...
    )
{
    EFI_STATUS          Status;
    UINT64              FlashConfigTable;
    FLASH_DESCRIPTOR    *Descriptor;
    FLASH_REGION_ENTRY  *RegionEntry;
    UINT32              RegionSize;
    UINTN               EntryCount;

    Status = EfiGetSystemConfigurationTable(&gEfiFlashProtocolGuid, &FlashConfigTable);
    if (EFI_ERROR(Status)) {
        for (Descriptor = HobGetNext(NULL);
             Descriptor != NULL && !CompareGuid(&gEfiFlashProtocolGuid, Descriptor + 8);
             Descriptor = HobGetNext(Descriptor + *(UINT16 *)(Descriptor + 2))) {
            ;
        }
    } else {
        Descriptor = (FLASH_DESCRIPTOR *)FlashConfigTable;
    }

    if (Descriptor != NULL) {
        RegionSize = *(UINT16 *)(Descriptor + 2) - sizeof(FLASH_DESCRIPTOR) + 8;
        EntryCount = *(UINT32 *)(Descriptor + 32);
        FlashRegionEntrySize = *((UINT32 *)Descriptor + 7);
        FlashRegionTableSize = FlashRegionEntrySize * DivU64x32(RegionSize, EntryCount);

        RegionEntry = (FLASH_REGION_ENTRY *)AllocatePool(0, FlashRegionTableSize);
        if (RegionEntry != NULL) {
            RegionEntry = InternalZeroMem(RegionEntry, FlashRegionTableSize);
        }

        FlashRegionTable = (UINT64)RegionEntry;
        if (RegionEntry != NULL) {
            FlashRegionTableEnd = (UINT64)RegionEntry + FlashRegionTableSize;

            if ((UINT64)(Descriptor + 40) < (UINT64)Descriptor + *(UINT16 *)(Descriptor + 2)) {
                do {
                    gBS->CopyMem(RegionEntry, Descriptor + 40 + 8, FlashRegionEntrySize);
                    Descriptor += EntryCount;
                    RegionEntry += FlashRegionEntrySize;
                } while ((UINT64)Descriptor < Descriptor + *(UINT16 *)(Descriptor + 2));
            }

            if (EFI_ERROR(Status)) {
                RegionEntry = AllocatePool(0, *(UINT16 *)(Descriptor + 2));
                gBS->CopyMem(RegionEntry, Descriptor, *(UINT16 *)(Descriptor + 2));
                gBS->InstallConfigurationTable(&gEfiFlashProtocolGuid, RegionEntry);
            }
        }
    }

    gBS->CreateEvent(
        EVT_NOTIFY_VIRTUAL_ADDRESS_CHANGE,
        TPL_NOTIFY,
        FlashVirtualAddressNotify,
        NULL,
        &VirtualAddressChangeEvent);

    gBS->CreateEvent(
        EVT_NOTIFY_SIGNAL_ALL,
        TPL_NOTIFY,
        FlashFreePciExpressMmio,
        NULL,
        &RuntimeNotifyEventHandle);

    return EFI_SUCCESS;
}

/**
 * FlashVirtualAddressNotify - Runtime address conversion.
 *
 * Converts all physical flash addresses to virtual addresses
 * during OS runtime transition.
 */
VOID
FlashVirtualAddressNotify (VOID)
{
    FLASH_REGION_ENTRY  *Entry;
    UINT64              (*DispatchFn)(UINT64, UINT64 *);
    UINTN               Index;

    if (FlashSpinelBase != 0 && FlashSpinelState != 1) {
        FlashSpinelState = 1;

        gRT->ConvertPointer(0, FlashSpinelBase);
        gRT->ConvertPointer(0, FlashSpinelBase + 8);
        gRT->ConvertPointer(0, FlashSpinelBase + 16);
        gRT->ConvertPointer(0, FlashSpinelBase + 24);
        gRT->ConvertPointer(0, FlashSpinelBase + 32);
        gRT->ConvertPointer(0, FlashSpinelBase + 40);
        gRT->ConvertPointer(0, FlashSpinelBase + 48);
        gRT->ConvertPointer(0, FlashSpinelBase + 56);
        gRT->ConvertPointer(0, FlashSpinelBase + 64);
        gRT->ConvertPointer(0, FlashSpinelBase + 80);
        gRT->ConvertPointer(0, &FlashSpinelBase);
        gRT->ConvertPointer(0, &unk_7108);
        gRT->ConvertPointer(0, &qword_7100);

        for (Index = 0; Index < FlashSpinelIndex; Index++) {
            gRT->ConvertPointer(0, &FlashSpinelBase + Index);
        }

        DispatchFn = (UINT64 (*)(UINT64, UINT64 *))&off_67E0;
        while (*DispatchFn != NULL) {
            if ((*DispatchFn)(gImageHandle, &FlashSpinelBase)) {
                break;
            }
            DispatchFn++;
        }

        gRT->ConvertPointer(0, &FlashSpinelBase);
    }

    if (FlashRegionTable != 0) {
        Entry = (FLASH_REGION_ENTRY *)FlashRegionTable;
        do {
            gRT->ConvertPointer(0, &Entry->VirtualAddress);
            Entry = FlashTableNextEntry(Entry);
        } while (Entry != NULL);

        gRT->ConvertPointer(0, &FlashRegionTable);
        gRT->ConvertPointer(0, &FlashRegionTableEnd);
    }
}

/**
 * FlashFreePciExpressMmio - Frees PCIe MMIO mappings.
 */
VOID
FlashFreePciExpressMmio (VOID)
{
    FLASH_REGION_ENTRY  *Entry;

    Entry = (FLASH_REGION_ENTRY *)FlashRegionTable;
    if (Entry == 0) {
        return;
    }

    do {
        gRT->ConvertPointer(0, &Entry->VirtualAddress);
        Entry = FlashTableNextEntry(Entry);
    } while (Entry != NULL);

    gRT->ConvertPointer(0, &FlashRegionTable);
    gRT->ConvertPointer(0, &FlashRegionTableEnd);
}

/**
 * FlashTableNextEntry - Get next flash region entry.
 */
FLASH_REGION_ENTRY *
FlashTableNextEntry (
    IN FLASH_REGION_ENTRY  *Entry
    )
{
    FLASH_REGION_ENTRY  *Next;

    Next = (FLASH_REGION_ENTRY *)((UINT8 *)Entry + 16);
    if ((UINT64)Next >= FlashRegionTableEnd) {
        return NULL;
    }
    if (Next->BaseAddress == 0 && Next->VirtualAddress == 0) {
        return NULL;
    }
    return Next;
}

/**
 * FlashDeviceProbe - SPI flash device probing.
 *
 * Dispatches to probe functions registered in off_67E0.
 */
EFI_STATUS
FlashDeviceProbe (
    IN UINTN  FlashDeviceIndex
    )
{
    UINT64  (*DispatchEntry)(UINT64, UINT64 *);
    UINT64  Result;

    DispatchEntry = (UINT64 (*)(UINT64, UINT64 *))&off_67E0;

    do {
        if (*DispatchEntry == NULL) {
            break;
        }
        Result = (*DispatchEntry)(FlashDeviceIndex, &FlashSpinelBase);
        DispatchEntry++;
    } while (!Result);

    return 0;
}

/**
 * GetDebugOutputInterface - Locate EFI Debug Protocol.
 */
VOID *
GetDebugOutputInterface (VOID)
{
    VOID    *DebugInterface;
    UINTN   BufferSize;

    DebugInterface = (VOID *)qword_7248;

    if (DebugInterface == NULL) {
        if (BootServices_0 != 0) {
            BufferSize = (UINTN)(*gBS->AllocatePool)(31);
            (*gBS->FreePool)(BufferSize);
            if (BufferSize <= 0x10) {
                Status = gBS->LocateProtocol(&gEfiDebugProtocolGuid, NULL, &DebugInterface);
                if (EFI_ERROR(Status)) {
                    DebugInterface = NULL;
                }
                qword_7248 = (UINT64)DebugInterface;
            }
        }
    }

    return DebugInterface;
}

/**
 * DebugPrint - Formatted debug print via CMOS level.
 */
VOID
EFIAPI
DebugPrint (
    IN UINTN             ErrorLevel,
    IN CONST CHAR8       *Format,
    ...
    )
{
    VOID        *DebugInterface;
    UINTN       DebugLevelMask;
    UINT8       CmosIndex, CmosValue;

    va_list     Marker;
    va_start(Marker, Format);

    DebugInterface = GetDebugOutputInterface();
    DebugLevelMask = 0;

    if (DebugInterface != NULL) {
        CmosIndex = __inbyte(0x70);
        __outbyte(0x70, CmosIndex & 0x80 | 0x4B);
        CmosValue = __inbyte(0x71);

        if (CmosValue > 3) {
            CmosValue = 3;
        }

        DebugLevelMask = CmosValue - 1;
        if ((UINT8)(CmosValue - 1) <= 0xFD) {
            if (CmosValue == 1) {
                DebugLevelMask = 2147483652LL;
            }
        }

        if (DebugLevelMask & ErrorLevel) {
            ((VOID (*)(UINTN, CONST CHAR8 *, va_list))DebugInterface->DebugPrint)(
                ErrorLevel, Format, Marker);
        }
    }
}

/**
 * DebugAssert - UEFI assertion handler.
 */
VOID
EFIAPI
DebugAssert (
    IN CONST CHAR8  *FileName,
    IN UINTN        LineNumber,
    IN CONST CHAR8  *Description
    )
{
    VOID  *DebugInterface;

    DebugInterface = GetDebugOutputInterface();
    if (DebugInterface != NULL) {
        ((VOID (*)(VOID *))DebugInterface->DebugAssert)(DebugInterface);
    }
}

/**
 * EfiGetSystemConfigurationTable - Locate config table by GUID.
 */
EFI_STATUS
EfiGetSystemConfigurationTable (
    IN  EFI_GUID  *TableGuid,
    OUT VOID      **Table
    )
{
    UINTN       Index;

    if (TableGuid == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
            97,
            "TableGuid != ((void *) 0)");
    }

    if (Table == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\UefiLib\\UefiLib.c",
            98,
            "Table != ((void *) 0)");
    }

    *Table = NULL;

    if (gST->NumberOfTableEntries == 0) {
        return EFI_NOT_FOUND;
    }

    for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
        if (CompareGuid(TableGuid, &gST->ConfigurationTable[Index].VendorGuid)) {
            *Table = gST->ConfigurationTable[Index].VendorTable;
            return EFI_SUCCESS;
        }
    }

    return EFI_NOT_FOUND;
}

/**
 * CompareGuid - Compare two GUIDs.
 */
BOOLEAN
CompareGuid (
    IN EFI_GUID  *Guid1,
    IN EFI_GUID  *Guid2
    )
{
    return (ReadUint64FromBuffer(Guid1) == ReadUint64FromBuffer(Guid2)) &&
           (ReadUint64FromBuffer((UINT8 *)Guid1 + 8) ==
            ReadUint64FromBuffer((UINT8 *)Guid2 + 8));
}

/**
 * ReadUint64FromBuffer - Read a UINT64 from buffer.
 */
UINT64
ReadUint64FromBuffer (
    IN VOID   *Buffer
    )
{
    return *((volatile UINT64 *)Buffer);
}

/**
 * NotifyVirtualAddressChangeNull - Dummy handler.
 */
VOID
NotifyVirtualAddressChangeNull (VOID)
{
    BootServices_0 = 0;
}

/**
 * NotifyVirtualAddressChangeRelease - Release handler.
 */
VOID
NotifyVirtualAddressChangeRelease (VOID)
{
    if (qword_7248 != 0) {
        gRT->ConvertPointer(0, &qword_7248);
    }
}

/**
 * NullFunction - No-op placeholder.
 */
VOID
NullFunction (VOID)
{
}

/**
 * RuntimeNotifyEvent - Register runtime notification.
 */
EFI_STATUS
RuntimeNotifyEvent (VOID)
{
    EFI_STATUS  Status;

    Status = gRT->ConvertPointer(0, &RuntimeServices_1);
    byte_7268 = 1;

    return Status;
}

/**
 * RuntimeFreePages - Free runtime pages.
 */
VOID
RuntimeFreePages (VOID)
{
    UINTN       Index;
    VOID        *Table;

    Table = (VOID *)mPcieSegBusTable;

    if (Table != NULL) {
        if (mPcieSegBusTableCount != 0) {
            for (Index = 0; Index < mPcieSegBusTableCount; Index++) {
                gRT->ConvertPointer(0, (UINT64)Table + Index * 16 + 8);
            }
        }
        gRT->ConvertPointer(0, &mPcieSegBusTable);
    }
}

/**
 * PciExpressGetAddress - Translate PCIe cfg address to MMIO.
 */
UINTN
EFIAPI
PciExpressGetAddress (
    IN UINTN  Address
    )
{
    UINTN           Translated;
    UINTN           PageOffset;
    UINTN           Index;

    if ((Address & 0xFFFFFFFFF0000000ULL) != 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\DxeRuntimePciExpressLib\\PciExpressLib.c",
            203,
            "((Address) & ~0xfffffff) == 0");
    }

    Translated = gPciExpressBaseAddress + Address;

    if (mEfiGoneVirtual) {
        PageOffset = Translated & 0xFFF;

        if (*(UINT64 *)(mPcieSegBusTable + 16 * mPciExpressRegistration) ==
            (Translated & 0xFFFFFFFFFFFFF000ULL)) {
            return *(UINT64 *)(mPcieSegBusTable + 16 * mPciExpressRegistration + 8) + PageOffset;
        }

        if (mPcieSegBusTableCount == 0) {
            goto Fail;
        }

        for (Index = 0; Index < mPcieSegBusTableCount; Index++) {
            if (*(UINT64 *)(mPcieSegBusTable + Index * 16) ==
                (Translated & 0xFFFFFFFFFFFFF000ULL)) {
                mPciExpressRegistration = Index;
                return *(UINT64 *)(mPcieSegBusTable + Index * 16 + 8) + PageOffset;
            }
        }

Fail:
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\DxeRuntimePciExpressLib\\PciExpressLib.c",
            246,
            "((BOOLEAN)(0==1))");
        __debugbreak();
    }

    return Translated;
}

/**
 * IoWrite16 - Write to I/O port (value 0x500).
 */
UINT16
IoWrite16 (
    IN UINT16  *Address
    )
{
    if (((UINTN)Address & 1) != 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
            183,
            "(Address & 1) == 0");
    }

    *Address = 0x500;
    return 0x500;
}

/**
 * IoRead32 - Read I/O port DWORD value.
 */
UINT32
IoRead32 (
    IN UINT16  Port
    )
{
    if ((Port & 3) != 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLibMsc.c",
            193,
            "(Port & 3) == 0");
    }

    return __indword(Port);
}

/**
 * DivU64x32 - 64/32 unsigned division.
 */
UINT64
DivU64x32 (
    IN UINT64  Dividend,
    IN UINT32  Divisor
    )
{
    if (Divisor == 0) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\BaseLib\\DivU64x32.c",
            43,
            "Divisor != 0");
    }

    return Dividend / Divisor;
}

/**
 * InternalZeroMem - Zero-fill memory.
 */
VOID *
EFIAPI
InternalZeroMem (
    IN VOID   *Buffer,
    IN UINTN  Length
    )
{
    if (Length == 0) {
        return Buffer;
    }

    if (Buffer == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
            53,
            "Buffer != ((void *) 0)");
    }

    if (Length > -Buffer) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\ZeroMemWrapper.c",
            54,
            "Length <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)Buffer + 1)");
    }

    return sub_10C0(Buffer, Length);
}

/**
 * InternalCopyMem - Copy memory buffer.
 */
VOID *
EFIAPI
InternalCopyMem (
    OUT VOID       *Destination,
    IN  CONST VOID *Source,
    IN  UINTN      Length
    )
{
    UINTN  DestEnd, SrcEnd;

    if (Length != 0) {
        if (Length - 1 > (UINTN)(-1) - (UINTN)Destination) {
            DebugAssert(
                "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
                56,
                "(Length - 1) <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)DestinationBuffer)");
        }

        if (Length - 1 > (UINTN)(-1) - (UINTN)Source) {
            DebugAssert(
                "e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c",
                57,
                "(Length - 1) <= (0xFFFFFFFFFFFFFFFFULL - (UINTN)SourceBuffer)");
        }

        if (Destination != Source) {
            return sub_1000(Destination, Source, Length);
        }
    }

    return Destination;
}

/**
 * AllocatePool - Allocate memory pool.
 */
VOID *
AllocatePool (
    IN UINT32  EntryType,
    IN UINTN   Size
    )
{
    EFI_STATUS  Status;
    VOID        *Buffer;

    Buffer = NULL;
    Status = gBS->AllocatePool(EfiRuntimeServicesData, Size, &Buffer);

    if (EFI_ERROR(Status)) {
        return NULL;
    }

    return Buffer;
}

/**
 * FlashIsReadyGet - Get flash ready state.
 */
BOOLEAN
FlashIsReadyGet (VOID)
{
    BOOLEAN  WasReady;

    WasReady = byte_7368;
    if (!byte_7368) {
        byte_7368 = 1;
    }

    return WasReady;
}

/**
 * FlashSpiFlashCmd - Send SPI flash command.
 */
EFI_STATUS
FlashSpiFlashCmd (
    IN VOID    *CmdBuffer
    )
{
    byte_7350 = 1;
    return ((EFI_RUNTIME_SERVICES *)CmdBuffer)->ConvertPointer(0, 29168);
}

/**
 * NotifySetDsNull - Sets DXE Services to null.
 */
VOID
NotifySetDsNull (VOID)
{
    gDS = 0;
}

/**
 * CpuPause - CPU pause instruction.
 */
VOID
CpuPause (VOID)
{
    _mm_pause();
}

/**
 * HOB_GET_NEXT - Walk HOB list for type 4.
 */
VOID *
HobGetNext (
    IN VOID   *HobStart
    )
{
    UINT16  *HobPtr;

    HobPtr = (UINT16 *)HobStart;

    if (HobPtr == NULL) {
        DebugAssert(
            "e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
            108,
            "HobStart != ((void *) 0)");
    }

    while (TRUE) {
        if (*HobPtr == 0xFFFF) {
            return NULL;
        }
        if (*HobPtr == 4) {
            break;
        }
        HobPtr = (UINT16 *)((UINT8 *)HobPtr + HobPtr[1]);
    }

    return HobPtr;
}