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