Newer
Older
AMI-Aptio-BIOS-Reversed / NvramSmm / NvramSmm.c
@Ajax Dong Ajax Dong 2 days ago 35 KB Init
// NvramSmm.c - NVRAM SMM Driver
// Build path: e:\hs\Build\HR6N0XMLK\DEBUG_VS2015\X64\AmiModulePkg\NVRAM\NvramSmm\DEBUG
// Source files: NvramSmm.c, NvramDxeCommon.c, NvramSmi.c, AuthService.c

#include "NvramSmm.h"

// ========================================================================
// Global State (from .data section)
// ========================================================================

EFI_HANDLE                      gImageHandle = NULL;                 // 0x11670
EFI_SYSTEM_TABLE               *gST = NULL;                         // 0x11660
EFI_BOOT_SERVICES              *gBS = NULL;                         // 0x11668
EFI_RUNTIME_SERVICES           *gRT = NULL;                         // 0x11678
EFI_SMM_SYSTEM_TABLE2          *gSmst = NULL;                       // 0x11680
VOID                           *gDS = NULL;                         // 0x11758

EFI_SMM_BASE2_PROTOCOL         *gSmmBase2;                          // 0x116F8
VOID                           *gMmst;                              // 0x116F0
VOID                           *gSmmCpuIo = NULL;                   // 0x11690
VOID                           *gSmmBufferValidation = NULL;         // 0x11750

UINT64                          gNvramStoreBase = 0;                // 0x115D0
UINT64                          gNvramStoreSize = 0;                // 0x115D8

UINT32                          gVarStoreCount = 0;                 // 0x11C24
UINT8                           gVarStoreInitFlags = 0;             // 0x11C20
UINT32                          gNvramUpdateDisabled = 0;           // 0x11C28

EFI_RUNTIME_SERVICES           *gRuntimeServicesOverride = NULL;    // 0x116E8

VOID                           *gDriverNvramBuffer = NULL;          // 0x11F10
UINTN                           gDriverNvramBufferSize = 0;         // 0x11F18
VOID                           *gNvramDmaBuffer = NULL;             // 0x11648

UINT64                          gMailboxNvramBase = 0;              // 0x11F28
UINT64                          gMailboxNvramSize = 0;              // 0x11F30
UINT32                          gMailboxNvramFlags = 0;             // 0x11F38
UINT64                          gMailboxVarStoreBase = 0;           // 0x11F40
UINT64                          gMailboxVarStoreSize = 0;           // 0x11F48

BOOLEAN                         gMigrationDone = FALSE;             // 0x11609
BOOLEAN                         gSmiProcessing = FALSE;             // 0x11768
UINT8                           gSecureBootMode = 0;                // 0x11894

VAR_STORE_INFO                  gVarStoreArray[?];                  // 0x11C38

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

EFI_STATUS
EFIAPI
ModuleEntryPoint(
    IN EFI_HANDLE        ImageHandle,
    IN EFI_SYSTEM_TABLE *SystemTable
    )
{
    EFI_STATUS Status;

    // Initialize all UEFI/SMM plumbing
    Status = NvramSmmInit(ImageHandle);
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Global status variable
    gBS              = gST->BootServices;
    gRT              = gST->RuntimeServices;
    gImageHandle     = ImageHandle;

    // Locate SmmBase2 protocol
    Status = gBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
    if (EFI_ERROR(Status)) {
        DEBUG((EFI_D_ERROR, "ASSERT: !EFI_ERROR(Status) - SmmServicesTableLib\n"));
        return Status;
    }

    // Get SMM System Table
    Status = gSmmBase2->GetSmstLocation(gSmmBase2, &gSmst);
    if (EFI_ERROR(Status) || gSmst == NULL) {
        DEBUG((EFI_D_ERROR, "ASSERT: gSmst != NULL\n"));
        return Status;
    }

    // Locate SMM memory allocation protocol
    Status = gBS->LocateProtocol(&gEfiSmmAccess2ProtocolGuid, NULL, &gSmmMemoryProtocol);
    if (EFI_ERROR(Status)) {
        DEBUG((EFI_D_ERROR, "ASSERT: !EFI_ERROR(Status) - MemoryAllocationLib\n"));
    }

    // Get SMRAM ranges
    gSmramRanges = AllocateSmramRanges(&gSmramRangeCount);

    // Initialize PCIE segment bus table
    PcieSegBusTableInit();

    // Initialize AmiCryptoLib
    AmiCryptoLibConstructor();

    // Initialize heap memory manager
    SmmHeapInit();

    // Locate SMM buffer validation protocol
    Status = gMmst->SmmLocateProtocol(&gSmmBufferValidationProtocolGuid, NULL, &gSmmBufferValidation);
    if (EFI_ERROR(Status)) {
        DEBUG((EFI_D_ERROR, "ASSERT: !EFI_ERROR(Status) - SmmAmiBufferValidationLib\n"));
        gSmmBufferValidation = NULL;
    }

    // Locate DxeServicesTable
    Status = gBS->LocateProtocol(&gEfiDxeServicesTableProtocolGuid, NULL, &gDS);
    if (EFI_ERROR(Status)) {
        DEBUG((EFI_D_ERROR, "ASSERT: !EFI_ERROR(Status) - DxeServicesTableLib\n"));
        return Status;
    }

    // Fall through to SMM protocol install / notification init (returned from Init)
    return EFI_SUCCESS;
}

