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