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