// ========================================================================
// NVRAM Initialization (sub_10F8)
// ========================================================================

EFI_STATUS
NvramCoreInit(
    VOID
    )
{
    EFI_STATUS              Status;
    UINTN                   NvramMailBoxSize = 24;
    UINT8                   MailboxBuffer[24];
    EFI_HOB_GUID_TYPE      *GuidHob;
    VAR_STORE_PTR          *VarStoreInfo;
    UINT64                  StoreBase, StoreSize;
    VOID                   *DmaBuffer;

    // Signal that NVRAM store size at least matches HOB pattern
    gNvramStoreSize = 1;

    // Get NVRAM HOB from HOB list
    Status = NvramHobRetrieve();
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Read NvramMailBox variable to get mailbox memory region info
    Status = gRT->GetVariable(
                    L"NvramMailBox",
                    &gNvramMailboxVariableGuid,
                    NULL,
                    &NvramMailBoxSize,
                    MailboxBuffer
                    );
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Extract mailbox NVRAM base/size details from the variable
    gMailboxNvramBase     = *(UINT64 *)(MailboxBuffer + 0);    // offset 0
    gMailboxNvramSize     = *(UINT64 *)(MailboxBuffer + 8);    // offset 8
    gMailboxNvramFlags    = *(UINT32 *)(MailboxBuffer + 60);   // offset 60
    gMailboxVarStoreBase  = *(UINT64 *)(MailboxBuffer + 736);  // offset 736
    gMailboxVarStoreSize  = *(UINT64 *)(MailboxBuffer + 744);  // offset 744

    // Close the variable
    gRT->SetVariable(L"NvramMailBox", &gNvramMailboxVariableGuid, 0, 0, NULL);

    // Validate that VarStoreInfo NVRAM sizes match mailbox
    if (VarStoreInfo->MemInfo->NvramSize != gMailboxVarStoreSize) {
        return EFI_INVALID_PARAMETER;
    }

    // Copy VarStoreInfo NVRAM data from mailbox into working buffer
    CopyMem(VarStoreInfo->MemInfo->Buffer, gMailboxVarStoreBase, gMailboxVarStoreSize);
    VarStoreInfo->MemInfo->FlagResets++;
    VarStoreInfo->MemInfo->CrcRecalc();

    // If simulation mode, also copy NvInfo data from mailbox
    if (gVarStoreInitFlags & 8) {
        if (VarStoreInfo->NvInfo->NvramSize != gMailboxVarStoreSize) {
            return EFI_INVALID_PARAMETER;
        }
        CopyMem(VarStoreInfo->NvInfo, gMailboxVarStoreBase, gMailboxVarStoreSize);
        VarStoreInfo->NvInfo->FlagResets++;
        VarStoreInfo->NvInfo->CrcRecalc();
        NotifyFlashUpdate();
    }

    NotifyVarStoreInfoChange();

    // Allocate DMA buffer for SMI communication (0x40000 bytes)
    Status = gMmst->SmmAllocatePool(EfiRuntimeServicesData, 0x40000, &DmaBuffer);
    if (EFI_ERROR(Status)) {
        return Status;
    }
    gNvramDmaBuffer = DmaBuffer;
    // Initialize buffer header
    *(UINT64 *)DmaBuffer = (UINT64)DmaBuffer + 24;  // data starts at +24
    *(UINT64 *)((UINT8 *)DmaBuffer + 8) = 0x40000 - 24; // usable size
    *(UINT64 *)((UINT8 *)DmaBuffer + 16) = 0;

    // Register SMI handler for NVRAM variable access
    Status = gMmst->SmiHandlerRegister(
                        SmiNvramCommHandler,
                        &gNvramMailboxVariableGuid,
                        &gSmiNvramCommHandle
                        );
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Register notification callback on SMM ReadyToLock
    Status = gMmst->SmmRegisterProtocolNotify(
                        &gEfiSmmReadyToLockProtocolGuid,
                        SmmReadyToLockNotification,
                        &gSmmReadyToLockNotifyHandle
                        );
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Override runtime variable services
    gRuntimeServicesOverride               = gSmmBase2->SmmGetRuntimeServices();
    gRuntimeServicesOverride->GetVariable  = RuntimeGetVariable;
    gRuntimeServicesOverride->SetVariable  = RuntimeSetVariable;
    gRuntimeServicesOverride->GetNextVariableName = RuntimeGetNextVariableName;
    gRuntimeServicesOverride->QueryVariableInfo  = RuntimeQueryVariableInfo;

    // Register variable change callbacks for variable sync
    Status = gMmst->SmmRegisterProtocolNotify(
                        &gVariableChangeProtocolGuid,
                        VariableChangeCallback,
                        &gVariableChangeNotifyHandle
                        );
    // Register additional callbacks for DmiArray variable change
    Status = gMmst->SmmRegisterProtocolNotify(
                        &gNvramMailboxVariableGuid,
                        NvramMailboxNotify,
                        &gNvramMailboxNotifyHandle
                        );
    // Register SMM communication protocol for variable sync
    Status = gMmst->SmmRegisterProtocolNotify(
                        &gSmmVariableSyncProtocolGuid,
                        SmmVariableSyncNotify,
                        &gSmmVariableSyncNotifyHandle
                        );

    return Status;
}

