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