BaseTool/VfrCompiler: Support Bit fields in EFI/Buffer VarStore

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=545

Enhance VfrCompiler to parse following case:
1. EFI/Buffer VarStore can contain bit fields in their structure.
2. For question Oneof/Checkbox/numeric, their storage can be
   bit fields of an EFI VarStore/Buffer VarStore.

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:
Dandan Bi 2017-08-23 16:27:26 +08:00 committed by Eric Dong
parent 2b7f3d4a6b
commit 42c808d4cb
8 changed files with 1200 additions and 494 deletions

View File

@ -1,7 +1,7 @@
/** @file
EDK II specific HII relative definition.
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
@ -212,10 +212,28 @@ typedef struct _EFI_IFR_GUID_VAREQNAME {
UINT16 NameId;
} EFI_IFR_GUID_VAREQNAME;
///
/// EDKII implementation extension GUID, used to indaicate there are bit fields in the varstore.
///
#define EDKII_IFR_BIT_VARSTORE_GUID \
{ 0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60 ,0xA7, 0x1D}}
///
/// EDKII implementation extension flags, used to indaicate the disply style and bit width for bit filed storage.
/// Two high bits for display style and the low six bits for bit width.
///
#define EDKII_IFR_DISPLAY_BIT 0xC0
#define EDKII_IFR_DISPLAY_INT_DEC_BIT 0x00
#define EDKII_IFR_DISPLAY_UINT_DEC_BIT 0x40
#define EDKII_IFR_DISPLAY_UINT_HEX_BIT 0x80
#define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F
#pragma pack()
extern EFI_GUID gEfiIfrTianoGuid;
extern EFI_GUID gEfiIfrFrameworkGuid;
extern EFI_GUID gEdkiiIfrBitVarStoreGuid;
#endif

View File

@ -2,7 +2,7 @@
VfrCompiler error handler.
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
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
@ -46,6 +46,7 @@ static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = {
{ VFR_RETURN_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},
{ VFR_RETURN_CONSTANT_ONLY, ": only constant is allowed in the expression"},
{ VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR, ": Varstore name is defined by more than one varstores, it can't be referred as varstore, only varstore strucure name could be used."},
{ VFR_RETURN_BIT_WIDTH_ERROR, ": bit width must be <= sizeof (type) * 8 and the max width can not > 32" },
{ VFR_RETURN_CODEUNDEFINED, ": undefined Error Code" }
};

View File

@ -2,7 +2,7 @@
VfrCompiler Error definition
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
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
@ -44,6 +44,7 @@ typedef enum {
VFR_RETURN_DEFAULT_VALUE_REDEFINED,
VFR_RETURN_CONSTANT_ONLY,
VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR,
VFR_RETURN_BIT_WIDTH_ERROR,
VFR_RETURN_CODEUNDEFINED
} EFI_VFR_RETURN_CODE;

View File

@ -2,7 +2,7 @@
The definition of CFormPkg's member function
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
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
@ -829,6 +829,9 @@ CFormPkg::DeclarePendingQuestion (
UINT32 ShrinkSize = 0;
EFI_VFR_RETURN_CODE ReturnCode;
EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
UINT8 LFlags;
UINT32 MaxValue;
CIfrGuid *GuidObj = NULL;
//
// Declare all questions as Numeric in DisableIf True
@ -844,14 +847,8 @@ CFormPkg::DeclarePendingQuestion (
// Declare Numeric qeustion for each undefined question.
for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
if (pNode->mFlag == PENDING) {
CIfrNumeric CNObj;
EFI_VARSTORE_INFO Info;
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
CNObj.SetLineNo (LineNo);
CNObj.SetPrompt (0x0);
CNObj.SetHelp (0x0);
//
// Register this question, assume it is normal question, not date or time question
//
@ -888,7 +885,7 @@ CFormPkg::DeclarePendingQuestion (
} else {
if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
} else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {
} else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {
VarStr = pNode->mKey;
//convert VarStr with store name to VarStr with structure name
ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);
@ -897,7 +894,7 @@ CFormPkg::DeclarePendingQuestion (
NewStr[0] = '\0';
strcpy (NewStr, SName);
strcat (NewStr, VarStr + strlen (FName));
ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);
ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize, Info.mIsBitVar);
delete[] NewStr;
}
} else {
@ -908,9 +905,32 @@ CFormPkg::DeclarePendingQuestion (
gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
return ReturnCode;
}
//
// If the storage is bit fields, create Guid opcode to wrap the numeric opcode.
//
if (Info.mIsBitVar) {
GuidObj = new CIfrGuid(0);
GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
GuidObj->SetLineNo(LineNo);
}
CIfrNumeric CNObj;
CNObj.SetLineNo (LineNo);
CNObj.SetPrompt (0x0);
CNObj.SetHelp (0x0);
CNObj.SetQuestionId (QId);
CNObj.SetVarStoreInfo (&Info);
//
// Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.
//
if (Info.mIsBitVar) {
MaxValue = (1 << Info.mVarTotalSize) -1;
CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);
ShrinkSize = 12;
LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & Info.mVarTotalSize);
CNObj.SetFlagsForBitField (0, LFlags);
} else {
//
// Numeric doesn't support BOOLEAN data type.
// BOOLEAN type has the same data size to UINT8.
@ -942,6 +962,7 @@ CFormPkg::DeclarePendingQuestion (
default:
break;
}
}
CNObj.ShrinkBinSize (ShrinkSize);
//
@ -958,6 +979,16 @@ CFormPkg::DeclarePendingQuestion (
//
CIfrEnd CEObj;
CEObj.SetLineNo (LineNo);
//
// End for Guided opcode
//
if (GuidObj != NULL) {
CIfrEnd CEObjGuid;
CEObjGuid.SetLineNo (LineNo);
GuidObj->SetScope(1);
delete GuidObj;
GuidObj = NULL;
}
}
}

View File

@ -2,7 +2,7 @@
The definition of CFormPkg's member function
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
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
@ -567,8 +567,12 @@ public:
mMinMaxStepData->u8.Step = Step;
}
UINT64 GetMinData (UINT8 VarType) {
UINT64 GetMinData (UINT8 VarType, BOOLEAN IsBitVar) {
UINT64 MinValue = 0;
if (IsBitVar) {
MinValue = mMinMaxStepData->u32.MinValue;
return MinValue;
}
switch (VarType) {
case EFI_IFR_TYPE_NUM_SIZE_64:
MinValue = mMinMaxStepData->u64.MinValue;
@ -588,8 +592,12 @@ public:
return MinValue;
}
UINT64 GetMaxData (UINT8 VarType) {
UINT64 GetMaxData (UINT8 VarType, BOOLEAN IsBitVar) {
UINT64 MaxValue = 0;
if (IsBitVar) {
MaxValue = mMinMaxStepData->u32.MaxValue;
return MaxValue;
}
switch (VarType) {
case EFI_IFR_TYPE_NUM_SIZE_64:
MaxValue = mMinMaxStepData->u64.MaxValue;
@ -609,8 +617,12 @@ public:
return MaxValue;
}
UINT64 GetStepData (UINT8 VarType) {
UINT64 GetStepData (UINT8 VarType, BOOLEAN IsBitVar) {
UINT64 MaxValue = 0;
if (IsBitVar) {
MaxValue = mMinMaxStepData->u32.Step;
return MaxValue;
}
switch (VarType) {
case EFI_IFR_TYPE_NUM_SIZE_64:
MaxValue = mMinMaxStepData->u64.Step;
@ -1407,6 +1419,22 @@ public:
return VFR_RETURN_SUCCESS;
}
EFI_VFR_RETURN_CODE SetFlagsForBitField (IN UINT8 HFlags, IN UINT8 LFlags, BOOLEAN DisplaySettingsSpecified = FALSE) {
EFI_VFR_RETURN_CODE Ret;
Ret = CIfrQuestionHeader::SetFlags (HFlags);
if (Ret != VFR_RETURN_SUCCESS) {
return Ret;
}
if (DisplaySettingsSpecified == FALSE) {
mNumeric->Flags = LFlags | EDKII_IFR_DISPLAY_UINT_DEC_BIT;
} else {
mNumeric->Flags = LFlags;
}
return VFR_RETURN_SUCCESS;
}
UINT8 GetNumericFlags () {
return mNumeric->Flags;
}
@ -1447,6 +1475,22 @@ public:
return VFR_RETURN_SUCCESS;
}
EFI_VFR_RETURN_CODE SetFlagsForBitField (IN UINT8 HFlags, IN UINT8 LFlags) {
EFI_VFR_RETURN_CODE Ret;
Ret = CIfrQuestionHeader::SetFlags (HFlags);
if (Ret != VFR_RETURN_SUCCESS) {
return Ret;
}
if (LFlags & EFI_IFR_DISPLAY) {
mOneOf->Flags = LFlags;
} else {
mOneOf->Flags = LFlags | EDKII_IFR_DISPLAY_UINT_DEC_BIT;
}
return VFR_RETURN_SUCCESS;
}
VOID ShrinkBinSize (IN UINT16 Size) {
//
// Update the buffer size which is truly be used later.

View File

@ -363,7 +363,11 @@ vfrDataStructFields [BOOLEAN FieldInUnion]:
dataStructFieldDate [FieldInUnion] |
dataStructFieldTime [FieldInUnion] |
dataStructFieldRef [FieldInUnion] |
dataStructFieldUser [FieldInUnion]
dataStructFieldUser [FieldInUnion] |
dataStructBitField64 [FieldInUnion] |
dataStructBitField32 [FieldInUnion] |
dataStructBitField16 [FieldInUnion] |
dataStructBitField8 [FieldInUnion]
)*
;
@ -469,6 +473,83 @@ dataStructFieldUser [BOOLEAN FieldInUnion]:
";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), T->getText(), ArrayNum, FieldInUnion), T); >>
;
dataStructBitField64[BOOLEAN FieldInUnion]:
<<
UINT32 Width = 0;
BOOLEAN HasBitFieldName = FALSE;
>>
D:"UINT64"
{
N:StringIdentifier << HasBitFieldName = TRUE;>>
}
":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
";" << if (HasBitFieldName) {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
} else {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
}
>>
;
dataStructBitField32[BOOLEAN FieldInUnion]:
<<
UINT32 Width = 0;
BOOLEAN HasBitFieldName = FALSE;
>>
D:"UINT32"
{
N:StringIdentifier << HasBitFieldName = TRUE;>>
}
":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
";" << if (HasBitFieldName) {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
} else {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
}
>>
;
dataStructBitField16[BOOLEAN FieldInUnion]:
<<
UINT32 Width = 0;
BOOLEAN HasBitFieldName = FALSE;
>>
D:"UINT16"
{
N:StringIdentifier << HasBitFieldName = TRUE;>>
}
":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
";" << if (HasBitFieldName) {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
} else {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
}
>>
;
dataStructBitField8[BOOLEAN FieldInUnion]:
<<
UINT32 Width = 0;
BOOLEAN HasBitFieldName = FALSE;
>>
D:"UINT8"
{
N:StringIdentifier << HasBitFieldName = TRUE;>>
}
":" I:Number << Width = _STOU32(I->getText(), I->getLine());>>
";" << if (HasBitFieldName) {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (N->getText(), D->getText(), Width, FieldInUnion), N);
} else {
_PCATCH(gCVfrVarDataTypeDB.DataTypeAddBitField (NULL, D->getText(), Width, FieldInUnion), D);
}
>>
;
//*****************************************************************************
//
// the syntax of GUID definition
@ -751,6 +832,11 @@ vfrExtensionData[UINT8 *DataBuff, UINT32 Size, CHAR8 *TypeName, UINT32 TypeSize,
EFI_STRING_ID Data_SID = 0;
BOOLEAN IsArray = FALSE;
UINT8 *ByteOffset = NULL;
BOOLEAN BitField = FALSE;
UINT64 Value;
UINT64 Mask;
UINT16 Offset;
UINT8 PreBits;
>>
(
("," "data" {OpenBracket IDX1:Number CloseBracket <<IsArray = TRUE;>>}
@ -807,23 +893,69 @@ vfrExtensionData[UINT8 *DataBuff, UINT32 Size, CHAR8 *TypeName, UINT32 TypeSize,
memcpy (ByteOffset, &Data_SID, TypeSize);
}
} else {
gCVfrVarDataTypeDB.GetDataFieldInfo(TFName, FieldOffset, FieldType, FieldSize);
gCVfrVarDataTypeDB.GetDataFieldInfo(TFName, FieldOffset, FieldType, FieldSize, BitField);
if (BitField) {
Mask = (1 << FieldSize) - 1;
Offset = FieldOffset / 8;
PreBits = FieldOffset % 8;
Mask <<= PreBits;
}
switch (FieldType) {
case EFI_IFR_TYPE_NUM_SIZE_8:
Data_U8 = _STOU8(RD->getText(), RD->getLine());
if (BitField) {
//
// Set the value to the bit fileds.
//
Value = *(UINT8*) (ByteOffset + Offset);
Data_U8 <<= PreBits;
Value = (Value & (~Mask)) | Data_U8;
memcpy (ByteOffset + Offset, &Value, sizeof (UINT8));
} else {
memcpy (ByteOffset + FieldOffset, &Data_U8, FieldSize);
}
break;
case EFI_IFR_TYPE_NUM_SIZE_16:
Data_U16 = _STOU16(RD->getText(), RD->getLine());
if (BitField) {
//
// Set the value to the bit fileds.
//
Value = *(UINT16*) (ByteOffset + Offset);
Data_U16 <<= PreBits;
Value = (Value & (~Mask)) | Data_U16;
memcpy (ByteOffset + Offset, &Value, sizeof (UINT16));
} else {
memcpy (ByteOffset + FieldOffset, &Data_U16, FieldSize);
}
break;
case EFI_IFR_TYPE_NUM_SIZE_32:
Data_U32 = _STOU32(RD->getText(), RD->getLine());
if (BitField) {
//
// Set the value to the bit fileds.
//
Value = *(UINT32*) (ByteOffset + Offset);
Data_U32 <<= PreBits;
Value = (Value & (~Mask)) | Data_U32;
memcpy (ByteOffset + Offset, &Value, sizeof (UINT32));
} else {
memcpy (ByteOffset + FieldOffset, &Data_U32, FieldSize);
}
break;
case EFI_IFR_TYPE_NUM_SIZE_64:
Data_U64 = _STOU64(RD->getText(), RD->getLine());
if (BitField) {
//
// Set the value to the bit fileds.
//
Value = *(UINT64*) (ByteOffset + Offset);
Data_U64 <<= PreBits;
Value = (Value & (~Mask)) | Data_U64;
memcpy (ByteOffset + Offset, &Value, sizeof (UINT64));
} else {
memcpy (ByteOffset + FieldOffset, &Data_U64, FieldSize);
}
break;
case EFI_IFR_TYPE_BOOLEAN:
Data_BL = _STOU8(RD->getText(), RD->getLine());
@ -874,10 +1006,11 @@ vfrStatementVarStoreLinear :
UINT32 LineNum;
EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
UINT32 Size;
BOOLEAN IsBitVarStore = FALSE;
>>
V:Varstore << VSObj.SetLineNo(V->getLine()); >>
(
TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); >>
TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); IsBitVarStore = gCVfrVarDataTypeDB.DataTypeHasBitField (TN->getText());>>
| U8:"UINT8" "," << TypeName = U8->getText(); LineNum = U8->getLine(); >>
| U16:"UINT16" "," << TypeName = U16->getText(); LineNum = U16->getLine(); >>
| C16:"CHAR16" "," << TypeName = (CHAR8 *) "UINT16"; LineNum = C16->getLine(); >>
@ -916,7 +1049,8 @@ vfrStatementVarStoreLinear :
&Guid,
&gCVfrVarDataTypeDB,
TypeName,
VarStoreId
VarStoreId,
IsBitVarStore
), LineNum);
VSObj.SetGuid (&Guid);
_PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);
@ -940,10 +1074,11 @@ vfrStatementVarStoreEfi :
UINT32 LineNum;
CHAR8 *StoreName = NULL;
BOOLEAN CustomizedName = FALSE;
BOOLEAN IsBitVarStore = FALSE;
>>
E:Efivarstore << VSEObj.SetLineNo(E->getLine()); >>
(
TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); CustomizedName = TRUE; >>
TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); CustomizedName = TRUE; IsBitVarStore = gCVfrVarDataTypeDB.DataTypeHasBitField (TN->getText());>>
| U8:"UINT8" "," << TypeName = U8->getText(); LineNum = U8->getLine(); >>
| U16:"UINT16" "," << TypeName = U16->getText(); LineNum = U16->getLine(); >>
| C16:"CHAR16" "," << TypeName = (CHAR8 *) "UINT16"; LineNum = C16->getLine(); >>
@ -1008,7 +1143,8 @@ vfrStatementVarStoreEfi :
&Guid,
&gCVfrVarDataTypeDB,
TypeName,
VarStoreId
VarStoreId,
IsBitVarStore
), LineNum);
_PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);
_PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);
@ -1018,7 +1154,8 @@ vfrStatementVarStoreEfi :
&Guid,
&gCVfrVarDataTypeDB,
TypeName,
VarStoreId
VarStoreId,
FALSE
), LineNum);
_PCATCH(gCVfrDataStorage.GetVarStoreId(TN->getText(), &VarStoreId, &Guid), VN);
_PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), N->getLine());
@ -1141,14 +1278,8 @@ vfrStatementHeader[CIfrStatementHeader *SHObj] :
Help "=" "STRING_TOKEN" "\(" S2:Number "\)" << $SHObj->SetHelp (_STOSID(S2->getText(), S2->getLine())); >>
;
vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_NORMAL]:
vfrQuestionBaseInfo[EFI_VARSTORE_INFO & Info, EFI_QUESTION_ID & QId, EFI_QUESION_TYPE QType = QUESTION_NORMAL]:
<<
EFI_VARSTORE_INFO Info;
Info.mVarType = EFI_IFR_TYPE_OTHER;
Info.mVarTotalSize = 0;
Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
CHAR8 *QName = NULL;
CHAR8 *VarIdStr = NULL;
mUsedDefaultCount = 0;
@ -1190,12 +1321,7 @@ vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_
default:
_PCATCH(VFR_RETURN_FATAL_ERROR);
}
$QHObj.SetQuestionId (QId);
if (VarIdStr != NULL) {
$QHObj.SetVarStoreInfo (&Info);
}
>>
vfrStatementHeader[&$QHObj]
<<
if (VarIdStr != NULL) {
delete VarIdStr;
@ -1204,6 +1330,25 @@ vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_
>>
;
vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_NORMAL]:
<<
EFI_VARSTORE_INFO Info;
Info.mVarType = EFI_IFR_TYPE_OTHER;
Info.mVarTotalSize = 0;
Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
Info.mIsBitVar = FALSE;
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
>>
vfrQuestionBaseInfo[Info, QId, QType]
<< $QHObj.SetQuestionId (QId);
if (Info.mVarStoreId != EFI_VARSTORE_ID_INVALID) {
$QHObj.SetVarStoreInfo (&Info);
}
>>
vfrStatementHeader[&$QHObj]
;
questionheaderFlagsField[UINT8 & Flags] :
ReadOnlyFlag << $Flags |= 0x01; >>
| InteractiveFlag << $Flags |= 0x04; >>
@ -1270,6 +1415,7 @@ vfrStorageVarId[EFI_VARSTORE_INFO & Info, CHAR8 *&QuestVarIdStr, BOOLEAN CheckFl
&gCVfrVarDataTypeDB,
SName,
EFI_VARSTORE_ID_INVALID,
FALSE,
FALSE
);
VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId, &mFormsetGuid);
@ -1301,7 +1447,7 @@ vfrStorageVarId[EFI_VARSTORE_INFO & Info, CHAR8 *&QuestVarIdStr, BOOLEAN CheckFl
if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {
_PCATCH(VfrReturnCode, SN2);
VarStoreType = gCVfrDataStorage.GetVarStoreType ($Info.mVarStoreId);
if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {
if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {
_PCATCH(gCVfrDataStorage.GetBufferVarStoreDataTypeName(Info.mVarStoreId, &TName), SN2);
_STRCAT(&VarStr, TName);
}
@ -1311,7 +1457,7 @@ vfrStorageVarId[EFI_VARSTORE_INFO & Info, CHAR8 *&QuestVarIdStr, BOOLEAN CheckFl
(
"." <<
if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {
_PCATCH(((VarStoreType != EFI_VFR_VARSTORE_BUFFER) ? VFR_RETURN_EFIVARSTORE_USE_ERROR : VFR_RETURN_SUCCESS), SN2);
_PCATCH((((VarStoreType != EFI_VFR_VARSTORE_BUFFER) && (VarStoreType != EFI_VFR_VARSTORE_BUFFER_BITS))? VFR_RETURN_EFIVARSTORE_USE_ERROR : VFR_RETURN_SUCCESS), SN2);
}
_STRCAT(&VarIdStr, "."); _STRCAT(&VarStr, ".");
>>
@ -1340,7 +1486,8 @@ vfrStorageVarId[EFI_VARSTORE_INFO & Info, CHAR8 *&QuestVarIdStr, BOOLEAN CheckFl
_PCATCH(gCVfrDataStorage.GetEfiVarStoreInfo (&$Info), SN2);
break;
case EFI_VFR_VARSTORE_BUFFER:
_PCATCH(gCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, $Info.mInfo.mVarOffset, $Info.mVarType, $Info.mVarTotalSize), SN2->getLine(), VarStr);
case EFI_VFR_VARSTORE_BUFFER_BITS:
_PCATCH(gCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, $Info.mInfo.mVarOffset, $Info.mVarType, $Info.mVarTotalSize, $Info.mIsBitVar), SN2->getLine(), VarStr);
VarGuid = gCVfrDataStorage.GetVarStoreGuid($Info.mVarStoreId);
_PCATCH((EFI_VFR_RETURN_CODE)gCVfrBufferConfig.Register (
SName,
@ -1438,6 +1585,12 @@ vfrConstantValueField[UINT8 Type, EFI_IFR_TYPE_VALUE &Value, BOOLEAN &ListType]
"\-" << Negative = TRUE; >>
}
N1:Number <<
//
// The value stored in bit fields is always set to UINT32 type.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
$Value.u32 = _STOU32(N1->getText(), N1->getLine());
} else {
switch ($Type) {
case EFI_IFR_TYPE_NUM_SIZE_8 :
$Value.u8 = _STOU8(N1->getText(), N1->getLine());
@ -1519,6 +1672,7 @@ vfrConstantValueField[UINT8 Type, EFI_IFR_TYPE_VALUE &Value, BOOLEAN &ListType]
default :
break;
}
}
>>
| B1:True << $Value.b = TRUE; >>
| B2:False << $Value.b = FALSE; >>
@ -1691,29 +1845,29 @@ vfrStatementDefault :
if (gCurrentMinMaxData != NULL && gCurrentMinMaxData->IsNumericOpcode()) {
//check default value is valid for Numeric Opcode
NumericQst = (CIfrNumeric *) gCurrentQuestion;
if ((NumericQst->GetNumericFlags() & EFI_IFR_DISPLAY) == 0) {
if ((NumericQst->GetNumericFlags() & EFI_IFR_DISPLAY) == 0 && !(_GET_CURRQEST_VARTINFO().mIsBitVar)) {
switch (_GET_CURRQEST_DATATYPE()) {
case EFI_IFR_TYPE_NUM_SIZE_8:
if (((INT8) Val->u8 < (INT8) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
((INT8) Val->u8 > (INT8) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
if (((INT8) Val->u8 < (INT8) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
((INT8) Val->u8 > (INT8) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
break;
case EFI_IFR_TYPE_NUM_SIZE_16:
if (((INT16) Val->u16 < (INT16) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
((INT16) Val->u16 > (INT16) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
if (((INT16) Val->u16 < (INT16) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
((INT16) Val->u16 > (INT16) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
break;
case EFI_IFR_TYPE_NUM_SIZE_32:
if (((INT32) Val->u32 < (INT32) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
((INT32) Val->u32 > (INT32) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
if (((INT32) Val->u32 < (INT32) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
((INT32) Val->u32 > (INT32) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
break;
case EFI_IFR_TYPE_NUM_SIZE_64:
if (((INT64) Val->u64 < (INT64) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
((INT64) Val->u64 > (INT64) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
if (((INT64) Val->u64 < (INT64) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE)) ||
((INT64) Val->u64 > (INT64) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE))) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
break;
@ -1721,9 +1875,18 @@ vfrStatementDefault :
break;
}
} else {
if (Val->u64 < gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE()) || Val->u64 > gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE())) {
//
// Value for question stored in bit fields is always set to UINT32 type.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
if (Val->u32 < gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), TRUE) || Val->u32 > gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), TRUE)) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
} else {
if (Val->u64 < gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE(), FALSE) || Val->u64 > gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE(), FALSE)) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
}
}
}
if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
@ -1760,9 +1923,13 @@ vfrStatementDefault :
default:
break;
}
} else {
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
Size = sizeof (UINT32);
} else {
_PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &Size), D->getLine());
}
}
Size += OFFSET_OF (EFI_IFR_DEFAULT, Value);
DObj = new CIfrDefault ((UINT8)Size);
DObj->SetLineNo(D->getLine());
@ -1770,9 +1937,13 @@ vfrStatementDefault :
DObj->SetType (EFI_IFR_TYPE_BUFFER);
} else if (gIsStringOp) {
DObj->SetType (EFI_IFR_TYPE_STRING);
} else {
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
DObj->SetType (EFI_IFR_TYPE_NUM_SIZE_32);
} else {
DObj->SetType (_GET_CURRQEST_DATATYPE());
}
}
DObj->SetValue(*Val);
>>
| << IsExp = TRUE; DObj2 = new CIfrDefault2; DObj2->SetLineNo(D->getLine()); DObj2->SetScope (1); >>
@ -2178,18 +2349,50 @@ vfrStatementBooleanType :
//
vfrStatementCheckBox :
<<
CIfrCheckBox CBObj;
CIfrCheckBox *CBObj = NULL;
EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
CHAR8 *VarStoreName = NULL;
UINT32 DataTypeSize;
EFI_GUID *VarStoreGuid = NULL;
CIfrGuid *GuidObj = NULL;
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;;
EFI_VARSTORE_INFO Info;
Info.mVarType = EFI_IFR_TYPE_OTHER;
Info.mVarTotalSize = 0;
Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
Info.mIsBitVar = FALSE;
>>
L:CheckBox << CBObj.SetLineNo(L->getLine()); >>
vfrQuestionHeader[CBObj] "," << //check data type
L:CheckBox
vfrQuestionBaseInfo[Info, QId] <<
//
// Create a GUID opcode to wrap the checkbox opcode, if it refer to bit varstore.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
GuidObj = new CIfrGuid(0);
GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
GuidObj->SetLineNo(L->getLine());
}
CBObj = new CIfrCheckBox;
CBObj->SetLineNo(L->getLine());
CBObj->SetQuestionId (QId);
CBObj->SetVarStoreInfo (&Info);
>>
vfrStatementHeader[CBObj]"," << //check data type
if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
_GET_CURRQEST_VARTINFO().mVarType = EFI_IFR_TYPE_BOOLEAN;
}
if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
//
// Check whether the question refers to a bit field, if yes. create a Guid to indicate the question refers to a bit field.
//
if (_GET_CURRQEST_VARTINFO ().mIsBitVar) {
_PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "CheckBox varid is not the valid data type");
if ((gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId) == EFI_VFR_VARSTORE_BUFFER_BITS) &&
(_GET_CURRQEST_VARSIZE() != 1)) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid only occupy 1 bit in Bit Varstore");
}
} else {
_PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "CheckBox varid is not the valid data type");
if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid doesn't support array");
@ -2198,15 +2401,16 @@ vfrStatementCheckBox :
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid only support BOOLEAN data type");
}
}
}
>>
{
F:FLAGS "=" vfrCheckBoxFlags[CBObj, F->getLine()] ","
F:FLAGS "=" vfrCheckBoxFlags[*CBObj, F->getLine()] ","
<<
if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
_PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), VFR_RETURN_SUCCESS, L, "Failed to retrieve varstore name");
VarStoreGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);
Val.b = TRUE;
if (CBObj.GetFlags () & 0x01) {
if (CBObj->GetFlags () & 0x01) {
CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_STANDARD, F);
_PCATCH(
gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
@ -2222,7 +2426,7 @@ vfrStatementCheckBox :
"No standard default storage found"
);
}
if (CBObj.GetFlags () & 0x02) {
if (CBObj->GetFlags () & 0x02) {
CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_MANUFACTURING, F);
_PCATCH(
gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
@ -2242,10 +2446,17 @@ vfrStatementCheckBox :
>>
}
{
Key "=" KN:Number "," << AssignQuestionKey (CBObj, KN); >>
Key "=" KN:Number "," << AssignQuestionKey (*CBObj, KN); >>
}
vfrStatementQuestionOptionList
E:EndCheckBox << CRT_END_OP (E); >>
E:EndCheckBox << CRT_END_OP (E);
if (GuidObj != NULL) {
GuidObj->SetScope(1);
CRT_END_OP (E);
delete GuidObj;
}
if (CBObj != NULL) delete CBObj;
>>
";"
;
@ -2441,7 +2652,8 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
UINT8 MaxU1 = 0, MinU1 = 0, StepU1 = 0;
BOOLEAN IntDecStyle = FALSE;
CIfrNumeric *NObj = (CIfrNumeric *) (&MMSDObj);
if ((NObj->GetOpCode() == EFI_IFR_NUMERIC_OP) && ((NObj->GetNumericFlags() & EFI_IFR_DISPLAY) == 0)) {
if (((_GET_CURRQEST_VARTINFO().mIsBitVar) && (NObj->GetOpCode() == EFI_IFR_NUMERIC_OP) && ((NObj->GetNumericFlags() & EDKII_IFR_DISPLAY_BIT) == 0)) ||
(!(_GET_CURRQEST_VARTINFO().mIsBitVar) && (NObj->GetOpCode() == EFI_IFR_NUMERIC_OP) && ((NObj->GetNumericFlags() & EFI_IFR_DISPLAY) == 0))) {
IntDecStyle = TRUE;
}
BOOLEAN MinNegative = FALSE;
@ -2455,6 +2667,15 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
if (!IntDecStyle && MinNegative) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "\"-\" can't be used when not in int decimal type. ");
}
//
// Value for question stored in bit fields is always set to UINT32 type.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
MinU4 = _STOU32(I->getText(), I->getLine());
if (!IntDecStyle && MinU4 > (1<< _GET_CURRQEST_VARTINFO().mVarTotalSize) -1) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "BIT type minimum can't small than 0, bigger than 2^BitWidth -1");
}
} else {
switch (_GET_CURRQEST_DATATYPE()) {
case EFI_IFR_TYPE_NUM_SIZE_64 :
MinU8 = _STOU64(I->getText(), I->getLine());
@ -2525,6 +2746,7 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
}
break;
}
}
>>
Maximum "="
{
@ -2534,7 +2756,12 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
if (!IntDecStyle && MaxNegative) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "\"-\" can't be used when not in int decimal type. ");
}
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
MaxU4 = _STOU32(A->getText(), A->getLine());
if (!IntDecStyle && MaxU4 > (1<< _GET_CURRQEST_VARTINFO().mVarTotalSize) -1) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "BIT type maximum can't bigger than 2^BitWidth -1");
}
} else {
switch (_GET_CURRQEST_DATATYPE()) {
case EFI_IFR_TYPE_NUM_SIZE_64 :
MaxU8 = _STOU64(A->getText(), A->getLine());
@ -2641,50 +2868,90 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
}
break;
}
}
>>
{
STEP "=" S:Number ","
<<
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
StepU4 = _STOU32(S->getText(), S->getLine());
} else {
switch (_GET_CURRQEST_DATATYPE()) {
case EFI_IFR_TYPE_NUM_SIZE_64 : StepU8 = _STOU64(S->getText(), S->getLine()); break;
case EFI_IFR_TYPE_NUM_SIZE_32 : StepU4 = _STOU32(S->getText(), S->getLine()); break;
case EFI_IFR_TYPE_NUM_SIZE_16 : StepU2 = _STOU16(S->getText(), S->getLine()); break;
case EFI_IFR_TYPE_NUM_SIZE_8 : StepU1 = _STOU8(S->getText(), S->getLine()); break;
}
}
>>
}
<<
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
$MMSDObj.SetMinMaxStepData (MinU4, MaxU4, StepU4);
} else {
switch (_GET_CURRQEST_DATATYPE()) {
case EFI_IFR_TYPE_NUM_SIZE_64 : $MMSDObj.SetMinMaxStepData (MinU8, MaxU8, StepU8); break;
case EFI_IFR_TYPE_NUM_SIZE_32 : $MMSDObj.SetMinMaxStepData (MinU4, MaxU4, StepU4); break;
case EFI_IFR_TYPE_NUM_SIZE_16 : $MMSDObj.SetMinMaxStepData (MinU2, MaxU2, StepU2); break;
case EFI_IFR_TYPE_NUM_SIZE_8 : $MMSDObj.SetMinMaxStepData (MinU1, MaxU1, StepU1); break;
}
}
>>
;
vfrStatementNumeric :
<<
CIfrNumeric NObj;
CIfrNumeric *NObj = NULL;
UINT32 DataTypeSize;
BOOLEAN IsSupported = TRUE;
UINT8 ShrinkSize = 0;
CIfrGuid *GuidObj = NULL;
UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
EFI_VARSTORE_INFO Info;
Info.mVarType = EFI_IFR_TYPE_OTHER;
Info.mVarTotalSize = 0;
Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
Info.mIsBitVar = FALSE;
>>
L:Numeric << NObj.SetLineNo(L->getLine()); >>
vfrQuestionHeader[NObj] "," << // check data type
L:Numeric
vfrQuestionBaseInfo[Info, QId] <<
//
// Create a GUID opcode to wrap the numeric opcode, if it refer to bit varstore.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
GuidObj = new CIfrGuid(0);
GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
GuidObj->SetLineNo(L->getLine());
}
NObj = new CIfrNumeric;
NObj->SetLineNo(L->getLine());
NObj->SetQuestionId (QId);
NObj->SetVarStoreInfo (&Info);
>>
vfrStatementHeader[NObj]","
<<
// check data type
if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & (_GET_CURRQEST_VARSIZE()));
_PCATCH(NObj->SetFlagsForBitField (NObj->FLAGS(), LFlags), L->getLine());
} else {
_PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "Numeric varid is not the valid data type");
if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Numeric varid doesn't support array");
}
_PCATCH(NObj.SetFlags (NObj.FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine());
_PCATCH(NObj->SetFlags (NObj->FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine());
}
}
>>
{ F:FLAGS "=" vfrNumericFlags[NObj, F->getLine()] "," }
{ F:FLAGS "=" vfrNumericFlags[*NObj, F->getLine()] "," }
{
Key "=" KN:Number "," << AssignQuestionKey (NObj, KN); >>
Key "=" KN:Number "," << AssignQuestionKey (*NObj, KN); >>
}
vfrSetMinMaxStep[NObj] <<
vfrSetMinMaxStep[*NObj] <<
if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
switch (_GET_CURRQEST_DATATYPE()) {
//
// Base on the type to know the actual used size,shrink the buffer
@ -2698,7 +2965,14 @@ vfrStatementNumeric :
IsSupported = FALSE;
break;
}
NObj.ShrinkBinSize (ShrinkSize);
} else {
//
// Question stored in bit fields saved as UINT32 type, so the ShrinkSize same as EFI_IFR_TYPE_NUM_SIZE_32.
//
ShrinkSize = 12;
}
NObj->ShrinkBinSize (ShrinkSize);
if (!IsSupported) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Numeric question only support UINT8, UINT16, UINT32 and UINT64 data type.");
}
@ -2706,6 +2980,12 @@ vfrStatementNumeric :
vfrStatementQuestionOptionList
E:EndNumeric <<
CRT_END_OP (E);
if (GuidObj != NULL) {
GuidObj->SetScope(1);
CRT_END_OP (E);
delete GuidObj;
}
if (NObj != NULL) delete NObj;
>>
";"
;
@ -2714,15 +2994,15 @@ vfrNumericFlags [CIfrNumeric & NObj, UINT32 LineNum] :
<<
UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
UINT8 HFlags = 0;
EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
BOOLEAN IsSetType = FALSE;
BOOLEAN IsDisplaySpecified = FALSE;
EFI_VFR_VARSTORE_TYPE VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
>>
numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified] ( "\|" numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified ] )*
numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] ( "\|" numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] )*
<<
//check data type flag
if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_EFI) {
if (_GET_CURRQEST_DATATYPE() != (LFlags & EFI_IFR_NUMERIC_SIZE)) {
_PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Numeric Flag is not same to Numeric VarData type");
@ -2738,43 +3018,115 @@ vfrNumericFlags [CIfrNumeric & NObj, UINT32 LineNum] :
_GET_CURRQEST_VARTINFO().mVarType = LFlags & EFI_IFR_NUMERIC_SIZE;
}
_PCATCH(NObj.SetFlags (HFlags, LFlags, IsDisplaySpecified), LineNum);
} else if ((_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) && (_GET_CURRQEST_VARTINFO().mIsBitVar)) {
LFlags |= (EDKII_IFR_NUMERIC_SIZE_BIT & (_GET_CURRQEST_VARSIZE()));
_PCATCH(NObj.SetFlagsForBitField (HFlags, LFlags, IsDisplaySpecified), LineNum);
}
>>
;
numericFlagsField [UINT8 & HFlags, UINT8 & LFlags, BOOLEAN & IsSetType, BOOLEAN & IsDisplaySpecified] :
numericFlagsField [UINT8 & HFlags, UINT8 & LFlags, BOOLEAN & IsSetType, BOOLEAN & IsDisplaySpecified, UINT32 LineNum] :
N:Number << _PCATCH(_STOU8(N->getText(), N->getLine()) == 0 ? VFR_RETURN_SUCCESS : VFR_RETURN_UNSUPPORTED, N->getLine()); >>
| "NUMERIC_SIZE_1" << $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_1; IsSetType = TRUE;>>
| "NUMERIC_SIZE_2" << $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_2; IsSetType = TRUE;>>
| "NUMERIC_SIZE_4" << $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_4; IsSetType = TRUE;>>
| "NUMERIC_SIZE_8" << $LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_8; IsSetType = TRUE;>>
| "DISPLAY_INT_DEC" << $LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_INT_DEC; IsDisplaySpecified = TRUE;>>
| "DISPLAY_UINT_DEC" << $LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_UINT_DEC; IsDisplaySpecified = TRUE;>>
| "DISPLAY_UINT_HEX" << $LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_UINT_HEX; IsDisplaySpecified = TRUE;>>
| "NUMERIC_SIZE_1" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_1;IsSetType = TRUE;
} else {
_PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
}
>>
| "NUMERIC_SIZE_2" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_2;IsSetType = TRUE;
} else {
_PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
}
>>
| "NUMERIC_SIZE_4" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_4; IsSetType = TRUE;
} else {
_PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
}
>>
| "NUMERIC_SIZE_8" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_NUMERIC_SIZE) | EFI_IFR_NUMERIC_SIZE_8; IsSetType = TRUE;
} else {
_PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Can not specify the size of the numeric value for BIT field");
}
>>
| "DISPLAY_INT_DEC" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_INT_DEC;
} else {
$LFlags = ($LFlags & ~EDKII_IFR_DISPLAY_BIT) | EDKII_IFR_DISPLAY_INT_DEC_BIT;
}
IsDisplaySpecified = TRUE;
>>
| "DISPLAY_UINT_DEC" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_UINT_DEC;
} else {
$LFlags = ($LFlags & ~EDKII_IFR_DISPLAY_BIT) | EDKII_IFR_DISPLAY_UINT_DEC_BIT;
}
IsDisplaySpecified = TRUE;
>>
| "DISPLAY_UINT_HEX" << if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
$LFlags = ($LFlags & ~EFI_IFR_DISPLAY) | EFI_IFR_DISPLAY_UINT_HEX;
} else {
$LFlags = ($LFlags & ~EDKII_IFR_DISPLAY_BIT) | EDKII_IFR_DISPLAY_UINT_HEX_BIT;
}
IsDisplaySpecified = TRUE;
>>
| questionheaderFlagsField[HFlags]
;
vfrStatementOneOf :
<<
CIfrOneOf OObj;
CIfrOneOf *OObj = NULL;
UINT32 DataTypeSize;
BOOLEAN IsSupported = TRUE;
UINT8 ShrinkSize = 0;
CIfrGuid *GuidObj = NULL;
UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;;
EFI_VARSTORE_INFO Info;
Info.mVarType = EFI_IFR_TYPE_OTHER;
Info.mVarTotalSize = 0;
Info.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
Info.mVarStoreId = EFI_VARSTORE_ID_INVALID;
Info.mIsBitVar = FALSE;
>>
L:OneOf << OObj.SetLineNo(L->getLine()); >>
vfrQuestionHeader[OObj] "," << //check data type
L:OneOf
vfrQuestionBaseInfo[Info, QId] <<
//
// Create a GUID opcode to wrap the oneof opcode, if it refer to bit varstore.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
GuidObj = new CIfrGuid(0);
GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
GuidObj->SetLineNo(L->getLine());
}
OObj = new CIfrOneOf;
OObj->SetLineNo(L->getLine());
OObj->SetQuestionId (QId);
OObj->SetVarStoreInfo (&Info);
>>
vfrStatementHeader[OObj]","
<< //check data type
if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & (_GET_CURRQEST_VARSIZE()));
_PCATCH(OObj->SetFlagsForBitField (OObj->FLAGS(), LFlags), L->getLine());
} else {
_PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "OneOf varid is not the valid data type");
if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "OneOf varid doesn't support array");
}
_PCATCH(OObj.SetFlags (OObj.FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine());
_PCATCH(OObj->SetFlags (OObj->FLAGS(), _GET_CURRQEST_DATATYPE()), L->getLine());
}
}
>>
{ F:FLAGS "=" vfrOneofFlagsField[OObj, F->getLine()] "," }
{ F:FLAGS "=" vfrOneofFlagsField[*OObj, F->getLine()] "," }
{
vfrSetMinMaxStep[OObj]
vfrSetMinMaxStep[*OObj]
}
<<
if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
switch (_GET_CURRQEST_DATATYPE()) {
//
// Base on the type to know the actual used size,shrink the buffer
@ -2788,7 +3140,14 @@ vfrStatementOneOf :
IsSupported = FALSE;
break;
}
OObj.ShrinkBinSize (ShrinkSize);
} else {
//
// Question stored in bit fields saved as UINT32 type, so the ShrinkSize same as EFI_IFR_TYPE_NUM_SIZE_32.
//
ShrinkSize = 12;
}
OObj->ShrinkBinSize (ShrinkSize);
if (!IsSupported) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "OneOf question only support UINT8, UINT16, UINT32 and UINT64 data type.");
}
@ -2796,6 +3155,12 @@ vfrStatementOneOf :
vfrStatementQuestionOptionList
E:EndOneOf <<
CRT_END_OP (E);
if (GuidObj != NULL) {
GuidObj->SetScope(1);
CRT_END_OP (E);
delete GuidObj;
}
if (OObj != NULL) delete OObj;
>>
";"
;
@ -2804,15 +3169,15 @@ vfrOneofFlagsField [CIfrOneOf & OObj, UINT32 LineNum] :
<<
UINT8 LFlags = _GET_CURRQEST_DATATYPE() & EFI_IFR_NUMERIC_SIZE;
UINT8 HFlags = 0;
EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
BOOLEAN IsSetType = FALSE;
BOOLEAN IsDisplaySpecified = FALSE;
EFI_VFR_VARSTORE_TYPE VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
>>
numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified] ( "\|" numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified] )*
numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] ( "\|" numericFlagsField[HFlags, LFlags, IsSetType, IsDisplaySpecified, LineNum] )*
<<
//check data type flag
if (!_GET_CURRQEST_VARTINFO().mIsBitVar) {
if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);
if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_EFI) {
if (_GET_CURRQEST_DATATYPE() != (LFlags & EFI_IFR_NUMERIC_SIZE)) {
_PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Numeric Flag is not same to Numeric VarData type");
@ -2828,6 +3193,9 @@ vfrOneofFlagsField [CIfrOneOf & OObj, UINT32 LineNum] :
_GET_CURRQEST_VARTINFO().mVarType = LFlags & EFI_IFR_NUMERIC_SIZE;
}
_PCATCH(OObj.SetFlags (HFlags, LFlags), LineNum);
} else if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {
_PCATCH(OObj.SetFlagsForBitField (HFlags, LFlags), LineNum);
}
>>
;
@ -3381,7 +3749,10 @@ vfrStatementOneOfOption :
<<
if (gCurrentMinMaxData != NULL) {
//set min/max value for oneof opcode
UINT64 Step = gCurrentMinMaxData->GetStepData(_GET_CURRQEST_DATATYPE());
UINT64 Step = gCurrentMinMaxData->GetStepData(_GET_CURRQEST_DATATYPE(), _GET_CURRQEST_VARTINFO().mIsBitVar);
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
gCurrentMinMaxData->SetMinMaxStepData(Val->u32, Val->u32, (UINT32) Step);
} else {
switch (_GET_CURRQEST_DATATYPE()) {
case EFI_IFR_TYPE_NUM_SIZE_64:
gCurrentMinMaxData->SetMinMaxStepData(Val->u64, Val->u64, Step);
@ -3399,6 +3770,7 @@ vfrStatementOneOfOption :
break;
}
}
}
if (_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
Size = sizeof (EFI_IFR_TYPE_VALUE);
} else if (ArrayType) {
@ -3429,9 +3801,16 @@ vfrStatementOneOfOption :
default:
break;
}
} else {
//
// For the oneof stored in bit fields, set the option type as UINT32.
//
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
Size = sizeof (UINT32);
} else {
ReturnCode = gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &Size);
}
}
if (ReturnCode != VFR_RETURN_SUCCESS) {
_PCATCH (ReturnCode, L->getLine());
}
@ -3442,9 +3821,13 @@ vfrStatementOneOfOption :
OOOObj->SetOption (_STOSID(S->getText(), S->getLine()));
if (ArrayType) {
OOOObj->SetType (EFI_IFR_TYPE_BUFFER);
} else {
if (_GET_CURRQEST_VARTINFO().mIsBitVar) {
OOOObj->SetType ( EFI_IFR_TYPE_NUM_SIZE_32);
} else {
OOOObj->SetType (_GET_CURRQEST_DATATYPE());
}
}
OOOObj->SetValue (*Val);
>>
F:FLAGS "=" vfrOneOfOptionFlags[*OOOObj, F->getLine()]
@ -5222,7 +5605,8 @@ EfiVfrParser::_DeclareDefaultLinearVarStore (
&mFormsetGuid,
&gCVfrVarDataTypeDB,
TypeNameList[Index],
EFI_VARSTORE_ID_INVALID
EFI_VARSTORE_ID_INVALID,
FALSE
);
gCVfrDataStorage.GetVarStoreId(TypeNameList[Index], &VarStoreId, &mFormsetGuid);
VSObj.SetVarStoreId (VarStoreId);
@ -5247,7 +5631,8 @@ EfiVfrParser::_DeclareDefaultLinearVarStore (
&mFormsetGuid,
&gCVfrVarDataTypeDB,
(CHAR8 *) DateType,
EFI_VARSTORE_ID_INVALID
EFI_VARSTORE_ID_INVALID,
FALSE
);
gCVfrDataStorage.GetVarStoreId((CHAR8 *) DateName, &VarStoreId, &mFormsetGuid);
VSObj.SetVarStoreId (VarStoreId);
@ -5268,7 +5653,8 @@ EfiVfrParser::_DeclareDefaultLinearVarStore (
&mFormsetGuid,
&gCVfrVarDataTypeDB,
(CHAR8 *) TimeType,
EFI_VARSTORE_ID_INVALID
EFI_VARSTORE_ID_INVALID,
FALSE
);
gCVfrDataStorage.GetVarStoreId((CHAR8 *) TimeName, &VarStoreId, &mFormsetGuid);
VSObj.SetVarStoreId (VarStoreId);

View File

@ -600,6 +600,61 @@ CVfrVarDataTypeDB::ExtractStructTypeName (
return VFR_RETURN_SUCCESS;
}
/**
Check whether the DataType contain bit field.
@param TypeName The name of the type.
**/
BOOLEAN
CVfrVarDataTypeDB::DataTypeHasBitField (
IN CHAR8 *TypeName
)
{
SVfrDataType *pType = NULL;
SVfrDataField *pTmp;
GetDataType (TypeName, &pType);
for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {
if (pTmp->mIsBitField) {
return TRUE;
}
}
return FALSE;
}
/**
Check whether the field is bit field or not.
@param VarStr Point to the field name which may contain the structure name.
**/
BOOLEAN
CVfrVarDataTypeDB::IsThisBitField (
IN CHAR8 *VarStr
)
{
CHAR8 FName[MAX_NAME_LEN];
CHAR8 TName[MAX_NAME_LEN];
UINT32 ArrayIdx;
SVfrDataType *pType = NULL;
SVfrDataField *pField = NULL;
CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
while (*VarStr != '\0') {
CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
pType = pField->mFieldType;
}
if (pField->mIsBitField) {
return TRUE;
} else {
return FALSE;
}
}
EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
IN CHAR8 *&VarStr,
@ -697,7 +752,8 @@ EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::GetFieldOffset (
IN SVfrDataField *Field,
IN UINT32 ArrayIdx,
OUT UINT32 &Offset
OUT UINT32 &Offset,
IN BOOLEAN IsBitField
)
{
if (Field == NULL) {
@ -729,8 +785,11 @@ CVfrVarDataTypeDB::GetFieldOffset (
// return VFR_RETURN_ERROR_ARRARY_NUM;
// }
//
if (IsBitField) {
Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;
} else {
Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
}
return VFR_RETURN_SUCCESS;
}
@ -749,7 +808,8 @@ CVfrVarDataTypeDB::GetFieldWidth (
UINT32
CVfrVarDataTypeDB::GetFieldSize (
IN SVfrDataField *Field,
IN UINT32 ArrayIdx
IN UINT32 ArrayIdx,
IN BOOLEAN BitField
)
{
if (Field == NULL) {
@ -758,10 +818,14 @@ CVfrVarDataTypeDB::GetFieldSize (
if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
return Field->mFieldType->mTotalSize * Field->mArrayNum;
} else {
if (BitField) {
return Field->mBitWidth;
} else {
return Field->mFieldType->mTotalSize;
}
}
}
VOID
CVfrVarDataTypeDB::InternalTypesListInit (
@ -788,18 +852,21 @@ CVfrVarDataTypeDB::InternalTypesListInit (
pYearField->mOffset = 0;
pYearField->mNext = pMonthField;
pYearField->mArrayNum = 0;
pYearField->mIsBitField = FALSE;
strcpy (pMonthField->mFieldName, "Month");
GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
pMonthField->mOffset = 2;
pMonthField->mNext = pDayField;
pMonthField->mArrayNum = 0;
pMonthField->mIsBitField = FALSE;
strcpy (pDayField->mFieldName, "Day");
GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
pDayField->mOffset = 3;
pDayField->mNext = NULL;
pDayField->mArrayNum = 0;
pDayField->mIsBitField = FALSE;
New->mMembers = pYearField;
} else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
@ -812,18 +879,21 @@ CVfrVarDataTypeDB::InternalTypesListInit (
pHoursField->mOffset = 0;
pHoursField->mNext = pMinutesField;
pHoursField->mArrayNum = 0;
pHoursField->mIsBitField = FALSE;
strcpy (pMinutesField->mFieldName, "Minutes");
GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
pMinutesField->mOffset = 1;
pMinutesField->mNext = pSecondsField;
pMinutesField->mArrayNum = 0;
pMinutesField->mIsBitField = FALSE;
strcpy (pSecondsField->mFieldName, "Seconds");
GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
pSecondsField->mOffset = 2;
pSecondsField->mNext = NULL;
pSecondsField->mArrayNum = 0;
pSecondsField->mIsBitField = FALSE;
New->mMembers = pHoursField;
} else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
@ -837,24 +907,28 @@ CVfrVarDataTypeDB::InternalTypesListInit (
pQuestionIdField->mOffset = 0;
pQuestionIdField->mNext = pFormIdField;
pQuestionIdField->mArrayNum = 0;
pQuestionIdField->mIsBitField = FALSE;
strcpy (pFormIdField->mFieldName, "FormId");
GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
pFormIdField->mOffset = 2;
pFormIdField->mNext = pFormSetGuidField;
pFormIdField->mArrayNum = 0;
pFormIdField->mIsBitField = FALSE;
strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
pFormSetGuidField->mOffset = 4;
pFormSetGuidField->mNext = pDevicePathField;
pFormSetGuidField->mArrayNum = 0;
pFormSetGuidField->mIsBitField = FALSE;
strcpy (pDevicePathField->mFieldName, "DevicePath");
GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
pDevicePathField->mOffset = 20;
pDevicePathField->mNext = NULL;
pDevicePathField->mArrayNum = 0;
pDevicePathField->mIsBitField = FALSE;
New->mMembers = pQuestionIdField;
} else {
@ -978,6 +1052,7 @@ CVfrVarDataTypeDB::DeclareDataTypeBegin (
pNewType->mTotalSize = 0;
pNewType->mMembers = NULL;
pNewType->mNext = NULL;
pNewType->mHasBitField = FALSE;
mNewDataType = pNewType;
}
@ -1009,6 +1084,125 @@ CVfrVarDataTypeDB::SetNewTypeName (
return VFR_RETURN_SUCCESS;
}
/**
Record the bit field info in the data type.
@param FieldName Point to the field name.
@param TypeName Point to the type name.
@param Width The bit width.
@param FieldInUnion The filed is in Union type or Structure type.
**/
EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::DataTypeAddBitField (
IN CHAR8 *FieldName,
IN CHAR8 *TypeName,
IN UINT32 Width,
IN BOOLEAN FieldInUnion
)
{
SVfrDataField *pNewField = NULL;
SVfrDataType *pFieldType = NULL;
SVfrDataField *pTmp;
UINT32 Align;
UINT32 MaxDataTypeSize;
BOOLEAN UpdateTotalSize;
CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
if (Width > MAX_BIT_WIDTH) {
return VFR_RETURN_BIT_WIDTH_ERROR;
}
if (Width > pFieldType->mTotalSize * 8) {
return VFR_RETURN_BIT_WIDTH_ERROR;
}
if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {
return VFR_RETURN_INVALID_PARAMETER;
}
if (Width == 0 && FieldName != NULL) {
return VFR_RETURN_INVALID_PARAMETER;
}
for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {
return VFR_RETURN_REDEFINED;
}
}
Align = MIN (mPackAlign, pFieldType->mAlign);
UpdateTotalSize = FALSE;
if ((pNewField = new SVfrDataField) == NULL) {
return VFR_RETURN_OUT_FOR_RESOURCES;
}
MaxDataTypeSize = mNewDataType->mTotalSize;
if (FieldName != NULL) {
strcpy (pNewField->mFieldName, FieldName);
}
pNewField->mFieldType = pFieldType;
pNewField->mIsBitField = TRUE;
pNewField->mBitWidth = Width;
pNewField->mArrayNum = 0;
pNewField->mBitOffset = 0;
pNewField->mOffset = 0;
if (mNewDataType->mMembers == NULL) {
mNewDataType->mMembers = pNewField;
pNewField->mNext = NULL;
} else {
for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
;
pTmp->mNext = pNewField;
pNewField->mNext = NULL;
}
if (FieldInUnion) {
pNewField->mOffset = 0;
if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
}
} else {
//
// Check whether the bit fileds can be contained within one FieldType.
//
if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&
(pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {
pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;
pNewField->mOffset = pTmp->mOffset;
//
// If BitWidth=0,used to force alignment at the next word boundary.
// So make this bit field occupy the remaing bit width of current field type.
//
if (pNewField->mBitWidth == 0) {
pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);
}
} else {
//
// The bit filed start a new memory
//
pNewField->mBitOffset = mNewDataType->mTotalSize * 8;
UpdateTotalSize = TRUE;
}
}
if (UpdateTotalSize){
if ((mNewDataType->mTotalSize % Align) == 0) {
pNewField->mOffset = mNewDataType->mTotalSize;
} else {
pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
}
mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);
}
mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
mNewDataType->mHasBitField = TRUE;
return VFR_RETURN_SUCCESS;
}
EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::DataTypeAddField (
IN CHAR8 *FieldName,
@ -1044,6 +1238,7 @@ CVfrVarDataTypeDB::DataTypeAddField (
strcpy (pNewField->mFieldName, FieldName);
pNewField->mFieldType = pFieldType;
pNewField->mArrayNum = ArrayNum;
pNewField->mIsBitField = FALSE;
if ((mNewDataType->mTotalSize % Align) == 0) {
pNewField->mOffset = mNewDataType->mTotalSize;
} else {
@ -1183,21 +1378,26 @@ CVfrVarDataTypeDB::GetDataFieldInfo (
IN CHAR8 *VarStr,
OUT UINT16 &Offset,
OUT UINT8 &Type,
OUT UINT32 &Size
OUT UINT32 &Size,
OUT BOOLEAN &BitField
)
{
CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
UINT32 ArrayIdx, Tmp;
SVfrDataType *pType = NULL;
SVfrDataField *pField = NULL;
CHAR8 *VarStrName;
Offset = 0;
Type = EFI_IFR_TYPE_OTHER;
Size = 0;
VarStrName = VarStr;
CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
BitField = IsThisBitField (VarStrName);
//
// if it is not struct data type
//
@ -1208,10 +1408,14 @@ CVfrVarDataTypeDB::GetDataFieldInfo (
CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
pType = pField->mFieldType;
CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);
if (BitField && !pField->mIsBitField) {
Offset = (UINT16) (Offset + Tmp * 8);
} else {
Offset = (UINT16) (Offset + Tmp);
}
Type = GetFieldWidth (pField);
Size = GetFieldSize (pField, ArrayIdx);
Size = GetFieldSize (pField, ArrayIdx, BitField);
}
return VFR_RETURN_SUCCESS;
}
@ -1360,6 +1564,7 @@ SVfrVarStorageNode::SVfrVarStorageNode (
IN CHAR8 *StoreName,
IN EFI_VARSTORE_ID VarStoreId,
IN SVfrDataType *DataType,
IN BOOLEAN BitsVarstore,
IN BOOLEAN Flag
)
{
@ -1376,7 +1581,11 @@ SVfrVarStorageNode::SVfrVarStorageNode (
}
mNext = NULL;
mVarStoreId = VarStoreId;
if (BitsVarstore) {
mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;
} else {
mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
}
mStorageInfo.mDataType = DataType;
mAssignedFlag = Flag;
}
@ -1648,6 +1857,7 @@ CVfrDataStorage::DeclareBufferVarStore (
IN CVfrVarDataTypeDB *DataTypeDB,
IN CHAR8 *TypeName,
IN EFI_VARSTORE_ID VarStoreId,
IN BOOLEAN IsBitVarStore,
IN BOOLEAN Flag
)
{
@ -1674,7 +1884,7 @@ CVfrDataStorage::DeclareBufferVarStore (
MarkVarStoreIdUsed (VarStoreId);
}
if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {
return VFR_RETURN_OUT_FOR_RESOURCES;
}
@ -2388,6 +2598,7 @@ EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
mVarType = EFI_IFR_TYPE_OTHER;
mVarTotalSize = 0;
mIsBitVar = FALSE;
}
EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
@ -2399,6 +2610,7 @@ EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
mInfo.mVarOffset = Info.mInfo.mVarOffset;
mVarType = Info.mVarType;
mVarTotalSize = Info.mVarTotalSize;
mIsBitVar = Info.mIsBitVar;
}
EFI_VARSTORE_INFO&
@ -2412,6 +2624,7 @@ EFI_VARSTORE_INFO::operator= (
mInfo.mVarOffset = Info.mInfo.mVarOffset;
mVarType = Info.mVarType;
mVarTotalSize = Info.mVarTotalSize;
mIsBitVar = Info.mIsBitVar;
}
return *this;
@ -2426,7 +2639,8 @@ EFI_VARSTORE_INFO::operator == (
(mInfo.mVarName == Info->mInfo.mVarName) &&
(mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
(mVarType == Info->mVarType) &&
(mVarTotalSize == Info->mVarTotalSize)) {
(mVarTotalSize == Info->mVarTotalSize) &&
(mIsBitVar == Info->mIsBitVar)) {
return TRUE;
}

View File

@ -22,7 +22,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "VfrError.h"
extern BOOLEAN VfrCompatibleMode;
static EFI_GUID gEdkiiIfrBitVarGuid = EDKII_IFR_BIT_VARSTORE_GUID;
#define MAX_BIT_WIDTH 32
#define MAX_NAME_LEN 64
#define MAX_STRING_LEN 0x100
#define DEFAULT_ALIGN 1
@ -116,6 +118,9 @@ struct SVfrDataField {
SVfrDataType *mFieldType;
UINT32 mOffset;
UINT32 mArrayNum;
BOOLEAN mIsBitField;
UINT8 mBitWidth;
UINT32 mBitOffset;
SVfrDataField *mNext;
};
@ -124,6 +129,7 @@ struct SVfrDataType {
UINT8 mType;
UINT32 mAlign;
UINT32 mTotalSize;
BOOLEAN mHasBitField;
SVfrDataField *mMembers;
SVfrDataType *mNext;
};
@ -195,9 +201,9 @@ private:
EFI_VFR_RETURN_CODE ExtractStructTypeName (IN CHAR8 *&, OUT CHAR8 *);
EFI_VFR_RETURN_CODE GetTypeField (IN CONST CHAR8 *, IN SVfrDataType *, IN SVfrDataField *&);
EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &);
EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &, IN BOOLEAN);
UINT8 GetFieldWidth (IN SVfrDataField *);
UINT32 GetFieldSize (IN SVfrDataField *, IN UINT32);
UINT32 GetFieldSize (IN SVfrDataField *, IN UINT32, IN BOOLEAN);
public:
CVfrVarDataTypeDB (VOID);
@ -206,15 +212,18 @@ public:
VOID DeclareDataTypeBegin (VOID);
EFI_VFR_RETURN_CODE SetNewTypeName (IN CHAR8 *);
EFI_VFR_RETURN_CODE DataTypeAddField (IN CHAR8 *, IN CHAR8 *, IN UINT32, IN BOOLEAN);
EFI_VFR_RETURN_CODE DataTypeAddBitField (IN CHAR8 *, IN CHAR8 *, IN UINT32, IN BOOLEAN);
VOID DeclareDataTypeEnd (VOID);
EFI_VFR_RETURN_CODE GetDataType (IN CHAR8 *, OUT SVfrDataType **);
EFI_VFR_RETURN_CODE GetDataTypeSize (IN CHAR8 *, OUT UINT32 *);
EFI_VFR_RETURN_CODE GetDataTypeSize (IN UINT8, OUT UINT32 *);
EFI_VFR_RETURN_CODE GetDataFieldInfo (IN CHAR8 *, OUT UINT16 &, OUT UINT8 &, OUT UINT32 &);
EFI_VFR_RETURN_CODE GetDataFieldInfo (IN CHAR8 *, OUT UINT16 &, OUT UINT8 &, OUT UINT32 &, OUT BOOLEAN &);
EFI_VFR_RETURN_CODE GetUserDefinedTypeNameList (OUT CHAR8 ***, OUT UINT32 *);
EFI_VFR_RETURN_CODE ExtractFieldNameAndArrary (IN CHAR8 *&, OUT CHAR8 *, OUT UINT32 &);
BOOLEAN DataTypeHasBitField (IN CHAR8 *);
BOOLEAN IsThisBitField (IN CHAR8 *);
BOOLEAN IsTypeNameDefined (IN CHAR8 *);
@ -238,7 +247,8 @@ typedef enum {
EFI_VFR_VARSTORE_INVALID,
EFI_VFR_VARSTORE_BUFFER,
EFI_VFR_VARSTORE_EFI,
EFI_VFR_VARSTORE_NAME
EFI_VFR_VARSTORE_NAME,
EFI_VFR_VARSTORE_BUFFER_BITS
} EFI_VFR_VARSTORE_TYPE;
struct SVfrVarStorageNode {
@ -268,7 +278,7 @@ struct SVfrVarStorageNode {
public:
SVfrVarStorageNode (IN EFI_GUID *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN EFI_STRING_ID, IN UINT32, IN BOOLEAN Flag = TRUE);
SVfrVarStorageNode (IN EFI_GUID *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *, IN BOOLEAN Flag = TRUE);
SVfrVarStorageNode (IN EFI_GUID *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *,IN BOOLEAN, IN BOOLEAN Flag = TRUE);
SVfrVarStorageNode (IN CHAR8 *, IN EFI_VARSTORE_ID);
~SVfrVarStorageNode (VOID);
@ -285,6 +295,7 @@ struct EFI_VARSTORE_INFO {
} mInfo;
UINT8 mVarType;
UINT32 mVarTotalSize;
BOOLEAN mIsBitVar;
EFI_VARSTORE_INFO (VOID);
EFI_VARSTORE_INFO (IN EFI_VARSTORE_INFO &);
@ -343,7 +354,7 @@ public:
EFI_VFR_RETURN_CODE DeclareEfiVarStore (IN CHAR8 *, IN EFI_GUID *, IN EFI_STRING_ID, IN UINT32, IN BOOLEAN Flag = TRUE);
EFI_VFR_RETURN_CODE DeclareBufferVarStore (IN CHAR8 *, IN EFI_GUID *, IN CVfrVarDataTypeDB *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN BOOLEAN Flag = TRUE);
EFI_VFR_RETURN_CODE DeclareBufferVarStore (IN CHAR8 *, IN EFI_GUID *, IN CVfrVarDataTypeDB *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN BOOLEAN, IN BOOLEAN Flag = TRUE);
EFI_VFR_RETURN_CODE GetVarStoreId (IN CHAR8 *, OUT EFI_VARSTORE_ID *, IN EFI_GUID *VarGuid = NULL);
EFI_VFR_VARSTORE_TYPE GetVarStoreType (IN EFI_VARSTORE_ID);