123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- /** @file
- @copyright
- Copyright 2012 - 2021 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <PiPei.h>
- #include <Library/MultiPlatSupportLib.h>
- #include <Library/HobLib.h>
- #include <MultiPlatSupport.h>
- #include <Ppi/MemoryDiscovered.h>
- #include <Library/ReadFfsLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Guid/AuthenticatedVariableFormat.h>
- #include <Library/PeiServicesLib.h>
- //notes
- //1: security variable and non-security variable may have different implementation
- //2. BP core variable sync may need update this module
- //3 different generation need to sync base on RP variable and Generation variable
- // this library to use a lightweight get variable service to patch variable hob before PEI variable service is ready
- /**
- Gets a vairable store header from FFS inserted by FCE
- Arguments:
- DefaultId - Specifies the type of defaults to retrieve.
- BoardId - Specifies the platform board of defaults to retrieve.
- @return The start address of VARIABLE_STORE_HEADER *. Null if cannot find it
- **/
- VOID * FindDefaultHobinFfs (
- IN UINT16 DefaultId,
- IN UINT16 BoardId
- )
- {
- EFI_PEI_SERVICES **PeiServices;
- UINTN FvInstance;
- EFI_PEI_FV_HANDLE FvHandle;
- EFI_PEI_FILE_HANDLE *FfsHandle;
- EFI_FFS_FILE_HEADER *FfsHeader;
- UINT32 FileSize;
- EFI_COMMON_SECTION_HEADER *Section;
- UINT32 SectionLength;
- BOOLEAN DefaultFileIsFound;
- DEFAULT_DATA *DefaultData;
- DEFAULT_INFO *DefaultInfo;
- VARIABLE_STORE_HEADER *VarStoreHeader;
- UINT32 FFSSize = 0;
- //
- // Find the FFS file that stores all default data.
- //
- DefaultFileIsFound = FALSE;
- FvInstance = 0;
- FfsHandle = NULL;
- while ((PeiServicesFfsFindNextVolume (FvInstance, &FvHandle) == EFI_SUCCESS) && (!DefaultFileIsFound)) {
- FfsHandle = NULL;
- while (PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_FREEFORM, FvHandle, FfsHandle) == EFI_SUCCESS) {
- if (CompareGuid ((EFI_GUID *) FfsHandle, &gDefaultDataFileGuid)) {
- DefaultFileIsFound = TRUE;
- FfsHeader = (EFI_FFS_FILE_HEADER *) FfsHandle;
- break;
- }
- }
- FvInstance ++;
- }
- //
- // FFS file is not found.
- //
- if (!DefaultFileIsFound) {
- if (PcdGet32 (PcdFailSafeVarFfsSize) != 0 ){
- //
- // try to search other FVS
- //
- FfsHeader = (EFI_FFS_FILE_HEADER *) AllocatePool (PcdGet32 (PcdFailSafeVarFfsSize));
- if (FfsHeader == NULL) {
- return NULL;
- }
- if (EFI_SUCCESS != ReadFFSFile ((EFI_FIRMWARE_VOLUME_HEADER *) PcdGet32 (PcdFailSafeVarFvBase), gDefaultDataFileGuid, 0, FfsHeader, &FFSSize, FALSE)) {
- return NULL;
- }
- ASSERT (PcdGet32 (PcdFailSafeVarFfsSize) <FFSSize);
- } else {
- return NULL;
- }
- }
- //
- // Find the matched default data for the input default ID and plat ID.
- //
- VarStoreHeader = NULL;
- Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
- FileSize = *(UINT32 *) (FfsHeader->Size) & 0x00FFFFFF;
- while (((UINTN) Section < (UINTN) FfsHeader + FileSize) && (VarStoreHeader == NULL)) {
- DefaultData = (DEFAULT_DATA *) (Section + 1);
- DefaultInfo = &(DefaultData->DefaultInfo[0]);
- while ((UINTN) DefaultInfo < (UINTN) DefaultData + DefaultData->HeaderSize) {
- if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->BoardId == BoardId) {
- VarStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) DefaultData + DefaultData->HeaderSize);
- break;
- }
- DefaultInfo ++;
- }
- //
- // Size is 24 bits wide so mask upper 8 bits.
- // SectionLength is adjusted it is 4 byte aligned.
- // Go to the next section
- //
- SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
- SectionLength = (SectionLength + 3) & (~3);
- ASSERT (SectionLength != 0);
- Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
- }
- return VarStoreHeader;
- }
- /**
- This function searches the first instance of a HOB from the starting HOB pointer.
- Such HOB should satisfy two conditions:
- its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
- If there does not exist such HOB from the starting HOB pointer, it will return NULL.
- Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
- to extract the data section and its size info respectively.
- In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
- unconditionally: it returns HobStart back if HobStart itself meets the requirement;
- caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
- If Guid is NULL, then ASSERT().
- If HobStart is NULL, then ASSERT().
- @param Guid The GUID to match with in the HOB list.
- @param HobStart A pointer to a Guid.
- @return The next instance of the matched GUID HOB from the starting HOB.
- **/
- VOID *
- InternalGetNextGuidHob (
- IN CONST EFI_GUID *Guid,
- IN CONST VOID *HobStart
- )
- {
- EFI_PEI_HOB_POINTERS GuidHob;
- GuidHob.Raw = (UINT8 *) HobStart;
- while (!END_OF_HOB_LIST (GuidHob)) {
- if (GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && CompareGuid (Guid, &GuidHob.Guid->Name)) {
- break;
- }
- GuidHob.Raw = GET_NEXT_HOB (GuidHob);
- }
- return GuidHob.Raw;
- }
- EFI_STATUS
- CreateDefaultVariableHob (
- IN UINT16 DefaultId,
- IN UINT16 BoardId
- )
- /*++
- Description:
- This function finds the matched default data and create GUID hob for it.
- Arguments:
- DefaultId - Specifies the type of defaults to retrieve.
- BoardId - Specifies the platform board of defaults to retrieve.
- Returns:
- EFI_SUCCESS - The matched default data is found.
- EFI_NOT_FOUND - The matched default data is not found.
- EFI_OUT_OF_RESOURCES - No enough resource to create HOB.
- --*/
- {
- VARIABLE_STORE_HEADER *VarStoreHeader;
- VARIABLE_STORE_HEADER *VarStoreHeaderHob;
- UINT8 *VarHobPtr;
- UINT8 *VarPtr;
- UINT32 VarDataOffset;
- UINT32 VarHobDataOffset;
- EFI_PEI_SERVICES **PeiServices;
- //
- // Get PeiService pointer
- //
- PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
- VarStoreHeader = (VARIABLE_STORE_HEADER*)FindDefaultHobinFfs( DefaultId, BoardId);
- //
- // Matched default data is not found.
- //
- if (VarStoreHeader == NULL) {
- return EFI_NOT_FOUND;
- }
- //
- // Create HOB to store defautl data so that Variable driver can use it.
- // Allocate more data for header alignment.
- //
- VarStoreHeaderHob = (VARIABLE_STORE_HEADER *) BuildGuidHob (&VarStoreHeader->Signature, VarStoreHeader->Size + HEADER_ALIGNMENT - 1);
- if (VarStoreHeaderHob == NULL) {
- //
- // No enough hob resource.
- //
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Copy variable storage header.
- //
- CopyMem (VarStoreHeaderHob, VarStoreHeader, sizeof (VARIABLE_STORE_HEADER));
- //
- // Copy variable data.
- //
- VarPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VarStoreHeader + 1));
- VarDataOffset = (UINT32) ((UINTN) VarPtr - (UINTN) VarStoreHeader);
- VarHobPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VarStoreHeaderHob + 1));
- VarHobDataOffset = (UINT32) ((UINTN) VarHobPtr - (UINTN) VarStoreHeaderHob);
- CopyMem (VarHobPtr, VarPtr, VarStoreHeader->Size - VarDataOffset);
- //
- // Update variable size.
- //
- VarStoreHeaderHob->Size = VarStoreHeader->Size - VarDataOffset + VarHobDataOffset;
- // SyncSetupVariable(PeiServices,VarStoreHeaderHob,FALSE);
- return EFI_SUCCESS;
- }
|