VerboseMsg("Processing EFI file %s\n", FList->FileName);\r
}\r
\r
- Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size);\r
+ Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevIdList[0], &Size);\r
} else if ((FList->FileFlags & FILE_FLAG_BINARY) !=0 ) {\r
if (mOptions.Verbose) {\r
VerboseMsg("Processing binary file %s\n", FList->FileName);\r
free (mOptions.FileList);\r
mOptions.FileList = FList;\r
}\r
- }\r
\r
+ //\r
+ // Clean up device ID list\r
+ //\r
+ if (mOptions.DevIdList != NULL) {\r
+ free (mOptions.DevIdList);\r
+ }\r
+ }\r
if (FptrOut != NULL) {\r
fclose (FptrOut);\r
}\r
UINT32 HeaderPadBytes;\r
UINT32 PadBytesBeforeImage;\r
UINT32 PadBytesAfterImage;\r
+ UINT32 DevIdListSize;\r
\r
//\r
// Try to open the input file\r
if (mOptions.Pci23 == 1) {\r
HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);\r
} else {\r
- HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);\r
+ if (mOptions.DevIdCount > 1) {\r
+ //\r
+ // Write device ID list when more than one device ID is specified.\r
+ // Leave space for list plus terminator.\r
+ //\r
+ DevIdListSize = (mOptions.DevIdCount + 1) * sizeof (UINT16);\r
+ } else {\r
+ DevIdListSize = 0;\r
+ }\r
+ HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + DevIdListSize + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);\r
}\r
\r
if (mOptions.Verbose) {\r
PciDs30.Signature = PCI_DATA_STRUCTURE_SIGNATURE;\r
PciDs30.VendorId = VendId;\r
PciDs30.DeviceId = DevId;\r
- PciDs30.DeviceListOffset = 0; // to be fixed\r
+ if (mOptions.DevIdCount > 1) {\r
+ //\r
+ // Place device list immediately after PCI structure\r
+ //\r
+ PciDs30.DeviceListOffset = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);\r
+ } else {\r
+ PciDs30.DeviceListOffset = 0;\r
+ }\r
PciDs30.Length = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);\r
PciDs30.Revision = 0x3;\r
//\r
} \r
}\r
\r
+ //\r
+ // Write the Device ID list to the output file\r
+ //\r
+ if (mOptions.DevIdCount > 1) {\r
+ if (fwrite (mOptions.DevIdList, sizeof (UINT16), mOptions.DevIdCount, OutFptr) != mOptions.DevIdCount) {\r
+ Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);\r
+ Status = STATUS_ERROR;\r
+ goto BailOut;\r
+ }\r
+ //\r
+ // Write two-byte terminating 0 at the end of the device list\r
+ //\r
+ if (putc (0, OutFptr) == EOF || putc (0, OutFptr) == EOF) {\r
+ Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);\r
+ Status = STATUS_ERROR;\r
+ goto BailOut;\r
+ }\r
+ }\r
+\r
+\r
//\r
// Pad head to make it a multiple of 512 bytes\r
//\r
INTN ReturnStatus;\r
BOOLEAN EfiRomFlag;\r
UINT64 TempValue;\r
+ char *OptionName;\r
+ UINT16 *DevIdList;\r
\r
ReturnStatus = 0;\r
FileFlags = 0;\r
//\r
FileList = PrevFileList = NULL;\r
\r
+ Options->DevIdList = NULL;\r
+ Options->DevIdCount = 0;\r
+\r
ClassCode = 0;\r
CodeRevision = 0;\r
//\r
Argv++;\r
Argc--;\r
} else if (stricmp (Argv[0], "-i") == 0) {\r
+\r
+ OptionName = Argv[0];\r
+\r
//\r
- // Device ID specified with -i\r
- // Make sure there's another parameter\r
+ // Device IDs specified with -i\r
+ // Make sure there's at least one more parameter\r
//\r
- Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);\r
+ if (Argc < 1) {\r
+ Error (NULL, 0, 2000, "Invalid parameter", "Missing Device Id with %s option!", OptionName);\r
ReturnStatus = 1;\r
goto Done;\r
}\r
- if (TempValue >= 0x10000) {\r
- Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);\r
- ReturnStatus = 1;\r
- goto Done;\r
+\r
+ //\r
+ // Process until another dash-argument parameter or the end of the list\r
+ //\r
+ while (Argc > 1 && Argv[1][0] != '-') {\r
+ Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 2000, "Invalid option value", "%s = %s", OptionName, Argv[1]);\r
+ ReturnStatus = 1;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Don't allow device IDs greater than 16 bits\r
+ // Don't allow 0, since it is used as a list terminator\r
+ //\r
+ if (TempValue >= 0x10000 || TempValue == 0) {\r
+ Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);\r
+ ReturnStatus = 1;\r
+ goto Done;\r
+ }\r
+\r
+ DevIdList = (UINT16*) realloc (Options->DevIdList, (Options->DevIdCount + 1) * sizeof (UINT16));\r
+ if (DevIdList == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);\r
+ ReturnStatus = 1;\r
+ goto Done;\r
+ }\r
+ Options->DevIdList = DevIdList;\r
+\r
+ Options->DevIdList[Options->DevIdCount++] = (UINT16) TempValue;\r
+\r
+ Argv++;\r
+ Argc--;\r
}\r
- Options->DevId = (UINT16) TempValue;\r
- Options->DevIdValid = 1;\r
\r
- Argv++;\r
- Argc--;\r
} else if ((stricmp (Argv[0], "-o") == 0) || (stricmp (Argv[0], "--output") == 0)) {\r
//\r
// Output filename specified with -o\r
Options->DumpOption = 1;\r
\r
Options->VendIdValid = 1;\r
- Options->DevIdValid = 1;\r
+ Options->DevIdCount = 1;\r
FileFlags = FILE_FLAG_BINARY;\r
} else if ((stricmp (Argv[0], "-l") == 0) || (stricmp (Argv[0], "--class-code") == 0)) {\r
//\r
goto Done;\r
}\r
\r
- if (!Options->DevIdValid) {\r
+ if (!Options->DevIdCount) {\r
Error (NULL, 0, 2000, "Missing Device ID in command line", NULL);\r
ReturnStatus = STATUS_ERROR;\r
goto Done;\r
}\r
}\r
\r
+ if (Options->DevIdCount > 1 && Options->Pci23) {\r
+ Error (NULL, 0, 2000, "Invalid parameter", "PCI 3.0 is required when specifying multiple Device IDs");\r
+ ReturnStatus = STATUS_ERROR;\r
+ goto Done;\r
+ }\r
+\r
Done:\r
if (ReturnStatus != 0) {\r
while (Options->FileList != NULL) {\r
fprintf (stdout, " -f VendorId\n\\r
Hex PCI Vendor ID for the device OpROM, must be specified\n");\r
fprintf (stdout, " -i DeviceId\n\\r
- Hex PCI Device ID for the device OpROM, must be specified\n");\r
+ One or more hex PCI Device IDs for the device OpROM, must be specified\n");\r
fprintf (stdout, " -p, --pci23\n\\r
Default layout meets PCI 3.0 specifications\n\\r
specifying this flag will for a PCI 2.3 layout.\n");\r
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr;\r
PCI_DATA_STRUCTURE PciDs23;\r
PCI_3_0_DATA_STRUCTURE PciDs30;\r
+ UINT16 DevId;\r
\r
//\r
// Open the input file\r
fprintf (stdout, " Length 0x%04X\n", PciDs30.Length);\r
fprintf (stdout, " Revision 0x%04X\n", PciDs30.Revision);\r
fprintf (stdout, " DeviceListOffset 0x%02X\n", PciDs30.DeviceListOffset); \r
+ if (PciDs30.DeviceListOffset) {\r
+ //\r
+ // Print device ID list\r
+ //\r
+ fprintf (stdout, " Device list contents\n");\r
+ if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs30.DeviceListOffset, SEEK_SET)) {\r
+ Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI device ID list!");\r
+ goto BailOut;\r
+ }\r
+\r
+ //\r
+ // Loop until terminating 0\r
+ //\r
+ do {\r
+ if (fread (&DevId, sizeof (DevId), 1, InFptr) != 1) {\r
+ Error (NULL, 0, 3001, "Not supported", "Failed to read PCI device ID list from file %s!", InFile->FileName);\r
+ goto BailOut;\r
+ }\r
+ if (DevId) {\r
+ fprintf (stdout, " 0x%04X\n", DevId);\r
+ }\r
+ } while (DevId);\r
+\r
+ }\r
fprintf (\r
stdout,\r
" Class Code 0x%06X\n",\r