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