]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/FlashMap/FlashDefFile.c
1. Removed the unnecessary #include statements and include files
[mirror_edk2.git] / Tools / Source / TianoTools / FlashMap / FlashDefFile.c
CommitLineData
d25c4bf0 1/*++\r
2\r
3Copyright (c) 2004-2005 Intel Corporation. All rights reserved\r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
12\r
13Module Name:\r
14\r
15 FlashDefFile.c\r
16\r
17Abstract:\r
18\r
19 Utility for flash management in the Intel Platform Innovation Framework\r
20 for EFI build environment.\r
21\r
22--*/\r
23\r
24#include <stdio.h>\r
25#include <string.h>\r
26#include <stdlib.h>\r
51d48c26 27#include <UefiBaseTypes.h>\r
28#include <Base.h>\r
d25c4bf0 29\r
d25c4bf0 30#include "EfiUtilityMsgs.h"\r
31#include "FlashDefFile.h"\r
32#include "SimpleFileParsing.h"\r
33#include "Symbols.h"\r
51d48c26 34// #include "EfiFirmwareVolumeHeader.h"\r
35#include "MultiPhase.h"\r
36#include "FirmwareVolumeHeader.h"\r
d25c4bf0 37\r
38//\r
39// #include "TrackMallocFree.h"\r
40//\r
41#define WCHAR_T char\r
42#define MAX_STRING_LEN 256\r
43#define MAX_NAME_LEN 128\r
44#define BUFFER_SIZE 1024\r
45#define MAX_ATTR_LEN 128\r
46#define MAX_AREATYPE_LEN 128\r
47#define COLUMN2_START 60\r
48#define COLUMN3_START 70\r
49//\r
50// Information for each subregions defined in the fdf file will be saved in these\r
51//\r
52typedef struct _FLASH_SUBREGION_DESCRIPTION {\r
53 struct _FLASH_SUBREGION_DESCRIPTION *Next;\r
54 int CreateHob; // to add to the auto-created HOB array\r
55 WCHAR_T Name[MAX_NAME_LEN]; // each subregion within a region must have a unique name\r
56 unsigned int Size; // size, in bytes, of this subregion\r
57 unsigned int SizeLeft; // used when creating the image\r
58 WCHAR_T Attributes[MAX_ATTR_LEN]; // subregion attributes used in the output HOB\r
59 WCHAR_T AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB\r
60 EFI_GUID NameGuid; // used in the output HOB\r
61 WCHAR_T NameGuidString[MAX_NAME_LEN];\r
62 EFI_GUID AreaTypeGuid; // used in the output HOB\r
63 WCHAR_T AreaTypeGuidString[MAX_NAME_LEN];\r
64 EFI_GUID FileSystemGuid; // used in the output HOB\r
65 WCHAR_T FileSystemGuidString[MAX_NAME_LEN];\r
66} FLASH_SUBREGION_DESCRIPTION;\r
67\r
68//\r
69// Information for each block in a flash device will be saved in one of these.\r
70// We'll also use it for region definitions.\r
71//\r
72typedef struct _FLASH_BLOCK_DESCRIPTION {\r
73 struct _FLASH_BLOCK_DESCRIPTION *Next; // next block in the linked list\r
74 WCHAR_T Name[MAX_NAME_LEN]; // each block must have a unique name\r
75 unsigned int Size; // size, in bytes, of this block\r
76 unsigned int SizeLeft; // for use when creating image\r
77 unsigned int Flags; // user-defined flags for the block\r
78 unsigned int Alignment; // power of 2 alignment\r
79 WCHAR_T Attributes[MAX_ATTR_LEN]; // only used for Region definitions\r
80 WCHAR_T AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions\r
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
800 //\r
801 // Parse optional Subregion definitions\r
802 //\r
803 SubregionSizeLeft = FBlockDesc->Size;\r
804 while (SFPIsToken ("Subregion")) {\r
805 if (!PreviousComma) {\r
806 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL);\r
807 WarningCount++;\r
808 PreviousComma = TRUE;\r
809 }\r
810\r
811 Subregion = ParseSubregionDefinition (SubregionSizeLeft);\r
812 if (Subregion == NULL) {\r
813 ErrorCount++;\r
814 goto Done;\r
815 }\r
816\r
817 SubregionSizeLeft -= Subregion->Size;\r
818 //\r
819 // Add it to the end of our list\r
820 //\r
821 if (FBlockDesc->Subregions == NULL) {\r
822 FBlockDesc->Subregions = Subregion;\r
823 } else {\r
824 FBlockDesc->LastSubregion->Next = Subregion;\r
825 }\r
826\r
827 FBlockDesc->LastSubregion = Subregion;\r
828 //\r
829 // Make sure all subregion names are unique. We do this each time\r
830 // through so that we catch the error immediately after it happens, in\r
831 // which case the reported line number is at least close to where the\r
832 // problem lies. We don't exit on the error because we can continue parsing\r
833 // the script to perhaps catch other errors or warnings.\r
834 //\r
835 for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
836 for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) {\r
837 if (strcmp (Subregion->Name, TempSubregion->Name) == 0) {\r
838 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name");\r
839 ErrorCount++;\r
840 }\r
841 }\r
842 }\r
843 }\r
844\r
845 if (!SFPIsToken ("}")) {\r
846 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL);\r
847 WarningCount++;\r
848 }\r
849 //\r
850 // Add the region descriptor to the end of the linked list\r
851 //\r
852 if (FDDesc->LastRegion != NULL) {\r
853 FDDesc->LastRegion->Next = FBlockDesc;\r
854 } else {\r
855 FDDesc->Regions = FBlockDesc;\r
856 }\r
857\r
858 FDDesc->LastRegion = FBlockDesc;\r
859 }\r
860 //\r
861 // Make sure sum of sizes of regions adds up to size of flash device\r
862 //\r
863 if (RegionSizeLeft != 0) {\r
864 Error (\r
865 SFPGetFileName (),\r
866 SFPGetLineNumber (),\r
867 0,\r
868 NULL,\r
869 "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X",\r
870 FDDesc->Size - RegionSizeLeft,\r
871 FDDesc->Size,\r
872 RegionSizeLeft\r
873 );\r
874 ErrorCount++;\r
875 }\r
876 //\r
877 // Look for closing brace\r
878 //\r
879 if (!SFPIsToken ("}")) {\r
880 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL);\r
881 WarningCount++;\r
882 }\r
883 //\r
884 // Add this flash description to the list\r
885 //\r
886 FDDesc->Next = mFlashDevices;\r
887 mFlashDevices = FDDesc;\r
888 }\r
889\r
890 while (SFPIsKeyword ("FlashDeviceImage")) {\r
891 //\r
892 // Allocate memory for a new FD image definition\r
893 //\r
894 ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION));\r
895 if (ImageDef == NULL) {\r
896 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
897 ErrorCount++;\r
898 goto Done;\r
899 }\r
900\r
901 memset (ImageDef, 0, sizeof (IMAGE_DEFINITION));\r
902 //\r
903 // Open brace -- warning if not there\r
904 //\r
905 if (!SFPIsToken ("{")) {\r
906 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
907 WarningCount++;\r
908 }\r
909 //\r
910 // Parse: Name = "ImageName",\r
911 //\r
912 if (!SFPIsKeyword ("Name")) {\r
913 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
914 ErrorCount++;\r
915 goto Done;\r
916 }\r
917\r
918 if (!SFPIsToken ("=")) {\r
919 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
920 WarningCount++;\r
921 }\r
922\r
923 if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) {\r
924 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL);\r
925 ErrorCount++;\r
926 goto Done;\r
927 }\r
928\r
929 if (!SFPIsToken (",")) {\r
930 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL);\r
931 WarningCount++;\r
932 }\r
933\r
934 while (1) {\r
935 //\r
936 // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE }\r
937 //\r
938 if (SFPIsKeyword ("File")) {\r
939 ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));\r
940 if (ImageDefEntry == NULL) {\r
941 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
942 ErrorCount++;\r
943 goto Done;\r
944 }\r
945\r
946 memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));\r
947 //\r
948 // Open brace -- warning if not there\r
949 //\r
950 if (!SFPIsToken ("{")) {\r
951 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
952 WarningCount++;\r
953 }\r
954 //\r
955 // Parse: Name = "FileName.txt"\r
956 //\r
957 if (!SFPIsKeyword ("Name")) {\r
958 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
959 ErrorCount++;\r
960 goto Done;\r
961 }\r
962\r
963 if (!SFPIsToken ("=")) {\r
964 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
965 WarningCount++;\r
966 }\r
967\r
968 if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {\r
969 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL);\r
970 ErrorCount++;\r
971 goto Done;\r
972 }\r
973\r
974 if (!SFPIsToken (",")) {\r
975 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL);\r
976 WarningCount++;\r
977 }\r
978 //\r
979 // Parse: Region = "REGION_NAME"\r
980 //\r
981 if (!SFPIsKeyword ("Region")) {\r
982 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);\r
983 ErrorCount++;\r
984 goto Done;\r
985 }\r
986\r
987 if (!SFPIsToken ("=")) {\r
988 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
989 WarningCount++;\r
990 }\r
991\r
992 if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {\r
993 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);\r
994 ErrorCount++;\r
995 goto Done;\r
996 }\r
997\r
998 if (!SFPIsToken (",")) {\r
999 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
1000 WarningCount++;\r
1001 }\r
1002 //\r
1003 // Parse optional: Subregion = "SUBREGION_NAME"\r
1004 //\r
1005 if (SFPIsKeyword ("Subregion")) {\r
1006 if (!SFPIsToken ("=")) {\r
1007 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1008 WarningCount++;\r
1009 }\r
1010\r
1011 if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {\r
1012 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);\r
1013 ErrorCount++;\r
1014 goto Done;\r
1015 }\r
1016\r
1017 if (!SFPIsToken (",")) {\r
1018 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);\r
1019 WarningCount++;\r
1020 }\r
1021 //\r
1022 // For a given region, you can only place data using the region name, or the subregion names.\r
1023 // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that\r
1024 // here by checking that any previous entries with the same Region name had a Subregion specified\r
1025 // as well.\r
1026 //\r
1027 for (TempImageDefEntry = ImageDef->Entries;\r
1028 TempImageDefEntry != NULL;\r
1029 TempImageDefEntry = TempImageDefEntry->Next\r
1030 ) {\r
1031 if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {\r
1032 if (TempImageDefEntry->SubregionName[0] == 0) {\r
1033 Error (\r
1034 SFPGetFileName (),\r
1035 SFPGetLineNumber (),\r
1036 0,\r
1037 TempImageDefEntry->RegionName,\r
1038 "data already placed on a region-basis in the region, can't place data using subregions"\r
1039 );\r
1040 ErrorCount++;\r
1041 }\r
1042 }\r
1043 }\r
1044 }\r
1045 //\r
1046 // Optional parse: Optional = TRUE | FALSE\r
1047 //\r
1048 if (SFPIsKeyword ("Optional")) {\r
1049 if (!SFPIsToken ("=")) {\r
1050 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1051 WarningCount++;\r
1052 }\r
1053\r
1054 if (!SFPIsKeyword ("TRUE")) {\r
1055 ImageDefEntry->Optional = 1;\r
1056 } else if (SFPIsKeyword ("FALSE")) {\r
1057 //\r
1058 // Already set to 0\r
1059 //\r
1060 } else {\r
1061 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);\r
1062 ErrorCount++;\r
1063 goto Done;\r
1064 }\r
1065\r
1066 SFPIsToken (",");\r
1067 }\r
1068 //\r
1069 // Closing brace\r
1070 //\r
1071 if (!SFPIsToken ("}")) {\r
1072 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL);\r
1073 ErrorCount++;\r
1074 goto Done;\r
1075 }\r
1076 //\r
1077 // Add the entry to the end of the list\r
1078 //\r
1079 if (ImageDef->LastEntry != NULL) {\r
1080 ImageDef->LastEntry->Next = ImageDefEntry;\r
1081 } else {\r
1082 ImageDef->Entries = ImageDefEntry;\r
1083 }\r
1084\r
1085 ImageDef->LastEntry = ImageDefEntry;\r
1086 } else if (SFPIsKeyword ("RawData")) {\r
1087 //\r
1088 // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }}\r
1089 //\r
1090 ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY));\r
1091 if (ImageDefEntry == NULL) {\r
1092 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
1093 ErrorCount++;\r
1094 goto Done;\r
1095 }\r
1096\r
1097 memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY));\r
1098 ImageDefEntry->IsRawData = 1;\r
1099 //\r
1100 // Open brace -- warning if not there\r
1101 //\r
1102 if (!SFPIsToken ("{")) {\r
1103 Warning (\r
1104 SFPGetFileName (),\r
1105 SFPGetLineNumber (),\r
1106 0,\r
1107 "expected '{' opening brace for RawData definition",\r
1108 NULL\r
1109 );\r
1110 WarningCount++;\r
1111 }\r
1112 //\r
1113 // Parse: Name = "PadBytes"\r
1114 //\r
1115 if (!SFPIsKeyword ("Name")) {\r
1116 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
1117 ErrorCount++;\r
1118 goto Done;\r
1119 }\r
1120\r
1121 if (!SFPIsToken ("=")) {\r
1122 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1123 WarningCount++;\r
1124 }\r
1125\r
1126 if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) {\r
1127 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL);\r
1128 ErrorCount++;\r
1129 goto Done;\r
1130 }\r
1131\r
1132 if (!SFPIsToken (",")) {\r
1133 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL);\r
1134 WarningCount++;\r
1135 }\r
1136 //\r
1137 // Parse: Region = "REGION_NAME"\r
1138 //\r
1139 if (!SFPIsKeyword ("Region")) {\r
1140 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL);\r
1141 ErrorCount++;\r
1142 goto Done;\r
1143 }\r
1144\r
1145 if (!SFPIsToken ("=")) {\r
1146 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1147 WarningCount++;\r
1148 }\r
1149\r
1150 if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) {\r
1151 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL);\r
1152 ErrorCount++;\r
1153 goto Done;\r
1154 }\r
1155\r
1156 if (!SFPIsToken (",")) {\r
1157 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
1158 WarningCount++;\r
1159 }\r
1160 //\r
1161 // Parse optional: Subregion = "SUBREGION_NAME"\r
1162 //\r
1163 if (SFPIsKeyword ("Subregion")) {\r
1164 if (!SFPIsToken ("=")) {\r
1165 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1166 WarningCount++;\r
1167 }\r
1168\r
1169 if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) {\r
1170 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL);\r
1171 ErrorCount++;\r
1172 goto Done;\r
1173 }\r
1174\r
1175 if (!SFPIsToken (",")) {\r
1176 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL);\r
1177 WarningCount++;\r
1178 }\r
1179 //\r
1180 // For a given region, you can only place data using the region name, or the subregion names.\r
1181 // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that\r
1182 // here by checking that any previous entries with the same Region name had a Subregion specified\r
1183 // as well.\r
1184 //\r
1185 for (TempImageDefEntry = ImageDef->Entries;\r
1186 TempImageDefEntry != NULL;\r
1187 TempImageDefEntry = TempImageDefEntry->Next\r
1188 ) {\r
1189 if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) {\r
1190 if (TempImageDefEntry->SubregionName[0] == 0) {\r
1191 Error (\r
1192 SFPGetFileName (),\r
1193 SFPGetLineNumber (),\r
1194 0,\r
1195 TempImageDefEntry->RegionName,\r
1196 "data already placed on a region-basis in the region, can't place data using subregions"\r
1197 );\r
1198 ErrorCount++;\r
1199 }\r
1200 }\r
1201 }\r
1202 }\r
1203 //\r
1204 // Parse: Data = { 0x78, 0x56, 0x34, 0x12 }\r
1205 //\r
1206 if (!SFPIsKeyword ("Data")) {\r
1207 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL);\r
1208 ErrorCount++;\r
1209 goto Done;\r
1210 }\r
1211\r
1212 if (!SFPIsToken ("=")) {\r
1213 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1214 WarningCount++;\r
1215 }\r
1216\r
1217 if (!SFPIsToken ("{")) {\r
1218 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL);\r
1219 WarningCount++;\r
1220 }\r
1221\r
1222 if ((BufferData = CreateBufferData ()) == NULL) {\r
1223 ErrorCount++;\r
1224 goto Done;\r
1225 }\r
1226 //\r
1227 // Read bytes from input file until closing brace\r
1228 //\r
1229 while (!SFPIsToken ("}")) {\r
1230 if (!SFPGetNumber (&Num)) {\r
1231 SFPGetNextToken (Str, sizeof (Str));\r
1232 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str);\r
1233 ErrorCount++;\r
1234 FreeBufferData (BufferData, TRUE);\r
1235 goto Done;\r
1236 } else {\r
1237 //\r
1238 // Only allow bytes\r
1239 //\r
1240 if (Num > 0xFF) {\r
1241 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL);\r
1242 ErrorCount++;\r
1243 FreeBufferData (BufferData, TRUE);\r
1244 goto Done;\r
1245 }\r
1246\r
1247 AddBufferDataByte (BufferData, (char) Num);\r
1248 SFPIsToken (",");\r
1249 }\r
1250 }\r
1251 //\r
1252 // Now get the data and save it in our image entry\r
1253 //\r
1254 ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize);\r
1255 FreeBufferData (BufferData, 0);\r
1256 //\r
1257 // Closing brace for RawData {}\r
1258 //\r
1259 if (!SFPIsToken ("}")) {\r
1260 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL);\r
1261 ErrorCount++;\r
1262 goto Done;\r
1263 }\r
1264 //\r
1265 // Add the entry to the end of the list\r
1266 //\r
1267 if (ImageDef->LastEntry != NULL) {\r
1268 ImageDef->LastEntry->Next = ImageDefEntry;\r
1269 } else {\r
1270 ImageDef->Entries = ImageDefEntry;\r
1271 }\r
1272\r
1273 ImageDef->LastEntry = ImageDefEntry;\r
1274 } else if (SFPIsToken ("}")) {\r
1275 //\r
1276 // Closing brace for FDImage {}\r
1277 //\r
1278 break;\r
1279 } else {\r
1280 SFPGetNextToken (Str, sizeof (Str));\r
1281 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str);\r
1282 ErrorCount++;\r
1283 goto Done;\r
1284 }\r
1285 }\r
1286 //\r
1287 // Add this image definition to our global list\r
1288 //\r
1289 ImageDef->Next = mImageDefinitions;\r
1290 mImageDefinitions = ImageDef;\r
1291 }\r
1292 //\r
1293 // Check for end-of-file\r
1294 //\r
1295 if (!SFPIsEOF ()) {\r
1296 SFPGetNextToken (Str, sizeof (Str));\r
1297 Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str);\r
1298 ErrorCount++;\r
1299 }\r
1300\r
1301Done:\r
1302 SFPCloseFile ();\r
1303 if (ErrorCount != 0) {\r
1304 return STATUS_ERROR;\r
1305 } else if (WarningCount != 0) {\r
1306 return STATUS_WARNING;\r
1307 }\r
1308\r
1309 return STATUS_SUCCESS;\r
1310}\r
1311\r
1312static\r
1313FLASH_SUBREGION_DESCRIPTION *\r
1314ParseSubregionDefinition (\r
1315 unsigned int SizeLeft\r
1316 )\r
1317/*++\r
1318 \r
1319Routine Description:\r
1320\r
1321 Parse Subregion definitions from the input flash definition file. Format:\r
1322\r
1323 Subregion {\r
1324 CreateHob = TRUE,\r
1325 Name = "FOO",\r
1326 Size = 0xA000,\r
1327 Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV",\r
1328 AreaType = "EFI_FLASH_AREA_EFI_VARIABLES",\r
1329 NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"),\r
1330 AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)\r
1331 FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional)\r
1332 }\r
1333\r
1334 NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace.\r
1335\r
1336Arguments:\r
1337 \r
1338 SizeLeft - in the flash definition file, a Region can be broken up into\r
1339 one or more subregions. As we parse the subregion definitions,\r
1340 the caller keeps track of how much space is left in the region\r
1341 that we're parsing subregions for. SizeLeft is that size, and\r
1342 so the size of the subregion we're now parsing better not\r
1343 exceed the size left.\r
1344 Returns:\r
1345\r
1346 NULL - unrecoverable errors detected while parsing the subregion definition\r
1347\r
1348 pointer to a subregion definition created from the parsed subregion\r
1349\r
1350--*/\r
1351{\r
1352 FLASH_SUBREGION_DESCRIPTION *Subregion;\r
1353 int ErrorCount;\r
1354 int WarningCount;\r
1355 unsigned int Number;\r
1356 BOOLEAN PreviousComma;\r
1357 //\r
1358 // Allocate memory for the new subregion descriptor\r
1359 //\r
1360 ErrorCount = 0;\r
1361 WarningCount = 0;\r
1362 Subregion = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION));\r
1363 if (Subregion == NULL) {\r
1364 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
1365 ErrorCount++;\r
1366 goto Done;\r
1367 }\r
1368\r
1369 memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION));\r
1370 //\r
1371 // Open brace -- warning if not there\r
1372 //\r
1373 if (!SFPIsToken ("{")) {\r
1374 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL);\r
1375 WarningCount++;\r
1376 }\r
1377 //\r
1378 // Parse: CreateHob = TRUE | FALSE,\r
1379 //\r
1380 if (!SFPIsKeyword ("CreateHob")) {\r
1381 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL);\r
1382 ErrorCount++;\r
1383 goto Done;\r
1384 }\r
1385\r
1386 if (!SFPIsToken ("=")) {\r
1387 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1388 WarningCount++;\r
1389 }\r
1390\r
1391 if (SFPIsToken ("TRUE")) {\r
1392 Subregion->CreateHob = 1;\r
1393 } else if (SFPIsToken ("FALSE")) {\r
1394 //\r
1395 // Subregion->CreateHob = 0; -- not required since we did a memset earlier\r
1396 //\r
1397 } else {\r
1398 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL);\r
1399 ErrorCount++;\r
1400 goto Done;\r
1401 }\r
1402\r
1403 if (!SFPIsToken (",")) {\r
1404 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL);\r
1405 WarningCount++;\r
1406 }\r
1407 //\r
1408 // Parse: Name = "Name",\r
1409 //\r
1410 if (!SFPIsKeyword ("Name")) {\r
1411 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL);\r
1412 ErrorCount++;\r
1413 goto Done;\r
1414 }\r
1415\r
1416 if (!SFPIsToken ("=")) {\r
1417 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1418 WarningCount++;\r
1419 }\r
1420\r
1421 if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) {\r
1422 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL);\r
1423 ErrorCount++;\r
1424 goto Done;\r
1425 }\r
1426\r
1427 if (!SFPIsToken (",")) {\r
1428 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL);\r
1429 WarningCount++;\r
1430 }\r
1431 //\r
1432 // Parse: Size = 0x2000,\r
1433 //\r
1434 if (!SFPIsKeyword ("Size")) {\r
1435 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL);\r
1436 ErrorCount++;\r
1437 goto Done;\r
1438 }\r
1439\r
1440 if (!SFPIsToken ("=")) {\r
1441 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1442 WarningCount++;\r
1443 }\r
1444\r
1445 if (!SFPGetNumber (&Subregion->Size)) {\r
1446 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL);\r
1447 ErrorCount++;\r
1448 goto Done;\r
1449 }\r
1450\r
1451 //\r
1452 // Check that the size does not exceed the size left passed in\r
1453 //\r
1454 if (Subregion->Size > SizeLeft) {\r
1455 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL);\r
1456 ErrorCount++;\r
1457 goto Done;\r
1458 }\r
1459\r
1460 if (!SFPIsToken (",")) {\r
1461 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL);\r
1462 }\r
1463 //\r
1464 // Parse: Attributes = Number | "String",\r
1465 //\r
1466 if (!SFPIsKeyword ("Attributes")) {\r
1467 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL);\r
1468 ErrorCount++;\r
1469 goto Done;\r
1470 }\r
1471\r
1472 if (!SFPIsToken ("=")) {\r
1473 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1474 WarningCount++;\r
1475 }\r
1476\r
1477 if (SFPGetNumber (&Number)) {\r
1478 sprintf (Subregion->Attributes, "0x%X", Number);\r
1479 } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) {\r
1480 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL);\r
1481 ErrorCount++;\r
1482 goto Done;\r
1483 }\r
1484\r
1485 if (!SFPIsToken (",")) {\r
1486 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL);\r
1487 }\r
1488 //\r
1489 // Parse: AreaType = Number | "String",\r
1490 // AreaType is a UINT8, so error if it exceeds the size\r
1491 //\r
1492 if (!SFPIsKeyword ("AreaType")) {\r
1493 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL);\r
1494 ErrorCount++;\r
1495 goto Done;\r
1496 }\r
1497\r
1498 if (!SFPIsToken ("=")) {\r
1499 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1500 WarningCount++;\r
1501 }\r
1502\r
1503 if (SFPGetNumber (&Number)) {\r
1504 if (Number > 0xFF) {\r
1505 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL);\r
1506 ErrorCount++;\r
1507 }\r
1508\r
1509 sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF);\r
1510 } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) {\r
1511 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL);\r
1512 ErrorCount++;\r
1513 goto Done;\r
1514 }\r
1515\r
1516 if (!SFPIsToken (",")) {\r
1517 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL);\r
1518 }\r
1519 //\r
1520 // Parse the three GUIDs (last two are optional)\r
1521 //\r
1522 // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID")\r
1523 // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")\r
1524 // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID")\r
1525 //\r
1526 if (!SFPIsKeyword ("NameGuid")) {\r
1527 Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL);\r
1528 ErrorCount++;\r
1529 goto Done;\r
1530 }\r
1531\r
1532 if (!SFPIsToken ("=")) {\r
1533 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1534 WarningCount++;\r
1535 }\r
1536 //\r
1537 // Allow a GUID or a quoted string identifier, which we'll just copy as a string\r
1538 //\r
1539 if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) {\r
1540 //\r
1541 // Nothing else to do\r
1542 //\r
1543 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) {\r
1544 Error (\r
1545 SFPGetFileName (),\r
1546 SFPGetLineNumber (),\r
1547 0,\r
1548 "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",\r
1549 NULL\r
1550 );\r
1551 ErrorCount++;\r
1552 goto Done;\r
1553 }\r
1554 //\r
1555 // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid\r
1556 //\r
1557 PreviousComma = SFPIsToken (",");\r
1558 if (SFPIsKeyword ("AreaTypeGuid")) {\r
1559 //\r
1560 // Check for preceeding comma now\r
1561 //\r
1562 if (!PreviousComma) {\r
1563 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL);\r
1564 WarningCount++;\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 if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) {\r
1573 //\r
1574 // Nothing else to do\r
1575 //\r
1576 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) {\r
1577 Error (\r
1578 SFPGetFileName (),\r
1579 SFPGetLineNumber (),\r
1580 0,\r
1581 "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC",\r
1582 NULL\r
1583 );\r
1584 ErrorCount++;\r
1585 goto Done;\r
1586 }\r
1587\r
1588 PreviousComma = SFPIsToken (",");\r
1589 }\r
1590\r
1591 if (SFPIsKeyword ("FileSystemGuid")) {\r
1592 //\r
1593 // Check for preceeding comma now\r
1594 //\r
1595 if (!PreviousComma) {\r
1596 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL);\r
1597 WarningCount++;\r
1598 }\r
1599\r
1600 if (!SFPIsToken ("=")) {\r
1601 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL);\r
1602 WarningCount++;\r
1603 }\r
1604 //\r
1605 // Allow a GUID or a quoted string identifier, which we'll just copy as a string\r
1606 //\r
1607 if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) {\r
1608 //\r
1609 // Nothing else to do\r
1610 //\r
1611 } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) {\r
1612 Error (\r
1613 SFPGetFileName (),\r
1614 SFPGetLineNumber (),\r
1615 0,\r
1616 "expected FileSystemGuid 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 SFPIsToken (",");\r
1624 }\r
1625 //\r
1626 // Look for subregion closing brace\r
1627 //\r
1628 if (!SFPIsToken ("}")) {\r
1629 Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL);\r
1630 WarningCount++;\r
1631 }\r
1632\r
1633Done:\r
1634 //\r
1635 // If any errors were encountered, then delete the subregion definition\r
1636 //\r
1637 if (ErrorCount != 0) {\r
1638 _free (Subregion);\r
1639 Subregion = NULL;\r
1640 }\r
1641\r
1642 return Subregion;\r
1643}\r
1644\r
1645STATUS\r
1646FDFCreateCIncludeFile (\r
1647 char *FlashDeviceName,\r
1648 char *FileName\r
1649 )\r
1650/*++\r
1651\r
1652Routine Description:\r
1653 Create a header file with #define definitions per an already-parsed\r
1654 flash definition file.\r
1655\r
1656Arguments:\r
1657 FlashDeviceName - name of flash device (from the flash definition file)\r
1658 to use\r
1659 FileName - name of output file to create\r
1660\r
1661Returns:\r
1662 STATUS_SUCCESS - no errors or warnings\r
1663 STATUS_WARNING - warnings, but no errors, were encountered\r
1664 STATUS_ERROR - errors were encountered\r
1665\r
1666--*/\r
1667{\r
1668 FILE *OutFptr;\r
1669 FLASH_BLOCK_DESCRIPTION *FBlock;\r
1670 FLASH_DEVICE_DESCRIPTION *FDev;\r
1671 FLASH_SUBREGION_DESCRIPTION *Subregion;\r
1672 unsigned int Offset;\r
1673 unsigned int SubregionOffset;\r
1674 int CreateHobs;\r
1675 //\r
1676 // Find the definition we're supposed to use\r
1677 //\r
1678 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
1679 if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
1680 break;\r
1681 }\r
1682 }\r
1683\r
1684 if (FDev == NULL) {\r
1685 Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");\r
1686 return STATUS_ERROR;\r
1687 }\r
1688\r
1689 if ((OutFptr = fopen (FileName, "w")) == NULL) {\r
1690 Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
1691 return STATUS_ERROR;\r
1692 }\r
1693 //\r
1694 // Write a header\r
1695 //\r
1696 fprintf (OutFptr, CIncludeHeader);\r
1697 //\r
1698 // Write flash block base and size defines\r
1699 //\r
1700 fprintf (OutFptr, "#define FLASH_BASE 0x%08X\n", FDev->BaseAddress);\r
1701 fprintf (OutFptr, "#define FLASH_SIZE 0x%08X\n\n", FDev->Size);\r
1702 //\r
1703 // Write flash regions base, size and offset defines\r
1704 //\r
1705 Offset = 0;\r
1706 CreateHobs = 0;\r
1707 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
1708 fprintf (\r
1709 OutFptr,\r
1710 "#define FLASH_REGION_%s_BASE %*c0x%08X\n",\r
1711 FBlock->Name,\r
1712 COLUMN2_START - 40 - strlen (FBlock->Name),\r
1713 ' ',\r
1714 Offset + FDev->BaseAddress\r
1715 );\r
1716 fprintf (\r
1717 OutFptr,\r
1718 "#define FLASH_REGION_%s_SIZE %*c0x%08X\n",\r
1719 FBlock->Name,\r
1720 COLUMN2_START - 40 - strlen (FBlock->Name),\r
1721 ' ',\r
1722 FBlock->Size\r
1723 );\r
1724 fprintf (\r
1725 OutFptr,\r
1726 "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n",\r
1727 FBlock->Name,\r
1728 COLUMN2_START - 40 - strlen (FBlock->Name),\r
1729 ' ',\r
1730 Offset\r
1731 );\r
1732 //\r
1733 // Create defines for any subregions\r
1734 //\r
1735 SubregionOffset = 0;\r
1736 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
1737 fprintf (\r
1738 OutFptr,\r
1739 "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n",\r
1740 FBlock->Name,\r
1741 Subregion->Name,\r
1742 COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
1743 ' ',\r
1744 FDev->BaseAddress + Offset + SubregionOffset\r
1745 );\r
1746 fprintf (\r
1747 OutFptr,\r
1748 "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n",\r
1749 FBlock->Name,\r
1750 Subregion->Name,\r
1751 COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
1752 ' ',\r
1753 Subregion->Size\r
1754 );\r
1755 fprintf (\r
1756 OutFptr,\r
1757 "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n",\r
1758 FBlock->Name,\r
1759 Subregion->Name,\r
1760 COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
1761 ' ',\r
1762 Offset + SubregionOffset\r
1763 );\r
1764 SubregionOffset += Subregion->Size;\r
1765 if (Subregion->CreateHob != 0) {\r
1766 CreateHobs = 1;\r
1767 }\r
1768 }\r
1769\r
1770 Offset += FBlock->Size;\r
1771 }\r
1772 //\r
1773 // Now create a #define for the flash map data definition\r
1774 //\r
1775 fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n");\r
1776 //\r
1777 // Emit entry for each region\r
1778 //\r
1779 Offset = 0;\r
1780 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
1781 fprintf (OutFptr, " /* %s region */\\\n", FBlock->Name);\r
1782 fprintf (OutFptr, " {\\\n");\r
1783 fprintf (OutFptr, " FLASH_REGION_%s_BASE,\\\n", FBlock->Name);\r
1784 fprintf (OutFptr, " FLASH_REGION_%s_SIZE,\\\n", FBlock->Name);\r
1785 fprintf (OutFptr, " %s,\\\n", FBlock->Attributes);\r
1786 fprintf (OutFptr, " %s,\\\n },\\\n", FBlock->AreaType);\r
1787 }\r
1788\r
1789 fprintf (OutFptr, "\n\n");\r
1790 //\r
1791 // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\r
1792 //\r
1793 if (CreateHobs != 0) {\r
1794 fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n");\r
1795 fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION");\r
1796 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
1797 //\r
1798 // See if the block has subregions, and that the CreateHobs flag is set\r
1799 // for any of them.\r
1800 //\r
1801 CreateHobs = 0;\r
1802 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
1803 if (Subregion->CreateHob != 0) {\r
1804 CreateHobs = 1;\r
1805 break;\r
1806 }\r
1807 }\r
1808 //\r
1809 // If any of the subregions had the CreateHobs flag set, then create the entries in the\r
1810 // output file\r
1811 //\r
1812 if (CreateHobs != 0) {\r
1813 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
1814 if (Subregion->CreateHob != 0) {\r
1815 fprintf (OutFptr, " \\\n");\r
1816 fprintf (OutFptr, " /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name);\r
1817 fprintf (OutFptr, " {\\\n");\r
1818 fprintf (OutFptr, " EFI_HOB_TYPE_GUID_EXTENSION,\\\n");\r
1819 fprintf (OutFptr, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n");\r
1820 fprintf (OutFptr, " 0,\\\n");\r
1821 //\r
1822 // The NameGuid may have been specified in the input flash definition file as a GUID, or\r
1823 // as a quoted string. Do the right one.\r
1824 //\r
1825 if (Subregion->NameGuidString[0] != 0) {\r
1826 fprintf (OutFptr, " %s, \\\n", Subregion->NameGuidString);\r
1827 } else {\r
1828 fprintf (\r
1829 OutFptr,\r
1830 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",\r
1831 Subregion->NameGuid.Data1,\r
1832 (unsigned int) Subregion->NameGuid.Data2,\r
1833 (unsigned int) Subregion->NameGuid.Data3,\r
1834 (unsigned int) Subregion->NameGuid.Data4[0],\r
1835 (unsigned int) Subregion->NameGuid.Data4[1],\r
1836 (unsigned int) Subregion->NameGuid.Data4[2],\r
1837 (unsigned int) Subregion->NameGuid.Data4[3],\r
1838 (unsigned int) Subregion->NameGuid.Data4[4],\r
1839 (unsigned int) Subregion->NameGuid.Data4[5],\r
1840 (unsigned int) Subregion->NameGuid.Data4[6],\r
1841 (unsigned int) Subregion->NameGuid.Data4[7]\r
1842 );\r
1843 }\r
1844\r
1845 fprintf (OutFptr, " 0, 0, 0,\\\n");\r
1846 fprintf (OutFptr, " %s,\\\n", Subregion->AreaType);\r
1847 //\r
1848 // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or\r
1849 // as a quoted string. Do the right one.\r
1850 //\r
1851 if (Subregion->AreaTypeGuidString[0] != 0) {\r
1852 fprintf (OutFptr, " %s, \\\n", Subregion->AreaTypeGuidString);\r
1853 } else {\r
1854 fprintf (\r
1855 OutFptr,\r
1856 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",\r
1857 Subregion->AreaTypeGuid.Data1,\r
1858 (unsigned int) Subregion->AreaTypeGuid.Data2,\r
1859 (unsigned int) Subregion->AreaTypeGuid.Data3,\r
1860 (unsigned int) Subregion->AreaTypeGuid.Data4[0],\r
1861 (unsigned int) Subregion->AreaTypeGuid.Data4[1],\r
1862 (unsigned int) Subregion->AreaTypeGuid.Data4[2],\r
1863 (unsigned int) Subregion->AreaTypeGuid.Data4[3],\r
1864 (unsigned int) Subregion->AreaTypeGuid.Data4[4],\r
1865 (unsigned int) Subregion->AreaTypeGuid.Data4[5],\r
1866 (unsigned int) Subregion->AreaTypeGuid.Data4[6],\r
1867 (unsigned int) Subregion->AreaTypeGuid.Data4[7]\r
1868 );\r
1869 }\r
1870\r
1871 fprintf (OutFptr, " 1,\\\n");\r
1872 fprintf (OutFptr, " {\\\n");\r
1873 fprintf (OutFptr, " %s,\\\n", Subregion->Attributes);\r
1874 fprintf (OutFptr, " 0,\\\n");\r
1875 fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name);\r
1876 fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name);\r
1877 //\r
1878 // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or\r
1879 // as a quoted string. Do the right one.\r
1880 //\r
1881 if (Subregion->FileSystemGuidString[0] != 0) {\r
1882 fprintf (OutFptr, " %s, \\\n", Subregion->FileSystemGuidString);\r
1883 } else {\r
1884 fprintf (\r
1885 OutFptr,\r
1886 " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n",\r
1887 Subregion->FileSystemGuid.Data1,\r
1888 (unsigned int) Subregion->FileSystemGuid.Data2,\r
1889 (unsigned int) Subregion->FileSystemGuid.Data3,\r
1890 (unsigned int) Subregion->FileSystemGuid.Data4[0],\r
1891 (unsigned int) Subregion->FileSystemGuid.Data4[1],\r
1892 (unsigned int) Subregion->FileSystemGuid.Data4[2],\r
1893 (unsigned int) Subregion->FileSystemGuid.Data4[3],\r
1894 (unsigned int) Subregion->FileSystemGuid.Data4[4],\r
1895 (unsigned int) Subregion->FileSystemGuid.Data4[5],\r
1896 (unsigned int) Subregion->FileSystemGuid.Data4[6],\r
1897 (unsigned int) Subregion->FileSystemGuid.Data4[7]\r
1898 );\r
1899 }\r
1900\r
1901 fprintf (OutFptr, " },\\\n");\r
1902 fprintf (OutFptr, " },");\r
1903 }\r
1904 }\r
1905 }\r
1906 }\r
1907\r
1908 fprintf (OutFptr, "\n\n");\r
1909 }\r
1910\r
1911 //\r
1912 // Write the file's closing #endif\r
1913 //\r
1914 fprintf (OutFptr, CIncludeFooter);\r
1915 fclose (OutFptr);\r
1916 return STATUS_SUCCESS;\r
1917}\r
1918\r
1919STATUS\r
1920FDFCreateAsmIncludeFile (\r
1921 char *FlashDeviceName,\r
1922 char *FileName\r
1923 )\r
1924/*++\r
1925\r
1926Routine Description:\r
1927 Create an assembly header file with equate definitions per an already-parsed\r
1928 flash definition file.\r
1929\r
1930Arguments:\r
1931 FlashDeviceName - name of flash device (from the flash definition file)\r
1932 to use\r
1933 FileName - name of output file to create\r
1934\r
1935Returns:\r
1936 STATUS_SUCCESS - no errors or warnings\r
1937 STATUS_WARNING - warnings, but no errors, were encountered\r
1938 STATUS_ERROR - errors were encountered\r
1939\r
1940--*/\r
1941{\r
1942 FILE *OutFptr;\r
1943 FLASH_BLOCK_DESCRIPTION *FBlock;\r
1944 FLASH_DEVICE_DESCRIPTION *FDev;\r
1945 unsigned int Offset;\r
1946 FLASH_SUBREGION_DESCRIPTION *Subregion;\r
1947 unsigned int SubregionOffset;\r
1948 //\r
1949 // Find the definition we're supposed to use\r
1950 //\r
1951 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
1952 if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
1953 break;\r
1954 }\r
1955 }\r
1956\r
1957 if (FDev == NULL) {\r
1958 Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");\r
1959 return STATUS_ERROR;\r
1960 }\r
1961\r
1962 if ((OutFptr = fopen (FileName, "w")) == NULL) {\r
1963 Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
1964 return STATUS_ERROR;\r
1965 }\r
1966 //\r
1967 // Write a header\r
1968 //\r
1969 fprintf (OutFptr, "\n\n");\r
1970 //\r
1971 // Write flash block size and offset defines\r
1972 //\r
1973 fprintf (\r
1974 OutFptr,\r
1975 "FLASH_BASE %*cequ 0%08Xh\n",\r
1976 COLUMN2_START - 40,\r
1977 ' ',\r
1978 FDev->BaseAddress\r
1979 );\r
1980 fprintf (OutFptr, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size);\r
1981 //\r
1982 // Write flash region size and offset defines\r
1983 //\r
1984 fprintf (OutFptr, "\n");\r
1985 Offset = 0;\r
1986 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
1987 fprintf (\r
1988 OutFptr,\r
1989 "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n",\r
1990 FBlock->Name,\r
1991 COLUMN2_START - 20 - strlen (FBlock->Name),\r
1992 ' ',\r
1993 FDev->BaseAddress + Offset\r
1994 );\r
1995 fprintf (\r
1996 OutFptr,\r
1997 "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n",\r
1998 FBlock->Name,\r
1999 COLUMN2_START - 20 - strlen (FBlock->Name),\r
2000 ' ',\r
2001 FBlock->Size\r
2002 );\r
2003 fprintf (\r
2004 OutFptr,\r
2005 "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n",\r
2006 FBlock->Name,\r
2007 COLUMN2_START - 20 - strlen (FBlock->Name),\r
2008 ' ',\r
2009 Offset\r
2010 );\r
2011 //\r
2012 // Create defines for any subregions\r
2013 //\r
2014 SubregionOffset = 0;\r
2015 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
2016 fprintf (\r
2017 OutFptr,\r
2018 "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n",\r
2019 FBlock->Name,\r
2020 Subregion->Name,\r
2021 COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
2022 ' ',\r
2023 FDev->BaseAddress + Offset + SubregionOffset\r
2024 );\r
2025 fprintf (\r
2026 OutFptr,\r
2027 "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n",\r
2028 FBlock->Name,\r
2029 Subregion->Name,\r
2030 COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
2031 ' ',\r
2032 Subregion->Size\r
2033 );\r
2034 fprintf (\r
2035 OutFptr,\r
2036 "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n",\r
2037 FBlock->Name,\r
2038 Subregion->Name,\r
2039 COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
2040 ' ',\r
2041 Offset + SubregionOffset\r
2042 );\r
2043 SubregionOffset += Subregion->Size;\r
2044 }\r
2045\r
2046 Offset += FBlock->Size;\r
2047 }\r
2048\r
2049 //\r
2050 // Write closing \n\r
2051 //\r
2052 fprintf (OutFptr, "\n\n");\r
2053 fclose (OutFptr);\r
2054 return STATUS_SUCCESS;\r
2055}\r
2056\r
2057STATUS\r
2058FDFCreateSymbols (\r
2059 char *FlashDeviceName\r
2060 )\r
2061/*++\r
2062\r
2063Routine Description:\r
2064 Using the given flash device name, add symbols to the global symbol table. This\r
2065 allows other functions to use the symbol definitions for other purposes.\r
2066\r
2067Arguments:\r
2068 FlashDeviceName - name of flash device (from the flash definition file)\r
2069 to use\r
2070\r
2071Returns:\r
2072 STATUS_SUCCESS - no errors or warnings\r
2073 STATUS_WARNING - warnings, but no errors, were encountered\r
2074 STATUS_ERROR - errors were encountered\r
2075\r
2076--*/\r
2077{\r
2078 FLASH_BLOCK_DESCRIPTION *FBlock;\r
2079 FLASH_DEVICE_DESCRIPTION *FDev;\r
2080 unsigned int Offset;\r
2081 char SymName[120];\r
2082 char SymValue[120];\r
2083 FLASH_SUBREGION_DESCRIPTION *Subregion;\r
2084 unsigned int SubregionOffset;\r
2085 //\r
2086 // Find the definition we're supposed to use\r
2087 //\r
2088 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
2089 if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
2090 break;\r
2091 }\r
2092 }\r
2093\r
2094 if (FDev == NULL) {\r
2095 Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions");\r
2096 return STATUS_ERROR;\r
2097 }\r
2098\r
2099 sprintf (SymValue, "0x%08X", FDev->BaseAddress);\r
2100 SymbolAdd ("FLASH_BASE", SymValue, 0);\r
2101 sprintf (SymValue, "0x%08X", FDev->Size);\r
2102 SymbolAdd ("FLASH_SIZE", SymValue, 0);\r
2103 //\r
2104 // Add flash block size and offset defines\r
2105 //\r
2106 // Offset = 0;\r
2107 // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) {\r
2108 // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name);\r
2109 // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);\r
2110 // SymbolAdd (SymName, SymValue, 0);\r
2111 // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name);\r
2112 // sprintf (SymValue, "0x%08X", FBlock->Size);\r
2113 // SymbolAdd (SymName, SymValue, 0);\r
2114 // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name);\r
2115 // sprintf (SymValue, "0x%08X", Offset);\r
2116 // SymbolAdd (SymName, SymValue, 0);\r
2117 // Offset += FBlock->Size;\r
2118 // }\r
2119 //\r
2120 // Add flash region block base, size, and offset defines\r
2121 //\r
2122 Offset = 0;\r
2123 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
2124 sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name);\r
2125 sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset);\r
2126 SymbolAdd (SymName, SymValue, 0);\r
2127 sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name);\r
2128 sprintf (SymValue, "0x%08X", FBlock->Size);\r
2129 SymbolAdd (SymName, SymValue, 0);\r
2130 sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name);\r
2131 sprintf (SymValue, "0x%08X", Offset);\r
2132 SymbolAdd (SymName, SymValue, 0);\r
2133 //\r
2134 // Add subregion symbols\r
2135 //\r
2136 if (FBlock->Subregions != NULL) {\r
2137 SubregionOffset = 0;\r
2138 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
2139 sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name);\r
2140 sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset);\r
2141 SymbolAdd (SymName, SymValue, 0);\r
2142 sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name);\r
2143 sprintf (SymValue, "0x%08X", Subregion->Size);\r
2144 SymbolAdd (SymName, SymValue, 0);\r
2145 sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name);\r
2146 sprintf (SymValue, "0x%08X", Offset + SubregionOffset);\r
2147 SymbolAdd (SymName, SymValue, 0);\r
2148 SubregionOffset += Subregion->Size;\r
2149 }\r
2150 }\r
2151\r
2152 Offset += FBlock->Size;\r
2153 }\r
2154\r
2155 return STATUS_SUCCESS;\r
2156}\r
2157\r
2158STATUS\r
2159FDFCreateImage (\r
2160 char *FlashDeviceName,\r
2161 char *ImageName,\r
2162 char *FileName\r
2163 )\r
2164/*++\r
2165\r
2166Routine Description:\r
2167 Create a flash image using the given device and image names.\r
2168\r
2169Arguments:\r
2170 FlashDeviceName - name of flash device (from the flash definition file)\r
2171 to use\r
2172 ImageName - name of image (from the flash definition file) to create\r
2173 FileName - name of output file to create\r
2174\r
2175Returns:\r
2176 STATUS_SUCCESS - no errors or warnings\r
2177 STATUS_WARNING - warnings, but no errors, were encountered\r
2178 STATUS_ERROR - errors were encountered\r
2179\r
2180--*/\r
2181{\r
2182 STATUS Status;\r
2183 FILE *OutFptr;\r
2184 FLASH_BLOCK_DESCRIPTION *RegionDef;\r
2185 FLASH_DEVICE_DESCRIPTION *FDev;\r
2186 IMAGE_DEFINITION *ImageDef;\r
2187 unsigned int Offset;\r
2188 char *Buffer;\r
2189 FILE *InFptr;\r
2190 long FileSize;\r
2191 IMAGE_DEFINITION_ENTRY *IDefEntry;\r
2192 FLASH_SUBREGION_DESCRIPTION *SubregionDef;\r
2193 //\r
2194 // Find the flash definition we're supposed to use\r
2195 //\r
2196 InFptr = NULL;\r
2197 Status = STATUS_ERROR;\r
2198 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
2199 if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
2200 break;\r
2201 }\r
2202 }\r
2203\r
2204 if (FDev == NULL) {\r
2205 Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");\r
2206 return STATUS_ERROR;\r
2207 }\r
2208 //\r
2209 // Find the image name we're supposed to create\r
2210 //\r
2211 for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) {\r
2212 if (strcmp (ImageDef->Name, ImageName) == 0) {\r
2213 break;\r
2214 }\r
2215 }\r
2216\r
2217 if (ImageDef == NULL) {\r
2218 Error (NULL, 0, 0, ImageName, "image definition not found in image definitions");\r
2219 return STATUS_ERROR;\r
2220 }\r
2221 //\r
2222 // Open the output file\r
2223 //\r
2224 if ((OutFptr = fopen (FileName, "wb")) == NULL) {\r
2225 Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
2226 return STATUS_ERROR;\r
2227 }\r
2228 //\r
2229 // Allocate a buffer to copy the input data to\r
2230 //\r
2231 Buffer = (char *) _malloc (FDev->Size);\r
2232 if (Buffer == NULL) {\r
2233 Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL);\r
2234 goto Done;\r
2235 }\r
2236 //\r
2237 // Set contents of buffer to the erased value\r
2238 //\r
2239 if (FDev->ErasePolarity) {\r
2240 memset (Buffer, 0xFF, FDev->Size);\r
2241 } else {\r
2242 memset (Buffer, 0, FDev->Size);\r
2243 }\r
2244 //\r
2245 // Set all region and subregion size-left fields to the size of the region/subregion\r
2246 //\r
2247 for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {\r
2248 RegionDef->SizeLeft = RegionDef->Size;\r
2249 for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {\r
2250 SubregionDef->SizeLeft = SubregionDef->Size;\r
2251 }\r
2252 }\r
2253 //\r
2254 // Now go through the image list, read files into the buffer.\r
2255 //\r
2256 for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) {\r
2257 //\r
2258 // If it's a file name, open the file, get the size, find the corresponding\r
2259 // flash region it's in, and copy the data.\r
2260 //\r
2261 if (IDefEntry->IsRawData == 0) {\r
2262 if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) {\r
2263 Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading");\r
2264 goto Done;\r
2265 }\r
2266\r
2267 fseek (InFptr, 0, SEEK_END);\r
2268 FileSize = ftell (InFptr);\r
2269 fseek (InFptr, 0, SEEK_SET);\r
2270 } else {\r
2271 FileSize = IDefEntry->RawDataSize;\r
2272 }\r
2273 //\r
2274 // Find the region/subregion it's in, see if we have space left\r
2275 //\r
2276 Offset = 0;\r
2277 for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) {\r
2278 if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) {\r
2279 break;\r
2280 }\r
2281\r
2282 Offset += RegionDef->Size;\r
2283 }\r
2284\r
2285 if (RegionDef == NULL) {\r
2286 Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name);\r
2287 goto Done;\r
2288 }\r
2289\r
2290 //\r
2291 // Check for subregion\r
2292 //\r
2293 if (IDefEntry->SubregionName[0] != 0) {\r
2294 for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) {\r
2295 if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) {\r
2296 break;\r
2297 }\r
2298\r
2299 Offset += SubregionDef->Size;\r
2300 }\r
2301\r
2302 if (SubregionDef == NULL) {\r
2303 Error (\r
2304 NULL,\r
2305 0,\r
2306 0,\r
2307 IDefEntry->SubregionName,\r
2308 "Subregion name not found in FlashDevice %s.%s Region definition",\r
2309 FDev->Name,\r
2310 RegionDef->Name\r
2311 );\r
2312 goto Done;\r
2313 }\r
2314 //\r
2315 // Enough space in the subregion?\r
2316 //\r
2317 if (SubregionDef->SizeLeft < (unsigned int) FileSize) {\r
2318 Error (\r
2319 NULL,\r
2320 0,\r
2321 0,\r
2322 IDefEntry->Name,\r
2323 "insufficient space in Subregion (at least 0x%X additional bytes required)",\r
2324 FileSize - SubregionDef->SizeLeft\r
2325 );\r
2326 goto Done;\r
2327 }\r
2328\r
2329 //\r
2330 // Read the file into the buffer if it's a file. Otherwise copy the raw data\r
2331 //\r
2332 if (IDefEntry->IsRawData == 0) {\r
2333 if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) {\r
2334 Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");\r
2335 goto Done;\r
2336 }\r
2337\r
2338 fclose (InFptr);\r
2339 InFptr = NULL;\r
2340 } else {\r
2341 memcpy (\r
2342 Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft),\r
2343 IDefEntry->RawData,\r
2344 IDefEntry->RawDataSize\r
2345 );\r
2346 }\r
2347\r
2348 SubregionDef->SizeLeft -= FileSize;\r
2349 //\r
2350 // Align based on the Region alignment requirements.\r
2351 //\r
2352 if (RegionDef->Alignment != 0) {\r
2353 while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) {\r
2354 if (SubregionDef->SizeLeft == 0) {\r
2355 break;\r
2356 }\r
2357\r
2358 SubregionDef->SizeLeft--;\r
2359 }\r
2360 }\r
2361 } else {\r
2362 //\r
2363 // Placing data in a region. Check for enough space in the region left.\r
2364 //\r
2365 if (RegionDef->SizeLeft < (unsigned int) FileSize) {\r
2366 Error (\r
2367 NULL,\r
2368 0,\r
2369 0,\r
2370 IDefEntry->Name,\r
2371 "insufficient space in Region (at least 0x%X additional bytes required)",\r
2372 FileSize - RegionDef->SizeLeft\r
2373 );\r
2374 goto Done;\r
2375 }\r
2376\r
2377 //\r
2378 // Read the file into the buffer if it's a file. Otherwise copy the raw data\r
2379 //\r
2380 if (IDefEntry->IsRawData == 0) {\r
2381 if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) {\r
2382 Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents");\r
2383 goto Done;\r
2384 }\r
2385\r
2386 fclose (InFptr);\r
2387 InFptr = NULL;\r
2388 } else {\r
2389 memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize);\r
2390 }\r
2391\r
2392 RegionDef->SizeLeft -= FileSize;\r
2393 //\r
2394 // Align\r
2395 //\r
2396 if (RegionDef->Alignment != 0) {\r
2397 while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) {\r
2398 if (RegionDef->SizeLeft == 0) {\r
2399 break;\r
2400 }\r
2401\r
2402 RegionDef->SizeLeft--;\r
2403 }\r
2404 }\r
2405 }\r
2406 }\r
2407\r
2408 if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) {\r
2409 Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL);\r
2410 goto Done;\r
2411 }\r
2412\r
2413 Status = STATUS_SUCCESS;\r
2414Done:\r
2415 if (InFptr != NULL) {\r
2416 fclose (InFptr);\r
2417 }\r
2418\r
2419 if (Buffer != NULL) {\r
2420 _free (Buffer);\r
2421 }\r
2422\r
2423 if (OutFptr != NULL) {\r
2424 fclose (OutFptr);\r
2425 if (Status == STATUS_ERROR) {\r
2426 remove (FileName);\r
2427 }\r
2428 }\r
2429\r
2430 return Status;\r
2431}\r
2432\r
2433STATUS\r
2434FDFCreateDscFile (\r
2435 char *FlashDeviceName,\r
2436 char *FileName\r
2437 )\r
2438/*++\r
2439\r
2440Routine Description:\r
2441 Create a DSC-style output file with equates for flash management.\r
2442\r
2443Arguments:\r
2444 FlashDeviceName - name of flash device (from the flash definition file)\r
2445 to use\r
2446 FileName - name of output file to create\r
2447\r
2448Returns:\r
2449 STATUS_SUCCESS - no errors or warnings\r
2450 STATUS_WARNING - warnings, but no errors, were encountered\r
2451 STATUS_ERROR - errors were encountered\r
2452\r
2453--*/\r
2454{\r
2455 FILE *OutFptr;\r
2456 FLASH_BLOCK_DESCRIPTION *FBlock;\r
2457 FLASH_DEVICE_DESCRIPTION *FDev;\r
2458 unsigned int Offset;\r
2459 FLASH_SUBREGION_DESCRIPTION *Subregion;\r
2460 unsigned int SubregionOffset;\r
2461 //\r
2462 // Find the definition we're supposed to use\r
2463 //\r
2464 for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) {\r
2465 if (strcmp (FDev->Name, FlashDeviceName) == 0) {\r
2466 break;\r
2467 }\r
2468 }\r
2469\r
2470 if (FDev == NULL) {\r
2471 Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions");\r
2472 return STATUS_ERROR;\r
2473 }\r
2474\r
2475 if ((OutFptr = fopen (FileName, "w")) == NULL) {\r
2476 Error (NULL, 0, 0, FileName, "failed to open output file for writing");\r
2477 return STATUS_ERROR;\r
2478 }\r
2479 //\r
2480 // Write the flash base address and size\r
2481 //\r
2482 fprintf (OutFptr, "\n");\r
2483 fprintf (OutFptr, "FLASH_BASE = 0x%08X\n", FDev->BaseAddress);\r
2484 fprintf (OutFptr, "FLASH_SIZE = 0x%08X\n\n", FDev->Size);\r
2485 //\r
2486 // Write flash block size and offset defines\r
2487 //\r
2488 Offset = 0;\r
2489 for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) {\r
2490 fprintf (\r
2491 OutFptr,\r
2492 "FLASH_REGION_%s_BASE %*c= 0x%08X\n",\r
2493 FBlock->Name,\r
2494 COLUMN2_START - 40 - strlen (FBlock->Name),\r
2495 ' ',\r
2496 Offset + FDev->BaseAddress\r
2497 );\r
2498 fprintf (\r
2499 OutFptr,\r
2500 "FLASH_REGION_%s_SIZE %*c= 0x%08X\n",\r
2501 FBlock->Name,\r
2502 COLUMN2_START - 40 - strlen (FBlock->Name),\r
2503 ' ',\r
2504 FBlock->Size\r
2505 );\r
2506 fprintf (\r
2507 OutFptr,\r
2508 "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n",\r
2509 FBlock->Name,\r
2510 COLUMN2_START - 40 - strlen (FBlock->Name),\r
2511 ' ',\r
2512 (FBlock->Size)/(FDev->PBlocks->Size)\r
2513 ); \r
2514 //\r
2515 // Create defines for any subregions\r
2516 //\r
2517 SubregionOffset = 0;\r
2518 for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) {\r
2519 fprintf (\r
2520 OutFptr,\r
2521 "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n",\r
2522 FBlock->Name,\r
2523 Subregion->Name,\r
2524 COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
2525 ' ',\r
2526 FDev->BaseAddress + Offset + SubregionOffset\r
2527 );\r
2528 fprintf (\r
2529 OutFptr,\r
2530 "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n",\r
2531 FBlock->Name,\r
2532 Subregion->Name,\r
2533 COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
2534 ' ',\r
2535 Subregion->Size\r
2536 );\r
2537 fprintf (\r
2538 OutFptr,\r
2539 "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n",\r
2540 FBlock->Name,\r
2541 Subregion->Name,\r
2542 COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name),\r
2543 ' ',\r
2544 Offset + SubregionOffset\r
2545 );\r
2546\r
2547 SubregionOffset += Subregion->Size;\r
2548 }\r
2549\r
2550 Offset += FBlock->Size;\r
2551 }\r
2552 //\r
2553 // Close file\r
2554 //\r
2555 fprintf (OutFptr, "\n");\r
2556 fclose (OutFptr);\r
2557 return STATUS_SUCCESS;\r
2558}\r
2559\r
2560\r
2561/*++\r
2562\r
2563Routine Description:\r
2564 The following buffer management routines are used to encapsulate functionality\r
2565 for managing a growable data buffer.\r
2566\r
2567Arguments:\r
2568 BUFFER_DATA - structure that is used to maintain a data buffer\r
2569\r
2570Returns:\r
2571 NA\r
2572\r
2573--*/\r
2574static\r
2575BUFFER_DATA *\r
2576CreateBufferData (\r
2577 VOID\r
2578 )\r
2579/*++\r
2580\r
2581Routine Description:\r
2582\r
2583 Create a growable data buffer with default buffer length.\r
2584\r
2585Arguments:\r
2586\r
2587 None\r
2588\r
2589Returns:\r
2590\r
2591 NULL - error occured during data buffer creation\r
2592 Not NULL - the pointer to the newly created data buffer\r
2593\r
2594--*/\r
2595{\r
2596 BUFFER_DATA *BD;\r
2597 BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA));\r
2598 if (BD == NULL) {\r
2599 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
2600 return NULL;\r
2601 }\r
2602\r
2603 memset (BD, 0, sizeof (BUFFER_DATA));\r
2604 BD->BufferStart = (char *) _malloc (BUFFER_SIZE);\r
2605 if (BD->BufferStart == NULL) {\r
2606 _free (BD);\r
2607 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
2608 return NULL;\r
2609 }\r
2610\r
2611 BD->BufferEnd = BD->BufferStart + BUFFER_SIZE;\r
2612 BD->BufferPos = BD->BufferStart;\r
2613 return BD;\r
2614}\r
2615\r
2616static\r
2617BOOLEAN\r
2618AddBufferDataByte (\r
2619 BUFFER_DATA *Buffer,\r
2620 char Data\r
2621 )\r
2622/*++\r
2623\r
2624Routine Description:\r
2625\r
2626 Add a single byte to a growable data buffer, growing the buffer if required.\r
2627\r
2628Arguments:\r
2629\r
2630 Buffer - pointer to the growable data buffer to add a single byte to\r
2631 Data - value of the single byte data to be added\r
2632\r
2633Returns:\r
2634\r
2635 TRUE - the single byte data was successfully added\r
2636 FALSE - error occurred, the single byte data was not added\r
2637\r
2638--*/\r
2639{\r
2640 int Size;\r
2641 char *NewBuffer;\r
2642 //\r
2643 // See if we have to grow the buffer\r
2644 //\r
2645 if (Buffer->BufferPos >= Buffer->BufferEnd) {\r
2646 Size = (int) Buffer->BufferEnd - (int) Buffer->BufferStart;\r
2647 NewBuffer = (char *) _malloc (Size + BUFFER_SIZE);\r
2648 if (NewBuffer == NULL) {\r
2649 Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
2650 return FALSE;\r
2651 }\r
2652\r
2653 memcpy (NewBuffer, Buffer->BufferStart, Size);\r
2654 _free (Buffer->BufferStart);\r
2655 Buffer->BufferStart = NewBuffer;\r
2656 Buffer->BufferPos = Buffer->BufferStart + Size;\r
2657 Buffer->BufferEnd = Buffer->BufferStart + Size + BUFFER_SIZE;\r
2658 }\r
2659\r
2660 *Buffer->BufferPos = Data;\r
2661 Buffer->BufferPos++;\r
2662 return TRUE;\r
2663}\r
2664\r
2665static\r
2666void\r
2667FreeBufferData (\r
2668 BUFFER_DATA *Buffer,\r
2669 BOOLEAN FreeData\r
2670 )\r
2671/*++\r
2672\r
2673Routine Description:\r
2674\r
2675 Free memory used to manage a growable data buffer.\r
2676\r
2677Arguments:\r
2678\r
2679 Buffer - pointer to the growable data buffer to be destructed\r
2680 FreeData - TRUE, free memory containing the buffered data\r
2681 FALSE, do not free the buffered data memory\r
2682\r
2683Returns:\r
2684\r
2685 None\r
2686\r
2687--*/\r
2688{\r
2689 if (Buffer != NULL) {\r
2690 if (FreeData && (Buffer->BufferStart != NULL)) {\r
2691 _free (Buffer->BufferStart);\r
2692 }\r
2693\r
2694 _free (Buffer);\r
2695 }\r
2696}\r
2697\r
2698static\r
2699char *\r
2700GetBufferData (\r
2701 BUFFER_DATA *Buffer,\r
2702 int *BufferSize\r
2703 )\r
2704/*++\r
2705\r
2706Routine Description:\r
2707\r
2708 Return a pointer and size of the data in a growable data buffer.\r
2709\r
2710Arguments:\r
2711\r
2712 Buffer - pointer to the growable data buffer\r
2713 BufferSize - size of the data in the growable data buffer\r
2714\r
2715Returns:\r
2716\r
2717 pointer of the data in the growable data buffer\r
2718\r
2719--*/\r
2720{\r
2721 *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart;\r
2722 return Buffer->BufferStart;\r
2723}\r
2724\r
2725STATUS\r
2726FDDiscover (\r
2727 char *FDFileName,\r
2728 unsigned int BaseAddr\r
2729 )\r
2730/*++\r
2731\r
2732Routine Description:\r
2733 Walk a binary image and see if you find anything that looks like a\r
2734 firmware volume.\r
2735\r
2736Arguments:\r
2737 FDFileName - name of input FD image to parse\r
2738 BaseAddr - base address of input FD image\r
2739\r
2740Returns:\r
2741 STATUS_SUCCESS - no errors or warnings\r
2742 STATUS_WARNING - warnings, but no errors, were encountered\r
2743 STATUS_ERROR - errors were encountered\r
2744\r
2745NOTE:\r
2746 This routine is used for debug purposes only.\r
2747\r
2748--*/\r
2749{\r
2750 FILE *InFptr;\r
2751 long FileSize;\r
2752 long Offset;\r
2753 EFI_FIRMWARE_VOLUME_HEADER FVHeader;\r
2754 EFI_GUID\r
2755 FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF };\r
2756\r
2757 if ((InFptr = fopen (FDFileName, "rb")) == NULL) {\r
2758 Error (NULL, 0, 0, FDFileName, "failed to open file for reading");\r
2759 return STATUS_ERROR;\r
2760 }\r
2761\r
2762 fseek (InFptr, 0, SEEK_END);\r
2763 FileSize = ftell (InFptr);\r
2764 fseek (InFptr, 0, SEEK_SET);\r
2765 Offset = 0;\r
2766 while (Offset < FileSize) {\r
2767 fseek (InFptr, Offset, SEEK_SET);\r
2768 //\r
2769 // Read the contents of the file, see if it's an FV header\r
2770 //\r
2771 if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) {\r
2772 //\r
2773 // Check version and GUID\r
2774 //\r
2775 if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) {\r
2776 fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength);\r
2777 if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) {\r
2778 fprintf (stdout, "standard FFS file system\n");\r
2779 } else {\r
2780 fprintf (stdout, "non-standard FFS file system\n");\r
2781 }\r
2782 }\r
2783 }\r
2784\r
2785 Offset += 16 * 1024;\r
2786 }\r
2787\r
2788 fclose (InFptr);\r
2789 return STATUS_SUCCESS;\r
2790}\r