summaryrefslogtreecommitdiff
path: root/Tools/CodeTools/Source/FlashMap
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CodeTools/Source/FlashMap')
-rw-r--r--Tools/CodeTools/Source/FlashMap/FlashDefFile.c2788
-rw-r--r--Tools/CodeTools/Source/FlashMap/FlashDefFile.h281
-rw-r--r--Tools/CodeTools/Source/FlashMap/FlashMap.c769
-rw-r--r--Tools/CodeTools/Source/FlashMap/Microcode.c304
-rw-r--r--Tools/CodeTools/Source/FlashMap/Microcode.h87
-rw-r--r--Tools/CodeTools/Source/FlashMap/Symbols.c648
-rw-r--r--Tools/CodeTools/Source/FlashMap/Symbols.h124
-rw-r--r--Tools/CodeTools/Source/FlashMap/build.xml76
8 files changed, 5077 insertions, 0 deletions
diff --git a/Tools/CodeTools/Source/FlashMap/FlashDefFile.c b/Tools/CodeTools/Source/FlashMap/FlashDefFile.c
new file mode 100644
index 0000000000..cdbf7886ec
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/FlashDefFile.c
@@ -0,0 +1,2788 @@
+/*++
+
+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:
+
+ FlashDefFile.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 <Common/UefiBaseTypes.h>
+#include <Common/FirmwareVolumeHeader.h>
+#include <Common/MultiPhase.h>
+
+#include "EfiUtilityMsgs.h"
+#include "FlashDefFile.h"
+#include "SimpleFileParsing.h"
+#include "Symbols.h"
+
+//
+// #include "TrackMallocFree.h"
+//
+#define WCHAR_T char
+#define MAX_STRING_LEN 256
+#define MAX_NAME_LEN 128
+#define BUFFER_SIZE 1024
+#define MAX_ATTR_LEN 128
+#define MAX_AREATYPE_LEN 128
+#define COLUMN2_START 60
+#define COLUMN3_START 70
+//
+// Information for each subregions defined in the fdf file will be saved in these
+//
+typedef struct _FLASH_SUBREGION_DESCRIPTION {
+ struct _FLASH_SUBREGION_DESCRIPTION *Next;
+ int CreateHob; // to add to the auto-created HOB array
+ WCHAR_T Name[MAX_NAME_LEN]; // each subregion within a region must have a unique name
+ unsigned int Size; // size, in bytes, of this subregion
+ unsigned int SizeLeft; // used when creating the image
+ WCHAR_T Attributes[MAX_ATTR_LEN]; // subregion attributes used in the output HOB
+ WCHAR_T AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB
+ EFI_GUID NameGuid; // used in the output HOB
+ WCHAR_T NameGuidString[MAX_NAME_LEN];
+ EFI_GUID AreaTypeGuid; // used in the output HOB
+ WCHAR_T AreaTypeGuidString[MAX_NAME_LEN];
+ EFI_GUID FileSystemGuid; // used in the output HOB
+ WCHAR_T FileSystemGuidString[MAX_NAME_LEN];
+} FLASH_SUBREGION_DESCRIPTION;
+
+//
+// Information for each block in a flash device will be saved in one of these.
+// We'll also use it for region definitions.
+//
+typedef struct _FLASH_BLOCK_DESCRIPTION {
+ struct _FLASH_BLOCK_DESCRIPTION *Next; // next block in the linked list
+ WCHAR_T Name[MAX_NAME_LEN]; // each block must have a unique name
+ unsigned int Size; // size, in bytes, of this block
+ unsigned int SizeLeft; // for use when creating image
+ unsigned int Flags; // user-defined flags for the block
+ unsigned int Alignment; // power of 2 alignment
+ WCHAR_T Attributes[MAX_ATTR_LEN]; // only used for Region definitions
+ WCHAR_T AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions
+ FLASH_SUBREGION_DESCRIPTION *Subregions;
+ FLASH_SUBREGION_DESCRIPTION *LastSubregion;
+} FLASH_BLOCK_DESCRIPTION;
+
+//
+// Information for each flash device will be saved in one of these
+//
+typedef struct _FLASH_DEVICE_DESCRIPTION {
+ struct _FLASH_DEVICE_DESCRIPTION *Next; // next flash device in our linked list
+ int ErasePolarity; // erase polarity of the flash device
+ unsigned int BaseAddress; // base address of the flash device
+ unsigned int Size; // total size, in bytes, of the flash device
+ WCHAR_T Name[MAX_NAME_LEN]; // name of the flash device
+ FLASH_BLOCK_DESCRIPTION *PBlocks; // linked list of physical block descriptors
+ FLASH_BLOCK_DESCRIPTION *LastPBlock; // last block in the linked list
+ FLASH_BLOCK_DESCRIPTION *Regions; // linked list of flash region descriptors
+ FLASH_BLOCK_DESCRIPTION *LastRegion; // last region in the linked list
+} FLASH_DEVICE_DESCRIPTION;
+
+//
+// For image definitions, they can specify a file name or raw data bytes. Keep a linked list.
+//
+typedef struct _IMAGE_DEFINITION_ENTRY {
+ struct _IMAGE_DEFINITION_ENTRY *Next;
+ WCHAR_T RegionName[MAX_NAME_LEN];
+ WCHAR_T SubregionName[MAX_NAME_LEN];
+ WCHAR_T Name[MAX_NAME_LEN]; // file or data name
+ int IsRawData; // non-zero if raw data bytes
+ unsigned int RawDataSize;
+ char *RawData;
+ int Optional; // optional file (don't include if it doesn't exist)
+} IMAGE_DEFINITION_ENTRY;
+
+//
+// When we parse an image definition, save all the data for each in one of these
+//
+typedef struct _IMAGE_DEFINITION {
+ struct _IMAGE_DEFINITION *Next;
+ WCHAR_T Name[MAX_NAME_LEN];
+ IMAGE_DEFINITION_ENTRY *Entries;
+ IMAGE_DEFINITION_ENTRY *LastEntry;
+} IMAGE_DEFINITION;
+
+typedef struct {
+ char *BufferStart;
+ char *BufferEnd;
+ char *BufferPos;
+} BUFFER_DATA;
+
+static const char *CIncludeHeader = "/*++\n\n"
+" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n""#ifndef _FLASH_MAP_H_\n"
+"#define _FLASH_MAP_H_\n\n";
+//
+// "#include \"EfiFlashMap.h\"\n\n";
+//
+static const char *CIncludeFooter = "#endif // #ifndef _FLASH_MAP_H_\n\n";
+
+static const char *CFlashMapDataFileHeader = "/*++\n\n"
+" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n";
+
+static FLASH_DEVICE_DESCRIPTION *mFlashDevices = NULL;
+static IMAGE_DEFINITION *mImageDefinitions = NULL;
+
+//
+// Local function prototypes
+//
+static
+BUFFER_DATA *
+CreateBufferData (
+ VOID
+ );
+
+static
+BOOLEAN
+AddBufferDataByte (
+ BUFFER_DATA *Buffer,
+ char Data
+ );
+
+static
+void
+FreeBufferData (
+ BUFFER_DATA *Buffer,
+ BOOLEAN FreeData
+ );
+
+static
+char *
+GetBufferData (
+ BUFFER_DATA *Buffer,
+ int *BufferSize
+ );
+
+static
+FLASH_SUBREGION_DESCRIPTION *
+ParseSubregionDefinition (
+ unsigned int SizeLeft
+ );
+
+void
+FDFConstructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Initialization routine for the services that operate on a flash
+ definition file.
+
+Arguments:
+ None.
+
+Returns:
+ NA
+
+--*/
+{
+ mFlashDevices = NULL;
+ mImageDefinitions = NULL;
+}
+
+void
+FDFDestructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Finalization/cleanup routine for the services that operate on a flash
+ definition file.
+
+Arguments:
+ None.
+
+Returns:
+ NA
+
+--*/
+{
+ FLASH_BLOCK_DESCRIPTION *FBNext;
+ FLASH_DEVICE_DESCRIPTION *FDNext;
+ IMAGE_DEFINITION *IDNext;
+ IMAGE_DEFINITION_ENTRY *IDENext;
+ FLASH_SUBREGION_DESCRIPTION *SubNext;
+ //
+ // Go through all our flash devices and free the memory
+ //
+ while (mFlashDevices != NULL) {
+ //
+ // Free the physical block definitions
+ //
+ while (mFlashDevices->PBlocks != NULL) {
+ FBNext = mFlashDevices->PBlocks->Next;
+ _free (mFlashDevices->PBlocks);
+ mFlashDevices->PBlocks = FBNext;
+ }
+ //
+ // Free the region definitions
+ //
+ while (mFlashDevices->Regions != NULL) {
+ FBNext = mFlashDevices->Regions->Next;
+ //
+ // First free the subregion definitions
+ //
+ while (mFlashDevices->Regions->Subregions != NULL) {
+ SubNext = mFlashDevices->Regions->Subregions->Next;
+ _free (mFlashDevices->Regions->Subregions);
+ mFlashDevices->Regions->Subregions = SubNext;
+ }
+
+ _free (mFlashDevices->Regions);
+ mFlashDevices->Regions = FBNext;
+ }
+
+ FDNext = mFlashDevices->Next;
+ _free (mFlashDevices);
+ mFlashDevices = FDNext;
+ }
+ //
+ // Free up the image definitions, and the data
+ //
+ while (mImageDefinitions != NULL) {
+ //
+ // Free the entries
+ //
+ while (mImageDefinitions->Entries != NULL) {
+ IDENext = mImageDefinitions->Entries->Next;
+ if (mImageDefinitions->Entries->RawData != NULL) {
+ _free (mImageDefinitions->Entries->RawData);
+ }
+
+ _free (mImageDefinitions->Entries);
+ mImageDefinitions->Entries = IDENext;
+ }
+
+ IDNext = mImageDefinitions->Next;
+ _free (mImageDefinitions);
+ mImageDefinitions = IDNext;
+ }
+}
+
+STATUS
+FDFParseFile (
+ char *FileName
+ )
+/*++
+
+Routine Description:
+ Parse the specified flash definition file, saving the definitions in
+ file-static variables for use by other functions.
+
+Arguments:
+ FileName - name of the input flash definition text file.
+
+Returns:
+ STATUS_SUCCESS - file parsed with no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered while parsing
+ STATUS_ERROR - errors were encountered while parsing
+
+--*/
+{
+ FILE *Fptr;
+ STATUS Status;
+ unsigned int Num;
+ FLASH_DEVICE_DESCRIPTION *FDDesc;
+ FLASH_BLOCK_DESCRIPTION *FBlockDesc;
+ FLASH_BLOCK_DESCRIPTION *TempBlockDesc;
+ FLASH_SUBREGION_DESCRIPTION *Subregion;
+ FLASH_SUBREGION_DESCRIPTION *TempSubregion;
+ unsigned int BlockSizeLeft;
+ unsigned int RegionSizeLeft;
+ unsigned int SubregionSizeLeft;
+ int ErrorCount;
+ int WarningCount;
+ IMAGE_DEFINITION *ImageDef;
+ IMAGE_DEFINITION_ENTRY *ImageDefEntry;
+ IMAGE_DEFINITION_ENTRY *TempImageDefEntry;
+ BUFFER_DATA *BufferData;
+ char Str[100];
+ BOOLEAN PreviousComma;
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "failed to open input flash definition file for reading");
+ return STATUS_ERROR;
+ }
+
+ fclose (Fptr);
+ Status = STATUS_SUCCESS;
+ ErrorCount = 0;
+ WarningCount = 0;
+ //
+ // Initialize the simple-file-parsing routines
+ //
+ SFPInit ();
+ //
+ // Open the file
+ //
+ if ((Status = SFPOpenFile (FileName)) != STATUS_SUCCESS) {
+ return Status;
+ }
+ //
+ // Parse the file. Should start with a series of these:
+ // FlashDevice {
+ // Name = "FLASH_1234", Size = 0x2004, BaseAddress = 0xFFF0000, ErasePolarity = 1,
+ // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }
+ // Block { Name = "BLOCK2", Size = 0x1004, Flags = 0x0002 }
+ // Region { Name = "REGION_NAME", Size = 0x2004, Align= 4 }
+ // }
+ //
+ while (SFPIsKeyword ("FlashDevice")) {
+ //
+ // Allocate memory for new flash device description block
+ //
+ FDDesc = (FLASH_DEVICE_DESCRIPTION *) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION));
+ if (FDDesc == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (FDDesc, 0, sizeof (FLASH_DEVICE_DESCRIPTION));
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "DeviceName",
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (FDDesc->Name, sizeof (FDDesc->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Size = 0x20000,
+ //
+ if (!SFPIsKeyword ("Size")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FDDesc->Size)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Check for 0 size
+ //
+ if (FDDesc->Size == 0) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc->Name, "Size field cannot be 0", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ SFPIsToken (",");
+ //
+ // Parse: BaseAddress = 0xFFF0000,
+ //
+ if (!SFPIsKeyword ("BaseAddress")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FDDesc->BaseAddress)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: ErasePolarity = 1,
+ //
+ if (!SFPIsKeyword ("ErasePolarity")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&Num) || ((Num != 0) && (Num != 1))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ FDDesc->ErasePolarity = Num;
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse array of:
+ // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }
+ //
+ // Keep track of size to make sure the sum of the physical blocks and region sizes do not
+ // exceed the size of the flash device.
+ //
+ BlockSizeLeft = FDDesc->Size;
+ RegionSizeLeft = FDDesc->Size;
+ while (SFPIsKeyword ("Block")) {
+ //
+ // Allocate memory for a new physical block descriptor
+ //
+ FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));
+ if (FBlockDesc == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "BlockName",
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Make sure there are no other physical block names with this same name
+ //
+ for (TempBlockDesc = FDDesc->PBlocks; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {
+ if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ TempBlockDesc->Name,
+ "physical block with this name already defined"
+ );
+ ErrorCount++;
+ }
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Size = 0x2000,
+ //
+ if (!SFPIsKeyword ("Size")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FBlockDesc->Size)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Make sure the sum of physical blocks so far does not exceed flash device size
+ //
+ if (BlockSizeLeft < FBlockDesc->Size) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ "sum of physical block sizes exceeds flash device size",
+ NULL
+ );
+ ErrorCount++;
+ }
+
+ BlockSizeLeft -= FBlockDesc->Size;
+ SFPIsToken (",");
+ //
+ // Optional parse: Flags = 0xFFF0000,
+ //
+ if (SFPIsKeyword ("Flags")) {
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FBlockDesc->Flags)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ }
+
+ if (!SFPIsToken ("}")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL);
+ WarningCount++;
+ }
+ //
+ // Add the physical block descriptor to the end of the linked list
+ //
+ if (FDDesc->LastPBlock != NULL) {
+ FDDesc->LastPBlock->Next = FBlockDesc;
+ } else {
+ FDDesc->PBlocks = FBlockDesc;
+ }
+
+ FDDesc->LastPBlock = FBlockDesc;
+ }
+ //
+ // Make sure sum of sizes of physical blocks added up to size of flash device
+ //
+ if (BlockSizeLeft != 0) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ NULL,
+ "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",
+ FDDesc->Size - BlockSizeLeft,
+ FDDesc->Size,
+ BlockSizeLeft
+ );
+ ErrorCount++;
+ }
+ //
+ // Parse array of:
+ // Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" }
+ //
+ while (SFPIsKeyword ("Region")) {
+ //
+ // Allocate memory for a new physical block descriptor
+ //
+ FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));
+ if (FBlockDesc == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "BlockName",
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Make sure there are no other region names with this same name
+ //
+ for (TempBlockDesc = FDDesc->Regions; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {
+ if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ TempBlockDesc->Name,
+ "Region with this name already defined"
+ );
+ ErrorCount++;
+ }
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Size = 0x2000,
+ //
+ if (!SFPIsKeyword ("Size")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FBlockDesc->Size)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
+ }
+ //
+ // Make sure the sum of regions so far does not exceed flash device size
+ //
+ if (RegionSizeLeft < FBlockDesc->Size) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL);
+ ErrorCount++;
+ }
+
+ RegionSizeLeft -= FBlockDesc->Size;
+ //
+ // Optional parse: Flags = 0xFFF0000,
+ //
+ if (SFPIsKeyword ("Flags")) {
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FBlockDesc->Flags)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // comma
+ //
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
+ }
+ }
+ //
+ // Optional parse: Alignment = 4
+ //
+ if (SFPIsKeyword ("Alignment")) {
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&FBlockDesc->Alignment)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // comma
+ //
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
+ }
+ }
+ //
+ // Parse: Attributes = "String",
+ //
+ if (!SFPIsKeyword ("Attributes")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (FBlockDesc->Attributes, sizeof (FBlockDesc->Attributes))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
+ }
+ //
+ // Parse: AreaType = "String",
+ //
+ if (!SFPIsKeyword ("AreaType")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (FBlockDesc->AreaType, sizeof (FBlockDesc->AreaType))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ PreviousComma = SFPIsToken (",");
+ //
+ // Parse optional Subregion definitions
+ //
+ SubregionSizeLeft = FBlockDesc->Size;
+ while (SFPIsToken ("Subregion")) {
+ if (!PreviousComma) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL);
+ WarningCount++;
+ PreviousComma = TRUE;
+ }
+
+ Subregion = ParseSubregionDefinition (SubregionSizeLeft);
+ if (Subregion == NULL) {
+ ErrorCount++;
+ goto Done;
+ }
+
+ SubregionSizeLeft -= Subregion->Size;
+ //
+ // Add it to the end of our list
+ //
+ if (FBlockDesc->Subregions == NULL) {
+ FBlockDesc->Subregions = Subregion;
+ } else {
+ FBlockDesc->LastSubregion->Next = Subregion;
+ }
+
+ FBlockDesc->LastSubregion = Subregion;
+ //
+ // Make sure all subregion names are unique. We do this each time
+ // through so that we catch the error immediately after it happens, in
+ // which case the reported line number is at least close to where the
+ // problem lies. We don't exit on the error because we can continue parsing
+ // the script to perhaps catch other errors or warnings.
+ //
+ for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) {
+ if (strcmp (Subregion->Name, TempSubregion->Name) == 0) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name");
+ ErrorCount++;
+ }
+ }
+ }
+ }
+
+ if (!SFPIsToken ("}")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL);
+ WarningCount++;
+ }
+ //
+ // Add the region descriptor to the end of the linked list
+ //
+ if (FDDesc->LastRegion != NULL) {
+ FDDesc->LastRegion->Next = FBlockDesc;
+ } else {
+ FDDesc->Regions = FBlockDesc;
+ }
+
+ FDDesc->LastRegion = FBlockDesc;
+ }
+ //
+ // Make sure sum of sizes of regions adds up to size of flash device
+ //
+ if (RegionSizeLeft != 0) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ NULL,
+ "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",
+ FDDesc->Size - RegionSizeLeft,
+ FDDesc->Size,
+ RegionSizeLeft
+ );
+ ErrorCount++;
+ }
+ //
+ // Look for closing brace
+ //
+ if (!SFPIsToken ("}")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL);
+ WarningCount++;
+ }
+ //
+ // Add this flash description to the list
+ //
+ FDDesc->Next = mFlashDevices;
+ mFlashDevices = FDDesc;
+ }
+
+ while (SFPIsKeyword ("FlashDeviceImage")) {
+ //
+ // Allocate memory for a new FD image definition
+ //
+ ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION));
+ if (ImageDef == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (ImageDef, 0, sizeof (IMAGE_DEFINITION));
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "ImageName",
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL);
+ WarningCount++;
+ }
+
+ while (1) {
+ //
+ // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE }
+ //
+ if (SFPIsKeyword ("File")) {
+ ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));
+ if (ImageDefEntry == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "FileName.txt"
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Region = "REGION_NAME"
+ //
+ if (!SFPIsKeyword ("Region")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse optional: Subregion = "SUBREGION_NAME"
+ //
+ if (SFPIsKeyword ("Subregion")) {
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);
+ WarningCount++;
+ }
+ //
+ // For a given region, you can only place data using the region name, or the subregion names.
+ // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that
+ // here by checking that any previous entries with the same Region name had a Subregion specified
+ // as well.
+ //
+ for (TempImageDefEntry = ImageDef->Entries;
+ TempImageDefEntry != NULL;
+ TempImageDefEntry = TempImageDefEntry->Next
+ ) {
+ if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {
+ if (TempImageDefEntry->SubregionName[0] == 0) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ TempImageDefEntry->RegionName,
+ "data already placed on a region-basis in the region, can't place data using subregions"
+ );
+ ErrorCount++;
+ }
+ }
+ }
+ }
+ //
+ // Optional parse: Optional = TRUE | FALSE
+ //
+ if (SFPIsKeyword ("Optional")) {
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPIsKeyword ("TRUE")) {
+ ImageDefEntry->Optional = 1;
+ } else if (SFPIsKeyword ("FALSE")) {
+ //
+ // Already set to 0
+ //
+ } else {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ SFPIsToken (",");
+ }
+ //
+ // Closing brace
+ //
+ if (!SFPIsToken ("}")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Add the entry to the end of the list
+ //
+ if (ImageDef->LastEntry != NULL) {
+ ImageDef->LastEntry->Next = ImageDefEntry;
+ } else {
+ ImageDef->Entries = ImageDefEntry;
+ }
+
+ ImageDef->LastEntry = ImageDefEntry;
+ } else if (SFPIsKeyword ("RawData")) {
+ //
+ // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }}
+ //
+ ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));
+ if (ImageDefEntry == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));
+ ImageDefEntry->IsRawData = 1;
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ "expected '{' opening brace for RawData definition",
+ NULL
+ );
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "PadBytes"
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Region = "REGION_NAME"
+ //
+ if (!SFPIsKeyword ("Region")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse optional: Subregion = "SUBREGION_NAME"
+ //
+ if (SFPIsKeyword ("Subregion")) {
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);
+ WarningCount++;
+ }
+ //
+ // For a given region, you can only place data using the region name, or the subregion names.
+ // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that
+ // here by checking that any previous entries with the same Region name had a Subregion specified
+ // as well.
+ //
+ for (TempImageDefEntry = ImageDef->Entries;
+ TempImageDefEntry != NULL;
+ TempImageDefEntry = TempImageDefEntry->Next
+ ) {
+ if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {
+ if (TempImageDefEntry->SubregionName[0] == 0) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ TempImageDefEntry->RegionName,
+ "data already placed on a region-basis in the region, can't place data using subregions"
+ );
+ ErrorCount++;
+ }
+ }
+ }
+ }
+ //
+ // Parse: Data = { 0x78, 0x56, 0x34, 0x12 }
+ //
+ if (!SFPIsKeyword ("Data")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL);
+ WarningCount++;
+ }
+
+ if ((BufferData = CreateBufferData ()) == NULL) {
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Read bytes from input file until closing brace
+ //
+ while (!SFPIsToken ("}")) {
+ if (!SFPGetNumber (&Num)) {
+ SFPGetNextToken (Str, sizeof (Str));
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str);
+ ErrorCount++;
+ FreeBufferData (BufferData, TRUE);
+ goto Done;
+ } else {
+ //
+ // Only allow bytes
+ //
+ if (Num > 0xFF) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL);
+ ErrorCount++;
+ FreeBufferData (BufferData, TRUE);
+ goto Done;
+ }
+
+ AddBufferDataByte (BufferData, (char) Num);
+ SFPIsToken (",");
+ }
+ }
+ //
+ // Now get the data and save it in our image entry
+ //
+ ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize);
+ FreeBufferData (BufferData, 0);
+ //
+ // Closing brace for RawData {}
+ //
+ if (!SFPIsToken ("}")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Add the entry to the end of the list
+ //
+ if (ImageDef->LastEntry != NULL) {
+ ImageDef->LastEntry->Next = ImageDefEntry;
+ } else {
+ ImageDef->Entries = ImageDefEntry;
+ }
+
+ ImageDef->LastEntry = ImageDefEntry;
+ } else if (SFPIsToken ("}")) {
+ //
+ // Closing brace for FDImage {}
+ //
+ break;
+ } else {
+ SFPGetNextToken (Str, sizeof (Str));
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str);
+ ErrorCount++;
+ goto Done;
+ }
+ }
+ //
+ // Add this image definition to our global list
+ //
+ ImageDef->Next = mImageDefinitions;
+ mImageDefinitions = ImageDef;
+ }
+ //
+ // Check for end-of-file
+ //
+ if (!SFPIsEOF ()) {
+ SFPGetNextToken (Str, sizeof (Str));
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str);
+ ErrorCount++;
+ }
+
+Done:
+ SFPCloseFile ();
+ if (ErrorCount != 0) {
+ return STATUS_ERROR;
+ } else if (WarningCount != 0) {
+ return STATUS_WARNING;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static
+FLASH_SUBREGION_DESCRIPTION *
+ParseSubregionDefinition (
+ unsigned int SizeLeft
+ )
+/*++
+
+Routine Description:
+
+ Parse Subregion definitions from the input flash definition file. Format:
+
+ Subregion {
+ CreateHob = TRUE,
+ Name = "FOO",
+ Size = 0xA000,
+ Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV",
+ AreaType = "EFI_FLASH_AREA_EFI_VARIABLES",
+ NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"),
+ AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)
+ FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)
+ }
+
+ NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace.
+
+Arguments:
+
+ SizeLeft - in the flash definition file, a Region can be broken up into
+ one or more subregions. As we parse the subregion definitions,
+ the caller keeps track of how much space is left in the region
+ that we're parsing subregions for. SizeLeft is that size, and
+ so the size of the subregion we're now parsing better not
+ exceed the size left.
+ Returns:
+
+ NULL - unrecoverable errors detected while parsing the subregion definition
+
+ pointer to a subregion definition created from the parsed subregion
+
+--*/
+{
+ FLASH_SUBREGION_DESCRIPTION *Subregion;
+ int ErrorCount;
+ int WarningCount;
+ unsigned int Number;
+ BOOLEAN PreviousComma;
+ //
+ // Allocate memory for the new subregion descriptor
+ //
+ ErrorCount = 0;
+ WarningCount = 0;
+ Subregion = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION));
+ if (Subregion == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION));
+ //
+ // Open brace -- warning if not there
+ //
+ if (!SFPIsToken ("{")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: CreateHob = TRUE | FALSE,
+ //
+ if (!SFPIsKeyword ("CreateHob")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (SFPIsToken ("TRUE")) {
+ Subregion->CreateHob = 1;
+ } else if (SFPIsToken ("FALSE")) {
+ //
+ // Subregion->CreateHob = 0; -- not required since we did a memset earlier
+ //
+ } else {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Name = "Name",
+ //
+ if (!SFPIsKeyword ("Name")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
+ WarningCount++;
+ }
+ //
+ // Parse: Size = 0x2000,
+ //
+ if (!SFPIsKeyword ("Size")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPGetNumber (&Subregion->Size)) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ //
+ // Check that the size does not exceed the size left passed in
+ //
+ if (Subregion->Size > SizeLeft) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL);
+ }
+ //
+ // Parse: Attributes = Number | "String",
+ //
+ if (!SFPIsKeyword ("Attributes")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (SFPGetNumber (&Number)) {
+ sprintf (Subregion->Attributes, "0x%X", Number);
+ } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
+ }
+ //
+ // Parse: AreaType = Number | "String",
+ // AreaType is a UINT8, so error if it exceeds the size
+ //
+ if (!SFPIsKeyword ("AreaType")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (SFPGetNumber (&Number)) {
+ if (Number > 0xFF) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL);
+ ErrorCount++;
+ }
+
+ sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF);
+ } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken (",")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL);
+ }
+ //
+ // Parse the three GUIDs (last two are optional)
+ //
+ // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID")
+ // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")
+ // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")
+ //
+ if (!SFPIsKeyword ("NameGuid")) {
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL);
+ ErrorCount++;
+ goto Done;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+ //
+ // Allow a GUID or a quoted string identifier, which we'll just copy as a string
+ //
+ if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) {
+ //
+ // Nothing else to do
+ //
+ } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
+ NULL
+ );
+ ErrorCount++;
+ goto Done;
+ }
+ //
+ // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid
+ //
+ PreviousComma = SFPIsToken (",");
+ if (SFPIsKeyword ("AreaTypeGuid")) {
+ //
+ // Check for preceeding comma now
+ //
+ if (!PreviousComma) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+
+ if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) {
+ //
+ // Nothing else to do
+ //
+ } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
+ NULL
+ );
+ ErrorCount++;
+ goto Done;
+ }
+
+ PreviousComma = SFPIsToken (",");
+ }
+
+ if (SFPIsKeyword ("FileSystemGuid")) {
+ //
+ // Check for preceeding comma now
+ //
+ if (!PreviousComma) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL);
+ WarningCount++;
+ }
+
+ if (!SFPIsToken ("=")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
+ WarningCount++;
+ }
+ //
+ // Allow a GUID or a quoted string identifier, which we'll just copy as a string
+ //
+ if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) {
+ //
+ // Nothing else to do
+ //
+ } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) {
+ Error (
+ SFPGetFileName (),
+ SFPGetLineNumber (),
+ 0,
+ "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
+ NULL
+ );
+ ErrorCount++;
+ goto Done;
+ }
+
+ SFPIsToken (",");
+ }
+ //
+ // Look for subregion closing brace
+ //
+ if (!SFPIsToken ("}")) {
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL);
+ WarningCount++;
+ }
+
+Done:
+ //
+ // If any errors were encountered, then delete the subregion definition
+ //
+ if (ErrorCount != 0) {
+ _free (Subregion);
+ Subregion = NULL;
+ }
+
+ return Subregion;
+}
+
+STATUS
+FDFCreateCIncludeFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+ Create a header file with #define definitions per an already-parsed
+ flash definition file.
+
+Arguments:
+ FlashDeviceName - name of flash device (from the flash definition file)
+ to use
+ FileName - name of output file to create
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ FILE *OutFptr;
+ FLASH_BLOCK_DESCRIPTION *FBlock;
+ FLASH_DEVICE_DESCRIPTION *FDev;
+ FLASH_SUBREGION_DESCRIPTION *Subregion;
+ unsigned int Offset;
+ unsigned int SubregionOffset;
+ int CreateHobs;
+ //
+ // Find the definition we're supposed to use
+ //
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {
+ break;
+ }
+ }
+
+ if (FDev == NULL) {
+ Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");
+ return STATUS_ERROR;
+ }
+
+ if ((OutFptr = fopen (FileName, "w")) == NULL) {
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");
+ return STATUS_ERROR;
+ }
+ //
+ // Write a header
+ //
+ fprintf (OutFptr, CIncludeHeader);
+ //
+ // Write flash block base and size defines
+ //
+ fprintf (OutFptr, "#define FLASH_BASE 0x%08X\n", FDev->BaseAddress);
+ fprintf (OutFptr, "#define FLASH_SIZE 0x%08X\n\n", FDev->Size);
+ //
+ // Write flash regions base, size and offset defines
+ //
+ Offset = 0;
+ CreateHobs = 0;
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
+ fprintf (
+ OutFptr,
+ "#define FLASH_REGION_%s_BASE %*c0x%08X\n",
+ FBlock->Name,
+ COLUMN2_START - 40 - strlen (FBlock->Name),
+ ' ',
+ Offset + FDev->BaseAddress
+ );
+ fprintf (
+ OutFptr,
+ "#define FLASH_REGION_%s_SIZE %*c0x%08X\n",
+ FBlock->Name,
+ COLUMN2_START - 40 - strlen (FBlock->Name),
+ ' ',
+ FBlock->Size
+ );
+ fprintf (
+ OutFptr,
+ "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n",
+ FBlock->Name,
+ COLUMN2_START - 40 - strlen (FBlock->Name),
+ ' ',
+ Offset
+ );
+ //
+ // Create defines for any subregions
+ //
+ SubregionOffset = 0;
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ fprintf (
+ OutFptr,
+ "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ FDev->BaseAddress + Offset + SubregionOffset
+ );
+ fprintf (
+ OutFptr,
+ "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ Subregion->Size
+ );
+ fprintf (
+ OutFptr,
+ "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ Offset + SubregionOffset
+ );
+ SubregionOffset += Subregion->Size;
+ if (Subregion->CreateHob != 0) {
+ CreateHobs = 1;
+ }
+ }
+
+ Offset += FBlock->Size;
+ }
+ //
+ // Now create a #define for the flash map data definition
+ //
+ fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n");
+ //
+ // Emit entry for each region
+ //
+ Offset = 0;
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
+ fprintf (OutFptr, " /* %s region */\\\n", FBlock->Name);
+ fprintf (OutFptr, " {\\\n");
+ fprintf (OutFptr, " FLASH_REGION_%s_BASE,\\\n", FBlock->Name);
+ fprintf (OutFptr, " FLASH_REGION_%s_SIZE,\\\n", FBlock->Name);
+ fprintf (OutFptr, " %s,\\\n", FBlock->Attributes);
+ fprintf (OutFptr, " %s,\\\n },\\\n", FBlock->AreaType);
+ }
+
+ fprintf (OutFptr, "\n\n");
+ //
+ // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition
+ //
+ if (CreateHobs != 0) {
+ fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n");
+ fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION");
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
+ //
+ // See if the block has subregions, and that the CreateHobs flag is set
+ // for any of them.
+ //
+ CreateHobs = 0;
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ if (Subregion->CreateHob != 0) {
+ CreateHobs = 1;
+ break;
+ }
+ }
+ //
+ // If any of the subregions had the CreateHobs flag set, then create the entries in the
+ // output file
+ //
+ if (CreateHobs != 0) {
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ if (Subregion->CreateHob != 0) {
+ fprintf (OutFptr, " \\\n");
+ fprintf (OutFptr, " /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name);
+ fprintf (OutFptr, " {\\\n");
+ fprintf (OutFptr, " EFI_HOB_TYPE_GUID_EXTENSION,\\\n");
+ fprintf (OutFptr, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n");
+ fprintf (OutFptr, " 0,\\\n");
+ //
+ // The NameGuid may have been specified in the input flash definition file as a GUID, or
+ // as a quoted string. Do the right one.
+ //
+ if (Subregion->NameGuidString[0] != 0) {
+ fprintf (OutFptr, " %s, \\\n", Subregion->NameGuidString);
+ } else {
+ fprintf (
+ OutFptr,
+ " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
+ Subregion->NameGuid.Data1,
+ (unsigned int) Subregion->NameGuid.Data2,
+ (unsigned int) Subregion->NameGuid.Data3,
+ (unsigned int) Subregion->NameGuid.Data4[0],
+ (unsigned int) Subregion->NameGuid.Data4[1],
+ (unsigned int) Subregion->NameGuid.Data4[2],
+ (unsigned int) Subregion->NameGuid.Data4[3],
+ (unsigned int) Subregion->NameGuid.Data4[4],
+ (unsigned int) Subregion->NameGuid.Data4[5],
+ (unsigned int) Subregion->NameGuid.Data4[6],
+ (unsigned int) Subregion->NameGuid.Data4[7]
+ );
+ }
+
+ fprintf (OutFptr, " 0, 0, 0,\\\n");
+ fprintf (OutFptr, " %s,\\\n", Subregion->AreaType);
+ //
+ // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or
+ // as a quoted string. Do the right one.
+ //
+ if (Subregion->AreaTypeGuidString[0] != 0) {
+ fprintf (OutFptr, " %s, \\\n", Subregion->AreaTypeGuidString);
+ } else {
+ fprintf (
+ OutFptr,
+ " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
+ Subregion->AreaTypeGuid.Data1,
+ (unsigned int) Subregion->AreaTypeGuid.Data2,
+ (unsigned int) Subregion->AreaTypeGuid.Data3,
+ (unsigned int) Subregion->AreaTypeGuid.Data4[0],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[1],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[2],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[3],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[4],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[5],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[6],
+ (unsigned int) Subregion->AreaTypeGuid.Data4[7]
+ );
+ }
+
+ fprintf (OutFptr, " 1,\\\n");
+ fprintf (OutFptr, " {\\\n");
+ fprintf (OutFptr, " %s,\\\n", Subregion->Attributes);
+ fprintf (OutFptr, " 0,\\\n");
+ fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name);
+ fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name);
+ //
+ // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or
+ // as a quoted string. Do the right one.
+ //
+ if (Subregion->FileSystemGuidString[0] != 0) {
+ fprintf (OutFptr, " %s, \\\n", Subregion->FileSystemGuidString);
+ } else {
+ fprintf (
+ OutFptr,
+ " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
+ Subregion->FileSystemGuid.Data1,
+ (unsigned int) Subregion->FileSystemGuid.Data2,
+ (unsigned int) Subregion->FileSystemGuid.Data3,
+ (unsigned int) Subregion->FileSystemGuid.Data4[0],
+ (unsigned int) Subregion->FileSystemGuid.Data4[1],
+ (unsigned int) Subregion->FileSystemGuid.Data4[2],
+ (unsigned int) Subregion->FileSystemGuid.Data4[3],
+ (unsigned int) Subregion->FileSystemGuid.Data4[4],
+ (unsigned int) Subregion->FileSystemGuid.Data4[5],
+ (unsigned int) Subregion->FileSystemGuid.Data4[6],
+ (unsigned int) Subregion->FileSystemGuid.Data4[7]
+ );
+ }
+
+ fprintf (OutFptr, " },\\\n");
+ fprintf (OutFptr, " },");
+ }
+ }
+ }
+ }
+
+ fprintf (OutFptr, "\n\n");
+ }
+
+ //
+ // Write the file's closing #endif
+ //
+ fprintf (OutFptr, CIncludeFooter);
+ fclose (OutFptr);
+ return STATUS_SUCCESS;
+}
+
+STATUS
+FDFCreateAsmIncludeFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+ Create an assembly header file with equate definitions per an already-parsed
+ flash definition file.
+
+Arguments:
+ FlashDeviceName - name of flash device (from the flash definition file)
+ to use
+ FileName - name of output file to create
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ FILE *OutFptr;
+ FLASH_BLOCK_DESCRIPTION *FBlock;
+ FLASH_DEVICE_DESCRIPTION *FDev;
+ unsigned int Offset;
+ FLASH_SUBREGION_DESCRIPTION *Subregion;
+ unsigned int SubregionOffset;
+ //
+ // Find the definition we're supposed to use
+ //
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {
+ break;
+ }
+ }
+
+ if (FDev == NULL) {
+ Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");
+ return STATUS_ERROR;
+ }
+
+ if ((OutFptr = fopen (FileName, "w")) == NULL) {
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");
+ return STATUS_ERROR;
+ }
+ //
+ // Write a header
+ //
+ fprintf (OutFptr, "\n\n");
+ //
+ // Write flash block size and offset defines
+ //
+ fprintf (
+ OutFptr,
+ "FLASH_BASE %*cequ 0%08Xh\n",
+ COLUMN2_START - 40,
+ ' ',
+ FDev->BaseAddress
+ );
+ fprintf (OutFptr, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size);
+ //
+ // Write flash region size and offset defines
+ //
+ fprintf (OutFptr, "\n");
+ Offset = 0;
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n",
+ FBlock->Name,
+ COLUMN2_START - 20 - strlen (FBlock->Name),
+ ' ',
+ FDev->BaseAddress + Offset
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n",
+ FBlock->Name,
+ COLUMN2_START - 20 - strlen (FBlock->Name),
+ ' ',
+ FBlock->Size
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n",
+ FBlock->Name,
+ COLUMN2_START - 20 - strlen (FBlock->Name),
+ ' ',
+ Offset
+ );
+ //
+ // Create defines for any subregions
+ //
+ SubregionOffset = 0;
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ FDev->BaseAddress + Offset + SubregionOffset
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ Subregion->Size
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ Offset + SubregionOffset
+ );
+ SubregionOffset += Subregion->Size;
+ }
+
+ Offset += FBlock->Size;
+ }
+
+ //
+ // Write closing \n
+ //
+ fprintf (OutFptr, "\n\n");
+ fclose (OutFptr);
+ return STATUS_SUCCESS;
+}
+
+STATUS
+FDFCreateSymbols (
+ char *FlashDeviceName
+ )
+/*++
+
+Routine Description:
+ Using the given flash device name, add symbols to the global symbol table. This
+ allows other functions to use the symbol definitions for other purposes.
+
+Arguments:
+ FlashDeviceName - name of flash device (from the flash definition file)
+ to use
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ FLASH_BLOCK_DESCRIPTION *FBlock;
+ FLASH_DEVICE_DESCRIPTION *FDev;
+ unsigned int Offset;
+ char SymName[120];
+ char SymValue[120];
+ FLASH_SUBREGION_DESCRIPTION *Subregion;
+ unsigned int SubregionOffset;
+ //
+ // Find the definition we're supposed to use
+ //
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {
+ break;
+ }
+ }
+
+ if (FDev == NULL) {
+ Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");
+ return STATUS_ERROR;
+ }
+
+ sprintf (SymValue, "0x%08X", FDev->BaseAddress);
+ SymbolAdd ("FLASH_BASE", SymValue, 0);
+ sprintf (SymValue, "0x%08X", FDev->Size);
+ SymbolAdd ("FLASH_SIZE", SymValue, 0);
+ //
+ // Add flash block size and offset defines
+ //
+ // Offset = 0;
+ // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) {
+ // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name);
+ // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);
+ // SymbolAdd (SymName, SymValue, 0);
+ // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name);
+ // sprintf (SymValue, "0x%08X", FBlock->Size);
+ // SymbolAdd (SymName, SymValue, 0);
+ // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name);
+ // sprintf (SymValue, "0x%08X", Offset);
+ // SymbolAdd (SymName, SymValue, 0);
+ // Offset += FBlock->Size;
+ // }
+ //
+ // Add flash region block base, size, and offset defines
+ //
+ Offset = 0;
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
+ sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name);
+ sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);
+ SymbolAdd (SymName, SymValue, 0);
+ sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name);
+ sprintf (SymValue, "0x%08X", FBlock->Size);
+ SymbolAdd (SymName, SymValue, 0);
+ sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name);
+ sprintf (SymValue, "0x%08X", Offset);
+ SymbolAdd (SymName, SymValue, 0);
+ //
+ // Add subregion symbols
+ //
+ if (FBlock->Subregions != NULL) {
+ SubregionOffset = 0;
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name);
+ sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset);
+ SymbolAdd (SymName, SymValue, 0);
+ sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name);
+ sprintf (SymValue, "0x%08X", Subregion->Size);
+ SymbolAdd (SymName, SymValue, 0);
+ sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name);
+ sprintf (SymValue, "0x%08X", Offset + SubregionOffset);
+ SymbolAdd (SymName, SymValue, 0);
+ SubregionOffset += Subregion->Size;
+ }
+ }
+
+ Offset += FBlock->Size;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+STATUS
+FDFCreateImage (
+ char *FlashDeviceName,
+ char *ImageName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+ Create a flash image using the given device and image names.
+
+Arguments:
+ FlashDeviceName - name of flash device (from the flash definition file)
+ to use
+ ImageName - name of image (from the flash definition file) to create
+ FileName - name of output file to create
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ STATUS Status;
+ FILE *OutFptr;
+ FLASH_BLOCK_DESCRIPTION *RegionDef;
+ FLASH_DEVICE_DESCRIPTION *FDev;
+ IMAGE_DEFINITION *ImageDef;
+ unsigned int Offset;
+ char *Buffer;
+ FILE *InFptr;
+ long FileSize;
+ IMAGE_DEFINITION_ENTRY *IDefEntry;
+ FLASH_SUBREGION_DESCRIPTION *SubregionDef;
+ //
+ // Find the flash definition we're supposed to use
+ //
+ InFptr = NULL;
+ Status = STATUS_ERROR;
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {
+ break;
+ }
+ }
+
+ if (FDev == NULL) {
+ Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");
+ return STATUS_ERROR;
+ }
+ //
+ // Find the image name we're supposed to create
+ //
+ for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) {
+ if (strcmp (ImageDef->Name, ImageName) == 0) {
+ break;
+ }
+ }
+
+ if (ImageDef == NULL) {
+ Error (NULL, 0, 0, ImageName, "image definition not found in image definitions");
+ return STATUS_ERROR;
+ }
+ //
+ // Open the output file
+ //
+ if ((OutFptr = fopen (FileName, "wb")) == NULL) {
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");
+ return STATUS_ERROR;
+ }
+ //
+ // Allocate a buffer to copy the input data to
+ //
+ Buffer = (char *) _malloc (FDev->Size);
+ if (Buffer == NULL) {
+ Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL);
+ goto Done;
+ }
+ //
+ // Set contents of buffer to the erased value
+ //
+ if (FDev->ErasePolarity) {
+ memset (Buffer, 0xFF, FDev->Size);
+ } else {
+ memset (Buffer, 0, FDev->Size);
+ }
+ //
+ // Set all region and subregion size-left fields to the size of the region/subregion
+ //
+ for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {
+ RegionDef->SizeLeft = RegionDef->Size;
+ for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {
+ SubregionDef->SizeLeft = SubregionDef->Size;
+ }
+ }
+ //
+ // Now go through the image list, read files into the buffer.
+ //
+ for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) {
+ //
+ // If it's a file name, open the file, get the size, find the corresponding
+ // flash region it's in, and copy the data.
+ //
+ if (IDefEntry->IsRawData == 0) {
+ if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) {
+ Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading");
+ goto Done;
+ }
+
+ fseek (InFptr, 0, SEEK_END);
+ FileSize = ftell (InFptr);
+ fseek (InFptr, 0, SEEK_SET);
+ } else {
+ FileSize = IDefEntry->RawDataSize;
+ }
+ //
+ // Find the region/subregion it's in, see if we have space left
+ //
+ Offset = 0;
+ for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {
+ if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) {
+ break;
+ }
+
+ Offset += RegionDef->Size;
+ }
+
+ if (RegionDef == NULL) {
+ Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name);
+ goto Done;
+ }
+
+ //
+ // Check for subregion
+ //
+ if (IDefEntry->SubregionName[0] != 0) {
+ for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {
+ if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) {
+ break;
+ }
+
+ Offset += SubregionDef->Size;
+ }
+
+ if (SubregionDef == NULL) {
+ Error (
+ NULL,
+ 0,
+ 0,
+ IDefEntry->SubregionName,
+ "Subregion name not found in FlashDevice %s.%s Region definition",
+ FDev->Name,
+ RegionDef->Name
+ );
+ goto Done;
+ }
+ //
+ // Enough space in the subregion?
+ //
+ if (SubregionDef->SizeLeft < (unsigned int) FileSize) {
+ Error (
+ NULL,
+ 0,
+ 0,
+ IDefEntry->Name,
+ "insufficient space in Subregion (at least 0x%X additional bytes required)",
+ FileSize - SubregionDef->SizeLeft
+ );
+ goto Done;
+ }
+
+ //
+ // Read the file into the buffer if it's a file. Otherwise copy the raw data
+ //
+ if (IDefEntry->IsRawData == 0) {
+ if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) {
+ Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");
+ goto Done;
+ }
+
+ fclose (InFptr);
+ InFptr = NULL;
+ } else {
+ memcpy (
+ Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft),
+ IDefEntry->RawData,
+ IDefEntry->RawDataSize
+ );
+ }
+
+ SubregionDef->SizeLeft -= FileSize;
+ //
+ // Align based on the Region alignment requirements.
+ //
+ if (RegionDef->Alignment != 0) {
+ while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) {
+ if (SubregionDef->SizeLeft == 0) {
+ break;
+ }
+
+ SubregionDef->SizeLeft--;
+ }
+ }
+ } else {
+ //
+ // Placing data in a region. Check for enough space in the region left.
+ //
+ if (RegionDef->SizeLeft < (unsigned int) FileSize) {
+ Error (
+ NULL,
+ 0,
+ 0,
+ IDefEntry->Name,
+ "insufficient space in Region (at least 0x%X additional bytes required)",
+ FileSize - RegionDef->SizeLeft
+ );
+ goto Done;
+ }
+
+ //
+ // Read the file into the buffer if it's a file. Otherwise copy the raw data
+ //
+ if (IDefEntry->IsRawData == 0) {
+ if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) {
+ Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");
+ goto Done;
+ }
+
+ fclose (InFptr);
+ InFptr = NULL;
+ } else {
+ memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize);
+ }
+
+ RegionDef->SizeLeft -= FileSize;
+ //
+ // Align
+ //
+ if (RegionDef->Alignment != 0) {
+ while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) {
+ if (RegionDef->SizeLeft == 0) {
+ break;
+ }
+
+ RegionDef->SizeLeft--;
+ }
+ }
+ }
+ }
+
+ if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) {
+ Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL);
+ goto Done;
+ }
+
+ Status = STATUS_SUCCESS;
+Done:
+ if (InFptr != NULL) {
+ fclose (InFptr);
+ }
+
+ if (Buffer != NULL) {
+ _free (Buffer);
+ }
+
+ if (OutFptr != NULL) {
+ fclose (OutFptr);
+ if (Status == STATUS_ERROR) {
+ remove (FileName);
+ }
+ }
+
+ return Status;
+}
+
+STATUS
+FDFCreateDscFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+ Create a DSC-style output file with equates for flash management.
+
+Arguments:
+ FlashDeviceName - name of flash device (from the flash definition file)
+ to use
+ FileName - name of output file to create
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ FILE *OutFptr;
+ FLASH_BLOCK_DESCRIPTION *FBlock;
+ FLASH_DEVICE_DESCRIPTION *FDev;
+ unsigned int Offset;
+ FLASH_SUBREGION_DESCRIPTION *Subregion;
+ unsigned int SubregionOffset;
+ //
+ // Find the definition we're supposed to use
+ //
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {
+ break;
+ }
+ }
+
+ if (FDev == NULL) {
+ Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");
+ return STATUS_ERROR;
+ }
+
+ if ((OutFptr = fopen (FileName, "w")) == NULL) {
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");
+ return STATUS_ERROR;
+ }
+ //
+ // Write the flash base address and size
+ //
+ fprintf (OutFptr, "\n");
+ fprintf (OutFptr, "FLASH_BASE = 0x%08X\n", FDev->BaseAddress);
+ fprintf (OutFptr, "FLASH_SIZE = 0x%08X\n\n", FDev->Size);
+ //
+ // Write flash block size and offset defines
+ //
+ Offset = 0;
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_BASE %*c= 0x%08X\n",
+ FBlock->Name,
+ COLUMN2_START - 40 - strlen (FBlock->Name),
+ ' ',
+ Offset + FDev->BaseAddress
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SIZE %*c= 0x%08X\n",
+ FBlock->Name,
+ COLUMN2_START - 40 - strlen (FBlock->Name),
+ ' ',
+ FBlock->Size
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n",
+ FBlock->Name,
+ COLUMN2_START - 40 - strlen (FBlock->Name),
+ ' ',
+ (FBlock->Size)/(FDev->PBlocks->Size)
+ );
+ //
+ // Create defines for any subregions
+ //
+ SubregionOffset = 0;
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ FDev->BaseAddress + Offset + SubregionOffset
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ Subregion->Size
+ );
+ fprintf (
+ OutFptr,
+ "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n",
+ FBlock->Name,
+ Subregion->Name,
+ COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),
+ ' ',
+ Offset + SubregionOffset
+ );
+
+ SubregionOffset += Subregion->Size;
+ }
+
+ Offset += FBlock->Size;
+ }
+ //
+ // Close file
+ //
+ fprintf (OutFptr, "\n");
+ fclose (OutFptr);
+ return STATUS_SUCCESS;
+}
+
+
+/*++
+
+Routine Description:
+ The following buffer management routines are used to encapsulate functionality
+ for managing a growable data buffer.
+
+Arguments:
+ BUFFER_DATA - structure that is used to maintain a data buffer
+
+Returns:
+ NA
+
+--*/
+static
+BUFFER_DATA *
+CreateBufferData (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Create a growable data buffer with default buffer length.
+
+Arguments:
+
+ None
+
+Returns:
+
+ NULL - error occured during data buffer creation
+ Not NULL - the pointer to the newly created data buffer
+
+--*/
+{
+ BUFFER_DATA *BD;
+ BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA));
+ if (BD == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ return NULL;
+ }
+
+ memset (BD, 0, sizeof (BUFFER_DATA));
+ BD->BufferStart = (char *) _malloc (BUFFER_SIZE);
+ if (BD->BufferStart == NULL) {
+ _free (BD);
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ return NULL;
+ }
+
+ BD->BufferEnd = BD->BufferStart + BUFFER_SIZE;
+ BD->BufferPos = BD->BufferStart;
+ return BD;
+}
+
+static
+BOOLEAN
+AddBufferDataByte (
+ BUFFER_DATA *Buffer,
+ char Data
+ )
+/*++
+
+Routine Description:
+
+ Add a single byte to a growable data buffer, growing the buffer if required.
+
+Arguments:
+
+ Buffer - pointer to the growable data buffer to add a single byte to
+ Data - value of the single byte data to be added
+
+Returns:
+
+ TRUE - the single byte data was successfully added
+ FALSE - error occurred, the single byte data was not added
+
+--*/
+{
+ int Size;
+ char *NewBuffer;
+ //
+ // See if we have to grow the buffer
+ //
+ if (Buffer->BufferPos >= Buffer->BufferEnd) {
+ Size = (int) Buffer->BufferEnd - (int) Buffer->BufferStart;
+ NewBuffer = (char *) _malloc (Size + BUFFER_SIZE);
+ if (NewBuffer == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
+ return FALSE;
+ }
+
+ memcpy (NewBuffer, Buffer->BufferStart, Size);
+ _free (Buffer->BufferStart);
+ Buffer->BufferStart = NewBuffer;
+ Buffer->BufferPos = Buffer->BufferStart + Size;
+ Buffer->BufferEnd = Buffer->BufferStart + Size + BUFFER_SIZE;
+ }
+
+ *Buffer->BufferPos = Data;
+ Buffer->BufferPos++;
+ return TRUE;
+}
+
+static
+void
+FreeBufferData (
+ BUFFER_DATA *Buffer,
+ BOOLEAN FreeData
+ )
+/*++
+
+Routine Description:
+
+ Free memory used to manage a growable data buffer.
+
+Arguments:
+
+ Buffer - pointer to the growable data buffer to be destructed
+ FreeData - TRUE, free memory containing the buffered data
+ FALSE, do not free the buffered data memory
+
+Returns:
+
+ None
+
+--*/
+{
+ if (Buffer != NULL) {
+ if (FreeData && (Buffer->BufferStart != NULL)) {
+ _free (Buffer->BufferStart);
+ }
+
+ _free (Buffer);
+ }
+}
+
+static
+char *
+GetBufferData (
+ BUFFER_DATA *Buffer,
+ int *BufferSize
+ )
+/*++
+
+Routine Description:
+
+ Return a pointer and size of the data in a growable data buffer.
+
+Arguments:
+
+ Buffer - pointer to the growable data buffer
+ BufferSize - size of the data in the growable data buffer
+
+Returns:
+
+ pointer of the data in the growable data buffer
+
+--*/
+{
+ *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart;
+ return Buffer->BufferStart;
+}
+
+STATUS
+FDDiscover (
+ char *FDFileName,
+ unsigned int BaseAddr
+ )
+/*++
+
+Routine Description:
+ Walk a binary image and see if you find anything that looks like a
+ firmware volume.
+
+Arguments:
+ FDFileName - name of input FD image to parse
+ BaseAddr - base address of input FD image
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_WARNING - warnings, but no errors, were encountered
+ STATUS_ERROR - errors were encountered
+
+NOTE:
+ This routine is used for debug purposes only.
+
+--*/
+{
+ FILE *InFptr;
+ long FileSize;
+ long Offset;
+ EFI_FIRMWARE_VOLUME_HEADER FVHeader;
+ EFI_GUID
+ FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF };
+
+ if ((InFptr = fopen (FDFileName, "rb")) == NULL) {
+ Error (NULL, 0, 0, FDFileName, "failed to open file for reading");
+ return STATUS_ERROR;
+ }
+
+ fseek (InFptr, 0, SEEK_END);
+ FileSize = ftell (InFptr);
+ fseek (InFptr, 0, SEEK_SET);
+ Offset = 0;
+ while (Offset < FileSize) {
+ fseek (InFptr, Offset, SEEK_SET);
+ //
+ // Read the contents of the file, see if it's an FV header
+ //
+ if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) {
+ //
+ // Check version and GUID
+ //
+ if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) {
+ fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength);
+ if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) {
+ fprintf (stdout, "standard FFS file system\n");
+ } else {
+ fprintf (stdout, "non-standard FFS file system\n");
+ }
+ }
+ }
+
+ Offset += 16 * 1024;
+ }
+
+ fclose (InFptr);
+ return STATUS_SUCCESS;
+}
diff --git a/Tools/CodeTools/Source/FlashMap/FlashDefFile.h b/Tools/CodeTools/Source/FlashMap/FlashDefFile.h
new file mode 100644
index 0000000000..0e2ea2c920
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/FlashDefFile.h
@@ -0,0 +1,281 @@
+/*++
+
+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:
+
+ FlashDefFile.h
+
+Abstract:
+
+ Header file for flash management utility in the Intel Platform
+ Innovation Framework for EFI build environment.
+
+--*/
+
+#ifndef _FLASH_DEF_FILE_H_
+#define _FLASH_DEF_FILE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void
+FDFConstructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+void
+FDFDestructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFParseFile (
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFCreateCIncludeFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FlashDeviceName - GC_TODO: add argument description
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFCreateCFlashMapDataFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FlashDeviceName - GC_TODO: add argument description
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFCreateAsmIncludeFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FlashDeviceName - GC_TODO: add argument description
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFParseFile (
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFCreateImage (
+ char *FlashDeviceName,
+ char *ImageName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FlashDeviceName - GC_TODO: add argument description
+ ImageName - GC_TODO: add argument description
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFCreateDscFile (
+ char *FlashDeviceName,
+ char *FileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FlashDeviceName - GC_TODO: add argument description
+ FileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDFCreateSymbols (
+ char *FlashDeviceName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FlashDeviceName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+FDDiscover (
+ char *FDFileName,
+ unsigned int BaseAddr
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ FDFileName - GC_TODO: add argument description
+ BaseAddr - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef _FLASH_DEF_FILE_H_
diff --git a/Tools/CodeTools/Source/FlashMap/FlashMap.c b/Tools/CodeTools/Source/FlashMap/FlashMap.c
new file mode 100644
index 0000000000..88f5003d2d
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/FlashMap.c
@@ -0,0 +1,769 @@
+/*++
+
+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;
+}
+
diff --git a/Tools/CodeTools/Source/FlashMap/Microcode.c b/Tools/CodeTools/Source/FlashMap/Microcode.c
new file mode 100644
index 0000000000..23353254a4
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/Microcode.c
@@ -0,0 +1,304 @@
+/*++
+
+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:
+
+ Microcode.c
+
+Abstract:
+
+ Utility for working with microcode patch files in the Intel
+ Platform Innovation Framework for EFI build environment.
+
+--*/
+
+#include <stdio.h>
+#include <string.h> // for memset()
+#include <ctype.h>
+#include <stdlib.h> // for malloc()
+
+#include "EfiUtilityMsgs.h"
+#include "Microcode.h"
+
+#define MAX_LINE_LEN 256
+
+//
+// Structure definition for a microcode header
+//
+typedef struct {
+ unsigned int HeaderVersion;
+ unsigned int PatchId;
+ unsigned int Date;
+ unsigned int CpuId;
+ unsigned int Checksum;
+ unsigned int LoaderVersion;
+ unsigned int PlatformId;
+ unsigned int DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid
+ unsigned int TotalSize; // number of bytes
+ unsigned int Reserved[3];
+} MICROCODE_IMAGE_HEADER;
+
+static
+STATUS
+MicrocodeReadData (
+ FILE *InFptr,
+ unsigned int *Data
+ );
+
+void
+MicrocodeConstructor (
+ void
+ )
+/*++
+
+Routine Description:
+
+ Constructor of module Microcode
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+}
+
+void
+MicrocodeDestructor (
+ void
+ )
+/*++
+
+Routine Description:
+
+ Destructor of module Microcode
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+}
+
+static
+STATUS
+MicrocodeReadData (
+ FILE *InFptr,
+ unsigned int *Data
+ )
+/*++
+
+Routine Description:
+ Read a 32-bit microcode data value from a text file and convert to raw binary form.
+
+Arguments:
+ InFptr - file pointer to input text file
+ Data - pointer to where to return the data parsed
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings, Data contains valid information
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ char Line[MAX_LINE_LEN];
+ char *cptr;
+
+ Line[MAX_LINE_LEN - 1] = 0;
+ *Data = 0;
+ if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {
+ return STATUS_ERROR;
+ }
+ //
+ // If it was a binary file, then it may have overwritten our null terminator
+ //
+ if (Line[MAX_LINE_LEN - 1] != 0) {
+ return STATUS_ERROR;
+ }
+ //
+ // Look for
+ // dd 000000001h ; comment
+ // dd XXXXXXXX
+ // DD XXXXXXXXX
+ // DD XXXXXXXXX
+ //
+ for (cptr = Line; *cptr && isspace(*cptr); cptr++) {
+ }
+ if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {
+ //
+ // Skip blanks and look for a hex digit
+ //
+ cptr += 3;
+ for (; *cptr && isspace(*cptr); cptr++) {
+ }
+ if (isxdigit (*cptr)) {
+ if (sscanf (cptr, "%X", Data) != 1) {
+ return STATUS_ERROR;
+ }
+ }
+ return STATUS_SUCCESS;
+ }
+ return STATUS_ERROR;
+}
+
+STATUS
+MicrocodeParseFile (
+ char *InFileName,
+ char *OutFileName
+ )
+/*++
+
+Routine Description:
+ Parse a microcode text file, and write the binary results to an output file.
+
+Arguments:
+ InFileName - input text file to parse
+ OutFileName - output file to write raw binary data from parsed input file
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_ERROR - errors were encountered
+
+--*/
+{
+ FILE *InFptr;
+ FILE *OutFptr;
+ STATUS Status;
+ MICROCODE_IMAGE_HEADER *Header;
+ unsigned int Size;
+ unsigned int Size2;
+ unsigned int Data;
+ unsigned int Checksum;
+ char *Buffer;
+ char *Ptr;
+ unsigned int TotalSize;
+
+ Status = STATUS_ERROR;
+ InFptr = NULL;
+ OutFptr = NULL;
+ Buffer = NULL;
+ //
+ // Open the input text file
+ //
+ if ((InFptr = fopen (InFileName, "r")) == NULL) {
+ Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading");
+ return STATUS_ERROR;
+ }
+ //
+ // Make two passes on the input file. The first pass is to determine how
+ // much data is in the file so we can allocate a working buffer. Then
+ // we'll allocate a buffer and re-read the file into the buffer for processing.
+ //
+ Size = 0;
+ do {
+ Status = MicrocodeReadData (InFptr, &Data);
+ if (Status == STATUS_SUCCESS) {
+ Size += sizeof (Data);
+ }
+ } while (Status == STATUS_SUCCESS);
+ //
+ // Error if no data.
+ //
+ if (Size == 0) {
+ Error (NULL, 0, 0, InFileName, "no parse-able data found in file");
+ goto Done;
+ }
+ if (Size < sizeof (MICROCODE_IMAGE_HEADER)) {
+ Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header");
+ goto Done;
+ }
+ //
+ // Allocate a buffer for the data
+ //
+ Buffer = (char *) _malloc (Size);
+ if (Buffer == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ goto Done;
+ }
+ //
+ // Re-read the file, storing the data into our buffer
+ //
+ fseek (InFptr, 0, SEEK_SET);
+ Ptr = Buffer;
+ do {
+ Status = MicrocodeReadData (InFptr, &Data);
+ if (Status == STATUS_SUCCESS) {
+ *(unsigned int *) Ptr = Data;
+ Ptr += sizeof (Data);
+ }
+ } while (Status == STATUS_SUCCESS);
+ //
+ // Can't do much checking on the header because, per the spec, the
+ // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,
+ // and the TotalSize field is invalid (actually missing). Thus we can't
+ // even verify the Reserved fields are 0.
+ //
+ Header = (MICROCODE_IMAGE_HEADER *) Buffer;
+ if (Header->DataSize == 0) {
+ TotalSize = 2048;
+ } else {
+ TotalSize = Header->TotalSize;
+ }
+ if (TotalSize != Size) {
+ Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize);
+ goto Done;
+ }
+ //
+ // Checksum the contents
+ //
+ Ptr = Buffer;
+ Checksum = 0;
+ Size2 = 0;
+ while (Size2 < Size) {
+ Checksum += *(unsigned int *) Ptr;
+ Ptr += 4;
+ Size2 += 4;
+ }
+ if (Checksum != 0) {
+ Error (NULL, 0, 0, InFileName, "checksum failed on file contents");
+ goto Done;
+ }
+ //
+ // Open the output file and write the buffer contents
+ //
+ if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
+ Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing");
+ goto Done;
+ }
+ if (fwrite (Buffer, Size, 1, OutFptr) != 1) {
+ Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file");
+ goto Done;
+ }
+ Status = STATUS_SUCCESS;
+Done:
+ if (Buffer != NULL) {
+ free (Buffer);
+ }
+ if (InFptr != NULL) {
+ fclose (InFptr);
+ }
+ if (OutFptr != NULL) {
+ fclose (OutFptr);
+ if (Status == STATUS_ERROR) {
+ remove (OutFileName);
+ }
+ }
+ return Status;
+}
diff --git a/Tools/CodeTools/Source/FlashMap/Microcode.h b/Tools/CodeTools/Source/FlashMap/Microcode.h
new file mode 100644
index 0000000000..f85313e978
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/Microcode.h
@@ -0,0 +1,87 @@
+/*++
+
+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:
+
+ Microcode.h
+
+Abstract:
+
+ Header file for flash management utility in the Intel Platform
+ Innovation Framework for EFI build environment.
+
+--*/
+
+#ifndef _MICROCODE_H_
+#define _MICROCODE_H_
+
+void
+MicrocodeConstructor (
+ void
+ );
+/*++
+
+Routine Description:
+
+ Constructor of module Microcode
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+
+void
+MicrocodeDestructor (
+ void
+ );
+/*++
+
+Routine Description:
+
+ Destructor of module Microcode
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+
+STATUS
+MicrocodeParseFile (
+ char *InFileName,
+ char *OutFileName
+ );
+/*++
+
+Routine Description:
+ Parse a microcode text file, and write the binary results to an output file.
+
+Arguments:
+ InFileName - input text file to parse
+ OutFileName - output file to write raw binary data from parsed input file
+
+Returns:
+ STATUS_SUCCESS - no errors or warnings
+ STATUS_ERROR - errors were encountered
+
+--*/
+
+
+#endif // #ifndef _MICROCODE_H_
diff --git a/Tools/CodeTools/Source/FlashMap/Symbols.c b/Tools/CodeTools/Source/FlashMap/Symbols.c
new file mode 100644
index 0000000000..8e408144db
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/Symbols.c
@@ -0,0 +1,648 @@
+/*++
+
+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:
+
+ Symbol.c
+
+Abstract:
+
+ Class-like implementation for a symbol table.
+
+--*/
+
+// GC_TODO: fix comment to set correct module name: Symbols.c
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+//
+// for isspace()
+//
+#include <ctype.h>
+
+#include <Common/UefiBaseTypes.h>
+
+#include "CommonLib.h"
+#include "EfiUtilityMsgs.h"
+#include "Symbols.h"
+
+#define MAX_LINE_LEN 512
+
+//
+// Linked list to keep track of all symbols
+//
+typedef struct _SYMBOL {
+ struct _SYMBOL *Next;
+ int Type;
+ char *Name;
+ char *Value;
+} SYMBOL;
+
+static
+SYMBOL *
+FreeSymbols (
+ SYMBOL *Syms
+ );
+
+static
+int
+ExpandMacros (
+ char *SourceLine,
+ char *DestLine,
+ int LineLen
+ );
+
+static SYMBOL *mSymbolTable = NULL;
+
+void
+SymbolsConstructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ SymbolsDestructor ();
+}
+
+void
+SymbolsDestructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ mSymbolTable = FreeSymbols (mSymbolTable);
+}
+
+char *
+GetSymbolValue (
+ char *SymbolName
+ )
+/*++
+
+Routine Description:
+
+ Look up a symbol in our symbol table.
+
+Arguments:
+
+ SymbolName
+
+Returns:
+
+ Pointer to the value of the symbol if found
+ NULL if the symbol is not found
+
+--*/
+// GC_TODO: SymbolName - add argument and description to function comment
+{
+ SYMBOL *Symbol;
+ //
+ // Walk the symbol table
+ //
+ Symbol = mSymbolTable;
+ while (Symbol) {
+ if (stricmp (SymbolName, Symbol->Name) == 0) {
+ return Symbol->Value;
+ }
+
+ Symbol = Symbol->Next;
+ }
+
+ return NULL;
+}
+
+int
+SymbolAdd (
+ char *Name,
+ char *Value,
+ int Mode
+ )
+/*++
+
+Routine Description:
+
+ Add a symbol name/value to the symbol table
+
+Arguments:
+
+ Name - name of symbol to add
+ Value - value of symbol to add
+ Mode - currrently unused
+
+Returns:
+
+ Length of symbol added.
+
+Notes:
+ If Value == NULL, then this routine will assume that the Name field
+ looks something like "MySymName = MySymValue", and will try to parse
+ it that way and add the symbol name/pair from the string.
+
+--*/
+{
+ SYMBOL *Symbol;
+
+ SYMBOL *NewSymbol;
+ int Len;
+ char *Start;
+ char *Cptr;
+ char CSave;
+ char *SaveCptr;
+
+ Len = 0;
+ SaveCptr = NULL;
+ CSave = 0;
+ //
+ // If value pointer is null, then they passed us a line something like:
+ // varname = value, or simply var =
+ //
+ if (Value == NULL) {
+ Start = Name;
+ while (*Name && isspace (*Name)) {
+ Name++;
+ }
+
+ if (Name == NULL) {
+ return -1;
+ }
+ //
+ // Find the end of the name. Either space or a '='.
+ //
+ for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++)
+ ;
+ if (Value == NULL) {
+ return -1;
+ }
+ //
+ // Look for the '='
+ //
+ Cptr = Value;
+ while (*Value && (*Value != '=')) {
+ Value++;
+ }
+
+ if (Value == NULL) {
+ return -1;
+ }
+ //
+ // Now truncate the name
+ //
+ *Cptr = 0;
+ //
+ // 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;
+ SaveCptr = Cptr;
+ *Cptr = 0;
+ Len = (int) (Cptr - Start);
+ }
+ //
+ // We now have a symbol name and a value. Look for an existing variable
+ // and overwrite it.
+ //
+ Symbol = mSymbolTable;
+ while (Symbol) {
+ //
+ // Check for symbol name match
+ //
+ if (stricmp (Name, Symbol->Name) == 0) {
+ _free (Symbol->Value);
+ Symbol->Value = (char *) _malloc (strlen (Value) + 1);
+ if (Symbol->Value == NULL) {
+ Error (NULL, 0, 0, NULL, "failed to allocate memory");
+ return -1;
+ }
+
+ strcpy (Symbol->Value, Value);
+ //
+ // If value == "NULL", then make it a 0-length string
+ //
+ if (stricmp (Symbol->Value, "NULL") == 0) {
+ Symbol->Value[0] = 0;
+ }
+
+ return Len;
+ }
+
+ Symbol = Symbol->Next;
+ }
+ //
+ // Does not exist, create a new one
+ //
+ NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL));
+ if (NewSymbol == NULL) {
+ Error (NULL, 0, 0, NULL, "memory allocation failure");
+ return -1;
+ }
+
+ memset ((char *) NewSymbol, 0, sizeof (SYMBOL));
+ NewSymbol->Name = (char *) _malloc (strlen (Name) + 1);
+ if (NewSymbol->Name == NULL) {
+ Error (NULL, 0, 0, NULL, "memory allocation failure");
+ _free (NewSymbol);
+ return -1;
+ }
+
+ NewSymbol->Value = (char *) _malloc (strlen (Value) + 1);
+ if (NewSymbol->Value == NULL) {
+ Error (NULL, 0, 0, NULL, "memory allocation failure");
+ _free (NewSymbol->Name);
+ _free (NewSymbol);
+ return -1;
+ }
+
+ strcpy (NewSymbol->Name, Name);
+ strcpy (NewSymbol->Value, Value);
+ //
+ // Remove trailing spaces
+ //
+ Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1;
+ while (Cptr > NewSymbol->Value) {
+ if (isspace (*Cptr)) {
+ *Cptr = 0;
+ Cptr--;
+ } else {
+ break;
+ }
+ }
+ //
+ // Add it to the head of the list.
+ //
+ NewSymbol->Next = mSymbolTable;
+ mSymbolTable = NewSymbol;
+ //
+ // If value == "NULL", then make it a 0-length string
+ //
+ if (stricmp (NewSymbol->Value, "NULL") == 0) {
+ NewSymbol->Value[0] = 0;
+ }
+ //
+ // Restore the terminator we inserted if they passed in var=value
+ //
+ if (SaveCptr != NULL) {
+ *SaveCptr = CSave;
+ }
+ _free (NewSymbol->Value);
+ _free (NewSymbol->Name);
+ _free (NewSymbol);
+ return Len;
+}
+
+static
+STATUS
+RemoveSymbol (
+ char *Name,
+ char SymbolType
+ )
+/*++
+
+Routine Description:
+
+ Remove a symbol name/value from the symbol table
+
+Arguments:
+
+ Name - name of symbol to remove
+ SymbolType - type of symbol to remove
+
+Returns:
+
+ STATUS_SUCCESS - matching symbol found and removed
+ STATUS_ERROR - matching symbol not found in symbol table
+
+--*/
+{
+ SYMBOL *Symbol;
+
+ SYMBOL *PrevSymbol;
+
+ PrevSymbol = NULL;
+ Symbol = mSymbolTable;
+ //
+ // Walk the linked list of symbols in the symbol table looking
+ // for a match of both symbol name and type.
+ //
+ while (Symbol) {
+ if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) {
+ //
+ // If the symbol has a value associated with it, free the memory
+ // allocated for the value.
+ // Then free the memory allocated for the symbols string name.
+ //
+ if (Symbol->Value) {
+ _free (Symbol->Value);
+ }
+
+ _free (Symbol->Name);
+ //
+ // Link the previous symbol to the next symbol to effectively
+ // remove this symbol from the linked list.
+ //
+ if (PrevSymbol) {
+ PrevSymbol->Next = Symbol->Next;
+ } else {
+ mSymbolTable = Symbol->Next;
+ }
+
+ _free (Symbol);
+ return STATUS_SUCCESS;
+ }
+
+ PrevSymbol = Symbol;
+ Symbol = Symbol->Next;
+ }
+
+ return STATUS_WARNING;
+}
+
+static
+SYMBOL *
+FreeSymbols (
+ SYMBOL *Syms
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ Syms - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ SYMBOL *Next;
+ while (Syms) {
+ if (Syms->Name != NULL) {
+ _free (Syms->Name);
+ }
+
+ if (Syms->Value != NULL) {
+ _free (Syms->Value);
+ }
+
+ Next = Syms->Next;
+ _free (Syms);
+ Syms = Next;
+ }
+
+ return Syms;
+}
+
+static
+int
+ExpandMacros (
+ char *SourceLine,
+ char *DestLine,
+ int LineLen
+ )
+/*++
+
+Routine Description:
+
+ Given a line of text, replace all variables of format $(NAME) with values
+ from our symbol table.
+
+Arguments:
+
+ SourceLine - input line of text to do symbol replacements on
+ DestLine - on output, SourceLine with symbols replaced
+ LineLen - length of DestLine, so we don't exceed its allocated length
+
+Returns:
+
+ STATUS_SUCCESS - no problems encountered
+ STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine
+ STATUS_ERROR - memory allocation failure
+
+--*/
+{
+ static int NestDepth = 0;
+ char *FromPtr;
+ char *ToPtr;
+ char *SaveStart;
+ char *Cptr;
+ char *value;
+ int Expanded;
+ int ExpandedCount;
+ INT8 *LocalDestLine;
+ STATUS Status;
+ int LocalLineLen;
+
+ NestDepth++;
+ Status = STATUS_SUCCESS;
+ LocalDestLine = (char *) _malloc (LineLen);
+ if (LocalDestLine == NULL) {
+ Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);
+ return STATUS_ERROR;
+ }
+
+ FromPtr = SourceLine;
+ ToPtr = LocalDestLine;
+ //
+ // Walk the entire line, replacing $(MACRO_NAME).
+ //
+ LocalLineLen = LineLen;
+ ExpandedCount = 0;
+ while (*FromPtr && (LocalLineLen > 0)) {
+ if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {
+ //
+ // Save the start in case it's undefined, in which case we copy it as-is.
+ //
+ SaveStart = FromPtr;
+ Expanded = 0;
+ //
+ // Macro expansion time. Find the end (no spaces allowed)
+ //
+ FromPtr += 2;
+ for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++)
+ ;
+ if (*Cptr) {
+ //
+ // Truncate the string at the closing parenthesis for ease-of-use.
+ // Then copy the string directly to the destination line in case we don't find
+ // a definition for it.
+ //
+ *Cptr = 0;
+ strcpy (ToPtr, SaveStart);
+ if ((value = GetSymbolValue (FromPtr)) != NULL) {
+ strcpy (ToPtr, value);
+ LocalLineLen -= strlen (value);
+ ToPtr += strlen (value);
+ Expanded = 1;
+ ExpandedCount++;
+ }
+
+ if (!Expanded) {
+ //
+ // Restore closing parenthesis, and advance to next character
+ //
+ *Cptr = ')';
+ FromPtr = SaveStart + 1;
+ ToPtr++;
+ } else {
+ FromPtr = Cptr + 1;
+ }
+ } else {
+ Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro");
+ strcpy (ToPtr, FromPtr);
+ Status = STATUS_WARNING;
+ goto Done;
+ }
+ } else {
+ *ToPtr = *FromPtr;
+ FromPtr++;
+ ToPtr++;
+ LocalLineLen--;
+ }
+ }
+
+ if (*FromPtr == 0) {
+ *ToPtr = 0;
+ }
+
+ //
+ // If we expanded at least one string successfully, then make a recursive call to try again.
+ //
+ if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) {
+ Status = ExpandMacros (LocalDestLine, DestLine, LineLen);
+ _free (LocalDestLine);
+ NestDepth = 0;
+ return Status;
+ }
+
+Done:
+ if (Status != STATUS_ERROR) {
+ strcpy (DestLine, LocalDestLine);
+ }
+
+ NestDepth = 0;
+ _free (LocalDestLine);
+ return Status;
+}
+
+STATUS
+SymbolsFileStringsReplace (
+ char *InFileName,
+ char *OutFileName
+ )
+/*++
+
+Routine Description:
+
+ Given input and output file names, read in the input file, replace variable
+ references of format $(NAME) with appropriate values from our symbol table,
+ and write the result out to the output file.
+
+Arguments:
+
+ InFileName - name of input text file to replace variable references
+ OutFileName - name of output text file to write results to
+
+Returns:
+
+ STATUS_SUCCESS - no problems encountered
+ STATUS_ERROR - failed to open input or output file
+
+--*/
+{
+ STATUS Status;
+ FILE *InFptr;
+ FILE *OutFptr;
+ char Line[MAX_LINE_LEN];
+ char OutLine[MAX_LINE_LEN];
+
+ Status = STATUS_ERROR;
+ //
+ // Open input and output files
+ //
+ InFptr = NULL;
+ OutFptr = NULL;
+ if ((InFptr = fopen (InFileName, "r")) == NULL) {
+ Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
+ goto Done;
+ }
+
+ if ((OutFptr = fopen (OutFileName, "w")) == NULL) {
+ Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
+ goto Done;
+ }
+ //
+ // Read lines from input file until done
+ //
+ while (fgets (Line, sizeof (Line), InFptr) != NULL) {
+ ExpandMacros (Line, OutLine, sizeof (OutLine));
+ fprintf (OutFptr, OutLine);
+ }
+
+ Status = STATUS_SUCCESS;
+Done:
+ if (InFptr != NULL) {
+ fclose (InFptr);
+ }
+
+ if (OutFptr != NULL) {
+ fclose (OutFptr);
+ }
+
+ return Status;
+}
diff --git a/Tools/CodeTools/Source/FlashMap/Symbols.h b/Tools/CodeTools/Source/FlashMap/Symbols.h
new file mode 100644
index 0000000000..a3cadff268
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/Symbols.h
@@ -0,0 +1,124 @@
+/*++
+
+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:
+
+ Symbols.h
+
+Abstract:
+
+ Defines and prototypes for a class-like symbol table service.
+
+--*/
+
+#ifndef _SYMBOLS_H_
+#define _SYMBOLS_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int
+SymbolAdd (
+ char *Name,
+ char *Value,
+ int Mode
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ Name - GC_TODO: add argument description
+ Value - GC_TODO: add argument description
+ Mode - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATUS
+SymbolsFileStringsReplace (
+ char *InFileName,
+ char *OutFileName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ InFileName - GC_TODO: add argument description
+ OutFileName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+void
+SymbolsConstructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+void
+SymbolsDestructor (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ None
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef _SYMBOLS_H_
diff --git a/Tools/CodeTools/Source/FlashMap/build.xml b/Tools/CodeTools/Source/FlashMap/build.xml
new file mode 100644
index 0000000000..680c1820b0
--- /dev/null
+++ b/Tools/CodeTools/Source/FlashMap/build.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" ?>
+<!--
+Copyright (c) 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.
+-->
+<project default="GenTool" basedir=".">
+<!--
+ EDK FlashMap Tool
+ Copyright (c) 2006, Intel Corporation
+-->
+ <property name="ToolName" value="FlashMap"/>
+ <property name="FileSet" value="*.c"/>
+
+ <taskdef resource="cpptasks.tasks"/>
+ <typedef resource="cpptasks.types"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+
+ <property name="LINK_OUTPUT_TYPE" value="static"/>
+ <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>
+
+ <target name="GenTool" depends="init, Tool">
+ <echo message="The EDK Tool: ${ToolName} build has completed!"/>
+ </target>
+
+ <target name="init">
+ <echo message="Building the EDK Tool: ${ToolName}"/>
+ <mkdir dir="${BUILD_DIR}"/>
+ </target>
+
+ <target name="Tool" depends="init">
+ <cc name="${ToolChain}" objdir="${BUILD_DIR}"
+ outfile="${BIN_DIR}/${ToolName}"
+ outtype="executable"
+ optimize="speed"
+ debug="true">
+ <compilerarg value="${ExtraArgus}" if="ExtraArgus" />
+
+ <defineset>
+ <define name="_malloc" value="malloc"/>
+ <define name="_free" value="free"/>
+ </defineset>
+
+ <fileset dir="${basedir}/${ToolName}"
+ includes="${FileSet}"
+ defaultexcludes="TRUE"
+ excludes="*.xml *.inf"/>
+
+ <includepath path="${PACKAGE_DIR}/Include"/>
+ <includepath path="${PACKAGE_DIR}/Include/${HostArch}"/>
+ <includepath path="${PACKAGE_DIR}/Common"/>
+ <libset dir="${LIB_DIR}" libs="CommonTools"/>
+ </cc>
+ </target>
+
+ <target name="clean">
+ <echo message="Removing Intermediate Files Only"/>
+ <delete>
+ <fileset dir="${BUILD_DIR}" includes="*.obj"/>
+ </delete>
+ </target>
+
+ <target name="cleanall">
+ <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>
+ <delete failonerror="false" quiet="true" includeEmptyDirs="true">
+ <fileset dir="${BUILD_DIR}"/>
+ <fileset file="${BIN_DIR}/${ToolName}${ext_exe}"/>
+ </delete>
+ </target>
+
+</project>