summaryrefslogtreecommitdiff
path: root/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c
diff options
context:
space:
mode:
Diffstat (limited to 'Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c')
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c
new file mode 100644
index 0000000000..cd93898d25
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c
@@ -0,0 +1,206 @@
+/** @file
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobVariableLib.h>
+#include <Library/HobLib.h>
+#include <Ppi/MemoryDiscovered.h>
+#include "Variable.h"
+#include "Fce.h"
+
+extern EFI_PEI_NOTIFY_DESCRIPTOR mMemoryNotifyList;
+
+/**
+ This function finds the matched default data and create GUID hob for it.
+
+ @param StoreId Specifies the type of defaults to retrieve.
+ @param SkuId Specifies the platform board of defaults to retrieve.
+
+ @retval EFI_SUCCESS The matched default data is found.
+ @retval EFI_NOT_FOUND The matched default data is not found.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to create HOB.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateDefaultVariableHob (
+ IN UINT16 StoreId,
+ IN UINT16 SkuId
+ )
+{
+ UINTN FvInstance;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+ UINT32 SectionLength;
+ EFI_STATUS Status;
+ BOOLEAN DefaultSettingIsFound;
+ DEFAULT_DATA *DefaultData;
+ DEFAULT_INFO *DefaultInfo;
+ VARIABLE_STORE_HEADER *VarStoreHeader;
+ VARIABLE_STORE_HEADER *VarStoreHeaderHob;
+ UINT8 *VarHobPtr;
+ UINT8 *VarPtr;
+ UINT32 VarDataOffset;
+ UINT32 VarHobDataOffset;
+ EFI_BOOT_MODE BootMode;
+ BOOLEAN IsFirstSection;
+ DATA_DELTA *DataDelta;
+ UINTN DataDeltaSize;
+ UINTN Index;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ //
+ // Get PeiService pointer
+ //
+ PeiServices = GetPeiServicesTablePointer ();
+
+ //
+ // Find the FFS file that stores all default data.
+ //
+ DefaultSettingIsFound = FALSE;
+ FvInstance = 0;
+ FfsHeader = NULL;
+ while (((*PeiServices)->FfsFindNextVolume (PeiServices, FvInstance, (VOID **) &FvHeader) == EFI_SUCCESS) &&
+ (!DefaultSettingIsFound)) {
+ FfsHeader = NULL;
+ while ((*PeiServices)->FfsFindNextFile (PeiServices, EFI_FV_FILETYPE_FREEFORM, FvHeader, (VOID **) &FfsHeader) == EFI_SUCCESS) {
+ if (CompareGuid ((EFI_GUID *) FfsHeader, &gDefaultDataOptSizeFileGuid)) {
+ DefaultSettingIsFound = TRUE;
+ break;
+ }
+ }
+ FvInstance ++;
+ }
+
+ //
+ // FFS file is not found.
+ //
+ if (!DefaultSettingIsFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find the matched default data for the input default ID and plat ID.
+ //
+ DefaultSettingIsFound = FALSE;
+ VarStoreHeaderHob = NULL;
+ VarHobPtr = NULL;
+ DataDelta = NULL;
+ DataDeltaSize = 0;
+ IsFirstSection = TRUE;
+ VarStoreHeader = NULL;
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
+ FileSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
+ while (((UINTN) Section < (UINTN) FfsHeader + FileSize) && !DefaultSettingIsFound) {
+ DefaultData = (DEFAULT_DATA *) (Section + 1);
+ DefaultInfo = &(DefaultData->DefaultInfo[0]);
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+
+ if (IsFirstSection) {
+ //
+ // Create HOB to store default data so that Variable driver can use it.
+ // Allocate more data for header alignment.
+ //
+ VarStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) DefaultData + DefaultData->HeaderSize);
+ 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;
+
+ //
+ // Update Delta Data
+ //
+ VarHobPtr = (UINT8 *) VarStoreHeaderHob - VarDataOffset + VarHobDataOffset;
+ } else {
+ //
+ // Apply delta setting
+ //
+ DataDelta = (DATA_DELTA *) ((UINT8 *) DefaultData + DefaultData->HeaderSize);
+ DataDeltaSize = SectionLength - sizeof (EFI_COMMON_SECTION_HEADER) - DefaultData->HeaderSize;
+ for (Index = 0; Index < DataDeltaSize / sizeof (DATA_DELTA); Index ++) {
+ *((UINT8 *) VarHobPtr + DataDelta[Index].Offset) = DataDelta[Index].Value;
+ }
+ }
+
+ //
+ // Find the matched DefaultId and BoardId
+ //
+ while ((UINTN) DefaultInfo < (UINTN) DefaultData + DefaultData->HeaderSize) {
+ if (DefaultInfo->DefaultId == StoreId && DefaultInfo->BoardId == SkuId) {
+ DefaultSettingIsFound = TRUE;
+ 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 = (SectionLength + 3) & (~3);
+ ASSERT (SectionLength != 0);
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ IsFirstSection = FALSE;
+ }
+ //
+ // Matched default data is not found.
+ //
+ if (!DefaultSettingIsFound) {
+ //
+ // Change created HOB type to be unused.
+ //
+ if (VarStoreHeaderHob != NULL) {
+ ((EFI_HOB_GUID_TYPE *)((UINT8 *) VarStoreHeaderHob - sizeof (EFI_HOB_GUID_TYPE)))->Header.HobType = EFI_HOB_TYPE_UNUSED;
+ }
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // On recovery boot mode, emulation variable driver will be used.
+ // But, Emulation variable only knows normal variable data format.
+ // So, if the default variable data format is authenticated, it needs to be converted to normal data.
+ //
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (BootMode == BOOT_IN_RECOVERY_MODE &&
+ CompareGuid (&VarStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) {
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mMemoryNotifyList);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}