Sync EDKII BaseTools to BaseTools project r1903.
[efi/edk2/.git] / edk2 / BaseTools / Source / C / GenFv / GenFv.c
1 /** @file\r
2 \r
3 Copyright (c) 2007 - 2010, 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 2010/2/1"\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 - 2010, 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 the child\n\\r
130                         FV base address when current FV base address is set.\n");\r
131   fprintf (stdout, "  -m logfile, --map logfile\n\\r
132                         Logfile is the output fv map file name. if it is not\n\\r
133                         given, the FvName.map will be the default map file name\n"); \r
134   fprintf (stdout, "  -g Guid, --guid Guid\n\\r
135                         GuidValue is one specific capsule guid value\n\\r
136                         or fv file system guid value.\n\\r
137                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
138   fprintf (stdout, "  --FvNameGuid Guid     Guid is used to specify Fv Name.\n\\r
139                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
140   fprintf (stdout, "  --capflag CapFlag     Capsule Reset Flag can be PersistAcrossReset,\n\\r
141                         or PopulateSystemTable or InitiateReset or not set\n");\r
142   fprintf (stdout, "  --capheadsize HeadSize\n\\r
143                         HeadSize is one HEX or DEC format value\n\\r
144                         HeadSize is required by Capsule Image.\n");                        \r
145   fprintf (stdout, "  -c, --capsule         Create Capsule Image.\n");\r
146   fprintf (stdout, "  -p, --dump            Dump Capsule Image header.\n");\r
147   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");\r
148   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");\r
149   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");\r
150   fprintf (stdout, "  --version             Show program's version number and exit.\n");\r
151   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");\r
152 }\r
153 \r
154 UINT32 mFvTotalSize;\r
155 UINT32 mFvTakenSize;\r
156 \r
157 int\r
158 main (\r
159   IN int   argc,\r
160   IN char  **argv\r
161   )\r
162 /*++\r
163 \r
164 Routine Description:\r
165 \r
166   This utility uses GenFvImage.Lib to build a firmware volume image.\r
167 \r
168 Arguments:\r
169 \r
170   FvInfFileName      The name of an FV image description file or Capsule Image.\r
171 \r
172   Arguments come in pair in any order.\r
173     -I FvInfFileName \r
174 \r
175 Returns:\r
176 \r
177   EFI_SUCCESS            No error conditions detected.\r
178   EFI_INVALID_PARAMETER  One or more of the input parameters is invalid.\r
179   EFI_OUT_OF_RESOURCES   A resource required by the utility was unavailable.  \r
180                          Most commonly this will be memory allocation \r
181                          or file creation.\r
182   EFI_LOAD_ERROR         GenFvImage.lib could not be loaded.\r
183   EFI_ABORTED            Error executing the GenFvImage lib.\r
184 \r
185 --*/\r
186 {\r
187   EFI_STATUS            Status;\r
188   CHAR8                 *InfFileName;\r
189   CHAR8                 *AddrFileName;\r
190   CHAR8                 *MapFileName;\r
191   CHAR8                 *InfFileImage;\r
192   UINT32                InfFileSize;\r
193   CHAR8                 *OutFileName;\r
194   BOOLEAN               CapsuleFlag;\r
195   BOOLEAN               DumpCapsule;\r
196   FILE                  *FpFile;\r
197   EFI_CAPSULE_HEADER    *CapsuleHeader;\r
198   UINT64                LogLevel, TempNumber;\r
199   UINT32                Index;\r
200 \r
201   InfFileName   = NULL;\r
202   AddrFileName  = NULL;\r
203   InfFileImage  = NULL;\r
204   OutFileName   = NULL;\r
205   MapFileName   = NULL;\r
206   InfFileSize   = 0;\r
207   CapsuleFlag   = FALSE;\r
208   DumpCapsule   = FALSE;\r
209   FpFile        = NULL;\r
210   CapsuleHeader = NULL;\r
211   LogLevel      = 0;\r
212   TempNumber    = 0;\r
213   Index         = 0;\r
214   mFvTotalSize  = 0;\r
215   mFvTakenSize  = 0;\r
216   Status        = EFI_SUCCESS;\r
217 \r
218   SetUtilityName (UTILITY_NAME);\r
219   \r
220   if (argc == 1) {\r
221     Error (NULL, 0, 1001, "Missing options", "No input options specified.");\r
222     Usage ();\r
223     return STATUS_ERROR;\r
224   }\r
225 \r
226   //\r
227   // Init global data to Zero\r
228   //\r
229   memset (&mFvDataInfo, 0, sizeof (FV_INFO));\r
230   memset (&mCapDataInfo, 0, sizeof (CAP_INFO)); \r
231   //\r
232   // Set the default FvGuid\r
233   //\r
234   memcpy (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid, sizeof (EFI_GUID));\r
235    \r
236   //\r
237   // Parse command line\r
238   //\r
239   argc --;\r
240   argv ++;\r
241 \r
242   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
243     Version ();\r
244     Usage ();\r
245     return STATUS_SUCCESS;    \r
246   }\r
247 \r
248   if (stricmp (argv[0], "--version") == 0) {\r
249     Version ();\r
250     return STATUS_SUCCESS;    \r
251   }\r
252 \r
253   while (argc > 0) {\r
254     if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {\r
255       InfFileName = argv[1];\r
256       if (InfFileName == NULL) {\r
257         Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");\r
258         return STATUS_ERROR;\r
259       }\r
260       argc -= 2;\r
261       argv += 2;\r
262       continue; \r
263     }\r
264 \r
265     if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {\r
266       AddrFileName = argv[1];\r
267       if (AddrFileName == NULL) {\r
268         Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");\r
269         return STATUS_ERROR;\r
270       }\r
271       argc -= 2;\r
272       argv += 2;\r
273       continue; \r
274     }\r
275 \r
276     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
277       OutFileName = argv[1];\r
278       if (OutFileName == NULL) {\r
279         Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");\r
280         return STATUS_ERROR;\r
281       }\r
282       argc -= 2;\r
283       argv += 2;\r
284       continue; \r
285     }\r
286 \r
287     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {\r
288       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
289       if (EFI_ERROR (Status)) {\r
290         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
291         return STATUS_ERROR;        \r
292       }\r
293       mFvDataInfo.BaseAddress    = TempNumber;\r
294       mFvDataInfo.BaseAddressSet = TRUE;\r
295       argc -= 2;\r
296       argv += 2;\r
297       continue; \r
298     }\r
299 \r
300     if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {\r
301       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
302       if (EFI_ERROR (Status)) {\r
303         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
304         return STATUS_ERROR;        \r
305       }\r
306       if (TempNumber == 0) {\r
307         Error (NULL, 0, 1003, "Invalid option value", "Fv block size can't be be set to zero");\r
308         return STATUS_ERROR;        \r
309       }\r
310       mFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;\r
311       DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%llx", EFI_BLOCK_SIZE_STRING, (unsigned long long) TempNumber);\r
312       argc -= 2;\r
313       argv += 2;\r
314       continue; \r
315     }\r
316 \r
317     if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {\r
318       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
319       if (EFI_ERROR (Status)) {\r
320         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
321         return STATUS_ERROR;        \r
322       }\r
323       if (TempNumber == 0) {\r
324         Error (NULL, 0, 1003, "Invalid option value", "Fv block number can't be set to zero");\r
325         return STATUS_ERROR;        \r
326       }\r
327       mFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;\r
328       DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%llx", EFI_NUM_BLOCKS_STRING, (unsigned long long) TempNumber);\r
329       argc -= 2;\r
330       argv += 2;\r
331       continue; \r
332     }\r
333 \r
334     if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {\r
335       if (argv[1] == NULL) {\r
336         Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");\r
337         return STATUS_ERROR;\r
338       }\r
339       strcpy (mFvDataInfo.FvFiles[Index], argv[1]);\r
340       DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index + 1, argv[1]);\r
341       argc -= 2;\r
342       argv += 2;\r
343 \r
344       if (argc > 0) {\r
345                     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {\r
346                       if (argv[1] == NULL) {\r
347                         Error (NULL, 0, 1003, "Invalid option value", "Ffsfile Size can't be null");\r
348                         return STATUS_ERROR;\r
349                       }\r
350                       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
351                       if (EFI_ERROR (Status)) {\r
352                         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
353                         return STATUS_ERROR;        \r
354                       }\r
355                       mFvDataInfo.SizeofFvFiles[Index] = (UINT32) TempNumber;\r
356                 DebugMsg (NULL, 0, 9, "FV component file size", "the %uth size is %s", (unsigned) Index + 1, argv[1]);\r
357                 argc -= 2;\r
358                 argv += 2;\r
359         }\r
360       }\r
361       Index ++;\r
362       continue; \r
363     }\r
364 \r
365     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--filetakensize") == 0)) {\r
366       Error (NULL, 0, 1003, "Invalid option", "It must be specified together with -f option to specify the file size.");\r
367       return STATUS_ERROR; \r
368     }\r
369 \r
370     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {\r
371       CapsuleFlag = TRUE;\r
372       argc --;\r
373       argv ++;\r
374       continue; \r
375     }\r
376 \r
377     if (stricmp (argv[0], "--capheadsize") == 0) {\r
378       //\r
379       // Get Capsule Image Header Size\r
380       //\r
381       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
382       if (EFI_ERROR (Status)) {\r
383         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
384         return STATUS_ERROR;        \r
385       }\r
386       mCapDataInfo.HeaderSize = (UINT32) TempNumber;\r
387       DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%llx", EFI_CAPSULE_HEADER_SIZE_STRING, (unsigned long long) TempNumber);\r
388       argc -= 2;\r
389       argv += 2;\r
390       continue; \r
391     }\r
392 \r
393     if (stricmp (argv[0], "--capflag") == 0) {\r
394       //\r
395       // Get Capsule Header\r
396       //\r
397       if (argv[1] == NULL) {\r
398         Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);\r
399         return STATUS_ERROR;\r
400       }\r
401       if (strcmp (argv[1], "PopulateSystemTable") == 0) {\r
402         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;\r
403       } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {\r
404         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;\r
405       } else if (strcmp (argv[1], "InitiateReset") == 0) {\r
406         mCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET;\r
407       } else {\r
408         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
409         return STATUS_ERROR;\r
410       }\r
411       DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);\r
412       argc -= 2;\r
413       argv += 2;\r
414       continue; \r
415     }\r
416 \r
417     if (stricmp (argv[0], "--capguid") == 0) {\r
418       //\r
419       // Get the Capsule Guid\r
420       //\r
421       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
422       if (EFI_ERROR (Status)) {\r
423         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
424         return STATUS_ERROR;\r
425       }\r
426       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
427       argc -= 2;\r
428       argv += 2;\r
429       continue; \r
430     }\r
431 \r
432     if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {\r
433       //\r
434       // Get the Capsule or Fv Guid\r
435       //\r
436       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
437       if (EFI_ERROR (Status)) {\r
438         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
439         return STATUS_ERROR;\r
440       }\r
441       memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));\r
442       mFvDataInfo.FvFileSystemGuidSet = TRUE;\r
443       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
444       DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);\r
445       argc -= 2;\r
446       argv += 2;\r
447       continue; \r
448     }\r
449 \r
450     if (stricmp (argv[0], "--FvNameGuid") == 0) {\r
451       //\r
452       // Get Fv Name Guid\r
453       //\r
454       Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);\r
455       if (EFI_ERROR (Status)) {\r
456         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
457         return STATUS_ERROR;\r
458       }\r
459       mFvDataInfo.FvNameGuidSet = TRUE;\r
460       DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);\r
461       argc -= 2;\r
462       argv += 2;\r
463       continue; \r
464     }\r
465 \r
466     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
467       DumpCapsule = TRUE;\r
468       argc --;\r
469       argv ++;\r
470       continue; \r
471     }\r
472 \r
473     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {\r
474       MapFileName = argv[1];\r
475       if (MapFileName == NULL) {\r
476         Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");\r
477         return STATUS_ERROR;\r
478       }\r
479       argc -= 2;\r
480       argv += 2;\r
481       continue; \r
482     }\r
483 \r
484     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
485       SetPrintLevel (VERBOSE_LOG_LEVEL);\r
486       VerboseMsg ("Verbose output Mode Set!");\r
487       argc --;\r
488       argv ++;\r
489       continue;\r
490     }\r
491 \r
492     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
493       SetPrintLevel (KEY_LOG_LEVEL);\r
494       KeyMsg ("Quiet output Mode Set!");\r
495       argc --;\r
496       argv ++;\r
497       continue;\r
498     }\r
499 \r
500     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
501       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
502       if (EFI_ERROR (Status)) {\r
503         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
504         return STATUS_ERROR;\r
505       }\r
506       if (LogLevel > 9) {\r
507         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
508         return STATUS_ERROR;\r
509       }\r
510       SetPrintLevel (LogLevel);\r
511       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
512       argc -= 2;\r
513       argv += 2;\r
514       continue;\r
515     }\r
516 \r
517     //\r
518     // Don't recognize the parameter.\r
519     //\r
520     Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);\r
521     return STATUS_ERROR;\r
522   }\r
523 \r
524   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
525   \r
526   //\r
527   // check input parameter, InfFileName can be NULL\r
528   //\r
529   if (InfFileName == NULL && DumpCapsule) {\r
530     Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");\r
531     return STATUS_ERROR;\r
532   }\r
533   VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);\r
534 \r
535   if (!DumpCapsule && OutFileName == NULL) {\r
536     Error (NULL, 0, 1001, "Missing option", "Output File");\r
537     return STATUS_ERROR;\r
538   }\r
539   if (OutFileName != NULL) {\r
540     VerboseMsg ("the output file name is %s", OutFileName);\r
541   }\r
542   \r
543   //\r
544   // Read the INF file image\r
545   //\r
546   if (InfFileName != NULL) {\r
547     Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
548     if (EFI_ERROR (Status)) {\r
549       return STATUS_ERROR;\r
550     }\r
551   }\r
552   \r
553   if (DumpCapsule) {\r
554     VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);\r
555     //\r
556     // Dump Capsule Image Header Information\r
557     //\r
558     CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;\r
559     if (OutFileName == NULL) {\r
560       FpFile = stdout;\r
561     } else {\r
562       FpFile = fopen (OutFileName, "w");\r
563       if (FpFile == NULL) {\r
564         Error (NULL, 0, 0001, "Error opening file", OutFileName);\r
565         return STATUS_ERROR;\r
566       }\r
567     }\r
568     fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);\r
569     fprintf (FpFile, "  GUID                  %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", \r
570                     (unsigned) CapsuleHeader->CapsuleGuid.Data1,\r
571                     (unsigned) CapsuleHeader->CapsuleGuid.Data2,\r
572                     (unsigned) CapsuleHeader->CapsuleGuid.Data3,\r
573                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[0],\r
574                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[1],\r
575                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[2],\r
576                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[3],\r
577                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[4],\r
578                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[5],\r
579                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[6],\r
580                     (unsigned) CapsuleHeader->CapsuleGuid.Data4[7]);\r
581     fprintf (FpFile, "  Header size           0x%08X\n", (unsigned) CapsuleHeader->HeaderSize);\r
582     fprintf (FpFile, "  Flags                 0x%08X\n", (unsigned) CapsuleHeader->Flags);\r
583     fprintf (FpFile, "  Capsule image size    0x%08X\n", (unsigned) CapsuleHeader->CapsuleImageSize);\r
584     fclose (FpFile);\r
585   } else if (CapsuleFlag) {\r
586     VerboseMsg ("Create capsule image");\r
587     //\r
588     // Call the GenerateCapImage to generate Capsule Image\r
589     //\r
590     for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {\r
591       strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);\r
592     }\r
593 \r
594     Status = GenerateCapImage (\r
595               InfFileImage, \r
596               InfFileSize,\r
597               OutFileName\r
598               );\r
599   } else {\r
600     VerboseMsg ("Create Fv image and its map file");\r
601     if (mFvDataInfo.BaseAddress != 0) {\r
602       VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);\r
603     }\r
604     //\r
605     // Call the GenerateFvImage to generate Fv Image\r
606     //\r
607     Status = GenerateFvImage (\r
608               InfFileImage,\r
609               InfFileSize,\r
610               OutFileName,\r
611               MapFileName\r
612               );\r
613   }\r
614 \r
615   //\r
616   // free InfFileImage memory\r
617   //\r
618   if (InfFileImage != NULL) {\r
619     free (InfFileImage);\r
620   }\r
621   \r
622   //\r
623   //  update boot driver address and runtime driver address in address file\r
624   //\r
625   if (Status == EFI_SUCCESS && AddrFileName != NULL && mFvBaseAddressNumber > 0) {\r
626     FpFile = fopen (AddrFileName, "w");\r
627     if (FpFile == NULL) {\r
628       Error (NULL, 0, 0001, "Error opening file", AddrFileName);\r
629       return STATUS_ERROR;\r
630     }\r
631     fprintf (FpFile, FV_BASE_ADDRESS_STRING);\r
632     fprintf (FpFile, "\n");\r
633     for (Index = 0; Index < mFvBaseAddressNumber; Index ++) {\r
634       fprintf (\r
635         FpFile,\r
636         "0x%llx\n",\r
637         (unsigned long long)mFvBaseAddress[Index]\r
638         );\r
639     }\r
640     fflush (FpFile);\r
641     fclose (FpFile);\r
642   }\r
643   \r
644   if (Status == EFI_SUCCESS) {\r
645     DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);\r
646     DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);\r
647     DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));\r
648   }\r
649 \r
650   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
651 \r
652   return GetUtilityStatus ();\r
653 }\r