3 Copyright (c) 2004-2006 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Utility for flash management in the Intel Platform Innovation Framework
19 for EFI build environment.
27 #include <Common/UefiBaseTypes.h>
28 #include <Common/FirmwareVolumeHeader.h>
29 #include <Common/MultiPhase.h>
31 #include "EfiUtilityMsgs.h"
32 #include "FlashDefFile.h"
33 #include "SimpleFileParsing.h"
37 // #include "TrackMallocFree.h"
40 #define MAX_STRING_LEN 256
41 #define MAX_NAME_LEN 128
42 #define BUFFER_SIZE 1024
43 #define MAX_ATTR_LEN 128
44 #define MAX_AREATYPE_LEN 128
45 #define COLUMN2_START 60
46 #define COLUMN3_START 70
48 // Information for each subregions defined in the fdf file will be saved in these
50 typedef struct _FLASH_SUBREGION_DESCRIPTION
{
51 struct _FLASH_SUBREGION_DESCRIPTION
*Next
;
52 int CreateHob
; // to add to the auto-created HOB array
53 WCHAR_T Name
[MAX_NAME_LEN
]; // each subregion within a region must have a unique name
54 unsigned int Size
; // size, in bytes, of this subregion
55 unsigned int SizeLeft
; // used when creating the image
56 WCHAR_T Attributes
[MAX_ATTR_LEN
]; // subregion attributes used in the output HOB
57 WCHAR_T AreaType
[MAX_AREATYPE_LEN
]; // subregion area type used in the output HOB
58 EFI_GUID NameGuid
; // used in the output HOB
59 WCHAR_T NameGuidString
[MAX_NAME_LEN
];
60 EFI_GUID AreaTypeGuid
; // used in the output HOB
61 WCHAR_T AreaTypeGuidString
[MAX_NAME_LEN
];
62 EFI_GUID FileSystemGuid
; // used in the output HOB
63 WCHAR_T FileSystemGuidString
[MAX_NAME_LEN
];
64 } FLASH_SUBREGION_DESCRIPTION
;
67 // Information for each block in a flash device will be saved in one of these.
68 // We'll also use it for region definitions.
70 typedef struct _FLASH_BLOCK_DESCRIPTION
{
71 struct _FLASH_BLOCK_DESCRIPTION
*Next
; // next block in the linked list
72 WCHAR_T Name
[MAX_NAME_LEN
]; // each block must have a unique name
73 unsigned int Size
; // size, in bytes, of this block
74 unsigned int SizeLeft
; // for use when creating image
75 unsigned int Flags
; // user-defined flags for the block
76 unsigned int Alignment
; // power of 2 alignment
77 WCHAR_T Attributes
[MAX_ATTR_LEN
]; // only used for Region definitions
78 WCHAR_T AreaType
[MAX_AREATYPE_LEN
]; // only used for Region definitions
79 EFI_GUID AreaTypeGuid
;
80 WCHAR_T AreaTypeGuidString
[MAX_NAME_LEN
];
81 FLASH_SUBREGION_DESCRIPTION
*Subregions
;
82 FLASH_SUBREGION_DESCRIPTION
*LastSubregion
;
83 } FLASH_BLOCK_DESCRIPTION
;
86 // Information for each flash device will be saved in one of these
88 typedef struct _FLASH_DEVICE_DESCRIPTION
{
89 struct _FLASH_DEVICE_DESCRIPTION
*Next
; // next flash device in our linked list
90 int ErasePolarity
; // erase polarity of the flash device
91 unsigned int BaseAddress
; // base address of the flash device
92 unsigned int Size
; // total size, in bytes, of the flash device
93 WCHAR_T Name
[MAX_NAME_LEN
]; // name of the flash device
94 FLASH_BLOCK_DESCRIPTION
*PBlocks
; // linked list of physical block descriptors
95 FLASH_BLOCK_DESCRIPTION
*LastPBlock
; // last block in the linked list
96 FLASH_BLOCK_DESCRIPTION
*Regions
; // linked list of flash region descriptors
97 FLASH_BLOCK_DESCRIPTION
*LastRegion
; // last region in the linked list
98 } FLASH_DEVICE_DESCRIPTION
;
101 // For image definitions, they can specify a file name or raw data bytes. Keep a linked list.
103 typedef struct _IMAGE_DEFINITION_ENTRY
{
104 struct _IMAGE_DEFINITION_ENTRY
*Next
;
105 WCHAR_T RegionName
[MAX_NAME_LEN
];
106 WCHAR_T SubregionName
[MAX_NAME_LEN
];
107 WCHAR_T Name
[MAX_NAME_LEN
]; // file or data name
108 int IsRawData
; // non-zero if raw data bytes
109 unsigned int RawDataSize
;
111 int Optional
; // optional file (don't include if it doesn't exist)
112 } IMAGE_DEFINITION_ENTRY
;
115 // When we parse an image definition, save all the data for each in one of these
117 typedef struct _IMAGE_DEFINITION
{
118 struct _IMAGE_DEFINITION
*Next
;
119 WCHAR_T Name
[MAX_NAME_LEN
];
120 IMAGE_DEFINITION_ENTRY
*Entries
;
121 IMAGE_DEFINITION_ENTRY
*LastEntry
;
130 static const char *CIncludeHeader
= "/*++\n\n"
131 " DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n""#ifndef _FLASH_MAP_H_\n"
132 "#define _FLASH_MAP_H_\n\n";
134 // "#include \"EfiFlashMap.h\"\n\n";
136 static const char *CIncludeFooter
= "#endif // #ifndef _FLASH_MAP_H_\n\n";
138 static const char *CFlashMapDataFileHeader
= "/*++\n\n"
139 " DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n";
141 static FLASH_DEVICE_DESCRIPTION
*mFlashDevices
= NULL
;
142 static IMAGE_DEFINITION
*mImageDefinitions
= NULL
;
145 // Local function prototypes
175 FLASH_SUBREGION_DESCRIPTION
*
176 ParseSubregionDefinition (
177 unsigned int SizeLeft
187 Initialization routine for the services that operate on a flash
198 mFlashDevices
= NULL
;
199 mImageDefinitions
= NULL
;
209 Finalization/cleanup routine for the services that operate on a flash
220 FLASH_BLOCK_DESCRIPTION
*FBNext
;
221 FLASH_DEVICE_DESCRIPTION
*FDNext
;
222 IMAGE_DEFINITION
*IDNext
;
223 IMAGE_DEFINITION_ENTRY
*IDENext
;
224 FLASH_SUBREGION_DESCRIPTION
*SubNext
;
226 // Go through all our flash devices and free the memory
228 while (mFlashDevices
!= NULL
) {
230 // Free the physical block definitions
232 while (mFlashDevices
->PBlocks
!= NULL
) {
233 FBNext
= mFlashDevices
->PBlocks
->Next
;
234 _free (mFlashDevices
->PBlocks
);
235 mFlashDevices
->PBlocks
= FBNext
;
238 // Free the region definitions
240 while (mFlashDevices
->Regions
!= NULL
) {
241 FBNext
= mFlashDevices
->Regions
->Next
;
243 // First free the subregion definitions
245 while (mFlashDevices
->Regions
->Subregions
!= NULL
) {
246 SubNext
= mFlashDevices
->Regions
->Subregions
->Next
;
247 _free (mFlashDevices
->Regions
->Subregions
);
248 mFlashDevices
->Regions
->Subregions
= SubNext
;
251 _free (mFlashDevices
->Regions
);
252 mFlashDevices
->Regions
= FBNext
;
255 FDNext
= mFlashDevices
->Next
;
256 _free (mFlashDevices
);
257 mFlashDevices
= FDNext
;
260 // Free up the image definitions, and the data
262 while (mImageDefinitions
!= NULL
) {
266 while (mImageDefinitions
->Entries
!= NULL
) {
267 IDENext
= mImageDefinitions
->Entries
->Next
;
268 if (mImageDefinitions
->Entries
->RawData
!= NULL
) {
269 _free (mImageDefinitions
->Entries
->RawData
);
272 _free (mImageDefinitions
->Entries
);
273 mImageDefinitions
->Entries
= IDENext
;
276 IDNext
= mImageDefinitions
->Next
;
277 _free (mImageDefinitions
);
278 mImageDefinitions
= IDNext
;
289 Parse the specified flash definition file, saving the definitions in
290 file-static variables for use by other functions.
293 FileName - name of the input flash definition text file.
296 STATUS_SUCCESS - file parsed with no errors or warnings
297 STATUS_WARNING - warnings, but no errors, were encountered while parsing
298 STATUS_ERROR - errors were encountered while parsing
305 FLASH_DEVICE_DESCRIPTION
*FDDesc
;
306 FLASH_BLOCK_DESCRIPTION
*FBlockDesc
;
307 FLASH_BLOCK_DESCRIPTION
*TempBlockDesc
;
308 FLASH_SUBREGION_DESCRIPTION
*Subregion
;
309 FLASH_SUBREGION_DESCRIPTION
*TempSubregion
;
310 unsigned int BlockSizeLeft
;
311 unsigned int RegionSizeLeft
;
312 unsigned int SubregionSizeLeft
;
315 IMAGE_DEFINITION
*ImageDef
;
316 IMAGE_DEFINITION_ENTRY
*ImageDefEntry
;
317 IMAGE_DEFINITION_ENTRY
*TempImageDefEntry
;
318 BUFFER_DATA
*BufferData
;
320 BOOLEAN PreviousComma
;
322 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
323 Error (NULL
, 0, 0, FileName
, "failed to open input flash definition file for reading");
328 Status
= STATUS_SUCCESS
;
332 // Initialize the simple-file-parsing routines
338 if ((Status
= SFPOpenFile (FileName
)) != STATUS_SUCCESS
) {
342 // Parse the file. Should start with a series of these:
344 // Name = "FLASH_1234", Size = 0x2004, BaseAddress = 0xFFF0000, ErasePolarity = 1,
345 // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }
346 // Block { Name = "BLOCK2", Size = 0x1004, Flags = 0x0002 }
347 // Region { Name = "REGION_NAME", Size = 0x2004, Align= 4 }
350 while (SFPIsKeyword ("FlashDevice")) {
352 // Allocate memory for new flash device description block
354 FDDesc
= (FLASH_DEVICE_DESCRIPTION
*) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION
));
355 if (FDDesc
== NULL
) {
356 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
361 memset (FDDesc
, 0, sizeof (FLASH_DEVICE_DESCRIPTION
));
363 // Open brace -- warning if not there
365 if (!SFPIsToken ("{")) {
366 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL
);
370 // Parse: Name = "DeviceName",
372 if (!SFPIsKeyword ("Name")) {
373 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
378 if (!SFPIsToken ("=")) {
379 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
383 if (!SFPGetQuotedString (FDDesc
->Name
, sizeof (FDDesc
->Name
))) {
384 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL
);
389 if (!SFPIsToken (",")) {
390 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL
);
394 // Parse: Size = 0x20000,
396 if (!SFPIsKeyword ("Size")) {
397 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL
);
402 if (!SFPIsToken ("=")) {
403 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
407 if (!SFPGetNumber (&FDDesc
->Size
)) {
408 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL
);
415 if (FDDesc
->Size
== 0) {
416 Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc
->Name
, "Size field cannot be 0", NULL
);
423 // Parse: BaseAddress = 0xFFF0000,
425 if (!SFPIsKeyword ("BaseAddress")) {
426 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL
);
431 if (!SFPIsToken ("=")) {
432 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
436 if (!SFPGetNumber (&FDDesc
->BaseAddress
)) {
437 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL
);
442 if (!SFPIsToken (",")) {
443 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL
);
447 // Parse: ErasePolarity = 1,
449 if (!SFPIsKeyword ("ErasePolarity")) {
450 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL
);
455 if (!SFPIsToken ("=")) {
456 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
460 if (!SFPGetNumber (&Num
) || ((Num
!= 0) && (Num
!= 1))) {
461 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL
);
466 FDDesc
->ErasePolarity
= Num
;
467 if (!SFPIsToken (",")) {
468 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL
);
473 // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }
475 // Keep track of size to make sure the sum of the physical blocks and region sizes do not
476 // exceed the size of the flash device.
478 BlockSizeLeft
= FDDesc
->Size
;
479 RegionSizeLeft
= FDDesc
->Size
;
480 while (SFPIsKeyword ("Block")) {
482 // Allocate memory for a new physical block descriptor
484 FBlockDesc
= (FLASH_BLOCK_DESCRIPTION
*) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION
));
485 if (FBlockDesc
== NULL
) {
486 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
491 memset (FBlockDesc
, 0, sizeof (FLASH_BLOCK_DESCRIPTION
));
493 // Open brace -- warning if not there
495 if (!SFPIsToken ("{")) {
496 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL
);
500 // Parse: Name = "BlockName",
502 if (!SFPIsKeyword ("Name")) {
503 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
508 if (!SFPIsToken ("=")) {
509 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
513 if (!SFPGetQuotedString (FBlockDesc
->Name
, sizeof (FBlockDesc
->Name
))) {
514 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL
);
519 // Make sure there are no other physical block names with this same name
521 for (TempBlockDesc
= FDDesc
->PBlocks
; TempBlockDesc
!= NULL
; TempBlockDesc
= TempBlockDesc
->Next
) {
522 if (strcmp (TempBlockDesc
->Name
, FBlockDesc
->Name
) == 0) {
528 "physical block with this name already defined"
534 if (!SFPIsToken (",")) {
535 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL
);
539 // Parse: Size = 0x2000,
541 if (!SFPIsKeyword ("Size")) {
542 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL
);
547 if (!SFPIsToken ("=")) {
548 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
552 if (!SFPGetNumber (&FBlockDesc
->Size
)) {
553 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL
);
558 // Make sure the sum of physical blocks so far does not exceed flash device size
560 if (BlockSizeLeft
< FBlockDesc
->Size
) {
565 "sum of physical block sizes exceeds flash device size",
571 BlockSizeLeft
-= FBlockDesc
->Size
;
574 // Optional parse: Flags = 0xFFF0000,
576 if (SFPIsKeyword ("Flags")) {
577 if (!SFPIsToken ("=")) {
578 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
582 if (!SFPGetNumber (&FBlockDesc
->Flags
)) {
583 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL
);
589 if (!SFPIsToken ("}")) {
590 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL
);
594 // Add the physical block descriptor to the end of the linked list
596 if (FDDesc
->LastPBlock
!= NULL
) {
597 FDDesc
->LastPBlock
->Next
= FBlockDesc
;
599 FDDesc
->PBlocks
= FBlockDesc
;
602 FDDesc
->LastPBlock
= FBlockDesc
;
605 // Make sure sum of sizes of physical blocks added up to size of flash device
607 if (BlockSizeLeft
!= 0) {
613 "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",
614 FDDesc
->Size
- BlockSizeLeft
,
622 // Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" }
624 while (SFPIsKeyword ("Region")) {
626 // Allocate memory for a new physical block descriptor
628 FBlockDesc
= (FLASH_BLOCK_DESCRIPTION
*) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION
));
629 if (FBlockDesc
== NULL
) {
630 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
635 memset (FBlockDesc
, 0, sizeof (FLASH_BLOCK_DESCRIPTION
));
637 // Open brace -- warning if not there
639 if (!SFPIsToken ("{")) {
640 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL
);
644 // Parse: Name = "BlockName",
646 if (!SFPIsKeyword ("Name")) {
647 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
652 if (!SFPIsToken ("=")) {
653 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
657 if (!SFPGetQuotedString (FBlockDesc
->Name
, sizeof (FBlockDesc
->Name
))) {
658 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL
);
663 // Make sure there are no other region names with this same name
665 for (TempBlockDesc
= FDDesc
->Regions
; TempBlockDesc
!= NULL
; TempBlockDesc
= TempBlockDesc
->Next
) {
666 if (strcmp (TempBlockDesc
->Name
, FBlockDesc
->Name
) == 0) {
672 "Region with this name already defined"
678 if (!SFPIsToken (",")) {
679 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL
);
683 // Parse: Size = 0x2000,
685 if (!SFPIsKeyword ("Size")) {
686 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL
);
691 if (!SFPIsToken ("=")) {
692 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
696 if (!SFPGetNumber (&FBlockDesc
->Size
)) {
697 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL
);
702 if (!SFPIsToken (",")) {
703 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL
);
706 // Make sure the sum of regions so far does not exceed flash device size
708 if (RegionSizeLeft
< FBlockDesc
->Size
) {
709 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL
);
713 RegionSizeLeft
-= FBlockDesc
->Size
;
715 // Optional parse: Flags = 0xFFF0000,
717 if (SFPIsKeyword ("Flags")) {
718 if (!SFPIsToken ("=")) {
719 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
723 if (!SFPGetNumber (&FBlockDesc
->Flags
)) {
724 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL
);
731 if (!SFPIsToken (",")) {
732 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL
);
736 // Optional parse: Alignment = 4
738 if (SFPIsKeyword ("Alignment")) {
739 if (!SFPIsToken ("=")) {
740 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
744 if (!SFPGetNumber (&FBlockDesc
->Alignment
)) {
745 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL
);
752 if (!SFPIsToken (",")) {
753 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL
);
757 // Parse: Attributes = "String",
759 if (!SFPIsKeyword ("Attributes")) {
760 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL
);
765 if (!SFPIsToken ("=")) {
766 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
770 if (!SFPGetQuotedString (FBlockDesc
->Attributes
, sizeof (FBlockDesc
->Attributes
))) {
771 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL
);
776 if (!SFPIsToken (",")) {
777 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL
);
780 // Parse: AreaType = "String",
782 if (!SFPIsKeyword ("AreaType")) {
783 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL
);
788 if (!SFPIsToken ("=")) {
789 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
793 if (!SFPGetQuotedString (FBlockDesc
->AreaType
, sizeof (FBlockDesc
->AreaType
))) {
794 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL
);
799 PreviousComma
= SFPIsToken (",");
801 // Parse optional attribute "AreaTypeGuid"
803 if (SFPIsKeyword ("AreaTypeGuid")) {
805 // Check for preceeding comma now
807 if (!PreviousComma
) {
808 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL
);
812 if (!SFPIsToken ("=")) {
813 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
817 if (SFPGetQuotedString (FBlockDesc
->AreaTypeGuidString
, sizeof (FBlockDesc
->AreaTypeGuidString
))) {
819 // Nothing else to do
821 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS
, &FBlockDesc
->AreaTypeGuid
)) {
826 "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
832 PreviousComma
= SFPIsToken (",");
836 // Parse optional Subregion definitions
838 SubregionSizeLeft
= FBlockDesc
->Size
;
839 while (SFPIsToken ("Subregion")) {
840 if (!PreviousComma
) {
841 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL
);
843 PreviousComma
= TRUE
;
846 Subregion
= ParseSubregionDefinition (SubregionSizeLeft
);
847 if (Subregion
== NULL
) {
852 SubregionSizeLeft
-= Subregion
->Size
;
854 // Add it to the end of our list
856 if (FBlockDesc
->Subregions
== NULL
) {
857 FBlockDesc
->Subregions
= Subregion
;
859 FBlockDesc
->LastSubregion
->Next
= Subregion
;
862 FBlockDesc
->LastSubregion
= Subregion
;
864 // Make sure all subregion names are unique. We do this each time
865 // through so that we catch the error immediately after it happens, in
866 // which case the reported line number is at least close to where the
867 // problem lies. We don't exit on the error because we can continue parsing
868 // the script to perhaps catch other errors or warnings.
870 for (Subregion
= FBlockDesc
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
871 for (TempSubregion
= Subregion
->Next
; TempSubregion
!= NULL
; TempSubregion
= TempSubregion
->Next
) {
872 if (strcmp (Subregion
->Name
, TempSubregion
->Name
) == 0) {
873 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion
->Name
, "duplicate Subregion name");
880 if (!SFPIsToken ("}")) {
881 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL
);
885 // Add the region descriptor to the end of the linked list
887 if (FDDesc
->LastRegion
!= NULL
) {
888 FDDesc
->LastRegion
->Next
= FBlockDesc
;
890 FDDesc
->Regions
= FBlockDesc
;
893 FDDesc
->LastRegion
= FBlockDesc
;
896 // Make sure sum of sizes of regions adds up to size of flash device
898 if (RegionSizeLeft
!= 0) {
904 "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",
905 FDDesc
->Size
- RegionSizeLeft
,
912 // Look for closing brace
914 if (!SFPIsToken ("}")) {
915 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL
);
919 // Add this flash description to the list
921 FDDesc
->Next
= mFlashDevices
;
922 mFlashDevices
= FDDesc
;
925 while (SFPIsKeyword ("FlashDeviceImage")) {
927 // Allocate memory for a new FD image definition
929 ImageDef
= (IMAGE_DEFINITION
*) _malloc (sizeof (IMAGE_DEFINITION
));
930 if (ImageDef
== NULL
) {
931 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
936 memset (ImageDef
, 0, sizeof (IMAGE_DEFINITION
));
938 // Open brace -- warning if not there
940 if (!SFPIsToken ("{")) {
941 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL
);
945 // Parse: Name = "ImageName",
947 if (!SFPIsKeyword ("Name")) {
948 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
953 if (!SFPIsToken ("=")) {
954 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
958 if (!SFPGetQuotedString (ImageDef
->Name
, sizeof (ImageDef
->Name
))) {
959 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL
);
964 if (!SFPIsToken (",")) {
965 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL
);
971 // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE }
973 if (SFPIsKeyword ("File")) {
974 ImageDefEntry
= (IMAGE_DEFINITION_ENTRY
*) _malloc (sizeof (IMAGE_DEFINITION_ENTRY
));
975 if (ImageDefEntry
== NULL
) {
976 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
981 memset (ImageDefEntry
, 0, sizeof (IMAGE_DEFINITION_ENTRY
));
983 // Open brace -- warning if not there
985 if (!SFPIsToken ("{")) {
986 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL
);
990 // Parse: Name = "FileName.txt"
992 if (!SFPIsKeyword ("Name")) {
993 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
998 if (!SFPIsToken ("=")) {
999 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1003 if (!SFPGetQuotedString (ImageDefEntry
->Name
, sizeof (ImageDefEntry
->Name
))) {
1004 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL
);
1009 if (!SFPIsToken (",")) {
1010 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL
);
1014 // Parse: Region = "REGION_NAME"
1016 if (!SFPIsKeyword ("Region")) {
1017 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL
);
1022 if (!SFPIsToken ("=")) {
1023 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1027 if (!SFPGetQuotedString (ImageDefEntry
->RegionName
, sizeof (ImageDefEntry
->RegionName
))) {
1028 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL
);
1033 if (!SFPIsToken (",")) {
1034 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL
);
1038 // Parse optional: Subregion = "SUBREGION_NAME"
1040 if (SFPIsKeyword ("Subregion")) {
1041 if (!SFPIsToken ("=")) {
1042 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1046 if (!SFPGetQuotedString (ImageDefEntry
->SubregionName
, sizeof (ImageDefEntry
->SubregionName
))) {
1047 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL
);
1052 if (!SFPIsToken (",")) {
1053 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL
);
1057 // For a given region, you can only place data using the region name, or the subregion names.
1058 // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that
1059 // here by checking that any previous entries with the same Region name had a Subregion specified
1062 for (TempImageDefEntry
= ImageDef
->Entries
;
1063 TempImageDefEntry
!= NULL
;
1064 TempImageDefEntry
= TempImageDefEntry
->Next
1066 if (strcmp (TempImageDefEntry
->Name
, ImageDefEntry
->Name
) == 0) {
1067 if (TempImageDefEntry
->SubregionName
[0] == 0) {
1070 SFPGetLineNumber (),
1072 TempImageDefEntry
->RegionName
,
1073 "data already placed on a region-basis in the region, can't place data using subregions"
1081 // Optional parse: Optional = TRUE | FALSE
1083 if (SFPIsKeyword ("Optional")) {
1084 if (!SFPIsToken ("=")) {
1085 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1089 if (!SFPIsKeyword ("TRUE")) {
1090 ImageDefEntry
->Optional
= 1;
1091 } else if (SFPIsKeyword ("FALSE")) {
1096 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL
);
1106 if (!SFPIsToken ("}")) {
1107 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL
);
1112 // Add the entry to the end of the list
1114 if (ImageDef
->LastEntry
!= NULL
) {
1115 ImageDef
->LastEntry
->Next
= ImageDefEntry
;
1117 ImageDef
->Entries
= ImageDefEntry
;
1120 ImageDef
->LastEntry
= ImageDefEntry
;
1121 } else if (SFPIsKeyword ("RawData")) {
1123 // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }}
1125 ImageDefEntry
= (IMAGE_DEFINITION_ENTRY
*) _malloc (sizeof (IMAGE_DEFINITION_ENTRY
));
1126 if (ImageDefEntry
== NULL
) {
1127 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
1132 memset (ImageDefEntry
, 0, sizeof (IMAGE_DEFINITION_ENTRY
));
1133 ImageDefEntry
->IsRawData
= 1;
1135 // Open brace -- warning if not there
1137 if (!SFPIsToken ("{")) {
1140 SFPGetLineNumber (),
1142 "expected '{' opening brace for RawData definition",
1148 // Parse: Name = "PadBytes"
1150 if (!SFPIsKeyword ("Name")) {
1151 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
1156 if (!SFPIsToken ("=")) {
1157 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1161 if (!SFPGetQuotedString (ImageDefEntry
->Name
, sizeof (ImageDefEntry
->Name
))) {
1162 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL
);
1167 if (!SFPIsToken (",")) {
1168 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL
);
1172 // Parse: Region = "REGION_NAME"
1174 if (!SFPIsKeyword ("Region")) {
1175 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL
);
1180 if (!SFPIsToken ("=")) {
1181 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1185 if (!SFPGetQuotedString (ImageDefEntry
->RegionName
, sizeof (ImageDefEntry
->RegionName
))) {
1186 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL
);
1191 if (!SFPIsToken (",")) {
1192 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL
);
1196 // Parse optional: Subregion = "SUBREGION_NAME"
1198 if (SFPIsKeyword ("Subregion")) {
1199 if (!SFPIsToken ("=")) {
1200 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1204 if (!SFPGetQuotedString (ImageDefEntry
->SubregionName
, sizeof (ImageDefEntry
->SubregionName
))) {
1205 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL
);
1210 if (!SFPIsToken (",")) {
1211 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL
);
1215 // For a given region, you can only place data using the region name, or the subregion names.
1216 // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that
1217 // here by checking that any previous entries with the same Region name had a Subregion specified
1220 for (TempImageDefEntry
= ImageDef
->Entries
;
1221 TempImageDefEntry
!= NULL
;
1222 TempImageDefEntry
= TempImageDefEntry
->Next
1224 if (strcmp (TempImageDefEntry
->Name
, ImageDefEntry
->Name
) == 0) {
1225 if (TempImageDefEntry
->SubregionName
[0] == 0) {
1228 SFPGetLineNumber (),
1230 TempImageDefEntry
->RegionName
,
1231 "data already placed on a region-basis in the region, can't place data using subregions"
1239 // Parse: Data = { 0x78, 0x56, 0x34, 0x12 }
1241 if (!SFPIsKeyword ("Data")) {
1242 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL
);
1247 if (!SFPIsToken ("=")) {
1248 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1252 if (!SFPIsToken ("{")) {
1253 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL
);
1257 if ((BufferData
= CreateBufferData ()) == NULL
) {
1262 // Read bytes from input file until closing brace
1264 while (!SFPIsToken ("}")) {
1265 if (!SFPGetNumber (&Num
)) {
1266 SFPGetNextToken (Str
, sizeof (Str
));
1267 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str
, "expected data value", Str
);
1269 FreeBufferData (BufferData
, TRUE
);
1276 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL
);
1278 FreeBufferData (BufferData
, TRUE
);
1282 AddBufferDataByte (BufferData
, (char) Num
);
1287 // Now get the data and save it in our image entry
1289 ImageDefEntry
->RawData
= GetBufferData (BufferData
, &ImageDefEntry
->RawDataSize
);
1290 FreeBufferData (BufferData
, 0);
1292 // Closing brace for RawData {}
1294 if (!SFPIsToken ("}")) {
1295 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL
);
1300 // Add the entry to the end of the list
1302 if (ImageDef
->LastEntry
!= NULL
) {
1303 ImageDef
->LastEntry
->Next
= ImageDefEntry
;
1305 ImageDef
->Entries
= ImageDefEntry
;
1308 ImageDef
->LastEntry
= ImageDefEntry
;
1309 } else if (SFPIsToken ("}")) {
1311 // Closing brace for FDImage {}
1315 SFPGetNextToken (Str
, sizeof (Str
));
1316 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str
, "unrecognized token", Str
);
1322 // Add this image definition to our global list
1324 ImageDef
->Next
= mImageDefinitions
;
1325 mImageDefinitions
= ImageDef
;
1328 // Check for end-of-file
1331 SFPGetNextToken (Str
, sizeof (Str
));
1332 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str
, "expected end-of-file", Str
);
1338 if (ErrorCount
!= 0) {
1339 return STATUS_ERROR
;
1340 } else if (WarningCount
!= 0) {
1341 return STATUS_WARNING
;
1344 return STATUS_SUCCESS
;
1348 FLASH_SUBREGION_DESCRIPTION
*
1349 ParseSubregionDefinition (
1350 unsigned int SizeLeft
1354 Routine Description:
1356 Parse Subregion definitions from the input flash definition file. Format:
1362 Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV",
1363 AreaType = "EFI_FLASH_AREA_EFI_VARIABLES",
1364 NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"),
1365 AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)
1366 FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)
1369 NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace.
1373 SizeLeft - in the flash definition file, a Region can be broken up into
1374 one or more subregions. As we parse the subregion definitions,
1375 the caller keeps track of how much space is left in the region
1376 that we're parsing subregions for. SizeLeft is that size, and
1377 so the size of the subregion we're now parsing better not
1378 exceed the size left.
1381 NULL - unrecoverable errors detected while parsing the subregion definition
1383 pointer to a subregion definition created from the parsed subregion
1387 FLASH_SUBREGION_DESCRIPTION
*Subregion
;
1390 unsigned int Number
;
1391 BOOLEAN PreviousComma
;
1393 // Allocate memory for the new subregion descriptor
1397 Subregion
= (FLASH_SUBREGION_DESCRIPTION
*) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION
));
1398 if (Subregion
== NULL
) {
1399 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
1404 memset (Subregion
, 0, sizeof (FLASH_SUBREGION_DESCRIPTION
));
1406 // Open brace -- warning if not there
1408 if (!SFPIsToken ("{")) {
1409 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL
);
1413 // Parse: CreateHob = TRUE | FALSE,
1415 if (!SFPIsKeyword ("CreateHob")) {
1416 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL
);
1421 if (!SFPIsToken ("=")) {
1422 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1426 if (SFPIsToken ("TRUE")) {
1427 Subregion
->CreateHob
= 1;
1428 } else if (SFPIsToken ("FALSE")) {
1430 // Subregion->CreateHob = 0; -- not required since we did a memset earlier
1433 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL
);
1438 if (!SFPIsToken (",")) {
1439 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL
);
1443 // Parse: Name = "Name",
1445 if (!SFPIsKeyword ("Name")) {
1446 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL
);
1451 if (!SFPIsToken ("=")) {
1452 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1456 if (!SFPGetQuotedString (Subregion
->Name
, sizeof (Subregion
->Name
))) {
1457 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL
);
1462 if (!SFPIsToken (",")) {
1463 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL
);
1467 // Parse: Size = 0x2000,
1469 if (!SFPIsKeyword ("Size")) {
1470 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL
);
1475 if (!SFPIsToken ("=")) {
1476 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1480 if (!SFPGetNumber (&Subregion
->Size
)) {
1481 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL
);
1487 // Check that the size does not exceed the size left passed in
1489 if (Subregion
->Size
> SizeLeft
) {
1490 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL
);
1495 if (!SFPIsToken (",")) {
1496 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL
);
1499 // Parse: Attributes = Number | "String",
1501 if (!SFPIsKeyword ("Attributes")) {
1502 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL
);
1507 if (!SFPIsToken ("=")) {
1508 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1512 if (SFPGetNumber (&Number
)) {
1513 sprintf (Subregion
->Attributes
, "0x%X", Number
);
1514 } else if (!SFPGetQuotedString (Subregion
->Attributes
, sizeof (Subregion
->Attributes
))) {
1515 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL
);
1520 if (!SFPIsToken (",")) {
1521 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL
);
1524 // Parse: AreaType = Number | "String",
1525 // AreaType is a UINT8, so error if it exceeds the size
1527 if (!SFPIsKeyword ("AreaType")) {
1528 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL
);
1533 if (!SFPIsToken ("=")) {
1534 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1538 if (SFPGetNumber (&Number
)) {
1539 if (Number
> 0xFF) {
1540 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL
);
1544 sprintf (Subregion
->AreaType
, "0x%X", Number
& 0x00FF);
1545 } else if (!SFPGetQuotedString (Subregion
->AreaType
, sizeof (Subregion
->AreaType
))) {
1546 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL
);
1551 if (!SFPIsToken (",")) {
1552 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL
);
1555 // Parse the three GUIDs (last two are optional)
1557 // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID")
1558 // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")
1559 // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")
1561 if (!SFPIsKeyword ("NameGuid")) {
1562 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL
);
1567 if (!SFPIsToken ("=")) {
1568 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1572 // Allow a GUID or a quoted string identifier, which we'll just copy as a string
1574 if (SFPGetQuotedString (Subregion
->NameGuidString
, sizeof (Subregion
->NameGuidString
))) {
1576 // Nothing else to do
1578 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS
, &Subregion
->NameGuid
)) {
1581 SFPGetLineNumber (),
1583 "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
1590 // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid
1592 PreviousComma
= SFPIsToken (",");
1593 if (SFPIsKeyword ("AreaTypeGuid")) {
1595 // Check for preceeding comma now
1597 if (!PreviousComma
) {
1598 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL
);
1602 if (!SFPIsToken ("=")) {
1603 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1607 if (SFPGetQuotedString (Subregion
->AreaTypeGuidString
, sizeof (Subregion
->AreaTypeGuidString
))) {
1609 // Nothing else to do
1611 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS
, &Subregion
->AreaTypeGuid
)) {
1614 SFPGetLineNumber (),
1616 "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
1623 PreviousComma
= SFPIsToken (",");
1626 if (SFPIsKeyword ("FileSystemGuid")) {
1628 // Check for preceeding comma now
1630 if (!PreviousComma
) {
1631 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL
);
1635 if (!SFPIsToken ("=")) {
1636 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL
);
1640 // Allow a GUID or a quoted string identifier, which we'll just copy as a string
1642 if (SFPGetQuotedString (Subregion
->FileSystemGuidString
, sizeof (Subregion
->FileSystemGuidString
))) {
1644 // Nothing else to do
1646 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS
, &Subregion
->FileSystemGuid
)) {
1649 SFPGetLineNumber (),
1651 "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
1661 // Look for subregion closing brace
1663 if (!SFPIsToken ("}")) {
1664 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL
);
1670 // If any errors were encountered, then delete the subregion definition
1672 if (ErrorCount
!= 0) {
1681 FDFCreateCIncludeFile (
1682 char *FlashDeviceName
,
1687 Routine Description:
1688 Create a header file with #define definitions per an already-parsed
1689 flash definition file.
1692 FlashDeviceName - name of flash device (from the flash definition file)
1694 FileName - name of output file to create
1697 STATUS_SUCCESS - no errors or warnings
1698 STATUS_WARNING - warnings, but no errors, were encountered
1699 STATUS_ERROR - errors were encountered
1704 FLASH_BLOCK_DESCRIPTION
*FBlock
;
1705 FLASH_DEVICE_DESCRIPTION
*FDev
;
1706 FLASH_SUBREGION_DESCRIPTION
*Subregion
;
1707 unsigned int Offset
;
1708 unsigned int SubregionOffset
;
1711 // Find the definition we're supposed to use
1713 for (FDev
= mFlashDevices
; FDev
!= NULL
; FDev
= FDev
->Next
) {
1714 if (strcmp (FDev
->Name
, FlashDeviceName
) == 0) {
1720 Error (NULL
, 0, 0, NULL
, FlashDeviceName
, "flash device not found in flash definitions");
1721 return STATUS_ERROR
;
1724 if ((OutFptr
= fopen (FileName
, "w")) == NULL
) {
1725 Error (NULL
, 0, 0, FileName
, "failed to open output file for writing");
1726 return STATUS_ERROR
;
1731 fprintf (OutFptr
, CIncludeHeader
);
1733 // Write flash block base and size defines
1735 fprintf (OutFptr
, "#define FLASH_BASE 0x%08X\n", FDev
->BaseAddress
);
1736 fprintf (OutFptr
, "#define FLASH_SIZE 0x%08X\n\n", FDev
->Size
);
1738 // Write flash regions base, size and offset defines
1742 for (FBlock
= FDev
->Regions
; FBlock
!= NULL
; FBlock
= FBlock
->Next
) {
1745 "#define FLASH_REGION_%s_BASE %*c0x%08X\n",
1747 COLUMN2_START
- 40 - strlen (FBlock
->Name
),
1749 Offset
+ FDev
->BaseAddress
1753 "#define FLASH_REGION_%s_SIZE %*c0x%08X\n",
1755 COLUMN2_START
- 40 - strlen (FBlock
->Name
),
1761 "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n",
1763 COLUMN2_START
- 40 - strlen (FBlock
->Name
),
1768 // Create defines for any subregions
1770 SubregionOffset
= 0;
1771 for (Subregion
= FBlock
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
1774 "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n",
1777 COLUMN3_START
- 43 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
1779 FDev
->BaseAddress
+ Offset
+ SubregionOffset
1783 "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n",
1786 COLUMN3_START
- 43 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
1792 "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n",
1795 COLUMN3_START
- 43 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
1797 Offset
+ SubregionOffset
1799 SubregionOffset
+= Subregion
->Size
;
1800 if (Subregion
->CreateHob
!= 0) {
1805 Offset
+= FBlock
->Size
;
1808 // Now create a #define for the flash map data definition
1810 fprintf (OutFptr
, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n");
1812 // Emit entry for each region
1815 for (FBlock
= FDev
->Regions
; FBlock
!= NULL
; FBlock
= FBlock
->Next
) {
1816 fprintf (OutFptr
, " /* %s region */\\\n", FBlock
->Name
);
1817 fprintf (OutFptr
, " {\\\n");
1818 fprintf (OutFptr
, " FLASH_REGION_%s_BASE,\\\n", FBlock
->Name
);
1819 fprintf (OutFptr
, " FLASH_REGION_%s_SIZE,\\\n", FBlock
->Name
);
1820 fprintf (OutFptr
, " %s,\\\n", FBlock
->Attributes
);
1821 fprintf (OutFptr
, " %s,\\\n", FBlock
->AreaType
);
1822 fprintf (OutFptr
, " 0, 0, 0,\\\n");
1824 // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or
1825 // as a quoted string. Do the right one.
1827 if (FBlock
->AreaTypeGuidString
[0] != 0) {
1828 fprintf (OutFptr
, " %s, \\\n", FBlock
->AreaTypeGuidString
);
1832 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
1833 FBlock
->AreaTypeGuid
.Data1
,
1834 (unsigned int) FBlock
->AreaTypeGuid
.Data2
,
1835 (unsigned int) FBlock
->AreaTypeGuid
.Data3
,
1836 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[0],
1837 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[1],
1838 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[2],
1839 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[3],
1840 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[4],
1841 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[5],
1842 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[6],
1843 (unsigned int) FBlock
->AreaTypeGuid
.Data4
[7]
1846 fprintf (OutFptr
, " },\\\n");
1849 fprintf (OutFptr
, "\n\n");
1851 // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition
1853 if (CreateHobs
!= 0) {
1854 fprintf (OutFptr
, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n");
1855 fprintf (OutFptr
, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION");
1856 for (FBlock
= FDev
->Regions
; FBlock
!= NULL
; FBlock
= FBlock
->Next
) {
1858 // See if the block has subregions, and that the CreateHobs flag is set
1862 for (Subregion
= FBlock
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
1863 if (Subregion
->CreateHob
!= 0) {
1869 // If any of the subregions had the CreateHobs flag set, then create the entries in the
1872 if (CreateHobs
!= 0) {
1873 for (Subregion
= FBlock
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
1874 if (Subregion
->CreateHob
!= 0) {
1875 fprintf (OutFptr
, " \\\n");
1876 fprintf (OutFptr
, " /* %s.%s Subregion */\\\n", FBlock
->Name
, Subregion
->Name
);
1877 fprintf (OutFptr
, " {\\\n");
1878 fprintf (OutFptr
, " {EFI_HOB_TYPE_GUID_EXTENSION,\\\n");
1879 fprintf (OutFptr
, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n");
1880 fprintf (OutFptr
, " 0},\\\n");
1882 // The NameGuid may have been specified in the input flash definition file as a GUID, or
1883 // as a quoted string. Do the right one.
1885 if (Subregion
->NameGuidString
[0] != 0) {
1886 fprintf (OutFptr
, " %s, \\\n", Subregion
->NameGuidString
);
1890 " { 0x%08X, 0x%04X, 0x%04X, {0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}},\\\n",
1891 Subregion
->NameGuid
.Data1
,
1892 (unsigned int) Subregion
->NameGuid
.Data2
,
1893 (unsigned int) Subregion
->NameGuid
.Data3
,
1894 (unsigned int) Subregion
->NameGuid
.Data4
[0],
1895 (unsigned int) Subregion
->NameGuid
.Data4
[1],
1896 (unsigned int) Subregion
->NameGuid
.Data4
[2],
1897 (unsigned int) Subregion
->NameGuid
.Data4
[3],
1898 (unsigned int) Subregion
->NameGuid
.Data4
[4],
1899 (unsigned int) Subregion
->NameGuid
.Data4
[5],
1900 (unsigned int) Subregion
->NameGuid
.Data4
[6],
1901 (unsigned int) Subregion
->NameGuid
.Data4
[7]
1905 fprintf (OutFptr
, " {0, 0, 0},\\\n");
1906 fprintf (OutFptr
, " %s,\\\n", Subregion
->AreaType
);
1908 // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or
1909 // as a quoted string. Do the right one.
1911 if (Subregion
->AreaTypeGuidString
[0] != 0) {
1912 fprintf (OutFptr
, " %s, \\\n", Subregion
->AreaTypeGuidString
);
1916 " { 0x%08X, 0x%04X, 0x%04X, {0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}},\\\n",
1917 Subregion
->AreaTypeGuid
.Data1
,
1918 (unsigned int) Subregion
->AreaTypeGuid
.Data2
,
1919 (unsigned int) Subregion
->AreaTypeGuid
.Data3
,
1920 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[0],
1921 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[1],
1922 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[2],
1923 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[3],
1924 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[4],
1925 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[5],
1926 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[6],
1927 (unsigned int) Subregion
->AreaTypeGuid
.Data4
[7]
1931 fprintf (OutFptr
, " 1,\\\n");
1932 fprintf (OutFptr
, " {{\\\n");
1933 fprintf (OutFptr
, " %s,\\\n", Subregion
->Attributes
);
1934 fprintf (OutFptr
, " 0,\\\n");
1935 fprintf (OutFptr
, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock
->Name
, Subregion
->Name
);
1936 fprintf (OutFptr
, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock
->Name
, Subregion
->Name
);
1938 // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or
1939 // as a quoted string. Do the right one.
1941 if (Subregion
->FileSystemGuidString
[0] != 0) {
1942 fprintf (OutFptr
, " %s, \\\n", Subregion
->FileSystemGuidString
);
1946 " { 0x%08X, 0x%04X, 0x%04X, {0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}},\\\n",
1947 Subregion
->FileSystemGuid
.Data1
,
1948 (unsigned int) Subregion
->FileSystemGuid
.Data2
,
1949 (unsigned int) Subregion
->FileSystemGuid
.Data3
,
1950 (unsigned int) Subregion
->FileSystemGuid
.Data4
[0],
1951 (unsigned int) Subregion
->FileSystemGuid
.Data4
[1],
1952 (unsigned int) Subregion
->FileSystemGuid
.Data4
[2],
1953 (unsigned int) Subregion
->FileSystemGuid
.Data4
[3],
1954 (unsigned int) Subregion
->FileSystemGuid
.Data4
[4],
1955 (unsigned int) Subregion
->FileSystemGuid
.Data4
[5],
1956 (unsigned int) Subregion
->FileSystemGuid
.Data4
[6],
1957 (unsigned int) Subregion
->FileSystemGuid
.Data4
[7]
1961 fprintf (OutFptr
, " }},\\\n");
1962 fprintf (OutFptr
, " },");
1968 fprintf (OutFptr
, "\n\n");
1972 // Write the file's closing #endif
1974 fprintf (OutFptr
, CIncludeFooter
);
1976 return STATUS_SUCCESS
;
1980 FDFCreateAsmIncludeFile (
1981 char *FlashDeviceName
,
1986 Routine Description:
1987 Create an assembly header file with equate definitions per an already-parsed
1988 flash definition file.
1991 FlashDeviceName - name of flash device (from the flash definition file)
1993 FileName - name of output file to create
1996 STATUS_SUCCESS - no errors or warnings
1997 STATUS_WARNING - warnings, but no errors, were encountered
1998 STATUS_ERROR - errors were encountered
2003 FLASH_BLOCK_DESCRIPTION
*FBlock
;
2004 FLASH_DEVICE_DESCRIPTION
*FDev
;
2005 unsigned int Offset
;
2006 FLASH_SUBREGION_DESCRIPTION
*Subregion
;
2007 unsigned int SubregionOffset
;
2009 // Find the definition we're supposed to use
2011 for (FDev
= mFlashDevices
; FDev
!= NULL
; FDev
= FDev
->Next
) {
2012 if (strcmp (FDev
->Name
, FlashDeviceName
) == 0) {
2018 Error (NULL
, 0, 0, NULL
, FlashDeviceName
, "flash device not found in flash definitions");
2019 return STATUS_ERROR
;
2022 if ((OutFptr
= fopen (FileName
, "w")) == NULL
) {
2023 Error (NULL
, 0, 0, FileName
, "failed to open output file for writing");
2024 return STATUS_ERROR
;
2029 fprintf (OutFptr
, "\n\n");
2031 // Write flash block size and offset defines
2035 "FLASH_BASE %*cequ 0%08Xh\n",
2040 fprintf (OutFptr
, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START
- 40, ' ', FDev
->Size
);
2042 // Write flash region size and offset defines
2044 fprintf (OutFptr
, "\n");
2046 for (FBlock
= FDev
->Regions
; FBlock
!= NULL
; FBlock
= FBlock
->Next
) {
2049 "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n",
2051 COLUMN2_START
- 20 - strlen (FBlock
->Name
),
2053 FDev
->BaseAddress
+ Offset
2057 "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n",
2059 COLUMN2_START
- 20 - strlen (FBlock
->Name
),
2065 "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n",
2067 COLUMN2_START
- 20 - strlen (FBlock
->Name
),
2072 // Create defines for any subregions
2074 SubregionOffset
= 0;
2075 for (Subregion
= FBlock
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
2078 "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n",
2081 COLUMN3_START
- 39 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
2083 FDev
->BaseAddress
+ Offset
+ SubregionOffset
2087 "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n",
2090 COLUMN3_START
- 39 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
2096 "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n",
2099 COLUMN3_START
- 39 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
2101 Offset
+ SubregionOffset
2103 SubregionOffset
+= Subregion
->Size
;
2106 Offset
+= FBlock
->Size
;
2112 fprintf (OutFptr
, "\n\n");
2114 return STATUS_SUCCESS
;
2119 char *FlashDeviceName
2123 Routine Description:
2124 Using the given flash device name, add symbols to the global symbol table. This
2125 allows other functions to use the symbol definitions for other purposes.
2128 FlashDeviceName - name of flash device (from the flash definition file)
2132 STATUS_SUCCESS - no errors or warnings
2133 STATUS_WARNING - warnings, but no errors, were encountered
2134 STATUS_ERROR - errors were encountered
2138 FLASH_BLOCK_DESCRIPTION
*FBlock
;
2139 FLASH_DEVICE_DESCRIPTION
*FDev
;
2140 unsigned int Offset
;
2143 FLASH_SUBREGION_DESCRIPTION
*Subregion
;
2144 unsigned int SubregionOffset
;
2146 // Find the definition we're supposed to use
2148 for (FDev
= mFlashDevices
; FDev
!= NULL
; FDev
= FDev
->Next
) {
2149 if (strcmp (FDev
->Name
, FlashDeviceName
) == 0) {
2155 Error (NULL
, 0, 0, NULL
, FlashDeviceName
, "flash device not found in flash definitions");
2156 return STATUS_ERROR
;
2159 sprintf (SymValue
, "0x%08X", FDev
->BaseAddress
);
2160 SymbolAdd ("FLASH_BASE", SymValue
, 0);
2161 sprintf (SymValue
, "0x%08X", FDev
->Size
);
2162 SymbolAdd ("FLASH_SIZE", SymValue
, 0);
2164 // Add flash block size and offset defines
2167 // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) {
2168 // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name);
2169 // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);
2170 // SymbolAdd (SymName, SymValue, 0);
2171 // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name);
2172 // sprintf (SymValue, "0x%08X", FBlock->Size);
2173 // SymbolAdd (SymName, SymValue, 0);
2174 // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name);
2175 // sprintf (SymValue, "0x%08X", Offset);
2176 // SymbolAdd (SymName, SymValue, 0);
2177 // Offset += FBlock->Size;
2180 // Add flash region block base, size, and offset defines
2183 for (FBlock
= FDev
->Regions
; FBlock
!= NULL
; FBlock
= FBlock
->Next
) {
2184 sprintf (SymName
, "FLASH_REGION_%s_BASE", FBlock
->Name
);
2185 sprintf (SymValue
, "0x%08X", FDev
->BaseAddress
+ Offset
);
2186 SymbolAdd (SymName
, SymValue
, 0);
2187 sprintf (SymName
, "FLASH_REGION_%s_SIZE", FBlock
->Name
);
2188 sprintf (SymValue
, "0x%08X", FBlock
->Size
);
2189 SymbolAdd (SymName
, SymValue
, 0);
2190 sprintf (SymName
, "FLASH_REGION_%s_OFFSET", FBlock
->Name
);
2191 sprintf (SymValue
, "0x%08X", Offset
);
2192 SymbolAdd (SymName
, SymValue
, 0);
2194 // Add subregion symbols
2196 if (FBlock
->Subregions
!= NULL
) {
2197 SubregionOffset
= 0;
2198 for (Subregion
= FBlock
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
2199 sprintf (SymName
, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock
->Name
, Subregion
->Name
);
2200 sprintf (SymValue
, "0x%08X", FDev
->BaseAddress
+ Offset
+ SubregionOffset
);
2201 SymbolAdd (SymName
, SymValue
, 0);
2202 sprintf (SymName
, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock
->Name
, Subregion
->Name
);
2203 sprintf (SymValue
, "0x%08X", Subregion
->Size
);
2204 SymbolAdd (SymName
, SymValue
, 0);
2205 sprintf (SymName
, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock
->Name
, Subregion
->Name
);
2206 sprintf (SymValue
, "0x%08X", Offset
+ SubregionOffset
);
2207 SymbolAdd (SymName
, SymValue
, 0);
2208 SubregionOffset
+= Subregion
->Size
;
2212 Offset
+= FBlock
->Size
;
2215 return STATUS_SUCCESS
;
2220 char *FlashDeviceName
,
2226 Routine Description:
2227 Create a flash image using the given device and image names.
2230 FlashDeviceName - name of flash device (from the flash definition file)
2232 ImageName - name of image (from the flash definition file) to create
2233 FileName - name of output file to create
2236 STATUS_SUCCESS - no errors or warnings
2237 STATUS_WARNING - warnings, but no errors, were encountered
2238 STATUS_ERROR - errors were encountered
2244 FLASH_BLOCK_DESCRIPTION
*RegionDef
;
2245 FLASH_DEVICE_DESCRIPTION
*FDev
;
2246 IMAGE_DEFINITION
*ImageDef
;
2247 unsigned int Offset
;
2251 IMAGE_DEFINITION_ENTRY
*IDefEntry
;
2252 FLASH_SUBREGION_DESCRIPTION
*SubregionDef
;
2254 // Find the flash definition we're supposed to use
2257 Status
= STATUS_ERROR
;
2258 for (FDev
= mFlashDevices
; FDev
!= NULL
; FDev
= FDev
->Next
) {
2259 if (strcmp (FDev
->Name
, FlashDeviceName
) == 0) {
2265 Error (NULL
, 0, 0, FlashDeviceName
, "flash device not found in flash definitions");
2266 return STATUS_ERROR
;
2269 // Find the image name we're supposed to create
2271 for (ImageDef
= mImageDefinitions
; ImageDef
!= NULL
; ImageDef
= ImageDef
->Next
) {
2272 if (strcmp (ImageDef
->Name
, ImageName
) == 0) {
2277 if (ImageDef
== NULL
) {
2278 Error (NULL
, 0, 0, ImageName
, "image definition not found in image definitions");
2279 return STATUS_ERROR
;
2282 // Open the output file
2284 if ((OutFptr
= fopen (FileName
, "wb")) == NULL
) {
2285 Error (NULL
, 0, 0, FileName
, "failed to open output file for writing");
2286 return STATUS_ERROR
;
2289 // Allocate a buffer to copy the input data to
2291 Buffer
= (char *) _malloc (FDev
->Size
);
2292 if (Buffer
== NULL
) {
2293 Error (NULL
, 0, 0, (INT8
*) "failed to allocate memory", NULL
);
2297 // Set contents of buffer to the erased value
2299 if (FDev
->ErasePolarity
) {
2300 memset (Buffer
, 0xFF, FDev
->Size
);
2302 memset (Buffer
, 0, FDev
->Size
);
2305 // Set all region and subregion size-left fields to the size of the region/subregion
2307 for (RegionDef
= FDev
->Regions
; RegionDef
!= NULL
; RegionDef
= RegionDef
->Next
) {
2308 RegionDef
->SizeLeft
= RegionDef
->Size
;
2309 for (SubregionDef
= RegionDef
->Subregions
; SubregionDef
!= NULL
; SubregionDef
= SubregionDef
->Next
) {
2310 SubregionDef
->SizeLeft
= SubregionDef
->Size
;
2314 // Now go through the image list, read files into the buffer.
2316 for (IDefEntry
= ImageDef
->Entries
; IDefEntry
!= NULL
; IDefEntry
= IDefEntry
->Next
) {
2318 // If it's a file name, open the file, get the size, find the corresponding
2319 // flash region it's in, and copy the data.
2321 if (IDefEntry
->IsRawData
== 0) {
2322 if ((InFptr
= fopen (IDefEntry
->Name
, "rb")) == NULL
) {
2323 Error (NULL
, 0, 0, IDefEntry
->Name
, "failed to open input file for reading");
2327 fseek (InFptr
, 0, SEEK_END
);
2328 FileSize
= ftell (InFptr
);
2329 fseek (InFptr
, 0, SEEK_SET
);
2331 FileSize
= IDefEntry
->RawDataSize
;
2334 // Find the region/subregion it's in, see if we have space left
2337 for (RegionDef
= FDev
->Regions
; RegionDef
!= NULL
; RegionDef
= RegionDef
->Next
) {
2338 if (strcmp (RegionDef
->Name
, IDefEntry
->RegionName
) == 0) {
2342 Offset
+= RegionDef
->Size
;
2345 if (RegionDef
== NULL
) {
2346 Error (NULL
, 0, 0, IDefEntry
->RegionName
, "Region name not found in FlashDevice %s definition", FDev
->Name
);
2351 // Check for subregion
2353 if (IDefEntry
->SubregionName
[0] != 0) {
2354 for (SubregionDef
= RegionDef
->Subregions
; SubregionDef
!= NULL
; SubregionDef
= SubregionDef
->Next
) {
2355 if (strcmp (SubregionDef
->Name
, IDefEntry
->SubregionName
) == 0) {
2359 Offset
+= SubregionDef
->Size
;
2362 if (SubregionDef
== NULL
) {
2367 IDefEntry
->SubregionName
,
2368 "Subregion name not found in FlashDevice %s.%s Region definition",
2375 // Enough space in the subregion?
2377 if (SubregionDef
->SizeLeft
< (unsigned int) FileSize
) {
2383 "insufficient space in Subregion (at least 0x%X additional bytes required)",
2384 FileSize
- SubregionDef
->SizeLeft
2390 // Read the file into the buffer if it's a file. Otherwise copy the raw data
2392 if (IDefEntry
->IsRawData
== 0) {
2393 if (fread (Buffer
+ Offset
+ (SubregionDef
->Size
- SubregionDef
->SizeLeft
), FileSize
, 1, InFptr
) != 1) {
2394 Error (NULL
, 0, 0, IDefEntry
->Name
, "failed to read file contents");
2402 Buffer
+ Offset
+ (SubregionDef
->Size
- SubregionDef
->SizeLeft
),
2404 IDefEntry
->RawDataSize
2408 SubregionDef
->SizeLeft
-= FileSize
;
2410 // Align based on the Region alignment requirements.
2412 if (RegionDef
->Alignment
!= 0) {
2413 while (((unsigned int) (SubregionDef
->Size
- SubregionDef
->SizeLeft
) &~RegionDef
->Alignment
) != 0) {
2414 if (SubregionDef
->SizeLeft
== 0) {
2418 SubregionDef
->SizeLeft
--;
2423 // Placing data in a region. Check for enough space in the region left.
2425 if (RegionDef
->SizeLeft
< (unsigned int) FileSize
) {
2431 "insufficient space in Region (at least 0x%X additional bytes required)",
2432 FileSize
- RegionDef
->SizeLeft
2438 // Read the file into the buffer if it's a file. Otherwise copy the raw data
2440 if (IDefEntry
->IsRawData
== 0) {
2441 if (fread (Buffer
+ Offset
+ (RegionDef
->Size
- RegionDef
->SizeLeft
), FileSize
, 1, InFptr
) != 1) {
2442 Error (NULL
, 0, 0, IDefEntry
->Name
, "failed to read file contents");
2449 memcpy (Buffer
+ Offset
+ (RegionDef
->Size
- RegionDef
->SizeLeft
), IDefEntry
->RawData
, IDefEntry
->RawDataSize
);
2452 RegionDef
->SizeLeft
-= FileSize
;
2456 if (RegionDef
->Alignment
!= 0) {
2457 while (((unsigned int) (RegionDef
->Size
- RegionDef
->SizeLeft
) &~RegionDef
->Alignment
) != 0) {
2458 if (RegionDef
->SizeLeft
== 0) {
2462 RegionDef
->SizeLeft
--;
2468 if (fwrite (Buffer
, FDev
->Size
, 1, OutFptr
) != 1) {
2469 Error (NULL
, 0, 0, "failed to write buffer contents to output file", NULL
);
2473 Status
= STATUS_SUCCESS
;
2475 if (InFptr
!= NULL
) {
2479 if (Buffer
!= NULL
) {
2483 if (OutFptr
!= NULL
) {
2485 if (Status
== STATUS_ERROR
) {
2495 char *FlashDeviceName
,
2500 Routine Description:
2501 Create a DSC-style output file with equates for flash management.
2504 FlashDeviceName - name of flash device (from the flash definition file)
2506 FileName - name of output file to create
2509 STATUS_SUCCESS - no errors or warnings
2510 STATUS_WARNING - warnings, but no errors, were encountered
2511 STATUS_ERROR - errors were encountered
2516 FLASH_BLOCK_DESCRIPTION
*FBlock
;
2517 FLASH_DEVICE_DESCRIPTION
*FDev
;
2518 unsigned int Offset
;
2519 FLASH_SUBREGION_DESCRIPTION
*Subregion
;
2520 unsigned int SubregionOffset
;
2522 // Find the definition we're supposed to use
2524 for (FDev
= mFlashDevices
; FDev
!= NULL
; FDev
= FDev
->Next
) {
2525 if (strcmp (FDev
->Name
, FlashDeviceName
) == 0) {
2531 Error (NULL
, 0, 0, FlashDeviceName
, "flash device not found in flash definitions");
2532 return STATUS_ERROR
;
2535 if ((OutFptr
= fopen (FileName
, "w")) == NULL
) {
2536 Error (NULL
, 0, 0, FileName
, "failed to open output file for writing");
2537 return STATUS_ERROR
;
2540 // Write the flash base address and size
2542 fprintf (OutFptr
, "\n");
2543 fprintf (OutFptr
, "FLASH_BASE = 0x%08X\n", FDev
->BaseAddress
);
2544 fprintf (OutFptr
, "FLASH_SIZE = 0x%08X\n\n", FDev
->Size
);
2546 // Write flash block size and offset defines
2549 for (FBlock
= FDev
->Regions
; FBlock
!= NULL
; FBlock
= FBlock
->Next
) {
2552 "FLASH_REGION_%s_BASE %*c= 0x%08X\n",
2554 COLUMN2_START
- 40 - strlen (FBlock
->Name
),
2556 Offset
+ FDev
->BaseAddress
2560 "FLASH_REGION_%s_SIZE %*c= 0x%08X\n",
2562 COLUMN2_START
- 40 - strlen (FBlock
->Name
),
2568 "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n",
2570 COLUMN2_START
- 40 - strlen (FBlock
->Name
),
2572 (FBlock
->Size
)/(FDev
->PBlocks
->Size
)
2575 // Create defines for any subregions
2577 SubregionOffset
= 0;
2578 for (Subregion
= FBlock
->Subregions
; Subregion
!= NULL
; Subregion
= Subregion
->Next
) {
2581 "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n",
2584 COLUMN3_START
- 48 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
2586 FDev
->BaseAddress
+ Offset
+ SubregionOffset
2590 "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n",
2593 COLUMN3_START
- 48 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
2599 "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n",
2602 COLUMN3_START
- 48 - strlen (FBlock
->Name
) - strlen (Subregion
->Name
),
2604 Offset
+ SubregionOffset
2607 SubregionOffset
+= Subregion
->Size
;
2610 Offset
+= FBlock
->Size
;
2615 fprintf (OutFptr
, "\n");
2617 return STATUS_SUCCESS
;
2623 Routine Description:
2624 The following buffer management routines are used to encapsulate functionality
2625 for managing a growable data buffer.
2628 BUFFER_DATA - structure that is used to maintain a data buffer
2641 Routine Description:
2643 Create a growable data buffer with default buffer length.
2651 NULL - error occured during data buffer creation
2652 Not NULL - the pointer to the newly created data buffer
2657 BD
= (BUFFER_DATA
*) _malloc (sizeof (BUFFER_DATA
));
2659 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
2663 memset (BD
, 0, sizeof (BUFFER_DATA
));
2664 BD
->BufferStart
= (char *) _malloc (BUFFER_SIZE
);
2665 if (BD
->BufferStart
== NULL
) {
2667 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
2671 BD
->BufferEnd
= BD
->BufferStart
+ BUFFER_SIZE
;
2672 BD
->BufferPos
= BD
->BufferStart
;
2679 BUFFER_DATA
*Buffer
,
2684 Routine Description:
2686 Add a single byte to a growable data buffer, growing the buffer if required.
2690 Buffer - pointer to the growable data buffer to add a single byte to
2691 Data - value of the single byte data to be added
2695 TRUE - the single byte data was successfully added
2696 FALSE - error occurred, the single byte data was not added
2703 // See if we have to grow the buffer
2705 if (Buffer
->BufferPos
>= Buffer
->BufferEnd
) {
2706 Size
= (int) Buffer
->BufferEnd
- (int) Buffer
->BufferStart
;
2707 NewBuffer
= (char *) _malloc (Size
+ BUFFER_SIZE
);
2708 if (NewBuffer
== NULL
) {
2709 Error (__FILE__
, __LINE__
, 0, "memory allocation failure", NULL
);
2713 memcpy (NewBuffer
, Buffer
->BufferStart
, Size
);
2714 _free (Buffer
->BufferStart
);
2715 Buffer
->BufferStart
= NewBuffer
;
2716 Buffer
->BufferPos
= Buffer
->BufferStart
+ Size
;
2717 Buffer
->BufferEnd
= Buffer
->BufferStart
+ Size
+ BUFFER_SIZE
;
2720 *Buffer
->BufferPos
= Data
;
2721 Buffer
->BufferPos
++;
2728 BUFFER_DATA
*Buffer
,
2733 Routine Description:
2735 Free memory used to manage a growable data buffer.
2739 Buffer - pointer to the growable data buffer to be destructed
2740 FreeData - TRUE, free memory containing the buffered data
2741 FALSE, do not free the buffered data memory
2749 if (Buffer
!= NULL
) {
2750 if (FreeData
&& (Buffer
->BufferStart
!= NULL
)) {
2751 _free (Buffer
->BufferStart
);
2761 BUFFER_DATA
*Buffer
,
2766 Routine Description:
2768 Return a pointer and size of the data in a growable data buffer.
2772 Buffer - pointer to the growable data buffer
2773 BufferSize - size of the data in the growable data buffer
2777 pointer of the data in the growable data buffer
2781 *BufferSize
= (int) Buffer
->BufferPos
- (int) Buffer
->BufferStart
;
2782 return Buffer
->BufferStart
;
2788 unsigned int BaseAddr
2792 Routine Description:
2793 Walk a binary image and see if you find anything that looks like a
2797 FDFileName - name of input FD image to parse
2798 BaseAddr - base address of input FD image
2801 STATUS_SUCCESS - no errors or warnings
2802 STATUS_WARNING - warnings, but no errors, were encountered
2803 STATUS_ERROR - errors were encountered
2806 This routine is used for debug purposes only.
2813 EFI_FIRMWARE_VOLUME_HEADER FVHeader
;
2815 FileSystemGuid
= { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF };
2817 if ((InFptr
= fopen (FDFileName
, "rb")) == NULL
) {
2818 Error (NULL
, 0, 0, FDFileName
, "failed to open file for reading");
2819 return STATUS_ERROR
;
2822 fseek (InFptr
, 0, SEEK_END
);
2823 FileSize
= ftell (InFptr
);
2824 fseek (InFptr
, 0, SEEK_SET
);
2826 while (Offset
< FileSize
) {
2827 fseek (InFptr
, Offset
, SEEK_SET
);
2829 // Read the contents of the file, see if it's an FV header
2831 if (fread (&FVHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
), 1, InFptr
) == 1) {
2833 // Check version and GUID
2835 if ((FVHeader
.Revision
== EFI_FVH_REVISION
) && (FVHeader
.Signature
== EFI_FVH_SIGNATURE
)) {
2836 fprintf (stdout
, "FV header at 0x%08X FVSize=0x%08X ", Offset
+ BaseAddr
, (UINT32
) FVHeader
.FvLength
);
2837 if (memcmp (&FVHeader
.FileSystemGuid
, &FileSystemGuid
, sizeof (EFI_GUID
)) == 0) {
2838 fprintf (stdout
, "standard FFS file system\n");
2840 fprintf (stdout
, "non-standard FFS file system\n");
2845 Offset
+= 16 * 1024;
2849 return STATUS_SUCCESS
;