mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
95a7135191
commit
37cd16ac57
|
@ -1225,7 +1225,7 @@ InsertBlockData (
|
||||||
for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
|
for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
|
||||||
BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
|
BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
|
||||||
if (BlockArray->Offset == BlockSingleData->Offset) {
|
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
|
// Insert this block data in the front of block array
|
||||||
//
|
//
|
||||||
|
@ -1233,7 +1233,7 @@ InsertBlockData (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BlockArray->Width == BlockSingleData->Width) {
|
if ((!BlockSingleData->IsBitVar) && BlockArray->Width == BlockSingleData->Width) {
|
||||||
//
|
//
|
||||||
// The same block array has been added.
|
// The same block array has been added.
|
||||||
//
|
//
|
||||||
|
@ -1980,6 +1980,7 @@ Done:
|
||||||
@param IfrOpHdr Ifr opcode header for this opcode.
|
@param IfrOpHdr Ifr opcode header for this opcode.
|
||||||
@param VarWidth The buffer width for this opcode.
|
@param VarWidth The buffer width for this opcode.
|
||||||
@param ReturnData The data block added 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_SUCCESS This opcode is required.
|
||||||
@retval EFI_NOT_FOUND This opcode is not required.
|
@retval EFI_NOT_FOUND This opcode is not required.
|
||||||
|
@ -1993,16 +1994,22 @@ IsThisOpcodeRequired (
|
||||||
IN OUT IFR_VARSTORAGE_DATA *VarStorageData,
|
IN OUT IFR_VARSTORAGE_DATA *VarStorageData,
|
||||||
IN EFI_IFR_OP_HEADER *IfrOpHdr,
|
IN EFI_IFR_OP_HEADER *IfrOpHdr,
|
||||||
IN UINT16 VarWidth,
|
IN UINT16 VarWidth,
|
||||||
OUT IFR_BLOCK_DATA **ReturnData
|
OUT IFR_BLOCK_DATA **ReturnData,
|
||||||
|
IN BOOLEAN IsBitVar
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IFR_BLOCK_DATA *BlockData;
|
IFR_BLOCK_DATA *BlockData;
|
||||||
UINT16 VarOffset;
|
UINT16 VarOffset;
|
||||||
EFI_STRING_ID NameId;
|
EFI_STRING_ID NameId;
|
||||||
EFI_IFR_QUESTION_HEADER *IfrQuestionHdr;
|
EFI_IFR_QUESTION_HEADER *IfrQuestionHdr;
|
||||||
|
UINT16 BitOffset;
|
||||||
|
UINT16 BitWidth;
|
||||||
|
UINT16 TotalBits;
|
||||||
|
|
||||||
NameId = 0;
|
NameId = 0;
|
||||||
VarOffset = 0;
|
VarOffset = 0;
|
||||||
|
BitOffset = 0;
|
||||||
|
BitWidth = 0;
|
||||||
IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)((CHAR8 *) IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));
|
IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)((CHAR8 *) IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));
|
||||||
|
|
||||||
if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
|
if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
|
||||||
|
@ -2018,7 +2025,23 @@ IsThisOpcodeRequired (
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
} else {
|
} 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.
|
// Check whether this question is in requested block array.
|
||||||
|
@ -2053,6 +2076,9 @@ IsThisOpcodeRequired (
|
||||||
BlockData->QuestionId = IfrQuestionHdr->QuestionId;
|
BlockData->QuestionId = IfrQuestionHdr->QuestionId;
|
||||||
BlockData->OpCode = IfrOpHdr->OpCode;
|
BlockData->OpCode = IfrOpHdr->OpCode;
|
||||||
BlockData->Scope = IfrOpHdr->Scope;
|
BlockData->Scope = IfrOpHdr->Scope;
|
||||||
|
BlockData->IsBitVar = IsBitVar;
|
||||||
|
BlockData->BitOffset = BitOffset;
|
||||||
|
BlockData->BitWidth = BitWidth;
|
||||||
InitializeListHead (&BlockData->DefaultValueEntry);
|
InitializeListHead (&BlockData->DefaultValueEntry);
|
||||||
//
|
//
|
||||||
// Add Block Data into VarStorageData BlockEntry
|
// Add Block Data into VarStorageData BlockEntry
|
||||||
|
@ -2126,6 +2152,7 @@ ParseIfrData (
|
||||||
UINT16 SmallestDefaultId;
|
UINT16 SmallestDefaultId;
|
||||||
BOOLEAN SmallestIdFromFlag;
|
BOOLEAN SmallestIdFromFlag;
|
||||||
BOOLEAN FromOtherDefaultOpcode;
|
BOOLEAN FromOtherDefaultOpcode;
|
||||||
|
BOOLEAN QuestionReferBitField;
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
BlockData = NULL;
|
BlockData = NULL;
|
||||||
|
@ -2137,6 +2164,7 @@ ParseIfrData (
|
||||||
ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));
|
ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));
|
||||||
SmallestDefaultId = 0xFFFF;
|
SmallestDefaultId = 0xFFFF;
|
||||||
FromOtherDefaultOpcode = FALSE;
|
FromOtherDefaultOpcode = FALSE;
|
||||||
|
QuestionReferBitField = FALSE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Go through the form package to parse OpCode one by one.
|
// Go through the form package to parse OpCode one by one.
|
||||||
|
@ -2311,7 +2339,7 @@ ParseIfrData (
|
||||||
BlockData = NULL;
|
BlockData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);
|
Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2343,7 +2371,12 @@ ParseIfrData (
|
||||||
if (IfrOneOf->Question.VarStoreId != VarStoreId) {
|
if (IfrOneOf->Question.VarStoreId != VarStoreId) {
|
||||||
break;
|
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.
|
// The BlockData may allocate by other opcode,need to clean.
|
||||||
|
@ -2352,7 +2385,7 @@ ParseIfrData (
|
||||||
BlockData = NULL;
|
BlockData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);
|
Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2378,26 +2411,33 @@ ParseIfrData (
|
||||||
// Numeric minimum value will be used as default value when no default is specified.
|
// Numeric minimum value will be used as default value when no default is specified.
|
||||||
//
|
//
|
||||||
DefaultData.Type = DefaultValueFromDefault;
|
DefaultData.Type = DefaultValueFromDefault;
|
||||||
switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {
|
if (QuestionReferBitField) {
|
||||||
case EFI_IFR_NUMERIC_SIZE_1:
|
//
|
||||||
DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;
|
// Since default value in bit field was stored as UINT32 type.
|
||||||
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));
|
CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));
|
||||||
break;
|
} 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_8:
|
case EFI_IFR_NUMERIC_SIZE_2:
|
||||||
CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));
|
CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case EFI_IFR_NUMERIC_SIZE_4:
|
||||||
Status = EFI_INVALID_PARAMETER;
|
CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));
|
||||||
goto Done;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Set default value base on the DefaultId list get from IFR data.
|
// Set default value base on the DefaultId list get from IFR data.
|
||||||
|
@ -2441,7 +2481,7 @@ ParseIfrData (
|
||||||
BlockData = NULL;
|
BlockData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);
|
Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2486,7 +2526,10 @@ ParseIfrData (
|
||||||
BlockData = NULL;
|
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 (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2517,7 +2560,11 @@ ParseIfrData (
|
||||||
// When flag is set, default value is TRUE.
|
// When flag is set, default value is TRUE.
|
||||||
//
|
//
|
||||||
DefaultData.Type = DefaultValueFromFlag;
|
DefaultData.Type = DefaultValueFromFlag;
|
||||||
DefaultData.Value.b = TRUE;
|
if (QuestionReferBitField) {
|
||||||
|
DefaultData.Value.u32 = TRUE;
|
||||||
|
} else {
|
||||||
|
DefaultData.Value.b = TRUE;
|
||||||
|
}
|
||||||
InsertDefaultValue (BlockData, &DefaultData);
|
InsertDefaultValue (BlockData, &DefaultData);
|
||||||
|
|
||||||
if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
|
if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
|
||||||
|
@ -2542,7 +2589,11 @@ ParseIfrData (
|
||||||
// When flag is set, default value is TRUE.
|
// When flag is set, default value is TRUE.
|
||||||
//
|
//
|
||||||
DefaultData.Type = DefaultValueFromFlag;
|
DefaultData.Type = DefaultValueFromFlag;
|
||||||
DefaultData.Value.b = TRUE;
|
if (QuestionReferBitField) {
|
||||||
|
DefaultData.Value.u32 = TRUE;
|
||||||
|
} else {
|
||||||
|
DefaultData.Value.b = TRUE;
|
||||||
|
}
|
||||||
InsertDefaultValue (BlockData, &DefaultData);
|
InsertDefaultValue (BlockData, &DefaultData);
|
||||||
|
|
||||||
if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
|
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.
|
// 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.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.
|
// 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.
|
// When flag is not set, default value is FASLE.
|
||||||
//
|
//
|
||||||
DefaultData.Type = DefaultValueFromDefault;
|
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.
|
// Set default value for all the default id in the DefaultId list.
|
||||||
//
|
//
|
||||||
|
@ -2614,7 +2673,7 @@ ParseIfrData (
|
||||||
}
|
}
|
||||||
|
|
||||||
VarWidth = (UINT16) sizeof (EFI_HII_DATE);
|
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 (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2656,7 +2715,7 @@ ParseIfrData (
|
||||||
}
|
}
|
||||||
|
|
||||||
VarWidth = (UINT16) sizeof (EFI_HII_TIME);
|
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 (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2698,7 +2757,7 @@ ParseIfrData (
|
||||||
}
|
}
|
||||||
|
|
||||||
VarWidth = (UINT16) (IfrString->MaxSize * sizeof (UINT16));
|
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 (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2740,7 +2799,7 @@ ParseIfrData (
|
||||||
}
|
}
|
||||||
|
|
||||||
VarWidth = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));
|
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 (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND){
|
if (Status == EFI_NOT_FOUND){
|
||||||
//
|
//
|
||||||
|
@ -2932,7 +2991,11 @@ ParseIfrData (
|
||||||
//
|
//
|
||||||
DefaultData.Type = DefaultValueFromOpcode;
|
DefaultData.Type = DefaultValueFromOpcode;
|
||||||
DefaultData.DefaultId = VarDefaultId;
|
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 the value field is expression, set the cleaned flag.
|
||||||
if (IfrDefault->Type == EFI_IFR_TYPE_OTHER) {
|
if (IfrDefault->Type == EFI_IFR_TYPE_OTHER) {
|
||||||
|
@ -2974,6 +3037,7 @@ ParseIfrData (
|
||||||
//
|
//
|
||||||
// End Opcode is for Var question.
|
// End Opcode is for Var question.
|
||||||
//
|
//
|
||||||
|
QuestionReferBitField = FALSE;
|
||||||
if (BlockData != NULL) {
|
if (BlockData != NULL) {
|
||||||
if (BlockData->Scope > 0) {
|
if (BlockData->Scope > 0) {
|
||||||
BlockData->Scope--;
|
BlockData->Scope--;
|
||||||
|
@ -2990,6 +3054,12 @@ ParseIfrData (
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EFI_IFR_GUID_OP:
|
||||||
|
if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
|
||||||
|
QuestionReferBitField = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (BlockData != NULL) {
|
if (BlockData != NULL) {
|
||||||
if (BlockData->Scope > 0) {
|
if (BlockData->Scope > 0) {
|
||||||
|
@ -3568,6 +3638,212 @@ GetStorageWidth (
|
||||||
return StorageWidth;
|
return StorageWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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.
|
Generate ConfigAltResp string base on the varstore info.
|
||||||
|
|
||||||
|
@ -3612,6 +3888,8 @@ GenerateAltConfigResp (
|
||||||
//
|
//
|
||||||
Length = StrLen (ConfigHdr) + 1;
|
Length = StrLen (ConfigHdr) + 1;
|
||||||
|
|
||||||
|
UpdateBlockDataArray (&VarStorageData->BlockEntry);
|
||||||
|
|
||||||
for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {
|
for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {
|
||||||
DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
|
DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Private structures definitions in HiiDatabase.
|
Private structures definitions in HiiDatabase.
|
||||||
|
|
||||||
Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#include <Guid/HiiKeyBoardLayout.h>
|
#include <Guid/HiiKeyBoardLayout.h>
|
||||||
#include <Guid/GlobalVariable.h>
|
#include <Guid/GlobalVariable.h>
|
||||||
|
#include <Guid/MdeModuleHii.h>
|
||||||
|
|
||||||
|
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
|
@ -77,11 +78,14 @@ typedef struct {
|
||||||
LIST_ENTRY Entry; // Link to Block array
|
LIST_ENTRY Entry; // Link to Block array
|
||||||
UINT16 Offset;
|
UINT16 Offset;
|
||||||
UINT16 Width;
|
UINT16 Width;
|
||||||
|
UINT16 BitOffset;
|
||||||
|
UINT16 BitWidth;
|
||||||
EFI_QUESTION_ID QuestionId;
|
EFI_QUESTION_ID QuestionId;
|
||||||
UINT8 OpCode;
|
UINT8 OpCode;
|
||||||
UINT8 Scope;
|
UINT8 Scope;
|
||||||
LIST_ENTRY DefaultValueEntry; // Link to its default value array
|
LIST_ENTRY DefaultValueEntry; // Link to its default value array
|
||||||
CHAR16 *Name;
|
CHAR16 *Name;
|
||||||
|
BOOLEAN IsBitVar;
|
||||||
} IFR_BLOCK_DATA;
|
} IFR_BLOCK_DATA;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
# This driver produces all required HII serivces that includes HiiDataBase, HiiString,
|
# This driver produces all required HII serivces that includes HiiDataBase, HiiString,
|
||||||
# HiiFont, HiiConfigRouting. To support UEFI HII, this driver is required.
|
# HiiFont, HiiConfigRouting. To support UEFI HII, this driver is required.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -90,6 +90,7 @@
|
||||||
gEfiHiiKeyBoardLayoutGuid
|
gEfiHiiKeyBoardLayoutGuid
|
||||||
gEfiHiiImageDecoderNameJpegGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol ## SOMETIMES_CONSUMES ## GUID
|
gEfiHiiImageDecoderNameJpegGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol ## SOMETIMES_CONSUMES ## GUID
|
||||||
gEfiHiiImageDecoderNamePngGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol ## SOMETIMES_CONSUMES ## GUID
|
gEfiHiiImageDecoderNamePngGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol ## SOMETIMES_CONSUMES ## GUID
|
||||||
|
gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
TRUE
|
TRUE
|
||||||
|
|
Loading…
Reference in New Issue