4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implement ReadOnly Variable Services required by PEIM and install PEI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ReadOnly Varaiable2 PPI. These services operates the non-volatile
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync storage space.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Module globals
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Provide the functionality of the variable services.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FileHandle Handle of the file being invoked.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PeiServices General purpose services available to every PEIM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If the interface could be successfully installed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Returned from PeiServicesInstallPpi()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Gets the pointer to the first variable header in given variable store area.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VarStoreHeader Pointer to the Variable Store Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the first variable header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The end of variable store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the pointer to the last variable memory pointer byte.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VarStoreHeader Pointer to the Variable Store Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return VARIABLE_HEADER* pointer to last unavailable Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The end of variable store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code checks if variable header is valid or not.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE Variable header is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE Variable header is not valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the size of name of variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Size of variable in bytes in type UINTN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the size of data of variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Size of variable in bytes in type UINTN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the pointer to the variable name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return A CHAR16* pointer to Variable Name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the pointer to the variable data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return A UINT8* pointer to Variable Data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Be careful about pad size for alignment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the pointer to the next variable header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the Variable Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return A VARIABLE_HEADER* pointer to next variable header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Be careful about pad size for alignment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code gets the pointer to the variable name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VarStoreHeader Pointer to the Variable Store Header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EfiRaw Variable store is raw
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EfiValid Variable store is valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EfiInvalid Variable store is invalid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareGuid (&VarStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function compares a variable with variable entries in database.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Variable Pointer to the variable in our database
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableName Name of the variable to compare to 'Variable'
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VendorGuid GUID of the variable to compare to 'Variable'
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PtrTrack Variable Track Pointer structure that contains Variable Information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Found match variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Variable not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableName[0] == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't use CompareGuid function here for performance reasons.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Instead we compare the GUID a UINT32 at a time and branch
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // on the first failed comparison.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable)) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Return the variable store header and the index table based on the Index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Type The type of the variable store.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IndexTable Return the index table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Pointer to the variable store header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The content of NV storage for variable is not reliable in recovery boot mode.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check if the Firmware Volume is not corrupted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Firmware Volume for Variable Store is corrupted\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) FvHeader + FvHeader->HeaderLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If it's the first time to access variable region in flash, create a guid hob to record
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // VAR_ADDED type variable info.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Note that as the resource of PEI phase is limited, only store the limited number of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // VAR_ADDED type variables to reduce access time.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*IndexTable)->StartPtr = GetStartPointer (VariableStoreHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*IndexTable)->EndPtr = GetEndPointer (VariableStoreHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find the variable in the specified variable store.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableStoreHeader Pointer to the variable store header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IndexTable Pointer to the index table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableName Name of the variable to be found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VendorGuid Vendor GUID to be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PtrTrack Variable Track Pointer structure that contains Variable Information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Variable found successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Variable not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Invalid variable name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No Variable Address equals zero, so 0 as initial value is safe.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // traverse the variable index table to look for varible.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The IndexTable->Index[Index] records the distance of two neighbouring VAR_ADDED type variables.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Offset = 0, Index = 0; Index < IndexTable->Length; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Index < sizeof (IndexTable->Index) / sizeof (IndexTable->Index[0]));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MaxIndex = (VARIABLE_HEADER *) ((UINT8 *) IndexTable->StartPtr + Offset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the table has all the existing variables indexed and we still cannot find it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // HOB exists but the variable cannot be found in HOB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If not found in HOB, then let's start from the MaxIndex we've found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start Pointers for the variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Actual Data Pointer where data can be written.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the variable by walk through non-volatile variable store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((Variable < PtrTrack->EndPtr) && IsValidVariableHeader (Variable)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record Variable in VariableIndex HOB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Offset > 0x0FFFF) || (IndexTable->Length == sizeof (IndexTable->Index) / sizeof (IndexTable->Index[0]))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stop to record if the distance of two neighbouring VAR_ADDED variable is larger than the allowable scope(UINT16),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // or the record buffer is full.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If gone through the VariableStore, that means we never find in Firmware any more.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find the variable in HOB and Non-Volatile variable storages.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableName Name of the variable to be found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VendorGuid Vendor GUID to be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param PtrTrack Variable Track Pointer structure that contains Variable Information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Variable found successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Variable not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Invalid variable name
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableStoreHeader = GetVariableStore (Type, &IndexTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This service retrieves a variable's value using its name and GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read the specified variable from the UEFI variable store. If the Data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer is too small to hold the contents of the variable, the error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the required buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size to obtain the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableName A pointer to a null-terminated string that is the variable's name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableGuid A pointer to an EFI_GUID that is the variable's GUID. The combination of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableGuid and VariableName must be unique.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Attributes If non-NULL, on return, points to the variable's attributes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DataSize On entry, points to the size in bytes of the Data buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On return, points to the size of the data returned in Data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Data Points to the buffer which will hold the returned variable value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The variable was read successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The variable could not be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the resulting data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSize is updated with the size required for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the specified variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER VariableName, VariableGuid, DataSize or Data is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find existing variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (VariableName, VariableGuid, &Variable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get data size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarDataSize = DataSizeOfVariable (Variable.CurrPtr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Return the next variable name and GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is called multiple times to retrieve the VariableName
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and VariableGuid of all variables currently available in the system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On each call, the previous results are passed into the interface,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and, on return, the interface returns the data for the next
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync interface. When the entire variable list has been returned,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_FOUND is returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On return, the size of the variable name buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableName On entry, a pointer to a null-terminated string that is the variable's name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On return, points to the next variable's null-terminated name string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param VariableGuid On entry, a pointer to an EFI_GUID that is the variable's GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On return, a pointer to the next variable's GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The variable was read successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The variable could not be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data. VariableNameSize is updated with the size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required for the specified variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableNameSize is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = FindVariable (VariableName, VariableGuid, &Variable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableName[0] != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If variable name is not NULL, get next variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Switch from HOB to Non-Volatile.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find current storage index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Switch to next storage
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Type++; Type < VariableStoreTypeMax; Type++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Capture the case that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 1. current storage is the last one, or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 2. no further storage
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't return NV variable when HOB overrides it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv]))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VarNameSize = NameSizeOfVariable (Variable.CurrPtr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Variable is found