summaryrefslogtreecommitdiff
path: root/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce
diff options
context:
space:
mode:
Diffstat (limited to 'Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce')
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Fce.h48
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/InternalCommonLib.c634
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.c467
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.inf54
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.c206
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.inf53
-rw-r--r--Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Variable.h178
7 files changed, 1640 insertions, 0 deletions
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Fce.h b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Fce.h
new file mode 100644
index 0000000000..a9010a2763
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Fce.h
@@ -0,0 +1,48 @@
+/**@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.
+
+**/
+
+#ifndef __FCE_H__
+#define __FCE_H__
+
+extern EFI_GUID gDefaultDataFileGuid;
+extern EFI_GUID gDefaultDataOptSizeFileGuid;
+
+#pragma pack(1)
+
+typedef struct {
+ UINT16 DefaultId;
+ UINT16 BoardId;
+} DEFAULT_INFO;
+
+typedef struct {
+ UINT16 Offset;
+ UINT8 Value;
+} DATA_DELTA;
+
+typedef struct {
+ //
+ // HeaderSize includes HeaderSize fields and DefaultInfo arrays
+ //
+ UINT16 HeaderSize;
+ //
+ // DefaultInfo arrays those have the same default setting.
+ //
+ DEFAULT_INFO DefaultInfo[1];
+ //
+ // Default data is stored as variable storage or the array of DATA_DELTA.
+ //
+} DEFAULT_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/InternalCommonLib.c b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/InternalCommonLib.c
new file mode 100644
index 0000000000..cb7f928426
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/InternalCommonLib.c
@@ -0,0 +1,634 @@
+/**@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 <Uefi.h>
+#include <PiPei.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobVariableLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Ppi/MemoryDiscovered.h>
+#include "Variable.h"
+#include "Fce.h"
+
+/**
+
+ Gets the pointer to the first variable header in given variable store area.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @return Pointer to the first variable header
+
+**/
+STATIC
+AUTHENTICATED_VARIABLE_HEADER *
+GetStartPointer (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+ //
+ // The end of variable store
+ //
+ return (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
+}
+
+
+/**
+ This code gets the pointer to the last variable memory pointer byte.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @return AUTHENTICATED_VARIABLE_HEADER* pointer to last unavailable Variable Header.
+
+**/
+STATIC
+AUTHENTICATED_VARIABLE_HEADER *
+GetEndPointer (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+ //
+ // The end of variable store
+ //
+ return (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);
+}
+
+
+/**
+ This code checks if variable header is valid or not.
+
+ @param Variable Pointer to the Variable Header.
+
+ @retval TRUE Variable header is valid.
+ @retval FALSE Variable header is not valid.
+
+**/
+STATIC
+BOOLEAN
+IsValidVariableHeader (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ This code gets the size of name of variable.
+
+ @param Variable Pointer to the Variable Header.
+ @param AuthFlag Authenticated variable flag.
+
+ @return Size of variable in bytes in type UINTN.
+
+**/
+STATIC
+UINTN
+NameSizeOfVariable (
+ IN AUTHENTICATED_VARIABLE_HEADER *AuthVariable,
+ IN BOOLEAN AuthFlag
+ )
+{
+ VARIABLE_HEADER *Variable;
+
+ Variable = (VARIABLE_HEADER *) AuthVariable;
+ if (AuthFlag) {
+ if (AuthVariable->State == (UINT8) (-1) ||
+ AuthVariable->DataSize == (UINT32) (-1) ||
+ AuthVariable->NameSize == (UINT32) (-1) ||
+ AuthVariable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) AuthVariable->NameSize;
+ } else {
+ if (Variable->State == (UINT8) (-1) ||
+ Variable->DataSize == (UINT32) (-1) ||
+ Variable->NameSize == (UINT32) (-1) ||
+ Variable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) Variable->NameSize;
+ }
+}
+
+
+/**
+ This code gets the size of data of variable.
+
+ @param Variable Pointer to the Variable Header.
+ @param AuthFlag Authenticated variable flag.
+
+ @return Size of variable in bytes in type UINTN.
+
+**/
+STATIC
+UINTN
+DataSizeOfVariable (
+ IN AUTHENTICATED_VARIABLE_HEADER *AuthVariable,
+ IN BOOLEAN AuthFlag
+ )
+{
+ VARIABLE_HEADER *Variable;
+
+ Variable = (VARIABLE_HEADER *) AuthVariable;
+ if (AuthFlag) {
+ if (AuthVariable->State == (UINT8) (-1) ||
+ AuthVariable->DataSize == (UINT32) (-1) ||
+ AuthVariable->NameSize == (UINT32) (-1) ||
+ AuthVariable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) AuthVariable->DataSize;
+ } else {
+ if (Variable->State == (UINT8) (-1) ||
+ Variable->DataSize == (UINT32) (-1) ||
+ Variable->NameSize == (UINT32) (-1) ||
+ Variable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) Variable->DataSize;
+ }
+}
+
+/**
+ This code gets the size of variable header.
+
+ @param AuthFlag Authenticated variable flag.
+
+ @return Size of variable header in bytes in type UINTN.
+
+**/
+UINTN
+GetVariableHeaderSize (
+ IN BOOLEAN AuthFlag
+ )
+{
+ UINTN Value;
+
+ if (AuthFlag) {
+ Value = sizeof (AUTHENTICATED_VARIABLE_HEADER);
+ } else {
+ Value = sizeof (VARIABLE_HEADER);
+ }
+
+ return Value;
+}
+
+
+/**
+ This code gets the pointer to the variable name.
+
+ @param Variable Pointer to the Variable Header.
+ @param AuthFlag Authenticated variable flag.
+
+ @return A CHAR16* pointer to Variable Name.
+
+**/
+STATIC
+CHAR16 *
+GetVariableNamePtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable,
+ IN BOOLEAN AuthFlag
+ )
+{
+ return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize (AuthFlag));
+}
+
+
+/**
+ This code gets the pointer to the variable guid.
+
+ @param Variable Pointer to the Variable Header.
+ @param AuthFlag Authenticated variable flag.
+
+ @return A EFI_GUID* pointer to Vendor Guid.
+
+**/
+EFI_GUID *
+GetVendorGuidPtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *AuthVariable,
+ IN BOOLEAN AuthFlag
+ )
+{
+ VARIABLE_HEADER *Variable;
+
+ Variable = (VARIABLE_HEADER *) AuthVariable;
+ if (AuthFlag) {
+ return &AuthVariable->VendorGuid;
+ } else {
+ return &Variable->VendorGuid;
+ }
+}
+
+
+/**
+ This code gets the pointer to the variable data.
+
+ @param Variable Pointer to the Variable Header.
+ @param AuthFlag Authenticated variable flag.
+
+ @return A UINT8* pointer to Variable Data.
+
+**/
+STATIC
+UINT8 *
+GetVariableDataPtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable,
+ IN BOOLEAN AuthFlag
+ )
+{
+ UINTN Value;
+
+ //
+ // Be careful about pad size for alignment
+ //
+ Value = (UINTN) GetVariableNamePtr (Variable, AuthFlag);
+ Value += NameSizeOfVariable (Variable, AuthFlag);
+ Value += GET_PAD_SIZE (NameSizeOfVariable (Variable, AuthFlag));
+
+ return (UINT8 *) Value;
+}
+
+
+/**
+ This code gets the pointer to the next variable header.
+
+ @param Variable Pointer to the Variable Header.
+ @param AuthFlag Authenticated variable flag.
+
+ @return A AUTHENTICATED_VARIABLE_HEADER* pointer to next variable header.
+
+**/
+STATIC
+AUTHENTICATED_VARIABLE_HEADER *
+GetNextVariablePtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable,
+ IN BOOLEAN AuthFlag
+ )
+{
+ UINTN Value;
+
+ if (!IsValidVariableHeader (Variable)) {
+ return NULL;
+ }
+
+ Value = (UINTN) GetVariableDataPtr (Variable, AuthFlag);
+ Value += DataSizeOfVariable (Variable, AuthFlag);
+ Value += GET_PAD_SIZE (DataSizeOfVariable (Variable, AuthFlag));
+
+ //
+ // Be careful about pad size for alignment
+ //
+ return (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN (Value);
+}
+
+EFI_STATUS
+EFIAPI
+BuildDefaultDataHobForRecoveryVariable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Convert Authenticated variable to normal variable data.
+
+Arguments:
+
+ PeiServices General purpose services available to every PEIM.
+ NotifyDescriptor Notify that this module published.
+ Ppi PPI that was installed.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+
+--*/
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VARIABLE_STORE_HEADER *AuthVarStoreHeader;
+ VARIABLE_STORE_HEADER *VarStoreHeader;
+ UINT32 VarStoreSize;
+ AUTHENTICATED_VARIABLE_HEADER *AuthStartPtr;
+ AUTHENTICATED_VARIABLE_HEADER *AuthEndPtr;
+ AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
+ VARIABLE_HEADER *Variable;
+ UINT8 *AuthVariablePtr;
+ UINT8 *VariablePtr;
+
+ GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
+ AuthVarStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);
+ //
+ // Go through AuthVarStore to calculate the required size for normal varstore.
+ //
+ VarStoreSize = sizeof (VARIABLE_STORE_HEADER);
+ AuthStartPtr = GetStartPointer (AuthVarStoreHeader);
+ AuthEndPtr = GetEndPointer (AuthVarStoreHeader);
+ AuthVariable = AuthStartPtr;
+ while ((AuthVariable < AuthEndPtr) && IsValidVariableHeader (AuthVariable)) {
+ if (AuthVariable->State == VAR_ADDED) {
+ VarStoreSize = HEADER_ALIGN (VarStoreSize);
+ VarStoreSize += sizeof (VARIABLE_HEADER);
+ VarStoreSize += AuthVariable->NameSize + GET_PAD_SIZE (AuthVariable->NameSize);
+ VarStoreSize += AuthVariable->DataSize + GET_PAD_SIZE (AuthVariable->DataSize);
+ }
+ AuthVariable = GetNextVariablePtr (AuthVariable, TRUE);
+ }
+
+ //
+ // Create HOB data for normal variable storage.
+ // Allocate more data for header alignment.
+ //
+ VarStoreSize = VarStoreSize + HEADER_ALIGNMENT - 1;
+ VarStoreHeader = (VARIABLE_STORE_HEADER *) BuildGuidHob (&gEfiVariableGuid, VarStoreSize);
+ ASSERT (VarStoreHeader != NULL);
+ if (VarStoreHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyGuid (&VarStoreHeader->Signature, &gEfiVariableGuid);
+ VarStoreHeader->Format = AuthVarStoreHeader->Format;
+ VarStoreHeader->State = AuthVarStoreHeader->State;
+
+ //
+ // Copy variable data from AuthVarStore to NormalVarStore
+ //
+ AuthVariable = AuthStartPtr;
+ VariablePtr = (UINT8 *) (VarStoreHeader + 1);
+ while ((AuthVariable < AuthEndPtr) && IsValidVariableHeader (AuthVariable)) {
+ if (AuthVariable->State == VAR_ADDED) {
+ Variable = (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VariablePtr);
+ //
+ // Copy variable header
+ //
+ Variable->StartId = AuthVariable->StartId;
+ Variable->State = AuthVariable->State;
+ Variable->Reserved = AuthVariable->Reserved;
+ Variable->Attributes = AuthVariable->Attributes;
+ Variable->NameSize = AuthVariable->NameSize;
+ Variable->DataSize = AuthVariable->DataSize;
+ CopyGuid (&Variable->VendorGuid, &AuthVariable->VendorGuid);
+ //
+ // Copy variable Name and Data
+ //
+ VariablePtr = (UINT8 *) (Variable + 1);
+ AuthVariablePtr = (UINT8 *) (AuthVariable + 1);
+ CopyMem (VariablePtr, AuthVariablePtr, Variable->NameSize);
+ VariablePtr = VariablePtr + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize);
+ AuthVariablePtr = AuthVariablePtr + AuthVariable->NameSize + GET_PAD_SIZE (AuthVariable->NameSize);
+ CopyMem (VariablePtr, AuthVariablePtr, Variable->DataSize);
+ VariablePtr = VariablePtr + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize);
+ }
+ AuthVariable = GetNextVariablePtr (AuthVariable, TRUE);
+ }
+
+ //
+ // Update Variable Storage Size
+ //
+ VarStoreHeader->Size = (UINT32) ((UINTN) VariablePtr - (UINTN) VarStoreHeader);
+
+ return EFI_SUCCESS;
+}
+
+EFI_PEI_NOTIFY_DESCRIPTOR mMemoryNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ BuildDefaultDataHobForRecoveryVariable
+};
+
+/**
+ Find variable from default variable HOB.
+
+ @param[in] VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[out] AuthFlag Pointer to output Authenticated variable flag.
+
+ @return Pointer to variable header, NULL if not found.
+
+**/
+AUTHENTICATED_VARIABLE_HEADER *
+FindVariableFromHob (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT BOOLEAN *AuthFlag
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ AUTHENTICATED_VARIABLE_HEADER *StartPtr;
+ AUTHENTICATED_VARIABLE_HEADER *EndPtr;
+ AUTHENTICATED_VARIABLE_HEADER *CurrPtr;
+ VOID *Point;
+
+ VariableStoreHeader = NULL;
+
+ GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
+ if (GuidHob != NULL) {
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);
+ *AuthFlag = TRUE;
+ } else {
+ GuidHob = GetFirstGuidHob (&gEfiVariableGuid);
+ if (GuidHob != NULL) {
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);
+ *AuthFlag = FALSE;
+ }
+ }
+ ASSERT (VariableStoreHeader != NULL);
+ if (VariableStoreHeader == NULL) {
+ return NULL;
+ }
+
+ StartPtr = GetStartPointer (VariableStoreHeader);
+ EndPtr = GetEndPointer (VariableStoreHeader);
+ for ( CurrPtr = StartPtr
+ ; (CurrPtr < EndPtr) && IsValidVariableHeader (CurrPtr)
+ ; CurrPtr = GetNextVariablePtr (CurrPtr, *AuthFlag)
+ ) {
+ if (CurrPtr->State == VAR_ADDED) {
+ if (CompareGuid (VendorGuid, GetVendorGuidPtr (CurrPtr, *AuthFlag))) {
+ Point = (VOID *) GetVariableNamePtr (CurrPtr, *AuthFlag);
+
+ ASSERT (NameSizeOfVariable (CurrPtr, *AuthFlag) != 0);
+ if (CompareMem (VariableName, Point, NameSizeOfVariable (CurrPtr, *AuthFlag)) == 0) {
+ return CurrPtr;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ Get variable from default variable HOB.
+
+ @param[in] VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[out] Attributes If not NULL, a pointer to the memory location to return the
+ attributes bitmask for the variable.
+ @param[in, out] DataSize On input, the size in bytes of the return Data buffer.
+ On output the size of data returned in Data.
+ @param[out] Data The buffer to return the contents of the variable.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The variable was not found.
+ @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result.
+ @retval EFI_INVALID_PARAMETER VariableName is NULL.
+ @retval EFI_INVALID_PARAMETER VendorGuid is NULL.
+ @retval EFI_INVALID_PARAMETER DataSize is NULL.
+ @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVariableFromHob (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes, OPTIONAL
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data
+ )
+{
+ BOOLEAN AuthFlag;
+ AUTHENTICATED_VARIABLE_HEADER *Variable;
+ UINTN VarDataSize;
+
+ if ((VariableName == NULL) || (VendorGuid == NULL) || (DataSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Variable = FindVariableFromHob (VariableName, VendorGuid, &AuthFlag);
+ if (Variable == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get data size
+ //
+ VarDataSize = DataSizeOfVariable (Variable, AuthFlag);
+ if (*DataSize >= VarDataSize) {
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem (Data, GetVariableDataPtr (Variable, AuthFlag), VarDataSize);
+
+ if (Attributes != NULL) {
+ *Attributes = Variable->Attributes;
+ }
+
+ *DataSize = VarDataSize;
+ return EFI_SUCCESS;
+ } else {
+ *DataSize = VarDataSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+}
+
+/**
+ Set variable to default variable HOB.
+
+ @param[in] VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] Attributes If not NULL, a pointer to the memory location to set the
+ attributes bitmask for the variable.
+ @param[in] DataSize On input, the size in bytes of the return Data buffer.
+ On output the size of data returned in Data.
+ @param[in] Data The buffer to return the contents of the variable.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The variable was not found.
+ @retval EFI_INVALID_PARAMETER VariableName is NULL.
+ @retval EFI_INVALID_PARAMETER VendorGuid is NULL.
+ @retval EFI_INVALID_PARAMETER Attributes is not NULL, but attributes value is 0.
+ @retval EFI_INVALID_PARAMETER DataSize is not equal to the variable data size.
+ @retval EFI_INVALID_PARAMETER The DataSize is equal to the variable data size, but Data is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+SetVariableToHob (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 *Attributes, OPTIONAL
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ BOOLEAN AuthFlag;
+ AUTHENTICATED_VARIABLE_HEADER *Variable;
+ UINTN VarDataSize;
+
+ if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Variable = FindVariableFromHob (VariableName, VendorGuid, &AuthFlag);
+ if (Variable == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get data size
+ //
+ VarDataSize = DataSizeOfVariable (Variable, AuthFlag);
+ if (DataSize == VarDataSize) {
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Attributes != NULL) {
+ if (*Attributes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Variable->Attributes = *Attributes;
+ }
+
+ CopyMem (GetVariableDataPtr (Variable, AuthFlag), Data, VarDataSize);
+
+ return EFI_SUCCESS;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ This function finds the matched data and create GUID hob for it.
+
+ @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
+CreateVariableHob (
+ VOID
+ )
+{
+ UINT16 StoreId;
+ UINT16 SkuId;
+
+ StoreId = EFI_HII_DEFAULT_CLASS_STANDARD; // BUGBUG: Should get from PCD
+ SkuId = (UINT16)LibPcdGetSku ();
+ return CreateDefaultVariableHob (StoreId, SkuId);
+} \ No newline at end of file
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.c b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.c
new file mode 100644
index 0000000000..ecad77ec8a
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.c
@@ -0,0 +1,467 @@
+/** @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"
+
+/**
+
+ Gets the pointer to the first variable header in given variable store area.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @return Pointer to the first variable header
+
+**/
+STATIC
+AUTHENTICATED_VARIABLE_HEADER *
+GetStartPointer (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+ //
+ // The end of variable store
+ //
+ return (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
+}
+
+
+/**
+ This code gets the pointer to the last variable memory pointer byte.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @return AUTHENTICATED_VARIABLE_HEADER* pointer to last unavailable Variable Header.
+
+**/
+STATIC
+AUTHENTICATED_VARIABLE_HEADER *
+GetEndPointer (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+ //
+ // The end of variable store
+ //
+ return (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);
+}
+
+
+/**
+ This code checks if variable header is valid or not.
+
+ @param Variable Pointer to the Variable Header.
+
+ @retval TRUE Variable header is valid.
+ @retval FALSE Variable header is not valid.
+
+**/
+STATIC
+BOOLEAN
+IsValidVariableHeader (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ This code gets the size of name of variable.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return Size of variable in bytes in type UINTN.
+
+**/
+STATIC
+UINTN
+NameSizeOfVariable (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable->State == (UINT8) (-1) ||
+ Variable->DataSize == (UINT32) (-1) ||
+ Variable->NameSize == (UINT32) (-1) ||
+ Variable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) Variable->NameSize;
+}
+
+
+/**
+ This code gets the size of data of variable.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return Size of variable in bytes in type UINTN.
+
+**/
+STATIC
+UINTN
+DataSizeOfVariable (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable->State == (UINT8) (-1) ||
+ Variable->DataSize == (UINT32) (-1) ||
+ Variable->NameSize == (UINT32) (-1) ||
+ Variable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) Variable->DataSize;
+}
+
+/**
+ This code gets the pointer to the variable name.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return A CHAR16* pointer to Variable Name.
+
+**/
+STATIC
+CHAR16 *
+GetVariableNamePtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+
+ return (CHAR16 *) (Variable + 1);
+}
+
+
+/**
+ This code gets the pointer to the variable data.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return A UINT8* pointer to Variable Data.
+
+**/
+STATIC
+UINT8 *
+GetVariableDataPtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+ UINTN Value;
+
+ //
+ // Be careful about pad size for alignment
+ //
+ Value = (UINTN) GetVariableNamePtr (Variable);
+ Value += NameSizeOfVariable (Variable);
+ Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
+
+ return (UINT8 *) Value;
+}
+
+
+/**
+ This code gets the pointer to the next variable header.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return A AUTHENTICATED_VARIABLE_HEADER* pointer to next variable header.
+
+**/
+STATIC
+AUTHENTICATED_VARIABLE_HEADER *
+GetNextVariablePtr (
+ IN AUTHENTICATED_VARIABLE_HEADER *Variable
+ )
+{
+ UINTN Value;
+
+ if (!IsValidVariableHeader (Variable)) {
+ return NULL;
+ }
+
+ Value = (UINTN) GetVariableDataPtr (Variable);
+ Value += DataSizeOfVariable (Variable);
+ Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
+
+ //
+ // Be careful about pad size for alignment
+ //
+ return (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN (Value);
+}
+
+EFI_STATUS
+EFIAPI
+BuildDefaultDataHobForRecoveryVariable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Convert Authenticated variable to normal variable data.
+
+Arguments:
+
+ PeiServices General purpose services available to every PEIM.
+ NotifyDescriptor Notify that this module published.
+ Ppi PPI that was installed.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully.
+
+--*/
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VARIABLE_STORE_HEADER *AuthVarStoreHeader;
+ VARIABLE_STORE_HEADER *VarStoreHeader;
+ UINT32 VarStoreSize;
+ AUTHENTICATED_VARIABLE_HEADER *AuthStartPtr;
+ AUTHENTICATED_VARIABLE_HEADER *AuthEndPtr;
+ AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
+ VARIABLE_HEADER *Variable;
+ UINT8 *AuthVariablePtr;
+ UINT8 *VariablePtr;
+
+ GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
+ AuthVarStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob);
+ //
+ // Go through AuthVarStore to calculate the required size for normal varstore.
+ //
+ VarStoreSize = sizeof (VARIABLE_STORE_HEADER);
+ AuthStartPtr = GetStartPointer (AuthVarStoreHeader);
+ AuthEndPtr = GetEndPointer (AuthVarStoreHeader);
+ AuthVariable = AuthStartPtr;
+ while ((AuthVariable < AuthEndPtr) && IsValidVariableHeader (AuthVariable)) {
+ if (AuthVariable->State == VAR_ADDED) {
+ VarStoreSize = HEADER_ALIGN (VarStoreSize);
+ VarStoreSize += sizeof (VARIABLE_HEADER);
+ VarStoreSize += AuthVariable->NameSize + GET_PAD_SIZE (AuthVariable->NameSize);
+ VarStoreSize += AuthVariable->DataSize + GET_PAD_SIZE (AuthVariable->DataSize);
+ }
+ AuthVariable = GetNextVariablePtr (AuthVariable);
+ }
+
+ //
+ // Create HOB data for normal variable storage.
+ // Allocate more data for header alignment.
+ //
+ VarStoreSize = VarStoreSize + HEADER_ALIGNMENT - 1;
+ VarStoreHeader = (VARIABLE_STORE_HEADER *) BuildGuidHob (&gEfiVariableGuid, VarStoreSize);
+ ASSERT (VarStoreHeader != NULL);
+ CopyGuid (&VarStoreHeader->Signature, &gEfiVariableGuid);
+ VarStoreHeader->Format = AuthVarStoreHeader->Format;
+ VarStoreHeader->State = AuthVarStoreHeader->State;
+
+ //
+ // Copy variable data from AuthVarStore to NormalVarStore
+ //
+ AuthVariable = AuthStartPtr;
+ VariablePtr = (UINT8 *) (VarStoreHeader + 1);
+ while ((AuthVariable < AuthEndPtr) && IsValidVariableHeader (AuthVariable)) {
+ if (AuthVariable->State == VAR_ADDED) {
+ Variable = (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VariablePtr);
+ //
+ // Copy variable header
+ //
+ Variable->StartId = AuthVariable->StartId;
+ Variable->State = AuthVariable->State;
+ Variable->Reserved = AuthVariable->Reserved;
+ Variable->Attributes = AuthVariable->Attributes;
+ Variable->NameSize = AuthVariable->NameSize;
+ Variable->DataSize = AuthVariable->DataSize;
+ CopyGuid (&Variable->VendorGuid, &AuthVariable->VendorGuid);
+ //
+ // Copy variable Name and Data
+ //
+ VariablePtr = (UINT8 *) (Variable + 1);
+ AuthVariablePtr = (UINT8 *) (AuthVariable + 1);
+ CopyMem (VariablePtr, AuthVariablePtr, Variable->NameSize);
+ VariablePtr = VariablePtr + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize);
+ AuthVariablePtr = AuthVariablePtr + AuthVariable->NameSize + GET_PAD_SIZE (AuthVariable->NameSize);
+ CopyMem (VariablePtr, AuthVariablePtr, Variable->DataSize);
+ VariablePtr = VariablePtr + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize);
+ }
+ AuthVariable = GetNextVariablePtr (AuthVariable);
+ }
+
+ //
+ // Update Variable Storage Size
+ //
+ VarStoreHeader->Size = (UINT32) ((UINTN) VariablePtr - (UINTN) VarStoreHeader);
+
+ return EFI_SUCCESS;
+}
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mMemoryNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ BuildDefaultDataHobForRecoveryVariable
+};
+
+/**
+ 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 DefaultFileIsFound;
+ 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;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ //
+ // Get PeiService pointer
+ //
+ PeiServices = GetPeiServicesTablePointer ();
+
+ //
+ // Find the FFS file that stores all default data.
+ //
+ DefaultFileIsFound = FALSE;
+ FvInstance = 0;
+ FfsHeader = NULL;
+ while (((*PeiServices)->FfsFindNextVolume (PeiServices, FvInstance, &FvHeader) == EFI_SUCCESS) &&
+ (!DefaultFileIsFound)) {
+ FfsHeader = NULL;
+ while ((*PeiServices)->FfsFindNextFile (PeiServices, EFI_FV_FILETYPE_FREEFORM, FvHeader, &FfsHeader) == EFI_SUCCESS) {
+ if (CompareGuid ((EFI_GUID *) FfsHeader, &gDefaultDataFileGuid)) {
+ DefaultFileIsFound = TRUE;
+ break;
+ }
+ }
+ FvInstance ++;
+ }
+
+ //
+ // FFS file is not found.
+ //
+ if (!DefaultFileIsFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // 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 == StoreId && DefaultInfo->BoardId == SkuId) {
+ 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);
+ }
+ //
+ // Matched default data is not found.
+ //
+ if (VarStoreHeader == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Create HOB to store default 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;
+
+ //
+ // 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;
+}
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.inf b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.inf
new file mode 100644
index 0000000000..66526b3fbd
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFce.inf
@@ -0,0 +1,54 @@
+### @file
+# Module define variable layout and access method for common
+# circumstance.
+#
+# 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 which 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.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiHobVariableLibFce
+ FILE_GUID = 5196F8AE-7C88-4DA8-83D4-21725AB4CF9B
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = HobVariableLib|PEIM
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+ BaseMemoryLib
+ PeiServicesTablePointerLib
+ HobLib
+ DebugLib
+ PcdLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[Sources]
+ PeiHobVariableLibFce.c
+ InternalCommonLib.c
+
+[Ppis]
+ gEfiPeiMemoryDiscoveredPpiGuid ## NOTIFY
+
+[Guids]
+ gEfiVariableGuid ## SOMETIMES_PRODUCES ## HOB
+ gEfiAuthenticatedVariableGuid ## SOMETIMES_CONSUMES ## HOB
+ gDefaultDataFileGuid ## SOMETIMES_CONSUMES ## FV
+
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;
+}
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.inf b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.inf
new file mode 100644
index 0000000000..9f6d60622d
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/PeiHobVariableLibFceOptSize.inf
@@ -0,0 +1,53 @@
+### @file
+# Finds the matched default data and creates GUID hob for it.
+#
+# 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 which 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.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiHobVariableLibFceOptSize
+ FILE_GUID = AD8F6AF5-F94C-44A2-AE7A-A4CDC22BDC6C
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = HobVariableLib|PEIM
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+ BaseMemoryLib
+ PeiServicesTablePointerLib
+ HobLib
+ DebugLib
+ PcdLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[Sources]
+ PeiHobVariableLibFceOptSize.c
+ InternalCommonLib.c
+
+[Ppis]
+ gEfiPeiMemoryDiscoveredPpiGuid ## NOTIFY
+
+[Guids]
+ gEfiVariableGuid ## SOMETIMES_PRODUCES ## HOB
+ gEfiAuthenticatedVariableGuid ## SOMETIMES_CONSUMES ## HOB
+ gDefaultDataOptSizeFileGuid ## SOMETIMES_CONSUMES ## FV
+
diff --git a/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Variable.h b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Variable.h
new file mode 100644
index 0000000000..fa9fb0292c
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/PeiHobVariableLibFce/Variable.h
@@ -0,0 +1,178 @@
+/**@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.
+
+**/
+
+#ifndef __VARIABLE_H__
+#define __VARIABLE_H__
+
+extern EFI_GUID gEfiVariableGuid;
+extern EFI_GUID gEfiAuthenticatedVariableGuid;
+
+///
+/// Alignment of variable name and data, according to the architecture:
+/// * For IA-32 and Intel(R) 64 architectures: 1.
+/// * For IA-64 architecture: 8.
+///
+#if defined (MDE_CPU_IPF)
+#define ALIGNMENT 8
+#else
+#define ALIGNMENT 1
+#endif
+
+//
+// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.
+//
+#if (ALIGNMENT == 1)
+#define GET_PAD_SIZE(a) (0)
+#else
+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))
+#endif
+
+///
+/// Alignment of Variable Data Header in Variable Store region.
+///
+#define HEADER_ALIGNMENT 4
+#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
+
+///
+/// Status of Variable Store Region.
+///
+typedef enum {
+ EfiRaw,
+ EfiValid,
+ EfiInvalid,
+ EfiUnknown
+} VARIABLE_STORE_STATUS;
+
+#pragma pack(1)
+
+///
+/// Variable Store Header Format and State.
+///
+#define VARIABLE_STORE_FORMATTED 0x5a
+#define VARIABLE_STORE_HEALTHY 0xfe
+
+///
+/// Variable Store region header.
+///
+typedef struct {
+ ///
+ /// Variable store region signature.
+ ///
+ EFI_GUID Signature;
+ ///
+ /// Size of entire variable store,
+ /// including size of variable store header but not including the size of FvHeader.
+ ///
+ UINT32 Size;
+ ///
+ /// Variable region format state.
+ ///
+ UINT8 Format;
+ ///
+ /// Variable region healthy state.
+ ///
+ UINT8 State;
+ UINT16 Reserved;
+ UINT32 Reserved1;
+} VARIABLE_STORE_HEADER;
+
+///
+/// Variable data start flag.
+///
+#define VARIABLE_DATA 0x55AA
+
+///
+/// Variable State flags.
+///
+#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition.
+#define VAR_DELETED 0xfd ///< Variable is obsolete.
+#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid.
+#define VAR_ADDED 0x3f ///< Variable has been completely added.
+
+///
+/// Single Variable Data Header Structure.
+///
+typedef struct {
+ ///
+ /// Variable Data Start Flag.
+ ///
+ UINT16 StartId;
+ ///
+ /// Variable State defined above.
+ ///
+ UINT8 State;
+ UINT8 Reserved;
+ ///
+ /// Attributes of variable defined in UEFI specification.
+ ///
+ UINT32 Attributes;
+ ///
+ /// Size of variable null-terminated Unicode string name.
+ ///
+ UINT32 NameSize;
+ ///
+ /// Size of the variable data without this header.
+ ///
+ UINT32 DataSize;
+ ///
+ /// A unique identifier for the vendor that produces and consumes this varaible.
+ ///
+ EFI_GUID VendorGuid;
+} VARIABLE_HEADER;
+
+///
+/// Single Variable Data Header Structure for Auth variable.
+///
+typedef struct {
+ ///
+ /// Variable Data Start Flag.
+ ///
+ UINT16 StartId;
+ ///
+ /// Variable State defined above.
+ ///
+ UINT8 State;
+ UINT8 Reserved;
+ ///
+ /// Attributes of variable defined in UEFI specification.
+ ///
+ UINT32 Attributes;
+ ///
+ /// Associated monotonic count value against replay attack.
+ ///
+ UINT64 MonotonicCount;
+ ///
+ /// Associated TimeStamp value against replay attack.
+ ///
+ EFI_TIME TimeStamp;
+ ///
+ /// Index of associated public key in database.
+ ///
+ UINT32 PubKeyIndex;
+ ///
+ /// Size of variable null-terminated Unicode string name.
+ ///
+ UINT32 NameSize;
+ ///
+ /// Size of the variable data without this header.
+ ///
+ UINT32 DataSize;
+ ///
+ /// A unique identifier for the vendor that produces and consumes this varaible.
+ ///
+ EFI_GUID VendorGuid;
+} AUTHENTICATED_VARIABLE_HEADER;
+
+#pragma pack()
+
+#endif