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