]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/FlashMap/FlashDefFile.c
Porting several more tools to edk2.
[mirror_edk2.git] / Tools / Source / TianoTools / FlashMap / FlashDefFile.c
1 /*++
2
3 Copyright (c) 2004-2005 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
10 Intel Corporation.
11
12
13 Module Name:
14
15 FlashDefFile.c
16
17 Abstract:
18
19 Utility for flash management in the Intel Platform Innovation Framework
20 for EFI build environment.
21
22 --*/
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <UefiBaseTypes.h>
28 #include <Base.h>
29
30 #include "EfiUtilityMsgs.h"
31 #include "FlashDefFile.h"
32 #include "SimpleFileParsing.h"
33 #include "Symbols.h"
34 // #include "EfiFirmwareVolumeHeader.h"
35 #include "MultiPhase.h"
36 #include "FirmwareVolumeHeader.h"
37
38 //
39 // #include "TrackMallocFree.h"
40 //
41 #define WCHAR_T char
42 #define MAX_STRING_LEN 256
43 #define MAX_NAME_LEN 128
44 #define BUFFER_SIZE 1024
45 #define MAX_ATTR_LEN 128
46 #define MAX_AREATYPE_LEN 128
47 #define COLUMN2_START 60
48 #define COLUMN3_START 70
49 //
50 // Information for each subregions defined in the fdf file will be saved in these
51 //
52 typedef struct _FLASH_SUBREGION_DESCRIPTION {
53 struct _FLASH_SUBREGION_DESCRIPTION *Next;
54 int CreateHob; // to add to the auto-created HOB array
55 WCHAR_T Name[MAX_NAME_LEN]; // each subregion within a region must have a unique name
56 unsigned int Size; // size, in bytes, of this subregion
57 unsigned int SizeLeft; // used when creating the image
58 WCHAR_T Attributes[MAX_ATTR_LEN]; // subregion attributes used in the output HOB
59 WCHAR_T AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB
60 EFI_GUID NameGuid; // used in the output HOB
61 WCHAR_T NameGuidString[MAX_NAME_LEN];
62 EFI_GUID AreaTypeGuid; // used in the output HOB
63 WCHAR_T AreaTypeGuidString[MAX_NAME_LEN];
64 EFI_GUID FileSystemGuid; // used in the output HOB
65 WCHAR_T FileSystemGuidString[MAX_NAME_LEN];
66 } FLASH_SUBREGION_DESCRIPTION;
67
68 //
69 // Information for each block in a flash device will be saved in one of these.
70 // We'll also use it for region definitions.
71 //
72 typedef struct _FLASH_BLOCK_DESCRIPTION {
73 struct _FLASH_BLOCK_DESCRIPTION *Next; // next block in the linked list
74 WCHAR_T Name[MAX_NAME_LEN]; // each block must have a unique name
75 unsigned int Size; // size, in bytes, of this block
76 unsigned int SizeLeft; // for use when creating image
77 unsigned int Flags; // user-defined flags for the block
78 unsigned int Alignment; // power of 2 alignment
79 WCHAR_T Attributes[MAX_ATTR_LEN]; // only used for Region definitions
80 WCHAR_T AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions
81 FLASH_SUBREGION_DESCRIPTION *Subregions;
82 FLASH_SUBREGION_DESCRIPTION *LastSubregion;
83 } FLASH_BLOCK_DESCRIPTION;
84
85 //
86 // Information for each flash device will be saved in one of these
87 //
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;
99
100 //
101 // For image definitions, they can specify a file name or raw data bytes. Keep a linked list.
102 //
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;
110 char *RawData;
111 int Optional; // optional file (don't include if it doesn't exist)
112 } IMAGE_DEFINITION_ENTRY;
113
114 //
115 // When we parse an image definition, save all the data for each in one of these
116 //
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;
122 } IMAGE_DEFINITION;
123
124 typedef struct {
125 char *BufferStart;
126 char *BufferEnd;
127 char *BufferPos;
128 } BUFFER_DATA;
129
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";
133 //
134 // "#include \"EfiFlashMap.h\"\n\n";
135 //
136 static const char *CIncludeFooter = "#endif // #ifndef _FLASH_MAP_H_\n\n";
137
138 static const char *CFlashMapDataFileHeader = "/*++\n\n"
139 " DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n";
140
141 static FLASH_DEVICE_DESCRIPTION *mFlashDevices = NULL;
142 static IMAGE_DEFINITION *mImageDefinitions = NULL;
143
144 //
145 // Local function prototypes
146 //
147 static
148 BUFFER_DATA *
149 CreateBufferData (
150 VOID
151 );
152
153 static
154 BOOLEAN
155 AddBufferDataByte (
156 BUFFER_DATA *Buffer,
157 char Data
158 );
159
160 static
161 void
162 FreeBufferData (
163 BUFFER_DATA *Buffer,
164 BOOLEAN FreeData
165 );
166
167 static
168 char *
169 GetBufferData (
170 BUFFER_DATA *Buffer,
171 int *BufferSize
172 );
173
174 static
175 FLASH_SUBREGION_DESCRIPTION *
176 ParseSubregionDefinition (
177 unsigned int SizeLeft
178 );
179
180 void
181 FDFConstructor (
182 VOID
183 )
184 /*++
185
186 Routine Description:
187 Initialization routine for the services that operate on a flash
188 definition file.
189
190 Arguments:
191 None.
192
193 Returns:
194 NA
195
196 --*/
197 {
198 mFlashDevices = NULL;
199 mImageDefinitions = NULL;
200 }
201
202 void
203 FDFDestructor (
204 VOID
205 )
206 /*++
207
208 Routine Description:
209 Finalization/cleanup routine for the services that operate on a flash
210 definition file.
211
212 Arguments:
213 None.
214
215 Returns:
216 NA
217
218 --*/
219 {
220 FLASH_BLOCK_DESCRIPTION *FBNext;
221 FLASH_DEVICE_DESCRIPTION *FDNext;
222 IMAGE_DEFINITION *IDNext;
223 IMAGE_DEFINITION_ENTRY *IDENext;
224 FLASH_SUBREGION_DESCRIPTION *SubNext;
225 //
226 // Go through all our flash devices and free the memory
227 //
228 while (mFlashDevices != NULL) {
229 //
230 // Free the physical block definitions
231 //
232 while (mFlashDevices->PBlocks != NULL) {
233 FBNext = mFlashDevices->PBlocks->Next;
234 _free (mFlashDevices->PBlocks);
235 mFlashDevices->PBlocks = FBNext;
236 }
237 //
238 // Free the region definitions
239 //
240 while (mFlashDevices->Regions != NULL) {
241 FBNext = mFlashDevices->Regions->Next;
242 //
243 // First free the subregion definitions
244 //
245 while (mFlashDevices->Regions->Subregions != NULL) {
246 SubNext = mFlashDevices->Regions->Subregions->Next;
247 _free (mFlashDevices->Regions->Subregions);
248 mFlashDevices->Regions->Subregions = SubNext;
249 }
250
251 _free (mFlashDevices->Regions);
252 mFlashDevices->Regions = FBNext;
253 }
254
255 FDNext = mFlashDevices->Next;
256 _free (mFlashDevices);
257 mFlashDevices = FDNext;
258 }
259 //
260 // Free up the image definitions, and the data
261 //
262 while (mImageDefinitions != NULL) {
263 //
264 // Free the entries
265 //
266 while (mImageDefinitions->Entries != NULL) {
267 IDENext = mImageDefinitions->Entries->Next;
268 if (mImageDefinitions->Entries->RawData != NULL) {
269 _free (mImageDefinitions->Entries->RawData);
270 }
271
272 _free (mImageDefinitions->Entries);
273 mImageDefinitions->Entries = IDENext;
274 }
275
276 IDNext = mImageDefinitions->Next;
277 _free (mImageDefinitions);
278 mImageDefinitions = IDNext;
279 }
280 }
281
282 STATUS
283 FDFParseFile (
284 char *FileName
285 )
286 /*++
287
288 Routine Description:
289 Parse the specified flash definition file, saving the definitions in
290 file-static variables for use by other functions.
291
292 Arguments:
293 FileName - name of the input flash definition text file.
294
295 Returns:
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
299
300 --*/
301 {
302 FILE *Fptr;
303 STATUS Status;
304 unsigned int Num;
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;
313 int ErrorCount;
314 int WarningCount;
315 IMAGE_DEFINITION *ImageDef;
316 IMAGE_DEFINITION_ENTRY *ImageDefEntry;
317 IMAGE_DEFINITION_ENTRY *TempImageDefEntry;
318 BUFFER_DATA *BufferData;
319 char Str[100];
320 BOOLEAN PreviousComma;
321
322 if ((Fptr = fopen (FileName, "r")) == NULL) {
323 Error (NULL, 0, 0, FileName, "failed to open input flash definition file for reading");
324 return STATUS_ERROR;
325 }
326
327 fclose (Fptr);
328 Status = STATUS_SUCCESS;
329 ErrorCount = 0;
330 WarningCount = 0;
331 //
332 // Initialize the simple-file-parsing routines
333 //
334 SFPInit ();
335 //
336 // Open the file
337 //
338 if ((Status = SFPOpenFile (FileName)) != STATUS_SUCCESS) {
339 return Status;
340 }
341 //
342 // Parse the file. Should start with a series of these:
343 // FlashDevice {
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 }
348 // }
349 //
350 while (SFPIsKeyword ("FlashDevice")) {
351 //
352 // Allocate memory for new flash device description block
353 //
354 FDDesc = (FLASH_DEVICE_DESCRIPTION *) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION));
355 if (FDDesc == NULL) {
356 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
357 ErrorCount++;
358 goto Done;
359 }
360
361 memset (FDDesc, 0, sizeof (FLASH_DEVICE_DESCRIPTION));
362 //
363 // Open brace -- warning if not there
364 //
365 if (!SFPIsToken ("{")) {
366 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
367 WarningCount++;
368 }
369 //
370 // Parse: Name = "DeviceName",
371 //
372 if (!SFPIsKeyword ("Name")) {
373 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
374 ErrorCount++;
375 goto Done;
376 }
377
378 if (!SFPIsToken ("=")) {
379 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
380 WarningCount++;
381 }
382
383 if (!SFPGetQuotedString (FDDesc->Name, sizeof (FDDesc->Name))) {
384 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL);
385 ErrorCount++;
386 goto Done;
387 }
388
389 if (!SFPIsToken (",")) {
390 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL);
391 WarningCount++;
392 }
393 //
394 // Parse: Size = 0x20000,
395 //
396 if (!SFPIsKeyword ("Size")) {
397 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
398 ErrorCount++;
399 goto Done;
400 }
401
402 if (!SFPIsToken ("=")) {
403 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
404 WarningCount++;
405 }
406
407 if (!SFPGetNumber (&FDDesc->Size)) {
408 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
409 ErrorCount++;
410 goto Done;
411 }
412 //
413 // Check for 0 size
414 //
415 if (FDDesc->Size == 0) {
416 Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc->Name, "Size field cannot be 0", NULL);
417 ErrorCount++;
418 goto Done;
419 }
420
421 SFPIsToken (",");
422 //
423 // Parse: BaseAddress = 0xFFF0000,
424 //
425 if (!SFPIsKeyword ("BaseAddress")) {
426 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL);
427 ErrorCount++;
428 goto Done;
429 }
430
431 if (!SFPIsToken ("=")) {
432 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
433 WarningCount++;
434 }
435
436 if (!SFPGetNumber (&FDDesc->BaseAddress)) {
437 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL);
438 ErrorCount++;
439 goto Done;
440 }
441
442 if (!SFPIsToken (",")) {
443 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL);
444 WarningCount++;
445 }
446 //
447 // Parse: ErasePolarity = 1,
448 //
449 if (!SFPIsKeyword ("ErasePolarity")) {
450 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL);
451 ErrorCount++;
452 goto Done;
453 }
454
455 if (!SFPIsToken ("=")) {
456 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
457 WarningCount++;
458 }
459
460 if (!SFPGetNumber (&Num) || ((Num != 0) && (Num != 1))) {
461 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL);
462 ErrorCount++;
463 goto Done;
464 }
465
466 FDDesc->ErasePolarity = Num;
467 if (!SFPIsToken (",")) {
468 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL);
469 WarningCount++;
470 }
471 //
472 // Parse array of:
473 // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 }
474 //
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.
477 //
478 BlockSizeLeft = FDDesc->Size;
479 RegionSizeLeft = FDDesc->Size;
480 while (SFPIsKeyword ("Block")) {
481 //
482 // Allocate memory for a new physical block descriptor
483 //
484 FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));
485 if (FBlockDesc == NULL) {
486 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
487 ErrorCount++;
488 goto Done;
489 }
490
491 memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));
492 //
493 // Open brace -- warning if not there
494 //
495 if (!SFPIsToken ("{")) {
496 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
497 WarningCount++;
498 }
499 //
500 // Parse: Name = "BlockName",
501 //
502 if (!SFPIsKeyword ("Name")) {
503 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
504 ErrorCount++;
505 goto Done;
506 }
507
508 if (!SFPIsToken ("=")) {
509 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
510 WarningCount++;
511 }
512
513 if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {
514 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL);
515 ErrorCount++;
516 goto Done;
517 }
518 //
519 // Make sure there are no other physical block names with this same name
520 //
521 for (TempBlockDesc = FDDesc->PBlocks; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {
522 if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {
523 Error (
524 SFPGetFileName (),
525 SFPGetLineNumber (),
526 0,
527 TempBlockDesc->Name,
528 "physical block with this name already defined"
529 );
530 ErrorCount++;
531 }
532 }
533
534 if (!SFPIsToken (",")) {
535 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL);
536 WarningCount++;
537 }
538 //
539 // Parse: Size = 0x2000,
540 //
541 if (!SFPIsKeyword ("Size")) {
542 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
543 ErrorCount++;
544 goto Done;
545 }
546
547 if (!SFPIsToken ("=")) {
548 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
549 WarningCount++;
550 }
551
552 if (!SFPGetNumber (&FBlockDesc->Size)) {
553 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
554 ErrorCount++;
555 goto Done;
556 }
557 //
558 // Make sure the sum of physical blocks so far does not exceed flash device size
559 //
560 if (BlockSizeLeft < FBlockDesc->Size) {
561 Error (
562 SFPGetFileName (),
563 SFPGetLineNumber (),
564 0,
565 "sum of physical block sizes exceeds flash device size",
566 NULL
567 );
568 ErrorCount++;
569 }
570
571 BlockSizeLeft -= FBlockDesc->Size;
572 SFPIsToken (",");
573 //
574 // Optional parse: Flags = 0xFFF0000,
575 //
576 if (SFPIsKeyword ("Flags")) {
577 if (!SFPIsToken ("=")) {
578 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
579 WarningCount++;
580 }
581
582 if (!SFPGetNumber (&FBlockDesc->Flags)) {
583 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);
584 ErrorCount++;
585 goto Done;
586 }
587 }
588
589 if (!SFPIsToken ("}")) {
590 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL);
591 WarningCount++;
592 }
593 //
594 // Add the physical block descriptor to the end of the linked list
595 //
596 if (FDDesc->LastPBlock != NULL) {
597 FDDesc->LastPBlock->Next = FBlockDesc;
598 } else {
599 FDDesc->PBlocks = FBlockDesc;
600 }
601
602 FDDesc->LastPBlock = FBlockDesc;
603 }
604 //
605 // Make sure sum of sizes of physical blocks added up to size of flash device
606 //
607 if (BlockSizeLeft != 0) {
608 Error (
609 SFPGetFileName (),
610 SFPGetLineNumber (),
611 0,
612 NULL,
613 "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",
614 FDDesc->Size - BlockSizeLeft,
615 FDDesc->Size,
616 BlockSizeLeft
617 );
618 ErrorCount++;
619 }
620 //
621 // Parse array of:
622 // Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" }
623 //
624 while (SFPIsKeyword ("Region")) {
625 //
626 // Allocate memory for a new physical block descriptor
627 //
628 FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION));
629 if (FBlockDesc == NULL) {
630 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
631 ErrorCount++;
632 goto Done;
633 }
634
635 memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION));
636 //
637 // Open brace -- warning if not there
638 //
639 if (!SFPIsToken ("{")) {
640 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
641 WarningCount++;
642 }
643 //
644 // Parse: Name = "BlockName",
645 //
646 if (!SFPIsKeyword ("Name")) {
647 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
648 ErrorCount++;
649 goto Done;
650 }
651
652 if (!SFPIsToken ("=")) {
653 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
654 WarningCount++;
655 }
656
657 if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) {
658 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);
659 ErrorCount++;
660 goto Done;
661 }
662 //
663 // Make sure there are no other region names with this same name
664 //
665 for (TempBlockDesc = FDDesc->Regions; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) {
666 if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) {
667 Error (
668 SFPGetFileName (),
669 SFPGetLineNumber (),
670 0,
671 TempBlockDesc->Name,
672 "Region with this name already defined"
673 );
674 ErrorCount++;
675 }
676 }
677
678 if (!SFPIsToken (",")) {
679 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
680 WarningCount++;
681 }
682 //
683 // Parse: Size = 0x2000,
684 //
685 if (!SFPIsKeyword ("Size")) {
686 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
687 ErrorCount++;
688 goto Done;
689 }
690
691 if (!SFPIsToken ("=")) {
692 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
693 WarningCount++;
694 }
695
696 if (!SFPGetNumber (&FBlockDesc->Size)) {
697 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
698 ErrorCount++;
699 goto Done;
700 }
701
702 if (!SFPIsToken (",")) {
703 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
704 }
705 //
706 // Make sure the sum of regions so far does not exceed flash device size
707 //
708 if (RegionSizeLeft < FBlockDesc->Size) {
709 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL);
710 ErrorCount++;
711 }
712
713 RegionSizeLeft -= FBlockDesc->Size;
714 //
715 // Optional parse: Flags = 0xFFF0000,
716 //
717 if (SFPIsKeyword ("Flags")) {
718 if (!SFPIsToken ("=")) {
719 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
720 WarningCount++;
721 }
722
723 if (!SFPGetNumber (&FBlockDesc->Flags)) {
724 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL);
725 ErrorCount++;
726 goto Done;
727 }
728 //
729 // comma
730 //
731 if (!SFPIsToken (",")) {
732 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
733 }
734 }
735 //
736 // Optional parse: Alignment = 4
737 //
738 if (SFPIsKeyword ("Alignment")) {
739 if (!SFPIsToken ("=")) {
740 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
741 WarningCount++;
742 }
743
744 if (!SFPGetNumber (&FBlockDesc->Alignment)) {
745 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL);
746 ErrorCount++;
747 goto Done;
748 }
749 //
750 // comma
751 //
752 if (!SFPIsToken (",")) {
753 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
754 }
755 }
756 //
757 // Parse: Attributes = "String",
758 //
759 if (!SFPIsKeyword ("Attributes")) {
760 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);
761 ErrorCount++;
762 goto Done;
763 }
764
765 if (!SFPIsToken ("=")) {
766 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
767 WarningCount++;
768 }
769
770 if (!SFPGetQuotedString (FBlockDesc->Attributes, sizeof (FBlockDesc->Attributes))) {
771 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);
772 ErrorCount++;
773 goto Done;
774 }
775
776 if (!SFPIsToken (",")) {
777 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
778 }
779 //
780 // Parse: AreaType = "String",
781 //
782 if (!SFPIsKeyword ("AreaType")) {
783 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);
784 ErrorCount++;
785 goto Done;
786 }
787
788 if (!SFPIsToken ("=")) {
789 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
790 WarningCount++;
791 }
792
793 if (!SFPGetQuotedString (FBlockDesc->AreaType, sizeof (FBlockDesc->AreaType))) {
794 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);
795 ErrorCount++;
796 goto Done;
797 }
798
799 PreviousComma = SFPIsToken (",");
800 //
801 // Parse optional Subregion definitions
802 //
803 SubregionSizeLeft = FBlockDesc->Size;
804 while (SFPIsToken ("Subregion")) {
805 if (!PreviousComma) {
806 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL);
807 WarningCount++;
808 PreviousComma = TRUE;
809 }
810
811 Subregion = ParseSubregionDefinition (SubregionSizeLeft);
812 if (Subregion == NULL) {
813 ErrorCount++;
814 goto Done;
815 }
816
817 SubregionSizeLeft -= Subregion->Size;
818 //
819 // Add it to the end of our list
820 //
821 if (FBlockDesc->Subregions == NULL) {
822 FBlockDesc->Subregions = Subregion;
823 } else {
824 FBlockDesc->LastSubregion->Next = Subregion;
825 }
826
827 FBlockDesc->LastSubregion = Subregion;
828 //
829 // Make sure all subregion names are unique. We do this each time
830 // through so that we catch the error immediately after it happens, in
831 // which case the reported line number is at least close to where the
832 // problem lies. We don't exit on the error because we can continue parsing
833 // the script to perhaps catch other errors or warnings.
834 //
835 for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
836 for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) {
837 if (strcmp (Subregion->Name, TempSubregion->Name) == 0) {
838 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name");
839 ErrorCount++;
840 }
841 }
842 }
843 }
844
845 if (!SFPIsToken ("}")) {
846 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL);
847 WarningCount++;
848 }
849 //
850 // Add the region descriptor to the end of the linked list
851 //
852 if (FDDesc->LastRegion != NULL) {
853 FDDesc->LastRegion->Next = FBlockDesc;
854 } else {
855 FDDesc->Regions = FBlockDesc;
856 }
857
858 FDDesc->LastRegion = FBlockDesc;
859 }
860 //
861 // Make sure sum of sizes of regions adds up to size of flash device
862 //
863 if (RegionSizeLeft != 0) {
864 Error (
865 SFPGetFileName (),
866 SFPGetLineNumber (),
867 0,
868 NULL,
869 "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",
870 FDDesc->Size - RegionSizeLeft,
871 FDDesc->Size,
872 RegionSizeLeft
873 );
874 ErrorCount++;
875 }
876 //
877 // Look for closing brace
878 //
879 if (!SFPIsToken ("}")) {
880 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL);
881 WarningCount++;
882 }
883 //
884 // Add this flash description to the list
885 //
886 FDDesc->Next = mFlashDevices;
887 mFlashDevices = FDDesc;
888 }
889
890 while (SFPIsKeyword ("FlashDeviceImage")) {
891 //
892 // Allocate memory for a new FD image definition
893 //
894 ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION));
895 if (ImageDef == NULL) {
896 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
897 ErrorCount++;
898 goto Done;
899 }
900
901 memset (ImageDef, 0, sizeof (IMAGE_DEFINITION));
902 //
903 // Open brace -- warning if not there
904 //
905 if (!SFPIsToken ("{")) {
906 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
907 WarningCount++;
908 }
909 //
910 // Parse: Name = "ImageName",
911 //
912 if (!SFPIsKeyword ("Name")) {
913 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
914 ErrorCount++;
915 goto Done;
916 }
917
918 if (!SFPIsToken ("=")) {
919 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
920 WarningCount++;
921 }
922
923 if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) {
924 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL);
925 ErrorCount++;
926 goto Done;
927 }
928
929 if (!SFPIsToken (",")) {
930 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL);
931 WarningCount++;
932 }
933
934 while (1) {
935 //
936 // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE }
937 //
938 if (SFPIsKeyword ("File")) {
939 ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));
940 if (ImageDefEntry == NULL) {
941 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
942 ErrorCount++;
943 goto Done;
944 }
945
946 memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));
947 //
948 // Open brace -- warning if not there
949 //
950 if (!SFPIsToken ("{")) {
951 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
952 WarningCount++;
953 }
954 //
955 // Parse: Name = "FileName.txt"
956 //
957 if (!SFPIsKeyword ("Name")) {
958 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
959 ErrorCount++;
960 goto Done;
961 }
962
963 if (!SFPIsToken ("=")) {
964 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
965 WarningCount++;
966 }
967
968 if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {
969 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL);
970 ErrorCount++;
971 goto Done;
972 }
973
974 if (!SFPIsToken (",")) {
975 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL);
976 WarningCount++;
977 }
978 //
979 // Parse: Region = "REGION_NAME"
980 //
981 if (!SFPIsKeyword ("Region")) {
982 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);
983 ErrorCount++;
984 goto Done;
985 }
986
987 if (!SFPIsToken ("=")) {
988 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
989 WarningCount++;
990 }
991
992 if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {
993 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);
994 ErrorCount++;
995 goto Done;
996 }
997
998 if (!SFPIsToken (",")) {
999 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
1000 WarningCount++;
1001 }
1002 //
1003 // Parse optional: Subregion = "SUBREGION_NAME"
1004 //
1005 if (SFPIsKeyword ("Subregion")) {
1006 if (!SFPIsToken ("=")) {
1007 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1008 WarningCount++;
1009 }
1010
1011 if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {
1012 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);
1013 ErrorCount++;
1014 goto Done;
1015 }
1016
1017 if (!SFPIsToken (",")) {
1018 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);
1019 WarningCount++;
1020 }
1021 //
1022 // For a given region, you can only place data using the region name, or the subregion names.
1023 // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that
1024 // here by checking that any previous entries with the same Region name had a Subregion specified
1025 // as well.
1026 //
1027 for (TempImageDefEntry = ImageDef->Entries;
1028 TempImageDefEntry != NULL;
1029 TempImageDefEntry = TempImageDefEntry->Next
1030 ) {
1031 if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {
1032 if (TempImageDefEntry->SubregionName[0] == 0) {
1033 Error (
1034 SFPGetFileName (),
1035 SFPGetLineNumber (),
1036 0,
1037 TempImageDefEntry->RegionName,
1038 "data already placed on a region-basis in the region, can't place data using subregions"
1039 );
1040 ErrorCount++;
1041 }
1042 }
1043 }
1044 }
1045 //
1046 // Optional parse: Optional = TRUE | FALSE
1047 //
1048 if (SFPIsKeyword ("Optional")) {
1049 if (!SFPIsToken ("=")) {
1050 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1051 WarningCount++;
1052 }
1053
1054 if (!SFPIsKeyword ("TRUE")) {
1055 ImageDefEntry->Optional = 1;
1056 } else if (SFPIsKeyword ("FALSE")) {
1057 //
1058 // Already set to 0
1059 //
1060 } else {
1061 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
1062 ErrorCount++;
1063 goto Done;
1064 }
1065
1066 SFPIsToken (",");
1067 }
1068 //
1069 // Closing brace
1070 //
1071 if (!SFPIsToken ("}")) {
1072 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL);
1073 ErrorCount++;
1074 goto Done;
1075 }
1076 //
1077 // Add the entry to the end of the list
1078 //
1079 if (ImageDef->LastEntry != NULL) {
1080 ImageDef->LastEntry->Next = ImageDefEntry;
1081 } else {
1082 ImageDef->Entries = ImageDefEntry;
1083 }
1084
1085 ImageDef->LastEntry = ImageDefEntry;
1086 } else if (SFPIsKeyword ("RawData")) {
1087 //
1088 // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }}
1089 //
1090 ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));
1091 if (ImageDefEntry == NULL) {
1092 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
1093 ErrorCount++;
1094 goto Done;
1095 }
1096
1097 memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));
1098 ImageDefEntry->IsRawData = 1;
1099 //
1100 // Open brace -- warning if not there
1101 //
1102 if (!SFPIsToken ("{")) {
1103 Warning (
1104 SFPGetFileName (),
1105 SFPGetLineNumber (),
1106 0,
1107 "expected '{' opening brace for RawData definition",
1108 NULL
1109 );
1110 WarningCount++;
1111 }
1112 //
1113 // Parse: Name = "PadBytes"
1114 //
1115 if (!SFPIsKeyword ("Name")) {
1116 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
1117 ErrorCount++;
1118 goto Done;
1119 }
1120
1121 if (!SFPIsToken ("=")) {
1122 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1123 WarningCount++;
1124 }
1125
1126 if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {
1127 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL);
1128 ErrorCount++;
1129 goto Done;
1130 }
1131
1132 if (!SFPIsToken (",")) {
1133 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL);
1134 WarningCount++;
1135 }
1136 //
1137 // Parse: Region = "REGION_NAME"
1138 //
1139 if (!SFPIsKeyword ("Region")) {
1140 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);
1141 ErrorCount++;
1142 goto Done;
1143 }
1144
1145 if (!SFPIsToken ("=")) {
1146 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1147 WarningCount++;
1148 }
1149
1150 if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {
1151 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);
1152 ErrorCount++;
1153 goto Done;
1154 }
1155
1156 if (!SFPIsToken (",")) {
1157 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
1158 WarningCount++;
1159 }
1160 //
1161 // Parse optional: Subregion = "SUBREGION_NAME"
1162 //
1163 if (SFPIsKeyword ("Subregion")) {
1164 if (!SFPIsToken ("=")) {
1165 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1166 WarningCount++;
1167 }
1168
1169 if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {
1170 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);
1171 ErrorCount++;
1172 goto Done;
1173 }
1174
1175 if (!SFPIsToken (",")) {
1176 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);
1177 WarningCount++;
1178 }
1179 //
1180 // For a given region, you can only place data using the region name, or the subregion names.
1181 // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that
1182 // here by checking that any previous entries with the same Region name had a Subregion specified
1183 // as well.
1184 //
1185 for (TempImageDefEntry = ImageDef->Entries;
1186 TempImageDefEntry != NULL;
1187 TempImageDefEntry = TempImageDefEntry->Next
1188 ) {
1189 if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {
1190 if (TempImageDefEntry->SubregionName[0] == 0) {
1191 Error (
1192 SFPGetFileName (),
1193 SFPGetLineNumber (),
1194 0,
1195 TempImageDefEntry->RegionName,
1196 "data already placed on a region-basis in the region, can't place data using subregions"
1197 );
1198 ErrorCount++;
1199 }
1200 }
1201 }
1202 }
1203 //
1204 // Parse: Data = { 0x78, 0x56, 0x34, 0x12 }
1205 //
1206 if (!SFPIsKeyword ("Data")) {
1207 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL);
1208 ErrorCount++;
1209 goto Done;
1210 }
1211
1212 if (!SFPIsToken ("=")) {
1213 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1214 WarningCount++;
1215 }
1216
1217 if (!SFPIsToken ("{")) {
1218 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL);
1219 WarningCount++;
1220 }
1221
1222 if ((BufferData = CreateBufferData ()) == NULL) {
1223 ErrorCount++;
1224 goto Done;
1225 }
1226 //
1227 // Read bytes from input file until closing brace
1228 //
1229 while (!SFPIsToken ("}")) {
1230 if (!SFPGetNumber (&Num)) {
1231 SFPGetNextToken (Str, sizeof (Str));
1232 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str);
1233 ErrorCount++;
1234 FreeBufferData (BufferData, TRUE);
1235 goto Done;
1236 } else {
1237 //
1238 // Only allow bytes
1239 //
1240 if (Num > 0xFF) {
1241 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL);
1242 ErrorCount++;
1243 FreeBufferData (BufferData, TRUE);
1244 goto Done;
1245 }
1246
1247 AddBufferDataByte (BufferData, (char) Num);
1248 SFPIsToken (",");
1249 }
1250 }
1251 //
1252 // Now get the data and save it in our image entry
1253 //
1254 ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize);
1255 FreeBufferData (BufferData, 0);
1256 //
1257 // Closing brace for RawData {}
1258 //
1259 if (!SFPIsToken ("}")) {
1260 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL);
1261 ErrorCount++;
1262 goto Done;
1263 }
1264 //
1265 // Add the entry to the end of the list
1266 //
1267 if (ImageDef->LastEntry != NULL) {
1268 ImageDef->LastEntry->Next = ImageDefEntry;
1269 } else {
1270 ImageDef->Entries = ImageDefEntry;
1271 }
1272
1273 ImageDef->LastEntry = ImageDefEntry;
1274 } else if (SFPIsToken ("}")) {
1275 //
1276 // Closing brace for FDImage {}
1277 //
1278 break;
1279 } else {
1280 SFPGetNextToken (Str, sizeof (Str));
1281 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str);
1282 ErrorCount++;
1283 goto Done;
1284 }
1285 }
1286 //
1287 // Add this image definition to our global list
1288 //
1289 ImageDef->Next = mImageDefinitions;
1290 mImageDefinitions = ImageDef;
1291 }
1292 //
1293 // Check for end-of-file
1294 //
1295 if (!SFPIsEOF ()) {
1296 SFPGetNextToken (Str, sizeof (Str));
1297 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str);
1298 ErrorCount++;
1299 }
1300
1301 Done:
1302 SFPCloseFile ();
1303 if (ErrorCount != 0) {
1304 return STATUS_ERROR;
1305 } else if (WarningCount != 0) {
1306 return STATUS_WARNING;
1307 }
1308
1309 return STATUS_SUCCESS;
1310 }
1311
1312 static
1313 FLASH_SUBREGION_DESCRIPTION *
1314 ParseSubregionDefinition (
1315 unsigned int SizeLeft
1316 )
1317 /*++
1318
1319 Routine Description:
1320
1321 Parse Subregion definitions from the input flash definition file. Format:
1322
1323 Subregion {
1324 CreateHob = TRUE,
1325 Name = "FOO",
1326 Size = 0xA000,
1327 Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV",
1328 AreaType = "EFI_FLASH_AREA_EFI_VARIABLES",
1329 NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"),
1330 AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)
1331 FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)
1332 }
1333
1334 NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace.
1335
1336 Arguments:
1337
1338 SizeLeft - in the flash definition file, a Region can be broken up into
1339 one or more subregions. As we parse the subregion definitions,
1340 the caller keeps track of how much space is left in the region
1341 that we're parsing subregions for. SizeLeft is that size, and
1342 so the size of the subregion we're now parsing better not
1343 exceed the size left.
1344 Returns:
1345
1346 NULL - unrecoverable errors detected while parsing the subregion definition
1347
1348 pointer to a subregion definition created from the parsed subregion
1349
1350 --*/
1351 {
1352 FLASH_SUBREGION_DESCRIPTION *Subregion;
1353 int ErrorCount;
1354 int WarningCount;
1355 unsigned int Number;
1356 BOOLEAN PreviousComma;
1357 //
1358 // Allocate memory for the new subregion descriptor
1359 //
1360 ErrorCount = 0;
1361 WarningCount = 0;
1362 Subregion = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION));
1363 if (Subregion == NULL) {
1364 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
1365 ErrorCount++;
1366 goto Done;
1367 }
1368
1369 memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION));
1370 //
1371 // Open brace -- warning if not there
1372 //
1373 if (!SFPIsToken ("{")) {
1374 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);
1375 WarningCount++;
1376 }
1377 //
1378 // Parse: CreateHob = TRUE | FALSE,
1379 //
1380 if (!SFPIsKeyword ("CreateHob")) {
1381 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL);
1382 ErrorCount++;
1383 goto Done;
1384 }
1385
1386 if (!SFPIsToken ("=")) {
1387 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1388 WarningCount++;
1389 }
1390
1391 if (SFPIsToken ("TRUE")) {
1392 Subregion->CreateHob = 1;
1393 } else if (SFPIsToken ("FALSE")) {
1394 //
1395 // Subregion->CreateHob = 0; -- not required since we did a memset earlier
1396 //
1397 } else {
1398 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);
1399 ErrorCount++;
1400 goto Done;
1401 }
1402
1403 if (!SFPIsToken (",")) {
1404 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL);
1405 WarningCount++;
1406 }
1407 //
1408 // Parse: Name = "Name",
1409 //
1410 if (!SFPIsKeyword ("Name")) {
1411 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);
1412 ErrorCount++;
1413 goto Done;
1414 }
1415
1416 if (!SFPIsToken ("=")) {
1417 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1418 WarningCount++;
1419 }
1420
1421 if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) {
1422 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL);
1423 ErrorCount++;
1424 goto Done;
1425 }
1426
1427 if (!SFPIsToken (",")) {
1428 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);
1429 WarningCount++;
1430 }
1431 //
1432 // Parse: Size = 0x2000,
1433 //
1434 if (!SFPIsKeyword ("Size")) {
1435 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);
1436 ErrorCount++;
1437 goto Done;
1438 }
1439
1440 if (!SFPIsToken ("=")) {
1441 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1442 WarningCount++;
1443 }
1444
1445 if (!SFPGetNumber (&Subregion->Size)) {
1446 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);
1447 ErrorCount++;
1448 goto Done;
1449 }
1450
1451 //
1452 // Check that the size does not exceed the size left passed in
1453 //
1454 if (Subregion->Size > SizeLeft) {
1455 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL);
1456 ErrorCount++;
1457 goto Done;
1458 }
1459
1460 if (!SFPIsToken (",")) {
1461 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL);
1462 }
1463 //
1464 // Parse: Attributes = Number | "String",
1465 //
1466 if (!SFPIsKeyword ("Attributes")) {
1467 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);
1468 ErrorCount++;
1469 goto Done;
1470 }
1471
1472 if (!SFPIsToken ("=")) {
1473 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1474 WarningCount++;
1475 }
1476
1477 if (SFPGetNumber (&Number)) {
1478 sprintf (Subregion->Attributes, "0x%X", Number);
1479 } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) {
1480 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);
1481 ErrorCount++;
1482 goto Done;
1483 }
1484
1485 if (!SFPIsToken (",")) {
1486 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);
1487 }
1488 //
1489 // Parse: AreaType = Number | "String",
1490 // AreaType is a UINT8, so error if it exceeds the size
1491 //
1492 if (!SFPIsKeyword ("AreaType")) {
1493 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);
1494 ErrorCount++;
1495 goto Done;
1496 }
1497
1498 if (!SFPIsToken ("=")) {
1499 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1500 WarningCount++;
1501 }
1502
1503 if (SFPGetNumber (&Number)) {
1504 if (Number > 0xFF) {
1505 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL);
1506 ErrorCount++;
1507 }
1508
1509 sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF);
1510 } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) {
1511 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);
1512 ErrorCount++;
1513 goto Done;
1514 }
1515
1516 if (!SFPIsToken (",")) {
1517 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL);
1518 }
1519 //
1520 // Parse the three GUIDs (last two are optional)
1521 //
1522 // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID")
1523 // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")
1524 // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")
1525 //
1526 if (!SFPIsKeyword ("NameGuid")) {
1527 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL);
1528 ErrorCount++;
1529 goto Done;
1530 }
1531
1532 if (!SFPIsToken ("=")) {
1533 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1534 WarningCount++;
1535 }
1536 //
1537 // Allow a GUID or a quoted string identifier, which we'll just copy as a string
1538 //
1539 if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) {
1540 //
1541 // Nothing else to do
1542 //
1543 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) {
1544 Error (
1545 SFPGetFileName (),
1546 SFPGetLineNumber (),
1547 0,
1548 "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
1549 NULL
1550 );
1551 ErrorCount++;
1552 goto Done;
1553 }
1554 //
1555 // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid
1556 //
1557 PreviousComma = SFPIsToken (",");
1558 if (SFPIsKeyword ("AreaTypeGuid")) {
1559 //
1560 // Check for preceeding comma now
1561 //
1562 if (!PreviousComma) {
1563 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL);
1564 WarningCount++;
1565 }
1566
1567 if (!SFPIsToken ("=")) {
1568 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1569 WarningCount++;
1570 }
1571
1572 if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) {
1573 //
1574 // Nothing else to do
1575 //
1576 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) {
1577 Error (
1578 SFPGetFileName (),
1579 SFPGetLineNumber (),
1580 0,
1581 "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
1582 NULL
1583 );
1584 ErrorCount++;
1585 goto Done;
1586 }
1587
1588 PreviousComma = SFPIsToken (",");
1589 }
1590
1591 if (SFPIsKeyword ("FileSystemGuid")) {
1592 //
1593 // Check for preceeding comma now
1594 //
1595 if (!PreviousComma) {
1596 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL);
1597 WarningCount++;
1598 }
1599
1600 if (!SFPIsToken ("=")) {
1601 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);
1602 WarningCount++;
1603 }
1604 //
1605 // Allow a GUID or a quoted string identifier, which we'll just copy as a string
1606 //
1607 if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) {
1608 //
1609 // Nothing else to do
1610 //
1611 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) {
1612 Error (
1613 SFPGetFileName (),
1614 SFPGetLineNumber (),
1615 0,
1616 "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",
1617 NULL
1618 );
1619 ErrorCount++;
1620 goto Done;
1621 }
1622
1623 SFPIsToken (",");
1624 }
1625 //
1626 // Look for subregion closing brace
1627 //
1628 if (!SFPIsToken ("}")) {
1629 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL);
1630 WarningCount++;
1631 }
1632
1633 Done:
1634 //
1635 // If any errors were encountered, then delete the subregion definition
1636 //
1637 if (ErrorCount != 0) {
1638 _free (Subregion);
1639 Subregion = NULL;
1640 }
1641
1642 return Subregion;
1643 }
1644
1645 STATUS
1646 FDFCreateCIncludeFile (
1647 char *FlashDeviceName,
1648 char *FileName
1649 )
1650 /*++
1651
1652 Routine Description:
1653 Create a header file with #define definitions per an already-parsed
1654 flash definition file.
1655
1656 Arguments:
1657 FlashDeviceName - name of flash device (from the flash definition file)
1658 to use
1659 FileName - name of output file to create
1660
1661 Returns:
1662 STATUS_SUCCESS - no errors or warnings
1663 STATUS_WARNING - warnings, but no errors, were encountered
1664 STATUS_ERROR - errors were encountered
1665
1666 --*/
1667 {
1668 FILE *OutFptr;
1669 FLASH_BLOCK_DESCRIPTION *FBlock;
1670 FLASH_DEVICE_DESCRIPTION *FDev;
1671 FLASH_SUBREGION_DESCRIPTION *Subregion;
1672 unsigned int Offset;
1673 unsigned int SubregionOffset;
1674 int CreateHobs;
1675 //
1676 // Find the definition we're supposed to use
1677 //
1678 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
1679 if (strcmp (FDev->Name, FlashDeviceName) == 0) {
1680 break;
1681 }
1682 }
1683
1684 if (FDev == NULL) {
1685 Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");
1686 return STATUS_ERROR;
1687 }
1688
1689 if ((OutFptr = fopen (FileName, "w")) == NULL) {
1690 Error (NULL, 0, 0, FileName, "failed to open output file for writing");
1691 return STATUS_ERROR;
1692 }
1693 //
1694 // Write a header
1695 //
1696 fprintf (OutFptr, CIncludeHeader);
1697 //
1698 // Write flash block base and size defines
1699 //
1700 fprintf (OutFptr, "#define FLASH_BASE 0x%08X\n", FDev->BaseAddress);
1701 fprintf (OutFptr, "#define FLASH_SIZE 0x%08X\n\n", FDev->Size);
1702 //
1703 // Write flash regions base, size and offset defines
1704 //
1705 Offset = 0;
1706 CreateHobs = 0;
1707 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
1708 fprintf (
1709 OutFptr,
1710 "#define FLASH_REGION_%s_BASE %*c0x%08X\n",
1711 FBlock->Name,
1712 COLUMN2_START - 40 - strlen (FBlock->Name),
1713 ' ',
1714 Offset + FDev->BaseAddress
1715 );
1716 fprintf (
1717 OutFptr,
1718 "#define FLASH_REGION_%s_SIZE %*c0x%08X\n",
1719 FBlock->Name,
1720 COLUMN2_START - 40 - strlen (FBlock->Name),
1721 ' ',
1722 FBlock->Size
1723 );
1724 fprintf (
1725 OutFptr,
1726 "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n",
1727 FBlock->Name,
1728 COLUMN2_START - 40 - strlen (FBlock->Name),
1729 ' ',
1730 Offset
1731 );
1732 //
1733 // Create defines for any subregions
1734 //
1735 SubregionOffset = 0;
1736 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
1737 fprintf (
1738 OutFptr,
1739 "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n",
1740 FBlock->Name,
1741 Subregion->Name,
1742 COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),
1743 ' ',
1744 FDev->BaseAddress + Offset + SubregionOffset
1745 );
1746 fprintf (
1747 OutFptr,
1748 "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n",
1749 FBlock->Name,
1750 Subregion->Name,
1751 COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),
1752 ' ',
1753 Subregion->Size
1754 );
1755 fprintf (
1756 OutFptr,
1757 "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n",
1758 FBlock->Name,
1759 Subregion->Name,
1760 COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),
1761 ' ',
1762 Offset + SubregionOffset
1763 );
1764 SubregionOffset += Subregion->Size;
1765 if (Subregion->CreateHob != 0) {
1766 CreateHobs = 1;
1767 }
1768 }
1769
1770 Offset += FBlock->Size;
1771 }
1772 //
1773 // Now create a #define for the flash map data definition
1774 //
1775 fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n");
1776 //
1777 // Emit entry for each region
1778 //
1779 Offset = 0;
1780 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
1781 fprintf (OutFptr, " /* %s region */\\\n", FBlock->Name);
1782 fprintf (OutFptr, " {\\\n");
1783 fprintf (OutFptr, " FLASH_REGION_%s_BASE,\\\n", FBlock->Name);
1784 fprintf (OutFptr, " FLASH_REGION_%s_SIZE,\\\n", FBlock->Name);
1785 fprintf (OutFptr, " %s,\\\n", FBlock->Attributes);
1786 fprintf (OutFptr, " %s,\\\n },\\\n", FBlock->AreaType);
1787 }
1788
1789 fprintf (OutFptr, "\n\n");
1790 //
1791 // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition
1792 //
1793 if (CreateHobs != 0) {
1794 fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n");
1795 fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION");
1796 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
1797 //
1798 // See if the block has subregions, and that the CreateHobs flag is set
1799 // for any of them.
1800 //
1801 CreateHobs = 0;
1802 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
1803 if (Subregion->CreateHob != 0) {
1804 CreateHobs = 1;
1805 break;
1806 }
1807 }
1808 //
1809 // If any of the subregions had the CreateHobs flag set, then create the entries in the
1810 // output file
1811 //
1812 if (CreateHobs != 0) {
1813 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
1814 if (Subregion->CreateHob != 0) {
1815 fprintf (OutFptr, " \\\n");
1816 fprintf (OutFptr, " /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name);
1817 fprintf (OutFptr, " {\\\n");
1818 fprintf (OutFptr, " EFI_HOB_TYPE_GUID_EXTENSION,\\\n");
1819 fprintf (OutFptr, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n");
1820 fprintf (OutFptr, " 0,\\\n");
1821 //
1822 // The NameGuid may have been specified in the input flash definition file as a GUID, or
1823 // as a quoted string. Do the right one.
1824 //
1825 if (Subregion->NameGuidString[0] != 0) {
1826 fprintf (OutFptr, " %s, \\\n", Subregion->NameGuidString);
1827 } else {
1828 fprintf (
1829 OutFptr,
1830 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
1831 Subregion->NameGuid.Data1,
1832 (unsigned int) Subregion->NameGuid.Data2,
1833 (unsigned int) Subregion->NameGuid.Data3,
1834 (unsigned int) Subregion->NameGuid.Data4[0],
1835 (unsigned int) Subregion->NameGuid.Data4[1],
1836 (unsigned int) Subregion->NameGuid.Data4[2],
1837 (unsigned int) Subregion->NameGuid.Data4[3],
1838 (unsigned int) Subregion->NameGuid.Data4[4],
1839 (unsigned int) Subregion->NameGuid.Data4[5],
1840 (unsigned int) Subregion->NameGuid.Data4[6],
1841 (unsigned int) Subregion->NameGuid.Data4[7]
1842 );
1843 }
1844
1845 fprintf (OutFptr, " 0, 0, 0,\\\n");
1846 fprintf (OutFptr, " %s,\\\n", Subregion->AreaType);
1847 //
1848 // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or
1849 // as a quoted string. Do the right one.
1850 //
1851 if (Subregion->AreaTypeGuidString[0] != 0) {
1852 fprintf (OutFptr, " %s, \\\n", Subregion->AreaTypeGuidString);
1853 } else {
1854 fprintf (
1855 OutFptr,
1856 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
1857 Subregion->AreaTypeGuid.Data1,
1858 (unsigned int) Subregion->AreaTypeGuid.Data2,
1859 (unsigned int) Subregion->AreaTypeGuid.Data3,
1860 (unsigned int) Subregion->AreaTypeGuid.Data4[0],
1861 (unsigned int) Subregion->AreaTypeGuid.Data4[1],
1862 (unsigned int) Subregion->AreaTypeGuid.Data4[2],
1863 (unsigned int) Subregion->AreaTypeGuid.Data4[3],
1864 (unsigned int) Subregion->AreaTypeGuid.Data4[4],
1865 (unsigned int) Subregion->AreaTypeGuid.Data4[5],
1866 (unsigned int) Subregion->AreaTypeGuid.Data4[6],
1867 (unsigned int) Subregion->AreaTypeGuid.Data4[7]
1868 );
1869 }
1870
1871 fprintf (OutFptr, " 1,\\\n");
1872 fprintf (OutFptr, " {\\\n");
1873 fprintf (OutFptr, " %s,\\\n", Subregion->Attributes);
1874 fprintf (OutFptr, " 0,\\\n");
1875 fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name);
1876 fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name);
1877 //
1878 // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or
1879 // as a quoted string. Do the right one.
1880 //
1881 if (Subregion->FileSystemGuidString[0] != 0) {
1882 fprintf (OutFptr, " %s, \\\n", Subregion->FileSystemGuidString);
1883 } else {
1884 fprintf (
1885 OutFptr,
1886 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",
1887 Subregion->FileSystemGuid.Data1,
1888 (unsigned int) Subregion->FileSystemGuid.Data2,
1889 (unsigned int) Subregion->FileSystemGuid.Data3,
1890 (unsigned int) Subregion->FileSystemGuid.Data4[0],
1891 (unsigned int) Subregion->FileSystemGuid.Data4[1],
1892 (unsigned int) Subregion->FileSystemGuid.Data4[2],
1893 (unsigned int) Subregion->FileSystemGuid.Data4[3],
1894 (unsigned int) Subregion->FileSystemGuid.Data4[4],
1895 (unsigned int) Subregion->FileSystemGuid.Data4[5],
1896 (unsigned int) Subregion->FileSystemGuid.Data4[6],
1897 (unsigned int) Subregion->FileSystemGuid.Data4[7]
1898 );
1899 }
1900
1901 fprintf (OutFptr, " },\\\n");
1902 fprintf (OutFptr, " },");
1903 }
1904 }
1905 }
1906 }
1907
1908 fprintf (OutFptr, "\n\n");
1909 }
1910
1911 //
1912 // Write the file's closing #endif
1913 //
1914 fprintf (OutFptr, CIncludeFooter);
1915 fclose (OutFptr);
1916 return STATUS_SUCCESS;
1917 }
1918
1919 STATUS
1920 FDFCreateAsmIncludeFile (
1921 char *FlashDeviceName,
1922 char *FileName
1923 )
1924 /*++
1925
1926 Routine Description:
1927 Create an assembly header file with equate definitions per an already-parsed
1928 flash definition file.
1929
1930 Arguments:
1931 FlashDeviceName - name of flash device (from the flash definition file)
1932 to use
1933 FileName - name of output file to create
1934
1935 Returns:
1936 STATUS_SUCCESS - no errors or warnings
1937 STATUS_WARNING - warnings, but no errors, were encountered
1938 STATUS_ERROR - errors were encountered
1939
1940 --*/
1941 {
1942 FILE *OutFptr;
1943 FLASH_BLOCK_DESCRIPTION *FBlock;
1944 FLASH_DEVICE_DESCRIPTION *FDev;
1945 unsigned int Offset;
1946 FLASH_SUBREGION_DESCRIPTION *Subregion;
1947 unsigned int SubregionOffset;
1948 //
1949 // Find the definition we're supposed to use
1950 //
1951 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
1952 if (strcmp (FDev->Name, FlashDeviceName) == 0) {
1953 break;
1954 }
1955 }
1956
1957 if (FDev == NULL) {
1958 Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");
1959 return STATUS_ERROR;
1960 }
1961
1962 if ((OutFptr = fopen (FileName, "w")) == NULL) {
1963 Error (NULL, 0, 0, FileName, "failed to open output file for writing");
1964 return STATUS_ERROR;
1965 }
1966 //
1967 // Write a header
1968 //
1969 fprintf (OutFptr, "\n\n");
1970 //
1971 // Write flash block size and offset defines
1972 //
1973 fprintf (
1974 OutFptr,
1975 "FLASH_BASE %*cequ 0%08Xh\n",
1976 COLUMN2_START - 40,
1977 ' ',
1978 FDev->BaseAddress
1979 );
1980 fprintf (OutFptr, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size);
1981 //
1982 // Write flash region size and offset defines
1983 //
1984 fprintf (OutFptr, "\n");
1985 Offset = 0;
1986 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
1987 fprintf (
1988 OutFptr,
1989 "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n",
1990 FBlock->Name,
1991 COLUMN2_START - 20 - strlen (FBlock->Name),
1992 ' ',
1993 FDev->BaseAddress + Offset
1994 );
1995 fprintf (
1996 OutFptr,
1997 "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n",
1998 FBlock->Name,
1999 COLUMN2_START - 20 - strlen (FBlock->Name),
2000 ' ',
2001 FBlock->Size
2002 );
2003 fprintf (
2004 OutFptr,
2005 "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n",
2006 FBlock->Name,
2007 COLUMN2_START - 20 - strlen (FBlock->Name),
2008 ' ',
2009 Offset
2010 );
2011 //
2012 // Create defines for any subregions
2013 //
2014 SubregionOffset = 0;
2015 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
2016 fprintf (
2017 OutFptr,
2018 "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n",
2019 FBlock->Name,
2020 Subregion->Name,
2021 COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),
2022 ' ',
2023 FDev->BaseAddress + Offset + SubregionOffset
2024 );
2025 fprintf (
2026 OutFptr,
2027 "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n",
2028 FBlock->Name,
2029 Subregion->Name,
2030 COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),
2031 ' ',
2032 Subregion->Size
2033 );
2034 fprintf (
2035 OutFptr,
2036 "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n",
2037 FBlock->Name,
2038 Subregion->Name,
2039 COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),
2040 ' ',
2041 Offset + SubregionOffset
2042 );
2043 SubregionOffset += Subregion->Size;
2044 }
2045
2046 Offset += FBlock->Size;
2047 }
2048
2049 //
2050 // Write closing \n
2051 //
2052 fprintf (OutFptr, "\n\n");
2053 fclose (OutFptr);
2054 return STATUS_SUCCESS;
2055 }
2056
2057 STATUS
2058 FDFCreateSymbols (
2059 char *FlashDeviceName
2060 )
2061 /*++
2062
2063 Routine Description:
2064 Using the given flash device name, add symbols to the global symbol table. This
2065 allows other functions to use the symbol definitions for other purposes.
2066
2067 Arguments:
2068 FlashDeviceName - name of flash device (from the flash definition file)
2069 to use
2070
2071 Returns:
2072 STATUS_SUCCESS - no errors or warnings
2073 STATUS_WARNING - warnings, but no errors, were encountered
2074 STATUS_ERROR - errors were encountered
2075
2076 --*/
2077 {
2078 FLASH_BLOCK_DESCRIPTION *FBlock;
2079 FLASH_DEVICE_DESCRIPTION *FDev;
2080 unsigned int Offset;
2081 char SymName[120];
2082 char SymValue[120];
2083 FLASH_SUBREGION_DESCRIPTION *Subregion;
2084 unsigned int SubregionOffset;
2085 //
2086 // Find the definition we're supposed to use
2087 //
2088 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
2089 if (strcmp (FDev->Name, FlashDeviceName) == 0) {
2090 break;
2091 }
2092 }
2093
2094 if (FDev == NULL) {
2095 Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");
2096 return STATUS_ERROR;
2097 }
2098
2099 sprintf (SymValue, "0x%08X", FDev->BaseAddress);
2100 SymbolAdd ("FLASH_BASE", SymValue, 0);
2101 sprintf (SymValue, "0x%08X", FDev->Size);
2102 SymbolAdd ("FLASH_SIZE", SymValue, 0);
2103 //
2104 // Add flash block size and offset defines
2105 //
2106 // Offset = 0;
2107 // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) {
2108 // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name);
2109 // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);
2110 // SymbolAdd (SymName, SymValue, 0);
2111 // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name);
2112 // sprintf (SymValue, "0x%08X", FBlock->Size);
2113 // SymbolAdd (SymName, SymValue, 0);
2114 // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name);
2115 // sprintf (SymValue, "0x%08X", Offset);
2116 // SymbolAdd (SymName, SymValue, 0);
2117 // Offset += FBlock->Size;
2118 // }
2119 //
2120 // Add flash region block base, size, and offset defines
2121 //
2122 Offset = 0;
2123 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
2124 sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name);
2125 sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);
2126 SymbolAdd (SymName, SymValue, 0);
2127 sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name);
2128 sprintf (SymValue, "0x%08X", FBlock->Size);
2129 SymbolAdd (SymName, SymValue, 0);
2130 sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name);
2131 sprintf (SymValue, "0x%08X", Offset);
2132 SymbolAdd (SymName, SymValue, 0);
2133 //
2134 // Add subregion symbols
2135 //
2136 if (FBlock->Subregions != NULL) {
2137 SubregionOffset = 0;
2138 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
2139 sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name);
2140 sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset);
2141 SymbolAdd (SymName, SymValue, 0);
2142 sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name);
2143 sprintf (SymValue, "0x%08X", Subregion->Size);
2144 SymbolAdd (SymName, SymValue, 0);
2145 sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name);
2146 sprintf (SymValue, "0x%08X", Offset + SubregionOffset);
2147 SymbolAdd (SymName, SymValue, 0);
2148 SubregionOffset += Subregion->Size;
2149 }
2150 }
2151
2152 Offset += FBlock->Size;
2153 }
2154
2155 return STATUS_SUCCESS;
2156 }
2157
2158 STATUS
2159 FDFCreateImage (
2160 char *FlashDeviceName,
2161 char *ImageName,
2162 char *FileName
2163 )
2164 /*++
2165
2166 Routine Description:
2167 Create a flash image using the given device and image names.
2168
2169 Arguments:
2170 FlashDeviceName - name of flash device (from the flash definition file)
2171 to use
2172 ImageName - name of image (from the flash definition file) to create
2173 FileName - name of output file to create
2174
2175 Returns:
2176 STATUS_SUCCESS - no errors or warnings
2177 STATUS_WARNING - warnings, but no errors, were encountered
2178 STATUS_ERROR - errors were encountered
2179
2180 --*/
2181 {
2182 STATUS Status;
2183 FILE *OutFptr;
2184 FLASH_BLOCK_DESCRIPTION *RegionDef;
2185 FLASH_DEVICE_DESCRIPTION *FDev;
2186 IMAGE_DEFINITION *ImageDef;
2187 unsigned int Offset;
2188 char *Buffer;
2189 FILE *InFptr;
2190 long FileSize;
2191 IMAGE_DEFINITION_ENTRY *IDefEntry;
2192 FLASH_SUBREGION_DESCRIPTION *SubregionDef;
2193 //
2194 // Find the flash definition we're supposed to use
2195 //
2196 InFptr = NULL;
2197 Status = STATUS_ERROR;
2198 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
2199 if (strcmp (FDev->Name, FlashDeviceName) == 0) {
2200 break;
2201 }
2202 }
2203
2204 if (FDev == NULL) {
2205 Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");
2206 return STATUS_ERROR;
2207 }
2208 //
2209 // Find the image name we're supposed to create
2210 //
2211 for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) {
2212 if (strcmp (ImageDef->Name, ImageName) == 0) {
2213 break;
2214 }
2215 }
2216
2217 if (ImageDef == NULL) {
2218 Error (NULL, 0, 0, ImageName, "image definition not found in image definitions");
2219 return STATUS_ERROR;
2220 }
2221 //
2222 // Open the output file
2223 //
2224 if ((OutFptr = fopen (FileName, "wb")) == NULL) {
2225 Error (NULL, 0, 0, FileName, "failed to open output file for writing");
2226 return STATUS_ERROR;
2227 }
2228 //
2229 // Allocate a buffer to copy the input data to
2230 //
2231 Buffer = (char *) _malloc (FDev->Size);
2232 if (Buffer == NULL) {
2233 Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL);
2234 goto Done;
2235 }
2236 //
2237 // Set contents of buffer to the erased value
2238 //
2239 if (FDev->ErasePolarity) {
2240 memset (Buffer, 0xFF, FDev->Size);
2241 } else {
2242 memset (Buffer, 0, FDev->Size);
2243 }
2244 //
2245 // Set all region and subregion size-left fields to the size of the region/subregion
2246 //
2247 for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {
2248 RegionDef->SizeLeft = RegionDef->Size;
2249 for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {
2250 SubregionDef->SizeLeft = SubregionDef->Size;
2251 }
2252 }
2253 //
2254 // Now go through the image list, read files into the buffer.
2255 //
2256 for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) {
2257 //
2258 // If it's a file name, open the file, get the size, find the corresponding
2259 // flash region it's in, and copy the data.
2260 //
2261 if (IDefEntry->IsRawData == 0) {
2262 if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) {
2263 Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading");
2264 goto Done;
2265 }
2266
2267 fseek (InFptr, 0, SEEK_END);
2268 FileSize = ftell (InFptr);
2269 fseek (InFptr, 0, SEEK_SET);
2270 } else {
2271 FileSize = IDefEntry->RawDataSize;
2272 }
2273 //
2274 // Find the region/subregion it's in, see if we have space left
2275 //
2276 Offset = 0;
2277 for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {
2278 if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) {
2279 break;
2280 }
2281
2282 Offset += RegionDef->Size;
2283 }
2284
2285 if (RegionDef == NULL) {
2286 Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name);
2287 goto Done;
2288 }
2289
2290 //
2291 // Check for subregion
2292 //
2293 if (IDefEntry->SubregionName[0] != 0) {
2294 for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {
2295 if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) {
2296 break;
2297 }
2298
2299 Offset += SubregionDef->Size;
2300 }
2301
2302 if (SubregionDef == NULL) {
2303 Error (
2304 NULL,
2305 0,
2306 0,
2307 IDefEntry->SubregionName,
2308 "Subregion name not found in FlashDevice %s.%s Region definition",
2309 FDev->Name,
2310 RegionDef->Name
2311 );
2312 goto Done;
2313 }
2314 //
2315 // Enough space in the subregion?
2316 //
2317 if (SubregionDef->SizeLeft < (unsigned int) FileSize) {
2318 Error (
2319 NULL,
2320 0,
2321 0,
2322 IDefEntry->Name,
2323 "insufficient space in Subregion (at least 0x%X additional bytes required)",
2324 FileSize - SubregionDef->SizeLeft
2325 );
2326 goto Done;
2327 }
2328
2329 //
2330 // Read the file into the buffer if it's a file. Otherwise copy the raw data
2331 //
2332 if (IDefEntry->IsRawData == 0) {
2333 if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) {
2334 Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");
2335 goto Done;
2336 }
2337
2338 fclose (InFptr);
2339 InFptr = NULL;
2340 } else {
2341 memcpy (
2342 Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft),
2343 IDefEntry->RawData,
2344 IDefEntry->RawDataSize
2345 );
2346 }
2347
2348 SubregionDef->SizeLeft -= FileSize;
2349 //
2350 // Align based on the Region alignment requirements.
2351 //
2352 if (RegionDef->Alignment != 0) {
2353 while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) {
2354 if (SubregionDef->SizeLeft == 0) {
2355 break;
2356 }
2357
2358 SubregionDef->SizeLeft--;
2359 }
2360 }
2361 } else {
2362 //
2363 // Placing data in a region. Check for enough space in the region left.
2364 //
2365 if (RegionDef->SizeLeft < (unsigned int) FileSize) {
2366 Error (
2367 NULL,
2368 0,
2369 0,
2370 IDefEntry->Name,
2371 "insufficient space in Region (at least 0x%X additional bytes required)",
2372 FileSize - RegionDef->SizeLeft
2373 );
2374 goto Done;
2375 }
2376
2377 //
2378 // Read the file into the buffer if it's a file. Otherwise copy the raw data
2379 //
2380 if (IDefEntry->IsRawData == 0) {
2381 if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) {
2382 Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");
2383 goto Done;
2384 }
2385
2386 fclose (InFptr);
2387 InFptr = NULL;
2388 } else {
2389 memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize);
2390 }
2391
2392 RegionDef->SizeLeft -= FileSize;
2393 //
2394 // Align
2395 //
2396 if (RegionDef->Alignment != 0) {
2397 while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) {
2398 if (RegionDef->SizeLeft == 0) {
2399 break;
2400 }
2401
2402 RegionDef->SizeLeft--;
2403 }
2404 }
2405 }
2406 }
2407
2408 if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) {
2409 Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL);
2410 goto Done;
2411 }
2412
2413 Status = STATUS_SUCCESS;
2414 Done:
2415 if (InFptr != NULL) {
2416 fclose (InFptr);
2417 }
2418
2419 if (Buffer != NULL) {
2420 _free (Buffer);
2421 }
2422
2423 if (OutFptr != NULL) {
2424 fclose (OutFptr);
2425 if (Status == STATUS_ERROR) {
2426 remove (FileName);
2427 }
2428 }
2429
2430 return Status;
2431 }
2432
2433 STATUS
2434 FDFCreateDscFile (
2435 char *FlashDeviceName,
2436 char *FileName
2437 )
2438 /*++
2439
2440 Routine Description:
2441 Create a DSC-style output file with equates for flash management.
2442
2443 Arguments:
2444 FlashDeviceName - name of flash device (from the flash definition file)
2445 to use
2446 FileName - name of output file to create
2447
2448 Returns:
2449 STATUS_SUCCESS - no errors or warnings
2450 STATUS_WARNING - warnings, but no errors, were encountered
2451 STATUS_ERROR - errors were encountered
2452
2453 --*/
2454 {
2455 FILE *OutFptr;
2456 FLASH_BLOCK_DESCRIPTION *FBlock;
2457 FLASH_DEVICE_DESCRIPTION *FDev;
2458 unsigned int Offset;
2459 FLASH_SUBREGION_DESCRIPTION *Subregion;
2460 unsigned int SubregionOffset;
2461 //
2462 // Find the definition we're supposed to use
2463 //
2464 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {
2465 if (strcmp (FDev->Name, FlashDeviceName) == 0) {
2466 break;
2467 }
2468 }
2469
2470 if (FDev == NULL) {
2471 Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");
2472 return STATUS_ERROR;
2473 }
2474
2475 if ((OutFptr = fopen (FileName, "w")) == NULL) {
2476 Error (NULL, 0, 0, FileName, "failed to open output file for writing");
2477 return STATUS_ERROR;
2478 }
2479 //
2480 // Write the flash base address and size
2481 //
2482 fprintf (OutFptr, "\n");
2483 fprintf (OutFptr, "FLASH_BASE = 0x%08X\n", FDev->BaseAddress);
2484 fprintf (OutFptr, "FLASH_SIZE = 0x%08X\n\n", FDev->Size);
2485 //
2486 // Write flash block size and offset defines
2487 //
2488 Offset = 0;
2489 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {
2490 fprintf (
2491 OutFptr,
2492 "FLASH_REGION_%s_BASE %*c= 0x%08X\n",
2493 FBlock->Name,
2494 COLUMN2_START - 40 - strlen (FBlock->Name),
2495 ' ',
2496 Offset + FDev->BaseAddress
2497 );
2498 fprintf (
2499 OutFptr,
2500 "FLASH_REGION_%s_SIZE %*c= 0x%08X\n",
2501 FBlock->Name,
2502 COLUMN2_START - 40 - strlen (FBlock->Name),
2503 ' ',
2504 FBlock->Size
2505 );
2506 fprintf (
2507 OutFptr,
2508 "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n",
2509 FBlock->Name,
2510 COLUMN2_START - 40 - strlen (FBlock->Name),
2511 ' ',
2512 (FBlock->Size)/(FDev->PBlocks->Size)
2513 );
2514 //
2515 // Create defines for any subregions
2516 //
2517 SubregionOffset = 0;
2518 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {
2519 fprintf (
2520 OutFptr,
2521 "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n",
2522 FBlock->Name,
2523 Subregion->Name,
2524 COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),
2525 ' ',
2526 FDev->BaseAddress + Offset + SubregionOffset
2527 );
2528 fprintf (
2529 OutFptr,
2530 "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n",
2531 FBlock->Name,
2532 Subregion->Name,
2533 COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),
2534 ' ',
2535 Subregion->Size
2536 );
2537 fprintf (
2538 OutFptr,
2539 "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n",
2540 FBlock->Name,
2541 Subregion->Name,
2542 COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),
2543 ' ',
2544 Offset + SubregionOffset
2545 );
2546
2547 SubregionOffset += Subregion->Size;
2548 }
2549
2550 Offset += FBlock->Size;
2551 }
2552 //
2553 // Close file
2554 //
2555 fprintf (OutFptr, "\n");
2556 fclose (OutFptr);
2557 return STATUS_SUCCESS;
2558 }
2559
2560
2561 /*++
2562
2563 Routine Description:
2564 The following buffer management routines are used to encapsulate functionality
2565 for managing a growable data buffer.
2566
2567 Arguments:
2568 BUFFER_DATA - structure that is used to maintain a data buffer
2569
2570 Returns:
2571 NA
2572
2573 --*/
2574 static
2575 BUFFER_DATA *
2576 CreateBufferData (
2577 VOID
2578 )
2579 /*++
2580
2581 Routine Description:
2582
2583 Create a growable data buffer with default buffer length.
2584
2585 Arguments:
2586
2587 None
2588
2589 Returns:
2590
2591 NULL - error occured during data buffer creation
2592 Not NULL - the pointer to the newly created data buffer
2593
2594 --*/
2595 {
2596 BUFFER_DATA *BD;
2597 BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA));
2598 if (BD == NULL) {
2599 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
2600 return NULL;
2601 }
2602
2603 memset (BD, 0, sizeof (BUFFER_DATA));
2604 BD->BufferStart = (char *) _malloc (BUFFER_SIZE);
2605 if (BD->BufferStart == NULL) {
2606 _free (BD);
2607 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
2608 return NULL;
2609 }
2610
2611 BD->BufferEnd = BD->BufferStart + BUFFER_SIZE;
2612 BD->BufferPos = BD->BufferStart;
2613 return BD;
2614 }
2615
2616 static
2617 BOOLEAN
2618 AddBufferDataByte (
2619 BUFFER_DATA *Buffer,
2620 char Data
2621 )
2622 /*++
2623
2624 Routine Description:
2625
2626 Add a single byte to a growable data buffer, growing the buffer if required.
2627
2628 Arguments:
2629
2630 Buffer - pointer to the growable data buffer to add a single byte to
2631 Data - value of the single byte data to be added
2632
2633 Returns:
2634
2635 TRUE - the single byte data was successfully added
2636 FALSE - error occurred, the single byte data was not added
2637
2638 --*/
2639 {
2640 int Size;
2641 char *NewBuffer;
2642 //
2643 // See if we have to grow the buffer
2644 //
2645 if (Buffer->BufferPos >= Buffer->BufferEnd) {
2646 Size = (int) Buffer->BufferEnd - (int) Buffer->BufferStart;
2647 NewBuffer = (char *) _malloc (Size + BUFFER_SIZE);
2648 if (NewBuffer == NULL) {
2649 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);
2650 return FALSE;
2651 }
2652
2653 memcpy (NewBuffer, Buffer->BufferStart, Size);
2654 _free (Buffer->BufferStart);
2655 Buffer->BufferStart = NewBuffer;
2656 Buffer->BufferPos = Buffer->BufferStart + Size;
2657 Buffer->BufferEnd = Buffer->BufferStart + Size + BUFFER_SIZE;
2658 }
2659
2660 *Buffer->BufferPos = Data;
2661 Buffer->BufferPos++;
2662 return TRUE;
2663 }
2664
2665 static
2666 void
2667 FreeBufferData (
2668 BUFFER_DATA *Buffer,
2669 BOOLEAN FreeData
2670 )
2671 /*++
2672
2673 Routine Description:
2674
2675 Free memory used to manage a growable data buffer.
2676
2677 Arguments:
2678
2679 Buffer - pointer to the growable data buffer to be destructed
2680 FreeData - TRUE, free memory containing the buffered data
2681 FALSE, do not free the buffered data memory
2682
2683 Returns:
2684
2685 None
2686
2687 --*/
2688 {
2689 if (Buffer != NULL) {
2690 if (FreeData && (Buffer->BufferStart != NULL)) {
2691 _free (Buffer->BufferStart);
2692 }
2693
2694 _free (Buffer);
2695 }
2696 }
2697
2698 static
2699 char *
2700 GetBufferData (
2701 BUFFER_DATA *Buffer,
2702 int *BufferSize
2703 )
2704 /*++
2705
2706 Routine Description:
2707
2708 Return a pointer and size of the data in a growable data buffer.
2709
2710 Arguments:
2711
2712 Buffer - pointer to the growable data buffer
2713 BufferSize - size of the data in the growable data buffer
2714
2715 Returns:
2716
2717 pointer of the data in the growable data buffer
2718
2719 --*/
2720 {
2721 *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart;
2722 return Buffer->BufferStart;
2723 }
2724
2725 STATUS
2726 FDDiscover (
2727 char *FDFileName,
2728 unsigned int BaseAddr
2729 )
2730 /*++
2731
2732 Routine Description:
2733 Walk a binary image and see if you find anything that looks like a
2734 firmware volume.
2735
2736 Arguments:
2737 FDFileName - name of input FD image to parse
2738 BaseAddr - base address of input FD image
2739
2740 Returns:
2741 STATUS_SUCCESS - no errors or warnings
2742 STATUS_WARNING - warnings, but no errors, were encountered
2743 STATUS_ERROR - errors were encountered
2744
2745 NOTE:
2746 This routine is used for debug purposes only.
2747
2748 --*/
2749 {
2750 FILE *InFptr;
2751 long FileSize;
2752 long Offset;
2753 EFI_FIRMWARE_VOLUME_HEADER FVHeader;
2754 EFI_GUID
2755 FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF };
2756
2757 if ((InFptr = fopen (FDFileName, "rb")) == NULL) {
2758 Error (NULL, 0, 0, FDFileName, "failed to open file for reading");
2759 return STATUS_ERROR;
2760 }
2761
2762 fseek (InFptr, 0, SEEK_END);
2763 FileSize = ftell (InFptr);
2764 fseek (InFptr, 0, SEEK_SET);
2765 Offset = 0;
2766 while (Offset < FileSize) {
2767 fseek (InFptr, Offset, SEEK_SET);
2768 //
2769 // Read the contents of the file, see if it's an FV header
2770 //
2771 if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) {
2772 //
2773 // Check version and GUID
2774 //
2775 if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) {
2776 fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength);
2777 if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) {
2778 fprintf (stdout, "standard FFS file system\n");
2779 } else {
2780 fprintf (stdout, "non-standard FFS file system\n");
2781 }
2782 }
2783 }
2784
2785 Offset += 16 * 1024;
2786 }
2787
2788 fclose (InFptr);
2789 return STATUS_SUCCESS;
2790 }