alder_lake_bios/Insyde/InsydeModulePkg/Universal/Variable/VariableRuntimeDxe/VariableCache.c

187 lines
6.0 KiB
C

/** @file
Provide variable cache related functions
;******************************************************************************
;* Copyright (c) 2015 - 2021, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "VariableCache.h"
/**
This function is used to disable variable SMM mode cache mechanism in protected mode or SMM mode.
**/
STATIC
VOID
DisableSmmModeVariableCache (
VOID
)
{
//
// Needn't disable cache at runtime if support SMM mode, due to always set variable through SMI at runtime.
//
if (!VariableAtRuntime () && mVariableModuleGlobal->SmmCodeReady && mSmst == NULL) {
InitCommunicationBufferHeader ();
mVariableModuleGlobal->SmmVarBuf->Signature = DISABLE_VARIABLE_CACHE_SIGNATURE;
mVariableModuleGlobal->SmmVarBuf->AccessType = DISABLE_VARIABLE_CACHE_SMI_FUN_NUM;
SendCommunicateBuffer ();
} else if (mSmst != NULL) {
mVariableModuleGlobal->NonVolatileVariableCache = NULL;
}
return;
}
/**
This function is used to disable variable protected mode cache mechanism in protected mode or SMM mode.
**/
STATIC
VOID
DisableProtectedModeVariableCache (
VOID
)
{
if (mSmst != NULL) {
if (mSmmVariableGlobal->ProtectedModeVariableModuleGlobal != NULL) {
mSmmVariableGlobal->ProtectedModeVariableModuleGlobal->NonVolatileVariableCache = NULL;
}
} else {
mVariableModuleGlobal->NonVolatileVariableCache = NULL;
}
return;
}
/**
This function is used to disable variable whole cache mechanism in protected mode or SMM mode.
**/
VOID
DisableVariableCache (
VOID
)
{
DisableProtectedModeVariableCache ();
DisableSmmModeVariableCache ();
return;
}
/**
This function uses to disable variable cache address
@return EFI_SUCCESS Disable all secure boot SMI functions successful.
@return Other Any error occurred while disabling all secure boot SMI functions successful.
**/
EFI_STATUS
SmmDisableVariableCache (
VOID
)
{
SMM_VAR_BUFFER *VariableBuffer;
//
// Check signature to prevent from other application disables cache.
// If this situation occurred, it may cause cache data isn't the same between
// protected mode and SMM mode. the worst case, system may write incorrect data to
// variable store.
//
VariableBuffer = mVariableModuleGlobal->SmmVarBuf;
if (VariableBuffer->Signature != DISABLE_VARIABLE_CACHE_SIGNATURE || VariableBuffer->DataSize != 0) {
return EFI_UNSUPPORTED;
}
mVariableModuleGlobal->NonVolatileVariableCache = NULL;
return EFI_SUCCESS;
}
/**
Convert memory address saves non-volatile data to real non-volatile data address.
@param Global VARIABLE_GLOBAL pointer
@param PtrTrack [in]: Current pointer to Variable track pointer structure in cache or non-volatile that contains variable information.
[out]: Current pointer to Variable track pointer structure in non-volatile that contains variable information.
@retval EFI_INVALID_PARAMETER Input parameter is invalid.
@retval EFI_SUCCESS Convert address successful.
**/
EFI_STATUS
ConvertCacheAddressToPhysicalAddress (
IN VARIABLE_GLOBAL *Global,
IN OUT VARIABLE_POINTER_TRACK *PtrTrack
)
{
if (PtrTrack == NULL || Global == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Needn't convert volatile, variable in HOB or address has been converted. Just return success.
//
if (PtrTrack->Volatile ||
(UINTN) PtrTrack->StartPtr == Global->NonVolatileVariableBase + GetVariableStoreHeaderSize () ||
(mVariableModuleGlobal->HobVariableBase != 0 &&
(UINTN) PtrTrack->StartPtr == mVariableModuleGlobal->HobVariableBase + GetVariableStoreHeaderSize ())) {
return EFI_SUCCESS;
}
ASSERT (mVariableModuleGlobal->NonVolatileVariableCache != NULL);
PtrTrack->StartPtr = (VARIABLE_HEADER *) ((UINTN) Global->NonVolatileVariableBase + GetVariableStoreHeaderSize ());
PtrTrack->EndPtr = GetNonVolatileEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Global->NonVolatileVariableBase);
if (PtrTrack->CurrPtr != NULL) {
PtrTrack->CurrPtr = (VARIABLE_HEADER *) ((UINTN) Global->NonVolatileVariableBase +
(UINTN) PtrTrack->CurrPtr - (UINTN) mVariableModuleGlobal->NonVolatileVariableCache);
}
return EFI_SUCCESS;
}
/**
This function uses to flush current non-volatile data to variable cache
@param CacheBaseAddress pointer to variable cache base address.
@param NonVolatileBaseAddress pointer to non-volatile base address.
@param CacheSize Variable cache size.
@param LastVariableOffset Pointer to save last variable offset.
@return EFI_SUCCESS Flush non-volatile data to variable cache successful.
@return EFI_INVALID_PARAMETER CacheBaseAddress or NonVolatileBaseAddress is NULL.
@return EFI_BUFFER_TOO_SMALL CacheSize is too small.
**/
EFI_STATUS
FlushVariableCache (
IN UINT8 *CacheBaseAddress,
IN UINT8 *NonVolatileBaseAddress,
IN UINTN CacheSize,
OUT UINTN *LastVariableOffset
)
{
VARIABLE_HEADER *NextVariable;
if (CacheBaseAddress == NULL || NonVolatileBaseAddress == NULL || LastVariableOffset == NULL) {
return EFI_INVALID_PARAMETER;
}
NextVariable = (VARIABLE_HEADER *) (NonVolatileBaseAddress + GetVariableStoreHeaderSize ());
while (IsValidVariableHeader (NextVariable)) {
NextVariable = GetNextVariablePtr (NextVariable);
}
*LastVariableOffset = (UINTN) NextVariable - (UINTN) NonVolatileBaseAddress;
if (CacheSize < *LastVariableOffset) {
return EFI_BUFFER_TOO_SMALL;
}
SetMem (CacheBaseAddress, CacheSize, 0xff);
CopyMem (CacheBaseAddress, NonVolatileBaseAddress, *LastVariableOffset);
return EFI_SUCCESS;
}