//\r
TemBuffer = ((UINT8 *) Buffer);\r
for (Index = 0; Index < BufferLen; Index ++, TemBuffer ++) {\r
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+ UnicodeValueToStringS (\r
+ TemString,\r
+ sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *TemBuffer,\r
+ 2\r
+ );\r
+ TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
}\r
break;\r
case 2:\r
// Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
//\r
for (; *TemName != L'\0'; TemName++) {\r
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
+ UnicodeValueToStringS (\r
+ TemString,\r
+ sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *TemName,\r
+ 4\r
+ );\r
+ TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
}\r
break;\r
case 3:\r
//\r
TemBuffer = ((UINT8 *) Buffer) + BufferLen - 1;\r
for (Index = 0; Index < BufferLen; Index ++, TemBuffer --) {\r
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+ UnicodeValueToStringS (\r
+ TemString,\r
+ sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *TemBuffer,\r
+ 2\r
+ );\r
+ TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
}\r
break;\r
default:\r
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
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
@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
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
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
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
UINT16 SmallestDefaultId;\r
BOOLEAN SmallestIdFromFlag;\r
BOOLEAN FromOtherDefaultOpcode;\r
+ BOOLEAN QuestionReferBitField;\r
\r
Status = EFI_SUCCESS;\r
BlockData = NULL;\r
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
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
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
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
// 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
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
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
// 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
// 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
// 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
// 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
}\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
}\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
}\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
}\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
//\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
//\r
// End Opcode is for Var question.\r
//\r
+ QuestionReferBitField = FALSE;\r
if (BlockData != NULL) {\r
if (BlockData->Scope > 0) {\r
BlockData->Scope--;\r
\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
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
//\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
TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
}\r
for (; Width > 0 && (TmpBuffer != NULL); Width--) {\r
- StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
+ UnicodeValueToStringS (\r
+ StringPtr,\r
+ Length * sizeof (CHAR16) - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ TmpBuffer[Width - 1],\r
+ 2\r
+ );\r
+ StringPtr += StrnLenS (StringPtr, Length - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp) / sizeof (CHAR16));\r
}\r
if (DefaultString != NULL){\r
FreePool(DefaultString);\r
TemString = ValueStr;\r
TemBuffer = Value + Width - 1;\r
for (Index = 0; Index < Width; Index ++, TemBuffer --) {\r
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+ UnicodeValueToStringS (\r
+ TemString,\r
+ Length * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *TemBuffer,\r
+ 2\r
+ );\r
+ TemString += StrnLenS (TemString, Length - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));\r
}\r
\r
FreePool (Value);\r