]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
index 4fd83f807281f9b7c70ae590aea85b04b38f97fc..6da0e30c989fbc6c882900984ed298f9db293a35 100644 (file)
@@ -1,25 +1,29 @@
 /** @file\r
 Implementation for EFI_HII_DATABASE_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 #include "HiiDatabase.h"\r
 \r
+#define BASE_NUMBER        10\r
+\r
 EFI_HII_PACKAGE_LIST_HEADER    *gRTDatabaseInfoBuffer = NULL;\r
 EFI_STRING                     gRTConfigRespBuffer    = NULL;\r
 UINTN                          gDatabaseInfoSize = 0;\r
 UINTN                          gConfigRespSize = 0;\r
-BOOLEAN                        gExportConfigResp = TRUE;\r
+BOOLEAN                        gExportConfigResp = FALSE;\r
+UINTN                          gNvDefaultStoreSize = 0;\r
+SKU_ID                         gSkuId              = 0xFFFFFFFFFFFFFFFF;\r
+LIST_ENTRY                     gVarStorageList     = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);\r
+\r
+//\r
+// HII database lock.\r
+//\r
+EFI_LOCK mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
 \r
 /**\r
   This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
@@ -531,6 +535,528 @@ RemoveGuidPackages (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Check the input question related to EFI variable\r
+\r
+  @param IfrQuestionHdr     Point to Question header\r
+  @param EfiVarStoreList    Point to EFI VarStore List\r
+  @param EfiVarStoreNumber  The number of EFI VarStore\r
+\r
+  @retval Index             The index of the found EFI varstore in EFI varstore list\r
+                            EfiVarStoreNumber will return if no EFI varstore is found.\r
+**/\r
+UINTN\r
+IsEfiVarStoreQuestion (\r
+  EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,\r
+  EFI_IFR_VARSTORE_EFI    **EfiVarStoreList,\r
+  UINTN                   EfiVarStoreNumber\r
+  )\r
+{\r
+  UINTN Index;\r
+  for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
+    if (IfrQuestionHdr->VarStoreId == EfiVarStoreList[Index]->VarStoreId) {\r
+      return Index;\r
+    }\r
+  }\r
+\r
+  return EfiVarStoreNumber;\r
+}\r
+\r
+/**\r
+  Find the matched variable from the input variable storage.\r
+\r
+  @param[in] VariableStorage Point to the variable storage header.\r
+  @param[in] VarGuid         A unique identifier for the variable.\r
+  @param[in] VarAttribute    The attributes bitmask for the variable.\r
+  @param[in] VarName         A Null-terminated ascii string that is the name of the variable.\r
+\r
+  @return Pointer to the matched variable header or NULL if not found.\r
+**/\r
+VARIABLE_HEADER *\r
+FindVariableData (\r
+  IN  VARIABLE_STORE_HEADER  *VariableStorage,\r
+  IN  EFI_GUID               *VarGuid,\r
+  IN  UINT32                 VarAttribute,\r
+  IN  CHAR16                 *VarName\r
+  )\r
+{\r
+  VARIABLE_HEADER *VariableHeader;\r
+  VARIABLE_HEADER *VariableEnd;\r
+\r
+  VariableEnd    = (VARIABLE_HEADER *) ((UINT8 *) VariableStorage + VariableStorage->Size);\r
+  VariableHeader = (VARIABLE_HEADER *) (VariableStorage + 1);\r
+  VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableHeader);\r
+  while (VariableHeader < VariableEnd) {\r
+    if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&\r
+        VariableHeader->Attributes == VarAttribute &&\r
+        StrCmp (VarName, (CHAR16 *) (VariableHeader + 1)) == 0) {\r
+      return VariableHeader;\r
+    }\r
+    VariableHeader = (VARIABLE_HEADER *) ((UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);\r
+    VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableHeader);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Find question default value from PcdNvStoreDefaultValueBuffer\r
+\r
+  @param DefaultId          Default store ID\r
+  @param EfiVarStore        Point to EFI VarStore header\r
+  @param IfrQuestionHdr     Point to Question header\r
+  @param ValueBuffer        Point to Buffer includes the found default setting\r
+  @param Width              Width of the default value\r
+  @param BitFieldQuestion   Whether the Question is stored in Bit field.\r
+\r
+  @retval EFI_SUCCESS       Question default value is found.\r
+  @retval EFI_NOT_FOUND     Question default value is not found.\r
+**/\r
+EFI_STATUS\r
+FindQuestionDefaultSetting (\r
+  IN  UINT16                  DefaultId,\r
+  IN  EFI_IFR_VARSTORE_EFI    *EfiVarStore,\r
+  IN  EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,\r
+  OUT VOID                    *ValueBuffer,\r
+  IN  UINTN                   Width,\r
+  IN  BOOLEAN                 BitFieldQuestion\r
+  )\r
+{\r
+  VARIABLE_HEADER            *VariableHeader;\r
+  VARIABLE_STORE_HEADER      *VariableStorage;\r
+  LIST_ENTRY                 *Link;\r
+  VARSTORAGE_DEFAULT_DATA    *Entry;\r
+  VARIABLE_STORE_HEADER      *NvStoreBuffer;\r
+  UINT8        *DataBuffer;\r
+  UINT8        *BufferEnd;\r
+  BOOLEAN      IsFound;\r
+  UINTN        Index;\r
+  UINT32       BufferValue;\r
+  UINT32       BitFieldVal;\r
+  UINTN        BitOffset;\r
+  UINTN        ByteOffset;\r
+  UINTN        BitWidth;\r
+  UINTN        StartBit;\r
+  UINTN        EndBit;\r
+  PCD_DEFAULT_DATA *DataHeader;\r
+  PCD_DEFAULT_INFO *DefaultInfo;\r
+  PCD_DATA_DELTA   *DeltaData;\r
+\r
+  if (gSkuId == 0xFFFFFFFFFFFFFFFF) {\r
+    gSkuId = LibPcdGetSku ();\r
+  }\r
+\r
+  //\r
+  // Find the DefaultId setting from the full DefaultSetting\r
+  //\r
+  VariableStorage = NULL;\r
+  Link = gVarStorageList.ForwardLink;\r
+  while (Link != &gVarStorageList) {\r
+    Entry = BASE_CR (Link, VARSTORAGE_DEFAULT_DATA, Entry);\r
+    if (Entry->DefaultId == DefaultId) {\r
+      VariableStorage = Entry->VariableStorage;\r
+      break;\r
+    }\r
+    Link = Link->ForwardLink;\r
+  }\r
+\r
+  if (Link == &gVarStorageList) {\r
+    DataBuffer = (UINT8 *) PcdGetPtr (PcdNvStoreDefaultValueBuffer);\r
+    gNvDefaultStoreSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;\r
+    //\r
+    // The first section data includes NV storage default setting.\r
+    //\r
+    DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));\r
+    NvStoreBuffer  = (VARIABLE_STORE_HEADER *) ((UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);\r
+    VariableStorage   = AllocatePool (NvStoreBuffer->Size);\r
+    ASSERT (VariableStorage != NULL);\r
+    CopyMem (VariableStorage, NvStoreBuffer, NvStoreBuffer->Size);\r
+\r
+    //\r
+    // Find the matched SkuId and DefaultId in the first section\r
+    //\r
+    IsFound = FALSE;\r
+    DefaultInfo    = &(DataHeader->DefaultInfo[0]);\r
+    BufferEnd      = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
+    while ((UINT8 *) DefaultInfo < BufferEnd) {\r
+      if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == gSkuId) {\r
+        IsFound = TRUE;\r
+        break;\r
+      }\r
+      DefaultInfo ++;\r
+    }\r
+    //\r
+    // Find the matched SkuId and DefaultId in the remaining section\r
+    //\r
+    Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));\r
+    DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
+    while (!IsFound && Index < gNvDefaultStoreSize && DataHeader->DataSize != 0xFFFF) {\r
+      DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
+      BufferEnd   = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
+      while ((UINT8 *) DefaultInfo < BufferEnd) {\r
+        if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == gSkuId) {\r
+          IsFound = TRUE;\r
+          break;\r
+        }\r
+        DefaultInfo ++;\r
+      }\r
+      if (IsFound) {\r
+        DeltaData = (PCD_DATA_DELTA *) BufferEnd;\r
+        BufferEnd = (UINT8 *) DataHeader + DataHeader->DataSize;\r
+        while ((UINT8 *) DeltaData < BufferEnd) {\r
+          *((UINT8 *) VariableStorage + DeltaData->Offset) = (UINT8) DeltaData->Value;\r
+          DeltaData ++;\r
+        }\r
+        break;\r
+      }\r
+      Index      = (Index + DataHeader->DataSize + 7) & (~7);\r
+      DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
+    }\r
+    //\r
+    // Cache the found result in VarStorageList\r
+    //\r
+    if (!IsFound) {\r
+      FreePool (VariableStorage);\r
+      VariableStorage = NULL;\r
+    }\r
+    Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));\r
+    if (Entry != NULL) {\r
+      Entry->DefaultId = DefaultId;\r
+      Entry->VariableStorage = VariableStorage;\r
+      InsertTailList (&gVarStorageList, &Entry->Entry);\r
+    } else if (VariableStorage != NULL) {\r
+      FreePool (VariableStorage);\r
+      VariableStorage = NULL;\r
+    }\r
+  }\r
+  //\r
+  // The matched variable storage is not found.\r
+  //\r
+  if (VariableStorage == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Find the question default value from the variable storage\r
+  //\r
+  VariableHeader = FindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *) EfiVarStore->Name);\r
+  if (VariableHeader == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  StartBit   = 0;\r
+  EndBit     = 0;\r
+  ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+  if (BitFieldQuestion) {\r
+    BitOffset  = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+    ByteOffset = BitOffset / 8;\r
+    BitWidth   = Width;\r
+    StartBit   = BitOffset % 8;\r
+    EndBit     = StartBit + BitWidth - 1;\r
+    Width      = EndBit / 8 + 1;\r
+  }\r
+  if (VariableHeader->DataSize < ByteOffset + Width) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Copy the question value\r
+  //\r
+  if (ValueBuffer != NULL) {\r
+    if (BitFieldQuestion) {\r
+      CopyMem (&BufferValue, (UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + ByteOffset, Width);\r
+      BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+      CopyMem (ValueBuffer, &BitFieldVal, Width);\r
+    } else {\r
+      CopyMem (ValueBuffer, (UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update IFR default setting in Form Package.\r
+\r
+  @param  FormPackage              Form Package to be updated\r
+\r
+**/\r
+VOID\r
+UpdateDefaultSettingInFormPackage (\r
+  HII_IFR_PACKAGE_INSTANCE *FormPackage\r
+  )\r
+{\r
+  UINTN                    IfrOffset;\r
+  UINTN                    PackageLength;\r
+  EFI_IFR_VARSTORE_EFI     *IfrEfiVarStore;\r
+  EFI_IFR_OP_HEADER        *IfrOpHdr;\r
+  EFI_IFR_ONE_OF_OPTION    *IfrOneOfOption;\r
+  UINT8                    IfrQuestionType;\r
+  UINT8                    IfrScope;\r
+  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;\r
+  EFI_IFR_VARSTORE_EFI     **EfiVarStoreList;\r
+  UINTN                    EfiVarStoreMaxNum;\r
+  UINTN                    EfiVarStoreNumber;\r
+  UINT16                   *DefaultIdList;\r
+  UINTN                    DefaultIdNumber;\r
+  UINTN                    DefaultIdMaxNum;\r
+  UINTN                    Index;\r
+  UINTN                    EfiVarStoreIndex;\r
+  EFI_IFR_TYPE_VALUE       IfrValue;\r
+  EFI_IFR_TYPE_VALUE       IfrManufactValue;\r
+  BOOLEAN                  StandardDefaultIsSet;\r
+  BOOLEAN                  ManufactDefaultIsSet;\r
+  EFI_IFR_CHECKBOX         *IfrCheckBox;\r
+  EFI_STATUS               Status;\r
+  EFI_IFR_DEFAULT          *IfrDefault;\r
+  UINTN                    Width;\r
+  EFI_IFR_QUESTION_HEADER  VarStoreQuestionHeader;\r
+  BOOLEAN                  QuestionReferBitField;\r
+\r
+  //\r
+  // If no default setting, do nothing\r
+  //\r
+  if (gNvDefaultStoreSize == 0) {\r
+    gNvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);\r
+  }\r
+  if (gNvDefaultStoreSize < sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
+    return;\r
+  }\r
+\r
+  ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));\r
+  PackageLength = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);\r
+  Width         = 0;\r
+  IfrOffset     = 0;\r
+  IfrScope      = 0;\r
+  IfrOpHdr      = (EFI_IFR_OP_HEADER *) FormPackage->IfrData;\r
+  IfrQuestionHdr    = NULL;\r
+  IfrQuestionType   = 0;\r
+  EfiVarStoreMaxNum = 0;\r
+  EfiVarStoreNumber = 0;\r
+  DefaultIdMaxNum   = 0;\r
+  DefaultIdNumber   = 0;\r
+  EfiVarStoreList   = NULL;\r
+  DefaultIdList     = NULL;\r
+  StandardDefaultIsSet = FALSE;\r
+  ManufactDefaultIsSet = FALSE;\r
+  QuestionReferBitField = FALSE;\r
+\r
+  while (IfrOffset < PackageLength) {\r
+    switch (IfrOpHdr->OpCode) {\r
+    case EFI_IFR_VARSTORE_EFI_OP:\r
+      if (EfiVarStoreNumber >= EfiVarStoreMaxNum) {\r
+        //\r
+        // Reallocate EFI VarStore Buffer\r
+        //\r
+        EfiVarStoreList   = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);\r
+        if (EfiVarStoreList == NULL) {\r
+          goto Done;\r
+        }\r
+        EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;\r
+      }\r
+      IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+      //\r
+      // Convert VarStore Name from ASCII string to Unicode string.\r
+      //\r
+      EfiVarStoreList [EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));\r
+      if (EfiVarStoreList [EfiVarStoreNumber] == NULL) {\r
+        break;\r
+      }\r
+      CopyMem (EfiVarStoreList [EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *) &(EfiVarStoreList [EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+      Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);\r
+      if (!EFI_ERROR (Status)) {\r
+        EfiVarStoreNumber ++;\r
+      } else {\r
+        FreePool (EfiVarStoreList [EfiVarStoreNumber]);\r
+        EfiVarStoreList [EfiVarStoreNumber] = NULL;\r
+      }\r
+      break;\r
+    case EFI_IFR_DEFAULTSTORE_OP:\r
+      if (DefaultIdNumber >= DefaultIdMaxNum) {\r
+        //\r
+        // Reallocate DefaultIdNumber\r
+        //\r
+        DefaultIdList   = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);\r
+        if (DefaultIdList == NULL) {\r
+          goto Done;\r
+        }\r
+        DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;\r
+      }\r
+      DefaultIdList[DefaultIdNumber ++] = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId;\r
+      break;\r
+    case EFI_IFR_FORM_OP:\r
+    case EFI_IFR_FORM_MAP_OP:\r
+      //\r
+      // No EFI varstore is found and directly return.\r
+      //\r
+      if (EfiVarStoreNumber == 0 || DefaultIdNumber == 0) {\r
+        goto Done;\r
+      }\r
+      break;\r
+    case EFI_IFR_CHECKBOX_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      IfrCheckBox      = (EFI_IFR_CHECKBOX *) IfrOpHdr;\r
+      EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
+      Width            = sizeof (BOOLEAN);\r
+      if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
+        for (Index = 0; Index < DefaultIdNumber; Index ++) {\r
+          if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+            Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              if (IfrValue.b) {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT;\r
+              } else {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT);\r
+              }\r
+            }\r
+          } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+            Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              if (IfrValue.b) {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT_MFG;\r
+              } else {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT_MFG);\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_NUMERIC_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      if (QuestionReferBitField) {\r
+        Width          = (UINTN) (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);\r
+      } else {\r
+        Width          = (UINTN) ((UINT32) 1 << (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));\r
+      }\r
+      break;\r
+    case EFI_IFR_ONE_OF_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      if (QuestionReferBitField) {\r
+        Width          = (UINTN) (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);\r
+      } else {\r
+        Width          = (UINTN) ((UINT32) 1 << (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));\r
+      }\r
+      EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
+      StandardDefaultIsSet = FALSE;\r
+      ManufactDefaultIsSet = FALSE;\r
+      //\r
+      // Find Default and Manufacturing default for OneOf question\r
+      //\r
+      if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
+        for (Index = 0; Index < DefaultIdNumber; Index ++) {\r
+          if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+            Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, Width, QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              StandardDefaultIsSet = TRUE;\r
+            }\r
+          } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+            Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrManufactValue, Width, QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              ManufactDefaultIsSet = TRUE;\r
+            }\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_ORDERED_LIST_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      break;\r
+    case EFI_IFR_ONE_OF_OPTION_OP:\r
+      if (IfrQuestionHdr != NULL && IfrScope > 0) {\r
+        IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpHdr;\r
+        if (IfrQuestionType == EFI_IFR_ONE_OF_OP) {\r
+          Width = (UINTN) ((UINT32) 1 << (IfrOneOfOption->Flags & EFI_IFR_NUMERIC_SIZE));\r
+          if (StandardDefaultIsSet) {\r
+            if (CompareMem (&IfrOneOfOption->Value, &IfrValue, Width) == 0) {\r
+              IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;\r
+            } else {\r
+              IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT;\r
+            }\r
+          }\r
+          if (ManufactDefaultIsSet) {\r
+            if (CompareMem (&IfrOneOfOption->Value, &IfrManufactValue, Width) == 0) {\r
+              IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;\r
+            } else {\r
+              IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT_MFG;\r
+            }\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_DEFAULT_OP:\r
+      if (IfrQuestionHdr != NULL && IfrScope > 0) {\r
+        IfrDefault = (EFI_IFR_DEFAULT *) IfrOpHdr;\r
+        //\r
+        // Collect default value width\r
+        //\r
+        if (!QuestionReferBitField) {\r
+          Width = 0;\r
+          if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_8 || IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN) {\r
+            Width = 1;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_16) {\r
+            Width = 2;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_32) {\r
+            Width = 4;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_64) {\r
+            Width = 8;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_BUFFER) {\r
+            Width = IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value);\r
+          }\r
+        }\r
+        //\r
+        // Update the default value\r
+        //\r
+        if (Width > 0) {\r
+          EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
+          if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
+            Status = FindQuestionDefaultSetting (IfrDefault->DefaultId, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrDefault->Value, Width, QuestionReferBitField);\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_END_OP:\r
+      if (IfrQuestionHdr != NULL) {\r
+        if (IfrScope > 0) {\r
+          IfrScope --;\r
+        }\r
+        if (IfrScope == 0) {\r
+          IfrQuestionHdr = NULL;\r
+          QuestionReferBitField = FALSE;\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_GUID_OP:\r
+      if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+        QuestionReferBitField = TRUE;\r
+      }\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    IfrOffset = IfrOffset + IfrOpHdr->Length;\r
+    IfrOpHdr  = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrOpHdr + IfrOpHdr->Length);\r
+    if (IfrScope > 0) {\r
+      IfrScope += IfrOpHdr->Scope;\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (EfiVarStoreList != NULL) {\r
+    for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
+      FreePool (EfiVarStoreList [Index]);\r
+    }\r
+  }\r
+  return;\r
+}\r
 \r
 /**\r
   This function insert a Form package to a package list node.\r
@@ -601,6 +1127,11 @@ InsertFormPackage (
   InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);\r
   *Package = FormPackage;\r
 \r
+  //\r
+  // Update FormPackage with the default setting\r
+  //\r
+  UpdateDefaultSettingInFormPackage (FormPackage);\r
+\r
   if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
     PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;\r
   }\r
@@ -899,7 +1430,7 @@ Error:
 \r
 /**\r
  Adjust all string packages in a single package list to have the same max string ID.\r
\r
+\r
  @param  PackageList        Pointer to a package list which will be adjusted.\r
 \r
  @retval EFI_SUCCESS  Adjust all string packages successfully.\r
@@ -2622,7 +3153,7 @@ AddPackages (
     PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
     CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
   }\r
-  \r
+\r
   //\r
   // Adjust String Package to make sure all string packages have the same max string ID.\r
   //\r
@@ -2903,39 +3434,6 @@ HiiGetDatabaseInfo(
 \r
 }\r
 \r
-/**\r
-This  function mainly use to get and update configuration settings information.\r
-\r
-@param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.\r
-\r
-@retval EFI_SUCCESS            Get the information successfully.\r
-@retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Configuration Setting data.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiGetConfigurationSetting(\r
-  IN CONST EFI_HII_DATABASE_PROTOCOL        *This\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-\r
-  //\r
-  // Get the HiiDatabase info.\r
-  //\r
-  Status = HiiGetDatabaseInfo(This);\r
-\r
-  //\r
-  // Get ConfigResp string\r
-  //\r
-  if (gExportConfigResp) {\r
-    Status = HiiGetConfigRespInfo (This);\r
-    gExportConfigResp = FALSE;\r
-  }\r
-  return Status;\r
-\r
-}\r
-\r
-\r
 /**\r
   This function adds the packages in the package list to the database and returns a handle. If there is a\r
   EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will\r
@@ -2988,17 +3486,20 @@ HiiNewPackageList (
     DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
     if (CompareGuid (\r
           &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
-          &PackageListGuid) && \r
+          &PackageListGuid) &&\r
         DatabaseRecord->DriverHandle == DriverHandle) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   //\r
   // Build a PackageList node\r
   //\r
   Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -3008,6 +3509,7 @@ HiiNewPackageList (
   //\r
   Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -3029,11 +3531,28 @@ HiiNewPackageList (
   *Handle = DatabaseRecord->Handle;\r
 \r
   //\r
-  // Check whether need to get the Database and configuration setting info.\r
+  // Check whether need to get the Database info.\r
   // Only after ReadyToBoot, need to do the export.\r
   //\r
   if (gExportAfterReadyToBoot) {\r
-    HiiGetConfigurationSetting(This);\r
+    HiiGetDatabaseInfo (This);\r
+  }\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+  //\r
+  // Notes:\r
+  // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+  // belong to the atomic behavior of Hii Database update.\r
+  // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+  // we can not think it belong to the atomic behavior of Hii Database update.\r
+  // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+  //\r
+\r
+  // Check whether need to get the configuration setting info from HII drivers.\r
+  // When after ReadyToBoot and need to do the export for form package add.\r
+  //\r
+  if (gExportAfterReadyToBoot && gExportConfigResp) {\r
+    HiiGetConfigRespInfo (This);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -3078,6 +3597,8 @@ HiiRemovePackageList (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   //\r
@@ -3095,34 +3616,42 @@ HiiRemovePackageList (
       //\r
       Status = RemoveGuidPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFormPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveStringPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveImagePackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
 \r
@@ -3142,16 +3671,35 @@ HiiRemovePackageList (
       FreePool (Node);\r
 \r
       //\r
-      // Check whether need to get the Database and configuration setting info.\r
+      // Check whether need to get the Database info.\r
       // Only after ReadyToBoot, need to do the export.\r
       //\r
       if (gExportAfterReadyToBoot) {\r
-        HiiGetConfigurationSetting(This);\r
+        HiiGetDatabaseInfo (This);\r
+      }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
+\r
+      //\r
+      // Check whether need to get the configuration setting info from HII drivers.\r
+      // When after ReadyToBoot and need to do the export for form package remove.\r
+      //\r
+      if (gExportAfterReadyToBoot && gExportConfigResp) {\r
+        HiiGetConfigRespInfo (This);\r
       }\r
       return EFI_SUCCESS;\r
     }\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3204,6 +3752,7 @@ HiiUpdatePackageList (
 \r
   Status = EFI_SUCCESS;\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
   //\r
   // Get original packagelist to be updated\r
   //\r
@@ -3245,6 +3794,7 @@ HiiUpdatePackageList (
         }\r
 \r
         if (EFI_ERROR (Status)) {\r
+          EfiReleaseLock (&mHiiDatabaseLock);\r
           return Status;\r
         }\r
 \r
@@ -3258,19 +3808,35 @@ HiiUpdatePackageList (
       Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
 \r
       //\r
-      // Check whether need to get the Database and configuration setting info.\r
+      // Check whether need to get the Database info.\r
       // Only after ReadyToBoot, need to do the export.\r
       //\r
-      if (gExportAfterReadyToBoot) {\r
-        if (Status == EFI_SUCCESS){\r
-          HiiGetConfigurationSetting(This);\r
-        }\r
+      if (gExportAfterReadyToBoot && Status == EFI_SUCCESS) {\r
+        HiiGetDatabaseInfo (This);\r
+      }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
+\r
+      //\r
+      // Check whether need to get the configuration setting info from HII drivers.\r
+      // When after ReadyToBoot and need to do the export for form package update.\r
+      //\r
+      if (gExportAfterReadyToBoot && gExportConfigResp && Status == EFI_SUCCESS) {\r
+        HiiGetConfigRespInfo (This);\r
       }\r
 \r
       return Status;\r
     }\r
   }\r
-\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3460,7 +4026,7 @@ HiiListPackageLists (
   @retval EFI_NOT_FOUND          The specified Handle could not be found in the\r
                                  current database.\r
   @retval EFI_INVALID_PARAMETER  BufferSize was NULL.\r
-  @retval EFI_INVALID_PARAMETER  The value referenced by BufferSize was not zero \r
+  @retval EFI_INVALID_PARAMETER  The value referenced by BufferSize was not zero\r
                                  and Buffer was NULL.\r
 \r
 **/\r