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