X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FC%2FVfrCompile%2FVfrUtilityLib.cpp;h=0d0f926f82660a4fa498480094fce1a32b294fe6;hp=7c1383eb7a89170852c2d82a21dccb928dfcc2a0;hb=fb0b35e05f772bd415fe264267bbbcde2e0accda;hpb=e8a47801a1dfdb148b1bfcd5bdc8ebc3bf51f92d diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp index 7c1383eb7a..0d0f926f82 100644 --- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp +++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp @@ -1,20 +1,22 @@ /** @file - + Vfr common library functions. -Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
-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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+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 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "stdio.h" #include "stdlib.h" +#include "assert.h" +#include "CommonLib.h" #include "VfrUtilityLib.h" #include "VfrFormPkg.h" @@ -70,9 +72,9 @@ CVfrBinaryOutput::WriteEnd ( } SConfigInfo::SConfigInfo ( - IN UINT8 Type, - IN UINT16 Offset, - IN UINT32 Width, + IN UINT8 Type, + IN UINT16 Offset, + IN UINT32 Width, IN EFI_IFR_TYPE_VALUE Value ) { @@ -109,6 +111,10 @@ SConfigInfo::SConfigInfo ( case EFI_IFR_TYPE_STRING : memcpy (mValue, &Value.string, mWidth); break; + case EFI_IFR_TYPE_BUFFER : + memcpy (mValue, &Value.u8, mWidth); + break; + case EFI_IFR_TYPE_OTHER : return; } @@ -118,7 +124,7 @@ SConfigInfo::~SConfigInfo ( VOID ) { - BUFFER_SAFE_FREE (mValue); + ARRAY_SAFE_FREE (mValue); } SConfigItem::SConfigItem ( @@ -195,9 +201,9 @@ SConfigItem::~SConfigItem ( { SConfigInfo *Info; - BUFFER_SAFE_FREE (mName); - BUFFER_SAFE_FREE (mGuid); - BUFFER_SAFE_FREE (mId); + ARRAY_SAFE_FREE (mName); + ARRAY_SAFE_FREE (mGuid); + ARRAY_SAFE_FREE (mId); while (mInfoStrList != NULL) { Info = mInfoStrList; mInfoStrList = mInfoStrList->mNext; @@ -354,7 +360,7 @@ CVfrBufferConfig::Write ( case 'i' : // set info if (mItemListPos->mId != NULL) { - delete mItemListPos->mId; + delete[] mItemListPos->mId; } mItemListPos->mId = NULL; if (Id != NULL) { @@ -547,7 +553,7 @@ _STR2U32 ( // // BUG: does not handle overflow here // - (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); + (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10); if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) { Value += (c - 'a' + 10); @@ -595,6 +601,65 @@ 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); + + if (pType == NULL){ + return FALSE; + } + 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 != NULL && pField->mIsBitField) { + return TRUE; + } else { + return FALSE; + } +} + EFI_VFR_RETURN_CODE CVfrVarDataTypeDB::ExtractFieldNameAndArrary ( IN CHAR8 *&VarStr, @@ -660,7 +725,7 @@ CVfrVarDataTypeDB::GetTypeField ( { SVfrDataField *pField = NULL; - if ((FName == NULL) && (Type == NULL)) { + if ((FName == NULL) || (Type == NULL)) { return VFR_RETURN_FATAL_ERROR; } @@ -692,13 +757,14 @@ EFI_VFR_RETURN_CODE CVfrVarDataTypeDB::GetFieldOffset ( IN SVfrDataField *Field, IN UINT32 ArrayIdx, - OUT UINT32 &Offset + OUT UINT32 &Offset, + IN BOOLEAN IsBitField ) { if (Field == NULL) { return VFR_RETURN_FATAL_ERROR; } - + // // Framework Vfr file Array Index is from 1. // But Uefi Vfr file Array Index is from 0. @@ -713,7 +779,7 @@ CVfrVarDataTypeDB::GetFieldOffset ( if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) { return VFR_RETURN_ERROR_ARRARY_NUM; } - + // // Be compatible with the current usage // If ArraryIdx is not specified, the first one is used. @@ -724,8 +790,11 @@ CVfrVarDataTypeDB::GetFieldOffset ( // return VFR_RETURN_ERROR_ARRARY_NUM; // } // - - Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx); + 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; } @@ -744,7 +813,8 @@ CVfrVarDataTypeDB::GetFieldWidth ( UINT32 CVfrVarDataTypeDB::GetFieldSize ( IN SVfrDataField *Field, - IN UINT32 ArrayIdx + IN UINT32 ArrayIdx, + IN BOOLEAN BitField ) { if (Field == NULL) { @@ -752,9 +822,13 @@ CVfrVarDataTypeDB::GetFieldSize ( } if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) { - return Field->mFieldType->mTotalSize * Field->mArrayNum; + return Field->mFieldType->mTotalSize * Field->mArrayNum; } else { - return Field->mFieldType->mTotalSize; + if (BitField) { + return Field->mBitWidth; + } else { + return Field->mFieldType->mTotalSize; + } } } @@ -769,7 +843,9 @@ CVfrVarDataTypeDB::InternalTypesListInit ( for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) { New = new SVfrDataType; if (New != NULL) { - strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName); + assert (strlen (gInternalTypesTable[Index].mTypeName) < MAX_NAME_LEN); + strncpy (New->mTypeName, gInternalTypesTable[Index].mTypeName, MAX_NAME_LEN - 1); + New->mTypeName[MAX_NAME_LEN - 1] = 0; New->mType = gInternalTypesTable[Index].mType; New->mAlign = gInternalTypesTable[Index].mAlign; New->mTotalSize = gInternalTypesTable[Index].mSize; @@ -783,18 +859,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) { @@ -807,18 +886,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) { @@ -832,24 +914,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 { @@ -872,6 +958,7 @@ CVfrVarDataTypeDB::CVfrVarDataTypeDB ( mPackAlign = DEFAULT_PACK_ALIGN; mPackStack = NULL; mFirstNewDataTypeName = NULL; + mCurrDataType = NULL; InternalTypesListInit (); } @@ -896,7 +983,7 @@ CVfrVarDataTypeDB::~CVfrVarDataTypeDB ( pType->mMembers = pType->mMembers->mNext; delete pField; } - delete pType; + delete pType; } while (mPackStack != NULL) { @@ -973,6 +1060,7 @@ CVfrVarDataTypeDB::DeclareDataTypeBegin ( pNewType->mTotalSize = 0; pNewType->mMembers = NULL; pNewType->mNext = NULL; + pNewType->mHasBitField = FALSE; mNewDataType = pNewType; } @@ -1000,7 +1088,128 @@ CVfrVarDataTypeDB::SetNewTypeName ( } } - strcpy(mNewDataType->mTypeName, TypeName); + strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1); + mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0; + 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) { + strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1); + pNewField->mFieldName[MAX_NAME_LEN - 1] = 0; + } + 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 fields 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; } @@ -1008,15 +1217,18 @@ EFI_VFR_RETURN_CODE CVfrVarDataTypeDB::DataTypeAddField ( IN CHAR8 *FieldName, IN CHAR8 *TypeName, - IN UINT32 ArrayNum + IN UINT32 ArrayNum, + IN BOOLEAN FieldInUnion ) { SVfrDataField *pNewField = NULL; SVfrDataType *pFieldType = NULL; SVfrDataField *pTmp; UINT32 Align; + UINT32 MaxDataTypeSize; CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS); + MaxDataTypeSize = mNewDataType->mTotalSize; if (strlen (FieldName) >= MAX_NAME_LEN) { return VFR_RETURN_INVALID_PARAMETER; @@ -1033,9 +1245,11 @@ CVfrVarDataTypeDB::DataTypeAddField ( if ((pNewField = new SVfrDataField) == NULL) { return VFR_RETURN_OUT_FOR_RESOURCES; } - strcpy (pNewField->mFieldName, FieldName); + strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1); + pNewField->mFieldName[MAX_NAME_LEN - 1] = 0; pNewField->mFieldType = pFieldType; pNewField->mArrayNum = ArrayNum; + pNewField->mIsBitField = FALSE; if ((mNewDataType->mTotalSize % Align) == 0) { pNewField->mOffset = mNewDataType->mTotalSize; } else { @@ -1052,7 +1266,15 @@ CVfrVarDataTypeDB::DataTypeAddField ( } mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign)); - mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum); + + if (FieldInUnion) { + if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) { + mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize; + } + pNewField->mOffset = 0; + } else { + mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum); + } return VFR_RETURN_SUCCESS; } @@ -1167,21 +1389,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 // @@ -1189,13 +1416,17 @@ CVfrVarDataTypeDB::GetDataFieldInfo ( Size = pType->mTotalSize; while (*VarStr != '\0') { - CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS); + 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); - Offset = (UINT16) (Offset + Tmp); + 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; } @@ -1274,10 +1505,10 @@ CVfrVarDataTypeDB::Dump ( fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName); for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) { if (pFNode->mArrayNum > 0) { - fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, + fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName); } else { - fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, + fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, pFNode->mFieldName, pFNode->mFieldType->mTypeName); } } @@ -1305,7 +1536,7 @@ CVfrVarDataTypeDB::ParserDB ( printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName); } printf ("\t\t};\n"); - printf ("---------------------------------------------------------------\n"); + printf ("---------------------------------------------------------------\n"); } printf ("***************************************************************\n"); } @@ -1323,7 +1554,7 @@ SVfrVarStorageNode::SVfrVarStorageNode ( if (Guid != NULL) { mGuid = *Guid; } else { - memset (&Guid, 0, sizeof (EFI_GUID)); + memset (&mGuid, 0, sizeof (EFI_GUID)); } if (StoreName != NULL) { mVarStoreName = new CHAR8[strlen(StoreName) + 1]; @@ -1344,13 +1575,14 @@ SVfrVarStorageNode::SVfrVarStorageNode ( IN CHAR8 *StoreName, IN EFI_VARSTORE_ID VarStoreId, IN SVfrDataType *DataType, + IN BOOLEAN BitsVarstore, IN BOOLEAN Flag ) { if (Guid != NULL) { mGuid = *Guid; } else { - memset (&Guid, 0, sizeof (EFI_GUID)); + memset (&mGuid, 0, sizeof (EFI_GUID)); } if (StoreName != NULL) { mVarStoreName = new CHAR8[strlen(StoreName) + 1]; @@ -1360,7 +1592,11 @@ SVfrVarStorageNode::SVfrVarStorageNode ( } mNext = NULL; mVarStoreId = VarStoreId; - mVarStoreType = EFI_VFR_VARSTORE_BUFFER; + if (BitsVarstore) { + mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS; + } else { + mVarStoreType = EFI_VFR_VARSTORE_BUFFER; + } mStorageInfo.mDataType = DataType; mAssignedFlag = Flag; } @@ -1370,6 +1606,7 @@ SVfrVarStorageNode::SVfrVarStorageNode ( IN EFI_VARSTORE_ID VarStoreId ) { + memset (&mGuid, 0, sizeof (EFI_GUID)); if (StoreName != NULL) { mVarStoreName = new CHAR8[strlen(StoreName) + 1]; strcpy (mVarStoreName, StoreName); @@ -1381,6 +1618,7 @@ SVfrVarStorageNode::SVfrVarStorageNode ( mVarStoreType = EFI_VFR_VARSTORE_NAME; mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS]; mStorageInfo.mNameSpace.mTableSize = 0; + mAssignedFlag = FALSE; } SVfrVarStorageNode::~SVfrVarStorageNode ( @@ -1388,11 +1626,11 @@ SVfrVarStorageNode::~SVfrVarStorageNode ( ) { if (mVarStoreName != NULL) { - delete mVarStoreName; + delete[] mVarStoreName; } if (mVarStoreType == EFI_VFR_VARSTORE_NAME) { - delete mStorageInfo.mNameSpace.mNameTable; + delete[] mStorageInfo.mNameSpace.mNameTable; } } @@ -1414,6 +1652,8 @@ CVfrDataStorage::CVfrDataStorage ( mNameVarStoreList = NULL; mCurrVarStorageNode = NULL; mNewVarStorageNode = NULL; + mBufferFieldInfoListHead = NULL; + mBufferFieldInfoListTail = NULL; } CVfrDataStorage::~CVfrDataStorage ( @@ -1448,7 +1688,7 @@ CVfrDataStorage::GetFreeVarStoreId ( ) { UINT32 Index, Mask, Offset; - + // // Assign the different ID range for the different type VarStore to support Framework Vfr // @@ -1467,6 +1707,10 @@ CVfrDataStorage::GetFreeVarStoreId ( } } + if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) { + return EFI_VARSTORE_ID_INVALID; + } + for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) { mFreeVarStoreIdBitMap[Index] |= Mask; @@ -1526,7 +1770,7 @@ CVfrDataStorage::DeclareNameVarStoreBegin ( if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) { return VFR_RETURN_REDEFINED; } - + if (VarStoreId == EFI_VARSTORE_ID_INVALID) { VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME); } else { @@ -1584,10 +1828,10 @@ CVfrDataStorage::DeclareNameVarStoreEnd ( return VFR_RETURN_SUCCESS; } -EFI_VFR_RETURN_CODE +EFI_VFR_RETURN_CODE CVfrDataStorage::DeclareEfiVarStore ( - IN CHAR8 *StoreName, - IN EFI_GUID *Guid, + IN CHAR8 *StoreName, + IN EFI_GUID *Guid, IN EFI_STRING_ID NameStrId, IN UINT32 VarSize, IN BOOLEAN Flag @@ -1619,13 +1863,14 @@ CVfrDataStorage::DeclareEfiVarStore ( return VFR_RETURN_SUCCESS; } -EFI_VFR_RETURN_CODE +EFI_VFR_RETURN_CODE CVfrDataStorage::DeclareBufferVarStore ( - IN CHAR8 *StoreName, - IN EFI_GUID *Guid, + IN CHAR8 *StoreName, + IN EFI_GUID *Guid, IN CVfrVarDataTypeDB *DataTypeDB, IN CHAR8 *TypeName, IN EFI_VARSTORE_ID VarStoreId, + IN BOOLEAN IsBitVarStore, IN BOOLEAN Flag ) { @@ -1652,7 +1897,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; } @@ -1666,7 +1911,7 @@ CVfrDataStorage::DeclareBufferVarStore ( return VFR_RETURN_SUCCESS; } -EFI_VFR_RETURN_CODE +EFI_VFR_RETURN_CODE CVfrDataStorage::GetVarStoreByDataType ( IN CHAR8 *DataTypeName, OUT SVfrVarStorageNode **VarNode, @@ -1675,7 +1920,7 @@ CVfrDataStorage::GetVarStoreByDataType ( { SVfrVarStorageNode *pNode; SVfrVarStorageNode *MatchNode; - + // // Framework VFR uses Data type name as varstore name, so don't need check again. // @@ -1705,7 +1950,7 @@ CVfrDataStorage::GetVarStoreByDataType ( } } } - + if (MatchNode == NULL) { return VFR_RETURN_UNDEFINED; } @@ -1714,7 +1959,7 @@ CVfrDataStorage::GetVarStoreByDataType ( return VFR_RETURN_SUCCESS; } -EFI_VARSTORE_ID +EFI_VARSTORE_ID CVfrDataStorage::CheckGuidField ( IN SVfrVarStorageNode *pNode, IN EFI_GUID *StoreGuid, @@ -1754,7 +1999,7 @@ CVfrDataStorage::CheckGuidField ( } /** - Base on the input store name and guid to find the varstore id. + Base on the input store name and guid to find the varstore id. If both name and guid are inputed, base on the name and guid to found the varstore. If only name inputed, base on the name to @@ -1762,10 +2007,10 @@ CVfrDataStorage::CheckGuidField ( has the same name. If only has found one varstore, return this varstore; if more than one varstore has same name, return varstore name redefined error. If no varstore found by varstore name, call - function GetVarStoreByDataType and use inputed varstore name as + function GetVarStoreByDataType and use inputed varstore name as data type name to search. **/ -EFI_VFR_RETURN_CODE +EFI_VFR_RETURN_CODE CVfrDataStorage::GetVarStoreId ( IN CHAR8 *StoreName, OUT EFI_VARSTORE_ID *VarStoreId, @@ -1813,14 +2058,14 @@ CVfrDataStorage::GetVarStoreId ( *VarStoreId = EFI_VARSTORE_ID_INVALID; // - // Assume that Data strucutre name is used as StoreName, and check again. + // Assume that Data structure name is used as StoreName, and check again. // ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid); if (pNode != NULL) { mCurrVarStorageNode = pNode; *VarStoreId = pNode->mVarStoreId; } - + return ReturnCode; } @@ -1924,7 +2169,7 @@ CVfrDataStorage::GetVarStoreGuid ( EFI_VFR_RETURN_CODE CVfrDataStorage::GetVarStoreName ( - IN EFI_VARSTORE_ID VarStoreId, + IN EFI_VARSTORE_ID VarStoreId, OUT CHAR8 **VarStoreName ) { @@ -1994,6 +2239,48 @@ CVfrDataStorage::GetEfiVarStoreInfo ( return VFR_RETURN_SUCCESS; } +EFI_VFR_RETURN_CODE +CVfrDataStorage::AddBufferVarStoreFieldInfo ( + IN EFI_VARSTORE_INFO *Info + ) +{ + BufferVarStoreFieldInfoNode *pNew; + + if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) { + return VFR_RETURN_FATAL_ERROR; + } + + if (mBufferFieldInfoListHead == NULL) { + mBufferFieldInfoListHead = pNew; + mBufferFieldInfoListTail= pNew; + } else { + mBufferFieldInfoListTail->mNext = pNew; + mBufferFieldInfoListTail = pNew; + } + + return VFR_RETURN_SUCCESS; +} + +EFI_VFR_RETURN_CODE +CVfrDataStorage::GetBufferVarStoreFieldInfo ( + IN OUT EFI_VARSTORE_INFO *Info + ) +{ + BufferVarStoreFieldInfoNode *pNode; + + pNode = mBufferFieldInfoListHead; + while (pNode != NULL) { + if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId && + Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) { + Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize; + Info->mVarType = pNode->mVarStoreInfo.mVarType; + return VFR_RETURN_SUCCESS; + } + pNode = pNode->mNext; + } + return VFR_RETURN_FATAL_ERROR; +} + EFI_VFR_RETURN_CODE CVfrDataStorage::GetNameVarStoreInfo ( OUT EFI_VARSTORE_INFO *Info, @@ -2007,7 +2294,7 @@ CVfrDataStorage::GetNameVarStoreInfo ( if (mCurrVarStorageNode == NULL) { return VFR_RETURN_GET_NVVARSTORE_ERROR; } - + // // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0. // @@ -2025,8 +2312,8 @@ CVfrDataStorage::GetNameVarStoreInfo ( SVfrDefaultStoreNode::SVfrDefaultStoreNode ( IN EFI_IFR_DEFAULTSTORE *ObjBinAddr, - IN CHAR8 *RefName, - IN EFI_STRING_ID DefaultStoreNameId, + IN CHAR8 *RefName, + IN EFI_STRING_ID DefaultStoreNameId, IN UINT16 DefaultId ) { @@ -2049,7 +2336,7 @@ SVfrDefaultStoreNode::~SVfrDefaultStoreNode ( ) { if (mRefName != NULL) { - delete mRefName; + delete[] mRefName; } } @@ -2104,7 +2391,7 @@ CVfrDefaultStore::RegisterDefaultStore ( } /* - * assign new reference name or new default store name id only if + * assign new reference name or new default store name id only if * the original is invalid */ EFI_VFR_RETURN_CODE @@ -2220,7 +2507,7 @@ CVfrDefaultStore::BufferVarStoreAltConfigAdd ( goto WriteError; } } - + gCVfrBufferConfig.Close (); return VFR_RETURN_SUCCESS; @@ -2251,7 +2538,7 @@ SVfrRuleNode::~SVfrRuleNode ( ) { if (mRuleName != NULL) { - delete mRuleName; + delete[] mRuleName; } } @@ -2324,6 +2611,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 ( @@ -2335,6 +2623,24 @@ EFI_VARSTORE_INFO::EFI_VARSTORE_INFO ( mInfo.mVarOffset = Info.mInfo.mVarOffset; mVarType = Info.mVarType; mVarTotalSize = Info.mVarTotalSize; + mIsBitVar = Info.mIsBitVar; +} + +EFI_VARSTORE_INFO& +EFI_VARSTORE_INFO::operator= ( + IN CONST EFI_VARSTORE_INFO &Info + ) +{ + if (this != &Info) { + mVarStoreId = Info.mVarStoreId; + mInfo.mVarName = Info.mInfo.mVarName; + mInfo.mVarOffset = Info.mInfo.mVarOffset; + mVarType = Info.mVarType; + mVarTotalSize = Info.mVarTotalSize; + mIsBitVar = Info.mIsBitVar; + } + + return *this; } BOOLEAN @@ -2343,16 +2649,37 @@ EFI_VARSTORE_INFO::operator == ( ) { if ((mVarStoreId == Info->mVarStoreId) && - (mInfo.mVarName == Info->mInfo.mVarName) && + (mInfo.mVarName == Info->mInfo.mVarName) && (mInfo.mVarOffset == Info->mInfo.mVarOffset) && (mVarType == Info->mVarType) && - (mVarTotalSize == Info->mVarTotalSize)) { + (mVarTotalSize == Info->mVarTotalSize) && + (mIsBitVar == Info->mIsBitVar)) { return TRUE; } return FALSE; } +BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode( + IN EFI_VARSTORE_INFO *Info + ) +{ + mVarStoreInfo.mVarType = Info->mVarType; + mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize; + mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset; + mVarStoreInfo.mVarStoreId = Info->mVarStoreId; + mNext = NULL; +} + +BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode () +{ + mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER; + mVarStoreInfo.mVarTotalSize = 0; + mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID; + mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID; + mNext = NULL; +} + static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo; EFI_QUESTION_ID @@ -2368,6 +2695,10 @@ CVfrQuestionDB::GetFreeQuestionId ( } } + if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) { + return EFI_QUESTION_ID_INVALID; + } + for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) { if ((mFreeQIdBitMap[Index] & Mask) == 0) { mFreeQIdBitMap[Index] |= Mask; @@ -2446,11 +2777,11 @@ SVfrQuestionNode::~SVfrQuestionNode ( ) { if (mName != NULL) { - delete mName; + delete[] mName; } if (mVarIdStr != NULL) { - delete mVarIdStr; + delete[] mVarIdStr; } } @@ -2501,7 +2832,7 @@ CVfrQuestionDB::ResetInit( // Question ID 0 is reserved. mFreeQIdBitMap[0] = 0x80000000; - mQuestionList = NULL; + mQuestionList = NULL; } VOID @@ -2512,7 +2843,7 @@ CVfrQuestionDB::PrintAllQuestion ( SVfrQuestionNode *pNode = NULL; for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) { - printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId); + printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId); } } @@ -2709,7 +3040,8 @@ CVfrQuestionDB::RegisterNewDateQuestion ( for (Index = 0; Index < 3; Index++) { if (VarIdStr[Index] != NULL) { - delete VarIdStr[Index]; + delete[] VarIdStr[Index]; + VarIdStr[Index] = NULL; } } @@ -2726,7 +3058,8 @@ Err: } if (VarIdStr[Index] != NULL) { - delete VarIdStr[Index]; + delete[] VarIdStr [Index]; + VarIdStr [Index] = NULL; } } } @@ -2885,7 +3218,8 @@ CVfrQuestionDB::RegisterNewTimeQuestion ( for (Index = 0; Index < 3; Index++) { if (VarIdStr[Index] != NULL) { - delete VarIdStr[Index]; + delete[] VarIdStr[Index]; + VarIdStr[Index] = NULL; } } @@ -2902,12 +3236,13 @@ Err: } if (VarIdStr[Index] != NULL) { - delete VarIdStr[Index]; + delete[] VarIdStr[Index]; + VarIdStr[Index] = NULL; } } } -VOID +VOID CVfrQuestionDB::RegisterRefQuestion ( IN CHAR8 *Name, IN CHAR8 *BaseVarId, @@ -2996,15 +3331,15 @@ CVfrQuestionDB::RegisterRefQuestion ( pNode[0]->mQuestionId = QuestionId; pNode[1]->mQuestionId = QuestionId; pNode[2]->mQuestionId = QuestionId; - pNode[3]->mQuestionId = QuestionId; + pNode[3]->mQuestionId = QuestionId; pNode[0]->mQtype = QUESTION_REF; pNode[1]->mQtype = QUESTION_REF; pNode[2]->mQtype = QUESTION_REF; - pNode[3]->mQtype = QUESTION_REF; + pNode[3]->mQtype = QUESTION_REF; pNode[0]->mNext = pNode[1]; pNode[1]->mNext = pNode[2]; pNode[2]->mNext = pNode[3]; - pNode[3]->mNext = mQuestionList; + pNode[3]->mNext = mQuestionList; mQuestionList = pNode[0]; gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID)); @@ -3033,15 +3368,15 @@ CVfrQuestionDB::UpdateQuestionId ( ) { SVfrQuestionNode *pNode = NULL; - + if (QId == NewQId) { // don't update return VFR_RETURN_SUCCESS; } - + // // For Framework Vfr, don't check question ID conflict. - // + // if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) { return VFR_RETURN_REDEFINED; } @@ -3097,7 +3432,7 @@ CVfrQuestionDB::GetQuestionId ( if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) { continue; } - } + } QuestionId = pNode->mQuestionId; BitMask = pNode->mBitMask; @@ -3158,13 +3493,13 @@ CVfrStringDB::CVfrStringDB () CVfrStringDB::~CVfrStringDB () { if (mStringFileName != NULL) { - delete mStringFileName; + delete[] mStringFileName; } mStringFileName = NULL; } -VOID +VOID CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName) { UINT32 FileLen = 0; @@ -3173,6 +3508,10 @@ CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName) return; } + if (mStringFileName != NULL) { + delete[] mStringFileName; + } + FileLen = strlen (StringFileName) + 1; mStringFileName = new CHAR8[FileLen]; if (mStringFileName == NULL) { @@ -3185,7 +3524,7 @@ CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName) /** - Returns TRUE or FALSE whether SupportedLanguages contains the best matching language + Returns TRUE or FALSE whether SupportedLanguages contains the best matching language from a set of supported languages. @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that @@ -3248,13 +3587,13 @@ CVfrStringDB::GetBestLanguage ( } // - // Trim Language from the right to the next '-' character + // Trim Language from the right to the next '-' character // for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--); } // - // No matches were found + // No matches were found // return FALSE; } @@ -3278,12 +3617,12 @@ CVfrStringDB::GetVarStoreNameFormStringId ( CHAR8 LineBuf[EFI_IFR_MAX_LENGTH]; UINT8 BlockType; EFI_HII_STRING_PACKAGE_HDR *PkgHeader; - - if (mStringFileName == '\0' ) { + + if (mStringFileName == NULL) { return NULL; } - if ((pInFile = fopen (mStringFileName, "rb")) == NULL) { + if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) { return NULL; } @@ -3310,7 +3649,7 @@ CVfrStringDB::GetVarStoreNameFormStringId ( // Check the String package. // if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) { - delete StringPtr; + delete[] StringPtr; return NULL; } @@ -3337,7 +3676,7 @@ CVfrStringDB::GetVarStoreNameFormStringId ( // Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType); if (Status != EFI_SUCCESS) { - delete StringPtr; + delete[] StringPtr; return NULL; } @@ -3370,7 +3709,7 @@ CVfrStringDB::GetVarStoreNameFormStringId ( break; } - delete StringPtr; + delete[] StringPtr; return VarStoreName; } @@ -3627,5 +3966,7 @@ CVfrStringDB::GetUnicodeStringTextSize ( BOOLEAN VfrCompatibleMode = FALSE; CVfrVarDataTypeDB gCVfrVarDataTypeDB; +CVfrDefaultStore gCVfrDefaultStore; +CVfrDataStorage gCVfrDataStorage;