Scrub BaseTools C Source to solve some gaps between EFI BaseTypes to POSIX types...
[efi/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 #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 GuidValue\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          GuidValue is the Fv Name Guid value.\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 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 {\r
411         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
412         return STATUS_ERROR;\r
413       }\r
414       DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);\r
415       argc -= 2;\r
416       argv += 2;\r
417       continue; \r
418     }\r
419 \r
420     if (stricmp (argv[0], "--capguid") == 0) {\r
421       //\r
422       // Get the Capsule Guid\r
423       //\r
424       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
425       if (EFI_ERROR (Status)) {\r
426         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
427         return STATUS_ERROR;\r
428       }\r
429       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
430       argc -= 2;\r
431       argv += 2;\r
432       continue; \r
433     }\r
434 \r
435     if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--guid") == 0)) {\r
436       //\r
437       // Get the Capsule or Fv Guid\r
438       //\r
439       Status = StringToGuid (argv[1], &mCapDataInfo.CapGuid);\r
440       if (EFI_ERROR (Status)) {\r
441         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
442         return STATUS_ERROR;\r
443       }\r
444       memcpy (&mFvDataInfo.FvFileSystemGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));\r
445       mFvDataInfo.FvFileSystemGuidSet = TRUE;\r
446       DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
447       DebugMsg (NULL, 0, 9, "FV Guid", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, argv[1]);\r
448       argc -= 2;\r
449       argv += 2;\r
450       continue; \r
451     }\r
452 \r
453     if (stricmp (argv[0], "--FvNameGuid") == 0) {\r
454       //\r
455       // Get Fv Name Guid\r
456       //\r
457       Status = StringToGuid (argv[1], &mFvDataInfo.FvNameGuid);\r
458       if (EFI_ERROR (Status)) {\r
459         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_GUID_STRING, argv[1]);\r
460         return STATUS_ERROR;\r
461       }\r
462       mFvDataInfo.FvNameGuidSet = TRUE;\r
463       DebugMsg (NULL, 0, 9, "FV Name Guid", "%s = %s", EFI_FV_NAMEGUID_STRING, argv[1]);\r
464       argc -= 2;\r
465       argv += 2;\r
466       continue; \r
467     }\r
468 \r
469     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
470       DumpCapsule = TRUE;\r
471       argc --;\r
472       argv ++;\r
473       continue; \r
474     }\r
475 \r
476     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--map") == 0)) {\r
477       MapFileName = argv[1];\r
478       if (MapFileName == NULL) {\r
479         Error (NULL, 0, 1003, "Invalid option value", "Map file can't be null");\r
480         return STATUS_ERROR;\r
481       }\r
482       argc -= 2;\r
483       argv += 2;\r
484       continue; \r
485     }\r
486 \r
487     if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
488       SetPrintLevel (VERBOSE_LOG_LEVEL);\r
489       VerboseMsg ("Verbose output Mode Set!");\r
490       argc --;\r
491       argv ++;\r
492       continue;\r
493     }\r
494 \r
495     if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
496       SetPrintLevel (KEY_LOG_LEVEL);\r
497       KeyMsg ("Quiet output Mode Set!");\r
498       argc --;\r
499       argv ++;\r
500       continue;\r
501     }\r
502 \r
503     if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
504       Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
505       if (EFI_ERROR (Status)) {\r
506         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
507         return STATUS_ERROR;\r
508       }\r
509       if (LogLevel > 9) {\r
510         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
511         return STATUS_ERROR;\r
512       }\r
513       SetPrintLevel (LogLevel);\r
514       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
515       argc -= 2;\r
516       argv += 2;\r
517       continue;\r
518     }\r
519 \r
520     //\r
521     // Don't recognize the parameter.\r
522     //\r
523     Error (NULL, 0, 1000, "Unknown option", "%s", argv[0]);\r
524     return STATUS_ERROR;\r
525   }\r
526 \r
527   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
528   \r
529   //\r
530   // check input parameter, InfFileName can be NULL\r
531   //\r
532   if (InfFileName == NULL && DumpCapsule) {\r
533     Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");\r
534     return STATUS_ERROR;\r
535   }\r
536   VerboseMsg ("the input FvInf or CapInf file name is %s", InfFileName);\r
537 \r
538   if (!DumpCapsule && OutFileName == NULL) {\r
539     Error (NULL, 0, 1001, "Missing option", "Output File");\r
540     return STATUS_ERROR;\r
541   }\r
542   if (OutFileName != NULL) {\r
543     VerboseMsg ("the output file name is %s", OutFileName);\r
544   }\r
545   \r
546   //\r
547   // Read boot and runtime address from address file\r
548   //\r
549   if (AddrFileName != NULL) {\r
550     VerboseMsg ("the input address file name is %s", AddrFileName);\r
551     Status = GetFileImage (AddrFileName, &InfFileImage, &InfFileSize);\r
552     if (EFI_ERROR (Status)) {\r
553       return STATUS_ERROR;\r
554     }\r
555 \r
556     AddrMemoryFile.FileImage           = InfFileImage;\r
557     AddrMemoryFile.CurrentFilePointer  = InfFileImage;\r
558     AddrMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
559 \r
560     //\r
561     // Read the boot driver base address for this FV image\r
562     //\r
563     Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
564     if (Status == EFI_SUCCESS) {\r
565       //\r
566       // Get the base address\r
567       //\r
568       Status = AsciiStringToUint64 (ValueString, FALSE, &TempNumber);\r
569       if (EFI_ERROR (Status)) {\r
570         Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
571         return STATUS_ERROR;\r
572       }\r
573       mFvDataInfo.BootBaseAddress = TempNumber;\r
574       DebugMsg (NULL, 0, 9, "Boot driver base address", "%s = %s", EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
575     }\r
576   \r
577     //\r
578     // Read the FV runtime driver base address\r
579     //\r
580     Status = FindToken (&AddrMemoryFile, OPTIONS_SECTION_STRING, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, 0, ValueString);\r
581     if (Status == EFI_SUCCESS) {\r
582       //\r
583       // Get the base address\r
584       //\r
585       Status = AsciiStringToUint64 (ValueString, FALSE, &TempNumber);\r
586       if (EFI_ERROR (Status)) {\r
587         Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
588         return STATUS_ERROR;\r
589       }\r
590       mFvDataInfo.RuntimeBaseAddress = TempNumber;\r
591       DebugMsg (NULL, 0, 9, "Runtime driver base address", "%s = %s", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, ValueString);\r
592     }\r
593     \r
594     //\r
595     // free the allocated memory space for addr file.\r
596     //\r
597     free (InfFileImage);\r
598     InfFileImage = NULL;\r
599     InfFileSize  = 0;\r
600   }\r
601 \r
602   //\r
603   // Read the INF file image\r
604   //\r
605   if (InfFileName != NULL) {\r
606     Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
607     if (EFI_ERROR (Status)) {\r
608       return STATUS_ERROR;\r
609     }\r
610   }\r
611   \r
612   if (DumpCapsule) {\r
613     VerboseMsg ("Dump the capsule header information for the input capsule image %s", InfFileName);\r
614     //\r
615     // Dump Capsule Image Header Information\r
616     //\r
617     CapsuleHeader = (EFI_CAPSULE_HEADER *) InfFileImage;\r
618     if (OutFileName == NULL) {\r
619       FpFile = stdout;\r
620     } else {\r
621       FpFile = fopen (OutFileName, "w");\r
622       if (FpFile == NULL) {\r
623         Error (NULL, 0, 0001, "Error opening file", OutFileName);\r
624         return STATUS_ERROR;\r
625       }\r
626     }\r
627     fprintf (FpFile, "Capsule %s Image Header Information\n", InfFileName);\r
628     fprintf (FpFile, "  GUID                  %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", \r
629                     (unsigned) CapsuleHeader->CapsuleGuid.Data1,\r
630                     (UINT32) CapsuleHeader->CapsuleGuid.Data2,\r
631                     (UINT32) CapsuleHeader->CapsuleGuid.Data3,\r
632                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[0],\r
633                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[1],\r
634                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[2],\r
635                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[3],\r
636                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[4],\r
637                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[5],\r
638                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[6],\r
639                     (UINT32) CapsuleHeader->CapsuleGuid.Data4[7]);\r
640     fprintf (FpFile, "  Header size           0x%08X\n", (unsigned) CapsuleHeader->HeaderSize);\r
641     fprintf (FpFile, "  Flags                 0x%08X\n", (unsigned) CapsuleHeader->Flags);\r
642     fprintf (FpFile, "  Capsule image size    0x%08X\n", (unsigned) CapsuleHeader->CapsuleImageSize);\r
643     fclose (FpFile);\r
644   } else if (CapsuleFlag) {\r
645     VerboseMsg ("Create capsule image");\r
646     //\r
647     // Call the GenerateCapImage to generate Capsule Image\r
648     //\r
649     for (Index = 0; mFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {\r
650       strcpy (mCapDataInfo.CapFiles[Index], mFvDataInfo.FvFiles[Index]);\r
651     }\r
652 \r
653     Status = GenerateCapImage (\r
654               InfFileImage, \r
655               InfFileSize,\r
656               OutFileName\r
657               );\r
658   } else {\r
659     VerboseMsg ("Create Fv image and its map file");\r
660     if (mFvDataInfo.BaseAddress != 0) {\r
661       VerboseMsg ("FvImage Rebase Address is 0x%llX", (unsigned long long) mFvDataInfo.BaseAddress);\r
662     }\r
663     //\r
664     // Call the GenerateFvImage to generate Fv Image\r
665     //\r
666     Status = GenerateFvImage (\r
667               InfFileImage,\r
668               InfFileSize,\r
669               OutFileName,\r
670               MapFileName\r
671               );\r
672   }\r
673 \r
674   //\r
675   // free InfFileImage memory\r
676   //\r
677   if (InfFileImage != NULL) {\r
678     free (InfFileImage);\r
679   }\r
680   \r
681   //\r
682   //  update boot driver address and runtime driver address in address file\r
683   //\r
684   if (Status == EFI_SUCCESS && AddrFileName != NULL) {\r
685     FpFile = fopen (AddrFileName, "w");\r
686     if (FpFile == NULL) {\r
687       Error (NULL, 0, 0001, "Error opening file", AddrFileName);\r
688       return STATUS_ERROR;\r
689     }\r
690     fprintf (FpFile, OPTIONS_SECTION_STRING);\r
691     fprintf (FpFile, "\n");\r
692     if (mFvDataInfo.BootBaseAddress != 0) {\r
693       fprintf (FpFile, EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING);\r
694       fprintf (FpFile, " = 0x%llx\n", mFvDataInfo.BootBaseAddress);\r
695       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
696     }\r
697     if (mFvDataInfo.RuntimeBaseAddress != 0) {\r
698       fprintf (FpFile, EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING);\r
699       fprintf (FpFile, " = 0x%llx\n", mFvDataInfo.RuntimeBaseAddress);\r
700       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
701     }\r
702     fclose (FpFile);\r
703   }\r
704   \r
705   if (Status == EFI_SUCCESS) {\r
706     DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);\r
707     DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);\r
708     DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, (unsigned) (mFvTotalSize - mFvTakenSize));\r
709   }\r
710 \r
711   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
712 \r
713   return GetUtilityStatus ();\r
714 }\r