Miss loop variable incremental, otherwise, will cause dead loop.
[mirror_edk2.git] / Tools / Source / TianoTools / FlashMap / FlashMap.c
CommitLineData
d25c4bf0 1/*++\r
2\r
b84b42fc 3Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
4This program and the accompanying materials are licensed and made available \r
5under the terms and conditions of the BSD License which accompanies this \r
6distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
d25c4bf0 11\r
12Module Name:\r
13\r
14 FlashMap.c\r
15\r
16Abstract:\r
17\r
18 Utility for flash management in the Intel Platform Innovation Framework\r
19 for EFI build environment.\r
20\r
21--*/\r
22\r
23#include <stdio.h>\r
24#include <string.h>\r
25#include <stdlib.h>\r
26#include <ctype.h>\r
ce53a8c3 27\r
28#include <Common/UefiBaseTypes.h>\r
d25c4bf0 29\r
30#include "EfiUtilityMsgs.h"\r
31#include "Microcode.h"\r
32#include "FlashDefFile.h"\r
33#include "Symbols.h"\r
34\r
35#define UTILITY_NAME "FlashMap"\r
36\r
37typedef struct _STRING_LIST {\r
38 struct _STRING_LIST *Next;\r
39 char *Str;\r
40} STRING_LIST;\r
41\r
42//\r
43// Keep our globals in one of these structures\r
44//\r
45static struct {\r
46 char *CIncludeFileName;\r
47 char *FlashDevice;\r
48 char *FlashDeviceImage;\r
49 char *MCIFileName;\r
50 char *MCOFileName;\r
51 char *ImageOutFileName;\r
52 char *DscFileName;\r
53 char *AsmIncludeFileName;\r
54 char *FlashDefinitionFileName;\r
55 char *StringReplaceInFileName;\r
56 char *StringReplaceOutFileName;\r
57 char *DiscoverFDImageName;\r
58 char MicrocodePadByteValue;\r
59 unsigned int MicrocodeAlignment;\r
60 STRING_LIST *MCIFileNames;\r
61 STRING_LIST *LastMCIFileNames;\r
62 unsigned int BaseAddress;\r
63} mGlobals;\r
64\r
65#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF\r
66#define DEFAULT_MC_ALIGNMENT 16\r
67\r
68static\r
69STATUS\r
70ProcessCommandLine (\r
71 int argc,\r
72 char *argv[]\r
73 );\r
74\r
75static\r
76STATUS\r
77MergeMicrocodeFiles (\r
78 char *OutFileName,\r
79 STRING_LIST *FileNames,\r
80 unsigned int Alignment,\r
81 char PadByteValue\r
82 );\r
83\r
84static\r
85void\r
86Usage (\r
87 VOID\r
88 );\r
89\r
2eaa5ba1 90char* \r
91NormalizePath (\r
92 char* OldPathName\r
93 );\r
94\r
d25c4bf0 95int\r
96main (\r
97 int argc,\r
98 char *argv[]\r
99 )\r
100/*++\r
101\r
102Routine Description:\r
103 Parse the command line arguments and then call worker functions to do the work\r
104 \r
105Arguments:\r
106 argc - number of elements in argv\r
107 argv - array of command-line arguments\r
108\r
109Returns:\r
110 STATUS_SUCCESS - no problems encountered while processing\r
111 STATUS_WARNING - warnings, but no errors, were encountered while processing\r
112 STATUS_ERROR - errors were encountered while processing\r
113 \r
114--*/\r
115{\r
116 STATUS Status;\r
117\r
118 SetUtilityName (UTILITY_NAME);\r
119 Status = ProcessCommandLine (argc, argv);\r
120 if (Status != STATUS_SUCCESS) {\r
121 return Status;\r
122 }\r
123 //\r
124 // Check for discovery of an FD (command line option)\r
125 //\r
126 if (mGlobals.DiscoverFDImageName != NULL) {\r
127 Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress);\r
128 goto Done;\r
129 }\r
130 //\r
131 // If they're doing microcode file parsing, then do that\r
132 //\r
133 if (mGlobals.MCIFileName != NULL) {\r
134 MicrocodeConstructor ();\r
135 MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName);\r
136 MicrocodeDestructor ();\r
137 }\r
138 //\r
139 // If they're doing microcode file merging, then do that now\r
140 //\r
141 if (mGlobals.MCIFileNames != NULL) {\r
142 MergeMicrocodeFiles (\r
143 mGlobals.MCOFileName,\r
144 mGlobals.MCIFileNames,\r
145 mGlobals.MicrocodeAlignment,\r
146 mGlobals.MicrocodePadByteValue\r
147 );\r
148 }\r
149 //\r
150 // If using a flash definition file, then process that and return\r
151 //\r
152 if (mGlobals.FlashDefinitionFileName != NULL) {\r
153 FDFConstructor ();\r
154 SymbolsConstructor ();\r
155 Status = FDFParseFile (mGlobals.FlashDefinitionFileName);\r
156 if (GetUtilityStatus () != STATUS_ERROR) {\r
157 //\r
158 // If they want us to do a string-replace on a file, then add the symbol definitions to\r
159 // the symbol table, and then do the string replace.\r
160 //\r
161 if (mGlobals.StringReplaceInFileName != NULL) {\r
162 Status = FDFCreateSymbols (mGlobals.FlashDevice);\r
163 Status = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName);\r
164 }\r
165 //\r
166 // If they want us to create a .h defines file or .c flashmap data file, then do so now\r
167 //\r
168 if (mGlobals.CIncludeFileName != NULL) {\r
169 Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName);\r
170 }\r
171 if (mGlobals.AsmIncludeFileName != NULL) {\r
172 Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName);\r
173 }\r
174 //\r
175 // If they want us to create an image, do that now\r
176 //\r
177 if (mGlobals.ImageOutFileName != NULL) {\r
178 Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName);\r
179 }\r
180 //\r
181 // If they want to create an output DSC file, do that now\r
182 //\r
183 if (mGlobals.DscFileName != NULL) {\r
184 Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName);\r
185 }\r
186 }\r
187 SymbolsDestructor ();\r
188 FDFDestructor ();\r
189 }\r
190Done:\r
191 //\r
192 // Free up memory\r
193 //\r
194 while (mGlobals.MCIFileNames != NULL) {\r
195 mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next;\r
196 _free (mGlobals.MCIFileNames);\r
197 mGlobals.MCIFileNames = mGlobals.LastMCIFileNames;\r
198 }\r
199 return GetUtilityStatus ();\r
200}\r
201\r
202static\r
203STATUS\r
204MergeMicrocodeFiles (\r
205 char *OutFileName,\r
206 STRING_LIST *FileNames,\r
207 unsigned int Alignment,\r
208 char PadByteValue\r
209 )\r
210/*++\r
211\r
212Routine Description:\r
213\r
214 Merge binary microcode files into a single file, taking into consideration\r
215 the alignment and pad value.\r
216\r
217Arguments:\r
218\r
219 OutFileName - name of the output file to create\r
220 FileNames - linked list of input microcode files to merge\r
221 Alignment - alignment for each microcode file in the output image\r
222 PadByteValue - value to use when padding to meet alignment requirements\r
223\r
224Returns:\r
225\r
226 STATUS_SUCCESS - merge completed successfully or with acceptable warnings\r
227 STATUS_ERROR - merge failed, output file not created\r
228\r
229--*/\r
230{\r
231 long FileSize;\r
232 long TotalFileSize;\r
233 FILE *InFptr;\r
234 FILE *OutFptr;\r
235 char *Buffer;\r
236 STATUS Status;\r
237\r
238 //\r
239 // Open the output file\r
240 //\r
241 if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {\r
242 Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");\r
243 return STATUS_ERROR;\r
244 }\r
245 //\r
246 // Walk the list of files\r
247 //\r
248 Status = STATUS_ERROR;\r
249 Buffer = NULL;\r
250 InFptr = NULL;\r
251 TotalFileSize = 0;\r
252 while (FileNames != NULL) {\r
253 //\r
254 // Open the file, determine the size, then read it in and write\r
255 // it back out.\r
256 //\r
2eaa5ba1 257 if ((InFptr = fopen (NormalizePath(FileNames->Str), "rb")) == NULL) {\r
258 Error (NULL, 0, 0, NormalizePath(FileNames->Str), "failed to open input file for reading");\r
d25c4bf0 259 goto Done;\r
260 }\r
261 fseek (InFptr, 0, SEEK_END);\r
262 FileSize = ftell (InFptr);\r
263 fseek (InFptr, 0, SEEK_SET);\r
264 if (FileSize != 0) {\r
265 Buffer = (char *) _malloc (FileSize);\r
266 if (Buffer == NULL) {\r
267 Error (NULL, 0, 0, "memory allocation failure", NULL);\r
268 goto Done;\r
269 }\r
270 if (fread (Buffer, FileSize, 1, InFptr) != 1) {\r
271 Error (NULL, 0, 0, FileNames->Str, "failed to read file contents");\r
272 goto Done;\r
273 }\r
274 //\r
275 // Align\r
276 //\r
277 if (Alignment != 0) {\r
278 while ((TotalFileSize % Alignment) != 0) {\r
279 if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) {\r
280 Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file");\r
281 goto Done;\r
282 }\r
283 TotalFileSize++;\r
284 }\r
285 }\r
286 TotalFileSize += FileSize;\r
287 if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {\r
288 Error (NULL, 0, 0, OutFileName, "failed to write to output file");\r
289 goto Done;\r
290 }\r
291 _free (Buffer);\r
292 Buffer = NULL;\r
293 } else {\r
294 Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered");\r
295 }\r
296 fclose (InFptr);\r
297 InFptr = NULL;\r
298 FileNames = FileNames->Next;\r
299 }\r
300 Status = STATUS_SUCCESS;\r
301Done:\r
302 fclose (OutFptr);\r
303 if (InFptr != NULL) {\r
304 fclose (InFptr);\r
305 }\r
306 if (Buffer != NULL) {\r
307 _free (Buffer);\r
308 }\r
309 if (Status == STATUS_ERROR) {\r
310 remove (OutFileName);\r
311 }\r
312 return Status;\r
313}\r
314\r
315static\r
316STATUS\r
317ProcessCommandLine (\r
318 int argc,\r
319 char *argv[]\r
320 )\r
321/*++\r
322\r
323Routine Description:\r
324 Process the command line arguments\r
325 \r
326Arguments:\r
327 argc - Standard C entry point arguments\r
328 argv[] - Standard C entry point arguments\r
329\r
330Returns:\r
331 STATUS_SUCCESS - no problems encountered while processing\r
332 STATUS_WARNING - warnings, but no errors, were encountered while processing\r
333 STATUS_ERROR - errors were encountered while processing\r
334 \r
335--*/\r
336{\r
337 int ThingsToDo;\r
338 unsigned int Temp;\r
339 STRING_LIST *Str;\r
340 //\r
341 // Skip program name arg, process others\r
342 //\r
343 argc--;\r
344 argv++;\r
345 if (argc == 0) {\r
346 Usage ();\r
347 return STATUS_ERROR;\r
348 }\r
349 //\r
350 // Clear out our globals, then start walking the arguments\r
351 //\r
352 memset ((void *) &mGlobals, 0, sizeof (mGlobals));\r
353 mGlobals.MicrocodePadByteValue = DEFAULT_MC_PAD_BYTE_VALUE;\r
354 mGlobals.MicrocodeAlignment = DEFAULT_MC_ALIGNMENT;\r
355 ThingsToDo = 0;\r
356 while (argc > 0) {\r
357 if (strcmp (argv[0], "-?") == 0) {\r
358 Usage ();\r
359 return STATUS_ERROR;\r
360 } else if (strcmp (argv[0], "-hfile") == 0) {\r
361 //\r
362 // -hfile FileName\r
363 //\r
364 // Used to specify an output C #include file to create that contains\r
365 // #define statements for all the flashmap region offsets and sizes.\r
366 // Check for additional argument.\r
367 //\r
368 if (argc < 2) {\r
369 Error (NULL, 0, 0, argv[0], "option requires an output file name");\r
370 return STATUS_ERROR;\r
371 }\r
372 argc--;\r
373 argv++;\r
374 mGlobals.CIncludeFileName = argv[0];\r
375 ThingsToDo++;\r
376 } else if (strcmp (argv[0], "-flashdevice") == 0) {\r
377 //\r
378 // -flashdevice FLASH_DEVICE_NAME\r
379 //\r
380 // Used to select which flash device definition to operate on.\r
381 // Check for additional argument\r
382 //\r
383 if (argc < 2) {\r
384 Error (NULL, 0, 0, argv[0], "option requires a flash device name to use");\r
385 return STATUS_ERROR;\r
386 }\r
387 argc--;\r
388 argv++;\r
389 mGlobals.FlashDevice = argv[0];\r
390 } else if (strcmp (argv[0], "-mco") == 0) {\r
391 //\r
392 // -mco OutFileName\r
393 //\r
394 // Used to specify a microcode output binary file to create.\r
395 // Check for additional argument.\r
396 //\r
397 if (argc < 2) {\r
398 Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create");\r
399 return STATUS_ERROR;\r
400 }\r
401 argc--;\r
402 argv++;\r
403 mGlobals.MCOFileName = argv[0];\r
404 ThingsToDo++;\r
405 } else if (strcmp (argv[0], "-asmincfile") == 0) {\r
406 //\r
407 // -asmincfile FileName\r
408 //\r
409 // Used to specify the name of the output assembly include file that contains\r
410 // equates for the flash region addresses and sizes.\r
411 // Check for additional argument.\r
412 //\r
413 if (argc < 2) {\r
414 Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create");\r
415 return STATUS_ERROR;\r
416 }\r
417 argc--;\r
418 argv++;\r
419 mGlobals.AsmIncludeFileName = argv[0];\r
420 ThingsToDo++;\r
421 } else if (strcmp (argv[0], "-mci") == 0) {\r
422 //\r
423 // -mci FileName\r
424 //\r
425 // Used to specify an input microcode text file to parse.\r
426 // Check for additional argument\r
427 //\r
428 if (argc < 2) {\r
429 Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse");\r
430 return STATUS_ERROR;\r
431 }\r
432 argc--;\r
433 argv++;\r
434 mGlobals.MCIFileName = argv[0];\r
435 } else if (strcmp (argv[0], "-flashdeviceimage") == 0) {\r
436 //\r
437 // -flashdeviceimage FlashDeviceImage\r
438 //\r
439 // Used to specify which flash device image definition from the input flash definition file\r
440 // to create.\r
441 // Check for additional argument.\r
442 //\r
443 if (argc < 2) {\r
444 Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use");\r
445 return STATUS_ERROR;\r
446 }\r
447 argc--;\r
448 argv++;\r
449 mGlobals.FlashDeviceImage = argv[0];\r
450 } else if (strcmp (argv[0], "-imageout") == 0) {\r
451 //\r
452 // -imageout FileName\r
453 //\r
454 // Used to specify the name of the output FD image file to create.\r
455 // Check for additional argument.\r
456 //\r
457 if (argc < 2) {\r
458 Error (NULL, 0, 0, argv[0], "option requires an output image filename to create");\r
459 return STATUS_ERROR;\r
460 }\r
461 argc--;\r
462 argv++;\r
463 mGlobals.ImageOutFileName = argv[0];\r
464 ThingsToDo++;\r
465 } else if (strcmp (argv[0], "-dsc") == 0) {\r
466 //\r
467 // -dsc FileName\r
468 //\r
469 // Used to specify the name of the output DSC file to create.\r
470 // Check for additional argument.\r
471 //\r
472 if (argc < 2) {\r
473 Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create");\r
474 return STATUS_ERROR;\r
475 }\r
476 argc--;\r
477 argv++;\r
478 mGlobals.DscFileName = argv[0];\r
479 ThingsToDo++;\r
480 } else if (strcmp (argv[0], "-fdf") == 0) {\r
481 //\r
482 // -fdf FileName\r
483 //\r
484 // Used to specify the name of the input flash definition file.\r
485 // Check for additional argument.\r
486 //\r
487 if (argc < 2) {\r
488 Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name");\r
489 return STATUS_ERROR;\r
490 }\r
491 argc--;\r
492 argv++;\r
493 mGlobals.FlashDefinitionFileName = argv[0];\r
494 } else if (strcmp (argv[0], "-discover") == 0) {\r
495 //\r
496 // -discover FDFileName\r
497 //\r
498 // Debug functionality used to scan an existing FD image, trying to find\r
499 // firmware volumes at 64K boundaries.\r
500 // Check for additional argument.\r
501 //\r
502 if (argc < 2) {\r
503 Error (NULL, 0, 0, argv[0], "option requires an input FD image file name");\r
504 return STATUS_ERROR;\r
505 }\r
506 argc--;\r
507 argv++;\r
508 mGlobals.DiscoverFDImageName = argv[0];\r
509 ThingsToDo++;\r
510 } else if (strcmp (argv[0], "-baseaddr") == 0) {\r
511 //\r
512 // -baseaddr Addr\r
513 //\r
514 // Used to specify a base address when doing a discover of an FD image.\r
515 // Check for additional argument.\r
516 //\r
517 if (argc < 2) {\r
518 Error (NULL, 0, 0, argv[0], "option requires a base address");\r
519 return STATUS_ERROR;\r
520 }\r
521 argc--;\r
522 argv++;\r
523 if (tolower (argv[0][1]) == 'x') {\r
524 sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress);\r
525 } else {\r
526 sscanf (argv[0], "%d", &mGlobals.BaseAddress);\r
527 }\r
528 } else if (strcmp (argv[0], "-padvalue") == 0) {\r
529 //\r
530 // -padvalue Value\r
531 //\r
532 // Used to specify the value to pad with when aligning data while\r
533 // creating an FD image. Check for additional argument.\r
534 //\r
535 if (argc < 2) {\r
536 Error (NULL, 0, 0, argv[0], "option requires a byte value");\r
537 return STATUS_ERROR;\r
538 }\r
539 argc--;\r
540 argv++;\r
541 if (tolower (argv[0][1]) == 'x') {\r
542 sscanf (argv[0] + 2, "%x", &Temp);\r
543 mGlobals.MicrocodePadByteValue = (char) Temp;\r
544 } else {\r
545 sscanf (argv[0], "%d", &Temp);\r
546 mGlobals.MicrocodePadByteValue = (char) Temp;\r
547 }\r
548 } else if (strcmp (argv[0], "-align") == 0) {\r
549 //\r
550 // -align Alignment\r
551 //\r
552 // Used to specify how each data file is aligned in the region\r
553 // when creating an FD image. Check for additional argument.\r
554 //\r
555 if (argc < 2) {\r
556 Error (NULL, 0, 0, argv[0], "option requires an alignment");\r
557 return STATUS_ERROR;\r
558 }\r
559 argc--;\r
560 argv++;\r
561 if (tolower (argv[0][1]) == 'x') {\r
562 sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment);\r
563 } else {\r
564 sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment);\r
565 }\r
566 } else if (strcmp (argv[0], "-mcmerge") == 0) {\r
567 //\r
568 // -mcmerge FileName(s)\r
569 //\r
570 // Used to concatenate multiple microde binary files. Can specify\r
571 // multiple file names with the one -mcmerge flag. Check for additional argument.\r
572 //\r
573 if ((argc < 2) || (argv[1][0] == '-')) {\r
574 Error (NULL, 0, 0, argv[0], "option requires one or more input file names");\r
575 return STATUS_ERROR;\r
576 }\r
577 //\r
578 // Take input files until another option or end of list\r
579 //\r
580 ThingsToDo++;\r
581 while ((argc > 1) && (argv[1][0] != '-')) {\r
582 Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST));\r
583 if (Str == NULL) {\r
584 Error (NULL, 0, 0, "memory allocation failure", NULL);\r
585 return STATUS_ERROR;\r
586 }\r
587 memset (Str, 0, sizeof (STRING_LIST));\r
588 Str->Str = argv[1];\r
589 if (mGlobals.MCIFileNames == NULL) {\r
590 mGlobals.MCIFileNames = Str;\r
591 } else {\r
592 mGlobals.LastMCIFileNames->Next = Str;\r
593 }\r
594 mGlobals.LastMCIFileNames = Str;\r
595 argc--;\r
596 argv++;\r
597 }\r
598 } else if (strcmp (argv[0], "-strsub") == 0) {\r
599 //\r
600 // -strsub SrcFile DestFile\r
601 //\r
602 // Used to perform string substitutions on a file, writing the result to a new\r
603 // file. Check for two additional arguments.\r
604 //\r
605 if (argc < 3) {\r
606 Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution");\r
607 return STATUS_ERROR;\r
608 }\r
609 argc--;\r
610 argv++;\r
611 mGlobals.StringReplaceInFileName = argv[0];\r
612 argc--;\r
613 argv++;\r
614 mGlobals.StringReplaceOutFileName = argv[0];\r
615 ThingsToDo++;\r
616 } else {\r
617 Error (NULL, 0, 0, argv[0], "invalid option");\r
618 return STATUS_ERROR;\r
619 }\r
620 argc--;\r
621 argv++;\r
622 }\r
623 //\r
624 // If no outputs requested, then report an error\r
625 //\r
626 if (ThingsToDo == 0) {\r
627 Error (NULL, 0, 0, "nothing to do", NULL);\r
628 return STATUS_ERROR;\r
629 }\r
630 //\r
631 // If they want an asm file, #include file, or C file to be created, then they have to specify a\r
632 // flash device name and flash definition file name.\r
633 //\r
634 if ((mGlobals.CIncludeFileName != NULL) &&\r
635 ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {\r
636 Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL);\r
637 return STATUS_ERROR;\r
638 }\r
639 if ((mGlobals.AsmIncludeFileName != NULL) &&\r
640 ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {\r
641 Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL);\r
642 return STATUS_ERROR;\r
643 }\r
644 //\r
645 // If they want a dsc file to be created, then they have to specify a\r
646 // flash device name and a flash definition file name\r
647 //\r
648 if (mGlobals.DscFileName != NULL) {\r
649 if (mGlobals.FlashDevice == NULL) {\r
650 Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL);\r
651 return STATUS_ERROR;\r
652 }\r
653 if (mGlobals.FlashDefinitionFileName == NULL) {\r
654 Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL);\r
655 return STATUS_ERROR;\r
656 }\r
657 }\r
658 //\r
659 // If they specified an output microcode file name, then they have to specify an input\r
660 // file name, and vice versa.\r
661 //\r
662 if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) {\r
663 Error (NULL, 0, 0, "must specify output microcode file name", NULL);\r
664 return STATUS_ERROR;\r
665 }\r
666 if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) {\r
667 Error (NULL, 0, 0, "must specify input microcode file name", NULL);\r
668 return STATUS_ERROR;\r
669 }\r
670 //\r
671 // If doing merge, then have to specify output file name\r
672 //\r
673 if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) {\r
674 Error (NULL, 0, 0, "must specify output microcode file name", NULL);\r
675 return STATUS_ERROR;\r
676 }\r
677 //\r
678 // If they want an output image to be created, then they have to specify\r
679 // the flash device and the flash device image to use.\r
680 //\r
681 if (mGlobals.ImageOutFileName != NULL) {\r
682 if (mGlobals.FlashDevice == NULL) {\r
683 Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL);\r
684 return STATUS_ERROR;\r
685 }\r
686 if (mGlobals.FlashDeviceImage == NULL) {\r
687 Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL);\r
688 return STATUS_ERROR;\r
689 }\r
690 if (mGlobals.FlashDefinitionFileName == NULL) {\r
691 Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL);\r
692 return STATUS_ERROR;\r
693 }\r
694 }\r
695 return STATUS_SUCCESS;\r
696}\r
697\r
698static\r
699void\r
700Usage (\r
701 VOID\r
702 )\r
703/*++\r
704\r
705Routine Description:\r
706 Print utility command line help\r
707 \r
708Arguments:\r
709 None\r
710\r
711Returns:\r
712 NA\r
713\r
714--*/\r
715{\r
716 int i;\r
717 char *Msg[] = {\r
718 "Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice",\r
719 " -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile",\r
720 " -discover FDImage -dsc DscFile -asmincfile AsmIncFile",\r
721 " -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile",\r
722 " -baseaddr BaseAddr -align Alignment -padvalue PadValue",\r
723 " -mcmerge MCIFile(s)",\r
724 " where",\r
725 " FlashDefFile - input Flash Definition File",\r
726 " FlashDevice - flash device to use (from flash definition file)",\r
727 " FlashDeviceImage - flash device image to use (from flash definition file)",\r
728 " MCIFile - input microcode file to parse",\r
729 " MCOFile - output binary microcode image to create from MCIFile",\r
730 " HFile - output #include file to create",\r
731 " FDImage - name of input FDImage file to scan",\r
732 " ImageOutFile - output image file to create",\r
733 " DscFile - output DSC file to create",\r
734 " AsmIncFile - output ASM include file to create",\r
735 " InStrFile - input file to replace symbol names, writing result to OutStrFile",\r
736 " BaseAddr - base address of FDImage (used with -discover)",\r
737 " Alignment - alignment to use when merging microcode binaries",\r
738 " PadValue - byte value to use as pad value when aligning microcode binaries",\r
739 " MCIFile(s) - one or more microcode binary files to merge/concatenate",\r
740 "",\r
741 NULL\r
742 };\r
743 for (i = 0; Msg[i] != NULL; i++) {\r
744 fprintf (stdout, "%s\n", Msg[i]);\r
745 }\r
746}\r
2eaa5ba1 747\r
748char* \r
749NormalizePath (\r
750 char* OldPathName\r
751 )\r
752{\r
753 char* Visitor;\r
754 \r
755 if (OldPathName == NULL) {\r
756 return NULL;\r
757 }\r
758 \r
759 Visitor = OldPathName;\r
760 while (*Visitor != '\0') {\r
761 if (*Visitor == '\\') {\r
762 *Visitor = '/';\r
763 }\r
af8eab84 764 Visitor++;\r
2eaa5ba1 765 }\r
766 \r
767 return Visitor;\r
768}