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