// ========================================================================
// SMI NVRAM Communication Handler (sub_6AE4)
// ========================================================================

EFI_STATUS
EFIAPI
SmiNvramCommHandler(
    IN     EFI_HANDLE  DispatchHandle,
    IN     CONST VOID *RegisterContext,
    IN OUT VOID       *CommBuffer,
    IN OUT UINTN      *CommBufferSize
    )
{
    UINT64     CommandCode;
    UINTN      BufferSize;
    UINT8     *AlignedBuffer;
    UINTN      AlignedSize;
    EFI_STATUS Status;

    BufferSize = *CommBufferSize;

    // Validate buffer address with SMM buffer validation protocol
    if (gSmmBufferValidation != NULL) {
        if (gSmmBufferValidation->ValidateBuffer(CommBuffer, BufferSize) != EFI_SUCCESS) {
            DEBUG((EFI_D_ERROR, "[%a]: SMM buffer security violation.\n", __FUNCTION__));
            return EFI_ACCESS_DENIED;
        }
    }

    // Align the buffer pointer to 8-byte boundary
    AlignedBuffer = (UINT8 *)((UINTN)CommBuffer & ~7);
    AlignedSize   = BufferSize - ((UINTN)CommBuffer - (UINTN)AlignedBuffer);

    if (AlignedSize < 8) {
        return EFI_INVALID_PARAMETER;
    }

    // Set SMI processing flag
    gSmiProcessing = TRUE;

    // Read command code at offset 0
    CommandCode = *(UINT64 *)AlignedBuffer;

    switch (CommandCode) {
    case SMI_NVRAM_CMD_GET_VARIABLE:
        // Type 0: GetVariable operation
        // Buffer layout: +0x00: cmd, +0x08: NameSize, +0x10: DataSize
        //               +0x18: Attributes, +0x20: Name[], +0x30: GUID + Data
        if (AlignedSize < 0x30 + 16) goto invalid;
        // Nested variable read with sub_5580
        Status = RuntimeGetVariable(
                    (CHAR16 *)(AlignedBuffer + 0x08),
                    (EFI_GUID *)(AlignedBuffer + 0x18),
                    (UINT32 *)(AlignedBuffer + 0x10),
                    (UINTN *)(AlignedBuffer + 0x28),
                    AlignedBuffer + 0x30
                    );
        break;

    case SMI_NVRAM_CMD_SET_VARIABLE:
        // Type 1: SetVariable operation
        // Buffer layout: +0x00: cmd, +0x08: NameLength, +0x10: DataSize
        //               +0x18: Attributes, +0x20: Name[], +0x20+NameSize: GUID
        //               +0x30+NameSize: Data[]
        if (AlignedSize < 0x20 + 2) goto invalid;
        // sub_5654 handles the actual set
        Status = RuntimeSetVariable(
                    (CHAR16 *)(AlignedBuffer + 0x08),
                    (EFI_GUID *)(AlignedBuffer + 0x20 + *(UINT16 *)AlignedBuffer & ~1),
                    *(UINT32 *)(AlignedBuffer + 0x18),
                    *(UINTN *)(AlignedBuffer + 0x10),
                    AlignedBuffer + 0x30 + (*(UINT16 *)AlignedBuffer & ~1)
                    );
        break;

    case SMI_NVRAM_CMD_GET_NEXT_VARIABLE:
        // Type 2: GetNextVariableName
        if (AlignedSize < 0x30) goto invalid;
        Status = RuntimeGetNextVariableName(
                    (UINTN *)(AlignedBuffer + 0x28),
                    (CHAR16 *)(AlignedBuffer + 0x08),
                    (EFI_GUID *)(AlignedBuffer + 0x18)
                    );
        break;

    case SMI_NVRAM_CMD_QUERY_VARIABLE_INFO:
        // Type 3: QueryVariableInfo
        if (AlignedSize != 40) goto invalid;
        Status = RuntimeQueryVariableInfo(
                    (UINTN *)(AlignedBuffer + 0x10),
                    (UINTN *)(AlignedBuffer + 0x18),
                    (UINTN *)(AlignedBuffer + 0x20)
                    );
        break;

    case SMI_NVRAM_CMD_TYPE_4:
        // Type 4: Variable write with auth
        if (AlignedSize < 0x20 + 2) goto invalid;
        Status = sub_575C(*(UINT16 *)AlignedBuffer >> 1,
                          AlignedBuffer + 0x20,
                          AlignedBuffer + 0x10);
        break;

    case SMI_NVRAM_CMD_MIGRATION_DONE:
        // Migration complete notification
        if (AlignedSize == 8) {
            gMigrationDone = TRUE;
            qword_11618 = 0;
            Status = EFI_SUCCESS;
        } else {
            goto invalid;
        }
        break;

    default:
        goto invalid;
    }

    gSmiProcessing = FALSE;

    // Write status back to command code location
    if (Status < 0) {
        Status |= 0x8000000000000000ULL;
    }
    *(UINT64 *)AlignedBuffer = Status;
    return EFI_SUCCESS;

invalid:
    gSmiProcessing = FALSE;
    *(UINT64 *)AlignedBuffer = EFI_INVALID_PARAMETER;
    return EFI_SUCCESS;
}

