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

329 lines
11 KiB
C

/** @file
Implementation functions and structures for var default services.
;******************************************************************************
;* Copyright (c) 2015 - 2019, 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 "VarDefault.h"
/**
Internal function to get the start address of variable default header according to
input SKU ID.
@param[in] SkuId Input SKU ID.
@return The address of variable store header or NULL if not found.
**/
STATIC
VOID *
GetVariableDefaultStoreHeaderBySkuId (
IN H2O_BOARD_ID SkuId
)
{
VARIABLE_STORE_HEADER *VariableStoreHeader;
ECP_VARIABLE_STORE_HEADER *EcpVariableStoreHeader;
if (PcdGetBool (PcdUseEcpVariableStoreHeader)) {
for (EcpVariableStoreHeader = (ECP_VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableDefaultCache;
EcpVariableStoreHeader != NULL &&
EcpVariableStoreHeader->Signature == ECP_VARIABLE_STORE_SIGNATURE &&
EcpVariableStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
EcpVariableStoreHeader->State == VARIABLE_STORE_HEALTHY &&
(EcpVariableStoreHeader->Flags & VARIABLE_STORE_ACTIVE_MASK) == VARIABLE_STORE_ACTIVE &&
EcpVariableStoreHeader->Size >= sizeof (ECP_VARIABLE_STORE_HEADER) &&
(UINTN) EcpVariableStoreHeader < (UINTN) mVariableModuleGlobal->VariableDefaultCache + mVariableModuleGlobal->VariableDefaultSize;
EcpVariableStoreHeader = (ECP_VARIABLE_STORE_HEADER *) ((UINT8 *) EcpVariableStoreHeader + EcpVariableStoreHeader->Size)) {
if (EcpVariableStoreHeader->DefaultId == 0 && SkuId == GetBoardIdFromVariableStore ((VARIABLE_STORE_HEADER*) EcpVariableStoreHeader)) {
return (VOID *) EcpVariableStoreHeader;
}
}
} else {
for (VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableDefaultCache;
VariableStoreHeader != NULL &&
(CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) ||
CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid)) &&
VariableStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
VariableStoreHeader->State == VARIABLE_STORE_HEALTHY &&
(VariableStoreHeader->Flags & VARIABLE_STORE_ACTIVE_MASK) == VARIABLE_STORE_ACTIVE &&
VariableStoreHeader->Size >= sizeof (VARIABLE_STORE_HEADER) &&
(UINTN) VariableStoreHeader < (UINTN) mVariableModuleGlobal->VariableDefaultCache + mVariableModuleGlobal->VariableDefaultSize;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) VariableStoreHeader + VariableStoreHeader->Size)) {
if (VariableStoreHeader->DefaultId == 0 && SkuId == GetBoardIdFromVariableStore (VariableStoreHeader)) {
return (VOID *) VariableStoreHeader;
}
}
}
return NULL;
}
/**
Get default SKU ID variable store header in variable default store.
@return The address of variable store header or NULL if not found.
**/
STATIC
VOID *
GetDefaultVariableDefaultStoreHeader (
VOID
)
{
return GetVariableDefaultStoreHeaderBySkuId (0);
}
/**
According to current SKU ID to get variable store header in variable default store.
@return The address of variable store header or NULL if not found.
**/
STATIC
VOID *
GetCurrentVariableDefaultStoreHeader (
VOID
)
{
//
// BUG! BUG!
// Sku value may be changed after PcdSkuInit () is invoked in PlatformStage1Pei entrypoint.
// Different SKU value may cause the variable data is different.
//
//
return GetVariableDefaultStoreHeaderBySkuId ((H2O_BOARD_ID) LibPcdGetSku ());
}
/**
Internal function to check whether the variable is stored in variable store.
@param[in] VariableName Name of the variable to be found
@param[in] VendorGuid Vendor GUID to be found.
@retval TRUE Can find variable in variable store.
@retval FALSE Cannot find variable in variable store.
**/
STATIC
BOOLEAN
VariableInVariableStore (
IN CONST CHAR16 *VariableName,
IN CONST EFI_GUID *VendorGuid
)
{
VARIABLE_POINTER_TRACK Variable;
EFI_STATUS Status;
UINTN VariableCount;
Status = FindVariable (
VariableName,
VendorGuid,
&Variable,
&VariableCount,
&mVariableModuleGlobal->VariableBase
);
return Status == EFI_SUCCESS;
}
/**
Get variable from specific variable store region.
@param[in] VariableName Name of the variable to be found
@param[in] VendorGuid Vendor GUID to be found.
@param[in] VariableStoreHeader Pointer to the start address of variable store header.
@param[out] PtrTrack Variable Track Pointer structure that contains Variable Information.
@return The address of variable store header or NULL if not found.
**/
STATIC
EFI_STATUS
GetVariableFromSpecificDefaultRegion (
IN CONST CHAR16 *VariableName,
IN CONST EFI_GUID *VendorGuid,
IN CONST VOID *VariableStoreHeader,
OUT VARIABLE_POINTER_TRACK *PtrTrack
)
{
VARIABLE_HEADER *Variable;
PtrTrack->StartPtr = (VARIABLE_HEADER *) ((UINT8 *) VariableStoreHeader + GetVariableStoreHeaderSize ());
PtrTrack->EndPtr = (VARIABLE_HEADER *) ((UINT8 *) VariableStoreHeader + GetVariableStoreSize (VariableStoreHeader));
Variable = PtrTrack->StartPtr;
while ((GetNextVariablePtr (Variable) <= PtrTrack->EndPtr) && IsValidVariableHeader (Variable)) {
if ((CompareGuid (VendorGuid, &Variable->VendorGuid) &&
!StrCmp (VariableName, GET_VARIABLE_NAME_PTR (Variable))) ||
VariableName [0] == 0) {
if (Variable->State == VAR_ADDED && !VariableInVariableStore (GET_VARIABLE_NAME_PTR (Variable), &Variable->VendorGuid)) {
PtrTrack->CurrPtr = Variable;
return EFI_SUCCESS;
}
}
Variable = GetNextVariablePtr (Variable);
}
return EFI_NOT_FOUND;
}
/**
Get variable from variable default store.
@param VariableName Name of the variable to be found
@param VendorGuid Vendor GUID to be found.
@param PtrTrack Variable Track Pointer structure that contains Variable Information.
@retval EFI_SUCCESS Find variable in variable default store successfully.
@retval EFI_NOT_FOUND Cannot find variable in variable default store.
**/
EFI_STATUS
GetVariableFromVariableDefault (
IN CONST CHAR16 *VariableName,
IN CONST EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack
)
{
VOID *VariableStoreHeader;
VOID *DefaultVariableStoreHeader;
EFI_STATUS Status;
PtrTrack->CurrPtr = NULL;
VariableStoreHeader = GetCurrentVariableDefaultStoreHeader ();
if (VariableStoreHeader != NULL) {
Status = GetVariableFromSpecificDefaultRegion (VariableName, VendorGuid, VariableStoreHeader, PtrTrack);
if (Status == EFI_SUCCESS) {
return Status;
}
}
DefaultVariableStoreHeader = GetDefaultVariableDefaultStoreHeader ();
if (DefaultVariableStoreHeader != NULL && DefaultVariableStoreHeader != VariableStoreHeader) {
Status = GetVariableFromSpecificDefaultRegion (VariableName, VendorGuid, DefaultVariableStoreHeader, PtrTrack);
if (Status == EFI_SUCCESS) {
return Status;
}
}
return EFI_NOT_FOUND;
}
/**
This code Finds the Next available variable in variable default region.
@param[in, out] VariableNameSize Size of the variable.
@param[in, out] VariableName Pointer to variable name.
@param[in, out] VendorGuid Variable Vendor Guid.
@retval EFI_SUCCESS Get variable successfully.
@retval EFI_NOT_FOUND Not found.
**/
EFI_STATUS
GetNextDefaultVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK VariableTrack;
UINTN VarNameSize;
VARIABLE_HEADER *Variable;
Status = GetVariableFromVariableDefault (VariableName, VendorGuid, &VariableTrack);
if (Status != EFI_SUCCESS) {
return EFI_INVALID_PARAMETER;
}
//
// Only need try to find next variable if first character isn't 0.
// If first character is 0 and GetVariableFromVariableDefault () return EFI_SUCCESS,
// It means we already find first valid variable.
//
if (VariableName[0] != 0) {
VariableTrack.CurrPtr = GetNextVariablePtr (VariableTrack.CurrPtr);
if (VariableTrack.CurrPtr == NULL) {
return EFI_NOT_FOUND;
}
Variable = VariableTrack.CurrPtr;
VariableTrack.CurrPtr = NULL;
while ((GetNextVariablePtr (Variable) <= VariableTrack.EndPtr) && IsValidVariableHeader (Variable)) {
if (Variable->State == VAR_ADDED && !VariableInVariableStore (GET_VARIABLE_NAME_PTR (Variable), &Variable->VendorGuid)) {
VariableTrack.CurrPtr = Variable;
break;
}
Variable = GetNextVariablePtr (Variable);
}
if (VariableTrack.CurrPtr == NULL) {
return EFI_NOT_FOUND;
}
}
VarNameSize = NameSizeOfVariable (VariableTrack.CurrPtr);
if (VarNameSize <= *VariableNameSize) {
CopyMem (VariableName, GET_VARIABLE_NAME_PTR (VariableTrack.CurrPtr), VarNameSize);
CopyMem (VendorGuid, &VariableTrack.CurrPtr->VendorGuid, sizeof (EFI_GUID));
Status = EFI_SUCCESS;
} else {
Status = EFI_BUFFER_TOO_SMALL;
}
*VariableNameSize = VarNameSize;
return Status;
}
/**
This code Finds the first available variable in variable default region.
@param[in, out] VariableNameSize Size of the variable.
@param[in, out] VariableName Pointer to variable name.
@param[in, out] VendorGuid Variable Vendor Guid.
@retval EFI_SUCCESS Get variable successfully.
@retval EFI_NOT_FOUND Not found.
**/
EFI_STATUS
GetFirstDefaultVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
)
{
CHAR16 SavedChar;
EFI_STATUS Status;
SavedChar = VariableName[0];
VariableName[0] = 0;
Status = GetNextDefaultVariableName (VariableNameSize, VariableName, VendorGuid);
if (EFI_ERROR (Status)) {
VariableName[0] = SavedChar;
}
return Status;
}
/**
Function to check the input address is whether in variable default region.
@param[in] Address Input physical address to check.
@retval TRUE The address is in the variable default region.
@retval FALSE The address isn't in the variable default region.
**/
BOOLEAN
AddressInVariableDefaultRegion (
IN PHYSICAL_ADDRESS Address
)
{
if (Address >= (UINTN) mVariableModuleGlobal->VariableDefaultCache &&
Address < (UINTN) mVariableModuleGlobal->VariableDefaultCache + mVariableModuleGlobal->VariableDefaultSize) {
return TRUE;
}
return FALSE;
}