return VFR_RETURN_SUCCESS;\r
}\r
\r
+/**\r
+ Check whether the DataType contain bit field.\r
+\r
+ @param TypeName The name of the type.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrVarDataTypeDB::DataTypeHasBitField (\r
+ IN CHAR8 *TypeName\r
+ )\r
+{\r
+ SVfrDataType *pType = NULL;\r
+ SVfrDataField *pTmp;\r
+\r
+ GetDataType (TypeName, &pType);\r
+\r
+ if (pType == NULL){\r
+ return FALSE;\r
+ }\r
+ for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {\r
+ if (pTmp->mIsBitField) {\r
+ return TRUE;\r
+ }\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check whether the field is bit field or not.\r
+\r
+ @param VarStr Point to the field name which may contain the structure name.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrVarDataTypeDB::IsThisBitField (\r
+ IN CHAR8 *VarStr\r
+ )\r
+{\r
+ CHAR8 FName[MAX_NAME_LEN];\r
+ CHAR8 TName[MAX_NAME_LEN];\r
+ UINT32 ArrayIdx;\r
+ SVfrDataType *pType = NULL;\r
+ SVfrDataField *pField = NULL;\r
+\r
+ CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
+ CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
+\r
+ while (*VarStr != '\0') {\r
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+ CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
+ pType = pField->mFieldType;\r
+ }\r
+ if (pField != NULL && pField->mIsBitField) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
EFI_VFR_RETURN_CODE\r
CVfrVarDataTypeDB::ExtractFieldNameAndArrary (\r
IN CHAR8 *&VarStr,\r
CVfrVarDataTypeDB::GetFieldOffset (\r
IN SVfrDataField *Field,\r
IN UINT32 ArrayIdx,\r
- OUT UINT32 &Offset\r
+ OUT UINT32 &Offset,\r
+ IN BOOLEAN IsBitField\r
)\r
{\r
if (Field == NULL) {\r
// return VFR_RETURN_ERROR_ARRARY_NUM;\r
// }\r
//\r
-\r
- Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+ if (IsBitField) {\r
+ Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;\r
+ } else {\r
+ Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+ }\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
UINT32\r
CVfrVarDataTypeDB::GetFieldSize (\r
IN SVfrDataField *Field,\r
- IN UINT32 ArrayIdx\r
+ IN UINT32 ArrayIdx,\r
+ IN BOOLEAN BitField\r
)\r
{\r
if (Field == NULL) {\r
}\r
\r
if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
- return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
+ return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
} else {\r
- return Field->mFieldType->mTotalSize;\r
+ if (BitField) {\r
+ return Field->mBitWidth;\r
+ } else {\r
+ return Field->mFieldType->mTotalSize;\r
+ }\r
}\r
}\r
\r
pYearField->mOffset = 0;\r
pYearField->mNext = pMonthField;\r
pYearField->mArrayNum = 0;\r
+ pYearField->mIsBitField = FALSE;\r
\r
strcpy (pMonthField->mFieldName, "Month");\r
GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);\r
pMonthField->mOffset = 2;\r
pMonthField->mNext = pDayField;\r
pMonthField->mArrayNum = 0;\r
+ pMonthField->mIsBitField = FALSE;\r
\r
strcpy (pDayField->mFieldName, "Day");\r
GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);\r
pDayField->mOffset = 3;\r
pDayField->mNext = NULL;\r
pDayField->mArrayNum = 0;\r
+ pDayField->mIsBitField = FALSE;\r
\r
New->mMembers = pYearField;\r
} else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
pHoursField->mOffset = 0;\r
pHoursField->mNext = pMinutesField;\r
pHoursField->mArrayNum = 0;\r
+ pHoursField->mIsBitField = FALSE;\r
\r
strcpy (pMinutesField->mFieldName, "Minutes");\r
GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);\r
pMinutesField->mOffset = 1;\r
pMinutesField->mNext = pSecondsField;\r
pMinutesField->mArrayNum = 0;\r
+ pMinutesField->mIsBitField = FALSE;\r
\r
strcpy (pSecondsField->mFieldName, "Seconds");\r
GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);\r
pSecondsField->mOffset = 2;\r
pSecondsField->mNext = NULL;\r
pSecondsField->mArrayNum = 0;\r
+ pSecondsField->mIsBitField = FALSE;\r
\r
New->mMembers = pHoursField;\r
} else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {\r
pQuestionIdField->mOffset = 0;\r
pQuestionIdField->mNext = pFormIdField;\r
pQuestionIdField->mArrayNum = 0;\r
+ pQuestionIdField->mIsBitField = FALSE;\r
\r
strcpy (pFormIdField->mFieldName, "FormId");\r
GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);\r
pFormIdField->mOffset = 2;\r
pFormIdField->mNext = pFormSetGuidField;\r
pFormIdField->mArrayNum = 0;\r
+ pFormIdField->mIsBitField = FALSE;\r
\r
strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");\r
GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);\r
pFormSetGuidField->mOffset = 4;\r
pFormSetGuidField->mNext = pDevicePathField;\r
pFormSetGuidField->mArrayNum = 0;\r
+ pFormSetGuidField->mIsBitField = FALSE;\r
\r
strcpy (pDevicePathField->mFieldName, "DevicePath");\r
GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);\r
pDevicePathField->mOffset = 20;\r
pDevicePathField->mNext = NULL;\r
pDevicePathField->mArrayNum = 0;\r
+ pDevicePathField->mIsBitField = FALSE;\r
\r
New->mMembers = pQuestionIdField;\r
} else {\r
pNewType->mTotalSize = 0;\r
pNewType->mMembers = NULL;\r
pNewType->mNext = NULL;\r
+ pNewType->mHasBitField = FALSE;\r
\r
mNewDataType = pNewType;\r
}\r
return VFR_RETURN_SUCCESS;\r
}\r
\r
+/**\r
+ Record the bit field info in the data type.\r
+\r
+ @param FieldName Point to the field name.\r
+ @param TypeName Point to the type name.\r
+ @param Width The bit width.\r
+ @param FieldInUnion The filed is in Union type or Structure type.\r
+\r
+**/\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::DataTypeAddBitField (\r
+ IN CHAR8 *FieldName,\r
+ IN CHAR8 *TypeName,\r
+ IN UINT32 Width,\r
+ IN BOOLEAN FieldInUnion\r
+ )\r
+{\r
+ SVfrDataField *pNewField = NULL;\r
+ SVfrDataType *pFieldType = NULL;\r
+ SVfrDataField *pTmp;\r
+ UINT32 Align;\r
+ UINT32 MaxDataTypeSize;\r
+ BOOLEAN UpdateTotalSize;\r
+\r
+ CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
+\r
+ if (Width > MAX_BIT_WIDTH) {\r
+ return VFR_RETURN_BIT_WIDTH_ERROR;\r
+ }\r
+\r
+ if (Width > pFieldType->mTotalSize * 8) {\r
+ return VFR_RETURN_BIT_WIDTH_ERROR;\r
+ }\r
+\r
+ if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {\r
+ return VFR_RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Width == 0 && FieldName != NULL) {\r
+ return VFR_RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
+ if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {\r
+ return VFR_RETURN_REDEFINED;\r
+ }\r
+ }\r
+\r
+ Align = MIN (mPackAlign, pFieldType->mAlign);\r
+ UpdateTotalSize = FALSE;\r
+\r
+ if ((pNewField = new SVfrDataField) == NULL) {\r
+ return VFR_RETURN_OUT_FOR_RESOURCES;\r
+ }\r
+\r
+ MaxDataTypeSize = mNewDataType->mTotalSize;\r
+ if (FieldName != NULL) {\r
+ strcpy (pNewField->mFieldName, FieldName);\r
+ }\r
+ pNewField->mFieldType = pFieldType;\r
+ pNewField->mIsBitField = TRUE;\r
+ pNewField->mBitWidth = Width;\r
+ pNewField->mArrayNum = 0;\r
+ pNewField->mBitOffset = 0;\r
+ pNewField->mOffset = 0;\r
+\r
+ if (mNewDataType->mMembers == NULL) {\r
+ mNewDataType->mMembers = pNewField;\r
+ pNewField->mNext = NULL;\r
+ } else {\r
+ for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
+ ;\r
+ pTmp->mNext = pNewField;\r
+ pNewField->mNext = NULL;\r
+ }\r
+\r
+ if (FieldInUnion) {\r
+ pNewField->mOffset = 0;\r
+ if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
+ mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
+ }\r
+ } else {\r
+ //\r
+ // Check whether the bit fileds can be contained within one FieldType.\r
+ //\r
+ if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&\r
+ (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {\r
+ pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;\r
+ pNewField->mOffset = pTmp->mOffset;\r
+ //\r
+ // If BitWidth=0,used to force alignment at the next word boundary.\r
+ // So make this bit field occupy the remaing bit width of current field type.\r
+ //\r
+ if (pNewField->mBitWidth == 0) {\r
+ pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);\r
+ }\r
+ } else {\r
+ //\r
+ // The bit filed start a new memory\r
+ //\r
+ pNewField->mBitOffset = mNewDataType->mTotalSize * 8;\r
+ UpdateTotalSize = TRUE;\r
+ }\r
+ }\r
+\r
+ if (UpdateTotalSize){\r
+ if ((mNewDataType->mTotalSize % Align) == 0) {\r
+ pNewField->mOffset = mNewDataType->mTotalSize;\r
+ } else {\r
+ pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
+ }\r
+ mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);\r
+ }\r
+\r
+ mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
+ mNewDataType->mHasBitField = TRUE;\r
+ return VFR_RETURN_SUCCESS;\r
+}\r
+\r
EFI_VFR_RETURN_CODE\r
CVfrVarDataTypeDB::DataTypeAddField (\r
IN CHAR8 *FieldName,\r
strcpy (pNewField->mFieldName, FieldName);\r
pNewField->mFieldType = pFieldType;\r
pNewField->mArrayNum = ArrayNum;\r
+ pNewField->mIsBitField = FALSE;\r
if ((mNewDataType->mTotalSize % Align) == 0) {\r
pNewField->mOffset = mNewDataType->mTotalSize;\r
} else {\r
IN CHAR8 *VarStr,\r
OUT UINT16 &Offset,\r
OUT UINT8 &Type,\r
- OUT UINT32 &Size\r
+ OUT UINT32 &Size,\r
+ OUT BOOLEAN &BitField\r
)\r
{\r
CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
UINT32 ArrayIdx, Tmp;\r
SVfrDataType *pType = NULL;\r
SVfrDataField *pField = NULL;\r
+ CHAR8 *VarStrName;\r
\r
Offset = 0;\r
Type = EFI_IFR_TYPE_OTHER;\r
Size = 0;\r
+ VarStrName = VarStr;\r
\r
CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
\r
+ BitField = IsThisBitField (VarStrName);\r
+\r
//\r
// if it is not struct data type\r
//\r
Size = pType->mTotalSize;\r
\r
while (*VarStr != '\0') {\r
- CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+ CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
pType = pField->mFieldType;\r
- CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
- Offset = (UINT16) (Offset + Tmp);\r
+ CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);\r
+ if (BitField && !pField->mIsBitField) {\r
+ Offset = (UINT16) (Offset + Tmp * 8);\r
+ } else {\r
+ Offset = (UINT16) (Offset + Tmp);\r
+ }\r
Type = GetFieldWidth (pField);\r
- Size = GetFieldSize (pField, ArrayIdx);\r
+ Size = GetFieldSize (pField, ArrayIdx, BitField);\r
}\r
return VFR_RETURN_SUCCESS;\r
}\r
IN CHAR8 *StoreName,\r
IN EFI_VARSTORE_ID VarStoreId,\r
IN SVfrDataType *DataType,\r
+ IN BOOLEAN BitsVarstore,\r
IN BOOLEAN Flag\r
)\r
{\r
}\r
mNext = NULL;\r
mVarStoreId = VarStoreId;\r
- mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
+ if (BitsVarstore) {\r
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;\r
+ } else {\r
+ mVarStoreType = EFI_VFR_VARSTORE_BUFFER;\r
+ }\r
mStorageInfo.mDataType = DataType;\r
mAssignedFlag = Flag;\r
}\r
IN CVfrVarDataTypeDB *DataTypeDB,\r
IN CHAR8 *TypeName,\r
IN EFI_VARSTORE_ID VarStoreId,\r
+ IN BOOLEAN IsBitVarStore,\r
IN BOOLEAN Flag\r
)\r
{\r
MarkVarStoreIdUsed (VarStoreId);\r
}\r
\r
- if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
+ if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {\r
return VFR_RETURN_OUT_FOR_RESOURCES;\r
}\r
\r
mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
mVarType = EFI_IFR_TYPE_OTHER;\r
mVarTotalSize = 0;\r
+ mIsBitVar = FALSE;\r
}\r
\r
EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
mVarType = Info.mVarType;\r
mVarTotalSize = Info.mVarTotalSize;\r
+ mIsBitVar = Info.mIsBitVar;\r
}\r
\r
EFI_VARSTORE_INFO&\r
mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
mVarType = Info.mVarType;\r
mVarTotalSize = Info.mVarTotalSize;\r
+ mIsBitVar = Info.mIsBitVar;\r
}\r
\r
return *this;\r
(mInfo.mVarName == Info->mInfo.mVarName) &&\r
(mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
(mVarType == Info->mVarType) &&\r
- (mVarTotalSize == Info->mVarTotalSize)) {\r
+ (mVarTotalSize == Info->mVarTotalSize) &&\r
+ (mIsBitVar == Info->mIsBitVar)) {\r
return TRUE;\r
}\r
\r