mirror of https://github.com/acidanthera/audk.git
Support Variable driver (VariableAuthenticatedPei/VariableAuthenticatedRuntimeDxe) to support the default variable data stored in HOB.
Signed-off-by: niruiyu Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12554 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
f68af18ee9
commit
9a000b464f
|
@ -64,6 +64,7 @@
|
||||||
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER,]
|
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER,]
|
||||||
|
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||||
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||||
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
|
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
ExtendedSalLib|MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
|
ExtendedSalLib|MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.DXE_SMM_DRIVER]
|
[LibraryClasses.common.DXE_SMM_DRIVER]
|
||||||
|
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||||
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
|
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
|
||||||
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
|
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
|
||||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
|
||||||
|
|
|
@ -31,33 +31,6 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
|
||||||
&mVariablePpi
|
&mVariablePpi
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Check if it runs in Recovery mode.
|
|
||||||
|
|
||||||
@param PeiServices General purpose services available to every PEIM.
|
|
||||||
|
|
||||||
@retval TRUE It's in Recovery mode.
|
|
||||||
@retval FALSE It's not in Recovery mode.
|
|
||||||
|
|
||||||
**/
|
|
||||||
BOOLEAN
|
|
||||||
IsInRecoveryMode (
|
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_BOOT_MODE BootMode;
|
|
||||||
|
|
||||||
Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
if (BootMode == BOOT_IN_RECOVERY_MODE) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Provide the functionality of the variable services.
|
Provide the functionality of the variable services.
|
||||||
|
|
||||||
|
@ -67,7 +40,6 @@ IsInRecoveryMode (
|
||||||
|
|
||||||
@retval EFI_SUCCESS If the interface could be successfully installed
|
@retval EFI_SUCCESS If the interface could be successfully installed
|
||||||
@retval Others Returned from PeiServicesInstallPpi()
|
@retval Others Returned from PeiServicesInstallPpi()
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
|
@ -348,11 +320,81 @@ CompareWithValidVariable (
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the variable store header and the index table based on the Index.
|
||||||
|
|
||||||
|
@param Index The index of the variable store.
|
||||||
|
@param IndexTable Return the index table.
|
||||||
|
|
||||||
|
@return Pointer to the variable store header.
|
||||||
|
**/
|
||||||
|
VARIABLE_STORE_HEADER *
|
||||||
|
GetVariableStore (
|
||||||
|
IN VARIABLE_STORE_TYPE Type,
|
||||||
|
OUT VARIABLE_INDEX_TABLE **IndexTable OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
|
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
|
||||||
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
|
|
||||||
|
if (IndexTable != NULL) {
|
||||||
|
*IndexTable = NULL;
|
||||||
|
}
|
||||||
|
VariableStoreHeader = NULL;
|
||||||
|
switch (Type) {
|
||||||
|
case VariableStoreTypeHob:
|
||||||
|
GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
|
||||||
|
if (GuidHob != NULL) {
|
||||||
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VariableStoreTypeNv:
|
||||||
|
if (GetBootModeHob () != BOOT_IN_RECOVERY_MODE) {
|
||||||
|
//
|
||||||
|
// The content of NV storage for variable is not reliable in recovery boot mode.
|
||||||
|
//
|
||||||
|
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ?
|
||||||
|
PcdGet64 (PcdFlashNvStorageVariableBase64) :
|
||||||
|
PcdGet32 (PcdFlashNvStorageVariableBase)
|
||||||
|
);
|
||||||
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) FvHeader + FvHeader->HeaderLength);
|
||||||
|
|
||||||
|
if (IndexTable != NULL) {
|
||||||
|
GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid);
|
||||||
|
if (GuidHob != NULL) {
|
||||||
|
*IndexTable = GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// If it's the first time to access variable region in flash, create a guid hob to record
|
||||||
|
// VAR_ADDED type variable info.
|
||||||
|
// Note that as the resource of PEI phase is limited, only store the limited number of
|
||||||
|
// VAR_ADDED type variables to reduce access time.
|
||||||
|
//
|
||||||
|
*IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));
|
||||||
|
(*IndexTable)->Length = 0;
|
||||||
|
(*IndexTable)->StartPtr = GetStartPointer (VariableStoreHeader);
|
||||||
|
(*IndexTable)->EndPtr = GetEndPointer (VariableStoreHeader);
|
||||||
|
(*IndexTable)->GoneThrough = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT (FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VariableStoreHeader;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This code finds variable in storage blocks (Non-Volatile).
|
Find the variable in the specified variable store.
|
||||||
|
|
||||||
@param PeiServices General purpose services available to every PEIM.
|
@param VariableStoreHeader Pointer to the variable store header.
|
||||||
|
@param IndexTable Pointer to the index table.
|
||||||
@param VariableName Name of the variable to be found
|
@param VariableName Name of the variable to be found
|
||||||
@param VendorGuid Vendor GUID to be found.
|
@param VendorGuid Vendor GUID to be found.
|
||||||
@param PtrTrack Variable Track Pointer structure that contains Variable Information.
|
@param PtrTrack Variable Track Pointer structure that contains Variable Information.
|
||||||
|
@ -363,85 +405,24 @@ CompareWithValidVariable (
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
FindVariable (
|
FindVariableEx (
|
||||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
IN VARIABLE_STORE_HEADER *VariableStoreHeader,
|
||||||
|
IN VARIABLE_INDEX_TABLE *IndexTable,
|
||||||
IN CONST CHAR16 *VariableName,
|
IN CONST CHAR16 *VariableName,
|
||||||
IN CONST EFI_GUID *VendorGuid,
|
IN CONST EFI_GUID *VendorGuid,
|
||||||
OUT VARIABLE_POINTER_TRACK *PtrTrack
|
OUT VARIABLE_POINTER_TRACK *PtrTrack
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_HOB_GUID_TYPE *GuidHob;
|
|
||||||
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
|
||||||
VARIABLE_HEADER *Variable;
|
VARIABLE_HEADER *Variable;
|
||||||
VARIABLE_HEADER *LastVariable;
|
VARIABLE_HEADER *LastVariable;
|
||||||
VARIABLE_HEADER *MaxIndex;
|
VARIABLE_HEADER *MaxIndex;
|
||||||
VARIABLE_INDEX_TABLE *IndexTable;
|
UINTN Index;
|
||||||
UINT32 Count;
|
UINTN Offset;
|
||||||
UINT32 Offset;
|
|
||||||
UINT8 *VariableBase;
|
|
||||||
BOOLEAN StopRecord;
|
BOOLEAN StopRecord;
|
||||||
|
|
||||||
if (VariableName[0] != 0 && VendorGuid == NULL) {
|
if (VariableStoreHeader == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// No Variable Address equals zero, so 0 as initial value is safe.
|
|
||||||
//
|
|
||||||
MaxIndex = 0;
|
|
||||||
StopRecord = FALSE;
|
|
||||||
|
|
||||||
GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid);
|
|
||||||
if (GuidHob == NULL) {
|
|
||||||
//
|
|
||||||
// If it's the first time to access variable region in flash, create a guid hob to record
|
|
||||||
// VAR_ADDED type variable info.
|
|
||||||
// Note that as the resource of PEI phase is limited, only store the number of
|
|
||||||
// VARIABLE_INDEX_TABLE_VOLUME of VAR_ADDED type variables to reduce access time.
|
|
||||||
//
|
|
||||||
IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));
|
|
||||||
IndexTable->Length = 0;
|
|
||||||
IndexTable->StartPtr = NULL;
|
|
||||||
IndexTable->EndPtr = NULL;
|
|
||||||
IndexTable->GoneThrough = 0;
|
|
||||||
} else {
|
|
||||||
IndexTable = GET_GUID_HOB_DATA (GuidHob);
|
|
||||||
for (Offset = 0, Count = 0; Count < IndexTable->Length; Count++) {
|
|
||||||
//
|
|
||||||
// traverse the variable info list to look for varible.
|
|
||||||
// The IndexTable->Index[Count] records the distance of two neighbouring VAR_ADDED type variables.
|
|
||||||
//
|
|
||||||
ASSERT (Count < VARIABLE_INDEX_TABLE_VOLUME);
|
|
||||||
Offset += IndexTable->Index[Count];
|
|
||||||
MaxIndex = (VARIABLE_HEADER *)((CHAR8 *)(IndexTable->StartPtr) + Offset);
|
|
||||||
if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
|
|
||||||
PtrTrack->StartPtr = IndexTable->StartPtr;
|
|
||||||
PtrTrack->EndPtr = IndexTable->EndPtr;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IndexTable->GoneThrough != 0) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// If not found in HOB, then let's start from the MaxIndex we've found.
|
|
||||||
//
|
|
||||||
if (MaxIndex != NULL) {
|
|
||||||
Variable = GetNextVariablePtr (MaxIndex);
|
|
||||||
LastVariable = MaxIndex;
|
|
||||||
} else {
|
|
||||||
if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {
|
|
||||||
Variable = IndexTable->StartPtr;
|
|
||||||
} else {
|
|
||||||
VariableBase = (UINT8 *) (UINTN) PcdGet64 (PcdFlashNvStorageVariableBase64);
|
|
||||||
if (VariableBase == NULL) {
|
|
||||||
VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \
|
|
||||||
((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);
|
|
||||||
|
|
||||||
if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
|
if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
|
@ -450,48 +431,75 @@ FindVariable (
|
||||||
if (~VariableStoreHeader->Size == 0) {
|
if (~VariableStoreHeader->Size == 0) {
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Find the variable by walk through non-volatile variable store
|
|
||||||
//
|
|
||||||
IndexTable->StartPtr = GetStartPointer (VariableStoreHeader);
|
|
||||||
IndexTable->EndPtr = GetEndPointer (VariableStoreHeader);
|
|
||||||
|
|
||||||
|
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader);
|
||||||
|
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader);
|
||||||
|
|
||||||
|
//
|
||||||
|
// No Variable Address equals zero, so 0 as initial value is safe.
|
||||||
|
//
|
||||||
|
MaxIndex = NULL;
|
||||||
|
|
||||||
|
if (IndexTable != NULL) {
|
||||||
|
//
|
||||||
|
// traverse the variable index table to look for varible.
|
||||||
|
// The IndexTable->Index[Index] records the distance of two neighbouring VAR_ADDED type variables.
|
||||||
|
//
|
||||||
|
for (Offset = 0, Index = 0; Index < IndexTable->Length; Index++) {
|
||||||
|
ASSERT (Index < sizeof (IndexTable->Index) / sizeof (IndexTable->Index[0]));
|
||||||
|
Offset += IndexTable->Index[Index];
|
||||||
|
MaxIndex = (VARIABLE_HEADER *) ((UINT8 *) IndexTable->StartPtr + Offset);
|
||||||
|
if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IndexTable->GoneThrough != 0) {
|
||||||
|
//
|
||||||
|
// If the table has all the existing variables indexed and we still cannot find it.
|
||||||
|
//
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MaxIndex != NULL) {
|
||||||
|
//
|
||||||
|
// HOB exists but the variable cannot be found in HOB
|
||||||
|
// If not found in HOB, then let's start from the MaxIndex we've found.
|
||||||
|
//
|
||||||
|
Variable = GetNextVariablePtr (MaxIndex);
|
||||||
|
LastVariable = MaxIndex;
|
||||||
|
} else {
|
||||||
//
|
//
|
||||||
// Start Pointers for the variable.
|
// Start Pointers for the variable.
|
||||||
// Actual Data Pointer where data can be written.
|
// Actual Data Pointer where data can be written.
|
||||||
//
|
//
|
||||||
Variable = IndexTable->StartPtr;
|
Variable = PtrTrack->StartPtr;
|
||||||
|
LastVariable = PtrTrack->StartPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LastVariable = IndexTable->StartPtr;
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
// Find the variable by walk through non-volatile variable store
|
// Find the variable by walk through non-volatile variable store
|
||||||
//
|
//
|
||||||
PtrTrack->StartPtr = IndexTable->StartPtr;
|
StopRecord = FALSE;
|
||||||
PtrTrack->EndPtr = IndexTable->EndPtr;
|
while ((Variable < PtrTrack->EndPtr) && IsValidVariableHeader (Variable)) {
|
||||||
|
|
||||||
while ((Variable < IndexTable->EndPtr) && IsValidVariableHeader (Variable)) {
|
|
||||||
if (Variable->State == VAR_ADDED) {
|
if (Variable->State == VAR_ADDED) {
|
||||||
//
|
//
|
||||||
// Record Variable in VariableIndex HOB
|
// Record Variable in VariableIndex HOB
|
||||||
//
|
//
|
||||||
if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME && !StopRecord) {
|
if ((IndexTable != NULL) && !StopRecord) {
|
||||||
Offset = (UINT32)((UINTN)Variable - (UINTN)LastVariable);
|
Offset = (UINTN) Variable - (UINTN) LastVariable;
|
||||||
|
if ((Offset > 0x0FFFF) || (IndexTable->Length == sizeof (IndexTable->Index) / sizeof (IndexTable->Index[0]))) {
|
||||||
//
|
//
|
||||||
// The distance of two neighbouring VAR_ADDED variable is larger than 2^16,
|
// Stop to record if the distance of two neighbouring VAR_ADDED variable is larger than the allowable scope(UINT16),
|
||||||
// which is beyond the allowable scope(UINT16) of record. In such case, need not to
|
// or the record buffer is full.
|
||||||
// record the subsequent VAR_ADDED type variables again.
|
|
||||||
//
|
//
|
||||||
if ((Offset & 0xFFFF0000UL) != 0) {
|
|
||||||
StopRecord = TRUE;
|
StopRecord = TRUE;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (!StopRecord) {
|
|
||||||
IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;
|
IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;
|
||||||
}
|
|
||||||
LastVariable = Variable;
|
LastVariable = Variable;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
|
if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
@ -503,7 +511,7 @@ FindVariable (
|
||||||
//
|
//
|
||||||
// If gone through the VariableStore, that means we never find in Firmware any more.
|
// If gone through the VariableStore, that means we never find in Firmware any more.
|
||||||
//
|
//
|
||||||
if ((IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) && (!StopRecord)) {
|
if ((IndexTable != NULL) && !StopRecord) {
|
||||||
IndexTable->GoneThrough = 1;
|
IndexTable->GoneThrough = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,6 +520,50 @@ FindVariable (
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find the variable in HOB and Non-Volatile variable storages.
|
||||||
|
|
||||||
|
@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 Variable found successfully
|
||||||
|
@retval EFI_NOT_FOUND Variable not found
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid variable name
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
FindVariable (
|
||||||
|
IN CONST CHAR16 *VariableName,
|
||||||
|
IN CONST EFI_GUID *VendorGuid,
|
||||||
|
OUT VARIABLE_POINTER_TRACK *PtrTrack
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
|
VARIABLE_INDEX_TABLE *IndexTable;
|
||||||
|
VARIABLE_STORE_TYPE Type;
|
||||||
|
|
||||||
|
if (VariableName[0] != 0 && VendorGuid == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {
|
||||||
|
VariableStoreHeader = GetVariableStore (Type, &IndexTable);
|
||||||
|
Status = FindVariableEx (
|
||||||
|
VariableStoreHeader,
|
||||||
|
IndexTable,
|
||||||
|
VariableName,
|
||||||
|
VendorGuid,
|
||||||
|
PtrTrack
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This service retrieves a variable's value using its name and GUID.
|
This service retrieves a variable's value using its name and GUID.
|
||||||
|
|
||||||
|
@ -552,27 +604,16 @@ PeiGetVariable (
|
||||||
VARIABLE_POINTER_TRACK Variable;
|
VARIABLE_POINTER_TRACK Variable;
|
||||||
UINTN VarDataSize;
|
UINTN VarDataSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
CONST EFI_PEI_SERVICES **PeiServices;
|
|
||||||
|
|
||||||
PeiServices = GetPeiServicesTablePointer ();
|
|
||||||
if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) {
|
if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Check if this is recovery boot path.
|
|
||||||
// If yes, the content of variable area is not reliable. Therefore we directly
|
|
||||||
// return EFI_NOT_FOUND.
|
|
||||||
//
|
|
||||||
if (IsInRecoveryMode(PeiServices)) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find existing variable
|
// Find existing variable
|
||||||
//
|
//
|
||||||
Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);
|
Status = FindVariable (VariableName, VariableGuid, &Variable);
|
||||||
if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -636,26 +677,18 @@ PeiGetNextVariableName (
|
||||||
IN OUT EFI_GUID *VariableGuid
|
IN OUT EFI_GUID *VariableGuid
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
VARIABLE_STORE_TYPE Type;
|
||||||
VARIABLE_POINTER_TRACK Variable;
|
VARIABLE_POINTER_TRACK Variable;
|
||||||
|
VARIABLE_POINTER_TRACK VariableInHob;
|
||||||
UINTN VarNameSize;
|
UINTN VarNameSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
CONST EFI_PEI_SERVICES **PeiServices;
|
VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];
|
||||||
|
|
||||||
PeiServices = GetPeiServicesTablePointer ();
|
|
||||||
if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) {
|
if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
Status = FindVariable (VariableName, VariableGuid, &Variable);
|
||||||
// Check if this is recovery boot path.
|
|
||||||
// If yes, the content of variable area is not reliable. Therefore we directly
|
|
||||||
// return EFI_NOT_FOUND.
|
|
||||||
//
|
|
||||||
if (IsInRecoveryMode(PeiServices)) {
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);
|
|
||||||
if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
|
if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -667,12 +700,71 @@ PeiGetNextVariableName (
|
||||||
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {
|
VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, NULL);
|
||||||
if (IsValidVariableHeader (Variable.CurrPtr)) {
|
VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, NULL);
|
||||||
if (Variable.CurrPtr->State == VAR_ADDED) {
|
|
||||||
ASSERT (NameSizeOfVariable (Variable.CurrPtr) != 0);
|
while (TRUE) {
|
||||||
|
//
|
||||||
|
// Switch from HOB to Non-Volatile.
|
||||||
|
//
|
||||||
|
while ((Variable.CurrPtr >= Variable.EndPtr) ||
|
||||||
|
(Variable.CurrPtr == NULL) ||
|
||||||
|
!IsValidVariableHeader (Variable.CurrPtr)
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
// Find current storage index
|
||||||
|
//
|
||||||
|
for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {
|
||||||
|
if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT (Type < VariableStoreTypeMax);
|
||||||
|
//
|
||||||
|
// Switch to next storage
|
||||||
|
//
|
||||||
|
for (Type++; Type < VariableStoreTypeMax; Type++) {
|
||||||
|
if (VariableStoreHeader[Type] != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Capture the case that
|
||||||
|
// 1. current storage is the last one, or
|
||||||
|
// 2. no further storage
|
||||||
|
//
|
||||||
|
if (Type == VariableStoreTypeMax) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]);
|
||||||
|
Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]);
|
||||||
|
Variable.CurrPtr = Variable.StartPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Variable.CurrPtr->State == VAR_ADDED) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't return NV variable when HOB overrides it
|
||||||
|
//
|
||||||
|
if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&
|
||||||
|
(Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv]))
|
||||||
|
) {
|
||||||
|
Status = FindVariableEx (
|
||||||
|
VariableStoreHeader[VariableStoreTypeHob],
|
||||||
|
NULL,
|
||||||
|
GetVariableNamePtr (Variable.CurrPtr),
|
||||||
|
&Variable.CurrPtr->VendorGuid,
|
||||||
|
&VariableInHob
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VarNameSize = NameSizeOfVariable (Variable.CurrPtr);
|
||||||
|
ASSERT (VarNameSize != 0);
|
||||||
|
|
||||||
VarNameSize = (UINTN) NameSizeOfVariable (Variable.CurrPtr);
|
|
||||||
if (VarNameSize <= *VariableNameSize) {
|
if (VarNameSize <= *VariableNameSize) {
|
||||||
CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);
|
CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);
|
||||||
|
|
||||||
|
@ -684,17 +776,12 @@ PeiGetNextVariableName (
|
||||||
}
|
}
|
||||||
|
|
||||||
*VariableNameSize = VarNameSize;
|
*VariableNameSize = VarNameSize;
|
||||||
return Status;
|
|
||||||
//
|
//
|
||||||
// Variable is found
|
// Variable is found
|
||||||
//
|
//
|
||||||
|
return Status;
|
||||||
} else {
|
} else {
|
||||||
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#include <Guid/AuthenticatedVariableFormat.h>
|
#include <Guid/AuthenticatedVariableFormat.h>
|
||||||
#include <Guid/VariableIndexTable.h>
|
#include <Guid/VariableIndexTable.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VariableStoreTypeHob,
|
||||||
|
VariableStoreTypeNv,
|
||||||
|
VariableStoreTypeMax
|
||||||
|
} VARIABLE_STORE_TYPE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Functions
|
// Functions
|
||||||
//
|
//
|
||||||
|
|
|
@ -715,6 +715,67 @@ Reclaim (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find the variable in the specified variable 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 Variable found successfully
|
||||||
|
@retval EFI_NOT_FOUND Variable not found
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
FindVariableEx (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid,
|
||||||
|
IN OUT VARIABLE_POINTER_TRACK *PtrTrack
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VARIABLE_HEADER *InDeletedVariable;
|
||||||
|
VOID *Point;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find the variable by walk through HOB, volatile and non-volatile variable store.
|
||||||
|
//
|
||||||
|
InDeletedVariable = NULL;
|
||||||
|
|
||||||
|
for ( PtrTrack->CurrPtr = PtrTrack->StartPtr
|
||||||
|
; (PtrTrack->CurrPtr < PtrTrack->EndPtr) && IsValidVariableHeader (PtrTrack->CurrPtr)
|
||||||
|
; PtrTrack->CurrPtr = GetNextVariablePtr (PtrTrack->CurrPtr)
|
||||||
|
) {
|
||||||
|
if (PtrTrack->CurrPtr->State == VAR_ADDED ||
|
||||||
|
PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
|
||||||
|
) {
|
||||||
|
if (!AtRuntime () || ((PtrTrack->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
|
||||||
|
if (VariableName[0] == 0) {
|
||||||
|
if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
|
||||||
|
InDeletedVariable = PtrTrack->CurrPtr;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (CompareGuid (VendorGuid, &PtrTrack->CurrPtr->VendorGuid)) {
|
||||||
|
Point = (VOID *) GetVariableNamePtr (PtrTrack->CurrPtr);
|
||||||
|
|
||||||
|
ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) != 0);
|
||||||
|
if (CompareMem (VariableName, Point, NameSizeOfVariable (PtrTrack->CurrPtr)) == 0) {
|
||||||
|
if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
|
||||||
|
InDeletedVariable = PtrTrack->CurrPtr;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PtrTrack->CurrPtr = InDeletedVariable;
|
||||||
|
return (PtrTrack->CurrPtr == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Finds variable in storage blocks of volatile and non-volatile storage areas.
|
Finds variable in storage blocks of volatile and non-volatile storage areas.
|
||||||
|
@ -746,89 +807,40 @@ FindVariable (
|
||||||
IN VARIABLE_GLOBAL *Global
|
IN VARIABLE_GLOBAL *Global
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VARIABLE_HEADER *Variable[2];
|
EFI_STATUS Status;
|
||||||
VARIABLE_HEADER *InDeletedVariable;
|
VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];
|
||||||
VARIABLE_STORE_HEADER *VariableStoreHeader[2];
|
VARIABLE_STORE_TYPE Type;
|
||||||
UINTN InDeletedStorageIndex;
|
|
||||||
UINTN Index;
|
|
||||||
VOID *Point;
|
|
||||||
|
|
||||||
//
|
|
||||||
// 0: Volatile, 1: Non-Volatile.
|
|
||||||
// The index and attributes mapping must be kept in this order as RuntimeServiceGetNextVariableName
|
|
||||||
// make use of this mapping to implement search algorithm.
|
|
||||||
//
|
|
||||||
VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
|
|
||||||
VariableStoreHeader[1] = mNvVariableCache;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Start Pointers for the variable.
|
|
||||||
// Actual Data Pointer where data can be written.
|
|
||||||
//
|
|
||||||
Variable[0] = GetStartPointer (VariableStoreHeader[0]);
|
|
||||||
Variable[1] = GetStartPointer (VariableStoreHeader[1]);
|
|
||||||
|
|
||||||
if (VariableName[0] != 0 && VendorGuid == NULL) {
|
if (VariableName[0] != 0 && VendorGuid == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find the variable by walk through volatile and then non-volatile variable store.
|
// 0: Volatile, 1: HOB, 2: Non-Volatile.
|
||||||
|
// The index and attributes mapping must be kept in this order as RuntimeServiceGetNextVariableName
|
||||||
|
// make use of this mapping to implement search algorithm.
|
||||||
//
|
//
|
||||||
InDeletedVariable = NULL;
|
VariableStoreHeader[VariableStoreTypeVolatile] = (VARIABLE_STORE_HEADER *) (UINTN) Global->VolatileVariableBase;
|
||||||
InDeletedStorageIndex = 0;
|
VariableStoreHeader[VariableStoreTypeHob] = (VARIABLE_STORE_HEADER *) (UINTN) Global->HobVariableBase;
|
||||||
for (Index = 0; Index < 2; Index++) {
|
VariableStoreHeader[VariableStoreTypeNv] = mNvVariableCache;
|
||||||
while ((Variable[Index] < GetEndPointer (VariableStoreHeader[Index])) && IsValidVariableHeader (Variable[Index])) {
|
|
||||||
if (Variable[Index]->State == VAR_ADDED ||
|
|
||||||
Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
|
|
||||||
) {
|
|
||||||
if (!AtRuntime () || ((Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
|
|
||||||
if (VariableName[0] == 0) {
|
|
||||||
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
|
|
||||||
InDeletedVariable = Variable[Index];
|
|
||||||
InDeletedStorageIndex = Index;
|
|
||||||
} else {
|
|
||||||
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
|
|
||||||
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
|
|
||||||
PtrTrack->CurrPtr = Variable[Index];
|
|
||||||
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
//
|
||||||
}
|
// Find the variable by walk through HOB, volatile and non-volatile variable store.
|
||||||
} else {
|
//
|
||||||
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
|
for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {
|
||||||
Point = (VOID *) GetVariableNamePtr (Variable[Index]);
|
if (VariableStoreHeader[Type] == NULL) {
|
||||||
|
continue;
|
||||||
ASSERT (NameSizeOfVariable (Variable[Index]) != 0);
|
|
||||||
if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index])) == 0) {
|
|
||||||
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
|
|
||||||
InDeletedVariable = Variable[Index];
|
|
||||||
InDeletedStorageIndex = Index;
|
|
||||||
} else {
|
|
||||||
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
|
|
||||||
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
|
|
||||||
PtrTrack->CurrPtr = Variable[Index];
|
|
||||||
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable[Index] = GetNextVariablePtr (Variable[Index]);
|
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Type]);
|
||||||
}
|
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Type]);
|
||||||
if (InDeletedVariable != NULL) {
|
PtrTrack->Volatile = (BOOLEAN) (Type == VariableStoreTypeVolatile);
|
||||||
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[InDeletedStorageIndex]);
|
|
||||||
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[InDeletedStorageIndex]);
|
Status = FindVariableEx (VariableName, VendorGuid, PtrTrack);
|
||||||
PtrTrack->CurrPtr = InDeletedVariable;
|
if (!EFI_ERROR (Status)) {
|
||||||
PtrTrack->Volatile = (BOOLEAN)(InDeletedStorageIndex == 0);
|
return Status;
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PtrTrack->CurrPtr = NULL;
|
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1226,7 +1238,7 @@ AutoUpdateLangVariable(
|
||||||
// Update Lang if PlatformLang is already set
|
// Update Lang if PlatformLang is already set
|
||||||
// Update PlatformLang if Lang is already set
|
// Update PlatformLang if Lang is already set
|
||||||
//
|
//
|
||||||
Status = FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *) mVariableModuleGlobal);
|
Status = FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// Update Lang
|
// Update Lang
|
||||||
|
@ -1235,7 +1247,7 @@ AutoUpdateLangVariable(
|
||||||
Data = GetVariableDataPtr (Variable.CurrPtr);
|
Data = GetVariableDataPtr (Variable.CurrPtr);
|
||||||
DataSize = Variable.CurrPtr->DataSize;
|
DataSize = Variable.CurrPtr->DataSize;
|
||||||
} else {
|
} else {
|
||||||
Status = FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *) mVariableModuleGlobal);
|
Status = FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// Update PlatformLang
|
// Update PlatformLang
|
||||||
|
@ -1280,7 +1292,7 @@ AutoUpdateLangVariable(
|
||||||
//
|
//
|
||||||
// Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
|
// Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
|
||||||
//
|
//
|
||||||
FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);
|
FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);
|
||||||
|
|
||||||
Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang,
|
Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang,
|
||||||
ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);
|
ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);
|
||||||
|
@ -1314,7 +1326,7 @@ AutoUpdateLangVariable(
|
||||||
//
|
//
|
||||||
// Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
|
// Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
|
||||||
//
|
//
|
||||||
FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);
|
FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);
|
||||||
|
|
||||||
Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang,
|
Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang,
|
||||||
AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);
|
AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);
|
||||||
|
@ -1935,9 +1947,12 @@ VariableServiceGetNextVariableName (
|
||||||
IN OUT EFI_GUID *VendorGuid
|
IN OUT EFI_GUID *VendorGuid
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
VARIABLE_STORE_TYPE Type;
|
||||||
VARIABLE_POINTER_TRACK Variable;
|
VARIABLE_POINTER_TRACK Variable;
|
||||||
|
VARIABLE_POINTER_TRACK VariableInHob;
|
||||||
UINTN VarNameSize;
|
UINTN VarNameSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];
|
||||||
|
|
||||||
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
|
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
@ -1957,45 +1972,85 @@ VariableServiceGetNextVariableName (
|
||||||
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 0: Volatile, 1: HOB, 2: Non-Volatile.
|
||||||
|
// The index and attributes mapping must be kept in this order as FindVariable
|
||||||
|
// makes use of this mapping to implement search algorithm.
|
||||||
|
//
|
||||||
|
VariableStoreHeader[VariableStoreTypeVolatile] = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase;
|
||||||
|
VariableStoreHeader[VariableStoreTypeHob] = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
|
||||||
|
VariableStoreHeader[VariableStoreTypeNv] = mNvVariableCache;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
//
|
//
|
||||||
// If both volatile and non-volatile variable store are parsed,
|
// Switch from Volatile to HOB, to Non-Volatile.
|
||||||
// return not found.
|
|
||||||
//
|
//
|
||||||
if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {
|
while ((Variable.CurrPtr >= Variable.EndPtr) ||
|
||||||
Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));
|
(Variable.CurrPtr == NULL) ||
|
||||||
if (!Variable.Volatile) {
|
!IsValidVariableHeader (Variable.CurrPtr)
|
||||||
Variable.StartPtr = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
|
) {
|
||||||
Variable.EndPtr = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase));
|
//
|
||||||
} else {
|
// Find current storage index
|
||||||
|
//
|
||||||
|
for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {
|
||||||
|
if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT (Type < VariableStoreTypeMax);
|
||||||
|
//
|
||||||
|
// Switch to next storage
|
||||||
|
//
|
||||||
|
for (Type++; Type < VariableStoreTypeMax; Type++) {
|
||||||
|
if (VariableStoreHeader[Type] != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Capture the case that
|
||||||
|
// 1. current storage is the last one, or
|
||||||
|
// 2. no further storage
|
||||||
|
//
|
||||||
|
if (Type == VariableStoreTypeMax) {
|
||||||
Status = EFI_NOT_FOUND;
|
Status = EFI_NOT_FOUND;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]);
|
||||||
|
Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]);
|
||||||
Variable.CurrPtr = Variable.StartPtr;
|
Variable.CurrPtr = Variable.StartPtr;
|
||||||
if (!IsValidVariableHeader (Variable.CurrPtr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Variable is found
|
// Variable is found
|
||||||
//
|
//
|
||||||
if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {
|
if (Variable.CurrPtr->State == VAR_ADDED) {
|
||||||
if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {
|
if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't return NV variable when HOB overrides it
|
||||||
|
//
|
||||||
|
if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&
|
||||||
|
(Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv]))
|
||||||
|
) {
|
||||||
|
VariableInHob.StartPtr = GetStartPointer (VariableStoreHeader[VariableStoreTypeHob]);
|
||||||
|
VariableInHob.EndPtr = GetEndPointer (VariableStoreHeader[VariableStoreTypeHob]);
|
||||||
|
Status = FindVariableEx (
|
||||||
|
GetVariableNamePtr (Variable.CurrPtr),
|
||||||
|
&Variable.CurrPtr->VendorGuid,
|
||||||
|
&VariableInHob
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VarNameSize = NameSizeOfVariable (Variable.CurrPtr);
|
VarNameSize = NameSizeOfVariable (Variable.CurrPtr);
|
||||||
ASSERT (VarNameSize != 0);
|
ASSERT (VarNameSize != 0);
|
||||||
|
|
||||||
if (VarNameSize <= *VariableNameSize) {
|
if (VarNameSize <= *VariableNameSize) {
|
||||||
CopyMem (
|
CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);
|
||||||
VariableName,
|
CopyMem (VendorGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));
|
||||||
GetVariableNamePtr (Variable.CurrPtr),
|
|
||||||
VarNameSize
|
|
||||||
);
|
|
||||||
CopyMem (
|
|
||||||
VendorGuid,
|
|
||||||
&Variable.CurrPtr->VendorGuid,
|
|
||||||
sizeof (EFI_GUID)
|
|
||||||
);
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
Status = EFI_BUFFER_TOO_SMALL;
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
@ -2376,16 +2431,16 @@ VariableWriteServiceInitialize (
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT8 Data;
|
UINT8 Data;
|
||||||
EFI_PHYSICAL_ADDRESS VariableStoreBase;
|
EFI_PHYSICAL_ADDRESS VariableStoreBase;
|
||||||
UINT64 VariableStoreLength;
|
VARIABLE_HEADER *Variable;
|
||||||
|
VOID *VariableData;
|
||||||
|
|
||||||
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
|
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
|
||||||
VariableStoreLength = VariableStoreHeader->Size;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if the free area is really free.
|
// Check if the free area is really free.
|
||||||
//
|
//
|
||||||
for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreLength; Index++) {
|
for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) {
|
||||||
Data = ((UINT8 *) mNvVariableCache)[Index];
|
Data = ((UINT8 *) mNvVariableCache)[Index];
|
||||||
if (Data != 0xff) {
|
if (Data != 0xff) {
|
||||||
//
|
//
|
||||||
|
@ -2404,6 +2459,35 @@ VariableWriteServiceInitialize (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flush the HOB variable to flash and invalidate HOB variable.
|
||||||
|
//
|
||||||
|
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
|
||||||
|
//
|
||||||
|
// Clear the HobVariableBase to avoid SetVariable() updating the variable in HOB
|
||||||
|
//
|
||||||
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
|
||||||
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
|
||||||
|
|
||||||
|
for ( Variable = GetStartPointer (VariableStoreHeader)
|
||||||
|
; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
|
||||||
|
; Variable = GetNextVariablePtr (Variable)
|
||||||
|
) {
|
||||||
|
ASSERT (Variable->State == VAR_ADDED);
|
||||||
|
ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
|
||||||
|
VariableData = GetVariableDataPtr (Variable);
|
||||||
|
Status = VariableServiceSetVariable (
|
||||||
|
GetVariableNamePtr (Variable),
|
||||||
|
&Variable->VendorGuid,
|
||||||
|
Variable->Attributes,
|
||||||
|
Variable->DataSize,
|
||||||
|
VariableData
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Authenticated variable initialize.
|
// Authenticated variable initialize.
|
||||||
//
|
//
|
||||||
|
@ -2434,6 +2518,7 @@ VariableCommonInitialize (
|
||||||
UINT64 VariableStoreLength;
|
UINT64 VariableStoreLength;
|
||||||
UINTN ScratchSize;
|
UINTN ScratchSize;
|
||||||
UINTN VariableSize;
|
UINTN VariableSize;
|
||||||
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate runtime memory for variable driver global structure.
|
// Allocate runtime memory for variable driver global structure.
|
||||||
|
@ -2453,6 +2538,19 @@ VariableCommonInitialize (
|
||||||
//
|
//
|
||||||
ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize));
|
ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get HOB variable store.
|
||||||
|
//
|
||||||
|
GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
|
||||||
|
if (GuidHob != NULL) {
|
||||||
|
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
|
||||||
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
|
||||||
|
} else {
|
||||||
|
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate memory for volatile variable store, note that there is a scratch space to store scratch data.
|
// Allocate memory for volatile variable store, note that there is a scratch space to store scratch data.
|
||||||
//
|
//
|
||||||
|
@ -2480,7 +2578,7 @@ VariableCommonInitialize (
|
||||||
VolatileVariableStore->Reserved1 = 0;
|
VolatileVariableStore->Reserved1 = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get non-volatile varaible store.
|
// Get non-volatile variable store.
|
||||||
//
|
//
|
||||||
|
|
||||||
TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
|
TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
|
||||||
|
|
|
@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <Protocol/FirmwareVolumeBlock.h>
|
#include <Protocol/FirmwareVolumeBlock.h>
|
||||||
#include <Protocol/Variable.h>
|
#include <Protocol/Variable.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
#include <Library/DxeServicesTableLib.h>
|
#include <Library/DxeServicesTableLib.h>
|
||||||
#include <Library/UefiRuntimeLib.h>
|
#include <Library/UefiRuntimeLib.h>
|
||||||
|
@ -46,6 +47,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
///
|
///
|
||||||
#define ISO_639_2_ENTRY_SIZE 3
|
#define ISO_639_2_ENTRY_SIZE 3
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VariableStoreTypeVolatile,
|
||||||
|
VariableStoreTypeHob,
|
||||||
|
VariableStoreTypeNv,
|
||||||
|
VariableStoreTypeMax
|
||||||
|
} VARIABLE_STORE_TYPE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VARIABLE_HEADER *CurrPtr;
|
VARIABLE_HEADER *CurrPtr;
|
||||||
VARIABLE_HEADER *EndPtr;
|
VARIABLE_HEADER *EndPtr;
|
||||||
|
@ -54,6 +62,7 @@ typedef struct {
|
||||||
} VARIABLE_POINTER_TRACK;
|
} VARIABLE_POINTER_TRACK;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
EFI_PHYSICAL_ADDRESS HobVariableBase;
|
||||||
EFI_PHYSICAL_ADDRESS VolatileVariableBase;
|
EFI_PHYSICAL_ADDRESS VolatileVariableBase;
|
||||||
EFI_PHYSICAL_ADDRESS NonVolatileVariableBase;
|
EFI_PHYSICAL_ADDRESS NonVolatileVariableBase;
|
||||||
EFI_LOCK VariableServicesLock;
|
EFI_LOCK VariableServicesLock;
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
PcdLib
|
PcdLib
|
||||||
BaseCryptLib
|
BaseCryptLib
|
||||||
PlatformSecureLib
|
PlatformSecureLib
|
||||||
|
HobLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
DxeServicesTableLib
|
DxeServicesTableLib
|
||||||
BaseCryptLib
|
BaseCryptLib
|
||||||
PlatformSecureLib
|
PlatformSecureLib
|
||||||
|
HobLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiSmmFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiSmmFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
|
Loading…
Reference in New Issue