X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FC%2FEfiRom%2FEfiRom.c;h=a7e2839b0a8422faca50023d647418f25fdb58ec;hb=2e351cbe8e190271b3716284fc1076551d005472;hp=838ee25cba74c9212342cb7a5f65105a090eb1c9;hpb=1be2ed90a20618d71ddf34b8a07d038da0b36854;p=mirror_edk2.git
diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c
index 838ee25cba..a7e2839b0a 100644
--- a/BaseTools/Source/C/EfiRom/EfiRom.c
+++ b/BaseTools/Source/C/EfiRom/EfiRom.c
@@ -1,22 +1,8 @@
/** @file
+Utility program to create an EFI option ROM image from binary and EFI PE32 files.
-Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available
-under the terms and conditions of the BSD License which accompanies this
-distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- EfiRom.c
-
-Abstract:
-
- Utility program to create an EFI option ROM image from binary and
- EFI PE32 files.
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -34,8 +20,8 @@ main (
/*++
Routine Description:
-
- Given an EFI image filename, create a ROM-able image by creating an option
+
+ Given an EFI image filename, create a ROM-able image by creating an option
ROM header and PCI data structure, filling them in, and then writing the
option ROM header + PCI data structure + EFI image out to the output file.
@@ -79,11 +65,11 @@ Returns:
} else if (mOptions.Debug) {
SetPrintLevel(DebugLevel);
}
-
+
if (mOptions.Verbose) {
VerboseMsg("%s tool start.\n", UTILITY_NAME);
}
-
+
//
// If dumping an image, then do that and quit
//
@@ -103,24 +89,34 @@ Returns:
// the command line, or the first input filename with a different extension.
//
if (!mOptions.OutFileName[0]) {
- strcpy (mOptions.OutFileName, mOptions.FileList->FileName);
- //
- // Find the last . on the line and replace the filename extension with
- // the default
- //
- for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;
- (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');
- Ext--
- )
- ;
- //
- // If dot here, then insert extension here, otherwise append
- //
- if (*Ext != '.') {
- Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);
- }
+ if (mOptions.FileList != NULL) {
+ if (strlen (mOptions.FileList->FileName) >= MAX_PATH) {
+ Status = STATUS_ERROR;
+ Error (NULL, 0, 2000, "Invalid parameter", "Input file name is too long - %s.", mOptions.FileList->FileName);
+ goto BailOut;
+ }
+ strncpy (mOptions.OutFileName, mOptions.FileList->FileName, MAX_PATH - 1);
+ mOptions.OutFileName[MAX_PATH - 1] = 0;
+ //
+ // Find the last . on the line and replace the filename extension with
+ // the default
+ //
+ Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;
+ while (Ext >= mOptions.OutFileName) {
+ if ((*Ext == '.') || (*Ext == '\\')) {
+ break;
+ }
+ Ext--;
+ }
+ //
+ // If dot here, then insert extension here, otherwise append
+ //
+ if (*Ext != '.') {
+ Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);
+ }
- strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);
+ strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);
+ }
}
//
// Make sure we don't have the same filename for input and output files
@@ -128,7 +124,7 @@ Returns:
for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) {
if (stricmp (mOptions.OutFileName, FList->FileName) == 0) {
Status = STATUS_ERROR;
- Error (NULL, 0, 1002, "Invalid input paramter", "Input and output file names must be different - %s = %s.", FList->FileName, mOptions.OutFileName);
+ Error (NULL, 0, 1002, "Invalid input parameter", "Input and output file names must be different - %s = %s.", FList->FileName, mOptions.OutFileName);
goto BailOut;
}
}
@@ -150,7 +146,7 @@ Returns:
VerboseMsg("Processing EFI file %s\n", FList->FileName);
}
- Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size);
+ Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevIdList[0], &Size);
} else if ((FList->FileFlags & FILE_FLAG_BINARY) !=0 ) {
if (mOptions.Verbose) {
VerboseMsg("Processing binary file %s\n", FList->FileName);
@@ -176,15 +172,12 @@ Returns:
// Check total size
//
if (TotalSize > MAX_OPTION_ROM_SIZE) {
- Error (NULL, 0, 2000, "Invalid paramter", "Option ROM image size exceeds limit of 0x%X bytes.", MAX_OPTION_ROM_SIZE);
+ Error (NULL, 0, 2000, "Invalid parameter", "Option ROM image size exceeds limit of 0x%X bytes.", MAX_OPTION_ROM_SIZE);
Status = STATUS_ERROR;
}
BailOut:
if (Status == STATUS_SUCCESS) {
- if (FptrOut != NULL) {
- fclose (FptrOut);
- }
//
// Clean up our file list
//
@@ -193,13 +186,23 @@ BailOut:
free (mOptions.FileList);
mOptions.FileList = FList;
}
+
+ //
+ // Clean up device ID list
+ //
+ if (mOptions.DevIdList != NULL) {
+ free (mOptions.DevIdList);
+ }
+ }
+ if (FptrOut != NULL) {
+ fclose (FptrOut);
}
if (mOptions.Verbose) {
VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
}
- return GetUtilityStatus ();
+ return GetUtilityStatus ();
}
static
@@ -212,7 +215,7 @@ ProcessBinFile (
/*++
Routine Description:
-
+
Process a binary input file.
Arguments:
@@ -238,7 +241,7 @@ Returns:
UINT32 Index;
UINT8 ByteCheckSum;
UINT16 CodeType;
-
+
PciDs23 = NULL;
PciDs30 = NULL;
Status = STATUS_SUCCESS;
@@ -247,7 +250,7 @@ Returns:
// Try to open the input file
//
if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {
- Error (NULL, 0, 0001, "Error opening file", InFile->FileName);
+ Error (NULL, 0, 0001, "Error opening file", "%s", InFile->FileName);
return STATUS_ERROR;
}
//
@@ -342,7 +345,7 @@ Returns:
} else {
PciDs30->ImageLength = (UINT16) (TotalSize / 512);
CodeType = PciDs30->CodeType;
- }
+ }
//
// If this is the last image, then set the LAST bit unless requested not
@@ -353,13 +356,13 @@ Returns:
PciDs23->Indicator = INDICATOR_LAST;
} else {
PciDs30->Indicator = INDICATOR_LAST;
- }
+ }
} else {
if (mOptions.Pci23 == 1) {
PciDs23->Indicator = 0;
} else {
PciDs30->Indicator = 0;
- }
+ }
}
if (CodeType != PCI_CODE_TYPE_EFI_IMAGE) {
@@ -422,7 +425,7 @@ ProcessEfiFile (
/*++
Routine Description:
-
+
Process a PE32 EFI file.
Arguments:
@@ -456,6 +459,7 @@ Returns:
UINT32 HeaderPadBytes;
UINT32 PadBytesBeforeImage;
UINT32 PadBytesAfterImage;
+ UINT32 DevIdListSize;
//
// Try to open the input file
@@ -492,14 +496,23 @@ Returns:
} else {
HeaderPadBytes = 0;
}
-
+
//
// For Pci3.0 to use the different data structure.
//
if (mOptions.Pci23 == 1) {
HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
} else {
- HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
+ if (mOptions.DevIdCount > 1) {
+ //
+ // Write device ID list when more than one device ID is specified.
+ // Leave space for list plus terminator.
+ //
+ DevIdListSize = (mOptions.DevIdCount + 1) * sizeof (UINT16);
+ } else {
+ DevIdListSize = 0;
+ }
+ HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + DevIdListSize + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);
}
if (mOptions.Verbose) {
@@ -581,7 +594,7 @@ Returns:
// Check size
//
if (TotalSize > MAX_OPTION_ROM_SIZE) {
- Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);
+ Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);
Status = STATUS_ERROR;
goto BailOut;
}
@@ -636,7 +649,14 @@ Returns:
PciDs30.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
PciDs30.VendorId = VendId;
PciDs30.DeviceId = DevId;
- PciDs30.DeviceListOffset = 0; // to be fixed
+ if (mOptions.DevIdCount > 1) {
+ //
+ // Place device list immediately after PCI structure
+ //
+ PciDs30.DeviceListOffset = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);
+ } else {
+ PciDs30.DeviceListOffset = 0;
+ }
PciDs30.Length = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);
PciDs30.Revision = 0x3;
//
@@ -659,12 +679,12 @@ Returns:
if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {
if (mOptions.Pci23 == 1) {
PciDs23.Indicator = INDICATOR_LAST;
- } else {
+ } else {
PciDs30.Indicator = INDICATOR_LAST;}
} else {
if (mOptions.Pci23 == 1) {
PciDs23.Indicator = 0;
- } else {
+ } else {
PciDs30.Indicator = 0;
}
}
@@ -697,15 +717,35 @@ Returns:
Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);
Status = STATUS_ERROR;
goto BailOut;
- }
+ }
} else {
if (fwrite (&PciDs30, sizeof (PciDs30), 1, OutFptr) != 1) {
Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);
Status = STATUS_ERROR;
goto BailOut;
- }
+ }
}
+ //
+ // Write the Device ID list to the output file
+ //
+ if (mOptions.DevIdCount > 1) {
+ if (fwrite (mOptions.DevIdList, sizeof (UINT16), mOptions.DevIdCount, OutFptr) != mOptions.DevIdCount) {
+ Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ //
+ // Write two-byte terminating 0 at the end of the device list
+ //
+ if (putc (0, OutFptr) == EOF || putc (0, OutFptr) == EOF) {
+ Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);
+ Status = STATUS_ERROR;
+ goto BailOut;
+ }
+ }
+
+
//
// Pad head to make it a multiple of 512 bytes
//
@@ -773,7 +813,7 @@ CheckPE32File (
/*++
Routine Description:
-
+
Given a file pointer to a supposed PE32 image file, verify that it is indeed a
PE32 image file, and then return the machine type in the supplied pointer.
@@ -865,7 +905,7 @@ ParseCommandLine (
/*++
Routine Description:
-
+
Given the Argc/Argv program arguments, and a pointer to an options structure,
parse the command-line options and check their validity.
@@ -889,9 +929,13 @@ Returns:
UINT32 ClassCode;
UINT32 CodeRevision;
EFI_STATUS Status;
+ INTN ReturnStatus;
BOOLEAN EfiRomFlag;
UINT64 TempValue;
+ char *OptionName;
+ UINT16 *DevIdList;
+ ReturnStatus = 0;
FileFlags = 0;
EfiRomFlag = FALSE;
@@ -905,6 +949,9 @@ Returns:
//
FileList = PrevFileList = NULL;
+ Options->DevIdList = NULL;
+ Options->DevIdCount = 0;
+
ClassCode = 0;
CodeRevision = 0;
//
@@ -920,12 +967,12 @@ Returns:
Usage ();
return STATUS_ERROR;
}
-
+
if ((stricmp(Argv[0], "-h") == 0) || (stricmp(Argv[0], "--help") == 0)) {
Usage();
return STATUS_ERROR;
}
-
+
if ((stricmp(Argv[0], "--version") == 0)) {
Version();
return STATUS_ERROR;
@@ -946,11 +993,13 @@ Returns:
Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
- return 1;
+ ReturnStatus = 1;
+ goto Done;
}
if (TempValue >= 0x10000) {
Error (NULL, 0, 2000, "Invalid option value", "Vendor Id %s out of range!", Argv[1]);
- return 1;
+ ReturnStatus = 1;
+ goto Done;
}
Options->VendId = (UINT16) TempValue;
Options->VendIdValid = 1;
@@ -958,24 +1007,53 @@ Returns:
Argv++;
Argc--;
} else if (stricmp (Argv[0], "-i") == 0) {
+
+ OptionName = Argv[0];
+
//
- // Device ID specified with -i
- // Make sure there's another parameter
+ // Device IDs specified with -i
+ // Make sure there's at least one more parameter
//
- Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
- return 1;
+ if (Argc < 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Missing Device Id with %s option!", OptionName);
+ ReturnStatus = 1;
+ goto Done;
}
- if (TempValue >= 0x10000) {
- Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);
- return 1;
+
+ //
+ // Process until another dash-argument parameter or the end of the list
+ //
+ while (Argc > 1 && Argv[1][0] != '-') {
+ Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", OptionName, Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ //
+ // Don't allow device IDs greater than 16 bits
+ // Don't allow 0, since it is used as a list terminator
+ //
+ if (TempValue >= 0x10000 || TempValue == 0) {
+ Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);
+ ReturnStatus = 1;
+ goto Done;
+ }
+
+ DevIdList = (UINT16*) realloc (Options->DevIdList, (Options->DevIdCount + 1) * sizeof (UINT16));
+ if (DevIdList == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);
+ ReturnStatus = 1;
+ goto Done;
+ }
+ Options->DevIdList = DevIdList;
+
+ Options->DevIdList[Options->DevIdCount++] = (UINT16) TempValue;
+
+ Argv++;
+ Argc--;
}
- Options->DevId = (UINT16) TempValue;
- Options->DevIdValid = 1;
- Argv++;
- Argc--;
} else if ((stricmp (Argv[0], "-o") == 0) || (stricmp (Argv[0], "--output") == 0)) {
//
// Output filename specified with -o
@@ -983,9 +1061,16 @@ Returns:
//
if (Argv[1] == NULL || Argv[1][0] == '-') {
Error (NULL, 0, 2000, "Invalid parameter", "Missing output file name with %s option!", Argv[0]);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
- strcpy (Options->OutFileName, Argv[1]);
+ if (strlen (Argv[1]) > MAX_PATH - 1) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Output file name %s is too long!", Argv[1]);
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+ strncpy (Options->OutFileName, Argv[1], MAX_PATH - 1);
+ Options->OutFileName[MAX_PATH - 1] = 0;
Argv++;
Argc--;
@@ -994,7 +1079,8 @@ Returns:
// Help option
//
Usage ();
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
} else if (stricmp (Argv[0], "-b") == 0) {
//
// Specify binary files with -b
@@ -1022,11 +1108,13 @@ Returns:
Status = AsciiStringToUint64(Argv[1], FALSE, &DebugLevel);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
- return 1;
+ ReturnStatus = 1;
+ goto Done;
}
if (DebugLevel > 9) {
Error (NULL, 0, 2000, "Invalid option value", "Debug Level range is 0-9, current input level is %d", Argv[1]);
- return 1;
+ ReturnStatus = 1;
+ goto Done;
}
if (DebugLevel>=5 && DebugLevel<=9) {
Options->Debug = TRUE;
@@ -1046,7 +1134,7 @@ Returns:
Options->DumpOption = 1;
Options->VendIdValid = 1;
- Options->DevIdValid = 1;
+ Options->DevIdCount = 1;
FileFlags = FILE_FLAG_BINARY;
} else if ((stricmp (Argv[0], "-l") == 0) || (stricmp (Argv[0], "--class-code") == 0)) {
//
@@ -1056,12 +1144,14 @@ Returns:
Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
- return 1;
+ ReturnStatus = 1;
+ goto Done;
}
ClassCode = (UINT32) TempValue;
if (ClassCode & 0xFF000000) {
Error (NULL, 0, 2000, "Invalid parameter", "Class code %s out of range!", Argv[1]);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
if (FileList != NULL && FileList->ClassCode == 0) {
FileList->ClassCode = ClassCode;
@@ -1077,12 +1167,14 @@ Returns:
Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);
- return 1;
+ ReturnStatus = 1;
+ goto Done;
}
CodeRevision = (UINT32) TempValue;
if (CodeRevision & 0xFFFF0000) {
Error (NULL, 0, 2000, "Invalid parameter", "Code revision %s out of range!", Argv[1]);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
if (FileList != NULL && FileList->CodeRevision == 0) {
FileList->CodeRevision = (UINT16) CodeRevision;
@@ -1096,7 +1188,8 @@ Returns:
mOptions.Pci23 = 1;
} else {
Error (NULL, 0, 2000, "Invalid parameter", "Invalid option specified: %s", Argv[0]);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
} else {
//
@@ -1105,7 +1198,8 @@ Returns:
//
if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) {
Error (NULL, 0, 2000, "Invalid parameter", "Missing -e or -b with input file %s!", Argv[0]);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
//
// Check Efi Option RomImage
@@ -1119,9 +1213,10 @@ Returns:
FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST));
if (FileList == NULL) {
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
-
+
//
// set flag and class code for this image.
//
@@ -1138,7 +1233,7 @@ Returns:
} else {
if (PrevFileList == NULL) {
PrevFileList = FileList;
- } else {
+ } else {
PrevFileList->Next = FileList;
}
}
@@ -1157,6 +1252,9 @@ Returns:
//
if (Options->FileList == NULL) {
Error (NULL, 0, 2000, "Invalid parameter", "Missing input file name!");
+ //
+ // No memory allocation, return directly.
+ //
return STATUS_ERROR;
}
@@ -1166,16 +1264,33 @@ Returns:
if (EfiRomFlag) {
if (!Options->VendIdValid) {
Error (NULL, 0, 2000, "Missing Vendor ID in command line", NULL);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
-
- if (!Options->DevIdValid) {
+
+ if (!Options->DevIdCount) {
Error (NULL, 0, 2000, "Missing Device ID in command line", NULL);
- return STATUS_ERROR;
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
}
}
- return 0;
+ if (Options->DevIdCount > 1 && Options->Pci23) {
+ Error (NULL, 0, 2000, "Invalid parameter", "PCI 3.0 is required when specifying multiple Device IDs");
+ ReturnStatus = STATUS_ERROR;
+ goto Done;
+ }
+
+Done:
+ if (ReturnStatus != 0) {
+ while (Options->FileList != NULL) {
+ FileList = Options->FileList->Next;
+ free (Options->FileList);
+ Options->FileList = FileList;
+ }
+ }
+
+ return ReturnStatus;
}
static
@@ -1186,7 +1301,7 @@ Version (
/*++
Routine Description:
-
+
Print version information for this utility.
Arguments:
@@ -1200,7 +1315,7 @@ Returns:
{
fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
}
-
+
static
void
Usage (
@@ -1209,7 +1324,7 @@ Usage (
/*++
Routine Description:
-
+
Print usage information for this utility.
Arguments:
@@ -1226,11 +1341,11 @@ Returns:
// Summary usage
//
fprintf (stdout, "Usage: %s -f VendorId -i DeviceId [options] [file name] \n\n", UTILITY_NAME);
-
+
//
// Copyright declaration
- //
- fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
//
// Details Option
@@ -1251,7 +1366,7 @@ Returns:
fprintf (stdout, " -f VendorId\n\
Hex PCI Vendor ID for the device OpROM, must be specified\n");
fprintf (stdout, " -i DeviceId\n\
- Hex PCI Device ID for the device OpROM, must be specified\n");
+ One or more hex PCI Device IDs for the device OpROM, must be specified\n");
fprintf (stdout, " -p, --pci23\n\
Default layout meets PCI 3.0 specifications\n\
specifying this flag will for a PCI 2.3 layout.\n");
@@ -1265,7 +1380,7 @@ Returns:
fprintf (stdout, " -q, --quiet\n\
Disable all messages except FATAL ERRORS.\n");
fprintf (stdout, " --debug [#,0-9]\n\
- Enable debug messages at level #.\n");
+ Enable debug messages at level #.\n");
}
static
@@ -1296,6 +1411,7 @@ Returns:
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr;
PCI_DATA_STRUCTURE PciDs23;
PCI_3_0_DATA_STRUCTURE PciDs30;
+ UINT16 DevId;
//
// Open the input file
@@ -1310,7 +1426,7 @@ Returns:
ImageCount = 0;
for (;;) {
//
- // Save our postition in the file, since offsets in the headers
+ // Save our position in the file, since offsets in the headers
// are relative to the particular image.
//
ImageStart = ftell (InFptr);
@@ -1393,7 +1509,31 @@ Returns:
fprintf (stdout, " Device ID 0x%04X\n", PciDs30.DeviceId);
fprintf (stdout, " Length 0x%04X\n", PciDs30.Length);
fprintf (stdout, " Revision 0x%04X\n", PciDs30.Revision);
- fprintf (stdout, " DeviceListOffset 0x%02X\n", PciDs30.DeviceListOffset);
+ fprintf (stdout, " DeviceListOffset 0x%02X\n", PciDs30.DeviceListOffset);
+ if (PciDs30.DeviceListOffset) {
+ //
+ // Print device ID list
+ //
+ fprintf (stdout, " Device list contents\n");
+ if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs30.DeviceListOffset, SEEK_SET)) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI device ID list!");
+ goto BailOut;
+ }
+
+ //
+ // Loop until terminating 0
+ //
+ do {
+ if (fread (&DevId, sizeof (DevId), 1, InFptr) != 1) {
+ Error (NULL, 0, 3001, "Not supported", "Failed to read PCI device ID list from file %s!", InFile->FileName);
+ goto BailOut;
+ }
+ if (DevId) {
+ fprintf (stdout, " 0x%04X\n", DevId);
+ }
+ } while (DevId);
+
+ }
fprintf (
stdout,
" Class Code 0x%06X\n",
@@ -1403,8 +1543,8 @@ Returns:
fprintf (stdout, " Code revision: 0x%04X\n", PciDs30.CodeRevision);
fprintf (stdout, " MaxRuntimeImageLength 0x%02X\n", PciDs30.MaxRuntimeImageLength);
fprintf (stdout, " ConfigUtilityCodeHeaderOffset 0x%02X\n", PciDs30.ConfigUtilityCodeHeaderOffset);
- fprintf (stdout, " DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset);
- fprintf (stdout, " Indicator 0x%02X", PciDs30.Indicator);
+ fprintf (stdout, " DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset);
+ fprintf (stdout, " Indicator 0x%02X", PciDs30.Indicator);
}
//
// Print the indicator, used to flag the last image
@@ -1420,7 +1560,7 @@ Returns:
if (mOptions.Pci23 == 1) {
fprintf (stdout, " Code type 0x%02X", PciDs23.CodeType);
} else {
- fprintf (stdout, " Code type 0x%02X", PciDs30.CodeType);
+ fprintf (stdout, " Code type 0x%02X", PciDs30.CodeType);
}
if (PciDs23.CodeType == PCI_CODE_TYPE_EFI_IMAGE || PciDs30.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {
fprintf (stdout, " (EFI image)\n");