--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004-2005 Intel Corporation. All rights reserved\r
+This software and associated documentation (if any) is furnished\r
+under a license and may only be used or copied in accordance\r
+with the terms of the license. Except as permitted by such\r
+license, no part of this software or documentation may be\r
+reproduced, stored in a retrieval system, or transmitted in any\r
+form or by any means without the express written consent of\r
+Intel Corporation.\r
+\r
+Module Name:\r
+\r
+ FlashMap.c\r
+\r
+Abstract:\r
+\r
+ Utility for flash management in the Intel Platform Innovation Framework\r
+ for EFI build environment.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+\r
+#include "Tiano.h"\r
+\r
+#ifndef INT8\r
+#define INT8 char\r
+#endif\r
+\r
+#include "EfiUtilityMsgs.h"\r
+#include "Microcode.h"\r
+#include "FlashDefFile.h"\r
+#include "Symbols.h"\r
+\r
+#define UTILITY_NAME "FlashMap"\r
+\r
+typedef struct _STRING_LIST {\r
+ struct _STRING_LIST *Next;\r
+ char *Str;\r
+} STRING_LIST;\r
+\r
+//\r
+// Keep our globals in one of these structures\r
+//\r
+static struct {\r
+ char *CIncludeFileName;\r
+ char *FlashDevice;\r
+ char *FlashDeviceImage;\r
+ char *MCIFileName;\r
+ char *MCOFileName;\r
+ char *ImageOutFileName;\r
+ char *DscFileName;\r
+ char *AsmIncludeFileName;\r
+ char *FlashDefinitionFileName;\r
+ char *StringReplaceInFileName;\r
+ char *StringReplaceOutFileName;\r
+ char *DiscoverFDImageName;\r
+ char MicrocodePadByteValue;\r
+ unsigned int MicrocodeAlignment;\r
+ STRING_LIST *MCIFileNames;\r
+ STRING_LIST *LastMCIFileNames;\r
+ unsigned int BaseAddress;\r
+} mGlobals;\r
+\r
+#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF\r
+#define DEFAULT_MC_ALIGNMENT 16\r
+\r
+static\r
+STATUS\r
+ProcessCommandLine (\r
+ int argc,\r
+ char *argv[]\r
+ );\r
+\r
+static\r
+STATUS\r
+MergeMicrocodeFiles (\r
+ char *OutFileName,\r
+ STRING_LIST *FileNames,\r
+ unsigned int Alignment,\r
+ char PadByteValue\r
+ );\r
+\r
+static\r
+void\r
+Usage (\r
+ VOID\r
+ );\r
+\r
+int\r
+main (\r
+ int argc,\r
+ char *argv[]\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Parse the command line arguments and then call worker functions to do the work\r
+ \r
+Arguments:\r
+ argc - number of elements in argv\r
+ argv - array of command-line arguments\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no problems encountered while processing\r
+ STATUS_WARNING - warnings, but no errors, were encountered while processing\r
+ STATUS_ERROR - errors were encountered while processing\r
+ \r
+--*/\r
+{\r
+ STATUS Status;\r
+\r
+ SetUtilityName (UTILITY_NAME);\r
+ Status = ProcessCommandLine (argc, argv);\r
+ if (Status != STATUS_SUCCESS) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Check for discovery of an FD (command line option)\r
+ //\r
+ if (mGlobals.DiscoverFDImageName != NULL) {\r
+ Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress);\r
+ goto Done;\r
+ }\r
+ //\r
+ // If they're doing microcode file parsing, then do that\r
+ //\r
+ if (mGlobals.MCIFileName != NULL) {\r
+ MicrocodeConstructor ();\r
+ MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName);\r
+ MicrocodeDestructor ();\r
+ }\r
+ //\r
+ // If they're doing microcode file merging, then do that now\r
+ //\r
+ if (mGlobals.MCIFileNames != NULL) {\r
+ MergeMicrocodeFiles (\r
+ mGlobals.MCOFileName,\r
+ mGlobals.MCIFileNames,\r
+ mGlobals.MicrocodeAlignment,\r
+ mGlobals.MicrocodePadByteValue\r
+ );\r
+ }\r
+ //\r
+ // If using a flash definition file, then process that and return\r
+ //\r
+ if (mGlobals.FlashDefinitionFileName != NULL) {\r
+ FDFConstructor ();\r
+ SymbolsConstructor ();\r
+ Status = FDFParseFile (mGlobals.FlashDefinitionFileName);\r
+ if (GetUtilityStatus () != STATUS_ERROR) {\r
+ //\r
+ // If they want us to do a string-replace on a file, then add the symbol definitions to\r
+ // the symbol table, and then do the string replace.\r
+ //\r
+ if (mGlobals.StringReplaceInFileName != NULL) {\r
+ Status = FDFCreateSymbols (mGlobals.FlashDevice);\r
+ Status = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName);\r
+ }\r
+ //\r
+ // If they want us to create a .h defines file or .c flashmap data file, then do so now\r
+ //\r
+ if (mGlobals.CIncludeFileName != NULL) {\r
+ Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName);\r
+ }\r
+ if (mGlobals.AsmIncludeFileName != NULL) {\r
+ Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName);\r
+ }\r
+ //\r
+ // If they want us to create an image, do that now\r
+ //\r
+ if (mGlobals.ImageOutFileName != NULL) {\r
+ Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName);\r
+ }\r
+ //\r
+ // If they want to create an output DSC file, do that now\r
+ //\r
+ if (mGlobals.DscFileName != NULL) {\r
+ Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName);\r
+ }\r
+ }\r
+ SymbolsDestructor ();\r
+ FDFDestructor ();\r
+ }\r
+Done:\r
+ //\r
+ // Free up memory\r
+ //\r
+ while (mGlobals.MCIFileNames != NULL) {\r
+ mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next;\r
+ _free (mGlobals.MCIFileNames);\r
+ mGlobals.MCIFileNames = mGlobals.LastMCIFileNames;\r
+ }\r
+ return GetUtilityStatus ();\r
+}\r
+\r
+static\r
+STATUS\r
+MergeMicrocodeFiles (\r
+ char *OutFileName,\r
+ STRING_LIST *FileNames,\r
+ unsigned int Alignment,\r
+ char PadByteValue\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Merge binary microcode files into a single file, taking into consideration\r
+ the alignment and pad value.\r
+\r
+Arguments:\r
+\r
+ OutFileName - name of the output file to create\r
+ FileNames - linked list of input microcode files to merge\r
+ Alignment - alignment for each microcode file in the output image\r
+ PadByteValue - value to use when padding to meet alignment requirements\r
+\r
+Returns:\r
+\r
+ STATUS_SUCCESS - merge completed successfully or with acceptable warnings\r
+ STATUS_ERROR - merge failed, output file not created\r
+\r
+--*/\r
+{\r
+ long FileSize;\r
+ long TotalFileSize;\r
+ FILE *InFptr;\r
+ FILE *OutFptr;\r
+ char *Buffer;\r
+ STATUS Status;\r
+\r
+ //\r
+ // Open the output file\r
+ //\r
+ if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {\r
+ Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Walk the list of files\r
+ //\r
+ Status = STATUS_ERROR;\r
+ Buffer = NULL;\r
+ InFptr = NULL;\r
+ TotalFileSize = 0;\r
+ while (FileNames != NULL) {\r
+ //\r
+ // Open the file, determine the size, then read it in and write\r
+ // it back out.\r
+ //\r
+ if ((InFptr = fopen (FileNames->Str, "rb")) == NULL) {\r
+ Error (NULL, 0, 0, FileNames->Str, "failed to open input file for reading");\r
+ goto Done;\r
+ }\r
+ fseek (InFptr, 0, SEEK_END);\r
+ FileSize = ftell (InFptr);\r
+ fseek (InFptr, 0, SEEK_SET);\r
+ if (FileSize != 0) {\r
+ Buffer = (char *) _malloc (FileSize);\r
+ if (Buffer == NULL) {\r
+ Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+ goto Done;\r
+ }\r
+ if (fread (Buffer, FileSize, 1, InFptr) != 1) {\r
+ Error (NULL, 0, 0, FileNames->Str, "failed to read file contents");\r
+ goto Done;\r
+ }\r
+ //\r
+ // Align\r
+ //\r
+ if (Alignment != 0) {\r
+ while ((TotalFileSize % Alignment) != 0) {\r
+ if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) {\r
+ Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file");\r
+ goto Done;\r
+ }\r
+ TotalFileSize++;\r
+ }\r
+ }\r
+ TotalFileSize += FileSize;\r
+ if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {\r
+ Error (NULL, 0, 0, OutFileName, "failed to write to output file");\r
+ goto Done;\r
+ }\r
+ _free (Buffer);\r
+ Buffer = NULL;\r
+ } else {\r
+ Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered");\r
+ }\r
+ fclose (InFptr);\r
+ InFptr = NULL;\r
+ FileNames = FileNames->Next;\r
+ }\r
+ Status = STATUS_SUCCESS;\r
+Done:\r
+ fclose (OutFptr);\r
+ if (InFptr != NULL) {\r
+ fclose (InFptr);\r
+ }\r
+ if (Buffer != NULL) {\r
+ _free (Buffer);\r
+ }\r
+ if (Status == STATUS_ERROR) {\r
+ remove (OutFileName);\r
+ }\r
+ return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+ProcessCommandLine (\r
+ int argc,\r
+ char *argv[]\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Process the command line arguments\r
+ \r
+Arguments:\r
+ argc - Standard C entry point arguments\r
+ argv[] - Standard C entry point arguments\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no problems encountered while processing\r
+ STATUS_WARNING - warnings, but no errors, were encountered while processing\r
+ STATUS_ERROR - errors were encountered while processing\r
+ \r
+--*/\r
+{\r
+ int ThingsToDo;\r
+ unsigned int Temp;\r
+ STRING_LIST *Str;\r
+ //\r
+ // Skip program name arg, process others\r
+ //\r
+ argc--;\r
+ argv++;\r
+ if (argc == 0) {\r
+ Usage ();\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Clear out our globals, then start walking the arguments\r
+ //\r
+ memset ((void *) &mGlobals, 0, sizeof (mGlobals));\r
+ mGlobals.MicrocodePadByteValue = DEFAULT_MC_PAD_BYTE_VALUE;\r
+ mGlobals.MicrocodeAlignment = DEFAULT_MC_ALIGNMENT;\r
+ ThingsToDo = 0;\r
+ while (argc > 0) {\r
+ if (strcmp (argv[0], "-?") == 0) {\r
+ Usage ();\r
+ return STATUS_ERROR;\r
+ } else if (strcmp (argv[0], "-hfile") == 0) {\r
+ //\r
+ // -hfile FileName\r
+ //\r
+ // Used to specify an output C #include file to create that contains\r
+ // #define statements for all the flashmap region offsets and sizes.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an output file name");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.CIncludeFileName = argv[0];\r
+ ThingsToDo++;\r
+ } else if (strcmp (argv[0], "-flashdevice") == 0) {\r
+ //\r
+ // -flashdevice FLASH_DEVICE_NAME\r
+ //\r
+ // Used to select which flash device definition to operate on.\r
+ // Check for additional argument\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires a flash device name to use");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.FlashDevice = argv[0];\r
+ } else if (strcmp (argv[0], "-mco") == 0) {\r
+ //\r
+ // -mco OutFileName\r
+ //\r
+ // Used to specify a microcode output binary file to create.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.MCOFileName = argv[0];\r
+ ThingsToDo++;\r
+ } else if (strcmp (argv[0], "-asmincfile") == 0) {\r
+ //\r
+ // -asmincfile FileName\r
+ //\r
+ // Used to specify the name of the output assembly include file that contains\r
+ // equates for the flash region addresses and sizes.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.AsmIncludeFileName = argv[0];\r
+ ThingsToDo++;\r
+ } else if (strcmp (argv[0], "-mci") == 0) {\r
+ //\r
+ // -mci FileName\r
+ //\r
+ // Used to specify an input microcode text file to parse.\r
+ // Check for additional argument\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.MCIFileName = argv[0];\r
+ } else if (strcmp (argv[0], "-flashdeviceimage") == 0) {\r
+ //\r
+ // -flashdeviceimage FlashDeviceImage\r
+ //\r
+ // Used to specify which flash device image definition from the input flash definition file\r
+ // to create.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.FlashDeviceImage = argv[0];\r
+ } else if (strcmp (argv[0], "-imageout") == 0) {\r
+ //\r
+ // -imageout FileName\r
+ //\r
+ // Used to specify the name of the output FD image file to create.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an output image filename to create");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.ImageOutFileName = argv[0];\r
+ ThingsToDo++;\r
+ } else if (strcmp (argv[0], "-dsc") == 0) {\r
+ //\r
+ // -dsc FileName\r
+ //\r
+ // Used to specify the name of the output DSC file to create.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.DscFileName = argv[0];\r
+ ThingsToDo++;\r
+ } else if (strcmp (argv[0], "-fdf") == 0) {\r
+ //\r
+ // -fdf FileName\r
+ //\r
+ // Used to specify the name of the input flash definition file.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.FlashDefinitionFileName = argv[0];\r
+ } else if (strcmp (argv[0], "-discover") == 0) {\r
+ //\r
+ // -discover FDFileName\r
+ //\r
+ // Debug functionality used to scan an existing FD image, trying to find\r
+ // firmware volumes at 64K boundaries.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an input FD image file name");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.DiscoverFDImageName = argv[0];\r
+ ThingsToDo++;\r
+ } else if (strcmp (argv[0], "-baseaddr") == 0) {\r
+ //\r
+ // -baseaddr Addr\r
+ //\r
+ // Used to specify a base address when doing a discover of an FD image.\r
+ // Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires a base address");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ if (tolower (argv[0][1]) == 'x') {\r
+ sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress);\r
+ } else {\r
+ sscanf (argv[0], "%d", &mGlobals.BaseAddress);\r
+ }\r
+ } else if (strcmp (argv[0], "-padvalue") == 0) {\r
+ //\r
+ // -padvalue Value\r
+ //\r
+ // Used to specify the value to pad with when aligning data while\r
+ // creating an FD image. Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires a byte value");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ if (tolower (argv[0][1]) == 'x') {\r
+ sscanf (argv[0] + 2, "%x", &Temp);\r
+ mGlobals.MicrocodePadByteValue = (char) Temp;\r
+ } else {\r
+ sscanf (argv[0], "%d", &Temp);\r
+ mGlobals.MicrocodePadByteValue = (char) Temp;\r
+ }\r
+ } else if (strcmp (argv[0], "-align") == 0) {\r
+ //\r
+ // -align Alignment\r
+ //\r
+ // Used to specify how each data file is aligned in the region\r
+ // when creating an FD image. Check for additional argument.\r
+ //\r
+ if (argc < 2) {\r
+ Error (NULL, 0, 0, argv[0], "option requires an alignment");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ if (tolower (argv[0][1]) == 'x') {\r
+ sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment);\r
+ } else {\r
+ sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment);\r
+ }\r
+ } else if (strcmp (argv[0], "-mcmerge") == 0) {\r
+ //\r
+ // -mcmerge FileName(s)\r
+ //\r
+ // Used to concatenate multiple microde binary files. Can specify\r
+ // multiple file names with the one -mcmerge flag. Check for additional argument.\r
+ //\r
+ if ((argc < 2) || (argv[1][0] == '-')) {\r
+ Error (NULL, 0, 0, argv[0], "option requires one or more input file names");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Take input files until another option or end of list\r
+ //\r
+ ThingsToDo++;\r
+ while ((argc > 1) && (argv[1][0] != '-')) {\r
+ Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST));\r
+ if (Str == NULL) {\r
+ Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ memset (Str, 0, sizeof (STRING_LIST));\r
+ Str->Str = argv[1];\r
+ if (mGlobals.MCIFileNames == NULL) {\r
+ mGlobals.MCIFileNames = Str;\r
+ } else {\r
+ mGlobals.LastMCIFileNames->Next = Str;\r
+ }\r
+ mGlobals.LastMCIFileNames = Str;\r
+ argc--;\r
+ argv++;\r
+ }\r
+ } else if (strcmp (argv[0], "-strsub") == 0) {\r
+ //\r
+ // -strsub SrcFile DestFile\r
+ //\r
+ // Used to perform string substitutions on a file, writing the result to a new\r
+ // file. Check for two additional arguments.\r
+ //\r
+ if (argc < 3) {\r
+ Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ mGlobals.StringReplaceInFileName = argv[0];\r
+ argc--;\r
+ argv++;\r
+ mGlobals.StringReplaceOutFileName = argv[0];\r
+ ThingsToDo++;\r
+ } else {\r
+ Error (NULL, 0, 0, argv[0], "invalid option");\r
+ return STATUS_ERROR;\r
+ }\r
+ argc--;\r
+ argv++;\r
+ }\r
+ //\r
+ // If no outputs requested, then report an error\r
+ //\r
+ if (ThingsToDo == 0) {\r
+ Error (NULL, 0, 0, "nothing to do", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // If they want an asm file, #include file, or C file to be created, then they have to specify a\r
+ // flash device name and flash definition file name.\r
+ //\r
+ if ((mGlobals.CIncludeFileName != NULL) &&\r
+ ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {\r
+ Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ if ((mGlobals.AsmIncludeFileName != NULL) &&\r
+ ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {\r
+ Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // If they want a dsc file to be created, then they have to specify a\r
+ // flash device name and a flash definition file name\r
+ //\r
+ if (mGlobals.DscFileName != NULL) {\r
+ if (mGlobals.FlashDevice == NULL) {\r
+ Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ if (mGlobals.FlashDefinitionFileName == NULL) {\r
+ Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ }\r
+ //\r
+ // If they specified an output microcode file name, then they have to specify an input\r
+ // file name, and vice versa.\r
+ //\r
+ if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) {\r
+ Error (NULL, 0, 0, "must specify output microcode file name", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) {\r
+ Error (NULL, 0, 0, "must specify input microcode file name", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // If doing merge, then have to specify output file name\r
+ //\r
+ if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) {\r
+ Error (NULL, 0, 0, "must specify output microcode file name", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // If they want an output image to be created, then they have to specify\r
+ // the flash device and the flash device image to use.\r
+ //\r
+ if (mGlobals.ImageOutFileName != NULL) {\r
+ if (mGlobals.FlashDevice == NULL) {\r
+ Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ if (mGlobals.FlashDeviceImage == NULL) {\r
+ Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ if (mGlobals.FlashDefinitionFileName == NULL) {\r
+ Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ }\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+Usage (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Print utility command line help\r
+ \r
+Arguments:\r
+ None\r
+\r
+Returns:\r
+ NA\r
+\r
+--*/\r
+{\r
+ int i;\r
+ char *Msg[] = {\r
+ "Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice",\r
+ " -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile",\r
+ " -discover FDImage -dsc DscFile -asmincfile AsmIncFile",\r
+ " -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile",\r
+ " -baseaddr BaseAddr -align Alignment -padvalue PadValue",\r
+ " -mcmerge MCIFile(s)",\r
+ " where",\r
+ " FlashDefFile - input Flash Definition File",\r
+ " FlashDevice - flash device to use (from flash definition file)",\r
+ " FlashDeviceImage - flash device image to use (from flash definition file)",\r
+ " MCIFile - input microcode file to parse",\r
+ " MCOFile - output binary microcode image to create from MCIFile",\r
+ " HFile - output #include file to create",\r
+ " FDImage - name of input FDImage file to scan",\r
+ " ImageOutFile - output image file to create",\r
+ " DscFile - output DSC file to create",\r
+ " AsmIncFile - output ASM include file to create",\r
+ " InStrFile - input file to replace symbol names, writing result to OutStrFile",\r
+ " BaseAddr - base address of FDImage (used with -discover)",\r
+ " Alignment - alignment to use when merging microcode binaries",\r
+ " PadValue - byte value to use as pad value when aligning microcode binaries",\r
+ " MCIFile(s) - one or more microcode binary files to merge/concatenate",\r
+ "",\r
+ NULL\r
+ };\r
+ for (i = 0; Msg[i] != NULL; i++) {\r
+ fprintf (stdout, "%s\n", Msg[i]);\r
+ }\r
+}\r