// ========================================================================
// SMI NVRAM Update Handler (sub_5FAC and sub_5E44)
// ========================================================================

EFI_STATUS
EFIAPI
SmiNvramUpdateHandler(
    IN     EFI_HANDLE  DispatchHandle,
    IN     CONST VOID *RegisterContext,
    IN OUT VOID       *CommBuffer,
    IN OUT UINTN      *CommBufferSize
    )
{
    VAR_STORE_PTR *StorePtr;
    UINTN          NvramSize;
    UINTN          ReadSize;
    UINT8         *TempBuffer;
    UINTN          TempBufferSize;
    UINT8         *Source;
    UINT8         *Dest;
    EFI_STATUS     Status;

    StorePtr = (VAR_STORE_PTR *)gVarStoreArray[0]; // qword_11F00

    // Validate comm buffer
    if (CommBuffer == NULL || CommBufferSize == NULL) {
        return EFI_INVALID_PARAMETER;
    }

    // Check size match
    NvramSize = StorePtr->NvramSize;
    if (*CommBufferSize != NvramSize) {
        return EFI_INVALID_PARAMETER;
    }

    // Check that source buffer has a valid FV header
    ReadSize = GetFvHeaderSize(CommBuffer);
    if (ReadSize == 0) {
        DEBUG((EFI_D_ERROR, "NVRAM: ERROR: AmiNvramUpdate->UpdateNvram failed, invalid FV header.\n"));
        return EFI_VOLUME_CORRUPTED;
    }

    // Check if FV header size is consistent
    if (ReadSize && *(UINT64 *)((UINT8 *)CommBuffer + 32) == StorePtr &&
        (GetFvHeaderSize(CommBuffer))) {

        // Validate the data aligns with store parameters
        TempBuffer = NULL;
        TempBufferSize = NvramSize;

        if (TempBufferSize > StorePtr->StoreSize) {
            // Need to allocate bigger temp buffer (3x)
            TempBuffer = HeapAlloc(TempBufferSize);
            if (TempBuffer == NULL) {
                return EFI_OUT_OF_RESOURCES;
            }
            if (3 * NvramSize > TempBufferSize) {
                HeapFree(gDriverNvramBuffer, gDriverNvramBufferSize);
                gDriverNvramBuffer = HeapAlloc(3 * NvramSize);
                if (gDriverNvramBuffer == NULL) {
                    HeapFree(TempBuffer, TempBufferSize);
                    return EFI_OUT_OF_RESOURCES;
                }
                TempBufferSize = 3 * NvramSize;
            }
        }

        // Copy source NVRAM data
        TempBuffer = AllocateCopyPool(NvramSize, CommBuffer);
        if (TempBuffer == NULL) {
            return EFI_OUT_OF_RESOURCES;
        }

        // Check that data is not all 0xFF (empty erased)
        if (!IsBufferErased(TempBuffer, NvramSize)) {
            // Check for active NVRAM (FV header + GUID match)
            if (!CompareGuid(TempBuffer + 18, &gNvramSignatureGuid, 16)) {
                goto cleanup;
            }
        } else {
            goto cleanup;
        }

        // Check size matches the data in the FV
        Source = TempBuffer + ReadSize;
        if ((*(UINT32 *)(Source + 20) & 0xFFFFFF) != NvramSize - ReadSize) {
            goto cleanup;
        }

        // Copy from temp to working store
        FreePool(TempBuffer);

        // Set up store pointers for the migration
        StorePtr->VolatileInfo = CommBuffer;     // source address
        StorePtr->NvInfo = (VOID *)Source;       // dest address

        // Validate store parameters
        Status = ValidateStoreParameters(StorePtr);
        if (EFI_ERROR(Status)) {
            DEBUG((EFI_D_ERROR, "ASSERT: !EFI_ERROR\n");
            return Status;
        }

        // F Fill header calculation
        UINT32 HeaderSize = GetStoreHeaderSize(StorePtrp->Info);
        if (HeaderSize == 0) {
            return EFI_DEVICE_ERROR;
        }

        // Set up the variable enumeration
        UINTN  FullSize = HeaderSize + 24;
        if (ReadSize + 24 == 0) {
            return EFI_DEVICE_ERROR;
        }

        if (StorePtr->NvInfo) {
            // Try to find space and move
            Status = StorePtr->FlashProtocol->Erase(StorePtr->NvInfo, FullSize);
            BOOLEAN CanFit = StorePtr->FlashProtocol->CanFit(StorePtr->NvInfo, FullSize, CommBuffer);
            StorePtr->FlashProtocol->Unlock();
            if (CanFit) {
                StorePtr->FlashProtocol->Write(StorePtr->NvInfo, FullSize, CommBuffer);
                return EFI_VOLUME_CORRUPTED;
            }
        }

        // Garbage collection / flush path
        Status = StorePtr->FlashProtocol->Erase(gNvramStoreBase, FullSize);
        BOOLEAN CanFit2 = StorePtr->FlashProtocol->CanFit(gNvramStoreBase, FullSize, CommBuffer);
        StorePtr->FlashProtocol->Unlock();
        if (CanFit2) {
            StorePtr->FlashProtocol->Write(gNvramStoreBase, FullSize, CommBuffer);
            // Mark old store entries
            UINTN OldSize = GetFvHeaderSize(CommBuffer);
            *(UINT8 *)(OldSize + CommBuffer + 23) = 0xFC;  // mark deleted
            return EFI_VOLUME_CORRUPTED;
        }

        // Full GC path
        Status = StorePtr->FlashProtocol->Erase(gNvramStoreBase, FullSize);
        if (EFI_ERROR(Status)) {
            return EFI_VOLUME_CORRUPTED;
        }
        BOOLEAN CanFit3 = StorePtr->FlashProtocol->CanFit(gNvramStoreBase, FullSize, NULL);
        StorePtr->FlashProtocol->Unlock();
        if (!CanFit3) {
            TempBuffer = NULL;
            StorePtr->FlashProtocol->SetMemory(gNvramStoreBase, FullSize, 0xFF);
            return EFI_SUCCESS;
            // At this point the GC reclaimed space
        }
        // ... continued
    }

cleanup:
    if (TempBuffer) {
        FreePool(TempBuffer);
    }
    return Status;
}

// ========================================================================
// Runtime Variable Service Overrides
// ========================================================================

EFI_STATUS
EFIAPI
RuntimeGetVariable(
    IN     CHAR16    *VariableName,
    IN     EFI_GUID  *VendorGuid,
    OUT    UINT32    *Attributes,
    IN OUT UINTN    *DataSize,
    OUT    VOID      *Data
    )
{
    // Dispatches to SMI via SMI_NVRAM_CMD_GET_VARIABLE command
    // For non-SMM context, sends SMI to enter SMM first.
    // Forward declaration: actual implementation at sub_5580.
    return EFI_INVALID_PARAMETER;
}

EFI_STATUS
EFIAPI
RuntimeSetVariable(
    IN CHAR16    *VariableName,
    IN EFI_GUID  *VendorGuid,
    IN UINT32     Attributes,
    IN UINTN      DataSize,
    IN VOID      *Data
    )
{
    // Dispatches to SMI via SMI_NVRAM_CMD_SET_VARIABLE command
    // Forward declaration: actual implementation at sub_5654.
    return EFI_INVALID_PARAMETER;
}

EFI_STATUS
EFIAPI
RuntimeGetNextVariableName(
    IN OUT UINTN   *VariableNameSize,
    IN OUT CHAR16  *VariableName,
    IN OUT EFI_GUID *VendorGuid
    )
{
    // Dispatches via SMI_NVRAM_CMD_GET_NEXT_VARIABLE
    // Forward declaration: actual implementation at sub_F54.
    return EFI_INVALID_PARAMETER;
}

EFI_STATUS
EFIAPI
RuntimeQueryVariableInfo(
    IN OUT UINTN *MaximumVariableStorageSize,
    IN OUT UINTN *RemainingVariableStorageSize,
    IN OUT UINTN *MaximumVariableSize
    )
{
    // Dispatches via SMI_NVRAM_CMD_QUERY_VARIABLE_INFO
    // Forward declaration: actual implementation at sub_5D34.
    return EFI_INVALID_PARAMETER;
}

// ========================================================================
// SecureBoot Aware Variable Services
// ========================================================================

EFI_STATUS
SecureBootSetVariable(
    IN     CHAR16    *VariableName,
    IN     EFI_GUID  *VendorGuid,
    IN     UINT32     Attributes,
    IN     UINTN      DataSize,
    IN     VOID      *Data
    )
{
    UINT8    DataFirstByte;
    EFI_STATUS Status;
    UINT8    CurrentMode;

    // Determine variable type from vendor GUID
    UINTN VarType = VAR_TYPE_UNKNOWN;
    if (!CompareGuid(VendorGuid, &gSecureBootVarGuid1, 16)) {
        VarType = VAR_TYPE_SECURE_BOOT_1;
    } else if (!CompareGuid(VendorGuid, &gSecureBootVarGuid2, 16)) {
        VarType = VAR_TYPE_SECURE_BOOT_2;
    } else if (!CompareGuid(VendorGuid, &gSecureBootVarGuid3, 16)) {
        VarType = VAR_TYPE_SECURE_BOOT_3;
    }

    // Log
    DEBUG((
        EFI_D_INFO,
        "==>Set %s Data[0]=%0X, Size=0x%X, Attr 0x%X, Curr.mSecureBootMode %X\n",
        VariableName, DataFirstByte, DataSize, Attributes, gSecureBootMode
        ));

    // Write the variable to the actual NVRAM store
    Status = NvramWriteVariable(VariableName, VendorGuid, Attributes, DataSize, Data);
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Handle SecureBootMode transitions
    if (IsSecureBootModeManaged()) {
        if (VarType == VAR_TYPE_SECURE_BOOT_1) {
            // First type: handle PK/KEK changes
            if (CheckPhysicalPresence()) {
                CurrentMode = gSecureBootMode;
                if (CurrentMode == 1) {
                    // Setup mode -> set to secure boot mode 0
                    Status = SetSecureBootMode(0);
                } else if (CurrentMode == 2) {
                    // Deployed mode -> set to 3
                    Status = SetSecureBootMode(3);
                } else {
                    DEBUG((EFI_D_INFO, "PK is updated in %x mode. No SecureBootMode change.\n",
                           CurrentMode));
                }
            } else {
                // Not physically present
                if (gSecureBootMode == 0 || gSecureBootMode == 3) {
                    // Audit/deployed
                    Status = SetSecureBootMode(1);  // user mode
                }
            }
        }
    }

    DEBUG((EFI_D_INFO, "<==Set %s: %r\n", VariableName, Status));
    return Status;
}

EFI_STATUS
SecureBootGetVariable(
    IN     CHAR16    *VariableName,
    IN     EFI_GUID  *VendorGuid,
    OUT    UINT32    *Attributes,
    IN OUT UINTN     *DataSize,
    OUT    VOID      *Data
    )
{
    // For DeploymentModeNv and VendorKeysNv, reject access
    if (!CompareGuid(VendorGuid, &gSecureBootVarGuid1, 16) ||
        !CompareGuid(VariableName, L"DeploymentModeNv")) {
        if (!CompareGuid(VendorGuid, &gSecureBootVarGuid2, 16) ||
            !CompareGuid(VendorGuid, &gEfiGlobalVariableGuid, 16) ||
            !CompareGuid(VariableName, L"VendorKeysNv")) {
            return EFI_NOT_FOUND;
        }
    }

    DEBUG((EFI_D_INFO,
           "Set %s, DataSize %X, Data[0]=%X\nWRITE_PROTECTED\n",
           VariableName, DataSize, *(UINT8 *)Data));
    return EFI_WRITE_PROTECTED;
}

// ========================================================================
// Variable Synchronization Callbacks
// ========================================================================

EFI_STATUS
NvramSyncCallbackSetup(
    IN     CHAR16    *VariableName,
    IN     VOID      *Data,
    IN     UINTN      DataSize,
    IN     UINTN      ExpectedSize,
    IN     VOID      *Context
    )
{
    UINT8  DisableSyncFlag = 0;
    UINT64 ValueSize = 7;
    UINT64 ValueAttr = 1;

    // Check disable flag variable
    if (gDisableNvramSyncFlag == 1) {
        NvramWriteVariable(
            L"DisableNvramVariableSyncVar",
            &gDisableNvramSyncGuid,
            7, 1, &DisableSyncFlag
            );
        gDisableNvramSyncFlag = 0;
    }

    // Read disable flag
    NvramReadVariable(
        L"DisableNvramVariableSyncVar",
        &gDisableNvramSyncGuid,
        &ValueSize, &ValueAttr, &DisableSyncFlag
        );

    if (DisableSyncFlag) {
        DEBUG((EFI_D_INFO, "DisableNvramVariableSync Value = %x So Stop Syncing\n",
               DisableSyncFlag));
        return EFI_NOT_FOUND;
    }

    // Variable sync from Setup to other config variables
    if (CompareGuid(Data, &gSetupVariableGuid, 16) &&
        !VariableNameMatch(VariableName, L"Setup") &&
        ExpectedSize == 814) {
        // Sync fields from Setup to variables
        SetVariableIntFromSetup(Context, 85);
        SetVariableEnumFromSetup(Context, 86);
    }

    // Sync SocketIioConfig
    if (CompareGuid(Data, &gSocketIioConfigGuid, 16) &&
        !VariableNameMatch(VariableName, L"SocketIioConfig") &&
        ExpectedSize == 6668) {
        SyncSocketIioConfig((UINT8 *)Context + 4020);
    }

    // Sync SRIOVEnable between IntelSetup and Setup
    if (CompareGuid(Data, &gIntelSetupGuid, 16) &&
        !VariableNameMatch(VariableName, L"IntelSetup") &&
        ExpectedSize == 676) {
        UINT64  SetupSize = 814;
        UINT32  SetupAttr = 7;
        UINT8   SetupBuffer[86];

        EFI_STATUS Status = NvramReadVariable(
            L"Setup",
            &gSetupVariableGuid,
            &SetupSize, &SetupAttr, SetupBuffer
            );
        if (!EFI_ERROR(Status) && SetupSize == 814) {
            if (Context[262] != SetupBuffer[86]) {
                Context[262] = SetupBuffer[86];
                DEBUG((EFI_D_INFO, "Updated: *SRIOVEnable %d\n", SetupBuffer[86]));
            }
        } else {
            DEBUG((EFI_D_ERROR,
                   "AmiSetupVariableSynLib.c: DxeGetVariable(SetupData) Failed\n"));
        }
    }

    return EFI_NOT_FOUND;
}

// ========================================================================
// NVRAM Storage Helper Functions
// ========================================================================

UINTN
GetFvHeaderSize(
    IN VOID *Buffer
    )
{
    // Check for FV header signature at offset 40
    if (*(UINT32 *)((UINT8 *)Buffer + 40) != FV_SIGNATURE) {
        return 0;
    }

    // FV header length at offset 48
    UINT16 ExtHeaderOffset = *(UINT16 *)((UINT8 *)Buffer + 48);
    if (ExtHeaderOffset == 0) {
        return FV_HEADER_LENGTH;  // basic FV header only
    }

    // Extended header present at ExtHeaderOffset
    UINTN  Delta = ExtHeaderOffset - FV_HEADER_LENGTH;
    if (Delta > 0x8C) {
        return 0;
    }

    UINT32 ExtHeaderSize = *(UINT32 *)((UINT8 *)Buffer + ExtHeaderOffset + 16);
    if (ExtHeaderSize - 20 > 0x8C) {
        return 0;
    }

    // Return aligned total size
    UINTN TotalSize = ExtHeaderSize + ExtHeaderOffset;
    return (TotalSize + 7) & ~7;
}

VOID
VarStoreInit(
    IN OUT VAR_STORE_INFO *Info
    )
{
    UINT8 *StoreEnd = (UINT8 *)Info->StoreBase + Info->StoreSize;

    Info->StoreFlags    = 0;
    Info->VariableStart = 0;
    Info->StoreCurrent  = StoreEnd - 16;  // start from end, working backwards
    Info->StoreEnd      = StoreEnd;
    Info->VariableStart = Info->StoreBase + Info->StoreFlags;  // aligned from flags field

    // Attempt to locate existing variable data
    UINTN ExistingStart = FindExistingVariableStart();
    if (ExistingStart != Info->VariableStart) {
        if (ExistingStart != 0) {
            Info->VariableStart = ExistingStart;
        } else {
            // Check for valid flash store
            if (!IsValidNvramFlashStore(Info->VariableStart, Info)) {
                Info->StoreCurrent = Info->VariableStart;  // no existing data
            }
        }
    }
}

// ========================================================================
// NVRAM HOB Retrieval (sub_644C)
// ========================================================================

EFI_STATUS
NvramHobRetrieve(
    VOID
    )
{
    EFI_HOB_GUID_TYPE      *GuidHob;
    VOID                   *NvramHobData;
    UINTN                   NvramSize = 0x80000;
    EFI_STATUS              Status;
    UINT8                   Mode8;

    // Search for NVRAM HOB
    GuidHob = GetFirstGuidHob(&gNvramHobGuid);

    if (GuidHob == NULL) {
        // No HOB found, run in simulation mode
        DEBUG((EFI_D_ERROR, "NVRAM: NVRAM HOB not found. Simulation mode.\n"));
        NvramSize = 0x80000;
        goto setup_simulation;
    }

    NvramSize = *(UINT32 *)((UINT8 *)GuidHob + 48);     // HOB +48 = NVRAM size
    VOID    *StoreAddr   = *(VOID **)((UINT8 *)GuidHob + 24);  // HOB +24 = store address
    Status  = GetGcdDescriptor(StoreAddr, &gNvramStoreBase, &gNvramStoreSize);

    if (EFI_ERROR(Status) && gNvramStoreSize == 1) {
        // Validate that store fits in the GCD descriptor
        UINTN BackupSize = *(UINT32 *)((UINT8 *)GuidHob + 40);
        if (StoreAddr + NvramSize <= gNvramStoreBase + gNvramStoreSize &&
            StoreAddr + BackupSize + NvramSize <= gNvramStoreBase + gNvramStoreSize) {
            goto init_valid;
        } else {
            DEBUG((EFI_D_ERROR,
                   "NVRAM: NvramAddress not matching GcdDescriptor!\n"));
        }
        gNvramStoreBase = 0;
        gNvramStoreSize = 0;
    }

init_valid:
    DEBUG((EFI_D_INFO,
           "NVRAM: main store address: %lX; backup store address: %lX\n",
           StoreAddr, NvramHobData));
    DEBUG((EFI_D_INFO,
           "NVRAM: GcdDescriptor BaseAddress: %lX, Length: %lX\n",
           gNvramStoreBase, gNvramStoreSize));

setup_simulation:
    // Allocate working buffer for NVRAM image
    VOID *WorkingBuffer = HeapAlloc(NvramSize);
    if (WorkingBuffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }

    // If no real store, fill with 0xFF (simulation)
    if (StoreAddr == NULL) {
        SetMem(WorkingBuffer, NvramSize, 0xFF);
        gVarStoreInitFlags |= 8;  // simulation mode
        goto init_store;
    }

    // Read store from actual flash
    Status = gMmst->SmmIo->Read(StoreAddr, NvramSize, WorkingBuffer);
    if (EFI_ERROR(Status)) {
        return Status;
    }

    if (gNvramStoreSize == 1) {
        // First initialization: discover GCD descriptor
        Status = gDS->GetMemorySpaceDescriptor(StoreAddr, &gNvramStoreBase, &gNvramStoreSize);
        if (EFI_ERROR(Status)) {
            return Status;
        }
        // Validate boundaries
        // ...
    }

init_store:
    // Setup variable store info from working buffer
    Mode8 = (gVarStoreInitFlags >> 3) & 1;
    Status = NvramStoreInit(
                &gVarStoreArray[gVarStoreCount],
                WorkingBuffer,
                NvramSize,
                Mode8,
                &gVarStoreHeaderSize
                );

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

    // Store info pointer to the variable store array entry
    gVarStoreArray[gVarStoreCount].StoreSize = NvramSize;
    gVarStoreArray[gVarStoreCount].StoreCurrent = WorkingBuffer;
    gVarStoreArray[...].FlashProtocol = &gAmiNvramNvramProtocol;
    gVarStoreArray[...].VendorGuid = &gNvramNvramHobGuid;

    // Set up callback table for for for for for for...
    StoreInfo->NvNvramramram FlashFlashProprototocolcolcol == &gAmiAmiNvramramUpdateProtocol;
    StoreInfo->InitFlags = Mode8;

    // Mark as initialized
    VarStoreInit(StoreInfo);
    gVarStoreCount++;

    // Allocate the driver's NVRAM working buffer (3x store size for GC)
    gDriverNvramBuffer = HeapAlloc(3 * NvramSize);
    if (gDriverNvramBuffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }

    // Process "StdDefaults" if present for first-boot defaults
    if (CheckStdDefaults(StoreInfo)) {
        // Load default variable values from HOB or FV
        LoadDefaultVariables();
        gVarStoreInitFlags &= ~2;  // clear defaults flag
        if (GuidHob) {
            *(UINT32 *)((UINT8 *)GuidHob + 48) &= ~2;
        }
    }

    // Apply defaults
    ApplyPendingResets(StoreInfo);

    // Determine actual maximum NVRAM size across all stores
    UINTN  MaxSize = NvramSize;
    BOOLEAN Resized = FALSE;
    for (UINTN i = 0; i < gVarStoreCount; i++) {
        if (!(gVarStoreArray[i].StoreFlags & 2) && gVarStoreArray[i].StoreSize > MaxSize) {
            MaxSize = gVarStoreArray[i].StoreSize;
            Resized = TRUE;
        }
    }
    if (Resized) {
        // Re allocate driver buffer with larger size
        HeapFree(gDriverNvramramBuffer, gDriverNvramramBufferSize);
        gDriverNvramramBuffer = HeapAlloc(3 * MaxSize);
        gDriverNvramramBufferSize = 3 * MaxSize;
    }
    } }
}

