Enhance GenFv tool to print Fv Size and Length, and Get module map by module pdb...
[people/mcb30/basetools.git] / Source / C / GenFv / GenFv.c
1 /** @file\r
2 \r
3 Copyright (c) 2007 - 2008, 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 \r
44 STATIC\r
45 VOID \r
46 Version (\r
47   VOID\r
48 )\r
49 /*++\r
50 \r
51 Routine Description:\r
52 \r
53   Displays the standard utility information to SDTOUT\r
54 \r
55 Arguments:\r
56 \r
57   None\r
58 \r
59 Returns:\r
60 \r
61   None\r
62 \r
63 --*/\r
64 {\r
65   fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
66 }\r
67 \r
68 STATIC\r
69 VOID \r
70 Usage (\r
71   VOID\r
72   )\r
73 /*++\r
74 \r
75 Routine Description:\r
76 \r
77   Displays the utility usage syntax to STDOUT\r
78 \r
79 Arguments:\r
80 \r
81   None\r
82 \r
83 Returns:\r
84 \r
85   None\r
86 \r
87 --*/\r
88 {\r
89   //\r
90   // Summary usage\r
91   //\r
92   fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);\r
93   \r
94   //\r
95   // Copyright declaration\r
96   // \r
97   fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
98 \r
99   //\r
100   // Details Option\r
101   //\r
102   fprintf (stdout, "Options:\n");\r
103   fprintf (stdout, "  -o FileName, --outputfile FileName\n\\r
104                         File is the FvImage or CapImage to be created.\n");\r
105   fprintf (stdout, "  -i FileName, --inputfile FileName\n\\r
106                         File is the input FV.inf or Cap.inf to specify\n\\r
107                         how to construct FvImage or CapImage.\n");\r
108   fprintf (stdout, "  -b BlockSize, --blocksize BlockSize\n\\r
109                         BlockSize is one HEX or DEC format value\n\\r
110                         BlockSize is required by Fv Image.\n");\r
111   fprintf (stdout, "  -n NumberBlock, --numberblock NumberBlock\n\\r
112                         NumberBlock is one HEX or DEC format value\n\\r
113                         NumberBlock is one optional parameter.\n");\r
114   fprintf (stdout, "  -f FfsFile, --ffsfile FfsFile\n\\r
115                         FfsFile is placed into Fv Image\n\\r
116                         multi files can input one by one\n");\r
117   fprintf (stdout, "  -r Address, --baseaddr Address\n\\r
118                         Address is the rebase start address for drivers that\n\\r
119                         run in Flash. It supports DEC or HEX digital format.\n");\r
120   fprintf (stdout, "  -a AddressFile, --addrfile AddressFile\n\\r
121                         AddressFile is one file used to record boot driver base\n\\r
122                         address and runtime driver base address. And this tool\n\\r
123                         will update these two addresses after it relocates all\n\\r
124                         boot drivers and runtime drivers in this fv iamge to\n\\r
125                         the preferred loaded memory address.\n");\r
126   fprintf (stdout, "  -m logfile, --map logfile\n\\r
127                         Logfile is the output fv map file name. if it is not\n\\r
128                         given, the FvName.map will be the default map file name\n"); \r
129   fprintf (stdout, "  --capguid GuidValue\n\\r
130                         GuidValue is one specific capsule vendor guid value.\n\\r
131                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
132   fprintf (stdout, "  --capflag CapFlag\n\\r
133                         Capsule Reset Flag can be PersistAcrossReset,\n\\r
134                         or PopulateSystemTable or not set.\n");\r
135   fprintf (stdout, "  --capheadsize HeadSize\n\\r
136                         HeadSize is one HEX or DEC format value\n\\r
137                         HeadSize is required by Capsule Image.\n");                        \r
138   fprintf (stdout, "  -c, --capsule         Create Capsule Image.\n");\r
139   fprintf (stdout, "  -p, --dump            Dump Capsule Image header.\n");\r
140   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");\r
141   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");\r
142   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");\r
143   fprintf (stdout, "  --version             Show program's version number and exit.\n");\r
144   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");\r
145 }\r
146 \r
147 UINT32 mFvTotalSize;\r
148 UINT32 mFvTakenSize;\r
149 \r
150 int\r
151 main (\r
152   IN INTN   argc,\r
153   IN CHAR8  **argv\r
154   )\r
155 /*++\r
156 \r
157 Routine Description:\r
158 \r
159   This utility uses GenFvImage.Lib to build a firmware volume image.\r
160 \r
161 Arguments:\r
162 \r
163   FvInfFileName      The name of an FV image description file or Capsule Image.\r
164 \r
165   Arguments come in pair in any order.\r
166     -I FvInfFileName \r
167 \r
168 Returns:\r
169 \r
170   EFI_SUCCESS            No error conditions detected.\r
171   EFI_INVALID_PARAMETER  One or more of the input parameters is invalid.\r
172   EFI_OUT_OF_RESOURCES   A resource required by the utility was unavailable.  \r
173                          Most commonly this will be memory allocation \r
174                          or file creation.\r
175   EFI_LOAD_ERROR         GenFvImage.lib could not be loaded.\r
176   EFI_ABORTED            Error executing the GenFvImage lib.\r
177 \r
178 --*/\r
179 {\r
180   EFI_STATUS            Status;\r
181   CHAR8                 *InfFileName;\r
182   CHAR8                 *AddrFileName;\r
183   CHAR8                 *MapFileName;\r
184   CHAR8                 *InfFileImage;\r
185   UINTN                 InfFileSize;\r
186   CHAR8                 *OutFileName;\r
187   CHAR8                 ValueString[_MAX_PATH];\r
188   EFI_PHYSICAL_ADDRESS  XipBase;\r
189   EFI_PHYSICAL_ADDRESS  BtBase;\r
190   EFI_PHYSICAL_ADDRESS  RtBase;\r
191   BOOLEAN               CapsuleFlag;\r
192   BOOLEAN               DumpCapsule;\r
193   MEMORY_FILE           AddrMemoryFile;\r
194   FILE                  *FpFile;\r
195   EFI_CAPSULE_HEADER    *CapsuleHeader;\r
196   UINT64                LogLevel, TempNumber;\r
197   UINT32                Index;\r
198 \r
199   InfFileName   = NULL;\r
200   AddrFileName  = NULL;\r
201   InfFileImage  = NULL;\r
202   OutFileName   = NULL;\r
203   MapFileName   = NULL;\r
204   XipBase       = 0;\r
205   BtBase        = 0;\r
206   RtBase        = 0;\r
207   InfFileSize   = 0;\r
208   CapsuleFlag   = FALSE;\r
209   DumpCapsule   = FALSE;\r
210   FpFile        = NULL;\r
211   CapsuleHeader = NULL;\r
212   LogLevel      = 0;\r
213   TempNumber    = 0;\r
214   Index         = 0;\r
215   mFvTotalSize  = 0;\r
216   mFvTakenSize  = 0;\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 (&gFvDataInfo, 0, sizeof (FV_INFO));\r
230   memset (&gCapDataInfo, 0, sizeof (CAP_INFO)); \r
231    \r
232   //\r
233   // Parse command line\r
234   //\r
235   argc --;\r
236   argv ++;\r
237 \r
238   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
239     Version ();\r
240     Usage ();\r
241     return STATUS_SUCCESS;    \r
242   }\r
243 \r
244   if (stricmp (argv[0], "--version") == 0) {\r
245     Version ();\r
246     return STATUS_SUCCESS;    \r
247   }\r
248 \r
249   while (argc > 0) {\r
250     if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--inputfile") == 0)) {\r
251       InfFileName = argv[1];\r
252       if (InfFileName == NULL) {\r
253         Error (NULL, 0, 1003, "Invalid option value", "Input file can't be null");\r
254         return STATUS_ERROR;\r
255       }\r
256       argc -= 2;\r
257       argv += 2;\r
258       continue; \r
259     }\r
260 \r
261     if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--addrfile") == 0)) {\r
262       AddrFileName = argv[1];\r
263       if (AddrFileName == NULL) {\r
264         Error (NULL, 0, 1003, "Invalid option value", "Address file can't be null");\r
265         return STATUS_ERROR;\r
266       }\r
267       argc -= 2;\r
268       argv += 2;\r
269       continue; \r
270     }\r
271 \r
272     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
273       OutFileName = argv[1];\r
274       if (OutFileName == NULL) {\r
275         Error (NULL, 0, 1003, "Invalid option value", "Output file can't be null");\r
276         return STATUS_ERROR;\r
277       }\r
278       argc -= 2;\r
279       argv += 2;\r
280       continue; \r
281     }\r
282 \r
283     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {\r
284       Status = AsciiStringToUint64 (argv[1], FALSE, &XipBase);\r
285       if (EFI_ERROR (Status)) {\r
286         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
287         return STATUS_ERROR;        \r
288       }\r
289       argc -= 2;\r
290       argv += 2;\r
291       continue; \r
292     }\r
293 \r
294     if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {\r
295       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
296       if (EFI_ERROR (Status)) {\r
297         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
298         return STATUS_ERROR;        \r
299       }\r
300       gFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;\r
301       DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%x", EFI_BLOCK_SIZE_STRING, TempNumber);\r
302       argc -= 2;\r
303       argv += 2;\r
304       continue; \r
305     }\r
306 \r
307     if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {\r
308       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
309       if (EFI_ERROR (Status)) {\r
310         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
311         return STATUS_ERROR;        \r
312       }\r
313       gFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;\r
314       DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%x", EFI_NUM_BLOCKS_STRING, TempNumber);\r
315       argc -= 2;\r
316       argv += 2;\r
317       continue; \r
318     }\r
319 \r
320     if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {\r
321       if (argv[1] == NULL) {\r
322         Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");\r
323         return STATUS_ERROR;\r
324       }\r
325       strcpy (gFvDataInfo.FvFiles[Index++], argv[1]);\r
326       DebugMsg (NULL, 0, 9, "FV component file", "the %dth name is %s", Index - 1, argv[1]);\r
327       argc -= 2;\r
328       argv += 2;\r
329       continue; \r
330     }\r
331 \r
332     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {\r
333       CapsuleFlag = TRUE;\r
334       argc --;\r
335       argv ++;\r
336       continue; \r
337     }\r
338 \r
339     if (stricmp (argv[0], "--capheadsize") == 0) {\r
340       //\r
341       // Get Capsule Image Header Size\r
342       //\r
343       Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
344       if (EFI_ERROR (Status)) {\r
345         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
346         return STATUS_ERROR;        \r
347       }\r
348       gCapDataInfo.HeaderSize = (UINT32) TempNumber;\r
349       DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%x", EFI_CAPSULE_HEADER_SIZE_STRING, TempNumber);\r
350       argc -= 2;\r
351       argv += 2;\r
352       continue; \r
353     }\r
354 \r
355     if (stricmp (argv[0], "--capflag") == 0) {\r
356       //\r
357       // Get Capsule Header\r
358       //\r
359       if (argv[1] == NULL) {\r
360         Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);\r
361         return STATUS_ERROR;\r
362       }\r
363       if (strcmp (argv[1], "PopulateSystemTable") == 0) {\r
364         gCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;\r
365       } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {\r
366         gCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;\r
367       } else {\r
368         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
369         return STATUS_ERROR;\r
370       }\r
371       DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);\r
372       argc -= 2;\r
373       argv += 2;\r
374       continue; \r
375     }\r
376 \r
377     if (stricmp (argv[0], "--capguid") == 0) {\r
378       //\r
379       // Get the Capsule Guid\r
380       //\r
381       Status = StringToGuid (argv[1], &gCapDataInfo.CapGuid);\r
382       if (EFI_ERROR (Status)) {\r
383         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
384         return EFI_ABORTED;\r
385       }\r
386       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
387       argc -= 2;\r
388       argv += 2;\r
389       continue; \r
390     }\r
391 \r
392     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
393       DumpCapsule = TRUE;\r
394       argc --;\r
395       argv ++;\r
396       continue; \r
397     }\r
398 \r
399     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {\r
400       MapFileName = argv[1];\r
401       if (MapFileName == NULL) {\r
402         Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");\r
403         return STATUS_ERROR;\r
404       }\r
405       argc -= 2;\r
406       argv += 2;\r
407       continue; \r
408     }\r
409 \r
410     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
411       SetPrintLevel (VERBOSE_LOG_LEVEL);\r
412       VerboseMsg ("Verbose output Mode Set!");\r
413       argc --;\r
414       argv ++;\r
415       continue;\r
416     }\r
417 \r
418     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
419       SetPrintLevel (KEY_LOG_LEVEL);\r
420       KeyMsg ("Quiet output Mode Set!");\r
421       argc --;\r
422       argv ++;\r
423       continue;\r
424     }\r
425 \r
426     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
427       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
428       if (EFI_ERROR (Status)) {\r
429         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
430         return STATUS_ERROR;\r
431       }\r
432       if (LogLevel > 9) {\r
433         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", LogLevel);\r
434         return STATUS_ERROR;\r
435       }\r
436       SetPrintLevel (LogLevel);\r
437       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
438       argc -= 2;\r
439       argv += 2;\r
440       continue;\r
441     }\r
442 \r
443     //\r
444     // Don't recognize the parameter.\r
445     //\r
446     Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);\r
447     return STATUS_ERROR;\r
448   }\r
449 \r
450   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
451   \r
452   //\r
453   // check input parameter, InfFileName can be NULL\r
454   //\r
455   if (InfFileName == NULL && DumpCapsule) {\r
456     Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");\r
457     return STATUS_ERROR;\r
458   }\r
459   VerboseMsg ("the input file name is %s", InfFileName);\r
460 \r
461   if (!DumpCapsule && OutFileName == NULL) {\r
462     Error (NULL, 0, 1001, "Missing option", "Output File");\r
463     return STATUS_ERROR;\r
464   }\r
465   if (OutFileName != NULL) {\r
466     VerboseMsg ("the output file name is %s", OutFileName);\r
467   }\r
468   \r
469   //\r
470   // Read boot and runtime address from address file\r
471   //\r
472   if (AddrFileName != NULL) {\r
473     VerboseMsg ("the input address file name is %s", AddrFileName);\r
474     Status = GetFileImage (AddrFileName, &InfFileImage, &InfFileSize);\r
475     if (EFI_ERROR (Status)) {\r
476       return STATUS_ERROR;\r
477     }\r
478 \r
479     AddrMemoryFile.FileImage           = InfFileImage;\r
480     AddrMemoryFile.CurrentFilePointer  = InfFileImage;\r
481     AddrMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
482 \r
483     //\r
484     // Read the boot driver base address for this FV image\r
485     //\r
486     Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
487     if (Status == EFI_SUCCESS) {\r
488       //\r
489       // Get the base address\r
490       //\r
491       Status = AsciiStringToUint64 (ValueString, FALSE, &BtBase);\r
492       if (EFI_ERROR (Status)) {\r
493         Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
494         return STATUS_ERROR;\r
495       }\r
496       DebugMsg (NULL, 0, 9, "Boot driver base address", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
497     }\r
498   \r
499     //\r
500     // Read the FV runtime driver base address\r
501     //\r
502     Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
503     if (Status == EFI_SUCCESS) {\r
504       //\r
505       // Get the base address\r
506       //\r
507       Status = AsciiStringToUint64 (ValueString, FALSE, &RtBase);\r
508       if (EFI_ERROR (Status)) {\r
509         Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
510         return STATUS_ERROR;\r
511       }\r
512       DebugMsg (NULL, 0, 9, "Runtime driver base address", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
513     }\r
514     \r
515     //\r
516     // free the allocated memory space for addr file.\r
517     //\r
518     free (InfFileImage);\r
519     InfFileImage = NULL;\r
520     InfFileSize  = 0;\r
521   }\r
522 \r
523   //\r
524   // Read the INF file image\r
525   //\r
526   if (InfFileName != NULL) {\r
527     Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
528     if (EFI_ERROR (Status)) {\r
529       return STATUS_ERROR;\r
530     }\r
531   }\r
532   \r
533   if (DumpCapsule) {\r
534     VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);\r
535     //\r
536     // Dump Capsule Image Header Information\r
537     //\r
538     CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;\r
539     if (OutFileName == NULL) {\r
540       FpFile = stdout;\r
541     } else {\r
542       FpFile = fopen (OutFileName, "w");\r
543       if (FpFile == NULL) {\r
544         Error (NULL, 0, 0001, "Error opening file", OutFileName);\r
545         return STATUS_ERROR;\r
546       }\r
547     }\r
548     fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);\r
549     fprintf (FpFile, "  GUID                  %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", \r
550                     CapsuleHeader->CapsuleGuid.Data1,\r
551                     (UINT32) CapsuleHeader->CapsuleGuid.Data2,\r
552                     (UINT32) CapsuleHeader->CapsuleGuid.Data3,\r
553                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[0],\r
554                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[1],\r
555                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[2],\r
556                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[3],\r
557                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[4],\r
558                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[5],\r
559                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[6],\r
560                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[7]);\r
561     fprintf (FpFile, "  Header size           0x%08X\n", CapsuleHeader->HeaderSize);\r
562     fprintf (FpFile, "  Flags                 0x%08X\n", CapsuleHeader->Flags);\r
563     fprintf (FpFile, "  Capsule image size    0x%08X\n", CapsuleHeader->CapsuleImageSize);\r
564     fclose (FpFile);\r
565   } else if (CapsuleFlag) {\r
566     VerboseMsg ("Create capsule image");\r
567     //\r
568     // Call the GenerateCapImage to generate Capsule Image\r
569     //\r
570     for (Index = 0; gFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {\r
571       strcpy (gCapDataInfo.CapFiles[Index], gFvDataInfo.FvFiles[Index]);\r
572     }\r
573 \r
574     Status = GenerateCapImage (\r
575               InfFileImage, \r
576               InfFileSize,\r
577               OutFileName\r
578               );\r
579   } else {\r
580     VerboseMsg ("Create Fv image and its map file");\r
581     if (XipBase != 0) {\r
582       VerboseMsg ("FvImage Rebase Address is 0x%X", XipBase);\r
583     }\r
584     //\r
585     // Call the GenerateFvImage to generate Fv Image\r
586     //\r
587     Status = GenerateFvImage (\r
588               InfFileImage,\r
589               InfFileSize,\r
590               OutFileName,\r
591               MapFileName,\r
592               XipBase,\r
593               &BtBase,\r
594               &RtBase\r
595               );\r
596   }\r
597 \r
598   //\r
599   // free InfFileImage memory\r
600   //\r
601   if (InfFileImage != NULL) {\r
602     free (InfFileImage);\r
603   }\r
604   \r
605   //\r
606   //  update boot driver address and runtime driver address in address file\r
607   //\r
608   if (Status == EFI_SUCCESS && AddrFileName != NULL) {\r
609     FpFile = fopen (AddrFileName, "w");\r
610     if (FpFile == NULL) {\r
611       Error (NULL, 0, 0001, "Error opening file", AddrFileName);\r
612       return STATUS_ERROR;\r
613     }\r
614     fprintf (FpFile, OPTIONS_SECTION_STRING);\r
615     fprintf (FpFile, "\n");\r
616     if (BtBase != 0) {\r
617       fprintf (FpFile, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING);\r
618       fprintf (FpFile, " = 0x%x\n", BtBase);\r
619       DebugMsg (NULL, 0, 9, "Updated boot driver base address", "%s = 0x%x", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, BtBase);\r
620     }\r
621     if (RtBase != 0) {\r
622       fprintf (FpFile, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING);\r
623       fprintf (FpFile, " = 0x%x\n", RtBase);\r
624       DebugMsg (NULL, 0, 9, "Updated runtime driver base address", "%s = 0x%x", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, RtBase);\r
625     }\r
626     if (mFvTotalSize != 0) {\r
627       fprintf (FpFile, EFI_FV_TOTAL_SIZE_STRING);\r
628       fprintf (FpFile, " = 0x%x\n", mFvTotalSize);\r
629       DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, mFvTotalSize);\r
630     }\r
631     if (mFvTakenSize != 0) {\r
632       fprintf (FpFile, EFI_FV_TAKEN_SIZE_STRING);\r
633       fprintf (FpFile, " = 0x%x\n", mFvTakenSize);\r
634       DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, mFvTakenSize);\r
635     }\r
636     if (mFvTotalSize != 0 && mFvTakenSize != 0) {\r
637       fprintf (FpFile, EFI_FV_SPACE_SIZE_STRING);\r
638       fprintf (FpFile, " = 0x%x\n", mFvTotalSize - mFvTakenSize);\r
639       DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, mFvTotalSize - mFvTakenSize);\r
640     }\r
641     fclose (FpFile);\r
642   }\r
643 \r
644   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
645 \r
646   return GetUtilityStatus ();\r
647 }\r