135c9ed23f8e3335b0518739a6c92ef3b7450cfc
[efi/edk2/.git] / edk2 / BaseTools / Source / C / GenFv / GenFv.c
1 /** @file\r
2 \r
3 Copyright (c) 2007 - 2009, Intel Corporation                                                         \r
4 All rights reserved. This program and the accompanying materials                          \r
5 are licensed and made available under the terms and conditions of the BSD License         \r
6 which accompanies this distribution.  The full text of the license may be found at        \r
7 http://opensource.org/licenses/bsd-license.php                                            \r
8                                                                                           \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
11 \r
12 Module Name:\r
13 \r
14   GenFv.c\r
15 \r
16 Abstract:\r
17 \r
18   This contains all code necessary to build the GenFvImage.exe utility.       \r
19   This utility relies heavily on the GenFvImage Lib.  Definitions for both\r
20   can be found in the Tiano Firmware Volume Generation Utility \r
21   Specification, review draft.\r
22 \r
23 **/\r
24 \r
25 //\r
26 // File included in build\r
27 //\r
28 #include <stdio.h>\r
29 #include <string.h>\r
30 #include <stdlib.h>\r
31 #include "GenFvInternalLib.h"\r
32 \r
33 //\r
34 // Utility Name\r
35 //\r
36 #define UTILITY_NAME  "GenFv"\r
37 \r
38 //\r
39 // Utility version information\r
40 //\r
41 #define UTILITY_MAJOR_VERSION 0\r
42 #define UTILITY_MINOR_VERSION 1\r
43 #define GENFV_UPDATE_TIME           " updated on 2008/11/21"\r
44 \r
45 EFI_GUID  mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;\r
46 \r
47 STATIC\r
48 VOID \r
49 Version (\r
50   VOID\r
51 )\r
52 /*++\r
53 \r
54 Routine Description:\r
55 \r
56   Displays the standard utility information to SDTOUT\r
57 \r
58 Arguments:\r
59 \r
60   None\r
61 \r
62 Returns:\r
63 \r
64   None\r
65 \r
66 --*/\r
67 {\r
68   fprintf (stdout, "%s Version %d.%d %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, GENFV_UPDATE_TIME);\r
69 }\r
70 \r
71 STATIC\r
72 VOID \r
73 Usage (\r
74   VOID\r
75   )\r
76 /*++\r
77 \r
78 Routine Description:\r
79 \r
80   Displays the utility usage syntax to STDOUT\r
81 \r
82 Arguments:\r
83 \r
84   None\r
85 \r
86 Returns:\r
87 \r
88   None\r
89 \r
90 --*/\r
91 {\r
92   //\r
93   // Summary usage\r
94   //\r
95   fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);\r
96   \r
97   //\r
98   // Copyright declaration\r
99   // \r
100   fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
101 \r
102   //\r
103   // Details Option\r
104   //\r
105   fprintf (stdout, "Options:\n");\r
106   fprintf (stdout, "  -o FileName, --outputfile FileName\n\\r
107                         File is the FvImage or CapImage to be created.\n");\r
108   fprintf (stdout, "  -i FileName, --inputfile FileName\n\\r
109                         File is the input FV.inf or Cap.inf to specify\n\\r
110                         how to construct FvImage or CapImage.\n");\r
111   fprintf (stdout, "  -b BlockSize, --blocksize BlockSize\n\\r
112                         BlockSize is one HEX or DEC format value\n\\r
113                         BlockSize is required by Fv Image.\n");\r
114   fprintf (stdout, "  -n NumberBlock, --numberblock NumberBlock\n\\r
115                         NumberBlock is one HEX or DEC format value\n\\r
116                         NumberBlock is one optional parameter.\n");\r
117   fprintf (stdout, "  -f FfsFile, --ffsfile FfsFile\n\\r
118                         FfsFile is placed into Fv Image\n\\r
119                         multi files can input one by one\n");\r
120   fprintf (stdout, "  -s FileTakenSize, --filetakensize FileTakenSize\n\\r
121                         FileTakenSize specifies the size of the required\n\\r
122                         space that the input file is placed in Fvimage.\n\\r
123                         It is specified together with the input file.\n");\r
124   fprintf (stdout, "  -r Address, --baseaddr Address\n\\r
125                         Address is the rebase start address for drivers that\n\\r
126                         run in Flash. It supports DEC or HEX digital format.\n\\r
127                         If it is set to zero, no rebase action will be taken\n");\r
128   fprintf (stdout, "  -a AddressFile, --addrfile AddressFile\n\\r
129                         AddressFile is one file used to record boot driver base\n\\r
130                         address and runtime driver base address. And this tool\n\\r
131                         will update these two addresses after it relocates all\n\\r
132                         boot drivers and runtime drivers in this fv iamge to\n\\r
133                         the preferred loaded memory address.\n");\r
134   fprintf (stdout, "  -m logfile, --map logfile\n\\r
135                         Logfile is the output fv map file name. if it is not\n\\r
136                         given, the FvName.map will be the default map file name\n"); \r
137   fprintf (stdout, "  -g Guid, --guid Guid\n\\r
138                         GuidValue is one specific capsule guid value\n\\r
139                         or fv file system guid value.\n\\r
140                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
141   fprintf (stdout, "  --FvNameGuid Guid     Guid is used to specify Fv Name.\n\\r
142                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
143   fprintf (stdout, "  --capflag CapFlag     Capsule Reset Flag can be PersistAcrossReset,\n\\r
144                         or PopulateSystemTable or InitiateReset or not set\n");\r
145   fprintf (stdout, "  --capheadsize HeadSize\n\\r
146                         HeadSize is one HEX or DEC format value\n\\r
147                         HeadSize is required by Capsule Image.\n");                        \r
148   fprintf (stdout, "  -c, --capsule         Create Capsule Image.\n");\r
149   fprintf (stdout, "  -p, --dump            Dump Capsule Image header.\n");\r
150   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");\r
151   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");\r
152   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");\r
153   fprintf (stdout, "  --version             Show program's version number and exit.\n");\r
154   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");\r
155 }\r
156 \r
157 UINT32 mFvTotalSize;\r
158 UINT32 mFvTakenSize;\r
159 \r
160 int\r
161 main (\r
162   IN int   argc,\r
163   IN char  **argv\r
164   )\r
165 /*++\r
166 \r
167 Routine Description:\r
168 \r
169   This utility uses GenFvImage.Lib to build a firmware volume image.\r
170 \r
171 Arguments:\r
172 \r
173   FvInfFileName      The name of an FV image description file or Capsule Image.\r
174 \r
175   Arguments come in pair in any order.\r
176     -I FvInfFileName \r
177 \r
178 Returns:\r
179 \r
180   EFI_SUCCESS            No error conditions detected.\r
181   EFI_INVALID_PARAMETER  One or more of the input parameters is invalid.\r
182   EFI_OUT_OF_RESOURCES   A resource required by the utility was unavailable.  \r
183                          Most commonly this will be memory allocation \r
184                          or file creation.\r
185   EFI_LOAD_ERROR         GenFvImage.lib could not be loaded.\r
186   EFI_ABORTED            Error executing the GenFvImage lib.\r
187 \r
188 --*/\r
189 {\r
190   EFI_STATUS            Status;\r
191   CHAR8                 *InfFileName;\r
192   CHAR8                 *AddrFileName;\r
193   CHAR8                 *MapFileName;\r
194   CHAR8                 *InfFileImage;\r
195   UINT32                InfFileSize;\r
196   CHAR8                 *OutFileName;\r
197   CHAR8                 ValueString[_MAX_PATH];\r
198   BOOLEAN               CapsuleFlag;\r
199   BOOLEAN               DumpCapsule;\r
200   MEMORY_FILE           AddrMemoryFile;\r
201   FILE                  *FpFile;\r
202   EFI_CAPSULE_HEADER    *CapsuleHeader;\r
203   UINT64                LogLevel, TempNumber;\r
204   UINT32                Index;\r
205 \r
206   InfFileName   = NULL;\r
207   AddrFileName  = NULL;\r
208   InfFileImage  = NULL;\r
209   OutFileName   = NULL;\r
210   MapFileName   = NULL;\r
211   InfFileSize   = 0;\r
212   CapsuleFlag   = FALSE;\r
213   DumpCapsule   = FALSE;\r
214   FpFile        = NULL;\r
215   CapsuleHeader = NULL;\r
216   LogLevel      = 0;\r
217   TempNumber    = 0;\r
218   Index         = 0;\r
219   mFvTotalSize  = 0;\r
220   mFvTakenSize  = 0;\r
221   Status        = EFI_SUCCESS;\r
222 \r
223   SetUtilityName (UTILITY_NAME);\r
224   \r
225   if (argc == 1) {\r
226     Error (NULL, 0, 1001, "Missing options", "No input options specified.");\r
227     Usage ();\r
228     return STATUS_ERROR;\r
229   }\r
230 \r
231   //\r
232   // Init global data to Zero\r
233   //\r
234   memset (&mFvDataInfo, 0, sizeof (FV_INFO));\r
235   memset (&mCapDataInfo, 0, sizeof (CAP_INFO)); \r
236   //\r
237   // Set the default FvGuid\r
238   //\r
239   memcpy (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid, sizeof (EFI_GUID));\r
240    \r
241   //\r
242   // Parse command line\r
243   //\r
244   argc --;\r
245   argv ++;\r
246 \r
247   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
248     Version ();\r
249     Usage ();\r
250     return STATUS_SUCCESS;    \r
251   }\r
252 \r
253   if (stricmp (argv[0], "--version") == 0) {\r
254     Version ();\r
255     return STATUS_SUCCESS;    \r
256   }\r
257 \r
258   while (argc > 0) {\r
259     if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {\r
260       InfFileName = argv[1];\r
261       if (InfFileName == NULL) {\r
262         Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");\r
263         return STATUS_ERROR;\r
264       }\r
265       argc -= 2;\r
266       argv += 2;\r
267       continue; \r
268     }\r
269 \r
270     if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {\r
271       AddrFileName = argv[1];\r
272       if (AddrFileName == NULL) {\r
273         Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");\r
274         return STATUS_ERROR;\r
275       }\r
276       argc -= 2;\r
277       argv += 2;\r
278       continue; \r
279     }\r
280 \r
281     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
282       OutFileName = argv[1];\r
283       if (OutFileName == NULL) {\r
284         Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");\r
285         return STATUS_ERROR;\r
286       }\r
287       argc -= 2;\r
288       argv += 2;\r
289       continue; \r
290     }\r
291 \r
292     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {\r
293       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
294       if (EFI_ERROR (Status)) {\r
295         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
296         return STATUS_ERROR;        \r
297       }\r
298       mFvDataInfo.BaseAddress    = TempNumber;\r
299       mFvDataInfo.BaseAddressSet = TRUE;\r
300       argc -= 2;\r
301       argv += 2;\r
302       continue; \r
303     }\r
304 \r
305     if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {\r
306       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
307       if (EFI_ERROR (Status)) {\r
308         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
309         return STATUS_ERROR;        \r
310       }\r
311       if (TempNumber == 0) {\r
312         Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");\r
313         return STATUS_ERROR;        \r
314       }\r
315       mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;\r
316       DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%llx", EFI_BLOCK_SIZE_STRING, (unsigned long long) TempNumber);\r
317       argc -= 2;\r
318       argv += 2;\r
319       continue; \r
320     }\r
321 \r
322     if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {\r
323       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
324       if (EFI_ERROR (Status)) {\r
325         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
326         return STATUS_ERROR;        \r
327       }\r
328       if (TempNumber == 0) {\r
329         Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");\r
330         return STATUS_ERROR;        \r
331       }\r
332       mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;\r
333       DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%llx", EFI_NUM_BLOCKS_STRING, (unsigned long long) TempNumber);\r
334       argc -= 2;\r
335       argv += 2;\r
336       continue; \r
337     }\r
338 \r
339     if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {\r
340       if (argv[1] == NULL) {\r
341         Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");\r
342         return STATUS_ERROR;\r
343       }\r
344       strcpy (mFvDataInfo.FvFiles[Index], argv[1]);\r
345       DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index + 1, argv[1]);\r
346       argc -= 2;\r
347       argv += 2;\r
348 \r
349       if (argc > 0) {\r
350                     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {\r
351                       if (argv[1] == NULL) {\r
352                         Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");\r
353                         return STATUS_ERROR;\r
354                       }\r
355                       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
356                       if (EFI_ERROR (Status)) {\r
357                         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
358                         return STATUS_ERROR;        \r
359                       }\r
360                       mFvDataInfo.SizeofFvFiles[Index] = (UINT32) TempNumber;\r
361                 DebugMsg (NULL, 0, 9, "FV component file size", "the %uth size is %s", (unsigned) Index + 1, argv[1]);\r
362                 argc -= 2;\r
363                 argv += 2;\r
364         }\r
365       }\r
366       Index ++;\r
367       continue; \r
368     }\r
369 \r
370     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {\r
371       Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");\r
372       return STATUS_ERROR; \r
373     }\r
374 \r
375     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {\r
376       CapsuleFlag = TRUE;\r
377       argc --;\r
378       argv ++;\r
379       continue; \r
380     }\r
381 \r
382     if (stricmp (argv[0], "--capheadsize") == 0) {\r
383       //\r
384       // Get Capsule Image Header Size\r
385       //\r
386       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
387       if (EFI_ERROR (Status)) {\r
388         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
389         return STATUS_ERROR;        \r
390       }\r
391       mCapDataInfo.HeaderSize = (UINT32) TempNumber;\r
392       DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%llx", EFI_CAPSULE_HEADER_SIZE_STRING, (unsigned long long) TempNumber);\r
393       argc -= 2;\r
394       argv += 2;\r
395       continue; \r
396     }\r
397 \r
398     if (stricmp (argv[0], "--capflag") == 0) {\r
399       //\r
400       // Get Capsule Header\r
401       //\r
402       if (argv[1] == NULL) {\r
403         Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);\r
404         return STATUS_ERROR;\r
405       }\r
406       if (strcmp (argv[1], "PopulateSystemTable") == 0) {\r
407         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;\r
408       } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {\r
409         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;\r
410       } else if (strcmp (argv[1], "InitiateReset") == 0) {\r
411         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET;\r
412       } else {\r
413         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
414         return STATUS_ERROR;\r
415       }\r
416       DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);\r
417       argc -= 2;\r
418       argv += 2;\r
419       continue; \r
420     }\r
421 \r
422     if (stricmp (argv[0], "--capguid") == 0) {\r
423       //\r
424       // Get the Capsule Guid\r
425       //\r
426       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
427       if (EFI_ERROR (Status)) {\r
428         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
429         return STATUS_ERROR;\r
430       }\r
431       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
432       argc -= 2;\r
433       argv += 2;\r
434       continue; \r
435     }\r
436 \r
437     if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {\r
438       //\r
439       // Get the Capsule or Fv Guid\r
440       //\r
441       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
442       if (EFI_ERROR (Status)) {\r
443         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
444         return STATUS_ERROR;\r
445       }\r
446       memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));\r
447       mFvDataInfo.FvFileSystemGuidSet = TRUE;\r
448       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
449       DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);\r
450       argc -= 2;\r
451       argv += 2;\r
452       continue; \r
453     }\r
454 \r
455     if (stricmp (argv[0], "--FvNameGuid") == 0) {\r
456       //\r
457       // Get Fv Name Guid\r
458       //\r
459       Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);\r
460       if (EFI_ERROR (Status)) {\r
461         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
462         return STATUS_ERROR;\r
463       }\r
464       mFvDataInfo.FvNameGuidSet = TRUE;\r
465       DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);\r
466       argc -= 2;\r
467       argv += 2;\r
468       continue; \r
469     }\r
470 \r
471     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
472       DumpCapsule = TRUE;\r
473       argc --;\r
474       argv ++;\r
475       continue; \r
476     }\r
477 \r
478     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {\r
479       MapFileName = argv[1];\r
480       if (MapFileName == NULL) {\r
481         Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");\r
482         return STATUS_ERROR;\r
483       }\r
484       argc -= 2;\r
485       argv += 2;\r
486       continue; \r
487     }\r
488 \r
489     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
490       SetPrintLevel (VERBOSE_LOG_LEVEL);\r
491       VerboseMsg ("Verbose output Mode Set!");\r
492       argc --;\r
493       argv ++;\r
494       continue;\r
495     }\r
496 \r
497     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
498       SetPrintLevel (KEY_LOG_LEVEL);\r
499       KeyMsg ("Quiet output Mode Set!");\r
500       argc --;\r
501       argv ++;\r
502       continue;\r
503     }\r
504 \r
505     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
506       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
507       if (EFI_ERROR (Status)) {\r
508         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
509         return STATUS_ERROR;\r
510       }\r
511       if (LogLevel > 9) {\r
512         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
513         return STATUS_ERROR;\r
514       }\r
515       SetPrintLevel (LogLevel);\r
516       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
517       argc -= 2;\r
518       argv += 2;\r
519       continue;\r
520     }\r
521 \r
522     //\r
523     // Don't recognize the parameter.\r
524     //\r
525     Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);\r
526     return STATUS_ERROR;\r
527   }\r
528 \r
529   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
530   \r
531   //\r
532   // check input parameter, InfFileName can be NULL\r
533   //\r
534   if (InfFileName == NULL && DumpCapsule) {\r
535     Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");\r
536     return STATUS_ERROR;\r
537   }\r
538   VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);\r
539 \r
540   if (!DumpCapsule && OutFileName == NULL) {\r
541     Error (NULL, 0, 1001, "Missing option", "Output File");\r
542     return STATUS_ERROR;\r
543   }\r
544   if (OutFileName != NULL) {\r
545     VerboseMsg ("the output file name is %s", OutFileName);\r
546   }\r
547   \r
548   //\r
549   // Read boot and runtime address from address file\r
550   //\r
551   if (AddrFileName != NULL) {\r
552     VerboseMsg ("the input address file name is %s", AddrFileName);\r
553     Status = GetFileImage (AddrFileName, &InfFileImage, &InfFileSize);\r
554     if (EFI_ERROR (Status)) {\r
555       return STATUS_ERROR;\r
556     }\r
557 \r
558     AddrMemoryFile.FileImage           = InfFileImage;\r
559     AddrMemoryFile.CurrentFilePointer  = InfFileImage;\r
560     AddrMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
561 \r
562     //\r
563     // Read the boot driver base address for this FV image\r
564     //\r
565     Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
566     if (Status == EFI_SUCCESS) {\r
567       //\r
568       // Get the base address\r
569       //\r
570       Status = AsciiStringToUint64 (ValueString, FALSE, &TempNumber);\r
571       if (EFI_ERROR (Status)) {\r
572         Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
573         return STATUS_ERROR;\r
574       }\r
575       mFvDataInfo.BootBaseAddress = TempNumber;\r
576       DebugMsg (NULL, 0, 9, "Boot driver base address", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
577     }\r
578   \r
579     //\r
580     // Read the FV runtime driver base address\r
581     //\r
582     Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
583     if (Status == EFI_SUCCESS) {\r
584       //\r
585       // Get the base address\r
586       //\r
587       Status = AsciiStringToUint64 (ValueString, FALSE, &TempNumber);\r
588       if (EFI_ERROR (Status)) {\r
589         Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
590         return STATUS_ERROR;\r
591       }\r
592       mFvDataInfo.RuntimeBaseAddress = TempNumber;\r
593       DebugMsg (NULL, 0, 9, "Runtime driver base address", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
594     }\r
595     \r
596     //\r
597     // free the allocated memory space for addr file.\r
598     //\r
599     free (InfFileImage);\r
600     InfFileImage = NULL;\r
601     InfFileSize  = 0;\r
602   }\r
603 \r
604   //\r
605   // Read the INF file image\r
606   //\r
607   if (InfFileName != NULL) {\r
608     Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
609     if (EFI_ERROR (Status)) {\r
610       return STATUS_ERROR;\r
611     }\r
612   }\r
613   \r
614   if (DumpCapsule) {\r
615     VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);\r
616     //\r
617     // Dump Capsule Image Header Information\r
618     //\r
619     CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;\r
620     if (OutFileName == NULL) {\r
621       FpFile = stdout;\r
622     } else {\r
623       FpFile = fopen (OutFileName, "w");\r
624       if (FpFile == NULL) {\r
625         Error (NULL, 0, 0001, "Error opening file", OutFileName);\r
626         return STATUS_ERROR;\r
627       }\r
628     }\r
629     fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);\r
630     fprintf (FpFile, "  GUID                  %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", \r
631                     (unsigned) CapsuleHeader->CapsuleGuid.Data1,\r
632                     (unsigned) CapsuleHeader->CapsuleGuid.Data2,\r
633                     (unsigned) CapsuleHeader->CapsuleGuid.Data3,\r
634                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[0],\r
635                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[1],\r
636                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[2],\r
637                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[3],\r
638                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[4],\r
639                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[5],\r
640                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[6],\r
641                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[7]);\r
642     fprintf (FpFile, "  Header size           0x%08X\n", (unsigned) CapsuleHeader->HeaderSize);\r
643     fprintf (FpFile, "  Flags                 0x%08X\n", (unsigned) CapsuleHeader->Flags);\r
644     fprintf (FpFile, "  Capsule image size    0x%08X\n", (unsigned) CapsuleHeader->CapsuleImageSize);\r
645     fclose (FpFile);\r
646   } else if (CapsuleFlag) {\r
647     VerboseMsg ("Create capsule image");\r
648     //\r
649     // Call the GenerateCapImage to generate Capsule Image\r
650     //\r
651     for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {\r
652       strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);\r
653     }\r
654 \r
655     Status = GenerateCapImage (\r
656               InfFileImage, \r
657               InfFileSize,\r
658               OutFileName\r
659               );\r
660   } else {\r
661     VerboseMsg ("Create Fv image and its map file");\r
662     if (mFvDataInfo.BaseAddress != 0) {\r
663       VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);\r
664     }\r
665     //\r
666     // Call the GenerateFvImage to generate Fv Image\r
667     //\r
668     Status = GenerateFvImage (\r
669               InfFileImage,\r
670               InfFileSize,\r
671               OutFileName,\r
672               MapFileName\r
673               );\r
674   }\r
675 \r
676   //\r
677   // free InfFileImage memory\r
678   //\r
679   if (InfFileImage != NULL) {\r
680     free (InfFileImage);\r
681   }\r
682   \r
683   //\r
684   //  update boot driver address and runtime driver address in address file\r
685   //\r
686   if (Status == EFI_SUCCESS && AddrFileName != NULL) {\r
687     FpFile = fopen (AddrFileName, "w");\r
688     if (FpFile == NULL) {\r
689       Error (NULL, 0, 0001, "Error opening file", AddrFileName);\r
690       return STATUS_ERROR;\r
691     }\r
692     fprintf (FpFile, OPTIONS_SECTION_STRING);\r
693     fprintf (FpFile, "\n");\r
694     if (mFvDataInfo.BootBaseAddress != 0) {\r
695       fprintf (FpFile, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING);\r
696       fprintf (\r
697         FpFile,\r
698         " = 0x%llx\n",\r
699         (unsigned long long)mFvDataInfo.BootBaseAddress\r
700         );\r
701       DebugMsg (NULL, 0, 9, "Updated boot driver base address", "%s = 0x%llx", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, (unsigned long long) mFvDataInfo.BootBaseAddress);\r
702     }\r
703     if (mFvDataInfo.RuntimeBaseAddress != 0) {\r
704       fprintf (FpFile, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING);\r
705       fprintf (\r
706         FpFile,\r
707         " = 0x%llx\n",\r
708         (unsigned long long)mFvDataInfo.RuntimeBaseAddress\r
709         );\r
710       DebugMsg (NULL, 0, 9, "Updated runtime driver base address", "%s = 0x%llx", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, (unsigned long long) mFvDataInfo.RuntimeBaseAddress);\r
711     }\r
712     fclose (FpFile);\r
713   }\r
714   \r
715   if (Status == EFI_SUCCESS) {\r
716     DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);\r
717     DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);\r
718     DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));\r
719   }\r
720 \r
721   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
722 \r
723   return GetUtilityStatus ();\r
724 }\r