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