2 Utility program to create an EFI option ROM image from binary and EFI PE32 files.
4 Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "EfiUtilityMsgs.h"
13 UINT64 DebugLevel
= 0;
24 Given an EFI image filename, create a ROM-able image by creating an option
25 ROM header and PCI data structure, filling them in, and then writing the
26 option ROM header + PCI data structure + EFI image out to the output file.
30 Argc - standard C main() argument count
32 Argv - standard C main() argument list
49 SetUtilityName(UTILITY_NAME
);
51 Status
= STATUS_SUCCESS
;
55 // Parse the command line arguments
57 if (ParseCommandLine (Argc
, Argv
, &mOptions
)) {
63 } else if (mOptions
.Verbose
) {
65 } else if (mOptions
.Debug
) {
66 SetPrintLevel(DebugLevel
);
69 if (mOptions
.Verbose
) {
70 VerboseMsg("%s tool start.\n", UTILITY_NAME
);
74 // If dumping an image, then do that and quit
76 if (mOptions
.DumpOption
== 1) {
77 if (mOptions
.FileList
!= NULL
) {
78 if ((Ptr0
= strstr ((CONST CHAR8
*) mOptions
.FileList
->FileName
, DEFAULT_OUTPUT_EXTENSION
)) != NULL
) {
79 DumpImage (mOptions
.FileList
);
82 Error (NULL
, 0, 1002, "No PciRom input file", "No *.rom input file");
88 // Determine the output filename. Either what they specified on
89 // the command line, or the first input filename with a different extension.
91 if (!mOptions
.OutFileName
[0]) {
92 if (mOptions
.FileList
!= NULL
) {
93 if (strlen (mOptions
.FileList
->FileName
) >= MAX_PATH
) {
94 Status
= STATUS_ERROR
;
95 Error (NULL
, 0, 2000, "Invalid parameter", "Input file name is too long - %s.", mOptions
.FileList
->FileName
);
98 strncpy (mOptions
.OutFileName
, mOptions
.FileList
->FileName
, MAX_PATH
- 1);
99 mOptions
.OutFileName
[MAX_PATH
- 1] = 0;
101 // Find the last . on the line and replace the filename extension with
104 Ext
= mOptions
.OutFileName
+ strlen (mOptions
.OutFileName
) - 1;
105 while (Ext
>= mOptions
.OutFileName
) {
106 if ((*Ext
== '.') || (*Ext
== '\\')) {
112 // If dot here, then insert extension here, otherwise append
115 Ext
= mOptions
.OutFileName
+ strlen (mOptions
.OutFileName
);
118 strcpy (Ext
, DEFAULT_OUTPUT_EXTENSION
);
122 // Make sure we don't have the same filename for input and output files
124 for (FList
= mOptions
.FileList
; FList
!= NULL
; FList
= FList
->Next
) {
125 if (stricmp (mOptions
.OutFileName
, FList
->FileName
) == 0) {
126 Status
= STATUS_ERROR
;
127 Error (NULL
, 0, 1002, "Invalid input parameter", "Input and output file names must be different - %s = %s.", FList
->FileName
, mOptions
.OutFileName
);
132 // Now open our output file
134 if ((FptrOut
= fopen (LongFilePath (mOptions
.OutFileName
), "wb")) == NULL
) {
135 Error (NULL
, 0, 0001, "Error opening file", "Error opening file %s", mOptions
.OutFileName
);
139 // Process all our files
142 for (FList
= mOptions
.FileList
; FList
!= NULL
; FList
= FList
->Next
) {
144 if ((FList
->FileFlags
& FILE_FLAG_EFI
) != 0) {
145 if (mOptions
.Verbose
) {
146 VerboseMsg("Processing EFI file %s\n", FList
->FileName
);
149 Status
= ProcessEfiFile (FptrOut
, FList
, mOptions
.VendId
, mOptions
.DevIdList
[0], &Size
);
150 } else if ((FList
->FileFlags
& FILE_FLAG_BINARY
) !=0 ) {
151 if (mOptions
.Verbose
) {
152 VerboseMsg("Processing binary file %s\n", FList
->FileName
);
155 Status
= ProcessBinFile (FptrOut
, FList
, &Size
);
157 Error (NULL
, 0, 2000, "Invalid parameter", "File type not specified, it must be either an EFI or binary file: %s.", FList
->FileName
);
158 Status
= STATUS_ERROR
;
161 if (mOptions
.Verbose
) {
162 VerboseMsg(" Output size = 0x%X\n", (unsigned) Size
);
165 if (Status
!= STATUS_SUCCESS
) {
174 if (TotalSize
> MAX_OPTION_ROM_SIZE
) {
175 Error (NULL
, 0, 2000, "Invalid parameter", "Option ROM image size exceeds limit of 0x%X bytes.", MAX_OPTION_ROM_SIZE
);
176 Status
= STATUS_ERROR
;
180 if (Status
== STATUS_SUCCESS
) {
182 // Clean up our file list
184 while (mOptions
.FileList
!= NULL
) {
185 FList
= mOptions
.FileList
->Next
;
186 free (mOptions
.FileList
);
187 mOptions
.FileList
= FList
;
191 // Clean up device ID list
193 if (mOptions
.DevIdList
!= NULL
) {
194 free (mOptions
.DevIdList
);
197 if (FptrOut
!= NULL
) {
201 if (mOptions
.Verbose
) {
202 VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME
, GetUtilityStatus ());
205 return GetUtilityStatus ();
219 Process a binary input file.
223 OutFptr - file pointer to output binary ROM image file we're creating
224 InFile - structure contains information on the binary file to process
225 Size - pointer to where to return the size added to the output file
238 PCI_EXPANSION_ROM_HEADER
*RomHdr
;
239 PCI_DATA_STRUCTURE
*PciDs23
;
240 PCI_3_0_DATA_STRUCTURE
*PciDs30
;
247 Status
= STATUS_SUCCESS
;
250 // Try to open the input file
252 if ((InFptr
= fopen (LongFilePath (InFile
->FileName
), "rb")) == NULL
) {
253 Error (NULL
, 0, 0001, "Error opening file", "%s", InFile
->FileName
);
257 // Seek to the end of the input file and get the file size. Then allocate
258 // a buffer to read it in to.
260 fseek (InFptr
, 0, SEEK_END
);
261 FileSize
= ftell (InFptr
);
262 if (mOptions
.Verbose
) {
263 VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize
);
266 fseek (InFptr
, 0, SEEK_SET
);
267 Buffer
= (UINT8
*) malloc (FileSize
);
268 if (Buffer
== NULL
) {
269 Error (NULL
, 0, 4003, "Resource", "memory cannot be allocated!");
270 Status
= STATUS_ERROR
;
274 if (fread (Buffer
, FileSize
, 1, InFptr
) != 1) {
275 Error (NULL
, 0, 2000, "Invalid", "Failed to read all bytes from input file.");
276 Status
= STATUS_ERROR
;
280 // Total size must be an even multiple of 512 bytes, and can't exceed
281 // the option ROM image size.
283 TotalSize
= FileSize
;
284 if (TotalSize
& 0x1FF) {
285 TotalSize
= (TotalSize
+ 0x200) &~0x1ff;
288 if (TotalSize
> MAX_OPTION_ROM_SIZE
) {
289 Error (NULL
, 0, 3001, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile
->FileName
, MAX_OPTION_ROM_SIZE
);
290 Status
= STATUS_ERROR
;
294 // Return the size to the caller so they can keep track of the running total.
299 // Crude check to make sure it's a legitimate ROM image
301 RomHdr
= (PCI_EXPANSION_ROM_HEADER
*) Buffer
;
302 if (RomHdr
->Signature
!= PCI_EXPANSION_ROM_HEADER_SIGNATURE
) {
303 Error (NULL
, 0, 2000, "Invalid parameter", "ROM image file has an invalid ROM signature.");
304 Status
= STATUS_ERROR
;
308 // Make sure the pointer to the PCI data structure is within the size of the image.
309 // Then check it for valid signature.
311 if ((RomHdr
->PcirOffset
> FileSize
) || (RomHdr
->PcirOffset
== 0)) {
312 Error (NULL
, 0, 2000, "Invalid parameter", "Invalid PCI data structure offset.");
313 Status
= STATUS_ERROR
;
318 // Check the header is conform to PCI2.3 or PCI3.0
320 if (mOptions
.Pci23
== 1) {
321 PciDs23
= (PCI_DATA_STRUCTURE
*) (Buffer
+ RomHdr
->PcirOffset
);
322 if (PciDs23
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
323 Error (NULL
, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature.");
324 Status
= STATUS_ERROR
;
329 // Default setting is PCI3.0 header
331 PciDs30
= (PCI_3_0_DATA_STRUCTURE
*)(Buffer
+ RomHdr
->PcirOffset
);
332 if (PciDs30
->Signature
!= PCI_DATA_STRUCTURE_SIGNATURE
) {
333 Error (NULL
, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature.");
334 Status
= STATUS_ERROR
;
340 // ReSet Option Rom size
342 if (mOptions
.Pci23
== 1) {
343 PciDs23
->ImageLength
= (UINT16
) (TotalSize
/ 512);
344 CodeType
= PciDs23
->CodeType
;
346 PciDs30
->ImageLength
= (UINT16
) (TotalSize
/ 512);
347 CodeType
= PciDs30
->CodeType
;
351 // If this is the last image, then set the LAST bit unless requested not
352 // to via the command-line -n argument. Otherwise, make sure you clear it.
354 if ((InFile
->Next
== NULL
) && (mOptions
.NoLast
== 0)) {
355 if (mOptions
.Pci23
== 1) {
356 PciDs23
->Indicator
= INDICATOR_LAST
;
358 PciDs30
->Indicator
= INDICATOR_LAST
;
361 if (mOptions
.Pci23
== 1) {
362 PciDs23
->Indicator
= 0;
364 PciDs30
->Indicator
= 0;
368 if (CodeType
!= PCI_CODE_TYPE_EFI_IMAGE
) {
370 for (Index
= 0; Index
< FileSize
- 1; Index
++) {
371 ByteCheckSum
= (UINT8
) (ByteCheckSum
+ Buffer
[Index
]);
374 Buffer
[FileSize
- 1] = (UINT8
) ((~ByteCheckSum
) + 1);
375 if (mOptions
.Verbose
) {
376 VerboseMsg(" Checksum = %02x\n\n", Buffer
[FileSize
- 1]);
381 // Now copy the input file contents out to the output file
383 if (fwrite (Buffer
, FileSize
, 1, OutFptr
) != 1) {
384 Error (NULL
, 0, 0005, "Failed to write all file bytes to output file.", NULL
);
385 Status
= STATUS_ERROR
;
389 TotalSize
-= FileSize
;
391 // Pad the rest of the image to make it a multiple of 512 bytes
393 while (TotalSize
> 0) {
399 if (InFptr
!= NULL
) {
403 if (Buffer
!= NULL
) {
407 // Print the file name if errors occurred
409 if (Status
!= STATUS_SUCCESS
) {
410 Error (NULL
, 0, 0003, "Error", "Error parsing file: %s", InFile
->FileName
);
429 Process a PE32 EFI file.
433 OutFptr - file pointer to output binary ROM image file we're creating
434 InFile - structure contains information on the PE32 file to process
435 VendId - vendor ID as required in the option ROM header
436 DevId - device ID as required in the option ROM header
437 Size - pointer to where to return the size added to the output file
447 EFI_PCI_EXPANSION_ROM_HEADER RomHdr
;
448 PCI_DATA_STRUCTURE PciDs23
;
449 PCI_3_0_DATA_STRUCTURE PciDs30
;
451 UINT32 CompressedFileSize
;
453 UINT8
*CompressedBuffer
;
454 UINT8
*TempBufferPtr
;
459 UINT32 HeaderPadBytes
;
460 UINT32 PadBytesBeforeImage
;
461 UINT32 PadBytesAfterImage
;
462 UINT32 DevIdListSize
;
465 // Try to open the input file
467 if ((InFptr
= fopen (LongFilePath (InFile
->FileName
), "rb")) == NULL
) {
468 Error (NULL
, 0, 0001, "Open file error", "Error opening file: %s", InFile
->FileName
);
472 // Initialize our buffer pointers to null.
475 CompressedBuffer
= NULL
;
478 // Double-check the file to make sure it's what we expect it to be
480 Status
= CheckPE32File (InFptr
, &MachineType
, &SubSystem
);
481 if (Status
!= STATUS_SUCCESS
) {
485 // Seek to the end of the input file and get the file size
487 fseek (InFptr
, 0, SEEK_END
);
488 FileSize
= ftell (InFptr
);
491 // Get the size of the headers we're going to put in front of the image. The
492 // EFI header must be aligned on a 4-byte boundary, so pad accordingly.
494 if (sizeof (RomHdr
) & 0x03) {
495 HeaderPadBytes
= 4 - (sizeof (RomHdr
) & 0x03);
501 // For Pci3.0 to use the different data structure.
503 if (mOptions
.Pci23
== 1) {
504 HeaderSize
= sizeof (PCI_DATA_STRUCTURE
) + HeaderPadBytes
+ sizeof (EFI_PCI_EXPANSION_ROM_HEADER
);
506 if (mOptions
.DevIdCount
> 1) {
508 // Write device ID list when more than one device ID is specified.
509 // Leave space for list plus terminator.
511 DevIdListSize
= (mOptions
.DevIdCount
+ 1) * sizeof (UINT16
);
515 HeaderSize
= sizeof (PCI_3_0_DATA_STRUCTURE
) + HeaderPadBytes
+ DevIdListSize
+ sizeof (EFI_PCI_EXPANSION_ROM_HEADER
);
518 if (mOptions
.Verbose
) {
519 VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize
);
522 // Allocate memory for the entire file (in case we have to compress), then
523 // seek back to the beginning of the file and read it into our buffer.
525 Buffer
= (UINT8
*) malloc (FileSize
);
526 if (Buffer
== NULL
) {
527 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
528 Status
= STATUS_ERROR
;
532 fseek (InFptr
, 0, SEEK_SET
);
533 if (fread (Buffer
, FileSize
, 1, InFptr
) != 1) {
534 Error (NULL
, 0, 0004, "Error reading file", "File %s", InFile
->FileName
);
535 Status
= STATUS_ERROR
;
539 // Now determine the size of the final output file. It's either the header size
540 // plus the file's size, or the header size plus the compressed file size.
542 if ((InFile
->FileFlags
& FILE_FLAG_COMPRESS
) != 0) {
544 // Allocate a buffer into which we can compress the image, compress it,
545 // and use that size as the new size.
547 CompressedBuffer
= (UINT8
*) malloc (FileSize
);
548 if (CompressedBuffer
== NULL
) {
549 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
550 Status
= STATUS_ERROR
;
554 CompressedFileSize
= FileSize
;
555 Status
= EfiCompress (Buffer
, FileSize
, CompressedBuffer
, &CompressedFileSize
);
556 if (Status
!= STATUS_SUCCESS
) {
557 Error (NULL
, 0, 0007, "Error compressing file!", NULL
);
561 // Now compute the size, then swap buffer pointers.
563 if (mOptions
.Verbose
) {
564 VerboseMsg(" Comp size = 0x%X\n", (unsigned) CompressedFileSize
);
567 TotalSize
= CompressedFileSize
+ HeaderSize
;
568 FileSize
= CompressedFileSize
;
569 TempBufferPtr
= Buffer
;
570 Buffer
= CompressedBuffer
;
571 CompressedBuffer
= TempBufferPtr
;
573 TotalSize
= FileSize
+ HeaderSize
;
576 // Total size must be an even multiple of 512 bytes
578 if (TotalSize
& 0x1FF) {
579 TotalSize
= (TotalSize
+ 0x200) &~0x1ff;
583 // If compressed, put the pad bytes after the image,
584 // else put the pad bytes before the image.
586 if ((InFile
->FileFlags
& FILE_FLAG_COMPRESS
) != 0) {
587 PadBytesBeforeImage
= 0;
588 PadBytesAfterImage
= TotalSize
- (FileSize
+ HeaderSize
);
590 PadBytesBeforeImage
= TotalSize
- (FileSize
+ HeaderSize
);
591 PadBytesAfterImage
= 0;
596 if (TotalSize
> MAX_OPTION_ROM_SIZE
) {
597 Error (NULL
, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile
->FileName
, MAX_OPTION_ROM_SIZE
);
598 Status
= STATUS_ERROR
;
602 // Return the size to the caller so they can keep track of the running total.
607 // Now fill in the ROM header. These values come from chapter 18 of the
608 // EFI 1.02 specification.
610 memset (&RomHdr
, 0, sizeof (RomHdr
));
611 RomHdr
.Signature
= PCI_EXPANSION_ROM_HEADER_SIGNATURE
;
612 RomHdr
.InitializationSize
= (UINT16
) (TotalSize
/ 512);
613 RomHdr
.EfiSignature
= EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
;
614 RomHdr
.EfiSubsystem
= SubSystem
;
615 RomHdr
.EfiMachineType
= MachineType
;
616 RomHdr
.EfiImageHeaderOffset
= (UINT16
) (HeaderSize
+ PadBytesBeforeImage
);
617 RomHdr
.PcirOffset
= (UINT16
) (sizeof (RomHdr
) + HeaderPadBytes
);
619 // Set image as compressed or not
621 if (InFile
->FileFlags
& FILE_FLAG_COMPRESS
) {
622 RomHdr
.CompressionType
= EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
;
625 // Fill in the PCI data structure
627 if (mOptions
.Pci23
== 1) {
628 memset (&PciDs23
, 0, sizeof (PCI_DATA_STRUCTURE
));
630 memset (&PciDs30
, 0, sizeof (PCI_3_0_DATA_STRUCTURE
));
633 if (mOptions
.Pci23
== 1) {
634 PciDs23
.Signature
= PCI_DATA_STRUCTURE_SIGNATURE
;
635 PciDs23
.VendorId
= VendId
;
636 PciDs23
.DeviceId
= DevId
;
637 PciDs23
.Length
= (UINT16
) sizeof (PCI_DATA_STRUCTURE
);
638 PciDs23
.Revision
= 0;
640 // Class code and code revision from the command line (optional)
642 PciDs23
.ClassCode
[0] = (UINT8
) InFile
->ClassCode
;
643 PciDs23
.ClassCode
[1] = (UINT8
) (InFile
->ClassCode
>> 8);
644 PciDs23
.ClassCode
[2] = (UINT8
) (InFile
->ClassCode
>> 16);
645 PciDs23
.ImageLength
= RomHdr
.InitializationSize
;
646 PciDs23
.CodeRevision
= InFile
->CodeRevision
;
647 PciDs23
.CodeType
= PCI_CODE_TYPE_EFI_IMAGE
;
649 PciDs30
.Signature
= PCI_DATA_STRUCTURE_SIGNATURE
;
650 PciDs30
.VendorId
= VendId
;
651 PciDs30
.DeviceId
= DevId
;
652 if (mOptions
.DevIdCount
> 1) {
654 // Place device list immediately after PCI structure
656 PciDs30
.DeviceListOffset
= (UINT16
) sizeof (PCI_3_0_DATA_STRUCTURE
);
658 PciDs30
.DeviceListOffset
= 0;
660 PciDs30
.Length
= (UINT16
) sizeof (PCI_3_0_DATA_STRUCTURE
);
661 PciDs30
.Revision
= 0x3;
663 // Class code and code revision from the command line (optional)
665 PciDs30
.ClassCode
[0] = (UINT8
) InFile
->ClassCode
;
666 PciDs30
.ClassCode
[1] = (UINT8
) (InFile
->ClassCode
>> 8);
667 PciDs30
.ClassCode
[2] = (UINT8
) (InFile
->ClassCode
>> 16);
668 PciDs30
.ImageLength
= RomHdr
.InitializationSize
;
669 PciDs30
.CodeRevision
= InFile
->CodeRevision
;
670 PciDs30
.CodeType
= PCI_CODE_TYPE_EFI_IMAGE
;
671 PciDs30
.MaxRuntimeImageLength
= 0; // to be fixed
672 PciDs30
.ConfigUtilityCodeHeaderOffset
= 0; // to be fixed
673 PciDs30
.DMTFCLPEntryPointOffset
= 0; // to be fixed
676 // If this is the last image, then set the LAST bit unless requested not
677 // to via the command-line -n argument.
679 if ((InFile
->Next
== NULL
) && (mOptions
.NoLast
== 0)) {
680 if (mOptions
.Pci23
== 1) {
681 PciDs23
.Indicator
= INDICATOR_LAST
;
683 PciDs30
.Indicator
= INDICATOR_LAST
;}
685 if (mOptions
.Pci23
== 1) {
686 PciDs23
.Indicator
= 0;
688 PciDs30
.Indicator
= 0;
692 // Write the ROM header to the output file
694 if (fwrite (&RomHdr
, sizeof (RomHdr
), 1, OutFptr
) != 1) {
695 Error (NULL
, 0, 0002, "Failed to write ROM header to output file!", NULL
);
696 Status
= STATUS_ERROR
;
701 // Write pad bytes to align the PciDs
703 while (HeaderPadBytes
> 0) {
704 if (putc (0, OutFptr
) == EOF
) {
705 Error (NULL
, 0, 0002, "Failed to write ROM header pad bytes to output file!", NULL
);
706 Status
= STATUS_ERROR
;
713 // Write the PCI data structure header to the output file
715 if (mOptions
.Pci23
== 1) {
716 if (fwrite (&PciDs23
, sizeof (PciDs23
), 1, OutFptr
) != 1) {
717 Error (NULL
, 0, 0002, "Failed to write PCI ROM header to output file!", NULL
);
718 Status
= STATUS_ERROR
;
722 if (fwrite (&PciDs30
, sizeof (PciDs30
), 1, OutFptr
) != 1) {
723 Error (NULL
, 0, 0002, "Failed to write PCI ROM header to output file!", NULL
);
724 Status
= STATUS_ERROR
;
730 // Write the Device ID list to the output file
732 if (mOptions
.DevIdCount
> 1) {
733 if (fwrite (mOptions
.DevIdList
, sizeof (UINT16
), mOptions
.DevIdCount
, OutFptr
) != mOptions
.DevIdCount
) {
734 Error (NULL
, 0, 0002, "Failed to write PCI device list to output file!", NULL
);
735 Status
= STATUS_ERROR
;
739 // Write two-byte terminating 0 at the end of the device list
741 if (putc (0, OutFptr
) == EOF
|| putc (0, OutFptr
) == EOF
) {
742 Error (NULL
, 0, 0002, "Failed to write PCI device list to output file!", NULL
);
743 Status
= STATUS_ERROR
;
750 // Pad head to make it a multiple of 512 bytes
752 while (PadBytesBeforeImage
> 0) {
753 if (putc (~0, OutFptr
) == EOF
) {
754 Error (NULL
, 0, 2000, "Failed to write trailing pad bytes output file!", NULL
);
755 Status
= STATUS_ERROR
;
758 PadBytesBeforeImage
--;
761 // Now dump the input file's contents to the output file
763 if (fwrite (Buffer
, FileSize
, 1, OutFptr
) != 1) {
764 Error (NULL
, 0, 0002, "Failed to write all file bytes to output file!", NULL
);
765 Status
= STATUS_ERROR
;
770 // Pad the rest of the image to make it a multiple of 512 bytes
772 while (PadBytesAfterImage
> 0) {
773 if (putc (~0, OutFptr
) == EOF
) {
774 Error (NULL
, 0, 2000, "Failed to write trailing pad bytes output file!", NULL
);
775 Status
= STATUS_ERROR
;
779 PadBytesAfterImage
--;
783 if (InFptr
!= NULL
) {
787 // Free up our buffers
789 if (Buffer
!= NULL
) {
793 if (CompressedBuffer
!= NULL
) {
794 free (CompressedBuffer
);
797 // Print the file name if errors occurred
799 if (Status
!= STATUS_SUCCESS
) {
800 Error (NULL
, 0, 0003, "Error parsing", "Error parsing file: %s", InFile
->FileName
);
817 Given a file pointer to a supposed PE32 image file, verify that it is indeed a
818 PE32 image file, and then return the machine type in the supplied pointer.
822 Fptr File pointer to the already-opened PE32 file
823 MachineType Location to stuff the machine type of the PE32 file. This is needed
824 because the image may be Itanium-based, IA32, or EBC.
833 EFI_IMAGE_DOS_HEADER DosHeader
;
834 EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr
;
837 // Position to the start of the file
839 fseek (Fptr
, 0, SEEK_SET
);
842 // Read the DOS header
844 if (fread (&DosHeader
, sizeof (DosHeader
), 1, Fptr
) != 1) {
845 Error (NULL
, 0, 0004, "Failed to read the DOS stub from the input file!", NULL
);
849 // Check the magic number (0x5A4D)
851 if (DosHeader
.e_magic
!= EFI_IMAGE_DOS_SIGNATURE
) {
852 Error (NULL
, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!");
856 // Position into the file and check the PE signature
858 fseek (Fptr
, (long) DosHeader
.e_lfanew
, SEEK_SET
);
863 if (fread (&PeHdr
, sizeof (PeHdr
), 1, Fptr
) != 1) {
864 Error (NULL
, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL
);
870 // Check the PE signature in the header "PE\0\0"
872 if (PeHdr
.Pe32
.Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
873 Error (NULL
, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!");
877 memcpy ((char *) MachineType
, &PeHdr
.Pe32
.FileHeader
.Machine
, 2);
879 if (PeHdr
.Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
880 *SubSystem
= PeHdr
.Pe32
.OptionalHeader
.Subsystem
;
881 } else if (PeHdr
.Pe32Plus
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
882 *SubSystem
= PeHdr
.Pe32Plus
.OptionalHeader
.Subsystem
;
884 Error (NULL
, 0, 2000, "Invalid parameter", "Unable to find subsystem type!");
888 if (mOptions
.Verbose
) {
889 VerboseMsg(" Got subsystem = 0x%X from image\n", *SubSystem
);
893 // File was successfully identified as a PE32
895 return STATUS_SUCCESS
;
909 Given the Argc/Argv program arguments, and a pointer to an options structure,
910 parse the command-line options and check their validity.
915 Argc - standard C main() argument count
916 Argv[] - standard C main() argument list
917 Options - pointer to a structure to store the options in
921 STATUS_SUCCESS success
927 FILE_LIST
*PrevFileList
;
943 // Clear out the options
945 memset ((char *) Options
, 0, sizeof (OPTIONS
));
948 // To avoid compile warnings
950 FileList
= PrevFileList
= NULL
;
952 Options
->DevIdList
= NULL
;
953 Options
->DevIdCount
= 0;
958 // Skip over the program name
964 // If no arguments, assume they want usage info
971 if ((stricmp(Argv
[0], "-h") == 0) || (stricmp(Argv
[0], "--help") == 0)) {
976 if ((stricmp(Argv
[0], "--version") == 0)) {
982 // Process until no more arguments
985 if (Argv
[0][0] == '-') {
987 // Vendor ID specified with -f
989 if (stricmp (Argv
[0], "-f") == 0) {
991 // Make sure there's another parameter
993 Status
= AsciiStringToUint64(Argv
[1], FALSE
, &TempValue
);
994 if (EFI_ERROR (Status
)) {
995 Error (NULL
, 0, 2000, "Invalid option value", "%s = %s", Argv
[0], Argv
[1]);
999 if (TempValue
>= 0x10000) {
1000 Error (NULL
, 0, 2000, "Invalid option value", "Vendor Id %s out of range!", Argv
[1]);
1004 Options
->VendId
= (UINT16
) TempValue
;
1005 Options
->VendIdValid
= 1;
1009 } else if (stricmp (Argv
[0], "-i") == 0) {
1011 OptionName
= Argv
[0];
1014 // Device IDs specified with -i
1015 // Make sure there's at least one more parameter
1018 Error (NULL
, 0, 2000, "Invalid parameter", "Missing Device Id with %s option!", OptionName
);
1024 // Process until another dash-argument parameter or the end of the list
1026 while (Argc
> 1 && Argv
[1][0] != '-') {
1027 Status
= AsciiStringToUint64(Argv
[1], FALSE
, &TempValue
);
1028 if (EFI_ERROR (Status
)) {
1029 Error (NULL
, 0, 2000, "Invalid option value", "%s = %s", OptionName
, Argv
[1]);
1034 // Don't allow device IDs greater than 16 bits
1035 // Don't allow 0, since it is used as a list terminator
1037 if (TempValue
>= 0x10000 || TempValue
== 0) {
1038 Error (NULL
, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv
[1]);
1043 DevIdList
= (UINT16
*) realloc (Options
->DevIdList
, (Options
->DevIdCount
+ 1) * sizeof (UINT16
));
1044 if (DevIdList
== NULL
) {
1045 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!", NULL
);
1049 Options
->DevIdList
= DevIdList
;
1051 Options
->DevIdList
[Options
->DevIdCount
++] = (UINT16
) TempValue
;
1057 } else if ((stricmp (Argv
[0], "-o") == 0) || (stricmp (Argv
[0], "--output") == 0)) {
1059 // Output filename specified with -o
1060 // Make sure there's another parameter
1062 if (Argv
[1] == NULL
|| Argv
[1][0] == '-') {
1063 Error (NULL
, 0, 2000, "Invalid parameter", "Missing output file name with %s option!", Argv
[0]);
1064 ReturnStatus
= STATUS_ERROR
;
1067 if (strlen (Argv
[1]) > MAX_PATH
- 1) {
1068 Error (NULL
, 0, 2000, "Invalid parameter", "Output file name %s is too long!", Argv
[1]);
1069 ReturnStatus
= STATUS_ERROR
;
1072 strncpy (Options
->OutFileName
, Argv
[1], MAX_PATH
- 1);
1073 Options
->OutFileName
[MAX_PATH
- 1] = 0;
1077 } else if ((stricmp (Argv
[0], "-h") == 0) || (stricmp (Argv
[0], "--help") == 0)) {
1082 ReturnStatus
= STATUS_ERROR
;
1084 } else if (stricmp (Argv
[0], "-b") == 0) {
1086 // Specify binary files with -b
1088 FileFlags
= FILE_FLAG_BINARY
;
1089 } else if ((stricmp (Argv
[0], "-e") == 0) || (stricmp (Argv
[0], "-ec") == 0)) {
1091 // Specify EFI files with -e. Specify EFI-compressed with -c.
1093 FileFlags
= FILE_FLAG_EFI
;
1094 if ((Argv
[0][2] == 'c') || (Argv
[0][2] == 'C')) {
1095 FileFlags
|= FILE_FLAG_COMPRESS
;
1098 // Specify not to set the LAST bit in the last file with -n
1100 } else if (stricmp (Argv
[0], "-n") == 0) {
1101 Options
->NoLast
= 1;
1102 } else if (((stricmp (Argv
[0], "-v") == 0)) || ((stricmp (Argv
[0], "--verbose") == 0))) {
1106 Options
->Verbose
= 1;
1107 } else if (stricmp (Argv
[0], "--debug") == 0) {
1108 Status
= AsciiStringToUint64(Argv
[1], FALSE
, &DebugLevel
);
1109 if (EFI_ERROR (Status
)) {
1110 Error (NULL
, 0, 2000, "Invalid option value", "%s = %s", Argv
[0], Argv
[1]);
1114 if (DebugLevel
> 9) {
1115 Error (NULL
, 0, 2000, "Invalid option value", "Debug Level range is 0-9, current input level is %llu", DebugLevel
);
1119 if (DebugLevel
>=5 && DebugLevel
<=9) {
1120 Options
->Debug
= TRUE
;
1122 Options
->Debug
= FALSE
;
1126 } else if ((stricmp (Argv
[0], "--quiet") == 0) || (stricmp (Argv
[0], "-q") == 0)) {
1127 Options
->Quiet
= TRUE
;
1128 } else if ((stricmp (Argv
[0], "--dump") == 0) || (stricmp (Argv
[0], "-d") == 0)) {
1130 // -dump for dumping a ROM image. In this case, say that the device id
1131 // and vendor id are valid so we don't have to specify bogus ones on the
1134 Options
->DumpOption
= 1;
1136 Options
->VendIdValid
= 1;
1137 Options
->DevIdCount
= 1;
1138 FileFlags
= FILE_FLAG_BINARY
;
1139 } else if ((stricmp (Argv
[0], "-l") == 0) || (stricmp (Argv
[0], "--class-code") == 0)) {
1141 // Class code value for the next file in the list.
1142 // Make sure there's another parameter
1144 Status
= AsciiStringToUint64(Argv
[1], FALSE
, &TempValue
);
1145 if (EFI_ERROR (Status
)) {
1146 Error (NULL
, 0, 2000, "Invalid option value", "%s = %s", Argv
[0], Argv
[1]);
1150 ClassCode
= (UINT32
) TempValue
;
1151 if (ClassCode
& 0xFF000000) {
1152 Error (NULL
, 0, 2000, "Invalid parameter", "Class code %s out of range!", Argv
[1]);
1153 ReturnStatus
= STATUS_ERROR
;
1156 if (FileList
!= NULL
&& FileList
->ClassCode
== 0) {
1157 FileList
->ClassCode
= ClassCode
;
1161 } else if ((stricmp (Argv
[0], "-r") == 0) || (stricmp (Argv
[0], "--Revision") == 0)) {
1163 // Code revision in the PCI data structure. The value is for the next
1164 // file in the list.
1165 // Make sure there's another parameter
1167 Status
= AsciiStringToUint64(Argv
[1], FALSE
, &TempValue
);
1168 if (EFI_ERROR (Status
)) {
1169 Error (NULL
, 0, 2000, "Invalid option value", "%s = %s", Argv
[0], Argv
[1]);
1173 CodeRevision
= (UINT32
) TempValue
;
1174 if (CodeRevision
& 0xFFFF0000) {
1175 Error (NULL
, 0, 2000, "Invalid parameter", "Code revision %s out of range!", Argv
[1]);
1176 ReturnStatus
= STATUS_ERROR
;
1179 if (FileList
!= NULL
&& FileList
->CodeRevision
== 0) {
1180 FileList
->CodeRevision
= (UINT16
) CodeRevision
;
1184 } else if ((stricmp (Argv
[0], "-p") == 0) || (stricmp (Argv
[0], "--pci23") == 0)) {
1186 // Default layout meets PCI 3.0 specifications, specifying this flag will for a PCI 2.3 layout.
1190 Error (NULL
, 0, 2000, "Invalid parameter", "Invalid option specified: %s", Argv
[0]);
1191 ReturnStatus
= STATUS_ERROR
;
1196 // Not a slash-option argument. Must be a file name. Make sure they've specified
1197 // -e or -b already.
1199 if ((FileFlags
& (FILE_FLAG_BINARY
| FILE_FLAG_EFI
)) == 0) {
1200 Error (NULL
, 0, 2000, "Invalid parameter", "Missing -e or -b with input file %s!", Argv
[0]);
1201 ReturnStatus
= STATUS_ERROR
;
1205 // Check Efi Option RomImage
1207 if ((FileFlags
& FILE_FLAG_EFI
) == FILE_FLAG_EFI
) {
1211 // Create a new file structure
1213 FileList
= (FILE_LIST
*) malloc (sizeof (FILE_LIST
));
1214 if (FileList
== NULL
) {
1215 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!", NULL
);
1216 ReturnStatus
= STATUS_ERROR
;
1221 // set flag and class code for this image.
1223 memset ((char *) FileList
, 0, sizeof (FILE_LIST
));
1224 FileList
->FileName
= Argv
[0];
1225 FileList
->FileFlags
= FileFlags
;
1226 FileList
->ClassCode
= ClassCode
;
1227 FileList
->CodeRevision
= (UINT16
) CodeRevision
;
1231 if (Options
->FileList
== NULL
) {
1232 Options
->FileList
= FileList
;
1234 if (PrevFileList
== NULL
) {
1235 PrevFileList
= FileList
;
1237 PrevFileList
->Next
= FileList
;
1241 PrevFileList
= FileList
;
1251 // Must have specified some files
1253 if (Options
->FileList
== NULL
) {
1254 Error (NULL
, 0, 2000, "Invalid parameter", "Missing input file name!");
1256 // No memory allocation, return directly.
1258 return STATUS_ERROR
;
1262 // For EFI OptionRom image, Make sure a device ID and vendor ID are both specified.
1265 if (!Options
->VendIdValid
) {
1266 Error (NULL
, 0, 2000, "Missing Vendor ID in command line", NULL
);
1267 ReturnStatus
= STATUS_ERROR
;
1271 if (!Options
->DevIdCount
) {
1272 Error (NULL
, 0, 2000, "Missing Device ID in command line", NULL
);
1273 ReturnStatus
= STATUS_ERROR
;
1278 if (Options
->DevIdCount
> 1 && Options
->Pci23
) {
1279 Error (NULL
, 0, 2000, "Invalid parameter", "PCI 3.0 is required when specifying multiple Device IDs");
1280 ReturnStatus
= STATUS_ERROR
;
1285 if (ReturnStatus
!= 0) {
1286 while (Options
->FileList
!= NULL
) {
1287 FileList
= Options
->FileList
->Next
;
1288 free (Options
->FileList
);
1289 Options
->FileList
= FileList
;
1293 return ReturnStatus
;
1303 Routine Description:
1305 Print version information for this utility.
1316 fprintf (stdout
, "%s Version %d.%d %s \n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
, __BUILD_VERSION
);
1326 Routine Description:
1328 Print usage information for this utility.
1343 fprintf (stdout
, "Usage: %s -f VendorId -i DeviceId [options] [file name<s>] \n\n", UTILITY_NAME
);
1346 // Copyright declaration
1348 fprintf (stdout
, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
1353 fprintf (stdout
, "Options:\n");
1354 fprintf (stdout
, " -o FileName, --output FileName\n\
1355 File will be created to store the output content.\n");
1356 fprintf (stdout
, " -e EfiFileName\n\
1357 EFI PE32 image files.\n");
1358 fprintf (stdout
, " -ec EfiFileName\n\
1359 EFI PE32 image files and will be compressed.\n");
1360 fprintf (stdout
, " -b BinFileName\n\
1361 Legacy binary files.\n");
1362 fprintf (stdout
, " -l ClassCode\n\
1363 Hex ClassCode in the PCI data structure header.\n");
1364 fprintf (stdout
, " -r Rev Hex Revision in the PCI data structure header.\n");
1365 fprintf (stdout
, " -n Not to automatically set the LAST bit in the last file.\n");
1366 fprintf (stdout
, " -f VendorId\n\
1367 Hex PCI Vendor ID for the device OpROM, must be specified\n");
1368 fprintf (stdout
, " -i DeviceId\n\
1369 One or more hex PCI Device IDs for the device OpROM, must be specified\n");
1370 fprintf (stdout
, " -p, --pci23\n\
1371 Default layout meets PCI 3.0 specifications\n\
1372 specifying this flag will for a PCI 2.3 layout.\n");
1373 fprintf (stdout
, " -d, --dump\n\
1374 Dump the headers of an existing option ROM image.\n");
1375 fprintf (stdout
, " -v, --verbose\n\
1376 Turn on verbose output with informational messages.\n");
1377 fprintf (stdout
, " --version Show program's version number and exit.\n");
1378 fprintf (stdout
, " -h, --help\n\
1379 Show this help message and exit.\n");
1380 fprintf (stdout
, " -q, --quiet\n\
1381 Disable all messages except FATAL ERRORS.\n");
1382 fprintf (stdout
, " --debug [#,0-9]\n\
1383 Enable debug messages at level #.\n");
1393 Routine Description:
1395 Dump the headers of an existing option ROM image
1399 InFile - the file name of an existing option ROM image
1407 PCI_EXPANSION_ROM_HEADER PciRomHdr
;
1411 EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr
;
1412 PCI_DATA_STRUCTURE PciDs23
;
1413 PCI_3_0_DATA_STRUCTURE PciDs30
;
1417 // Open the input file
1419 if ((InFptr
= fopen (LongFilePath (InFile
->FileName
), "rb")) == NULL
) {
1420 Error (NULL
, 0, 0001, "Error opening file", InFile
->FileName
);
1424 // Go through the image and dump the header stuff for each
1429 // Save our position in the file, since offsets in the headers
1430 // are relative to the particular image.
1432 ImageStart
= ftell (InFptr
);
1436 // Read the option ROM header. Have to assume a raw binary image for now.
1438 if (fread (&PciRomHdr
, sizeof (PciRomHdr
), 1, InFptr
) != 1) {
1439 Error (NULL
, 0, 3001, "Not supported", "Failed to read PCI ROM header from file!");
1444 // Dump the contents of the header
1446 fprintf (stdout
, "Image %u -- Offset 0x%X\n", (unsigned) ImageCount
, (unsigned) ImageStart
);
1447 fprintf (stdout
, " ROM header contents\n");
1448 fprintf (stdout
, " Signature 0x%04X\n", PciRomHdr
.Signature
);
1449 fprintf (stdout
, " PCIR offset 0x%04X\n", PciRomHdr
.PcirOffset
);
1451 // Find PCI data structure
1453 if (fseek (InFptr
, ImageStart
+ PciRomHdr
.PcirOffset
, SEEK_SET
)) {
1454 Error (NULL
, 0, 3001, "Not supported", "Failed to seek to PCI data structure!");
1458 // Read and dump the PCI data structure
1460 memset (&PciDs23
, 0, sizeof (PciDs23
));
1461 memset (&PciDs30
, 0, sizeof (PciDs30
));
1462 if (mOptions
.Pci23
== 1) {
1463 if (fread (&PciDs23
, sizeof (PciDs23
), 1, InFptr
) != 1) {
1464 Error (NULL
, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile
->FileName
);
1468 if (fread (&PciDs30
, sizeof (PciDs30
), 1, InFptr
) != 1) {
1469 Error (NULL
, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile
->FileName
);
1473 if (mOptions
.Verbose
) {
1474 VerboseMsg("Read PCI data structure from file %s", InFile
->FileName
);
1477 //fprintf (stdout, " PCI Data Structure\n");
1478 if (mOptions
.Pci23
== 1) {
1481 " Signature %c%c%c%c\n",
1482 (char) PciDs23
.Signature
,
1483 (char) (PciDs23
.Signature
>> 8),
1484 (char) (PciDs23
.Signature
>> 16),
1485 (char) (PciDs23
.Signature
>> 24)
1487 fprintf (stdout
, " Vendor ID 0x%04X\n", PciDs23
.VendorId
);
1488 fprintf (stdout
, " Device ID 0x%04X\n", PciDs23
.DeviceId
);
1489 fprintf (stdout
, " Length 0x%04X\n", PciDs23
.Length
);
1490 fprintf (stdout
, " Revision 0x%04X\n", PciDs23
.Revision
);
1493 " Class Code 0x%06X\n",
1494 (unsigned) (PciDs23
.ClassCode
[0] | (PciDs23
.ClassCode
[1] << 8) | (PciDs23
.ClassCode
[2] << 16))
1496 fprintf (stdout
, " Image size 0x%X\n", (unsigned) PciDs23
.ImageLength
* 512);
1497 fprintf (stdout
, " Code revision: 0x%04X\n", PciDs23
.CodeRevision
);
1498 fprintf (stdout
, " Indicator 0x%02X", PciDs23
.Indicator
);
1502 " Signature %c%c%c%c\n",
1503 (char) PciDs30
.Signature
,
1504 (char) (PciDs30
.Signature
>> 8),
1505 (char) (PciDs30
.Signature
>> 16),
1506 (char) (PciDs30
.Signature
>> 24)
1508 fprintf (stdout
, " Vendor ID 0x%04X\n", PciDs30
.VendorId
);
1509 fprintf (stdout
, " Device ID 0x%04X\n", PciDs30
.DeviceId
);
1510 fprintf (stdout
, " Length 0x%04X\n", PciDs30
.Length
);
1511 fprintf (stdout
, " Revision 0x%04X\n", PciDs30
.Revision
);
1512 fprintf (stdout
, " DeviceListOffset 0x%02X\n", PciDs30
.DeviceListOffset
);
1513 if (PciDs30
.DeviceListOffset
) {
1515 // Print device ID list
1517 fprintf (stdout
, " Device list contents\n");
1518 if (fseek (InFptr
, ImageStart
+ PciRomHdr
.PcirOffset
+ PciDs30
.DeviceListOffset
, SEEK_SET
)) {
1519 Error (NULL
, 0, 3001, "Not supported", "Failed to seek to PCI device ID list!");
1524 // Loop until terminating 0
1527 if (fread (&DevId
, sizeof (DevId
), 1, InFptr
) != 1) {
1528 Error (NULL
, 0, 3001, "Not supported", "Failed to read PCI device ID list from file %s!", InFile
->FileName
);
1532 fprintf (stdout
, " 0x%04X\n", DevId
);
1539 " Class Code 0x%06X\n",
1540 (unsigned) (PciDs30
.ClassCode
[0] | (PciDs30
.ClassCode
[1] << 8) | (PciDs30
.ClassCode
[2] << 16))
1542 fprintf (stdout
, " Image size 0x%X\n", (unsigned) PciDs30
.ImageLength
* 512);
1543 fprintf (stdout
, " Code revision: 0x%04X\n", PciDs30
.CodeRevision
);
1544 fprintf (stdout
, " MaxRuntimeImageLength 0x%02X\n", PciDs30
.MaxRuntimeImageLength
);
1545 fprintf (stdout
, " ConfigUtilityCodeHeaderOffset 0x%02X\n", PciDs30
.ConfigUtilityCodeHeaderOffset
);
1546 fprintf (stdout
, " DMTFCLPEntryPointOffset 0x%02X\n", PciDs30
.DMTFCLPEntryPointOffset
);
1547 fprintf (stdout
, " Indicator 0x%02X", PciDs30
.Indicator
);
1550 // Print the indicator, used to flag the last image
1552 if (PciDs23
.Indicator
== INDICATOR_LAST
|| PciDs30
.Indicator
== INDICATOR_LAST
) {
1553 fprintf (stdout
, " (last image)\n");
1555 fprintf (stdout
, "\n");
1558 // Print the code type. If EFI code, then we can provide more info.
1560 if (mOptions
.Pci23
== 1) {
1561 fprintf (stdout
, " Code type 0x%02X", PciDs23
.CodeType
);
1563 fprintf (stdout
, " Code type 0x%02X", PciDs30
.CodeType
);
1565 if (PciDs23
.CodeType
== PCI_CODE_TYPE_EFI_IMAGE
|| PciDs30
.CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) {
1566 fprintf (stdout
, " (EFI image)\n");
1568 // Re-read the header as an EFI ROM header, then dump more info
1570 fprintf (stdout
, " EFI ROM header contents\n");
1571 if (fseek (InFptr
, ImageStart
, SEEK_SET
)) {
1572 Error (NULL
, 0, 5001, "Failed to re-seek to ROM header structure!", NULL
);
1576 if (fread (&EfiRomHdr
, sizeof (EfiRomHdr
), 1, InFptr
) != 1) {
1577 Error (NULL
, 0, 5001, "Failed to read EFI PCI ROM header from file!", NULL
);
1581 // Now dump more info
1583 fprintf (stdout
, " EFI Signature 0x%04X\n", (unsigned) EfiRomHdr
.EfiSignature
);
1586 " Compression Type 0x%04X ",
1587 EfiRomHdr
.CompressionType
1589 if (EfiRomHdr
.CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1590 fprintf (stdout
, "(compressed)\n");
1592 fprintf (stdout
, "(not compressed)\n");
1597 " Machine type 0x%04X (%s)\n",
1598 EfiRomHdr
.EfiMachineType
,
1599 GetMachineTypeStr (EfiRomHdr
.EfiMachineType
)
1603 " Subsystem 0x%04X (%s)\n",
1604 EfiRomHdr
.EfiSubsystem
,
1605 GetSubsystemTypeStr (EfiRomHdr
.EfiSubsystem
)
1609 " EFI image offset 0x%04X (@0x%X)\n",
1610 EfiRomHdr
.EfiImageHeaderOffset
,
1611 EfiRomHdr
.EfiImageHeaderOffset
+ (unsigned) ImageStart
1618 fprintf (stdout
, "\n");
1621 // If code type is EFI image, then dump it as well?
1623 // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
1626 // If last image, then we're done
1628 if (PciDs23
.Indicator
== INDICATOR_LAST
|| PciDs30
.Indicator
== INDICATOR_LAST
) {
1632 // Seek to the start of the next image
1634 if (mOptions
.Pci23
== 1) {
1635 if (fseek (InFptr
, ImageStart
+ (PciDs23
.ImageLength
* 512), SEEK_SET
)) {
1636 Error (NULL
, 0, 3001, "Not supported", "Failed to seek to next image!");
1640 if (fseek (InFptr
, ImageStart
+ (PciDs30
.ImageLength
* 512), SEEK_SET
)) {
1641 Error (NULL
, 0, 3001, "Not supported", "Failed to seek to next image!");
1657 Routine Description:
1659 GC_TODO: Add function description
1663 MachineType - GC_TODO: add argument description
1667 GC_TODO: add return values
1673 for (Index
= 0; mMachineTypes
[Index
].Name
!= NULL
; Index
++) {
1674 if (mMachineTypes
[Index
].Value
== MachineType
) {
1675 return mMachineTypes
[Index
].Name
;
1684 GetSubsystemTypeStr (
1685 UINT16 SubsystemType
1689 Routine Description:
1691 GC_TODO: Add function description
1695 SubsystemType - GC_TODO: add argument description
1699 GC_TODO: add return values
1705 for (Index
= 0; mSubsystemTypes
[Index
].Name
!= NULL
; Index
++) {
1706 if (mSubsystemTypes
[Index
].Value
== SubsystemType
) {
1707 return mSubsystemTypes
[Index
].Name
;