]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
MdeModulePkg/HiiDatabase: Handle questions with Bit VarStore
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigRouting.c
index c9ff1cff627f9cf49e1ac6976d00a131d1b472c6..646864f4dfc1bc7a88019562408d011f5f9e2893 100644 (file)
@@ -1225,7 +1225,7 @@ InsertBlockData (
   for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
     BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
     if (BlockArray->Offset == BlockSingleData->Offset) {\r
-      if (BlockArray->Width > BlockSingleData->Width) {\r
+      if ((BlockArray->Width > BlockSingleData->Width) || (BlockSingleData->IsBitVar && BlockArray->Width == BlockSingleData->Width)) {\r
         //\r
         // Insert this block data in the front of block array\r
         //\r
@@ -1233,7 +1233,7 @@ InsertBlockData (
         return;\r
       }\r
 \r
-      if (BlockArray->Width == BlockSingleData->Width) {\r
+      if ((!BlockSingleData->IsBitVar) && BlockArray->Width == BlockSingleData->Width) {\r
         //\r
         // The same block array has been added.\r
         //\r
@@ -1980,6 +1980,7 @@ Done:
   @param  IfrOpHdr               Ifr opcode header for this opcode.\r
   @param  VarWidth               The buffer width for this opcode.\r
   @param  ReturnData             The data block added for this opcode.\r
+  @param  IsBitVar               Whether the the opcode refers to bit storage.\r
 \r
   @retval  EFI_SUCCESS           This opcode is required.\r
   @retval  EFI_NOT_FOUND         This opcode is not required.\r
@@ -1993,16 +1994,22 @@ IsThisOpcodeRequired (
   IN OUT IFR_VARSTORAGE_DATA      *VarStorageData,\r
   IN     EFI_IFR_OP_HEADER        *IfrOpHdr,\r
   IN     UINT16                   VarWidth,\r
-  OUT    IFR_BLOCK_DATA           **ReturnData\r
+  OUT    IFR_BLOCK_DATA           **ReturnData,\r
+  IN     BOOLEAN                  IsBitVar\r
   )\r
 {\r
   IFR_BLOCK_DATA           *BlockData;\r
   UINT16                   VarOffset;\r
   EFI_STRING_ID            NameId;\r
   EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;\r
+  UINT16                   BitOffset;\r
+  UINT16                   BitWidth;\r
+  UINT16                   TotalBits;\r
 \r
   NameId    = 0;\r
   VarOffset = 0;\r
+  BitOffset = 0;\r
+  BitWidth = 0;\r
   IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER  *)((CHAR8 *) IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));\r
 \r
   if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
@@ -2018,7 +2025,23 @@ IsThisOpcodeRequired (
       return EFI_NOT_FOUND;\r
     }\r
   } else {\r
-    VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+    //\r
+    // Get the byte offset/with and bit offset/width\r
+    //\r
+    if (IsBitVar) {\r
+      BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+      BitWidth = VarWidth;\r
+      VarOffset = BitOffset / 8;\r
+      //\r
+      // Use current bit width and the bit width before current bit (with same byte offset) to calculate the byte width.\r
+      //\r
+      TotalBits = BitOffset % 8 + BitWidth;\r
+      VarWidth = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);\r
+    } else {\r
+      VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+      BitWidth = VarWidth;\r
+      BitOffset = VarOffset * 8;\r
+    }\r
     \r
     //\r
     // Check whether this question is in requested block array.\r
@@ -2053,6 +2076,9 @@ IsThisOpcodeRequired (
   BlockData->QuestionId = IfrQuestionHdr->QuestionId;\r
   BlockData->OpCode     = IfrOpHdr->OpCode;\r
   BlockData->Scope      = IfrOpHdr->Scope;\r
+  BlockData->IsBitVar   = IsBitVar;\r
+  BlockData->BitOffset  = BitOffset;\r
+  BlockData->BitWidth   = BitWidth;\r
   InitializeListHead (&BlockData->DefaultValueEntry);\r
   //\r
   // Add Block Data into VarStorageData BlockEntry\r
@@ -2126,6 +2152,7 @@ ParseIfrData (
   UINT16                   SmallestDefaultId;\r
   BOOLEAN                  SmallestIdFromFlag;\r
   BOOLEAN                  FromOtherDefaultOpcode;\r
+  BOOLEAN                  QuestionReferBitField;\r
 \r
   Status           = EFI_SUCCESS;\r
   BlockData        = NULL;\r
@@ -2137,6 +2164,7 @@ ParseIfrData (
   ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));\r
   SmallestDefaultId = 0xFFFF;\r
   FromOtherDefaultOpcode = FALSE;\r
+  QuestionReferBitField = FALSE;\r
 \r
   //\r
   // Go through the form package to parse OpCode one by one.\r
@@ -2311,7 +2339,7 @@ ParseIfrData (
         BlockData = NULL;\r
       }\r
 \r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2343,7 +2371,12 @@ ParseIfrData (
       if (IfrOneOf->Question.VarStoreId != VarStoreId) {\r
         break;\r
       }\r
-      VarWidth  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+\r
+      if (QuestionReferBitField) {\r
+        VarWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+      } else {\r
+        VarWidth  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+      }\r
 \r
       //\r
       // The BlockData may allocate by other opcode,need to clean.\r
@@ -2352,7 +2385,7 @@ ParseIfrData (
         BlockData = NULL;\r
       }\r
 \r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2378,26 +2411,33 @@ ParseIfrData (
         // Numeric minimum value will be used as default value when no default is specified. \r
         //\r
         DefaultData.Type        = DefaultValueFromDefault;\r
-        switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-        case EFI_IFR_NUMERIC_SIZE_1:\r
-          DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
-          break;\r
+        if (QuestionReferBitField) {\r
+          //\r
+          // Since default value in bit field was stored as UINT32 type.\r
+          //\r
+          CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+        } else {\r
+          switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+          case EFI_IFR_NUMERIC_SIZE_1:\r
+            DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
+            break;\r
 \r
-        case EFI_IFR_NUMERIC_SIZE_2:\r
-          CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
-          break;\r
+          case EFI_IFR_NUMERIC_SIZE_2:\r
+           CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
+           break;\r
 \r
-        case EFI_IFR_NUMERIC_SIZE_4:\r
-          CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
-          break;\r
+          case EFI_IFR_NUMERIC_SIZE_4:\r
+            CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+            break;\r
 \r
-        case EFI_IFR_NUMERIC_SIZE_8:\r
-          CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));\r
-          break;\r
+          case EFI_IFR_NUMERIC_SIZE_8:\r
+            CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));\r
+            break;\r
 \r
-        default:\r
-          Status = EFI_INVALID_PARAMETER;\r
-          goto Done;\r
+          default:\r
+            Status = EFI_INVALID_PARAMETER;\r
+            goto Done;\r
+         }\r
         }\r
         //\r
         // Set default value base on the DefaultId list get from IFR data.\r
@@ -2441,7 +2481,7 @@ ParseIfrData (
         BlockData = NULL;\r
       }\r
 \r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2486,7 +2526,10 @@ ParseIfrData (
         BlockData = NULL;\r
       }\r
 \r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (QuestionReferBitField) {\r
+        VarWidth = 1;\r
+      }\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2517,7 +2560,11 @@ ParseIfrData (
         // When flag is set, default value is TRUE.\r
         //\r
         DefaultData.Type    = DefaultValueFromFlag;\r
-        DefaultData.Value.b = TRUE;\r
+        if (QuestionReferBitField) {\r
+          DefaultData.Value.u32 = TRUE;\r
+        } else {\r
+          DefaultData.Value.b = TRUE;\r
+        }\r
         InsertDefaultValue (BlockData, &DefaultData);\r
 \r
         if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
@@ -2542,7 +2589,11 @@ ParseIfrData (
         // When flag is set, default value is TRUE.\r
         //\r
         DefaultData.Type    = DefaultValueFromFlag;\r
-        DefaultData.Value.b = TRUE;\r
+        if (QuestionReferBitField) {\r
+          DefaultData.Value.u32 = TRUE;\r
+        } else {\r
+          DefaultData.Value.b = TRUE;\r
+        }\r
         InsertDefaultValue (BlockData, &DefaultData);\r
 \r
         if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
@@ -2558,7 +2609,11 @@ ParseIfrData (
         // When smallest default Id is given by the  flag of CheckBox, set default value with TRUE for other default Id in the DefaultId list.\r
         //\r
         DefaultData.Type    = DefaultValueFromOtherDefault;\r
-        DefaultData.Value.b = TRUE;\r
+        if (QuestionReferBitField) {\r
+          DefaultData.Value.u32 = TRUE;\r
+        } else {\r
+          DefaultData.Value.b = TRUE;\r
+        }\r
         //\r
         // Set default value for all the default id in the DefaultId list.\r
         //\r
@@ -2572,7 +2627,11 @@ ParseIfrData (
         // When flag is not set, default value is FASLE.\r
         //\r
         DefaultData.Type    = DefaultValueFromDefault;\r
-        DefaultData.Value.b = FALSE;\r
+        if (QuestionReferBitField) {\r
+          DefaultData.Value.u32 = FALSE;\r
+        } else {\r
+          DefaultData.Value.b = FALSE;\r
+        }\r
         //\r
         // Set default value for all the default id in the DefaultId list.\r
         //\r
@@ -2614,7 +2673,7 @@ ParseIfrData (
       }\r
 \r
       VarWidth  = (UINT16) sizeof (EFI_HII_DATE);\r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2656,7 +2715,7 @@ ParseIfrData (
       }\r
 \r
       VarWidth  = (UINT16) sizeof (EFI_HII_TIME);\r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2698,7 +2757,7 @@ ParseIfrData (
       }\r
 \r
       VarWidth  = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2740,7 +2799,7 @@ ParseIfrData (
       }\r
 \r
       VarWidth  = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));\r
-      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         if (Status == EFI_NOT_FOUND){\r
           //\r
@@ -2932,7 +2991,11 @@ ParseIfrData (
       //\r
       DefaultData.Type        = DefaultValueFromOpcode;\r
       DefaultData.DefaultId   = VarDefaultId;\r
-      CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+      if (QuestionReferBitField) {\r
+        CopyMem (&DefaultData.Value.u32, &IfrDefault->Value.u32, sizeof (UINT32));\r
+      } else {\r
+        CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+      }\r
 \r
       // If the value field is expression, set the cleaned flag.\r
       if (IfrDefault->Type ==  EFI_IFR_TYPE_OTHER) {\r
@@ -2974,6 +3037,7 @@ ParseIfrData (
       //\r
       // End Opcode is for Var question.\r
       //\r
+      QuestionReferBitField = FALSE;\r
       if (BlockData != NULL) {\r
         if (BlockData->Scope > 0) {\r
           BlockData->Scope--;\r
@@ -2990,6 +3054,12 @@ ParseIfrData (
 \r
       break;\r
 \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
+\r
     default:\r
       if (BlockData != NULL) {\r
         if (BlockData->Scope > 0) {\r
@@ -3568,6 +3638,212 @@ GetStorageWidth (
   return StorageWidth;\r
 }\r
 \r
+/**\r
+  Update the default value in the block data which is used as bit var store.\r
+\r
+  For example:\r
+  A question value saved in a bit fied: bitoffset = 1; bitwidth = 2;default value = 1.\r
+  And corresponding block data info: offset==0; width==1;currently the default value\r
+  is saved as 1.Actually the default value 1 need to be set to bit field 1, so the\r
+  default value of this block data shuold be:2.\r
+\r
+  typedef struct {\r
+    UINT8  Bit1 : 1; //\r
+    UINT8  Bit2 : 2; // Question saved in Bit2,so originalBlock info: offset = 0; width = 1;(byte level) defaul = 1.\r
+                     // (default value record for the bit field)\r
+    ......\r
+  }ExampleData;\r
+\r
+  After function UpdateDefaultValue,the Block info is: offset = 0; width = 1;(byte level) default = 2.\r
+                                                       (default value record for the Block)\r
+\r
+  UpdateDefaultValue function update default value of bit var block based on the bit field info in the block.\r
+\r
+  @param  BlockLink     The Link of the block data.\r
+\r
+**/\r
+VOID\r
+UpdateDefaultValue (\r
+  IN LIST_ENTRY        *BlockLink\r
+)\r
+{\r
+  LIST_ENTRY          *Link;\r
+  LIST_ENTRY          *ListEntry;\r
+  LIST_ENTRY          *LinkDefault;\r
+  IFR_BLOCK_DATA      *BlockData;\r
+  IFR_DEFAULT_DATA    *DefaultValueData;\r
+  UINTN               StartBit;\r
+  UINTN               EndBit;\r
+  UINT32              BitFieldDefaultValue;\r
+\r
+  for ( Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (!BlockData ->IsBitVar) {\r
+      continue;\r
+    }\r
+    ListEntry  = &BlockData->DefaultValueEntry;\r
+    //\r
+    // Update the default value in the block data with all existing default id.\r
+    //\r
+    for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+      //\r
+      // Get the default data, and the value of the default data is for some field in the block.\r
+      // Note: Default value for bit field question is stored as UINT32.\r
+      //\r
+      DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+      BitFieldDefaultValue = DefaultValueData->Value.u32;\r
+\r
+      StartBit = BlockData->BitOffset % 8;\r
+      EndBit = StartBit + BlockData->BitWidth - 1;\r
+\r
+      //\r
+      // Set the bit field default value to related bit filed, then we will got the new default vaule for the block data.\r
+      //\r
+      DefaultValueData->Value.u32 = BitFieldWrite32 (0, StartBit, EndBit, BitFieldDefaultValue);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+Merge the default value in two block datas which have overlap region.\r
+\r
+For bit fields, their related block data may have overlap region, such as:\r
+\r
+typedef struct {\r
+  UINT16  Bit1 : 6;  // Question1 refer Bit1, Block1: offset = 0; width = 1;(byte level) default = 1\r
+  UINT16  Bit2 : 5;  // Question2 refer Bit2, Block2: offset = 0; width = 2;(byte level) default = 5\r
+                     // (default value record for the bit field)\r
+  ......\r
+}ExampleData;\r
+\r
+After function UpdateDefaultValue:\r
+Block1: offset = 0; width = 1;(byte level) default = 1\r
+Block2: offset = 0; width = 2;(byte level) default = 320 (5 * (2 << 6))\r
+(default value record for block)\r
+\r
+After function MergeBlockDefaultValue:\r
+Block1: offset = 0; width = 1;(byte level) default = 65\r
+Block2: offset = 0; width = 2;(byte level) default = 321\r
+(Block1 and Block2 has overlap region, merge the overlap value to Block1 and Blcok2)\r
+\r
+Block1 and Block2 have overlap byte region, but currntly the default value of Block1 only contains\r
+value of Bit1 (low 6 bits),the default value of Block2 only contains the value of Bit2 (middle 5 bits).\r
+\r
+This fuction merge the default value of these two blocks, and make the default value of block1\r
+also contain the value of lower 2 bits of the Bit2. And make the default value of Block2 also\r
+contain the default value of Bit1.\r
+\r
+We can get the total value of the whole block that just cover these two blocks(in this case is:\r
+block: offset =0; width =2;) then the value of block2 is same as block, the value of block1 is\r
+the first byte value of block.\r
+\r
+@param  FirstBlock     Point to the block date whose default value need to be merged.\r
+@param  SecondBlock    Point to the block date whose default value need to be merged.\r
+\r
+**/\r
+VOID\r
+MergeBlockDefaultValue (\r
+  IN OUT IFR_BLOCK_DATA      *FirstBlock,\r
+  IN OUT IFR_BLOCK_DATA      *SecondBlock\r
+)\r
+{\r
+  LIST_ENTRY          *FirstListEntry;\r
+  LIST_ENTRY          *SecondListEntry;\r
+  LIST_ENTRY          *FirstDefaultLink;\r
+  LIST_ENTRY          *SecondDefaultLink;\r
+  IFR_DEFAULT_DATA    *FirstDefaultValueData;\r
+  IFR_DEFAULT_DATA    *SecondDefaultValueData;\r
+  UINT32              *FirstDefaultValue;\r
+  UINT32              *SecondDefaultValue;\r
+  UINT64              TotalValue;\r
+  UINT64              ShiftedValue;\r
+  UINT16              OffsetShift;\r
+\r
+  FirstListEntry = &FirstBlock->DefaultValueEntry;\r
+  for (FirstDefaultLink = FirstListEntry->ForwardLink; FirstDefaultLink != FirstListEntry; FirstDefaultLink = FirstDefaultLink->ForwardLink) {\r
+    FirstDefaultValueData = BASE_CR (FirstDefaultLink, IFR_DEFAULT_DATA, Entry);\r
+    SecondListEntry = &SecondBlock->DefaultValueEntry;\r
+    for (SecondDefaultLink = SecondListEntry->ForwardLink; SecondDefaultLink != SecondListEntry; SecondDefaultLink = SecondDefaultLink->ForwardLink) {\r
+      SecondDefaultValueData = BASE_CR (SecondDefaultLink, IFR_DEFAULT_DATA, Entry);\r
+      if (FirstDefaultValueData->DefaultId != SecondDefaultValueData->DefaultId) {\r
+        continue;\r
+      }\r
+      //\r
+      // Find default value with same default id in the two blocks.\r
+      // Note: Default value for bit field question is stored as UINT32 type.\r
+      //\r
+      FirstDefaultValue = &FirstDefaultValueData->Value.u32;\r
+      SecondDefaultValue = &SecondDefaultValueData->Value.u32;\r
+      //\r
+      // 1. Get the default value of the whole blcok that can just cover FirstBlock and SecondBlock.\r
+      // 2. Get the default value of FirstBlock and SecondBlock form the value of whole block based\r
+      //    on the offset and width of FirstBlock and SecondBlock.\r
+      //\r
+      if (FirstBlock->Offset > SecondBlock->Offset) {\r
+        OffsetShift = FirstBlock->Offset - SecondBlock->Offset;\r
+        ShiftedValue = LShiftU64 ((UINT64) (*FirstDefaultValue), OffsetShift * 8);\r
+        TotalValue = ShiftedValue | (UINT64) (*SecondDefaultValue);\r
+        *SecondDefaultValue = (UINT32) BitFieldRead64 (TotalValue, 0, SecondBlock->Width * 8 -1);\r
+        *FirstDefaultValue = (UINT32) BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + FirstBlock->Width *8 -1);\r
+      } else {\r
+        OffsetShift = SecondBlock->Offset -FirstBlock->Offset;\r
+        ShiftedValue = LShiftU64 ((UINT64) (*SecondDefaultValue), OffsetShift * 8);\r
+        TotalValue = ShiftedValue | (UINT64) (*FirstDefaultValue);\r
+        *FirstDefaultValue = (UINT32) BitFieldRead64 (TotalValue, 0, FirstBlock->Width * 8 -1);\r
+        *SecondDefaultValue = (UINT32) BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + SecondBlock->Width *8 -1);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+\r
+Update the default value in the block data which used as Bit VarStore\r
+\r
+@param  BlockLink     The Link of the block data.\r
+\r
+**/\r
+VOID\r
+UpdateBlockDataArray (\r
+  IN LIST_ENTRY        *BlockLink\r
+)\r
+{\r
+  LIST_ENTRY          *Link;\r
+  LIST_ENTRY          *TempLink;\r
+  IFR_BLOCK_DATA      *BlockData;\r
+  IFR_BLOCK_DATA      *NextBlockData;\r
+\r
+  //\r
+  // 1. Update default value in BitVar block data.\r
+  // Sine some block datas are used as BitVarStore, then the default value recored in the block\r
+  // is for related bit field in the block. so we need to set the default value to the related bit\r
+  // fields in the block data if the block data is used as bit varstore, then the default value of\r
+  // the block will be updated.\r
+  //\r
+  UpdateDefaultValue (BlockLink);\r
+\r
+  //\r
+  // 2.Update default value for overlap BitVar blcok datas.\r
+  // For block datas have overlap region, we need to merge the default value in different blocks.\r
+  //\r
+  for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (!BlockData ->IsBitVar) {\r
+      continue;\r
+    }\r
+    for (TempLink = Link->ForwardLink; TempLink != BlockLink; TempLink = TempLink->ForwardLink) {\r
+      NextBlockData = BASE_CR (TempLink, IFR_BLOCK_DATA, Entry);\r
+      if (!NextBlockData->IsBitVar || NextBlockData->Offset >= BlockData->Offset + BlockData->Width || BlockData->Offset >= NextBlockData->Offset + NextBlockData->Width) {\r
+        continue;\r
+      }\r
+      //\r
+      // Find two blocks are used as bit VarStore and have overlap region, so need to merge default value of these two blocks.\r
+      //\r
+      MergeBlockDefaultValue (BlockData, NextBlockData);\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Generate ConfigAltResp string base on the varstore info.\r
 \r
@@ -3612,6 +3888,8 @@ GenerateAltConfigResp (
   //\r
   Length = StrLen (ConfigHdr) + 1;\r
 \r
+  UpdateBlockDataArray (&VarStorageData->BlockEntry);\r
+\r
   for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
     DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
     //\r