//\r
// END include differences\r
//\r
-#include "Pci22.h" // for option ROM header structures\r
+#include "Pci.h" // for option ROM header structures\r
//\r
// Version of this utility\r
//\r
-#define UTILITY_VERSION "v2.5"\r
+#define UTILITY_VERSION "v2.6"\r
\r
//\r
// Define some status return values\r
0,\r
NULL\r
};\r
+\r
+static char* mCodeTypeStr[] = {\r
+ "PCAT Image",\r
+ "Open Firmware Image",\r
+ "HP PA RISC Image",\r
+ "EFI Image",\r
+ "Undefined"\r
+};\r
+\r
//\r
// Function prototypes\r
//\r
\r
return Status;\r
}\r
+ \r
+UINT8\r
+CheckSum (\r
+ UINT8 *Buffer, \r
+ UINT32 DataSize,\r
+ UINT32 PaddingSize\r
+ )\r
+/*++\r
+Routine Description:\r
+ Calculate checksum from DataSize of Buffer.\r
+\r
+Arguments:\r
+ Buffer - pointer to data buffer\r
+ DataSize - size of data buffer in bytes\r
+\r
+Return:\r
+ UINT8 - checksum\r
+--*/\r
+{\r
+ UINT8 Checksum = 0;\r
+ while (DataSize-- != 0) {\r
+ Checksum = Checksum + Buffer[DataSize];\r
+ }\r
+ while (PaddingSize-- != 0) {\r
+ Checksum = Checksum + 0xff;\r
+ }\r
+ return Checksum;\r
+}\r
+\r
+char *\r
+GetCodeTypeStr (\r
+ UINT8 CodeType\r
+ )\r
+{\r
+ if (CodeType >= sizeof (mCodeTypeStr) / sizeof (*mCodeTypeStr)) {\r
+ CodeType = sizeof (mCodeTypeStr) / sizeof (*mCodeTypeStr) - 1;\r
+ }\r
+ return mCodeTypeStr[CodeType];\r
+}\r
\r
static\r
int\r
FILE *InFptr;\r
UINT32 TotalSize;\r
UINT32 FileSize;\r
+ UINT32 DataSize;\r
+ UINT32 PaddingSize;\r
UINT8 *Buffer;\r
UINT32 Status;\r
PCI_EXPANSION_ROM_HEADER *RomHdr;\r
PCI_DATA_STRUCTURE *PciDs;\r
- UINT32 Index;\r
UINT8 ByteCheckSum;\r
\r
Status = STATUS_SUCCESS;\r
Status = STATUS_ERROR;\r
goto BailOut;\r
}\r
- //\r
- // Total size must be an even multiple of 512 bytes, and can't exceed\r
- // the option ROM image size.\r
- //\r
- TotalSize = FileSize;\r
- if (TotalSize & 0x1FF) {\r
- TotalSize = (TotalSize + 0x200) &~0x1ff;\r
- }\r
\r
- if (TotalSize > MAX_OPTION_ROM_SIZE) {\r
- fprintf (\r
- stdout,\r
- "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n",\r
- InFile->FileName,\r
- MAX_OPTION_ROM_SIZE\r
- );\r
- Status = STATUS_ERROR;\r
- goto BailOut;\r
- }\r
- //\r
- // Return the size to the caller so they can keep track of the running total.\r
- //\r
- *Size = TotalSize;\r
+ \r
+ RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;\r
+ PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);\r
\r
//\r
// Crude check to make sure it's a legitimate ROM image\r
//\r
- RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer;\r
if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
fprintf (stdout, "ERROR: ROM image file has invalid ROM signature\n");\r
Status = STATUS_ERROR;\r
goto BailOut;\r
}\r
\r
- PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset);\r
if (PciDs->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
fprintf (stdout, "ERROR: PCI data structure has invalid signature\n");\r
Status = STATUS_ERROR;\r
goto BailOut;\r
}\r
+\r
+ if ((UINT32) (PciDs->ImageLength * 512) == FileSize) {\r
+ //\r
+ // ImageLength reflects the actual file size correctly.\r
+ //\r
+ DataSize = FileSize - 1;\r
+ PaddingSize = 0;\r
+ TotalSize = FileSize;\r
+ } else {\r
+ //\r
+ // ImageLength doesn't reflect the actual file size,\r
+ // 1). add additional 512 bytes if actual file size is multiple of 512\r
+ // 2). add additional X (X <= 512) bytes so that the result size is multiple of 512\r
+ //\r
+ fprintf (stdout, "WARNING: ImageLength in PCI data structure != Actual File Size\n"\r
+ " --> add additional padding bytes\n"\r
+ " --> adjust ImageLength\n"\r
+ );\r
+ TotalSize = (FileSize + 0x200) & ~0x1ff;\r
+ DataSize = FileSize;\r
+ PaddingSize = TotalSize - DataSize - 1;\r
+ PciDs->ImageLength = (UINT16) (TotalSize / 512);\r
+ }\r
+\r
+ //\r
+ // Check size\r
+ //\r
+ if (TotalSize > MAX_OPTION_ROM_SIZE) {\r
+ fprintf (\r
+ stdout,\r
+ "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n",\r
+ InFile->FileName,\r
+ MAX_OPTION_ROM_SIZE\r
+ );\r
+ Status = STATUS_ERROR;\r
+ goto BailOut;\r
+ }\r
+\r
+ //\r
+ // Return the size to the caller so they can keep track of the running total.\r
+ //\r
+ *Size = TotalSize;\r
+\r
//\r
// If this is the last image, then set the LAST bit unless requested not\r
// to via the command-line -l argument. Otherwise, make sure you clear it.\r
//\r
if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {\r
- PciDs->Indicator = INDICATOR_LAST;\r
+ PciDs->Indicator |= INDICATOR_LAST;\r
} else {\r
- PciDs->Indicator = 0;\r
+ PciDs->Indicator &= ~INDICATOR_LAST;\r
}\r
\r
- ByteCheckSum = 0;\r
- for (Index = 0; Index < FileSize - 1; Index++) {\r
- ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]);\r
- }\r
-\r
- Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1);\r
- fprintf (stdout, "CheckSUm = %02x\n", (UINT32) Buffer[FileSize - 1]);\r
+ ByteCheckSum = -CheckSum (Buffer, DataSize, PaddingSize);\r
\r
- //\r
- // Now copy the input file contents out to the output file\r
- //\r
- if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {\r
+ if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) {\r
fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n");\r
Status = STATUS_ERROR;\r
goto BailOut;\r
}\r
\r
- TotalSize -= FileSize;\r
- //\r
- // Pad the rest of the image to make it a multiple of 512 bytes\r
- //\r
- while (TotalSize > 0) {\r
+ while (PaddingSize-- != 0) {\r
putc (~0, OutFptr);\r
- TotalSize--;\r
}\r
+ putc (ByteCheckSum, OutFptr);\r
\r
BailOut:\r
if (InFptr != NULL) {\r
//\r
// Total size must be an even multiple of 512 bytes\r
//\r
- if (TotalSize & 0x1FF) {\r
- TotalSize = (TotalSize + 0x200) &~0x1ff;\r
- }\r
+ TotalSize = (TotalSize + 0x1ff) & ~0x1ff;\r
+\r
//\r
// Check size\r
//\r
// to via the command-line -l argument.\r
//\r
if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {\r
- PciDs.Indicator = INDICATOR_LAST;\r
+ PciDs.Indicator |= INDICATOR_LAST;\r
}\r
//\r
// Write the ROM header to the output file\r
//\r
// Specify binary files with -b\r
//\r
- FileFlags = (FileFlags &~FILE_FLAG_EFI) | FILE_FLAG_BINARY;\r
+ FileFlags = (FileFlags & ~FILE_FLAG_EFI) | FILE_FLAG_BINARY;\r
} else if ((_stricmp (Argv[0], "-e") == 0) || (_stricmp (Argv[0], "-ec") == 0)) {\r
//\r
// Specify EFI files with -e. Specify EFI-compressed with -ec.\r
" the following FileName",\r
" -dump - to dump the headers of an existing option ROM image",\r
"",\r
- "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ",\r
+ "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi",\r
"",\r
NULL\r
};\r
FILE *InFptr;\r
UINT32 ImageStart;\r
UINT32 ImageCount;\r
+ UINT16 DeviceId;\r
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr;\r
- PCI_DATA_STRUCTURE PciDs;\r
+ PCI_3_0_DATA_STRUCTURE PciDs;\r
\r
//\r
// Open the input file\r
);\r
fprintf (stdout, " Vendor ID 0x%04X\n", PciDs.VendorId);\r
fprintf (stdout, " Device ID 0x%04X\n", PciDs.DeviceId);\r
+ fprintf (stdout, " Structure Length 0x%04X\n", PciDs.Length);\r
+ fprintf (stdout, " PCI Revision 0x%02X\n", PciDs.Revision);\r
fprintf (\r
stdout,\r
" Class Code 0x%06X\n",\r
(UINT32) (PciDs.ClassCode[0] | (PciDs.ClassCode[1] << 8) | (PciDs.ClassCode[2] << 16))\r
);\r
fprintf (stdout, " Image size 0x%X\n", PciDs.ImageLength * 512);\r
- fprintf (stdout, " Code revision: 0x%04X\n", PciDs.CodeRevision);\r
+ fprintf (stdout, " Code revision 0x%04X\n", PciDs.CodeRevision);\r
fprintf (stdout, " Indicator 0x%02X", (UINT32) PciDs.Indicator);\r
//\r
// Print the indicator, used to flag the last image\r
//\r
- if (PciDs.Indicator == INDICATOR_LAST) {\r
+ if ((PciDs.Indicator & INDICATOR_LAST) == INDICATOR_LAST) {\r
fprintf (stdout, " (last image)\n");\r
} else {\r
fprintf (stdout, "\n");\r
}\r
+\r
//\r
// Print the code type. If EFI code, then we can provide more info.\r
//\r
- fprintf (stdout, " Code type 0x%02X", (UINT32) PciDs.CodeType);\r
+ fprintf (stdout, " Code type 0x%02X (%s)\n", (UINT32) PciDs.CodeType, GetCodeTypeStr (PciDs.CodeType));\r
if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
- fprintf (stdout, " (EFI image)\n");\r
//\r
// Re-read the header as an EFI ROM header, then dump more info\r
//\r
fprintf (stdout, " EFI ROM header contents\n");\r
- if (fseek (InFptr, ImageStart, SEEK_SET)) {\r
- fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n");\r
- goto BailOut;\r
- }\r
-\r
- if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) {\r
- fprintf (stdout, "ERROR: Failed to read EFI PCI ROM header from file\n");\r
- goto BailOut;\r
- }\r
+ memcpy (&EfiRomHdr, &PciRomHdr, sizeof (EfiRomHdr));\r
//\r
// Now dump more info\r
//\r
(UINT32) EfiRomHdr.EfiImageHeaderOffset,\r
(UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart)\r
);\r
-\r
- } else {\r
- //\r
- // Not an EFI image\r
- //\r
- fprintf (stdout, "\n");\r
}\r
+\r
//\r
- // If code type is EFI image, then dump it as well?\r
+ // Dump additional information for PCI 3.0 OpROM\r
//\r
- // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
- // }\r
+ if (PciDs.Revision >= 3) {\r
+ fprintf (stdout, " Extended for PCI 3.0\n");\r
+ \r
+ if (PciDs.DeviceListOffset != 0) {\r
+ if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs.DeviceListOffset, SEEK_SET)) {\r
+ fprintf (stdout, "ERROR: Failed to seek to supported Device List\n");\r
+ goto BailOut;\r
+ }\r
+ fprintf (stdout, " Device ID List ");\r
+ while (TRUE) {\r
+ if (fread (&DeviceId, sizeof (DeviceId), 1, InFptr) != 1) {\r
+ fprintf (stdout, "ERROR: Failed to read supported DeviceId from DeviceId List\n");\r
+ goto BailOut;\r
+ }\r
+ if (DeviceId == 0) {\r
+ break;\r
+ }\r
+ fprintf (stdout, "0x%04X ", DeviceId);\r
+ }\r
+ fprintf (stdout, "\n");\r
+ }\r
+ fprintf (stdout, " Max Runtime Image Length 0x%08X\n", PciDs.MaxRuntimeImageLength * 512);\r
+ if (PciDs.Length == sizeof (PCI_3_0_DATA_STRUCTURE)) {\r
+ fprintf (stdout, " Config Utility Header 0x%04X\n", PciDs.ConfigUtilityCodeHeaderOffset);\r
+ fprintf (stdout, " DMTF CLP Entry Point 0x%04X\n", PciDs.DMTFCLPEntryPointOffset);\r
+ } else {\r
+ fprintf (stdout, "WARNING: Oprom declars 3.0 revision with wrong structure length 0x%04X\n", PciDs.Length);\r
+ }\r
+ }\r
+\r
//\r
// If last image, then we're done\r
//\r
- if (PciDs.Indicator == INDICATOR_LAST) {\r
+ if ((PciDs.Indicator & INDICATOR_LAST) == INDICATOR_LAST) {\r
goto BailOut;\r
}\r
//\r
\r
return "unknown";\r
}\r
+\r