X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FProcessDsc%2FFWVolume.c;fp=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FProcessDsc%2FFWVolume.c;h=0000000000000000000000000000000000000000;hp=5181373a54037235ba4d3c869d3e23376a82b11a;hb=c455bc8c8d78ad51c24426a500914ea32504bf06;hpb=5bca07268acabe7f31407358e875ccf89cb5e386 diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/FWVolume.c b/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/FWVolume.c deleted file mode 100644 index 5181373a54..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/ProcessDsc/FWVolume.c +++ /dev/null @@ -1,1550 +0,0 @@ -/*++ - -Copyright (c) 2004 - 2010, 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. - -Module Name: - - FWVolume.c - -Abstract: - - This module contains functionality to keep track of files destined for - multiple firmware volues. It saves them up, and when told to, dumps the - file names out to some files used as input to other utilities that - actually generate the FVs. - ---*/ - -#include // for max_path definition -#include -#include -#include // for malloc() -#include "Common.h" -#include "DSCFile.h" -#include "FWVolume.h" - -#define FV_INF_DIR "FV_INF_DIR" // symbol for where we create the FV INF file -#define FV_FILENAME "FV_FILENAME" // symbol for the current FV.INF filename -#define EFI_BASE_ADDRESS "EFI_BASE_ADDRESS" -#define DEFAULT_FV_INF_DIR "FV" // default dir for where we create the FV INF file -#define DEFAULT_FV_DIR "$(BUILD_DIR)" // where the FV file comes from - -typedef struct { - char *ComponentType; - char *Extension; -} COMP_TYPE_EXTENSION; - -// -// Use a linked list of these to keep track of all the FV names used -// -typedef struct _FV_LIST { - struct _FV_LIST *Next; - char FVFileName[MAX_PATH]; - char BaseAddress[MAX_LINE_LEN]; - SMART_FILE *FVFilePtr; - SMART_FILE *AprioriFilePtr; - char *Processor; - int ComponentsInstance; // highest [components.n] section with a file for this FV -} FV_LIST; - -// -// Use a linked list of these to keep track of all FFS files built. When -// we're done, we turn the info into the FV INF files used to build the -// firmware volumes. -// -typedef struct _FILE_LIST { - struct _FILE_LIST *Next; - char *FileName; - char *BaseFileName; - char *FVs; // from FV=x,y,z - char *BaseName; // only needed for duplicate basename check - char *Processor; // only needed for duplicate basename check - char Apriori[100]; // of format "FVRecovery:1,FVMain:2" from APRIORI define - char *Guid; // guid string - int ComponentsInstance; // which [components.n] section it's in -} FILE_LIST; - -typedef struct _LINKED_LIST { - struct _LINKED_LIST *Next; - void *Data; -} LINKED_LIST; - -static FILE_LIST *mFileList; -static FILE_LIST *mLastFile; -static char *mXRefFileName = NULL; -static FV_LIST *mNonFfsFVList = NULL; - -// -// Whenever an FV name is referenced, then add it to our list of known -// FV's using these. -// -static FV_LIST *mFVList = NULL; -static FV_LIST *mFVListLast = NULL; - -// -// We use this list so that from a given component type, we can determine -// the name of the file on disk. For example, if we're given a file's -// guid and base name, and we know it's a "bs_driver", then we can look -// up "bs_driver" in this array and know that the file (after it's built) -// name is GUID-BASENAME.DXE -// -static const COMP_TYPE_EXTENSION mCompTypeExtension[] = { - { - "bs_driver", - ".dxe" - }, - { - "rt_driver", - ".dxe" - }, - { - "sal_rt_driver", - ".dxe" - }, - { - "security_core", - ".sec" - }, - { - "pei_core", - ".pei" - }, - { - "pic_peim", - ".pei" - }, - { - "pe32_peim", - ".pei" - }, - { - "relocatable_peim", - ".pei" - }, - { - "binary", - ".ffs" - }, - { - "application", - ".app" - }, - { - "file", - ".ffs" - }, - { - "fvimagefile", - ".fvi" - }, - { - "rawfile", - ".raw" - }, - { - "apriori", - ".ffs" - }, - { - "combined_peim_driver", - ".pei" - }, - { - NULL, - NULL - } -}; - -static -void -CFVFreeFileList ( - VOID - ); - -static -char * -UpperCaseString ( - char *Str - ); - -static -BOOLEAN -InSameFv ( - char *FVs1, - char *FVs2 -); - -static -void -AddFirmwareVolumes ( - char *FVs, - int ComponentsInstance - ); - -static -BOOLEAN -OrderInFvList ( - char *FvList, - char *FvName, - int *Order - ); - -int -GetBaseAddress ( - char *Name, - char *BaseAddress - ) -{ - char *Start; - char *Cptr; - char CSave; - char *Value; - - Start = Name; - while (*Name && isspace (*Name)) { - Name++; - } - - if (!*Name) { - return STATUS_ERROR; - } - // - // Find the end of the name. Either space or a '='. - // - for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++) - ; - if (!*Value) { - return STATUS_ERROR; - } - // - // Look for the '=' - // - Cptr = Value; - while (*Value && (*Value != '=')) { - Value++; - } - - if (!*Value) { - return STATUS_ERROR; - } - // - // Now truncate the name - // - CSave = *Cptr; - *Cptr = 0; - if (_stricmp (Name, EFI_BASE_ADDRESS) != 0) { - return STATUS_ERROR; - } - - *Cptr = CSave; - // - // Skip over the = and then any spaces - // - Value++; - while (*Value && isspace (*Value)) { - Value++; - } - // - // Find end of string, checking for quoted string - // - if (*Value == '\"') { - Value++; - for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++) - ; - } else { - for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++) - ; - } - // - // Null terminate the value string - // - CSave = *Cptr; - *Cptr = 0; - strcpy (BaseAddress, Value); - *Cptr = CSave; - - return STATUS_SUCCESS; -} - -int -CFVAddFVFile ( - char *Name, - char *ComponentType, - char *FVs, - int ComponentsInstance, - char *FFSExt, - char *Processor, - char *Apriori, - char *BaseName, - char *Guid - ) -/*++ - -Routine Description: - - Add a file to the list of files in one or more firmware volumes. - -Arguments: - - Name - $(FILE_GUID)-$(BASE_NAME), or filename - ComponentType - type of component being added. Required so we know the - resultant file name after it has been built - FVs - string of commma-separated FVs that the given file is - to be added to. For example, FVs="FV0001,FV0002" - FFSExt - FFS filename extension of the file after it has been built. - This is passed in to us in case we don't know the default - filename extension based on the component type. - Processor - the target processor which the FV is being built for - Apriori - pointer to the definition of APRIORI. For example APRIORI="FvRecovery:1,FvMain:4" - -Returns: - - STATUS_SUCCESS if successful - ---*/ -{ - FILE_LIST *Ptr; - char FileName[MAX_PATH]; - char Str[MAX_PATH]; - int i; - char *Sym; - - // If they provided a filename extension for this type of file, then use it. - // If they did not provide a filename extension, search our list for a - // matching component type and use the extension appropriate for this - // component type. - // - if (FFSExt == NULL) { - // - // They didn't give us a filename extension. Figure it out from the - // component type. - // - for (i = 0; mCompTypeExtension[i].ComponentType != NULL; i++) { - if (_stricmp (ComponentType, mCompTypeExtension[i].ComponentType) == 0) { - FFSExt = mCompTypeExtension[i].Extension; - break; - } - } - // - // If we don't know the file extension, then error out. Just means - // the need to define "FFS_EXT = raw" in the component INF file. - // - if (mCompTypeExtension[i].ComponentType == NULL) { - Error ( - NULL, - 0, - 0, - ComponentType, - "unknown component type - must define FFS_EXT for built filename extension in component INF file" - ); - return STATUS_ERROR; - } - } - // - // We now have all the parts to the FFS filename. Prepend the path to it if - // it's not a full pathname. - // See if they overrode the default base directory for the FV files. - // - if (!IsAbsolutePath (Name)) { - Sym = GetSymbolValue (FV_DIR); - if (Sym == NULL) { - Sym = DEFAULT_FV_DIR; - } - // - // Create the file path. Something like $(BUILD_DIR)\$(PROCESSOR)\$(GUID)-$(BASE_NAME).ext - // If the extension is non-zero length, then make sure there's a dot in it. - // - if ((strlen (FFSExt) > 0) && (FFSExt[0] != '.')) { - sprintf (Str, "%s\\%s\\%s.%s", Sym, Processor, Name, FFSExt); - } else { - sprintf (Str, "%s\\%s\\%s%s", Sym, Processor, Name, FFSExt); - } - - ExpandSymbols (Str, FileName, sizeof (FileName), EXPANDMODE_NO_UNDEFS); - } else { - strcpy (FileName, Name); - } - // - // Traverse the list of files we have so far and make sure we don't have - // any duplicate basenames. If the base name and processor match, then we'll - // have build issues, so don't allow it. We also don't allow the same file GUID - // in the same FV which will cause boot time error if we allow this. - // - Ptr = mFileList; - while (Ptr != NULL) { - if ((Ptr->BaseName != NULL) && (BaseName != NULL) && (_stricmp (BaseName, Ptr->BaseName) == 0)) { - if ((Ptr->Processor != NULL) && (Processor != NULL) && (_stricmp (Processor, Ptr->Processor) == 0)) { - Error (NULL, 0, 0, BaseName, "duplicate base name specified"); - return STATUS_ERROR; - } - } - - if ((Ptr->Guid != NULL) && (Guid != NULL) && (_stricmp (Guid, Ptr->Guid) == 0)) { - if ((Ptr->FVs != NULL) && (FVs != NULL) && (InSameFv (FVs, Ptr->FVs))) { - Error (NULL, 0, 0, Guid, "duplicate Guid specified in the same FV for %s and %s", - (Ptr->BaseName==NULL)?"Unknown":Ptr->BaseName, - (BaseName==NULL)?"Unknown":BaseName); - return STATUS_ERROR; - } - } - - Ptr = Ptr->Next; - } - // - // Allocate a new structure so we can add this file to the list of - // files. - // - Ptr = (FILE_LIST *) malloc (sizeof (FILE_LIST)); - if (Ptr == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - memset ((char *) Ptr, 0, sizeof (FILE_LIST)); - Ptr->FileName = (char *) malloc (strlen (FileName) + 1); - if (Ptr->FileName == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - strcpy (Ptr->FileName, FileName); - Ptr->ComponentsInstance = ComponentsInstance; - // - // Allocate memory to save the FV list if it's going into an FV. - // - if ((FVs != NULL) && (FVs[0] != 0)) { - Ptr->FVs = (char *) malloc (strlen (FVs) + 1); - if (Ptr->FVs == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - strcpy (Ptr->FVs, FVs); - } - - Ptr->BaseFileName = (char *) malloc (strlen (Name) + 1); - if (Ptr->BaseFileName == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - strcpy (Ptr->BaseFileName, Name); - // - // Allocate memory for the basename if they gave us one. May not have one - // if the user is simply adding pre-existing binary files to the image. - // - if (BaseName != NULL) { - Ptr->BaseName = (char *) malloc (strlen (BaseName) + 1); - if (Ptr->BaseName == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - strcpy (Ptr->BaseName, BaseName); - } - // - // Allocate memory for the processor name - // - if (Processor != NULL) { - Ptr->Processor = (char *) malloc (strlen (Processor) + 1); - if (Ptr->Processor == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - strcpy (Ptr->Processor, Processor); - } - // - // Allocate memory for the guid name - // - if (Guid != NULL) { - Ptr->Guid = (char *) malloc (strlen (Guid) + 1); - if (Ptr->Guid == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return STATUS_ERROR; - } - - strcpy (Ptr->Guid, Guid); - } - // - // If non-null apriori symbol, then save the apriori list for this file - // - if (Apriori != NULL) { - strcpy (Ptr->Apriori, Apriori); - } - - if (mFileList == NULL) { - mFileList = Ptr; - } else { - mLastFile->Next = Ptr; - } - - mLastFile = Ptr; - // - // Add these firmware volumes to the list of known firmware - // volume names. - // - AddFirmwareVolumes (FVs, ComponentsInstance); - - return STATUS_SUCCESS; -} - -void -CFVConstructor ( - VOID - ) -{ - mFileList = NULL; - mLastFile = NULL; -} - -void -CFVDestructor ( - VOID - ) -{ - CFVFreeFileList (); - // - // Free up our firmware volume list - // - while (mFVList != NULL) { - mFVListLast = mFVList->Next; - free (mFVList); - mFVList = mFVListLast; - } -} - -static -void -CFVFreeFileList ( - VOID - ) -{ - FILE_LIST *Next; - while (mFileList != NULL) { - if (mFileList->FileName != NULL) { - free (mFileList->FileName); - } - - if (mFileList->FVs != NULL) { - free (mFileList->FVs); - } - - free (mFileList->BaseFileName); - if (mFileList->BaseName != NULL) { - free (mFileList->BaseName); - } - - if (mFileList->Processor != NULL) { - free (mFileList->Processor); - } - - if (mFileList->Guid != NULL) { - free (mFileList->Guid); - } - - Next = mFileList->Next; - free (mFileList); - mFileList = Next; - } - - mFileList = NULL; -} - -int -CFVWriteInfFiles ( - DSC_FILE *DSC, - FILE *MakeFptr - ) -/*++ - -Routine Description: - - After processing all components in a DSC file, create the firmware - volume INF files. We actually do a lot more here. - - * Create the FVxxx.inf file that is used by GenFvImage - * Create the Apriori files for each firmware volume that requires one - * Create makefile.out macros for FVxxx_FILES = FVxxx_FILES AnotherFile - so you can do incremental builds of firmware volumes. - * For each FV, emit its build commands to makefile.out - -Arguments: - - DSC - pointer to a DSC_FILE object to extract info from - MakeFptr - pointer to the output makefile - -Returns: - - 0 if successful - non-zero otherwise - ---*/ -{ - FILE_LIST *FileListPtr; - FV_LIST *FVList; - FV_LIST *LastFVList; - FV_LIST *FVPtr; - SECTION *Section; - char *StartCptr; - char *EndCptr; - char CSave; - char Str[MAX_PATH]; - char Line[MAX_LINE_LEN]; - char ExpandedLine[MAX_LINE_LEN]; - char FVDir[MAX_PATH]; - FILE *XRefFptr; - int AprioriCounter; - int AprioriCount; - int AprioriPosition; - BOOLEAN AprioriFound; - int ComponentsInstance; - int ComponentCount; - - // - // Use this to keep track of all the firmware volume names - // - FVList = NULL; - LastFVList = NULL; - // - // See if they specified a FV directory to dump the FV files out to. If not, - // then use the default. Then create the output directory. - // - StartCptr = GetSymbolValue (FV_INF_DIR); - if (StartCptr == NULL) { - ExpandSymbols (DEFAULT_FV_INF_DIR, FVDir, sizeof (FVDir), EXPANDMODE_NO_UNDEFS); - } else { - strcpy (FVDir, StartCptr); - } - // - // Make sure the fv directory path ends in / - // - CSave = FVDir[strlen (FVDir) - 1]; - if ((CSave != '\\') && (CSave != '/')) { - strcat (FVDir, "\\"); - } - // - // Traverse the list of all files, determine which FV each is in, then - // write out the file's name to the output FVxxx.inf file. - // - for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) { - // - // Parse all the "FV1,FV2..." in the FVs - // - if (FileListPtr->FVs != NULL) { - // - // Process each fv this file is in - // - StartCptr = FileListPtr->FVs; - while (*StartCptr) { - EndCptr = StartCptr; - while (*EndCptr && (*EndCptr != ',')) { - EndCptr++; - } - - CSave = *EndCptr; - *EndCptr = 0; - // - // Ok, we have a fv name, now see if we've already opened - // an fv output file of this name. - // - for (FVPtr = FVList; FVPtr != NULL; FVPtr = FVPtr->Next) { - if (_stricmp (FVPtr->FVFileName, StartCptr) == 0) { - break; - } - } - // - // If we didn't find one, then create a new one - // - if (FVPtr == NULL) { - // - // Create a new one, add it to the list - // - FVPtr = (FV_LIST *) malloc (sizeof (FV_LIST)); - if (FVPtr == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory for FV"); - return STATUS_ERROR; - } - - memset ((char *) FVPtr, 0, sizeof (FV_LIST)); - // - // Add it to the end of our list - // - if (FVList == NULL) { - FVList = FVPtr; - } else { - LastFVList->Next = FVPtr; - } - - LastFVList = FVPtr; - // - // Save the FV name in the FileName pointer so we can compare - // for any future FV names specified. - // - strcpy (FVPtr->FVFileName, StartCptr); - - // - // Add a symbol for the FV filename - // - UpperCaseString (FVPtr->FVFileName); - AddSymbol (FV_FILENAME, FVPtr->FVFileName, SYM_LOCAL | SYM_OVERWRITE); - // - // Now create the FVx.inf filename from the fv name and - // default filename extension. Dump it in the FV directory - // as well. - // - strcpy (Str, FVDir); - strcat (Str, FVPtr->FVFileName); - strcat (Str, ".inf"); - // - // Create the directory path for our new fv.inf output file. - // - MakeFilePath (Str); - if ((FVPtr->FVFilePtr = SmartOpen (Str)) == NULL) { - Error (NULL, 0, 0, Str, "could not open FV output file"); - return STATUS_ERROR; - } - // - // Now copy the [fv.$(FV).options] to the fv INF file - // - sprintf (Str, "fv.%s.options", StartCptr); - Section = DSCFileFindSection (DSC, Str); - if (Section != NULL) { - SmartWrite (FVPtr->FVFilePtr, "[options]\n"); - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols (Line, ExpandedLine, sizeof (ExpandedLine), 0); - SmartWrite (FVPtr->FVFilePtr, ExpandedLine); - GetBaseAddress (ExpandedLine, FVPtr->BaseAddress); - } - } else { - Error (NULL, 0, 0, Str, "could not find FV section in description file"); - } - // - // Copy the [fv.$(FV).attributes] to the fv INF file - // - sprintf (Str, "fv.%s.attributes", StartCptr); - Section = DSCFileFindSection (DSC, Str); - if (Section != NULL) { - SmartWrite (FVPtr->FVFilePtr, "[attributes]\n"); - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols (Line, ExpandedLine, sizeof (ExpandedLine), 0); - SmartWrite (FVPtr->FVFilePtr, ExpandedLine); - } - } else { - Error (NULL, 0, 0, Str, "Could not find FV section in description file"); - } - // - // Start the files section - // - SmartWrite (FVPtr->FVFilePtr, "\n[files]\n"); - } - // - // Now write the FV filename to the FV.inf file. Prepend $(PROCESSOR) on - // it. - // - sprintf (ExpandedLine, "EFI_FILE_NAME = %s\n", FileListPtr->FileName); - SmartWrite (FVPtr->FVFilePtr, ExpandedLine); - - // - // Next FV on the FV list - // - *EndCptr = CSave; - StartCptr = EndCptr; - if (*StartCptr) { - StartCptr++; - } - } - } - } - // - // Now we walk the list of firmware volumes and create the APRIORI list - // file for it . - // - for (FVPtr = FVList; FVPtr != NULL; FVPtr = FVPtr->Next) { - // - // Run through all the files and count up how many are to be - // added to the apriori list for this FV. Then when we're done - // we'll make sure we processed them all. We do this in case they - // skipped an apriori index for a given FV. - // - AprioriCount = 0; - for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) { - if (OrderInFvList (FileListPtr->Apriori, FVPtr->FVFileName, &AprioriPosition)) { - // - // Emit an error if the index was 0, or they didn't give one. - // - if (AprioriPosition == 0) { - Error ( - GetSymbolValue (DSC_FILENAME), - 1, - 0, - "apriori indexes are 1-based", - "component %s:APRIORI=%s", - FileListPtr->BaseName, - FileListPtr->Apriori - ); - } else { - AprioriCount++; - } - - } - } - // - // Now scan the files as we increment our apriori index - // - AprioriCounter = 0; - do { - AprioriFound = 0; - AprioriCounter++; - for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) { - // - // If in the apriori list for this fv, print the name. Open the - // file first if we have to. - // - if ((FileListPtr->Apriori[0] != 0) && - (OrderInFvList (FileListPtr->Apriori, FVPtr->FVFileName, &AprioriPosition)) - ) { - if (AprioriPosition == AprioriCounter) { - // - // If we've already found one for this index, emit an error. Decrement the - // count of how files we are to process so we don't emit another error for - // a miscount below. - // - if (AprioriFound) { - Error ( - GetSymbolValue (DSC_FILENAME), - 1, - 0, - "duplicate apriori index found", - "%s:%d", - FVPtr->FVFileName, - AprioriCounter - ); - AprioriCount--; - } - - AprioriFound = 1; - // - // Open the apriori output file if we haven't already - // - if (FVPtr->AprioriFilePtr == NULL) { - strcpy (Str, FVDir); - strcat (Str, FVPtr->FVFileName); - strcat (Str, ".apr"); - if ((FVPtr->AprioriFilePtr = SmartOpen (Str)) == NULL) { - Error (NULL, 0, 0, Str, "could not open output Apriori file for writing"); - return STATUS_ERROR; - } - } - - sprintf (ExpandedLine, "%s\n", FileListPtr->BaseFileName); - SmartWrite (FVPtr->AprioriFilePtr, ExpandedLine); - } - } - } - } while (AprioriFound); - // - // See if they skipped an apriori position for this FV - // - if (AprioriCount != (AprioriCounter - 1)) { - Error ( - GetSymbolValue (DSC_FILENAME), - 1, - 0, - "apriori index skipped", - "%s:%d", - FVPtr->FVFileName, - AprioriCounter - ); - } - } - // - // Traverse the list of all files again, and create a macro in the output makefile - // that defines all the files in each fv. For example, for each FV file, create a line: - // FV0001_FILES = $(FV_0001_FILES) xxxx-yyy.dxe. - // This can then be used as a dependency in their makefile. - // Also if they wanted us to dump a cross-reference, do that now. - // - if (mXRefFileName != NULL) { - if ((XRefFptr = fopen (mXRefFileName, "w")) == NULL) { - Message ( - 0, - "Failed to open cross-reference file '%s' for writing\n", - mXRefFileName - ); - } - } else { - XRefFptr = NULL; - } - - for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) { - // - // Parse all the "FV1,FV2..." in the FV field that came from FV=FVa,FVb,... on the - // component line in the DSC file. - // - if (FileListPtr->FVs != NULL) { - // - // If generating a cross-reference file, dump the data - // - if (XRefFptr != NULL) { - if ((FileListPtr->Guid != NULL) && (FileListPtr->BaseName != NULL) && (FileListPtr->Processor)) { - fprintf ( - XRefFptr, - "%s %s %s\n", - FileListPtr->Guid, - FileListPtr->BaseName, - FileListPtr->Processor - ); - } - } - // - // Convert to uppercase since we're going to use the name as a macro variable name - // in the makefile. - // - UpperCaseString (FileListPtr->FVs); - // - // Process each FV this file is in to write fvxxx_FILES = $(fvxxx_FILES) Guid-BaseName.ffs - // - StartCptr = FileListPtr->FVs; - while (*StartCptr) { - EndCptr = StartCptr; - while (*EndCptr && (*EndCptr != ',')) { - EndCptr++; - } - - CSave = *EndCptr; - *EndCptr = 0; - fprintf ( - MakeFptr, - "%s_FILES = $(%s_FILES) %s\n", - StartCptr, - StartCptr, - FileListPtr->FileName - ); - // - // Next FV on the FV list - // - *EndCptr = CSave; - StartCptr = EndCptr; - if (*StartCptr) { - StartCptr++; - } - } - } - } - - fprintf (MakeFptr, "\n"); - - // - // Now go through the list of all NonFFS FVs they specified and search for - // a [build.fv.$(FV)] or [build.fv] command and emit the commands to the - // output makefile. Add them to the "fvs_0" target as well. - // - if (mNonFfsFVList != NULL) { - fprintf (MakeFptr, "fvs_0 ::"); - FVPtr = mNonFfsFVList; - while (FVPtr != NULL) { - fprintf (MakeFptr, " %s%s.fv", FVDir, FVPtr->FVFileName); - FVPtr = FVPtr->Next; - } - - fprintf (MakeFptr, "\n\n"); - FVPtr = mNonFfsFVList; - while (FVPtr != NULL) { - // - // Save the position in the file - // - DSCFileSavePosition (DSC); - // - // first try to find a build section specific for this fv. - // - sprintf (Str, "build.fv.%s", FVPtr->FVFileName); - Section = DSCFileFindSection (DSC, Str); - if (Section == NULL) { - sprintf (Str, "build.fv"); - Section = DSCFileFindSection (DSC, Str); - } - - if (Section == NULL) { - Warning ( - NULL, - 0, - 0, - NULL, - "No [build.fv.%s] nor [%s] section found in description file for building %s", - FVPtr->FVFileName, - Str, - FVPtr->FVFileName - ); - } else { - // - // Add a symbol for the FV filename - // - UpperCaseString (FVPtr->FVFileName); - AddSymbol (FV_FILENAME, FVPtr->FVFileName, SYM_LOCAL | SYM_OVERWRITE); - AddSymbol (EFI_BASE_ADDRESS, FVPtr->BaseAddress, SYM_LOCAL | SYM_OVERWRITE); - - // - // Now copy the build commands from the section to the makefile - // - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols ( - Line, - ExpandedLine, - sizeof (ExpandedLine), - EXPANDMODE_NO_DESTDIR | EXPANDMODE_NO_SOURCEDIR - ); - - fprintf (MakeFptr, ExpandedLine); - } - } - - FVPtr = FVPtr->Next; - DSCFileRestorePosition (DSC); - } - } - - // - // Get the components count - // - ComponentCount = -1; - for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) { - if (FileListPtr->ComponentsInstance > ComponentCount) { - ComponentCount = FileListPtr->ComponentsInstance; - } - } - ComponentCount++; - - // - // Now print firmware volumes build targets fvs_0, fvs_1 etc. - // - for (ComponentsInstance = 0; ComponentsInstance < ComponentCount; ComponentsInstance++) { - fprintf (MakeFptr, "fvs_%d ::", ComponentsInstance); - for (FVPtr = mFVList; FVPtr != NULL; FVPtr = FVPtr->Next) { - if (FVPtr->ComponentsInstance == ComponentsInstance) { - fprintf (MakeFptr, " %s%s.fv", FVDir, FVPtr->FVFileName); - } - } - fprintf (MakeFptr, "\n\n"); - } - - // - // Create an "fvs" target that builds everything. It has to be a mix of - // components and FV's in order. For example: - // fvs :: components_0 fvs_0 components_1 fvs_1 - // - fprintf (MakeFptr, "fvs ::"); - for (ComponentsInstance = 0; ComponentsInstance < ComponentCount; ComponentsInstance++) { - fprintf (MakeFptr, " components_%d fvs_%d", ComponentsInstance, ComponentsInstance); - } - fprintf (MakeFptr, "\n\n"); - - // - // Create a "components" target for build convenience. It should - // look something like: - // components : components_0 components_1... - // - if (ComponentCount > 0) { - fprintf (MakeFptr, "components :"); - for (ComponentsInstance = 0; ComponentsInstance < ComponentCount; ComponentsInstance++) { - fprintf (MakeFptr, " components_%d", ComponentsInstance); - } - - fprintf (MakeFptr, "\n\n"); - } - // - // Now go through the list of all FV's defined and search for - // a [build.fv.$(FV)] or [build.fv] command and emit the commands to the - // output makefile. - // - FVPtr = mFVList; - while (FVPtr != NULL) { - if (FVPtr->FVFileName[0]) { - // - // Save the position in the file - // - DSCFileSavePosition (DSC); - // - // First try to find a build section specific for this FV. - // - sprintf (Str, "build.fv.%s", FVPtr->FVFileName); - Section = DSCFileFindSection (DSC, Str); - if (Section == NULL) { - sprintf (Str, "build.fv"); - Section = DSCFileFindSection (DSC, Str); - } - - if (Section == NULL) { - Error ( - NULL, - 0, - 0, - NULL, - "no [build.fv.%s] nor [%s] section found in description file for building %s", - FVPtr->FVFileName, - Str, - FVPtr->FVFileName - ); - } else { - // - // Add a symbol for the FV filename - // - UpperCaseString (FVPtr->FVFileName); - AddSymbol (FV_FILENAME, FVPtr->FVFileName, SYM_LOCAL | SYM_OVERWRITE); - AddSymbol (EFI_BASE_ADDRESS, FVPtr->BaseAddress, SYM_LOCAL | SYM_OVERWRITE); - - // - // Now copy the build commands from the section to the makefile - // - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols ( - Line, - ExpandedLine, - sizeof (ExpandedLine), - EXPANDMODE_NO_DESTDIR | EXPANDMODE_NO_SOURCEDIR - ); - fprintf (MakeFptr, ExpandedLine); - } - } - - DSCFileRestorePosition (DSC); - } - - FVPtr = FVPtr->Next; - } - // - // Close all the files and free up the memory - // - while (FVList != NULL) { - FVPtr = FVList->Next; - if (FVList->FVFilePtr != NULL) { - SmartClose (FVList->FVFilePtr); - } - - if (FVList->AprioriFilePtr != NULL) { - SmartClose (FVList->AprioriFilePtr); - } - - free (FVList); - FVList = FVPtr; - } - - while (mNonFfsFVList != NULL) { - FVPtr = mNonFfsFVList->Next; - free (mNonFfsFVList); - mNonFfsFVList = FVPtr; - } - - if (XRefFptr != NULL) { - fclose (XRefFptr); - } - - return STATUS_SUCCESS; -} - -int -NonFFSFVWriteInfFiles ( - DSC_FILE *DSC, - char *FileName - ) -/*++ - -Routine Description: - - Generate a Non FFS fv file. It can only some variables, - or simply contains nothing except header. - -Arguments: - - DSC - pointer to a DSC_FILE object to extract info from - FileName - pointer to the fv file - -Returns: - - STATUS_SUCCESS if successful - non-STATUS_SUCCESS otherwise - ---*/ -{ - FV_LIST *FVPtr; - SECTION *Section; - char *StartCptr; - char *EndCptr; - char CSave; - char Str[MAX_PATH]; - char Line[MAX_LINE_LEN]; - char ExpandedLine[MAX_LINE_LEN]; - char FVDir[MAX_PATH]; - - // - // See if they specified a FV directory to dump the FV files out to. If not, - // then use the default. Then create the output directory. - // - DSCFileSavePosition (DSC); - StartCptr = GetSymbolValue (FV_INF_DIR); - if (StartCptr == NULL) { - ExpandSymbols (DEFAULT_FV_INF_DIR, FVDir, sizeof (FVDir), EXPANDMODE_NO_UNDEFS); - } else { - strcpy (FVDir, StartCptr); - } - - // - // Make sure the fv directory path ends in / - // - CSave = FVDir[strlen (FVDir) - 1]; - if ((CSave != '\\') && (CSave != '/')) { - strcat (FVDir, "\\"); - } - - StartCptr = FileName; - while (*StartCptr) { - EndCptr = StartCptr; - while (*EndCptr && (*EndCptr != ',')) { - EndCptr++; - } - - CSave = *EndCptr; - *EndCptr = 0; - // - // Ok, we have a fv name, now see if we've already opened - // an fv output file of this name. - // - for (FVPtr = mNonFfsFVList; FVPtr != NULL; FVPtr = FVPtr->Next) { - if (_stricmp (FVPtr->FVFileName, StartCptr) == 0) { - break; - } - } - // - // If there is already one with the same name, wrong - // - if (FVPtr != NULL) { - DSCFileRestorePosition (DSC); - return STATUS_ERROR; - } - // - // Create a new one, add it to the list - // - FVPtr = (FV_LIST *) malloc (sizeof (FV_LIST)); - if (FVPtr == NULL) { - Error (__FILE__, __LINE__, 0, "failed to allocate memory", NULL); - DSCFileRestorePosition (DSC); - return STATUS_ERROR; - } - - memset ((char *) FVPtr, 0, sizeof (FV_LIST)); - FVPtr->Next = mNonFfsFVList; - mNonFfsFVList = FVPtr; - // - // Save the FV name in the FileName pointer so we can compare - // for any future FV names specified. - // - strcpy (FVPtr->FVFileName, StartCptr); - // - // Add a symbol for the FV filename - // - UpperCaseString (FVPtr->FVFileName); - AddSymbol (FV_FILENAME, FVPtr->FVFileName, SYM_LOCAL | SYM_OVERWRITE); - - // - // Now create the FVx.inf filename from the fv name and - // default filename extension. Dump it in the FV directory - // as well. - // - strcpy (Str, FVDir); - strcat (Str, FVPtr->FVFileName); - strcat (Str, ".inf"); - // - // Create the directory path for our new fv.inf output file. - // - MakeFilePath (Str); - if ((FVPtr->FVFilePtr = SmartOpen (Str)) == NULL) { - Error (NULL, 0, 0, Str, "could not open FV output file"); - DSCFileRestorePosition (DSC); - return STATUS_ERROR; - } - // - // Now copy the [fv.fvfile.options] to the fv file - // - sprintf (Str, "fv.%s.options", StartCptr); - Section = DSCFileFindSection (DSC, Str); - if (Section != NULL) { - SmartWrite (FVPtr->FVFilePtr, "[options]\n"); - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols (Line, ExpandedLine, sizeof (ExpandedLine), 0); - SmartWrite (FVPtr->FVFilePtr, ExpandedLine); - GetBaseAddress (ExpandedLine, FVPtr->BaseAddress); - } - } else { - Warning (NULL, 0, 0, NULL, "Could not find FV section '%s' in description file", Str); - } - // - // Copy the [fv.fvfile.attributes] to the fv file - // - sprintf (Str, "fv.%s.attributes", StartCptr); - Section = DSCFileFindSection (DSC, Str); - if (Section != NULL) { - SmartWrite (FVPtr->FVFilePtr, "[attributes]\n"); - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols (Line, ExpandedLine, sizeof (ExpandedLine), 0); - SmartWrite (FVPtr->FVFilePtr, ExpandedLine); - } - } else { - Warning (NULL, 0, 0, NULL, "Could not find FV section '%s' in description file", Str); - } - // - // Copy the [fv.fvfile.components] to the fv file - // - sprintf (Str, "fv.%s.components", StartCptr); - Section = DSCFileFindSection (DSC, Str); - if (Section != NULL) { - SmartWrite (FVPtr->FVFilePtr, "[components]\n"); - while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) { - ExpandSymbols (Line, ExpandedLine, sizeof (ExpandedLine), 0); - SmartWrite (FVPtr->FVFilePtr, ExpandedLine); - } - } else { - // - // An empty FV is allowed to contain nothing - // - } - // - // Close the file - // - SmartClose (FVPtr->FVFilePtr); - // - // Next FV in FileName - // - *EndCptr = CSave; - StartCptr = EndCptr; - if (*StartCptr) { - StartCptr++; - } - } - - DSCFileRestorePosition (DSC); - return STATUS_SUCCESS; -} - -static -void -AddFirmwareVolumes ( - char *FVs, - int ComponentsInstance - ) -{ - FV_LIST *FvPtr; - char *StartPtr; - char *EndPtr; - char SaveChar; - - if ((FVs != NULL) && (FVs[0] != 0)) { - // - // Extract each FV name from the string. It's from the DSC file "FV=FvRecover,FvMain" - // - StartPtr = FVs; - while (*StartPtr != 0) { - EndPtr = StartPtr; - while (*EndPtr && (*EndPtr != ',')) { - EndPtr++; - } - - SaveChar = *EndPtr; - *EndPtr = 0; - // - // Look through our list of known firmware volumes and see if we've - // already added it. - // - for (FvPtr = mFVList; FvPtr != NULL; FvPtr = FvPtr->Next) { - if (_stricmp (FvPtr->FVFileName, StartPtr) == 0) { - break; - } - } - // - // If we didn't find a match, then create a new one - // - if (FvPtr == NULL) { - FvPtr = malloc (sizeof (FV_LIST)); - if (FvPtr == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "memory allocation failed"); - return ; - } - - memset (FvPtr, 0, sizeof (FV_LIST)); - strcpy (FvPtr->FVFileName, StartPtr); - if (mFVList == NULL) { - mFVList = FvPtr; - } else { - mFVListLast->Next = FvPtr; - } - - mFVListLast = FvPtr; - } - // - // If this component's section number is higher than that of this - // FV, then set the FV's to it. - // - if (FvPtr->ComponentsInstance < ComponentsInstance) { - FvPtr->ComponentsInstance = ComponentsInstance; - } - // - // If we found then end of the FVs in the string, then we're done. - // Always restore the original string's contents. - // - if (SaveChar != 0) { - *EndPtr = SaveChar; - StartPtr = EndPtr + 1; - } else { - StartPtr = EndPtr; - } - } - } -} - -static -BOOLEAN -OrderInFvList ( - char *FvList, - char *FvName, - int *Order - ) -{ - // - // Given FvList of format "FV_a,FV_b,FV_c" or "FV_a:1,FV_b:2" and - // FvName of format "FV_c", determine if FvName is in FvList. If - // FV_a:1 format, then return the value after the colon. - // - while (*FvList) { - // - // If it matches for the length of FvName... - // - if (_strnicmp (FvList, FvName, strlen (FvName)) == 0) { - // - // Then see if the match string in FvList is terminated at the - // same length. - // - if ((FvList[strlen (FvName)] == ',') || (FvList[strlen (FvName)] == 0)) { - *Order = 0; - return TRUE; - } else if (FvList[strlen (FvName)] == ':') { - *Order = atoi (FvList + strlen (FvName) + 1); - return TRUE; - } - } - // - // Skip to next FV in the comma-separated list - // - while ((*FvList != ',') && (*FvList != 0)) { - FvList++; - } - // - // Skip over comma - // - if (*FvList == ',') { - FvList++; - } - } - - return FALSE; -} - -static -char * -UpperCaseString ( - char *Str - ) -{ - char *Cptr; - - for (Cptr = Str; *Cptr; Cptr++) { - *Cptr = (char) toupper (*Cptr); - } - - return Str; -} - -static -BOOLEAN -InSameFv ( - char *FVs1, - char *FVs2 -) -{ - char *StartCptr1; - char *StartCptr2; - char *EndCptr1; - char *EndCptr2; - char CSave1; - char CSave2; - - // - // Process each FV in first FV list - // - StartCptr1 = FVs1; - while (*StartCptr1) { - EndCptr1 = StartCptr1; - while (*EndCptr1 && (*EndCptr1 != ',')) { - EndCptr1++; - } - - CSave1 = *EndCptr1; - *EndCptr1 = 0; - - if (*StartCptr1) { - // - // Process each FV in second FV list - // - StartCptr2 = FVs2; - while (*StartCptr2) { - EndCptr2 = StartCptr2; - while (*EndCptr2 && (*EndCptr2 != ',')) { - EndCptr2++; - } - - CSave2 = *EndCptr2; - *EndCptr2 = 0; - - if (_stricmp (StartCptr1, StartCptr2) == 0) { - *EndCptr1 = CSave1; - *EndCptr2 = CSave2; - return TRUE; - } - - // - // Next FV on the second FV list - // - *EndCptr2 = CSave2; - StartCptr2 = EndCptr2; - if (*StartCptr2) { - StartCptr2++; - } - } - } - - // - // Next FV on the first FV list - // - *EndCptr1 = CSave1; - StartCptr1 = EndCptr1; - if (*StartCptr1) { - StartCptr1++; - } - } - - return FALSE; -} - -int -CFVSetXRefFileName ( - char *FileName - ) -{ - mXRefFileName = FileName; - return 0; -}