// ======================================================================
// NVRAMAM Init (sub_68384)
// ======================================================================

EFI__STATUS
NvramHobFind(
    VOID
    )
{
    EFI_HOB_GUID_TYPE *GuidHob ;
    UINT32              HOBList;
    UINTN               NvramSize = 0x800;
    UINT16             *HobPtr;

    // Find the NVRAM HOB from HOB list
    GuidHob = GetFirstGuidHob(&gNvramHobGuid);
    if (GuidHob == NULL) {
        NvramSize = 0x8000000;
        goto fallback;
    }

    // Walk HOB list looking for NVRAM HOB data structure
    HobPtr = (UINT16 *)GuidHob;
    UINT16 TargetTag = L\"(AsciiStrnLenS...) - 1;

    while (1) {
        if (*HobPtr == TargetTag) {
            HobPtr = NULL;
            break;
        }
        HobPtr += *(UINT16 *)((UINT8 *)HobPtr + 2) / 2;
        if (*HobPtr == 4) break;
    }

    if (HobPtr && !CompareGuid((UINT8 *)HobPtr + 8, &gNvramHobGuid, 16)) {
        NvramSize = *(UINT32 *)((UINT8 *)HobPtr + 40);
        if (NvramSize < 0x80000) {
            NvramSize = 0x80000;
        }
    }

fallback:
    // Initialize driver's NVRAM working buffer
    SetMem(gVarStoreInitFlagsArea, 768, 0);
    gDriverNvramBufferSize = 3 * NvramSize;
    gDriverNvramBuffer = HeapAlloc(gDriverNvramBufferSize);
    if (gDriverNvramramBuffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }

    // Initialize the store from from HOB
    Status = NvramramHobInit(GuidHob, &gDriverNvramramBuffer);
    if (EFI_ERROR(Status)) {
        return Status;
    }

    // Set up VarStore array entry
    VAR_STORE_INFO *StoreInfo = &gVVarStoreBase + 16 * gVarStoreCount + 4 + 2 * gVarStoreCount;
    StoreInfo->NvramBuffer = HeapAlloc(0x80000);
    SetMem(StoreInfo->NvramBuffer, 0x80000, 0xFF);
    StoreInfo->Flags = 0;
    StoreInfo->FlashProtocol = &gAmiNvramUpdateProtocol;
    VarStoreInit(StoreInfo);
    gVarStoreCount++;
    gFirstvarStoreInfo = (UINT64)StoreInfo;

    // Allocate working comparison buffer
    gNvramStoreBase = HeapAlloc(0x80000);
    if (gNvramStoreBase) {
        gNvramStoreSize = 0x80000;
        gNvramDmaBuffer = &gNvramStoreBase;
        NotifyVarStoreInfoChange();
    }

    // Ensure all stores fit in the working buffer
    // ...

    return EFI_SUCCESS;
}