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