MdeModulePkg/SetupBrowser: Handle questions with Bit VarStore
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=545 For oneof/numeric/CheckBox(storage can be Bit VarStore) If the question value can be updated and shown correctly in UI page, we need do enhancements in following cases: 1. Parse the Ifr data to get the bit VarStore info correctly. 2. Set/get value to/from bit VarStore correctly. 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:
@@ -59,6 +59,7 @@ CreateStatement (
|
||||
|
||||
Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
|
||||
Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;
|
||||
Statement->QuestionReferToBitField = FALSE;
|
||||
|
||||
StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
|
||||
CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
|
||||
@@ -1314,6 +1315,8 @@ ParseOpCodes (
|
||||
FORMSET_DEFAULTSTORE *PreDefaultStore;
|
||||
LIST_ENTRY *DefaultLink;
|
||||
BOOLEAN HaveInserted;
|
||||
UINT16 TotalBits;
|
||||
BOOLEAN QuestionReferBitField;
|
||||
|
||||
SuppressForQuestion = FALSE;
|
||||
SuppressForOption = FALSE;
|
||||
@@ -1335,6 +1338,7 @@ ParseOpCodes (
|
||||
ConditionalExprCount = 0;
|
||||
InUnknownScope = FALSE;
|
||||
UnknownDepth = 0;
|
||||
QuestionReferBitField = FALSE;
|
||||
|
||||
//
|
||||
// Get the number of Statements and Expressions
|
||||
@@ -1980,43 +1984,94 @@ ParseOpCodes (
|
||||
CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
|
||||
Value = &CurrentStatement->HiiValue;
|
||||
|
||||
switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
|
||||
case EFI_IFR_NUMERIC_SIZE_1:
|
||||
CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
|
||||
CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
|
||||
CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
|
||||
break;
|
||||
if (QuestionReferBitField) {
|
||||
//
|
||||
// Get the bit var store info (bit/byte offset, bit/byte offset)
|
||||
//
|
||||
CurrentStatement->QuestionReferToBitField = TRUE;
|
||||
CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
|
||||
CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;
|
||||
CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;
|
||||
TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;
|
||||
CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);
|
||||
|
||||
case EFI_IFR_NUMERIC_SIZE_2:
|
||||
CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
|
||||
CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
|
||||
CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
|
||||
break;
|
||||
//
|
||||
// Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)
|
||||
//
|
||||
CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue;
|
||||
CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue;
|
||||
CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step;
|
||||
|
||||
case EFI_IFR_NUMERIC_SIZE_4:
|
||||
CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
|
||||
CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
|
||||
CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
|
||||
break;
|
||||
//
|
||||
// Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,
|
||||
// in order to make Browser handle these question with bit varstore correctly.
|
||||
//
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->Flags &= EDKII_IFR_DISPLAY_BIT;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->Flags >>= 2;
|
||||
switch (CurrentStatement->StorageWidth) {
|
||||
case 1:
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue = (UINT8)CurrentStatement->Minimum;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue = (UINT8)CurrentStatement->Maximum;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step = (UINT8)CurrentStatement->Step;
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
|
||||
break;
|
||||
case 2:
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue = (UINT16)CurrentStatement->Minimum;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue = (UINT16)CurrentStatement->Maximum;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step = (UINT16)CurrentStatement->Step;
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue = (UINT32)CurrentStatement->Minimum;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue = (UINT32)CurrentStatement->Maximum;
|
||||
((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step = (UINT32)CurrentStatement->Step;
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
|
||||
case EFI_IFR_NUMERIC_SIZE_1:
|
||||
CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
|
||||
CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
|
||||
CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
|
||||
break;
|
||||
|
||||
case EFI_IFR_NUMERIC_SIZE_8:
|
||||
CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
|
||||
CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
|
||||
CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
|
||||
break;
|
||||
case EFI_IFR_NUMERIC_SIZE_2:
|
||||
CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
|
||||
CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
|
||||
CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case EFI_IFR_NUMERIC_SIZE_4:
|
||||
CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
|
||||
CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
|
||||
CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
|
||||
break;
|
||||
|
||||
case EFI_IFR_NUMERIC_SIZE_8:
|
||||
CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
|
||||
CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
|
||||
CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
|
||||
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
|
||||
|
||||
if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
|
||||
@@ -2047,6 +2102,18 @@ ParseOpCodes (
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
|
||||
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
|
||||
|
||||
if (QuestionReferBitField) {
|
||||
//
|
||||
// Get the bit var store info (bit/byte offset, bit/byte offset)
|
||||
//
|
||||
CurrentStatement->QuestionReferToBitField = TRUE;
|
||||
CurrentStatement->BitStorageWidth = 1;
|
||||
CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;
|
||||
CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;
|
||||
TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;
|
||||
CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);
|
||||
}
|
||||
|
||||
InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
|
||||
|
||||
break;
|
||||
@@ -2594,14 +2661,19 @@ ParseOpCodes (
|
||||
//
|
||||
// Vendor specific
|
||||
//
|
||||
case EFI_IFR_GUID_OP:
|
||||
case EFI_IFR_GUID_OP:
|
||||
CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
|
||||
if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
|
||||
Scope = 0;
|
||||
QuestionReferBitField = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Scope End
|
||||
//
|
||||
case EFI_IFR_END_OP:
|
||||
QuestionReferBitField = FALSE;
|
||||
Status = PopScope (&ScopeOpCode);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ResetScopeStack ();
|
||||
|
Reference in New Issue
Block a user