+/**\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