--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
+This program and the accompanying materials are licensed and made available \r
+under the terms and conditions of the BSD License which accompanies this \r
+distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ FlashDefFile.c\r
+\r
+Abstract:\r
+\r
+ Utility for flash management in the Intel Platform Innovation Framework\r
+ for EFI build environment.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+#include <Common/FirmwareVolumeHeader.h>\r
+#include <Common/MultiPhase.h>\r
+\r
+#include "EfiUtilityMsgs.h"\r
+#include "FlashDefFile.h"\r
+#include "SimpleFileParsing.h"\r
+#include "Symbols.h"\r
+\r
+//\r
+// #include "TrackMallocFree.h"\r
+//\r
+#define WCHAR_T char\r
+#define MAX_STRING_LEN 256\r
+#define MAX_NAME_LEN 128\r
+#define BUFFER_SIZE 1024\r
+#define MAX_ATTR_LEN 128\r
+#define MAX_AREATYPE_LEN 128\r
+#define COLUMN2_START 60\r
+#define COLUMN3_START 70\r
+//\r
+// Information for each subregions defined in the fdf file will be saved in these\r
+//\r
+typedef struct _FLASH_SUBREGION_DESCRIPTION {\r
+ struct _FLASH_SUBREGION_DESCRIPTION *Next;\r
+ int CreateHob; // to add to the auto-created HOB array\r
+ WCHAR_T Name[MAX_NAME_LEN]; // each subregion within a region must have a unique name\r
+ unsigned int Size; // size, in bytes, of this subregion\r
+ unsigned int SizeLeft; // used when creating the image\r
+ WCHAR_T Attributes[MAX_ATTR_LEN]; // subregion attributes used in the output HOB\r
+ WCHAR_T AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB\r
+ EFI_GUID NameGuid; // used in the output HOB\r
+ WCHAR_T NameGuidString[MAX_NAME_LEN];\r
+ EFI_GUID AreaTypeGuid; // used in the output HOB\r
+ WCHAR_T AreaTypeGuidString[MAX_NAME_LEN];\r
+ EFI_GUID FileSystemGuid; // used in the output HOB\r
+ WCHAR_T FileSystemGuidString[MAX_NAME_LEN];\r
+} FLASH_SUBREGION_DESCRIPTION;\r
+\r
+//\r
+// Information for each block in a flash device will be saved in one of these.\r
+// We'll also use it for region definitions.\r
+//\r
+typedef struct _FLASH_BLOCK_DESCRIPTION {\r
+ struct _FLASH_BLOCK_DESCRIPTION *Next; // next block in the linked list\r
+ WCHAR_T Name[MAX_NAME_LEN]; // each block must have a unique name\r
+ unsigned int Size; // size, in bytes, of this block\r
+ unsigned int SizeLeft; // for use when creating image\r
+ unsigned int Flags; // user-defined flags for the block\r
+ unsigned int Alignment; // power of 2 alignment\r
+ WCHAR_T Attributes[MAX_ATTR_LEN]; // only used for Region definitions\r
+ WCHAR_T AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions\r
+ FLASH_SUBREGION_DESCRIPTION *Subregions;\r
+ FLASH_SUBREGION_DESCRIPTION *LastSubregion;\r
+} FLASH_BLOCK_DESCRIPTION;\r
+\r
+//\r
+// Information for each flash device will be saved in one of these\r
+//\r
+typedef struct _FLASH_DEVICE_DESCRIPTION {\r
+ struct _FLASH_DEVICE_DESCRIPTION *Next; // next flash device in our linked list\r
+ int ErasePolarity; // erase polarity of the flash device\r
+ unsigned int BaseAddress; // base address of the flash device\r
+ unsigned int Size; // total size, in bytes, of the flash device\r
+ WCHAR_T Name[MAX_NAME_LEN]; // name of the flash device\r
+ FLASH_BLOCK_DESCRIPTION *PBlocks; // linked list of physical block descriptors\r
+ FLASH_BLOCK_DESCRIPTION *LastPBlock; // last block in the linked list\r
+ FLASH_BLOCK_DESCRIPTION *Regions; // linked list of flash region descriptors\r
+ FLASH_BLOCK_DESCRIPTION *LastRegion; // last region in the linked list\r
+} FLASH_DEVICE_DESCRIPTION;\r
+\r
+//\r
+// For image definitions, they can specify a file name or raw data bytes. Keep a linked list.\r
+//\r
+typedef struct _IMAGE_DEFINITION_ENTRY {\r
+ struct _IMAGE_DEFINITION_ENTRY *Next;\r
+ WCHAR_T RegionName[MAX_NAME_LEN];\r
+ WCHAR_T SubregionName[MAX_NAME_LEN];\r
+ WCHAR_T Name[MAX_NAME_LEN]; // file or data name\r
+ int IsRawData; // non-zero if raw data bytes\r
+ unsigned int RawDataSize;\r
+ char *RawData;\r
+ int Optional; // optional file (don't include if it doesn't exist)\r
+} IMAGE_DEFINITION_ENTRY;\r
+\r
+//\r
+// When we parse an image definition, save all the data for each in one of these\r
+//\r
+typedef struct _IMAGE_DEFINITION {\r
+ struct _IMAGE_DEFINITION *Next;\r
+ WCHAR_T Name[MAX_NAME_LEN];\r
+ IMAGE_DEFINITION_ENTRY *Entries;\r
+ IMAGE_DEFINITION_ENTRY *LastEntry;\r
+} IMAGE_DEFINITION;\r
+\r
+typedef struct {\r
+ char *BufferStart;\r
+ char *BufferEnd;\r
+ char *BufferPos;\r
+} BUFFER_DATA;\r
+\r
+static const char *CIncludeHeader = "/*++\n\n"\r
+" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n""#ifndef _FLASH_MAP_H_\n"\r
+"#define _FLASH_MAP_H_\n\n";\r
+//\r
+// "#include \"EfiFlashMap.h\"\n\n";\r
+//\r
+static const char *CIncludeFooter = "#endif // #ifndef _FLASH_MAP_H_\n\n";\r
+\r
+static const char *CFlashMapDataFileHeader = "/*++\n\n"\r
+" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n";\r
+\r
+static FLASH_DEVICE_DESCRIPTION *mFlashDevices = NULL;\r
+static IMAGE_DEFINITION *mImageDefinitions = NULL;\r
+\r
+//\r
+// Local function prototypes\r
+//\r
+static\r
+BUFFER_DATA *\r
+CreateBufferData (\r
+ VOID\r
+ );\r
+\r
+static\r
+BOOLEAN\r
+AddBufferDataByte (\r
+ BUFFER_DATA *Buffer,\r
+ char Data\r
+ );\r
+\r
+static\r
+void\r
+FreeBufferData (\r
+ BUFFER_DATA *Buffer,\r
+ BOOLEAN FreeData\r
+ );\r
+\r
+static\r
+char *\r
+GetBufferData (\r
+ BUFFER_DATA *Buffer,\r
+ int *BufferSize\r
+ );\r
+\r
+static\r
+FLASH_SUBREGION_DESCRIPTION *\r
+ParseSubregionDefinition (\r
+ unsigned int SizeLeft\r
+ );\r
+\r
+void\r
+FDFConstructor (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Initialization routine for the services that operate on a flash\r
+ definition file.\r
+\r
+Arguments:\r
+ None.\r
+\r
+Returns:\r
+ NA\r
+\r
+--*/\r
+{\r
+ mFlashDevices = NULL;\r
+ mImageDefinitions = NULL;\r
+}\r
+\r
+void\r
+FDFDestructor (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Finalization/cleanup routine for the services that operate on a flash\r
+ definition file.\r
+\r
+Arguments:\r
+ None.\r
+\r
+Returns:\r
+ NA\r
+\r
+--*/\r
+{\r
+ FLASH_BLOCK_DESCRIPTION *FBNext;\r
+ FLASH_DEVICE_DESCRIPTION *FDNext;\r
+ IMAGE_DEFINITION *IDNext;\r
+ IMAGE_DEFINITION_ENTRY *IDENext;\r
+ FLASH_SUBREGION_DESCRIPTION *SubNext;\r
+ //\r
+ // Go through all our flash devices and free the memory\r
+ //\r
+ while (mFlashDevices != NULL) {\r
+ //\r
+ // Free the physical block definitions\r
+ //\r
+ while (mFlashDevices->PBlocks != NULL) {\r
+ FBNext = mFlashDevices->PBlocks->Next;\r
+ _free (mFlashDevices->PBlocks);\r
+ mFlashDevices->PBlocks = FBNext;\r
+ }\r
+ //\r
+ // Free the region definitions\r
+ //\r
+ while (mFlashDevices->Regions != NULL) {\r
+ FBNext = mFlashDevices->Regions->Next;\r
+ //\r
+ // First free the subregion definitions\r
+ //\r
+ while (mFlashDevices->Regions->Subregions != NULL) {\r
+ SubNext = mFlashDevices->Regions->Subregions->Next;\r
+ _free (mFlashDevices->Regions->Subregions);\r
+ mFlashDevices->Regions->Subregions = SubNext;\r
+ }\r
+\r
+ _free (mFlashDevices->Regions);\r
+ mFlashDevices->Regions = FBNext;\r
+ }\r
+\r
+ FDNext = mFlashDevices->Next;\r
+ _free (mFlashDevices);\r
+ mFlashDevices = FDNext;\r
+ }\r
+ //\r
+ // Free up the image definitions, and the data\r
+ //\r
+ while (mImageDefinitions != NULL) {\r
+ //\r
+ // Free the entries\r
+ //\r
+ while (mImageDefinitions->Entries != NULL) {\r
+ IDENext = mImageDefinitions->Entries->Next;\r
+ if (mImageDefinitions->Entries->RawData != NULL) {\r
+ _free (mImageDefinitions->Entries->RawData);\r
+ }\r
+\r
+ _free (mImageDefinitions->Entries);\r
+ mImageDefinitions->Entries = IDENext;\r
+ }\r
+\r
+ IDNext = mImageDefinitions->Next;\r
+ _free (mImageDefinitions);\r
+ mImageDefinitions = IDNext;\r
+ }\r
+}\r
+\r
+STATUS\r
+FDFParseFile (\r
+ char *FileName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Parse the specified flash definition file, saving the definitions in\r
+ file-static variables for use by other functions.\r
+ \r
+Arguments:\r
+ FileName - name of the input flash definition text file.\r
+\r
+Returns:\r
+ STATUS_SUCCESS - file parsed with no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered while parsing\r
+ STATUS_ERROR - errors were encountered while parsing\r
+ \r
+--*/\r
+{\r
+ FILE *Fptr;\r
+ STATUS Status;\r
+ unsigned int Num;\r
+ FLASH_DEVICE_DESCRIPTION *FDDesc;\r
+ FLASH_BLOCK_DESCRIPTION *FBlockDesc;\r
+ FLASH_BLOCK_DESCRIPTION *TempBlockDesc;\r
+ FLASH_SUBREGION_DESCRIPTION *Subregion;\r
+ FLASH_SUBREGION_DESCRIPTION *TempSubregion;\r
+ unsigned int BlockSizeLeft;\r
+ unsigned int RegionSizeLeft;\r
+ unsigned int SubregionSizeLeft;\r
+ int ErrorCount;\r
+ int WarningCount;\r
+ IMAGE_DEFINITION *ImageDef;\r
+ IMAGE_DEFINITION_ENTRY *ImageDefEntry;\r
+ IMAGE_DEFINITION_ENTRY *TempImageDefEntry;\r
+ BUFFER_DATA *BufferData;\r
+ char Str[100];\r
+ BOOLEAN PreviousComma;\r
+\r
+ if ((Fptr = fopen (FileName, "r")) == NULL) {\r
+ Error (NULL, 0, 0, FileName, "failed to open input flash definition file for reading");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ fclose (Fptr);\r
+ Status = STATUS_SUCCESS;\r
+ ErrorCount = 0;\r
+ WarningCount = 0;\r
+ //\r
+ // Initialize the simple-file-parsing routines\r
+ //\r
+ SFPInit ();\r
+ //\r
+ // Open the file\r
+ //\r
+ if ((Status = SFPOpenFile (FileName)) != STATUS_SUCCESS) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Parse the file. Should start with a series of these:\r
+ // FlashDevice {\r
+ // Name = "FLASH_1234", Size = 0x2004, BaseAddress = 0xFFF0000, ErasePolarity = 1,\r
+ // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }\r
+ // Block { Name = "BLOCK2", Size = 0x1004, Flags = 0x0002 }\r
+ // Region { Name = "REGION_NAME", Size = 0x2004, Align= 4 }\r
+ // }\r
+ //\r
+ while (SFPIsKeyword ("FlashDevice")) {\r
+ //\r
+ // Allocate memory for new flash device description block\r
+ //\r
+ FDDesc = (FLASH_DEVICE_DESCRIPTION *) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION));\r
+ if (FDDesc == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (FDDesc, 0, sizeof (FLASH_DEVICE_DESCRIPTION));\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "DeviceName",\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (FDDesc->Name, sizeof (FDDesc->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Size = 0x20000,\r
+ //\r
+ if (!SFPIsKeyword ("Size")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FDDesc->Size)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check for 0 size\r
+ //\r
+ if (FDDesc->Size == 0) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc->Name, "Size field cannot be 0", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ SFPIsToken (",");\r
+ //\r
+ // Parse: BaseAddress = 0xFFF0000,\r
+ //\r
+ if (!SFPIsKeyword ("BaseAddress")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FDDesc->BaseAddress)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: ErasePolarity = 1,\r
+ //\r
+ if (!SFPIsKeyword ("ErasePolarity")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&Num) || ((Num != 0) && (Num != 1))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ FDDesc->ErasePolarity = Num;\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse array of:\r
+ // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }\r
+ //\r
+ // Keep track of size to make sure the sum of the physical blocks and region sizes do not\r
+ // exceed the size of the flash device.\r
+ //\r
+ BlockSizeLeft = FDDesc->Size;\r
+ RegionSizeLeft = FDDesc->Size;\r
+ while (SFPIsKeyword ("Block")) {\r
+ //\r
+ // Allocate memory for a new physical block descriptor\r
+ //\r
+ FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));\r
+ if (FBlockDesc == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "BlockName",\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Make sure there are no other physical block names with this same name\r
+ //\r
+ for (TempBlockDesc = FDDesc->PBlocks; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {\r
+ if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ TempBlockDesc->Name,\r
+ "physical block with this name already defined"\r
+ );\r
+ ErrorCount++;\r
+ }\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Size = 0x2000,\r
+ //\r
+ if (!SFPIsKeyword ("Size")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FBlockDesc->Size)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Make sure the sum of physical blocks so far does not exceed flash device size\r
+ //\r
+ if (BlockSizeLeft < FBlockDesc->Size) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ "sum of physical block sizes exceeds flash device size",\r
+ NULL\r
+ );\r
+ ErrorCount++;\r
+ }\r
+\r
+ BlockSizeLeft -= FBlockDesc->Size;\r
+ SFPIsToken (",");\r
+ //\r
+ // Optional parse: Flags = 0xFFF0000,\r
+ //\r
+ if (SFPIsKeyword ("Flags")) {\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FBlockDesc->Flags)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ if (!SFPIsToken ("}")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Add the physical block descriptor to the end of the linked list\r
+ //\r
+ if (FDDesc->LastPBlock != NULL) {\r
+ FDDesc->LastPBlock->Next = FBlockDesc;\r
+ } else {\r
+ FDDesc->PBlocks = FBlockDesc;\r
+ }\r
+\r
+ FDDesc->LastPBlock = FBlockDesc;\r
+ }\r
+ //\r
+ // Make sure sum of sizes of physical blocks added up to size of flash device\r
+ //\r
+ if (BlockSizeLeft != 0) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ NULL,\r
+ "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",\r
+ FDDesc->Size - BlockSizeLeft,\r
+ FDDesc->Size,\r
+ BlockSizeLeft\r
+ );\r
+ ErrorCount++;\r
+ }\r
+ //\r
+ // Parse array of:\r
+ // Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" }\r
+ //\r
+ while (SFPIsKeyword ("Region")) {\r
+ //\r
+ // Allocate memory for a new physical block descriptor\r
+ //\r
+ FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));\r
+ if (FBlockDesc == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "BlockName",\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Make sure there are no other region names with this same name\r
+ //\r
+ for (TempBlockDesc = FDDesc->Regions; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {\r
+ if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ TempBlockDesc->Name,\r
+ "Region with this name already defined"\r
+ );\r
+ ErrorCount++;\r
+ }\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Size = 0x2000,\r
+ //\r
+ if (!SFPIsKeyword ("Size")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FBlockDesc->Size)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);\r
+ }\r
+ //\r
+ // Make sure the sum of regions so far does not exceed flash device size\r
+ //\r
+ if (RegionSizeLeft < FBlockDesc->Size) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL);\r
+ ErrorCount++;\r
+ }\r
+\r
+ RegionSizeLeft -= FBlockDesc->Size;\r
+ //\r
+ // Optional parse: Flags = 0xFFF0000,\r
+ //\r
+ if (SFPIsKeyword ("Flags")) {\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FBlockDesc->Flags)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // comma\r
+ //\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);\r
+ }\r
+ }\r
+ //\r
+ // Optional parse: Alignment = 4\r
+ //\r
+ if (SFPIsKeyword ("Alignment")) {\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&FBlockDesc->Alignment)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // comma\r
+ //\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);\r
+ }\r
+ }\r
+ //\r
+ // Parse: Attributes = "String",\r
+ //\r
+ if (!SFPIsKeyword ("Attributes")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (FBlockDesc->Attributes, sizeof (FBlockDesc->Attributes))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);\r
+ }\r
+ //\r
+ // Parse: AreaType = "String",\r
+ //\r
+ if (!SFPIsKeyword ("AreaType")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (FBlockDesc->AreaType, sizeof (FBlockDesc->AreaType))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ PreviousComma = SFPIsToken (",");\r
+ //\r
+ // Parse optional Subregion definitions\r
+ //\r
+ SubregionSizeLeft = FBlockDesc->Size;\r
+ while (SFPIsToken ("Subregion")) {\r
+ if (!PreviousComma) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL);\r
+ WarningCount++;\r
+ PreviousComma = TRUE;\r
+ }\r
+\r
+ Subregion = ParseSubregionDefinition (SubregionSizeLeft);\r
+ if (Subregion == NULL) {\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ SubregionSizeLeft -= Subregion->Size;\r
+ //\r
+ // Add it to the end of our list\r
+ //\r
+ if (FBlockDesc->Subregions == NULL) {\r
+ FBlockDesc->Subregions = Subregion;\r
+ } else {\r
+ FBlockDesc->LastSubregion->Next = Subregion;\r
+ }\r
+\r
+ FBlockDesc->LastSubregion = Subregion;\r
+ //\r
+ // Make sure all subregion names are unique. We do this each time\r
+ // through so that we catch the error immediately after it happens, in\r
+ // which case the reported line number is at least close to where the\r
+ // problem lies. We don't exit on the error because we can continue parsing\r
+ // the script to perhaps catch other errors or warnings.\r
+ //\r
+ for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) {\r
+ if (strcmp (Subregion->Name, TempSubregion->Name) == 0) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name");\r
+ ErrorCount++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!SFPIsToken ("}")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Add the region descriptor to the end of the linked list\r
+ //\r
+ if (FDDesc->LastRegion != NULL) {\r
+ FDDesc->LastRegion->Next = FBlockDesc;\r
+ } else {\r
+ FDDesc->Regions = FBlockDesc;\r
+ }\r
+\r
+ FDDesc->LastRegion = FBlockDesc;\r
+ }\r
+ //\r
+ // Make sure sum of sizes of regions adds up to size of flash device\r
+ //\r
+ if (RegionSizeLeft != 0) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ NULL,\r
+ "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",\r
+ FDDesc->Size - RegionSizeLeft,\r
+ FDDesc->Size,\r
+ RegionSizeLeft\r
+ );\r
+ ErrorCount++;\r
+ }\r
+ //\r
+ // Look for closing brace\r
+ //\r
+ if (!SFPIsToken ("}")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Add this flash description to the list\r
+ //\r
+ FDDesc->Next = mFlashDevices;\r
+ mFlashDevices = FDDesc;\r
+ }\r
+\r
+ while (SFPIsKeyword ("FlashDeviceImage")) {\r
+ //\r
+ // Allocate memory for a new FD image definition\r
+ //\r
+ ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION));\r
+ if (ImageDef == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (ImageDef, 0, sizeof (IMAGE_DEFINITION));\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "ImageName",\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ while (1) {\r
+ //\r
+ // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE }\r
+ //\r
+ if (SFPIsKeyword ("File")) {\r
+ ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));\r
+ if (ImageDefEntry == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "FileName.txt"\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Region = "REGION_NAME"\r
+ //\r
+ if (!SFPIsKeyword ("Region")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse optional: Subregion = "SUBREGION_NAME"\r
+ //\r
+ if (SFPIsKeyword ("Subregion")) {\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // For a given region, you can only place data using the region name, or the subregion names.\r
+ // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that\r
+ // here by checking that any previous entries with the same Region name had a Subregion specified\r
+ // as well.\r
+ //\r
+ for (TempImageDefEntry = ImageDef->Entries;\r
+ TempImageDefEntry != NULL;\r
+ TempImageDefEntry = TempImageDefEntry->Next\r
+ ) {\r
+ if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {\r
+ if (TempImageDefEntry->SubregionName[0] == 0) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ TempImageDefEntry->RegionName,\r
+ "data already placed on a region-basis in the region, can't place data using subregions"\r
+ );\r
+ ErrorCount++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // Optional parse: Optional = TRUE | FALSE\r
+ //\r
+ if (SFPIsKeyword ("Optional")) {\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPIsKeyword ("TRUE")) {\r
+ ImageDefEntry->Optional = 1;\r
+ } else if (SFPIsKeyword ("FALSE")) {\r
+ //\r
+ // Already set to 0\r
+ //\r
+ } else {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ SFPIsToken (",");\r
+ }\r
+ //\r
+ // Closing brace\r
+ //\r
+ if (!SFPIsToken ("}")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Add the entry to the end of the list\r
+ //\r
+ if (ImageDef->LastEntry != NULL) {\r
+ ImageDef->LastEntry->Next = ImageDefEntry;\r
+ } else {\r
+ ImageDef->Entries = ImageDefEntry;\r
+ }\r
+\r
+ ImageDef->LastEntry = ImageDefEntry;\r
+ } else if (SFPIsKeyword ("RawData")) {\r
+ //\r
+ // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }}\r
+ //\r
+ ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));\r
+ if (ImageDefEntry == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));\r
+ ImageDefEntry->IsRawData = 1;\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ "expected '{' opening brace for RawData definition",\r
+ NULL\r
+ );\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "PadBytes"\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Region = "REGION_NAME"\r
+ //\r
+ if (!SFPIsKeyword ("Region")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse optional: Subregion = "SUBREGION_NAME"\r
+ //\r
+ if (SFPIsKeyword ("Subregion")) {\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // For a given region, you can only place data using the region name, or the subregion names.\r
+ // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that\r
+ // here by checking that any previous entries with the same Region name had a Subregion specified\r
+ // as well.\r
+ //\r
+ for (TempImageDefEntry = ImageDef->Entries;\r
+ TempImageDefEntry != NULL;\r
+ TempImageDefEntry = TempImageDefEntry->Next\r
+ ) {\r
+ if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {\r
+ if (TempImageDefEntry->SubregionName[0] == 0) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ TempImageDefEntry->RegionName,\r
+ "data already placed on a region-basis in the region, can't place data using subregions"\r
+ );\r
+ ErrorCount++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // Parse: Data = { 0x78, 0x56, 0x34, 0x12 }\r
+ //\r
+ if (!SFPIsKeyword ("Data")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if ((BufferData = CreateBufferData ()) == NULL) {\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Read bytes from input file until closing brace\r
+ //\r
+ while (!SFPIsToken ("}")) {\r
+ if (!SFPGetNumber (&Num)) {\r
+ SFPGetNextToken (Str, sizeof (Str));\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str);\r
+ ErrorCount++;\r
+ FreeBufferData (BufferData, TRUE);\r
+ goto Done;\r
+ } else {\r
+ //\r
+ // Only allow bytes\r
+ //\r
+ if (Num > 0xFF) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL);\r
+ ErrorCount++;\r
+ FreeBufferData (BufferData, TRUE);\r
+ goto Done;\r
+ }\r
+\r
+ AddBufferDataByte (BufferData, (char) Num);\r
+ SFPIsToken (",");\r
+ }\r
+ }\r
+ //\r
+ // Now get the data and save it in our image entry\r
+ //\r
+ ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize);\r
+ FreeBufferData (BufferData, 0);\r
+ //\r
+ // Closing brace for RawData {}\r
+ //\r
+ if (!SFPIsToken ("}")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Add the entry to the end of the list\r
+ //\r
+ if (ImageDef->LastEntry != NULL) {\r
+ ImageDef->LastEntry->Next = ImageDefEntry;\r
+ } else {\r
+ ImageDef->Entries = ImageDefEntry;\r
+ }\r
+\r
+ ImageDef->LastEntry = ImageDefEntry;\r
+ } else if (SFPIsToken ("}")) {\r
+ //\r
+ // Closing brace for FDImage {}\r
+ //\r
+ break;\r
+ } else {\r
+ SFPGetNextToken (Str, sizeof (Str));\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ }\r
+ //\r
+ // Add this image definition to our global list\r
+ //\r
+ ImageDef->Next = mImageDefinitions;\r
+ mImageDefinitions = ImageDef;\r
+ }\r
+ //\r
+ // Check for end-of-file\r
+ //\r
+ if (!SFPIsEOF ()) {\r
+ SFPGetNextToken (Str, sizeof (Str));\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str);\r
+ ErrorCount++;\r
+ }\r
+\r
+Done:\r
+ SFPCloseFile ();\r
+ if (ErrorCount != 0) {\r
+ return STATUS_ERROR;\r
+ } else if (WarningCount != 0) {\r
+ return STATUS_WARNING;\r
+ }\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+FLASH_SUBREGION_DESCRIPTION *\r
+ParseSubregionDefinition (\r
+ unsigned int SizeLeft\r
+ )\r
+/*++\r
+ \r
+Routine Description:\r
+\r
+ Parse Subregion definitions from the input flash definition file. Format:\r
+\r
+ Subregion {\r
+ CreateHob = TRUE,\r
+ Name = "FOO",\r
+ Size = 0xA000,\r
+ Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV",\r
+ AreaType = "EFI_FLASH_AREA_EFI_VARIABLES",\r
+ NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"),\r
+ AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)\r
+ FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)\r
+ }\r
+\r
+ NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace.\r
+\r
+Arguments:\r
+ \r
+ SizeLeft - in the flash definition file, a Region can be broken up into\r
+ one or more subregions. As we parse the subregion definitions,\r
+ the caller keeps track of how much space is left in the region\r
+ that we're parsing subregions for. SizeLeft is that size, and\r
+ so the size of the subregion we're now parsing better not\r
+ exceed the size left.\r
+ Returns:\r
+\r
+ NULL - unrecoverable errors detected while parsing the subregion definition\r
+\r
+ pointer to a subregion definition created from the parsed subregion\r
+\r
+--*/\r
+{\r
+ FLASH_SUBREGION_DESCRIPTION *Subregion;\r
+ int ErrorCount;\r
+ int WarningCount;\r
+ unsigned int Number;\r
+ BOOLEAN PreviousComma;\r
+ //\r
+ // Allocate memory for the new subregion descriptor\r
+ //\r
+ ErrorCount = 0;\r
+ WarningCount = 0;\r
+ Subregion = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION));\r
+ if (Subregion == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION));\r
+ //\r
+ // Open brace -- warning if not there\r
+ //\r
+ if (!SFPIsToken ("{")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: CreateHob = TRUE | FALSE,\r
+ //\r
+ if (!SFPIsKeyword ("CreateHob")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (SFPIsToken ("TRUE")) {\r
+ Subregion->CreateHob = 1;\r
+ } else if (SFPIsToken ("FALSE")) {\r
+ //\r
+ // Subregion->CreateHob = 0; -- not required since we did a memset earlier\r
+ //\r
+ } else {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Name = "Name",\r
+ //\r
+ if (!SFPIsKeyword ("Name")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Parse: Size = 0x2000,\r
+ //\r
+ if (!SFPIsKeyword ("Size")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPGetNumber (&Subregion->Size)) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check that the size does not exceed the size left passed in\r
+ //\r
+ if (Subregion->Size > SizeLeft) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL);\r
+ }\r
+ //\r
+ // Parse: Attributes = Number | "String",\r
+ //\r
+ if (!SFPIsKeyword ("Attributes")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (SFPGetNumber (&Number)) {\r
+ sprintf (Subregion->Attributes, "0x%X", Number);\r
+ } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);\r
+ }\r
+ //\r
+ // Parse: AreaType = Number | "String",\r
+ // AreaType is a UINT8, so error if it exceeds the size\r
+ //\r
+ if (!SFPIsKeyword ("AreaType")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (SFPGetNumber (&Number)) {\r
+ if (Number > 0xFF) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL);\r
+ ErrorCount++;\r
+ }\r
+\r
+ sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF);\r
+ } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken (",")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL);\r
+ }\r
+ //\r
+ // Parse the three GUIDs (last two are optional)\r
+ //\r
+ // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID")\r
+ // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")\r
+ // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")\r
+ //\r
+ if (!SFPIsKeyword ("NameGuid")) {\r
+ Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL);\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Allow a GUID or a quoted string identifier, which we'll just copy as a string\r
+ //\r
+ if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) {\r
+ //\r
+ // Nothing else to do\r
+ //\r
+ } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",\r
+ NULL\r
+ );\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid\r
+ //\r
+ PreviousComma = SFPIsToken (",");\r
+ if (SFPIsKeyword ("AreaTypeGuid")) {\r
+ //\r
+ // Check for preceeding comma now\r
+ //\r
+ if (!PreviousComma) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) {\r
+ //\r
+ // Nothing else to do\r
+ //\r
+ } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",\r
+ NULL\r
+ );\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ PreviousComma = SFPIsToken (",");\r
+ }\r
+\r
+ if (SFPIsKeyword ("FileSystemGuid")) {\r
+ //\r
+ // Check for preceeding comma now\r
+ //\r
+ if (!PreviousComma) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+ if (!SFPIsToken ("=")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
+ WarningCount++;\r
+ }\r
+ //\r
+ // Allow a GUID or a quoted string identifier, which we'll just copy as a string\r
+ //\r
+ if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) {\r
+ //\r
+ // Nothing else to do\r
+ //\r
+ } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) {\r
+ Error (\r
+ SFPGetFileName (),\r
+ SFPGetLineNumber (),\r
+ 0,\r
+ "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",\r
+ NULL\r
+ );\r
+ ErrorCount++;\r
+ goto Done;\r
+ }\r
+\r
+ SFPIsToken (",");\r
+ }\r
+ //\r
+ // Look for subregion closing brace\r
+ //\r
+ if (!SFPIsToken ("}")) {\r
+ Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL);\r
+ WarningCount++;\r
+ }\r
+\r
+Done:\r
+ //\r
+ // If any errors were encountered, then delete the subregion definition\r
+ //\r
+ if (ErrorCount != 0) {\r
+ _free (Subregion);\r
+ Subregion = NULL;\r
+ }\r
+\r
+ return Subregion;\r
+}\r
+\r
+STATUS\r
+FDFCreateCIncludeFile (\r
+ char *FlashDeviceName,\r
+ char *FileName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Create a header file with #define definitions per an already-parsed\r
+ flash definition file.\r
+\r
+Arguments:\r
+ FlashDeviceName - name of flash device (from the flash definition file)\r
+ to use\r
+ FileName - name of output file to create\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered\r
+ STATUS_ERROR - errors were encountered\r
+\r
+--*/\r
+{\r
+ FILE *OutFptr;\r
+ FLASH_BLOCK_DESCRIPTION *FBlock;\r
+ FLASH_DEVICE_DESCRIPTION *FDev;\r
+ FLASH_SUBREGION_DESCRIPTION *Subregion;\r
+ unsigned int Offset;\r
+ unsigned int SubregionOffset;\r
+ int CreateHobs;\r
+ //\r
+ // Find the definition we're supposed to use\r
+ //\r
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FDev == NULL) {\r
+ Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ if ((OutFptr = fopen (FileName, "w")) == NULL) {\r
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Write a header\r
+ //\r
+ fprintf (OutFptr, CIncludeHeader);\r
+ //\r
+ // Write flash block base and size defines\r
+ //\r
+ fprintf (OutFptr, "#define FLASH_BASE 0x%08X\n", FDev->BaseAddress);\r
+ fprintf (OutFptr, "#define FLASH_SIZE 0x%08X\n\n", FDev->Size);\r
+ //\r
+ // Write flash regions base, size and offset defines\r
+ //\r
+ Offset = 0;\r
+ CreateHobs = 0;\r
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
+ fprintf (\r
+ OutFptr,\r
+ "#define FLASH_REGION_%s_BASE %*c0x%08X\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 40 - strlen (FBlock->Name),\r
+ ' ',\r
+ Offset + FDev->BaseAddress\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "#define FLASH_REGION_%s_SIZE %*c0x%08X\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 40 - strlen (FBlock->Name),\r
+ ' ',\r
+ FBlock->Size\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 40 - strlen (FBlock->Name),\r
+ ' ',\r
+ Offset\r
+ );\r
+ //\r
+ // Create defines for any subregions\r
+ //\r
+ SubregionOffset = 0;\r
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ fprintf (\r
+ OutFptr,\r
+ "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ FDev->BaseAddress + Offset + SubregionOffset\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ Subregion->Size\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ Offset + SubregionOffset\r
+ );\r
+ SubregionOffset += Subregion->Size;\r
+ if (Subregion->CreateHob != 0) {\r
+ CreateHobs = 1;\r
+ }\r
+ }\r
+\r
+ Offset += FBlock->Size;\r
+ }\r
+ //\r
+ // Now create a #define for the flash map data definition\r
+ //\r
+ fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n");\r
+ //\r
+ // Emit entry for each region\r
+ //\r
+ Offset = 0;\r
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
+ fprintf (OutFptr, " /* %s region */\\\n", FBlock->Name);\r
+ fprintf (OutFptr, " {\\\n");\r
+ fprintf (OutFptr, " FLASH_REGION_%s_BASE,\\\n", FBlock->Name);\r
+ fprintf (OutFptr, " FLASH_REGION_%s_SIZE,\\\n", FBlock->Name);\r
+ fprintf (OutFptr, " %s,\\\n", FBlock->Attributes);\r
+ fprintf (OutFptr, " %s,\\\n },\\\n", FBlock->AreaType);\r
+ }\r
+\r
+ fprintf (OutFptr, "\n\n");\r
+ //\r
+ // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\r
+ //\r
+ if (CreateHobs != 0) {\r
+ fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n");\r
+ fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION");\r
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
+ //\r
+ // See if the block has subregions, and that the CreateHobs flag is set\r
+ // for any of them.\r
+ //\r
+ CreateHobs = 0;\r
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ if (Subregion->CreateHob != 0) {\r
+ CreateHobs = 1;\r
+ break;\r
+ }\r
+ }\r
+ //\r
+ // If any of the subregions had the CreateHobs flag set, then create the entries in the\r
+ // output file\r
+ //\r
+ if (CreateHobs != 0) {\r
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ if (Subregion->CreateHob != 0) {\r
+ fprintf (OutFptr, " \\\n");\r
+ fprintf (OutFptr, " /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name);\r
+ fprintf (OutFptr, " {\\\n");\r
+ fprintf (OutFptr, " EFI_HOB_TYPE_GUID_EXTENSION,\\\n");\r
+ fprintf (OutFptr, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n");\r
+ fprintf (OutFptr, " 0,\\\n");\r
+ //\r
+ // The NameGuid may have been specified in the input flash definition file as a GUID, or\r
+ // as a quoted string. Do the right one.\r
+ //\r
+ if (Subregion->NameGuidString[0] != 0) {\r
+ fprintf (OutFptr, " %s, \\\n", Subregion->NameGuidString);\r
+ } else {\r
+ fprintf (\r
+ OutFptr,\r
+ " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",\r
+ Subregion->NameGuid.Data1,\r
+ (unsigned int) Subregion->NameGuid.Data2,\r
+ (unsigned int) Subregion->NameGuid.Data3,\r
+ (unsigned int) Subregion->NameGuid.Data4[0],\r
+ (unsigned int) Subregion->NameGuid.Data4[1],\r
+ (unsigned int) Subregion->NameGuid.Data4[2],\r
+ (unsigned int) Subregion->NameGuid.Data4[3],\r
+ (unsigned int) Subregion->NameGuid.Data4[4],\r
+ (unsigned int) Subregion->NameGuid.Data4[5],\r
+ (unsigned int) Subregion->NameGuid.Data4[6],\r
+ (unsigned int) Subregion->NameGuid.Data4[7]\r
+ );\r
+ }\r
+\r
+ fprintf (OutFptr, " 0, 0, 0,\\\n");\r
+ fprintf (OutFptr, " %s,\\\n", Subregion->AreaType);\r
+ //\r
+ // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or\r
+ // as a quoted string. Do the right one.\r
+ //\r
+ if (Subregion->AreaTypeGuidString[0] != 0) {\r
+ fprintf (OutFptr, " %s, \\\n", Subregion->AreaTypeGuidString);\r
+ } else {\r
+ fprintf (\r
+ OutFptr,\r
+ " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",\r
+ Subregion->AreaTypeGuid.Data1,\r
+ (unsigned int) Subregion->AreaTypeGuid.Data2,\r
+ (unsigned int) Subregion->AreaTypeGuid.Data3,\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[0],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[1],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[2],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[3],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[4],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[5],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[6],\r
+ (unsigned int) Subregion->AreaTypeGuid.Data4[7]\r
+ );\r
+ }\r
+\r
+ fprintf (OutFptr, " 1,\\\n");\r
+ fprintf (OutFptr, " {\\\n");\r
+ fprintf (OutFptr, " %s,\\\n", Subregion->Attributes);\r
+ fprintf (OutFptr, " 0,\\\n");\r
+ fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name);\r
+ fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name);\r
+ //\r
+ // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or\r
+ // as a quoted string. Do the right one.\r
+ //\r
+ if (Subregion->FileSystemGuidString[0] != 0) {\r
+ fprintf (OutFptr, " %s, \\\n", Subregion->FileSystemGuidString);\r
+ } else {\r
+ fprintf (\r
+ OutFptr,\r
+ " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",\r
+ Subregion->FileSystemGuid.Data1,\r
+ (unsigned int) Subregion->FileSystemGuid.Data2,\r
+ (unsigned int) Subregion->FileSystemGuid.Data3,\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[0],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[1],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[2],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[3],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[4],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[5],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[6],\r
+ (unsigned int) Subregion->FileSystemGuid.Data4[7]\r
+ );\r
+ }\r
+\r
+ fprintf (OutFptr, " },\\\n");\r
+ fprintf (OutFptr, " },");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ fprintf (OutFptr, "\n\n");\r
+ }\r
+\r
+ //\r
+ // Write the file's closing #endif\r
+ //\r
+ fprintf (OutFptr, CIncludeFooter);\r
+ fclose (OutFptr);\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+FDFCreateAsmIncludeFile (\r
+ char *FlashDeviceName,\r
+ char *FileName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Create an assembly header file with equate definitions per an already-parsed\r
+ flash definition file.\r
+\r
+Arguments:\r
+ FlashDeviceName - name of flash device (from the flash definition file)\r
+ to use\r
+ FileName - name of output file to create\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered\r
+ STATUS_ERROR - errors were encountered\r
+\r
+--*/\r
+{\r
+ FILE *OutFptr;\r
+ FLASH_BLOCK_DESCRIPTION *FBlock;\r
+ FLASH_DEVICE_DESCRIPTION *FDev;\r
+ unsigned int Offset;\r
+ FLASH_SUBREGION_DESCRIPTION *Subregion;\r
+ unsigned int SubregionOffset;\r
+ //\r
+ // Find the definition we're supposed to use\r
+ //\r
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FDev == NULL) {\r
+ Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ if ((OutFptr = fopen (FileName, "w")) == NULL) {\r
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Write a header\r
+ //\r
+ fprintf (OutFptr, "\n\n");\r
+ //\r
+ // Write flash block size and offset defines\r
+ //\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_BASE %*cequ 0%08Xh\n",\r
+ COLUMN2_START - 40,\r
+ ' ',\r
+ FDev->BaseAddress\r
+ );\r
+ fprintf (OutFptr, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size);\r
+ //\r
+ // Write flash region size and offset defines\r
+ //\r
+ fprintf (OutFptr, "\n");\r
+ Offset = 0;\r
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 20 - strlen (FBlock->Name),\r
+ ' ',\r
+ FDev->BaseAddress + Offset\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 20 - strlen (FBlock->Name),\r
+ ' ',\r
+ FBlock->Size\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 20 - strlen (FBlock->Name),\r
+ ' ',\r
+ Offset\r
+ );\r
+ //\r
+ // Create defines for any subregions\r
+ //\r
+ SubregionOffset = 0;\r
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ FDev->BaseAddress + Offset + SubregionOffset\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ Subregion->Size\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ Offset + SubregionOffset\r
+ );\r
+ SubregionOffset += Subregion->Size;\r
+ }\r
+\r
+ Offset += FBlock->Size;\r
+ }\r
+\r
+ //\r
+ // Write closing \n\r
+ //\r
+ fprintf (OutFptr, "\n\n");\r
+ fclose (OutFptr);\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+FDFCreateSymbols (\r
+ char *FlashDeviceName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Using the given flash device name, add symbols to the global symbol table. This\r
+ allows other functions to use the symbol definitions for other purposes.\r
+\r
+Arguments:\r
+ FlashDeviceName - name of flash device (from the flash definition file)\r
+ to use\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered\r
+ STATUS_ERROR - errors were encountered\r
+\r
+--*/\r
+{\r
+ FLASH_BLOCK_DESCRIPTION *FBlock;\r
+ FLASH_DEVICE_DESCRIPTION *FDev;\r
+ unsigned int Offset;\r
+ char SymName[120];\r
+ char SymValue[120];\r
+ FLASH_SUBREGION_DESCRIPTION *Subregion;\r
+ unsigned int SubregionOffset;\r
+ //\r
+ // Find the definition we're supposed to use\r
+ //\r
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FDev == NULL) {\r
+ Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ sprintf (SymValue, "0x%08X", FDev->BaseAddress);\r
+ SymbolAdd ("FLASH_BASE", SymValue, 0);\r
+ sprintf (SymValue, "0x%08X", FDev->Size);\r
+ SymbolAdd ("FLASH_SIZE", SymValue, 0);\r
+ //\r
+ // Add flash block size and offset defines\r
+ //\r
+ // Offset = 0;\r
+ // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) {\r
+ // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name);\r
+ // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);\r
+ // SymbolAdd (SymName, SymValue, 0);\r
+ // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name);\r
+ // sprintf (SymValue, "0x%08X", FBlock->Size);\r
+ // SymbolAdd (SymName, SymValue, 0);\r
+ // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name);\r
+ // sprintf (SymValue, "0x%08X", Offset);\r
+ // SymbolAdd (SymName, SymValue, 0);\r
+ // Offset += FBlock->Size;\r
+ // }\r
+ //\r
+ // Add flash region block base, size, and offset defines\r
+ //\r
+ Offset = 0;\r
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
+ sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name);\r
+ sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);\r
+ SymbolAdd (SymName, SymValue, 0);\r
+ sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name);\r
+ sprintf (SymValue, "0x%08X", FBlock->Size);\r
+ SymbolAdd (SymName, SymValue, 0);\r
+ sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name);\r
+ sprintf (SymValue, "0x%08X", Offset);\r
+ SymbolAdd (SymName, SymValue, 0);\r
+ //\r
+ // Add subregion symbols\r
+ //\r
+ if (FBlock->Subregions != NULL) {\r
+ SubregionOffset = 0;\r
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name);\r
+ sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset);\r
+ SymbolAdd (SymName, SymValue, 0);\r
+ sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name);\r
+ sprintf (SymValue, "0x%08X", Subregion->Size);\r
+ SymbolAdd (SymName, SymValue, 0);\r
+ sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name);\r
+ sprintf (SymValue, "0x%08X", Offset + SubregionOffset);\r
+ SymbolAdd (SymName, SymValue, 0);\r
+ SubregionOffset += Subregion->Size;\r
+ }\r
+ }\r
+\r
+ Offset += FBlock->Size;\r
+ }\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+STATUS\r
+FDFCreateImage (\r
+ char *FlashDeviceName,\r
+ char *ImageName,\r
+ char *FileName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Create a flash image using the given device and image names.\r
+\r
+Arguments:\r
+ FlashDeviceName - name of flash device (from the flash definition file)\r
+ to use\r
+ ImageName - name of image (from the flash definition file) to create\r
+ FileName - name of output file to create\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered\r
+ STATUS_ERROR - errors were encountered\r
+\r
+--*/\r
+{\r
+ STATUS Status;\r
+ FILE *OutFptr;\r
+ FLASH_BLOCK_DESCRIPTION *RegionDef;\r
+ FLASH_DEVICE_DESCRIPTION *FDev;\r
+ IMAGE_DEFINITION *ImageDef;\r
+ unsigned int Offset;\r
+ char *Buffer;\r
+ FILE *InFptr;\r
+ long FileSize;\r
+ IMAGE_DEFINITION_ENTRY *IDefEntry;\r
+ FLASH_SUBREGION_DESCRIPTION *SubregionDef;\r
+ //\r
+ // Find the flash definition we're supposed to use\r
+ //\r
+ InFptr = NULL;\r
+ Status = STATUS_ERROR;\r
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FDev == NULL) {\r
+ Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Find the image name we're supposed to create\r
+ //\r
+ for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) {\r
+ if (strcmp (ImageDef->Name, ImageName) == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (ImageDef == NULL) {\r
+ Error (NULL, 0, 0, ImageName, "image definition not found in image definitions");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Open the output file\r
+ //\r
+ if ((OutFptr = fopen (FileName, "wb")) == NULL) {\r
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Allocate a buffer to copy the input data to\r
+ //\r
+ Buffer = (char *) _malloc (FDev->Size);\r
+ if (Buffer == NULL) {\r
+ Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL);\r
+ goto Done;\r
+ }\r
+ //\r
+ // Set contents of buffer to the erased value\r
+ //\r
+ if (FDev->ErasePolarity) {\r
+ memset (Buffer, 0xFF, FDev->Size);\r
+ } else {\r
+ memset (Buffer, 0, FDev->Size);\r
+ }\r
+ //\r
+ // Set all region and subregion size-left fields to the size of the region/subregion\r
+ //\r
+ for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {\r
+ RegionDef->SizeLeft = RegionDef->Size;\r
+ for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {\r
+ SubregionDef->SizeLeft = SubregionDef->Size;\r
+ }\r
+ }\r
+ //\r
+ // Now go through the image list, read files into the buffer.\r
+ //\r
+ for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) {\r
+ //\r
+ // If it's a file name, open the file, get the size, find the corresponding\r
+ // flash region it's in, and copy the data.\r
+ //\r
+ if (IDefEntry->IsRawData == 0) {\r
+ if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) {\r
+ Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading");\r
+ goto Done;\r
+ }\r
+\r
+ fseek (InFptr, 0, SEEK_END);\r
+ FileSize = ftell (InFptr);\r
+ fseek (InFptr, 0, SEEK_SET);\r
+ } else {\r
+ FileSize = IDefEntry->RawDataSize;\r
+ }\r
+ //\r
+ // Find the region/subregion it's in, see if we have space left\r
+ //\r
+ Offset = 0;\r
+ for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {\r
+ if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) {\r
+ break;\r
+ }\r
+\r
+ Offset += RegionDef->Size;\r
+ }\r
+\r
+ if (RegionDef == NULL) {\r
+ Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name);\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check for subregion\r
+ //\r
+ if (IDefEntry->SubregionName[0] != 0) {\r
+ for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {\r
+ if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) {\r
+ break;\r
+ }\r
+\r
+ Offset += SubregionDef->Size;\r
+ }\r
+\r
+ if (SubregionDef == NULL) {\r
+ Error (\r
+ NULL,\r
+ 0,\r
+ 0,\r
+ IDefEntry->SubregionName,\r
+ "Subregion name not found in FlashDevice %s.%s Region definition",\r
+ FDev->Name,\r
+ RegionDef->Name\r
+ );\r
+ goto Done;\r
+ }\r
+ //\r
+ // Enough space in the subregion?\r
+ //\r
+ if (SubregionDef->SizeLeft < (unsigned int) FileSize) {\r
+ Error (\r
+ NULL,\r
+ 0,\r
+ 0,\r
+ IDefEntry->Name,\r
+ "insufficient space in Subregion (at least 0x%X additional bytes required)",\r
+ FileSize - SubregionDef->SizeLeft\r
+ );\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Read the file into the buffer if it's a file. Otherwise copy the raw data\r
+ //\r
+ if (IDefEntry->IsRawData == 0) {\r
+ if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) {\r
+ Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");\r
+ goto Done;\r
+ }\r
+\r
+ fclose (InFptr);\r
+ InFptr = NULL;\r
+ } else {\r
+ memcpy (\r
+ Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft),\r
+ IDefEntry->RawData,\r
+ IDefEntry->RawDataSize\r
+ );\r
+ }\r
+\r
+ SubregionDef->SizeLeft -= FileSize;\r
+ //\r
+ // Align based on the Region alignment requirements.\r
+ //\r
+ if (RegionDef->Alignment != 0) {\r
+ while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) {\r
+ if (SubregionDef->SizeLeft == 0) {\r
+ break;\r
+ }\r
+\r
+ SubregionDef->SizeLeft--;\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // Placing data in a region. Check for enough space in the region left.\r
+ //\r
+ if (RegionDef->SizeLeft < (unsigned int) FileSize) {\r
+ Error (\r
+ NULL,\r
+ 0,\r
+ 0,\r
+ IDefEntry->Name,\r
+ "insufficient space in Region (at least 0x%X additional bytes required)",\r
+ FileSize - RegionDef->SizeLeft\r
+ );\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Read the file into the buffer if it's a file. Otherwise copy the raw data\r
+ //\r
+ if (IDefEntry->IsRawData == 0) {\r
+ if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) {\r
+ Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");\r
+ goto Done;\r
+ }\r
+\r
+ fclose (InFptr);\r
+ InFptr = NULL;\r
+ } else {\r
+ memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize);\r
+ }\r
+\r
+ RegionDef->SizeLeft -= FileSize;\r
+ //\r
+ // Align\r
+ //\r
+ if (RegionDef->Alignment != 0) {\r
+ while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) {\r
+ if (RegionDef->SizeLeft == 0) {\r
+ break;\r
+ }\r
+\r
+ RegionDef->SizeLeft--;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) {\r
+ Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL);\r
+ goto Done;\r
+ }\r
+\r
+ Status = STATUS_SUCCESS;\r
+Done:\r
+ if (InFptr != NULL) {\r
+ fclose (InFptr);\r
+ }\r
+\r
+ if (Buffer != NULL) {\r
+ _free (Buffer);\r
+ }\r
+\r
+ if (OutFptr != NULL) {\r
+ fclose (OutFptr);\r
+ if (Status == STATUS_ERROR) {\r
+ remove (FileName);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+STATUS\r
+FDFCreateDscFile (\r
+ char *FlashDeviceName,\r
+ char *FileName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Create a DSC-style output file with equates for flash management.\r
+\r
+Arguments:\r
+ FlashDeviceName - name of flash device (from the flash definition file)\r
+ to use\r
+ FileName - name of output file to create\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered\r
+ STATUS_ERROR - errors were encountered\r
+\r
+--*/\r
+{\r
+ FILE *OutFptr;\r
+ FLASH_BLOCK_DESCRIPTION *FBlock;\r
+ FLASH_DEVICE_DESCRIPTION *FDev;\r
+ unsigned int Offset;\r
+ FLASH_SUBREGION_DESCRIPTION *Subregion;\r
+ unsigned int SubregionOffset;\r
+ //\r
+ // Find the definition we're supposed to use\r
+ //\r
+ for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
+ if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FDev == NULL) {\r
+ Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ if ((OutFptr = fopen (FileName, "w")) == NULL) {\r
+ Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
+ return STATUS_ERROR;\r
+ }\r
+ //\r
+ // Write the flash base address and size\r
+ //\r
+ fprintf (OutFptr, "\n");\r
+ fprintf (OutFptr, "FLASH_BASE = 0x%08X\n", FDev->BaseAddress);\r
+ fprintf (OutFptr, "FLASH_SIZE = 0x%08X\n\n", FDev->Size);\r
+ //\r
+ // Write flash block size and offset defines\r
+ //\r
+ Offset = 0;\r
+ for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_BASE %*c= 0x%08X\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 40 - strlen (FBlock->Name),\r
+ ' ',\r
+ Offset + FDev->BaseAddress\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SIZE %*c= 0x%08X\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 40 - strlen (FBlock->Name),\r
+ ' ',\r
+ FBlock->Size\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n",\r
+ FBlock->Name,\r
+ COLUMN2_START - 40 - strlen (FBlock->Name),\r
+ ' ',\r
+ (FBlock->Size)/(FDev->PBlocks->Size)\r
+ ); \r
+ //\r
+ // Create defines for any subregions\r
+ //\r
+ SubregionOffset = 0;\r
+ for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ FDev->BaseAddress + Offset + SubregionOffset\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ Subregion->Size\r
+ );\r
+ fprintf (\r
+ OutFptr,\r
+ "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n",\r
+ FBlock->Name,\r
+ Subregion->Name,\r
+ COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
+ ' ',\r
+ Offset + SubregionOffset\r
+ );\r
+\r
+ SubregionOffset += Subregion->Size;\r
+ }\r
+\r
+ Offset += FBlock->Size;\r
+ }\r
+ //\r
+ // Close file\r
+ //\r
+ fprintf (OutFptr, "\n");\r
+ fclose (OutFptr);\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+ The following buffer management routines are used to encapsulate functionality\r
+ for managing a growable data buffer.\r
+\r
+Arguments:\r
+ BUFFER_DATA - structure that is used to maintain a data buffer\r
+\r
+Returns:\r
+ NA\r
+\r
+--*/\r
+static\r
+BUFFER_DATA *\r
+CreateBufferData (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create a growable data buffer with default buffer length.\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ NULL - error occured during data buffer creation\r
+ Not NULL - the pointer to the newly created data buffer\r
+\r
+--*/\r
+{\r
+ BUFFER_DATA *BD;\r
+ BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA));\r
+ if (BD == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ return NULL;\r
+ }\r
+\r
+ memset (BD, 0, sizeof (BUFFER_DATA));\r
+ BD->BufferStart = (char *) _malloc (BUFFER_SIZE);\r
+ if (BD->BufferStart == NULL) {\r
+ _free (BD);\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ return NULL;\r
+ }\r
+\r
+ BD->BufferEnd = BD->BufferStart + BUFFER_SIZE;\r
+ BD->BufferPos = BD->BufferStart;\r
+ return BD;\r
+}\r
+\r
+static\r
+BOOLEAN\r
+AddBufferDataByte (\r
+ BUFFER_DATA *Buffer,\r
+ char Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Add a single byte to a growable data buffer, growing the buffer if required.\r
+\r
+Arguments:\r
+\r
+ Buffer - pointer to the growable data buffer to add a single byte to\r
+ Data - value of the single byte data to be added\r
+\r
+Returns:\r
+\r
+ TRUE - the single byte data was successfully added\r
+ FALSE - error occurred, the single byte data was not added\r
+\r
+--*/\r
+{\r
+ int Size;\r
+ char *NewBuffer;\r
+ //\r
+ // See if we have to grow the buffer\r
+ //\r
+ if (Buffer->BufferPos >= Buffer->BufferEnd) {\r
+ Size = (int) Buffer->BufferEnd - (int) Buffer->BufferStart;\r
+ NewBuffer = (char *) _malloc (Size + BUFFER_SIZE);\r
+ if (NewBuffer == NULL) {\r
+ Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
+ return FALSE;\r
+ }\r
+\r
+ memcpy (NewBuffer, Buffer->BufferStart, Size);\r
+ _free (Buffer->BufferStart);\r
+ Buffer->BufferStart = NewBuffer;\r
+ Buffer->BufferPos = Buffer->BufferStart + Size;\r
+ Buffer->BufferEnd = Buffer->BufferStart + Size + BUFFER_SIZE;\r
+ }\r
+\r
+ *Buffer->BufferPos = Data;\r
+ Buffer->BufferPos++;\r
+ return TRUE;\r
+}\r
+\r
+static\r
+void\r
+FreeBufferData (\r
+ BUFFER_DATA *Buffer,\r
+ BOOLEAN FreeData\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free memory used to manage a growable data buffer.\r
+\r
+Arguments:\r
+\r
+ Buffer - pointer to the growable data buffer to be destructed\r
+ FreeData - TRUE, free memory containing the buffered data\r
+ FALSE, do not free the buffered data memory\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ if (Buffer != NULL) {\r
+ if (FreeData && (Buffer->BufferStart != NULL)) {\r
+ _free (Buffer->BufferStart);\r
+ }\r
+\r
+ _free (Buffer);\r
+ }\r
+}\r
+\r
+static\r
+char *\r
+GetBufferData (\r
+ BUFFER_DATA *Buffer,\r
+ int *BufferSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Return a pointer and size of the data in a growable data buffer.\r
+\r
+Arguments:\r
+\r
+ Buffer - pointer to the growable data buffer\r
+ BufferSize - size of the data in the growable data buffer\r
+\r
+Returns:\r
+\r
+ pointer of the data in the growable data buffer\r
+\r
+--*/\r
+{\r
+ *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart;\r
+ return Buffer->BufferStart;\r
+}\r
+\r
+STATUS\r
+FDDiscover (\r
+ char *FDFileName,\r
+ unsigned int BaseAddr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Walk a binary image and see if you find anything that looks like a\r
+ firmware volume.\r
+\r
+Arguments:\r
+ FDFileName - name of input FD image to parse\r
+ BaseAddr - base address of input FD image\r
+\r
+Returns:\r
+ STATUS_SUCCESS - no errors or warnings\r
+ STATUS_WARNING - warnings, but no errors, were encountered\r
+ STATUS_ERROR - errors were encountered\r
+\r
+NOTE:\r
+ This routine is used for debug purposes only.\r
+\r
+--*/\r
+{\r
+ FILE *InFptr;\r
+ long FileSize;\r
+ long Offset;\r
+ EFI_FIRMWARE_VOLUME_HEADER FVHeader;\r
+ EFI_GUID\r
+ FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF };\r
+\r
+ if ((InFptr = fopen (FDFileName, "rb")) == NULL) {\r
+ Error (NULL, 0, 0, FDFileName, "failed to open file for reading");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ fseek (InFptr, 0, SEEK_END);\r
+ FileSize = ftell (InFptr);\r
+ fseek (InFptr, 0, SEEK_SET);\r
+ Offset = 0;\r
+ while (Offset < FileSize) {\r
+ fseek (InFptr, Offset, SEEK_SET);\r
+ //\r
+ // Read the contents of the file, see if it's an FV header\r
+ //\r
+ if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) {\r
+ //\r
+ // Check version and GUID\r
+ //\r
+ if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) {\r
+ fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength);\r
+ if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) {\r
+ fprintf (stdout, "standard FFS file system\n");\r
+ } else {\r
+ fprintf (stdout, "non-standard FFS file system\n");\r
+ }\r
+ }\r
+ }\r
+\r
+ Offset += 16 * 1024;\r
+ }\r
+\r
+ fclose (InFptr);\r
+ return STATUS_SUCCESS;\r
+}\r