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