REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3562
Create new command line option to have VfrCompile generate a Json format file that contains the EFI Variable related information including: 1. The C struct associate the EFI variable 2. The variable vendor Guid, name and attribute 3. The variable field's default value Signed-off-by: Bob Feng <bob.c.f...@intel.com> Cc: Liming Gao <gaolim...@byosoft.com.cn> Cc: Yuwei Chen <yuwei.c...@intel.com> --- BaseTools/Source/C/VfrCompile/VfrCompiler.cpp | 54 +++++++ BaseTools/Source/C/VfrCompile/VfrCompiler.h | 5 + BaseTools/Source/C/VfrCompile/VfrSyntax.g | 6 +- .../Source/C/VfrCompile/VfrUtilityLib.cpp | 145 +++++++++++++++++- BaseTools/Source/C/VfrCompile/VfrUtilityLib.h | 14 +- 5 files changed, 219 insertions(+), 5 deletions(-) diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp index 5f4d262d85c5..f13562be6727 100644 --- a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp +++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp @@ -76,10 +76,11 @@ CVfrCompiler::OptionInitialization ( mOptions.CPreprocessorOptions = NULL; mOptions.HasOverrideClassGuid = FALSE; mOptions.WarningAsError = FALSE; mOptions.AutoDefault = FALSE; mOptions.CheckDefault = FALSE; + mOptions.GenJson = FALSE; memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID)); if (Argc == 1) { Usage (); SET_RUN_STATUS (STATUS_DEAD); @@ -93,10 +94,12 @@ CVfrCompiler::OptionInitialization ( return; } else if (stricmp(Argv[Index], "--version") == 0) { Version (); SET_RUN_STATUS (STATUS_DEAD); return; + } else if (stricmp(Argv[Index], "--variable") == 0) { + mOptions.GenJson = TRUE; } else if (stricmp(Argv[Index], "-l") == 0) { mOptions.CreateRecordListFile = TRUE; gCIfrRecordInfoDB.TurnOn (); } else if (stricmp(Argv[Index], "-i") == 0) { Index++; @@ -203,10 +206,13 @@ CVfrCompiler::OptionInitialization ( goto Fail; } if (SetRecordListFileName () != 0) { goto Fail; } + if (SetRecordListJsonFileName () != 0) { + goto Fail; + } return; Fail: SET_RUN_STATUS (STATUS_DEAD); @@ -458,10 +464,38 @@ CVfrCompiler::SetRecordListFileName ( strcpy (mOptions.RecordListFile, mOptions.OutputDirectory); strcat (mOptions.RecordListFile, mOptions.VfrBaseFileName); strcat (mOptions.RecordListFile, VFR_RECORDLIST_FILENAME_EXTENSION); + return 0; +} +INT8 +CVfrCompiler::SetRecordListJsonFileName ( + VOID + ) +{ + INTN Length; + + if (mOptions.VfrBaseFileName == NULL) { + return -1; + } + + Length = strlen (mOptions.OutputDirectory) + + strlen (mOptions.VfrBaseFileName) + + strlen (VFR_RECORDLIST_JSON_FILENAME_EXTENSION) + + 1; + + mOptions.RecordListJsonFile = (CHAR8 *) malloc (Length); + if (mOptions.RecordListJsonFile == NULL) { + return -1; + } + + strcpy (mOptions.RecordListJsonFile, mOptions.OutputDirectory); + strcat (mOptions.RecordListJsonFile, mOptions.VfrBaseFileName); + strcat (mOptions.RecordListJsonFile, VFR_RECORDLIST_JSON_FILENAME_EXTENSION); + + return 0; } CVfrCompiler::CVfrCompiler ( IN INT32 Argc, @@ -565,10 +599,11 @@ CVfrCompiler::Usage ( " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", " -w --warning-as-error", " treat warning as an error", " -a --autodefaut generate default value for question opcode if some default is missing", " -d --checkdefault check the default information in a question opcode", + " --variable generate default_data binary", NULL }; for (Index = 0; Help[Index] != NULL; Index++) { fprintf (stdout, "%s\n", Help[Index]); } @@ -902,10 +937,28 @@ CVfrCompiler::GenRecordListFile ( Err1: fclose (pInFile); } +VOID +CVfrCompiler::GenRecordListJsonFile( + VOID + ) +{ + if (!mOptions.GenJson) + return; + + FILE *pOutFile2 = NULL; + if ((pOutFile2 = fopen (LongFilePath (mOptions.RecordListJsonFile), "w")) == NULL) { + DebugError (NULL, 0, 0001, "Error opening the record list file", "%s",mOptions.RecordListJsonFile ); + } + gCVfrBufferConfig.DumpJson(pOutFile2); + fclose (pOutFile2); + + return; + +} int main ( IN int Argc, IN char **Argv ) @@ -919,10 +972,11 @@ main ( Compiler.Compile(); Compiler.AdjustBin(); Compiler.GenBinary(); Compiler.GenCFile(); Compiler.GenRecordListFile (); + Compiler.GenRecordListJsonFile (); Status = Compiler.RunStatus (); if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) { return 2; } diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.h b/BaseTools/Source/C/VfrCompile/VfrCompiler.h index b6e207d2ce1a..04fa4ed8eaf5 100644 --- a/BaseTools/Source/C/VfrCompile/VfrCompiler.h +++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.h @@ -31,18 +31,21 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // Specify the filename extensions for the files we generate. // #define VFR_PREPROCESS_FILENAME_EXTENSION ".i" #define VFR_PACKAGE_FILENAME_EXTENSION ".hpk" #define VFR_RECORDLIST_FILENAME_EXTENSION ".lst" +#define VFR_RECORDLIST_JSON_FILENAME_EXTENSION "_var.json" typedef struct { CHAR8 *VfrFileName; CHAR8 *RecordListFile; + CHAR8 *RecordListJsonFile; CHAR8 *PkgOutputFileName; CHAR8 *COutputFileName; bool CreateRecordListFile; bool CreateIfrPkgFile; + bool GenJson; CHAR8 *OutputDirectory; CHAR8 *PreprocessorOutputFileName; CHAR8 *VfrBaseFileName; // name of input VFR file with no path or extension CHAR8 *IncludePaths; bool SkipCPreprocessor; @@ -78,10 +81,11 @@ class CVfrCompiler { INT8 SetBaseFileName (VOID); INT8 SetPkgOutputFileName (VOID); INT8 SetCOutputFileName(VOID); INT8 SetPreprocessorOutputFileName (VOID); INT8 SetRecordListFileName (VOID); + INT8 SetRecordListJsonFileName (VOID); VOID SET_RUN_STATUS (IN COMPILER_RUN_STATUS); BOOLEAN IS_RUN_STATUS (IN COMPILER_RUN_STATUS); public: @@ -100,9 +104,10 @@ class CVfrCompiler { VOID Compile (VOID); VOID AdjustBin (VOID); VOID GenBinary (VOID); VOID GenCFile (VOID); VOID GenRecordListFile (VOID); + VOID GenRecordListJsonFile (VOID); VOID DebugError (IN CHAR8*, IN UINT32, IN UINT32, IN CONST CHAR8*, IN CONST CHAR8*, ...); }; #endif diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g index 3f896c6f1acc..81a40d44cb36 100644 --- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g +++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g @@ -1130,22 +1130,24 @@ vfrStatementVarStoreEfi : StoreName, &Guid, &gCVfrVarDataTypeDB, TypeName, VarStoreId, - IsBitVarStore + IsBitVarStore, + Attr ), LineNum); _PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN); _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum); } else { _PCATCH(gCVfrDataStorage.DeclareBufferVarStore ( TN->getText(), &Guid, &gCVfrVarDataTypeDB, TypeName, VarStoreId, - FALSE + FALSE, + Attr ), LineNum); _PCATCH(gCVfrDataStorage.GetVarStoreId(TN->getText(), &VarStoreId, &Guid), VN); _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), N->getLine()); } VSEObj.SetGuid (&Guid); diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp index 2b9b5dbb1ca5..0cf2b950de74 100644 --- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp +++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp @@ -283,10 +283,150 @@ CVfrBufferConfig::Select ( } return 1; } +VOID +CVfrBufferConfig::DumpJson ( + IN FILE *pFile + ) +{ + SVfrDataType *pTNode; + SVfrDataField *pFNode; + SConfigItem *pItem; + SConfigInfo *pInfo; + SConfigInfo *pInfoIndex = NULL; + SVfrVarStorageNode *pVsNode; + CHAR8 *DefaultStoreId = "0000"; + UINT8 indentation = 0; + + + fprintf (pFile, "{\n"); + fprintf (pFile, "%*c\"DataStruct\" : {\n", 2 , ' '); + for (pTNode = gCVfrVarDataTypeDB.GetDataTypeList(); pTNode != NULL; pTNode = pTNode->mNext) { + fprintf (pFile, "%*c\"%s\" : [\n", 4, ' ',pTNode->mTypeName); + for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) { + fprintf (pFile, "%*c{ \n", 6 ,' '); + fprintf (pFile,"%*c\"Name\": \"%s\",\n", 8 , ' ', pFNode->mFieldName); + if (pFNode->mArrayNum > 0) { + fprintf (pFile,"%*c\"Type\": \"%s[%d]\",\n", 8 , ' ', pFNode->mFieldType->mTypeName,pFNode->mArrayNum); + } else { + fprintf (pFile,"%*c\"Type\": \"%s\",\n", 8 , ' ', pFNode->mFieldType->mTypeName); + } + fprintf (pFile,"%*c\"Offset\": %d\n", 8 , ' ', pFNode->mOffset); + + if (pFNode->mNext == NULL) { + fprintf (pFile, "%*c}\n", 6 ,' '); + } + else { + fprintf (pFile, "%*c},\n", 6 ,' '); + } + } + if (pTNode->mNext == NULL) { + fprintf (pFile, "%*c]\n", 4, ' '); + } + else { + fprintf (pFile, "%*c],\n", 4, ' '); + } + } + fprintf (pFile, "%*c},\n", 2, ' '); + + fprintf(pFile, "%*c\"DataStructAttribute\": {\n", 2, ' '); + for (pTNode = gCVfrVarDataTypeDB.GetDataTypeList(); pTNode != NULL; pTNode = pTNode->mNext) { + fprintf(pFile, "%*c\"%s\": {\n", 4, ' ', pTNode->mTypeName); + fprintf(pFile, "%*c\"Alignment\": %u,\n", 6, ' ',pTNode->mAlign); + fprintf(pFile, "%*c\"TotalSize\": %u\n", 6, ' ',pTNode->mTotalSize); + if (pTNode->mNext == NULL) { + fprintf(pFile, "%*c}\n", 4, ' '); + } + else { + fprintf(pFile, "%*c},\n", 4, ' '); + } + } + fprintf (pFile, "%*c},\n", 2, ' '); + + fprintf (pFile, "%*c\"VarDefine\": {\n", 2, ' '); + for (pVsNode = gCVfrDataStorage.GetBufferVarStoreList(); pVsNode != NULL; pVsNode = pVsNode->mNext) { + fprintf (pFile, "%*c\"%s\" : {\n", 4, ' ', pVsNode->mVarStoreName); + fprintf (pFile, "%*c\"Type\" : \"%s\",\n", 6, ' ', pVsNode->mStorageInfo.mDataType->mTypeName); + fprintf (pFile, "%*c\"Attributes\" : %d\n", 6, ' ', pVsNode->mAttributes); + if (pVsNode->mNext == NULL) { + fprintf(pFile, "%*c}\n", 4, ' '); + } + else { + fprintf(pFile, "%*c},\n", 4, ' '); + } + } + fprintf (pFile, "%*c},\n", 2, ' '); + + indentation = 0; + fprintf (pFile, "%*c\"Data\" : [\n",2, ' '); + for (pItem = mItemListHead; pItem!=NULL; pItem = pItem->mNext) { + if (pItem->mId == NULL) { + continue; + } + + DefaultStoreId = pItem->mId; + //find the last pInfo whose value is not 0 + if (pItem->mNext == NULL) { + for (pInfo = pItem->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) { + if(*pInfo->mValue !=0) { + pInfoIndex = pInfo; + } + } + } + for (pInfo = pItem->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) { + bool pass = 1; + for (int i=0;i<pInfo->mWidth;i++){ + pass &= (*(pInfo->mValue+i) == 0); + } + if (pass) { + continue; + } + fprintf (pFile, "%*c{\n",4, ' '); + fprintf(pFile, "%*c\"VendorGuid\": \"{0x%02x, 0x%02x, 0x%02x, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}\",\n", + 6, + ' ', + pItem->mGuid->Data1, + pItem->mGuid->Data2, + pItem->mGuid->Data3, + pItem->mGuid->Data4[0], + pItem->mGuid->Data4[1], + pItem->mGuid->Data4[2], + pItem->mGuid->Data4[3], + pItem->mGuid->Data4[4], + pItem->mGuid->Data4[5], + pItem->mGuid->Data4[6], + pItem->mGuid->Data4[7] + ); + fprintf (pFile, "%*c\"VarName\": \"%s\",\n", 6, ' ', pItem->mName); + fprintf (pFile, "%*c\"DefaultStore\": \"%s\",\n", 6, ' ', DefaultStoreId); + fprintf (pFile, "%*c\"Size\": %u,\n", 6, ' ', pInfo->mWidth); + fprintf (pFile, "%*c\"Offset\": %u,\n", 6, ' ',pInfo->mOffset); + fprintf (pFile, "%*c\"Value\": \"0x", 6, ' '); + for (int i = pInfo->mWidth -1 ; i>=0; i--) { + fprintf (pFile, "%02x", *(pInfo->mValue+i)); + } + fprintf (pFile,"\"\n"); + fprintf(pFile, "%*c},\n", 4, ' '); + } + } + //End item + fprintf (pFile, "%*c{\n",4, ' '); + fprintf(pFile, "%*c\"VendorGuid\": \"NA\",\n", 6, ' '); + fprintf (pFile, "%*c\"VarName\": \"NA\",\n", 6, ' '); + fprintf (pFile, "%*c\"DefaultStore\": \"NA\",\n", 6, ' '); + fprintf (pFile, "%*c\"Size\": 0,\n", 6, ' '); + fprintf (pFile, "%*c\"Offset\": 0,\n", 6, ' '); + fprintf (pFile, "%*c\"Value\": \"0x00\"\n", 6, ' '); + fprintf(pFile, "%*c}\n", 4, ' '); + //End item + + fprintf (pFile, "%*c]\n", 2, ' '); + + fprintf (pFile, "}\n"); +} UINT8 CVfrBufferConfig::Write ( IN CONST CHAR8 Mode, IN CHAR8 *Name, IN EFI_GUID *Guid, @@ -1557,10 +1697,11 @@ SVfrVarStorageNode::SVfrVarStorageNode ( IN EFI_GUID *Guid, IN CHAR8 *StoreName, IN EFI_VARSTORE_ID VarStoreId, IN SVfrDataType *DataType, IN BOOLEAN BitsVarstore, + IN UINT32 Attributes, IN BOOLEAN Flag ) { if (Guid != NULL) { mGuid = *Guid; @@ -1580,10 +1721,11 @@ SVfrVarStorageNode::SVfrVarStorageNode ( } else { mVarStoreType = EFI_VFR_VARSTORE_BUFFER; } mStorageInfo.mDataType = DataType; mAssignedFlag = Flag; + mAttributes = Attributes; } SVfrVarStorageNode::SVfrVarStorageNode ( IN CHAR8 *StoreName, IN EFI_VARSTORE_ID VarStoreId @@ -1842,10 +1984,11 @@ CVfrDataStorage::DeclareBufferVarStore ( IN EFI_GUID *Guid, IN CVfrVarDataTypeDB *DataTypeDB, IN CHAR8 *TypeName, IN EFI_VARSTORE_ID VarStoreId, IN BOOLEAN IsBitVarStore, + IN UINT32 Attr, IN BOOLEAN Flag ) { SVfrVarStorageNode *pNew = NULL; SVfrDataType *pDataType = NULL; @@ -1868,11 +2011,11 @@ CVfrDataStorage::DeclareBufferVarStore ( return VFR_RETURN_VARSTOREID_REDEFINED; } MarkVarStoreIdUsed (VarStoreId); } - if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) { + if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Attr, Flag)) == NULL) { return VFR_RETURN_OUT_FOR_RESOURCES; } pNew->mNext = mBufferVarStoreList; mBufferVarStoreList = pNew; diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h index 57bb0c424daf..d3842aebb13b 100644 --- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h +++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h @@ -86,10 +86,11 @@ class CVfrBufferConfig { virtual UINT8 Register (IN CHAR8 *, IN EFI_GUID *,IN CHAR8 *Info = NULL); virtual VOID Open (VOID); virtual BOOLEAN Eof(VOID); virtual UINT8 Select (IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *Info = NULL); virtual UINT8 Write (IN CONST CHAR8, IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *, IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE); + virtual VOID DumpJson(IN FILE *); #if 0 virtual UINT8 Read (OUT CHAR8 **, OUT CHAR8 **, OUT CHAR8 **, OUT CHAR8 **, OUT CHAR8 **); #endif virtual VOID Close (VOID); virtual VOID OutputCFile (IN FILE *, IN CHAR8 *); @@ -200,10 +201,18 @@ class CVfrVarDataTypeDB { public: CVfrVarDataTypeDB (VOID); ~CVfrVarDataTypeDB (VOID); + inline SVfrDataType * GetDataTypeList(VOID) { + return mDataTypeList; + } + + inline UINT32 GetPackAlign(VOID) { + return mPackAlign; + } + 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); @@ -247,10 +256,11 @@ typedef enum { struct SVfrVarStorageNode { EFI_GUID mGuid; CHAR8 *mVarStoreName; EFI_VARSTORE_ID mVarStoreId; BOOLEAN mAssignedFlag; //Create varstore opcode + UINT32 mAttributes; struct SVfrVarStorageNode *mNext; EFI_VFR_VARSTORE_TYPE mVarStoreType; union { // EFI Variable @@ -269,11 +279,11 @@ struct SVfrVarStorageNode { } mNameSpace; } mStorageInfo; 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, IN BOOLEAN Flag = TRUE); + SVfrVarStorageNode (IN EFI_GUID *, IN CHAR8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *,IN BOOLEAN, IN UINT32, IN BOOLEAN Flag = TRUE); SVfrVarStorageNode (IN CHAR8 *, IN EFI_VARSTORE_ID); ~SVfrVarStorageNode (VOID); private: SVfrVarStorageNode (IN CONST SVfrVarStorageNode&); // Prevent copy-construction @@ -345,11 +355,11 @@ class CVfrDataStorage { EFI_VFR_RETURN_CODE NameTableAddItem (EFI_STRING_ID); EFI_VFR_RETURN_CODE DeclareNameVarStoreEnd (EFI_GUID *); 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, 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 UINT32 Attr = 0, 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); EFI_GUID * GetVarStoreGuid (IN EFI_VARSTORE_ID); EFI_VFR_RETURN_CODE GetVarStoreName (IN EFI_VARSTORE_ID, OUT CHAR8 **); -- 2.18.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#79272): https://edk2.groups.io/g/devel/message/79272 Mute This Topic: https://groups.io/mt/84861458/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-