mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-04 05:25:45 +01:00 
			
		
		
		
	2. Removed the unnecessary library and include path from MSA files git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@541 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2790 lines
		
	
	
		
			86 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2790 lines
		
	
	
		
			86 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c)  2004-2005 Intel Corporation. All rights reserved
 | 
						|
This software and associated documentation (if any) is furnished
 | 
						|
under a license and may only be used or copied in accordance
 | 
						|
with the terms of the license. Except as permitted by such
 | 
						|
license, no part of this software or documentation may be
 | 
						|
reproduced, stored in a retrieval system, or transmitted in any
 | 
						|
form or by any means without the express written consent of
 | 
						|
Intel Corporation.
 | 
						|
 | 
						|
 | 
						|
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;
 | 
						|
}
 |