187 lines
6.0 KiB
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;
|
|
}
|
|
|
|
|