EfiRom.c revision 1be2ed90a20618d71ddf34b8a07d038da0b36854
130fdf1140b8d1ce93f3821d986fa165552023440lgao/** @file 230fdf1140b8d1ce93f3821d986fa165552023440lgao 31be2ed90a20618d71ddf34b8a07d038da0b36854Hess ChenCopyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR> 430fdf1140b8d1ce93f3821d986fa165552023440lgaoThis program and the accompanying materials are licensed and made available 530fdf1140b8d1ce93f3821d986fa165552023440lgaounder the terms and conditions of the BSD License which accompanies this 630fdf1140b8d1ce93f3821d986fa165552023440lgaodistribution. The full text of the license may be found at 730fdf1140b8d1ce93f3821d986fa165552023440lgaohttp://opensource.org/licenses/bsd-license.php 830fdf1140b8d1ce93f3821d986fa165552023440lgao 930fdf1140b8d1ce93f3821d986fa165552023440lgaoTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1030fdf1140b8d1ce93f3821d986fa165552023440lgaoWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1130fdf1140b8d1ce93f3821d986fa165552023440lgao 1230fdf1140b8d1ce93f3821d986fa165552023440lgaoModule Name: 1330fdf1140b8d1ce93f3821d986fa165552023440lgao 1430fdf1140b8d1ce93f3821d986fa165552023440lgao EfiRom.c 1530fdf1140b8d1ce93f3821d986fa165552023440lgao 1630fdf1140b8d1ce93f3821d986fa165552023440lgaoAbstract: 1730fdf1140b8d1ce93f3821d986fa165552023440lgao 1830fdf1140b8d1ce93f3821d986fa165552023440lgao Utility program to create an EFI option ROM image from binary and 1930fdf1140b8d1ce93f3821d986fa165552023440lgao EFI PE32 files. 2030fdf1140b8d1ce93f3821d986fa165552023440lgao 2130fdf1140b8d1ce93f3821d986fa165552023440lgao**/ 2230fdf1140b8d1ce93f3821d986fa165552023440lgao 2330fdf1140b8d1ce93f3821d986fa165552023440lgao#include "EfiUtilityMsgs.h" 2430fdf1140b8d1ce93f3821d986fa165552023440lgao#include "ParseInf.h" 2530fdf1140b8d1ce93f3821d986fa165552023440lgao#include "EfiRom.h" 2630fdf1140b8d1ce93f3821d986fa165552023440lgao 2730fdf1140b8d1ce93f3821d986fa165552023440lgaoUINT64 DebugLevel = 0; 2830fdf1140b8d1ce93f3821d986fa165552023440lgao 2930fdf1140b8d1ce93f3821d986fa165552023440lgaoint 3030fdf1140b8d1ce93f3821d986fa165552023440lgaomain ( 3130fdf1140b8d1ce93f3821d986fa165552023440lgao int Argc, 3230fdf1140b8d1ce93f3821d986fa165552023440lgao char *Argv[] 3330fdf1140b8d1ce93f3821d986fa165552023440lgao ) 3430fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 3530fdf1140b8d1ce93f3821d986fa165552023440lgao 3630fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 3730fdf1140b8d1ce93f3821d986fa165552023440lgao 3830fdf1140b8d1ce93f3821d986fa165552023440lgao Given an EFI image filename, create a ROM-able image by creating an option 3930fdf1140b8d1ce93f3821d986fa165552023440lgao ROM header and PCI data structure, filling them in, and then writing the 4030fdf1140b8d1ce93f3821d986fa165552023440lgao option ROM header + PCI data structure + EFI image out to the output file. 4130fdf1140b8d1ce93f3821d986fa165552023440lgao 4230fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 4330fdf1140b8d1ce93f3821d986fa165552023440lgao 4430fdf1140b8d1ce93f3821d986fa165552023440lgao Argc - standard C main() argument count 4530fdf1140b8d1ce93f3821d986fa165552023440lgao 4630fdf1140b8d1ce93f3821d986fa165552023440lgao Argv - standard C main() argument list 4730fdf1140b8d1ce93f3821d986fa165552023440lgao 4830fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 4930fdf1140b8d1ce93f3821d986fa165552023440lgao 5030fdf1140b8d1ce93f3821d986fa165552023440lgao 0 success 5130fdf1140b8d1ce93f3821d986fa165552023440lgao non-zero otherwise 5230fdf1140b8d1ce93f3821d986fa165552023440lgao 5330fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 5430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 5530fdf1140b8d1ce93f3821d986fa165552023440lgao CHAR8 *Ext; 5630fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *FptrOut; 5730fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 Status; 5830fdf1140b8d1ce93f3821d986fa165552023440lgao FILE_LIST *FList; 5930fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 TotalSize; 6030fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 Size; 6130fdf1140b8d1ce93f3821d986fa165552023440lgao CHAR8 *Ptr0; 6230fdf1140b8d1ce93f3821d986fa165552023440lgao 6330fdf1140b8d1ce93f3821d986fa165552023440lgao SetUtilityName(UTILITY_NAME); 6430fdf1140b8d1ce93f3821d986fa165552023440lgao 6530fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_SUCCESS; 6630fdf1140b8d1ce93f3821d986fa165552023440lgao FptrOut = NULL; 6730fdf1140b8d1ce93f3821d986fa165552023440lgao 6830fdf1140b8d1ce93f3821d986fa165552023440lgao // 6930fdf1140b8d1ce93f3821d986fa165552023440lgao // Parse the command line arguments 7030fdf1140b8d1ce93f3821d986fa165552023440lgao // 7130fdf1140b8d1ce93f3821d986fa165552023440lgao if (ParseCommandLine (Argc, Argv, &mOptions)) { 7230fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 7330fdf1140b8d1ce93f3821d986fa165552023440lgao } 7430fdf1140b8d1ce93f3821d986fa165552023440lgao 7530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Quiet) { 7630fdf1140b8d1ce93f3821d986fa165552023440lgao SetPrintLevel(40); 7730fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (mOptions.Verbose) { 7830fdf1140b8d1ce93f3821d986fa165552023440lgao SetPrintLevel(15); 7930fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (mOptions.Debug) { 8030fdf1140b8d1ce93f3821d986fa165552023440lgao SetPrintLevel(DebugLevel); 8130fdf1140b8d1ce93f3821d986fa165552023440lgao } 8230fdf1140b8d1ce93f3821d986fa165552023440lgao 8330fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 8430fdf1140b8d1ce93f3821d986fa165552023440lgao VerboseMsg("%s tool start.\n", UTILITY_NAME); 8530fdf1140b8d1ce93f3821d986fa165552023440lgao } 8630fdf1140b8d1ce93f3821d986fa165552023440lgao 8730fdf1140b8d1ce93f3821d986fa165552023440lgao // 8830fdf1140b8d1ce93f3821d986fa165552023440lgao // If dumping an image, then do that and quit 8930fdf1140b8d1ce93f3821d986fa165552023440lgao // 9030fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.DumpOption == 1) { 91fd171542e0aa89ac12a09d79608173f48019b14bvanjeff if (mOptions.FileList != NULL) { 92fd171542e0aa89ac12a09d79608173f48019b14bvanjeff if ((Ptr0 = strstr ((CONST CHAR8 *) mOptions.FileList->FileName, DEFAULT_OUTPUT_EXTENSION)) != NULL) { 9330fdf1140b8d1ce93f3821d986fa165552023440lgao DumpImage (mOptions.FileList); 9430fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 9530fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 9630fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 1002, "No PciRom input file", "No *.rom input file"); 9730fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 9830fdf1140b8d1ce93f3821d986fa165552023440lgao } 9930fdf1140b8d1ce93f3821d986fa165552023440lgao } 10030fdf1140b8d1ce93f3821d986fa165552023440lgao } 10130fdf1140b8d1ce93f3821d986fa165552023440lgao // 10230fdf1140b8d1ce93f3821d986fa165552023440lgao // Determine the output filename. Either what they specified on 10330fdf1140b8d1ce93f3821d986fa165552023440lgao // the command line, or the first input filename with a different extension. 10430fdf1140b8d1ce93f3821d986fa165552023440lgao // 10530fdf1140b8d1ce93f3821d986fa165552023440lgao if (!mOptions.OutFileName[0]) { 10630fdf1140b8d1ce93f3821d986fa165552023440lgao strcpy (mOptions.OutFileName, mOptions.FileList->FileName); 10730fdf1140b8d1ce93f3821d986fa165552023440lgao // 10830fdf1140b8d1ce93f3821d986fa165552023440lgao // Find the last . on the line and replace the filename extension with 10930fdf1140b8d1ce93f3821d986fa165552023440lgao // the default 11030fdf1140b8d1ce93f3821d986fa165552023440lgao // 11130fdf1140b8d1ce93f3821d986fa165552023440lgao for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; 11230fdf1140b8d1ce93f3821d986fa165552023440lgao (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); 11330fdf1140b8d1ce93f3821d986fa165552023440lgao Ext-- 11430fdf1140b8d1ce93f3821d986fa165552023440lgao ) 11530fdf1140b8d1ce93f3821d986fa165552023440lgao ; 11630fdf1140b8d1ce93f3821d986fa165552023440lgao // 11730fdf1140b8d1ce93f3821d986fa165552023440lgao // If dot here, then insert extension here, otherwise append 11830fdf1140b8d1ce93f3821d986fa165552023440lgao // 11930fdf1140b8d1ce93f3821d986fa165552023440lgao if (*Ext != '.') { 12030fdf1140b8d1ce93f3821d986fa165552023440lgao Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); 12130fdf1140b8d1ce93f3821d986fa165552023440lgao } 12230fdf1140b8d1ce93f3821d986fa165552023440lgao 12330fdf1140b8d1ce93f3821d986fa165552023440lgao strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); 12430fdf1140b8d1ce93f3821d986fa165552023440lgao } 12530fdf1140b8d1ce93f3821d986fa165552023440lgao // 12630fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure we don't have the same filename for input and output files 12730fdf1140b8d1ce93f3821d986fa165552023440lgao // 12830fdf1140b8d1ce93f3821d986fa165552023440lgao for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) { 12930fdf1140b8d1ce93f3821d986fa165552023440lgao if (stricmp (mOptions.OutFileName, FList->FileName) == 0) { 13030fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 13130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 1002, "Invalid input paramter", "Input and output file names must be different - %s = %s.", FList->FileName, mOptions.OutFileName); 13230fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 13330fdf1140b8d1ce93f3821d986fa165552023440lgao } 13430fdf1140b8d1ce93f3821d986fa165552023440lgao } 13530fdf1140b8d1ce93f3821d986fa165552023440lgao // 13630fdf1140b8d1ce93f3821d986fa165552023440lgao // Now open our output file 13730fdf1140b8d1ce93f3821d986fa165552023440lgao // 1381be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chen if ((FptrOut = fopen (LongFilePath (mOptions.OutFileName), "wb")) == NULL) { 13930fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0001, "Error opening file", "Error opening file %s", mOptions.OutFileName); 14030fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 14130fdf1140b8d1ce93f3821d986fa165552023440lgao } 14230fdf1140b8d1ce93f3821d986fa165552023440lgao // 14330fdf1140b8d1ce93f3821d986fa165552023440lgao // Process all our files 14430fdf1140b8d1ce93f3821d986fa165552023440lgao // 14530fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize = 0; 14630fdf1140b8d1ce93f3821d986fa165552023440lgao for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) { 14730fdf1140b8d1ce93f3821d986fa165552023440lgao Size = 0; 14830fdf1140b8d1ce93f3821d986fa165552023440lgao if ((FList->FileFlags & FILE_FLAG_EFI) != 0) { 14930fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 15030fdf1140b8d1ce93f3821d986fa165552023440lgao VerboseMsg("Processing EFI file %s\n", FList->FileName); 15130fdf1140b8d1ce93f3821d986fa165552023440lgao } 15230fdf1140b8d1ce93f3821d986fa165552023440lgao 15330fdf1140b8d1ce93f3821d986fa165552023440lgao Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size); 15430fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((FList->FileFlags & FILE_FLAG_BINARY) !=0 ) { 15530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 15630fdf1140b8d1ce93f3821d986fa165552023440lgao VerboseMsg("Processing binary file %s\n", FList->FileName); 15730fdf1140b8d1ce93f3821d986fa165552023440lgao } 15830fdf1140b8d1ce93f3821d986fa165552023440lgao 15930fdf1140b8d1ce93f3821d986fa165552023440lgao Status = ProcessBinFile (FptrOut, FList, &Size); 16030fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 16130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "File type not specified, it must be either an EFI or binary file: %s.", FList->FileName); 16230fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 16330fdf1140b8d1ce93f3821d986fa165552023440lgao } 16430fdf1140b8d1ce93f3821d986fa165552023440lgao 16530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 166fd171542e0aa89ac12a09d79608173f48019b14bvanjeff VerboseMsg(" Output size = 0x%X\n", (unsigned) Size); 16730fdf1140b8d1ce93f3821d986fa165552023440lgao } 16830fdf1140b8d1ce93f3821d986fa165552023440lgao 16930fdf1140b8d1ce93f3821d986fa165552023440lgao if (Status != STATUS_SUCCESS) { 17030fdf1140b8d1ce93f3821d986fa165552023440lgao break; 17130fdf1140b8d1ce93f3821d986fa165552023440lgao } 17230fdf1140b8d1ce93f3821d986fa165552023440lgao 17330fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize += Size; 17430fdf1140b8d1ce93f3821d986fa165552023440lgao } 17530fdf1140b8d1ce93f3821d986fa165552023440lgao // 17630fdf1140b8d1ce93f3821d986fa165552023440lgao // Check total size 17730fdf1140b8d1ce93f3821d986fa165552023440lgao // 17830fdf1140b8d1ce93f3821d986fa165552023440lgao if (TotalSize > MAX_OPTION_ROM_SIZE) { 17930fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid paramter", "Option ROM image size exceeds limit of 0x%X bytes.", MAX_OPTION_ROM_SIZE); 18030fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 18130fdf1140b8d1ce93f3821d986fa165552023440lgao } 18230fdf1140b8d1ce93f3821d986fa165552023440lgao 18330fdf1140b8d1ce93f3821d986fa165552023440lgaoBailOut: 18430fdf1140b8d1ce93f3821d986fa165552023440lgao if (Status == STATUS_SUCCESS) { 18530fdf1140b8d1ce93f3821d986fa165552023440lgao if (FptrOut != NULL) { 18630fdf1140b8d1ce93f3821d986fa165552023440lgao fclose (FptrOut); 18730fdf1140b8d1ce93f3821d986fa165552023440lgao } 18830fdf1140b8d1ce93f3821d986fa165552023440lgao // 18930fdf1140b8d1ce93f3821d986fa165552023440lgao // Clean up our file list 19030fdf1140b8d1ce93f3821d986fa165552023440lgao // 19130fdf1140b8d1ce93f3821d986fa165552023440lgao while (mOptions.FileList != NULL) { 19230fdf1140b8d1ce93f3821d986fa165552023440lgao FList = mOptions.FileList->Next; 19330fdf1140b8d1ce93f3821d986fa165552023440lgao free (mOptions.FileList); 19430fdf1140b8d1ce93f3821d986fa165552023440lgao mOptions.FileList = FList; 19530fdf1140b8d1ce93f3821d986fa165552023440lgao } 19630fdf1140b8d1ce93f3821d986fa165552023440lgao } 19730fdf1140b8d1ce93f3821d986fa165552023440lgao 19830fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 19930fdf1140b8d1ce93f3821d986fa165552023440lgao VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ()); 20030fdf1140b8d1ce93f3821d986fa165552023440lgao } 20130fdf1140b8d1ce93f3821d986fa165552023440lgao 20230fdf1140b8d1ce93f3821d986fa165552023440lgao return GetUtilityStatus (); 20330fdf1140b8d1ce93f3821d986fa165552023440lgao} 20430fdf1140b8d1ce93f3821d986fa165552023440lgao 20530fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 20630fdf1140b8d1ce93f3821d986fa165552023440lgaoint 20730fdf1140b8d1ce93f3821d986fa165552023440lgaoProcessBinFile ( 20830fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *OutFptr, 20930fdf1140b8d1ce93f3821d986fa165552023440lgao FILE_LIST *InFile, 21030fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 *Size 21130fdf1140b8d1ce93f3821d986fa165552023440lgao ) 21230fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 21330fdf1140b8d1ce93f3821d986fa165552023440lgao 21430fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 21530fdf1140b8d1ce93f3821d986fa165552023440lgao 21630fdf1140b8d1ce93f3821d986fa165552023440lgao Process a binary input file. 21730fdf1140b8d1ce93f3821d986fa165552023440lgao 21830fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 21930fdf1140b8d1ce93f3821d986fa165552023440lgao 22030fdf1140b8d1ce93f3821d986fa165552023440lgao OutFptr - file pointer to output binary ROM image file we're creating 22130fdf1140b8d1ce93f3821d986fa165552023440lgao InFile - structure contains information on the binary file to process 22230fdf1140b8d1ce93f3821d986fa165552023440lgao Size - pointer to where to return the size added to the output file 22330fdf1140b8d1ce93f3821d986fa165552023440lgao 22430fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 22530fdf1140b8d1ce93f3821d986fa165552023440lgao 22630fdf1140b8d1ce93f3821d986fa165552023440lgao 0 - successful 22730fdf1140b8d1ce93f3821d986fa165552023440lgao 22830fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 22930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 23030fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *InFptr; 23130fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 TotalSize; 23230fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 FileSize; 23330fdf1140b8d1ce93f3821d986fa165552023440lgao UINT8 *Buffer; 23430fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 Status; 23530fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_EXPANSION_ROM_HEADER *RomHdr; 23630fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_DATA_STRUCTURE *PciDs23; 23730fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_3_0_DATA_STRUCTURE *PciDs30; 23830fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 Index; 23930fdf1140b8d1ce93f3821d986fa165552023440lgao UINT8 ByteCheckSum; 2402bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming UINT16 CodeType; 24130fdf1140b8d1ce93f3821d986fa165552023440lgao 242fd171542e0aa89ac12a09d79608173f48019b14bvanjeff PciDs23 = NULL; 243fd171542e0aa89ac12a09d79608173f48019b14bvanjeff PciDs30 = NULL; 24430fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_SUCCESS; 24530fdf1140b8d1ce93f3821d986fa165552023440lgao 24630fdf1140b8d1ce93f3821d986fa165552023440lgao // 24730fdf1140b8d1ce93f3821d986fa165552023440lgao // Try to open the input file 24830fdf1140b8d1ce93f3821d986fa165552023440lgao // 2491be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chen if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) { 25030fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0001, "Error opening file", InFile->FileName); 25130fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 25230fdf1140b8d1ce93f3821d986fa165552023440lgao } 25330fdf1140b8d1ce93f3821d986fa165552023440lgao // 25430fdf1140b8d1ce93f3821d986fa165552023440lgao // Seek to the end of the input file and get the file size. Then allocate 25530fdf1140b8d1ce93f3821d986fa165552023440lgao // a buffer to read it in to. 25630fdf1140b8d1ce93f3821d986fa165552023440lgao // 25730fdf1140b8d1ce93f3821d986fa165552023440lgao fseek (InFptr, 0, SEEK_END); 25830fdf1140b8d1ce93f3821d986fa165552023440lgao FileSize = ftell (InFptr); 25930fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 260fd171542e0aa89ac12a09d79608173f48019b14bvanjeff VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize); 26130fdf1140b8d1ce93f3821d986fa165552023440lgao } 26230fdf1140b8d1ce93f3821d986fa165552023440lgao 26330fdf1140b8d1ce93f3821d986fa165552023440lgao fseek (InFptr, 0, SEEK_SET); 26430fdf1140b8d1ce93f3821d986fa165552023440lgao Buffer = (UINT8 *) malloc (FileSize); 26530fdf1140b8d1ce93f3821d986fa165552023440lgao if (Buffer == NULL) { 26630fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 4003, "Resource", "memory cannot be allocated!"); 26730fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 26830fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 26930fdf1140b8d1ce93f3821d986fa165552023440lgao } 27030fdf1140b8d1ce93f3821d986fa165552023440lgao 27130fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (Buffer, FileSize, 1, InFptr) != 1) { 27230fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid", "Failed to read all bytes from input file."); 27330fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 27430fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 27530fdf1140b8d1ce93f3821d986fa165552023440lgao } 27630fdf1140b8d1ce93f3821d986fa165552023440lgao // 27730fdf1140b8d1ce93f3821d986fa165552023440lgao // Total size must be an even multiple of 512 bytes, and can't exceed 27830fdf1140b8d1ce93f3821d986fa165552023440lgao // the option ROM image size. 27930fdf1140b8d1ce93f3821d986fa165552023440lgao // 28030fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize = FileSize; 28130fdf1140b8d1ce93f3821d986fa165552023440lgao if (TotalSize & 0x1FF) { 28230fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize = (TotalSize + 0x200) &~0x1ff; 28330fdf1140b8d1ce93f3821d986fa165552023440lgao } 28430fdf1140b8d1ce93f3821d986fa165552023440lgao 28530fdf1140b8d1ce93f3821d986fa165552023440lgao if (TotalSize > MAX_OPTION_ROM_SIZE) { 28630fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE); 28730fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 28830fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 28930fdf1140b8d1ce93f3821d986fa165552023440lgao } 29030fdf1140b8d1ce93f3821d986fa165552023440lgao // 29130fdf1140b8d1ce93f3821d986fa165552023440lgao // Return the size to the caller so they can keep track of the running total. 29230fdf1140b8d1ce93f3821d986fa165552023440lgao // 29330fdf1140b8d1ce93f3821d986fa165552023440lgao *Size = TotalSize; 29430fdf1140b8d1ce93f3821d986fa165552023440lgao 29530fdf1140b8d1ce93f3821d986fa165552023440lgao // 29630fdf1140b8d1ce93f3821d986fa165552023440lgao // Crude check to make sure it's a legitimate ROM image 29730fdf1140b8d1ce93f3821d986fa165552023440lgao // 29830fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer; 29930fdf1140b8d1ce93f3821d986fa165552023440lgao if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { 30030fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "ROM image file has an invalid ROM signature."); 30130fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 30230fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 30330fdf1140b8d1ce93f3821d986fa165552023440lgao } 30430fdf1140b8d1ce93f3821d986fa165552023440lgao // 30530fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure the pointer to the PCI data structure is within the size of the image. 30630fdf1140b8d1ce93f3821d986fa165552023440lgao // Then check it for valid signature. 30730fdf1140b8d1ce93f3821d986fa165552023440lgao // 30830fdf1140b8d1ce93f3821d986fa165552023440lgao if ((RomHdr->PcirOffset > FileSize) || (RomHdr->PcirOffset == 0)) { 30930fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Invalid PCI data structure offset."); 31030fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 31130fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 31230fdf1140b8d1ce93f3821d986fa165552023440lgao } 31330fdf1140b8d1ce93f3821d986fa165552023440lgao 31430fdf1140b8d1ce93f3821d986fa165552023440lgao // 31530fdf1140b8d1ce93f3821d986fa165552023440lgao // Check the header is conform to PCI2.3 or PCI3.0 31630fdf1140b8d1ce93f3821d986fa165552023440lgao // 31730fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 31830fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23 = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset); 31930fdf1140b8d1ce93f3821d986fa165552023440lgao if (PciDs23->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { 32030fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature."); 32130fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 32230fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 32330fdf1140b8d1ce93f3821d986fa165552023440lgao } 32430fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 32530fdf1140b8d1ce93f3821d986fa165552023440lgao // 32630fdf1140b8d1ce93f3821d986fa165552023440lgao // Default setting is PCI3.0 header 32730fdf1140b8d1ce93f3821d986fa165552023440lgao // 32830fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30 = (PCI_3_0_DATA_STRUCTURE *)(Buffer + RomHdr->PcirOffset); 32930fdf1140b8d1ce93f3821d986fa165552023440lgao if (PciDs30->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { 33030fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "PCI data structure has an invalid signature."); 33130fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 33230fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 33330fdf1140b8d1ce93f3821d986fa165552023440lgao } 33430fdf1140b8d1ce93f3821d986fa165552023440lgao } 33530fdf1140b8d1ce93f3821d986fa165552023440lgao 33630fdf1140b8d1ce93f3821d986fa165552023440lgao // 33730fdf1140b8d1ce93f3821d986fa165552023440lgao // ReSet Option Rom size 33830fdf1140b8d1ce93f3821d986fa165552023440lgao // 33930fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 34030fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23->ImageLength = (UINT16) (TotalSize / 512); 3412bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming CodeType = PciDs23->CodeType; 34230fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 34330fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30->ImageLength = (UINT16) (TotalSize / 512); 3442bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming CodeType = PciDs30->CodeType; 34530fdf1140b8d1ce93f3821d986fa165552023440lgao } 34630fdf1140b8d1ce93f3821d986fa165552023440lgao 34730fdf1140b8d1ce93f3821d986fa165552023440lgao // 34830fdf1140b8d1ce93f3821d986fa165552023440lgao // If this is the last image, then set the LAST bit unless requested not 34930fdf1140b8d1ce93f3821d986fa165552023440lgao // to via the command-line -n argument. Otherwise, make sure you clear it. 35030fdf1140b8d1ce93f3821d986fa165552023440lgao // 35130fdf1140b8d1ce93f3821d986fa165552023440lgao if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { 35230fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 35330fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23->Indicator = INDICATOR_LAST; 35430fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 35530fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30->Indicator = INDICATOR_LAST; 35630fdf1140b8d1ce93f3821d986fa165552023440lgao } 35730fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 35830fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 35930fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23->Indicator = 0; 36030fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 36130fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30->Indicator = 0; 36230fdf1140b8d1ce93f3821d986fa165552023440lgao } 36330fdf1140b8d1ce93f3821d986fa165552023440lgao } 36430fdf1140b8d1ce93f3821d986fa165552023440lgao 3652bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming if (CodeType != PCI_CODE_TYPE_EFI_IMAGE) { 3662bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming ByteCheckSum = 0; 3672bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming for (Index = 0; Index < FileSize - 1; Index++) { 3682bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]); 3692bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming } 37030fdf1140b8d1ce93f3821d986fa165552023440lgao 3712bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1); 3722bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming if (mOptions.Verbose) { 3732bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming VerboseMsg(" Checksum = %02x\n\n", Buffer[FileSize - 1]); 3742bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming } 37530fdf1140b8d1ce93f3821d986fa165552023440lgao } 37630fdf1140b8d1ce93f3821d986fa165552023440lgao 37730fdf1140b8d1ce93f3821d986fa165552023440lgao // 37830fdf1140b8d1ce93f3821d986fa165552023440lgao // Now copy the input file contents out to the output file 37930fdf1140b8d1ce93f3821d986fa165552023440lgao // 38030fdf1140b8d1ce93f3821d986fa165552023440lgao if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { 38130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0005, "Failed to write all file bytes to output file.", NULL); 38230fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 38330fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 38430fdf1140b8d1ce93f3821d986fa165552023440lgao } 38530fdf1140b8d1ce93f3821d986fa165552023440lgao 38630fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize -= FileSize; 38730fdf1140b8d1ce93f3821d986fa165552023440lgao // 38830fdf1140b8d1ce93f3821d986fa165552023440lgao // Pad the rest of the image to make it a multiple of 512 bytes 38930fdf1140b8d1ce93f3821d986fa165552023440lgao // 39030fdf1140b8d1ce93f3821d986fa165552023440lgao while (TotalSize > 0) { 39130fdf1140b8d1ce93f3821d986fa165552023440lgao putc (~0, OutFptr); 39230fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize--; 39330fdf1140b8d1ce93f3821d986fa165552023440lgao } 39430fdf1140b8d1ce93f3821d986fa165552023440lgao 39530fdf1140b8d1ce93f3821d986fa165552023440lgaoBailOut: 39630fdf1140b8d1ce93f3821d986fa165552023440lgao if (InFptr != NULL) { 39730fdf1140b8d1ce93f3821d986fa165552023440lgao fclose (InFptr); 39830fdf1140b8d1ce93f3821d986fa165552023440lgao } 39930fdf1140b8d1ce93f3821d986fa165552023440lgao 40030fdf1140b8d1ce93f3821d986fa165552023440lgao if (Buffer != NULL) { 40130fdf1140b8d1ce93f3821d986fa165552023440lgao free (Buffer); 40230fdf1140b8d1ce93f3821d986fa165552023440lgao } 40330fdf1140b8d1ce93f3821d986fa165552023440lgao // 40430fdf1140b8d1ce93f3821d986fa165552023440lgao // Print the file name if errors occurred 40530fdf1140b8d1ce93f3821d986fa165552023440lgao // 40630fdf1140b8d1ce93f3821d986fa165552023440lgao if (Status != STATUS_SUCCESS) { 40730fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0003, "Error", "Error parsing file: %s", InFile->FileName); 40830fdf1140b8d1ce93f3821d986fa165552023440lgao } 40930fdf1140b8d1ce93f3821d986fa165552023440lgao 41030fdf1140b8d1ce93f3821d986fa165552023440lgao return Status; 41130fdf1140b8d1ce93f3821d986fa165552023440lgao} 41230fdf1140b8d1ce93f3821d986fa165552023440lgao 41330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 41430fdf1140b8d1ce93f3821d986fa165552023440lgaoint 41530fdf1140b8d1ce93f3821d986fa165552023440lgaoProcessEfiFile ( 41630fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *OutFptr, 41730fdf1140b8d1ce93f3821d986fa165552023440lgao FILE_LIST *InFile, 41830fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 VendId, 41930fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 DevId, 42030fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 *Size 42130fdf1140b8d1ce93f3821d986fa165552023440lgao ) 42230fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 42330fdf1140b8d1ce93f3821d986fa165552023440lgao 42430fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 42530fdf1140b8d1ce93f3821d986fa165552023440lgao 42630fdf1140b8d1ce93f3821d986fa165552023440lgao Process a PE32 EFI file. 42730fdf1140b8d1ce93f3821d986fa165552023440lgao 42830fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 42930fdf1140b8d1ce93f3821d986fa165552023440lgao 43030fdf1140b8d1ce93f3821d986fa165552023440lgao OutFptr - file pointer to output binary ROM image file we're creating 43130fdf1140b8d1ce93f3821d986fa165552023440lgao InFile - structure contains information on the PE32 file to process 43230fdf1140b8d1ce93f3821d986fa165552023440lgao VendId - vendor ID as required in the option ROM header 43330fdf1140b8d1ce93f3821d986fa165552023440lgao DevId - device ID as required in the option ROM header 43430fdf1140b8d1ce93f3821d986fa165552023440lgao Size - pointer to where to return the size added to the output file 43530fdf1140b8d1ce93f3821d986fa165552023440lgao 43630fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 43730fdf1140b8d1ce93f3821d986fa165552023440lgao 43830fdf1140b8d1ce93f3821d986fa165552023440lgao 0 - successful 43930fdf1140b8d1ce93f3821d986fa165552023440lgao 44030fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 44130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 44230fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 Status; 44330fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *InFptr; 44430fdf1140b8d1ce93f3821d986fa165552023440lgao EFI_PCI_EXPANSION_ROM_HEADER RomHdr; 44530fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_DATA_STRUCTURE PciDs23; 44630fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_3_0_DATA_STRUCTURE PciDs30; 44730fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 FileSize; 44830fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 CompressedFileSize; 44930fdf1140b8d1ce93f3821d986fa165552023440lgao UINT8 *Buffer; 45030fdf1140b8d1ce93f3821d986fa165552023440lgao UINT8 *CompressedBuffer; 45130fdf1140b8d1ce93f3821d986fa165552023440lgao UINT8 *TempBufferPtr; 45230fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 TotalSize; 45330fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 HeaderSize; 45430fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 MachineType; 45530fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 SubSystem; 45630fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 HeaderPadBytes; 4572bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming UINT32 PadBytesBeforeImage; 4582bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming UINT32 PadBytesAfterImage; 45930fdf1140b8d1ce93f3821d986fa165552023440lgao 46030fdf1140b8d1ce93f3821d986fa165552023440lgao // 46130fdf1140b8d1ce93f3821d986fa165552023440lgao // Try to open the input file 46230fdf1140b8d1ce93f3821d986fa165552023440lgao // 4631be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chen if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) { 46430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0001, "Open file error", "Error opening file: %s", InFile->FileName); 46530fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 46630fdf1140b8d1ce93f3821d986fa165552023440lgao } 46730fdf1140b8d1ce93f3821d986fa165552023440lgao // 46830fdf1140b8d1ce93f3821d986fa165552023440lgao // Initialize our buffer pointers to null. 46930fdf1140b8d1ce93f3821d986fa165552023440lgao // 47030fdf1140b8d1ce93f3821d986fa165552023440lgao Buffer = NULL; 47130fdf1140b8d1ce93f3821d986fa165552023440lgao CompressedBuffer = NULL; 47230fdf1140b8d1ce93f3821d986fa165552023440lgao 47330fdf1140b8d1ce93f3821d986fa165552023440lgao // 47430fdf1140b8d1ce93f3821d986fa165552023440lgao // Double-check the file to make sure it's what we expect it to be 47530fdf1140b8d1ce93f3821d986fa165552023440lgao // 47630fdf1140b8d1ce93f3821d986fa165552023440lgao Status = CheckPE32File (InFptr, &MachineType, &SubSystem); 47730fdf1140b8d1ce93f3821d986fa165552023440lgao if (Status != STATUS_SUCCESS) { 47830fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 47930fdf1140b8d1ce93f3821d986fa165552023440lgao } 48030fdf1140b8d1ce93f3821d986fa165552023440lgao // 48130fdf1140b8d1ce93f3821d986fa165552023440lgao // Seek to the end of the input file and get the file size 48230fdf1140b8d1ce93f3821d986fa165552023440lgao // 48330fdf1140b8d1ce93f3821d986fa165552023440lgao fseek (InFptr, 0, SEEK_END); 48430fdf1140b8d1ce93f3821d986fa165552023440lgao FileSize = ftell (InFptr); 48530fdf1140b8d1ce93f3821d986fa165552023440lgao 48630fdf1140b8d1ce93f3821d986fa165552023440lgao // 48730fdf1140b8d1ce93f3821d986fa165552023440lgao // Get the size of the headers we're going to put in front of the image. The 48830fdf1140b8d1ce93f3821d986fa165552023440lgao // EFI header must be aligned on a 4-byte boundary, so pad accordingly. 48930fdf1140b8d1ce93f3821d986fa165552023440lgao // 49030fdf1140b8d1ce93f3821d986fa165552023440lgao if (sizeof (RomHdr) & 0x03) { 49130fdf1140b8d1ce93f3821d986fa165552023440lgao HeaderPadBytes = 4 - (sizeof (RomHdr) & 0x03); 49230fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 49330fdf1140b8d1ce93f3821d986fa165552023440lgao HeaderPadBytes = 0; 49430fdf1140b8d1ce93f3821d986fa165552023440lgao } 49530fdf1140b8d1ce93f3821d986fa165552023440lgao 49630fdf1140b8d1ce93f3821d986fa165552023440lgao // 49730fdf1140b8d1ce93f3821d986fa165552023440lgao // For Pci3.0 to use the different data structure. 49830fdf1140b8d1ce93f3821d986fa165552023440lgao // 49930fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 50030fdf1140b8d1ce93f3821d986fa165552023440lgao HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER); 50130fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 50230fdf1140b8d1ce93f3821d986fa165552023440lgao HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER); 50330fdf1140b8d1ce93f3821d986fa165552023440lgao } 50430fdf1140b8d1ce93f3821d986fa165552023440lgao 50530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 506fd171542e0aa89ac12a09d79608173f48019b14bvanjeff VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize); 50730fdf1140b8d1ce93f3821d986fa165552023440lgao } 50830fdf1140b8d1ce93f3821d986fa165552023440lgao // 50930fdf1140b8d1ce93f3821d986fa165552023440lgao // Allocate memory for the entire file (in case we have to compress), then 51030fdf1140b8d1ce93f3821d986fa165552023440lgao // seek back to the beginning of the file and read it into our buffer. 51130fdf1140b8d1ce93f3821d986fa165552023440lgao // 51230fdf1140b8d1ce93f3821d986fa165552023440lgao Buffer = (UINT8 *) malloc (FileSize); 51330fdf1140b8d1ce93f3821d986fa165552023440lgao if (Buffer == NULL) { 51430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); 51530fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 51630fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 51730fdf1140b8d1ce93f3821d986fa165552023440lgao } 51830fdf1140b8d1ce93f3821d986fa165552023440lgao 51930fdf1140b8d1ce93f3821d986fa165552023440lgao fseek (InFptr, 0, SEEK_SET); 52030fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (Buffer, FileSize, 1, InFptr) != 1) { 52130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName); 52230fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 52330fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 52430fdf1140b8d1ce93f3821d986fa165552023440lgao } 52530fdf1140b8d1ce93f3821d986fa165552023440lgao // 52630fdf1140b8d1ce93f3821d986fa165552023440lgao // Now determine the size of the final output file. It's either the header size 52730fdf1140b8d1ce93f3821d986fa165552023440lgao // plus the file's size, or the header size plus the compressed file size. 52830fdf1140b8d1ce93f3821d986fa165552023440lgao // 52930fdf1140b8d1ce93f3821d986fa165552023440lgao if ((InFile->FileFlags & FILE_FLAG_COMPRESS) != 0) { 53030fdf1140b8d1ce93f3821d986fa165552023440lgao // 53130fdf1140b8d1ce93f3821d986fa165552023440lgao // Allocate a buffer into which we can compress the image, compress it, 53230fdf1140b8d1ce93f3821d986fa165552023440lgao // and use that size as the new size. 53330fdf1140b8d1ce93f3821d986fa165552023440lgao // 53430fdf1140b8d1ce93f3821d986fa165552023440lgao CompressedBuffer = (UINT8 *) malloc (FileSize); 53530fdf1140b8d1ce93f3821d986fa165552023440lgao if (CompressedBuffer == NULL) { 53630fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); 53730fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 53830fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 53930fdf1140b8d1ce93f3821d986fa165552023440lgao } 54030fdf1140b8d1ce93f3821d986fa165552023440lgao 54130fdf1140b8d1ce93f3821d986fa165552023440lgao CompressedFileSize = FileSize; 54230fdf1140b8d1ce93f3821d986fa165552023440lgao Status = EfiCompress (Buffer, FileSize, CompressedBuffer, &CompressedFileSize); 54330fdf1140b8d1ce93f3821d986fa165552023440lgao if (Status != STATUS_SUCCESS) { 54430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0007, "Error compressing file!", NULL); 54530fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 54630fdf1140b8d1ce93f3821d986fa165552023440lgao } 54730fdf1140b8d1ce93f3821d986fa165552023440lgao // 54830fdf1140b8d1ce93f3821d986fa165552023440lgao // Now compute the size, then swap buffer pointers. 54930fdf1140b8d1ce93f3821d986fa165552023440lgao // 55030fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 551fd171542e0aa89ac12a09d79608173f48019b14bvanjeff VerboseMsg(" Comp size = 0x%X\n", (unsigned) CompressedFileSize); 55230fdf1140b8d1ce93f3821d986fa165552023440lgao } 55330fdf1140b8d1ce93f3821d986fa165552023440lgao 55430fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize = CompressedFileSize + HeaderSize; 55530fdf1140b8d1ce93f3821d986fa165552023440lgao FileSize = CompressedFileSize; 55630fdf1140b8d1ce93f3821d986fa165552023440lgao TempBufferPtr = Buffer; 55730fdf1140b8d1ce93f3821d986fa165552023440lgao Buffer = CompressedBuffer; 55830fdf1140b8d1ce93f3821d986fa165552023440lgao CompressedBuffer = TempBufferPtr; 55930fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 56030fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize = FileSize + HeaderSize; 56130fdf1140b8d1ce93f3821d986fa165552023440lgao } 56230fdf1140b8d1ce93f3821d986fa165552023440lgao // 56330fdf1140b8d1ce93f3821d986fa165552023440lgao // Total size must be an even multiple of 512 bytes 56430fdf1140b8d1ce93f3821d986fa165552023440lgao // 56530fdf1140b8d1ce93f3821d986fa165552023440lgao if (TotalSize & 0x1FF) { 56630fdf1140b8d1ce93f3821d986fa165552023440lgao TotalSize = (TotalSize + 0x200) &~0x1ff; 56730fdf1140b8d1ce93f3821d986fa165552023440lgao } 56830fdf1140b8d1ce93f3821d986fa165552023440lgao // 5692bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming // Workaround: 5702bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming // If compressed, put the pad bytes after the image, 5712bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming // else put the pad bytes before the image. 5722bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming // 5732bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming if ((InFile->FileFlags & FILE_FLAG_COMPRESS) != 0) { 5742bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming PadBytesBeforeImage = 0; 5752bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming PadBytesAfterImage = TotalSize - (FileSize + HeaderSize); 5762bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming } else { 5772bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming PadBytesBeforeImage = TotalSize - (FileSize + HeaderSize); 5782bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming PadBytesAfterImage = 0; 5792bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming } 5802bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming // 58130fdf1140b8d1ce93f3821d986fa165552023440lgao // Check size 58230fdf1140b8d1ce93f3821d986fa165552023440lgao // 58330fdf1140b8d1ce93f3821d986fa165552023440lgao if (TotalSize > MAX_OPTION_ROM_SIZE) { 58430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE); 58530fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 58630fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 58730fdf1140b8d1ce93f3821d986fa165552023440lgao } 58830fdf1140b8d1ce93f3821d986fa165552023440lgao // 58930fdf1140b8d1ce93f3821d986fa165552023440lgao // Return the size to the caller so they can keep track of the running total. 59030fdf1140b8d1ce93f3821d986fa165552023440lgao // 59130fdf1140b8d1ce93f3821d986fa165552023440lgao *Size = TotalSize; 59230fdf1140b8d1ce93f3821d986fa165552023440lgao 59330fdf1140b8d1ce93f3821d986fa165552023440lgao // 59430fdf1140b8d1ce93f3821d986fa165552023440lgao // Now fill in the ROM header. These values come from chapter 18 of the 59530fdf1140b8d1ce93f3821d986fa165552023440lgao // EFI 1.02 specification. 59630fdf1140b8d1ce93f3821d986fa165552023440lgao // 59730fdf1140b8d1ce93f3821d986fa165552023440lgao memset (&RomHdr, 0, sizeof (RomHdr)); 59830fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE; 59930fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.InitializationSize = (UINT16) (TotalSize / 512); 60030fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE; 60130fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.EfiSubsystem = SubSystem; 60230fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.EfiMachineType = MachineType; 6032bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming RomHdr.EfiImageHeaderOffset = (UINT16) (HeaderSize + PadBytesBeforeImage); 60430fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.PcirOffset = (UINT16) (sizeof (RomHdr) + HeaderPadBytes); 60530fdf1140b8d1ce93f3821d986fa165552023440lgao // 60630fdf1140b8d1ce93f3821d986fa165552023440lgao // Set image as compressed or not 60730fdf1140b8d1ce93f3821d986fa165552023440lgao // 60830fdf1140b8d1ce93f3821d986fa165552023440lgao if (InFile->FileFlags & FILE_FLAG_COMPRESS) { 60930fdf1140b8d1ce93f3821d986fa165552023440lgao RomHdr.CompressionType = EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED; 61030fdf1140b8d1ce93f3821d986fa165552023440lgao } 61130fdf1140b8d1ce93f3821d986fa165552023440lgao // 61230fdf1140b8d1ce93f3821d986fa165552023440lgao // Fill in the PCI data structure 61330fdf1140b8d1ce93f3821d986fa165552023440lgao // 61430fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 61530fdf1140b8d1ce93f3821d986fa165552023440lgao memset (&PciDs23, 0, sizeof (PCI_DATA_STRUCTURE)); 61630fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 61730fdf1140b8d1ce93f3821d986fa165552023440lgao memset (&PciDs30, 0, sizeof (PCI_3_0_DATA_STRUCTURE)); 61830fdf1140b8d1ce93f3821d986fa165552023440lgao } 61930fdf1140b8d1ce93f3821d986fa165552023440lgao 62030fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 62130fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.Signature = PCI_DATA_STRUCTURE_SIGNATURE; 62230fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.VendorId = VendId; 62330fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.DeviceId = DevId; 62430fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.Length = (UINT16) sizeof (PCI_DATA_STRUCTURE); 62530fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.Revision = 0; 62630fdf1140b8d1ce93f3821d986fa165552023440lgao // 62730fdf1140b8d1ce93f3821d986fa165552023440lgao // Class code and code revision from the command line (optional) 62830fdf1140b8d1ce93f3821d986fa165552023440lgao // 62930fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.ClassCode[0] = (UINT8) InFile->ClassCode; 63030fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.ClassCode[1] = (UINT8) (InFile->ClassCode >> 8); 63130fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.ClassCode[2] = (UINT8) (InFile->ClassCode >> 16); 63230fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.ImageLength = RomHdr.InitializationSize; 63330fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.CodeRevision = InFile->CodeRevision; 63430fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.CodeType = PCI_CODE_TYPE_EFI_IMAGE; 63530fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 63630fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.Signature = PCI_DATA_STRUCTURE_SIGNATURE; 63730fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.VendorId = VendId; 63830fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.DeviceId = DevId; 63930fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.DeviceListOffset = 0; // to be fixed 64030fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.Length = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE); 64130fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.Revision = 0x3; 64230fdf1140b8d1ce93f3821d986fa165552023440lgao // 64330fdf1140b8d1ce93f3821d986fa165552023440lgao // Class code and code revision from the command line (optional) 64430fdf1140b8d1ce93f3821d986fa165552023440lgao // 64530fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.ClassCode[0] = (UINT8) InFile->ClassCode; 64630fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.ClassCode[1] = (UINT8) (InFile->ClassCode >> 8); 64730fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.ClassCode[2] = (UINT8) (InFile->ClassCode >> 16); 64830fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.ImageLength = RomHdr.InitializationSize; 64930fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.CodeRevision = InFile->CodeRevision; 65030fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.CodeType = PCI_CODE_TYPE_EFI_IMAGE; 65130fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.MaxRuntimeImageLength = 0; // to be fixed 65230fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.ConfigUtilityCodeHeaderOffset = 0; // to be fixed 65330fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.DMTFCLPEntryPointOffset = 0; // to be fixed 65430fdf1140b8d1ce93f3821d986fa165552023440lgao } 65530fdf1140b8d1ce93f3821d986fa165552023440lgao // 65630fdf1140b8d1ce93f3821d986fa165552023440lgao // If this is the last image, then set the LAST bit unless requested not 65730fdf1140b8d1ce93f3821d986fa165552023440lgao // to via the command-line -n argument. 65830fdf1140b8d1ce93f3821d986fa165552023440lgao // 65930fdf1140b8d1ce93f3821d986fa165552023440lgao if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { 66030fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 66130fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.Indicator = INDICATOR_LAST; 66230fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 66330fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.Indicator = INDICATOR_LAST;} 66430fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 66530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 66630fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs23.Indicator = 0; 66730fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 66830fdf1140b8d1ce93f3821d986fa165552023440lgao PciDs30.Indicator = 0; 66930fdf1140b8d1ce93f3821d986fa165552023440lgao } 67030fdf1140b8d1ce93f3821d986fa165552023440lgao } 67130fdf1140b8d1ce93f3821d986fa165552023440lgao // 67230fdf1140b8d1ce93f3821d986fa165552023440lgao // Write the ROM header to the output file 67330fdf1140b8d1ce93f3821d986fa165552023440lgao // 67430fdf1140b8d1ce93f3821d986fa165552023440lgao if (fwrite (&RomHdr, sizeof (RomHdr), 1, OutFptr) != 1) { 67530fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0002, "Failed to write ROM header to output file!", NULL); 67630fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 67730fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 67830fdf1140b8d1ce93f3821d986fa165552023440lgao } 67930fdf1140b8d1ce93f3821d986fa165552023440lgao 68030fdf1140b8d1ce93f3821d986fa165552023440lgao // 68130fdf1140b8d1ce93f3821d986fa165552023440lgao // Write pad bytes to align the PciDs 68230fdf1140b8d1ce93f3821d986fa165552023440lgao // 68330fdf1140b8d1ce93f3821d986fa165552023440lgao while (HeaderPadBytes > 0) { 68430fdf1140b8d1ce93f3821d986fa165552023440lgao if (putc (0, OutFptr) == EOF) { 68530fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0002, "Failed to write ROM header pad bytes to output file!", NULL); 68630fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 68730fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 68830fdf1140b8d1ce93f3821d986fa165552023440lgao } 68930fdf1140b8d1ce93f3821d986fa165552023440lgao 69030fdf1140b8d1ce93f3821d986fa165552023440lgao HeaderPadBytes--; 69130fdf1140b8d1ce93f3821d986fa165552023440lgao } 69230fdf1140b8d1ce93f3821d986fa165552023440lgao // 69330fdf1140b8d1ce93f3821d986fa165552023440lgao // Write the PCI data structure header to the output file 69430fdf1140b8d1ce93f3821d986fa165552023440lgao // 69530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 69630fdf1140b8d1ce93f3821d986fa165552023440lgao if (fwrite (&PciDs23, sizeof (PciDs23), 1, OutFptr) != 1) { 69730fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL); 69830fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 69930fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 70030fdf1140b8d1ce93f3821d986fa165552023440lgao } 70130fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 70230fdf1140b8d1ce93f3821d986fa165552023440lgao if (fwrite (&PciDs30, sizeof (PciDs30), 1, OutFptr) != 1) { 70330fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL); 70430fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 70530fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 70630fdf1140b8d1ce93f3821d986fa165552023440lgao } 70730fdf1140b8d1ce93f3821d986fa165552023440lgao } 7082bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming 70930fdf1140b8d1ce93f3821d986fa165552023440lgao // 7102bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming // Pad head to make it a multiple of 512 bytes 71130fdf1140b8d1ce93f3821d986fa165552023440lgao // 7122bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming while (PadBytesBeforeImage > 0) { 7132bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming if (putc (~0, OutFptr) == EOF) { 7142bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming Error (NULL, 0, 2000, "Failed to write trailing pad bytes output file!", NULL); 7152bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming Status = STATUS_ERROR; 7162bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming goto BailOut; 7172bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming } 7182bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming PadBytesBeforeImage--; 7192bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming } 72030fdf1140b8d1ce93f3821d986fa165552023440lgao // 72130fdf1140b8d1ce93f3821d986fa165552023440lgao // Now dump the input file's contents to the output file 72230fdf1140b8d1ce93f3821d986fa165552023440lgao // 72330fdf1140b8d1ce93f3821d986fa165552023440lgao if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { 72430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0002, "Failed to write all file bytes to output file!", NULL); 72530fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 72630fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 72730fdf1140b8d1ce93f3821d986fa165552023440lgao } 72830fdf1140b8d1ce93f3821d986fa165552023440lgao 72930fdf1140b8d1ce93f3821d986fa165552023440lgao // 73030fdf1140b8d1ce93f3821d986fa165552023440lgao // Pad the rest of the image to make it a multiple of 512 bytes 73130fdf1140b8d1ce93f3821d986fa165552023440lgao // 7322bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming while (PadBytesAfterImage > 0) { 73330fdf1140b8d1ce93f3821d986fa165552023440lgao if (putc (~0, OutFptr) == EOF) { 73430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Failed to write trailing pad bytes output file!", NULL); 73530fdf1140b8d1ce93f3821d986fa165552023440lgao Status = STATUS_ERROR; 73630fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 73730fdf1140b8d1ce93f3821d986fa165552023440lgao } 73830fdf1140b8d1ce93f3821d986fa165552023440lgao 7392bc3256ca6d439ebf5d85d5e74e5f3e68df14130Gao, Liming PadBytesAfterImage--; 74030fdf1140b8d1ce93f3821d986fa165552023440lgao } 74130fdf1140b8d1ce93f3821d986fa165552023440lgao 74230fdf1140b8d1ce93f3821d986fa165552023440lgaoBailOut: 74330fdf1140b8d1ce93f3821d986fa165552023440lgao if (InFptr != NULL) { 74430fdf1140b8d1ce93f3821d986fa165552023440lgao fclose (InFptr); 74530fdf1140b8d1ce93f3821d986fa165552023440lgao } 74630fdf1140b8d1ce93f3821d986fa165552023440lgao // 74730fdf1140b8d1ce93f3821d986fa165552023440lgao // Free up our buffers 74830fdf1140b8d1ce93f3821d986fa165552023440lgao // 74930fdf1140b8d1ce93f3821d986fa165552023440lgao if (Buffer != NULL) { 75030fdf1140b8d1ce93f3821d986fa165552023440lgao free (Buffer); 75130fdf1140b8d1ce93f3821d986fa165552023440lgao } 75230fdf1140b8d1ce93f3821d986fa165552023440lgao 75330fdf1140b8d1ce93f3821d986fa165552023440lgao if (CompressedBuffer != NULL) { 75430fdf1140b8d1ce93f3821d986fa165552023440lgao free (CompressedBuffer); 75530fdf1140b8d1ce93f3821d986fa165552023440lgao } 75630fdf1140b8d1ce93f3821d986fa165552023440lgao // 75730fdf1140b8d1ce93f3821d986fa165552023440lgao // Print the file name if errors occurred 75830fdf1140b8d1ce93f3821d986fa165552023440lgao // 75930fdf1140b8d1ce93f3821d986fa165552023440lgao if (Status != STATUS_SUCCESS) { 76030fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0003, "Error parsing", "Error parsing file: %s", InFile->FileName); 76130fdf1140b8d1ce93f3821d986fa165552023440lgao } 76230fdf1140b8d1ce93f3821d986fa165552023440lgao 76330fdf1140b8d1ce93f3821d986fa165552023440lgao return Status; 76430fdf1140b8d1ce93f3821d986fa165552023440lgao} 76530fdf1140b8d1ce93f3821d986fa165552023440lgao 76630fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 76730fdf1140b8d1ce93f3821d986fa165552023440lgaoint 76830fdf1140b8d1ce93f3821d986fa165552023440lgaoCheckPE32File ( 76930fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *Fptr, 77030fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 *MachineType, 77130fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 *SubSystem 77230fdf1140b8d1ce93f3821d986fa165552023440lgao ) 77330fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 77430fdf1140b8d1ce93f3821d986fa165552023440lgao 77530fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 77630fdf1140b8d1ce93f3821d986fa165552023440lgao 77730fdf1140b8d1ce93f3821d986fa165552023440lgao Given a file pointer to a supposed PE32 image file, verify that it is indeed a 77830fdf1140b8d1ce93f3821d986fa165552023440lgao PE32 image file, and then return the machine type in the supplied pointer. 77930fdf1140b8d1ce93f3821d986fa165552023440lgao 78030fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 78130fdf1140b8d1ce93f3821d986fa165552023440lgao 78230fdf1140b8d1ce93f3821d986fa165552023440lgao Fptr File pointer to the already-opened PE32 file 78330fdf1140b8d1ce93f3821d986fa165552023440lgao MachineType Location to stuff the machine type of the PE32 file. This is needed 78430fdf1140b8d1ce93f3821d986fa165552023440lgao because the image may be Itanium-based, IA32, or EBC. 78530fdf1140b8d1ce93f3821d986fa165552023440lgao 78630fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 78730fdf1140b8d1ce93f3821d986fa165552023440lgao 78830fdf1140b8d1ce93f3821d986fa165552023440lgao 0 success 78930fdf1140b8d1ce93f3821d986fa165552023440lgao non-zero otherwise 79030fdf1140b8d1ce93f3821d986fa165552023440lgao 79130fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 79230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 79330fdf1140b8d1ce93f3821d986fa165552023440lgao EFI_IMAGE_DOS_HEADER DosHeader; 79430fdf1140b8d1ce93f3821d986fa165552023440lgao EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; 79530fdf1140b8d1ce93f3821d986fa165552023440lgao 79630fdf1140b8d1ce93f3821d986fa165552023440lgao // 79730fdf1140b8d1ce93f3821d986fa165552023440lgao // Position to the start of the file 79830fdf1140b8d1ce93f3821d986fa165552023440lgao // 79930fdf1140b8d1ce93f3821d986fa165552023440lgao fseek (Fptr, 0, SEEK_SET); 80030fdf1140b8d1ce93f3821d986fa165552023440lgao 80130fdf1140b8d1ce93f3821d986fa165552023440lgao // 80230fdf1140b8d1ce93f3821d986fa165552023440lgao // Read the DOS header 80330fdf1140b8d1ce93f3821d986fa165552023440lgao // 80430fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { 80530fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0004, "Failed to read the DOS stub from the input file!", NULL); 80630fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 80730fdf1140b8d1ce93f3821d986fa165552023440lgao } 80830fdf1140b8d1ce93f3821d986fa165552023440lgao // 80930fdf1140b8d1ce93f3821d986fa165552023440lgao // Check the magic number (0x5A4D) 81030fdf1140b8d1ce93f3821d986fa165552023440lgao // 81130fdf1140b8d1ce93f3821d986fa165552023440lgao if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { 81230fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!"); 81330fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 81430fdf1140b8d1ce93f3821d986fa165552023440lgao } 81530fdf1140b8d1ce93f3821d986fa165552023440lgao // 81630fdf1140b8d1ce93f3821d986fa165552023440lgao // Position into the file and check the PE signature 81730fdf1140b8d1ce93f3821d986fa165552023440lgao // 81830fdf1140b8d1ce93f3821d986fa165552023440lgao fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); 81930fdf1140b8d1ce93f3821d986fa165552023440lgao 82030fdf1140b8d1ce93f3821d986fa165552023440lgao // 82130fdf1140b8d1ce93f3821d986fa165552023440lgao // Read PE headers 82230fdf1140b8d1ce93f3821d986fa165552023440lgao // 82330fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (&PeHdr, sizeof (PeHdr), 1, Fptr) != 1) { 82430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL); 82530fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 82630fdf1140b8d1ce93f3821d986fa165552023440lgao } 82730fdf1140b8d1ce93f3821d986fa165552023440lgao 82830fdf1140b8d1ce93f3821d986fa165552023440lgao 82930fdf1140b8d1ce93f3821d986fa165552023440lgao // 83030fdf1140b8d1ce93f3821d986fa165552023440lgao // Check the PE signature in the header "PE\0\0" 83130fdf1140b8d1ce93f3821d986fa165552023440lgao // 83230fdf1140b8d1ce93f3821d986fa165552023440lgao if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { 83330fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!"); 83430fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 83530fdf1140b8d1ce93f3821d986fa165552023440lgao } 83630fdf1140b8d1ce93f3821d986fa165552023440lgao 83730fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy ((char *) MachineType, &PeHdr.Pe32.FileHeader.Machine, 2); 83830fdf1140b8d1ce93f3821d986fa165552023440lgao 83930fdf1140b8d1ce93f3821d986fa165552023440lgao if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 84030fdf1140b8d1ce93f3821d986fa165552023440lgao *SubSystem = PeHdr.Pe32.OptionalHeader.Subsystem; 84130fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (PeHdr.Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 84230fdf1140b8d1ce93f3821d986fa165552023440lgao *SubSystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem; 84330fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 84430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Unable to find subsystem type!"); 84530fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 84630fdf1140b8d1ce93f3821d986fa165552023440lgao } 84730fdf1140b8d1ce93f3821d986fa165552023440lgao 84830fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 849fd171542e0aa89ac12a09d79608173f48019b14bvanjeff VerboseMsg(" Got subsystem = 0x%X from image\n", *SubSystem); 85030fdf1140b8d1ce93f3821d986fa165552023440lgao } 85130fdf1140b8d1ce93f3821d986fa165552023440lgao 85230fdf1140b8d1ce93f3821d986fa165552023440lgao // 85330fdf1140b8d1ce93f3821d986fa165552023440lgao // File was successfully identified as a PE32 85430fdf1140b8d1ce93f3821d986fa165552023440lgao // 85530fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_SUCCESS; 85630fdf1140b8d1ce93f3821d986fa165552023440lgao} 85730fdf1140b8d1ce93f3821d986fa165552023440lgao 85830fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 85930fdf1140b8d1ce93f3821d986fa165552023440lgaoint 86030fdf1140b8d1ce93f3821d986fa165552023440lgaoParseCommandLine ( 86130fdf1140b8d1ce93f3821d986fa165552023440lgao int Argc, 86230fdf1140b8d1ce93f3821d986fa165552023440lgao char *Argv[], 86330fdf1140b8d1ce93f3821d986fa165552023440lgao OPTIONS *Options 86430fdf1140b8d1ce93f3821d986fa165552023440lgao ) 86530fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 86630fdf1140b8d1ce93f3821d986fa165552023440lgao 86730fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 86830fdf1140b8d1ce93f3821d986fa165552023440lgao 86930fdf1140b8d1ce93f3821d986fa165552023440lgao Given the Argc/Argv program arguments, and a pointer to an options structure, 87030fdf1140b8d1ce93f3821d986fa165552023440lgao parse the command-line options and check their validity. 87130fdf1140b8d1ce93f3821d986fa165552023440lgao 87230fdf1140b8d1ce93f3821d986fa165552023440lgao 87330fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 87430fdf1140b8d1ce93f3821d986fa165552023440lgao 87530fdf1140b8d1ce93f3821d986fa165552023440lgao Argc - standard C main() argument count 87630fdf1140b8d1ce93f3821d986fa165552023440lgao Argv[] - standard C main() argument list 87730fdf1140b8d1ce93f3821d986fa165552023440lgao Options - pointer to a structure to store the options in 87830fdf1140b8d1ce93f3821d986fa165552023440lgao 87930fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 88030fdf1140b8d1ce93f3821d986fa165552023440lgao 88130fdf1140b8d1ce93f3821d986fa165552023440lgao STATUS_SUCCESS success 88230fdf1140b8d1ce93f3821d986fa165552023440lgao non-zero otherwise 88330fdf1140b8d1ce93f3821d986fa165552023440lgao 88430fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 88530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 88630fdf1140b8d1ce93f3821d986fa165552023440lgao FILE_LIST *FileList; 88730fdf1140b8d1ce93f3821d986fa165552023440lgao FILE_LIST *PrevFileList; 88830fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 FileFlags; 88930fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 ClassCode; 89030fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 CodeRevision; 89130fdf1140b8d1ce93f3821d986fa165552023440lgao EFI_STATUS Status; 89230fdf1140b8d1ce93f3821d986fa165552023440lgao BOOLEAN EfiRomFlag; 89330fdf1140b8d1ce93f3821d986fa165552023440lgao UINT64 TempValue; 89430fdf1140b8d1ce93f3821d986fa165552023440lgao 89530fdf1140b8d1ce93f3821d986fa165552023440lgao FileFlags = 0; 89630fdf1140b8d1ce93f3821d986fa165552023440lgao EfiRomFlag = FALSE; 89730fdf1140b8d1ce93f3821d986fa165552023440lgao 89830fdf1140b8d1ce93f3821d986fa165552023440lgao // 89930fdf1140b8d1ce93f3821d986fa165552023440lgao // Clear out the options 90030fdf1140b8d1ce93f3821d986fa165552023440lgao // 90130fdf1140b8d1ce93f3821d986fa165552023440lgao memset ((char *) Options, 0, sizeof (OPTIONS)); 90230fdf1140b8d1ce93f3821d986fa165552023440lgao 90330fdf1140b8d1ce93f3821d986fa165552023440lgao // 90430fdf1140b8d1ce93f3821d986fa165552023440lgao // To avoid compile warnings 90530fdf1140b8d1ce93f3821d986fa165552023440lgao // 90630fdf1140b8d1ce93f3821d986fa165552023440lgao FileList = PrevFileList = NULL; 90730fdf1140b8d1ce93f3821d986fa165552023440lgao 90830fdf1140b8d1ce93f3821d986fa165552023440lgao ClassCode = 0; 90930fdf1140b8d1ce93f3821d986fa165552023440lgao CodeRevision = 0; 91030fdf1140b8d1ce93f3821d986fa165552023440lgao // 91130fdf1140b8d1ce93f3821d986fa165552023440lgao // Skip over the program name 91230fdf1140b8d1ce93f3821d986fa165552023440lgao // 91330fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 91430fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 91530fdf1140b8d1ce93f3821d986fa165552023440lgao 91630fdf1140b8d1ce93f3821d986fa165552023440lgao // 91730fdf1140b8d1ce93f3821d986fa165552023440lgao // If no arguments, assume they want usage info 91830fdf1140b8d1ce93f3821d986fa165552023440lgao // 91930fdf1140b8d1ce93f3821d986fa165552023440lgao if (Argc == 0) { 92030fdf1140b8d1ce93f3821d986fa165552023440lgao Usage (); 92130fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 92230fdf1140b8d1ce93f3821d986fa165552023440lgao } 92330fdf1140b8d1ce93f3821d986fa165552023440lgao 92430fdf1140b8d1ce93f3821d986fa165552023440lgao if ((stricmp(Argv[0], "-h") == 0) || (stricmp(Argv[0], "--help") == 0)) { 92530fdf1140b8d1ce93f3821d986fa165552023440lgao Usage(); 92630fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 92730fdf1140b8d1ce93f3821d986fa165552023440lgao } 92830fdf1140b8d1ce93f3821d986fa165552023440lgao 92930fdf1140b8d1ce93f3821d986fa165552023440lgao if ((stricmp(Argv[0], "--version") == 0)) { 93030fdf1140b8d1ce93f3821d986fa165552023440lgao Version(); 93130fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 93230fdf1140b8d1ce93f3821d986fa165552023440lgao } 93330fdf1140b8d1ce93f3821d986fa165552023440lgao 93430fdf1140b8d1ce93f3821d986fa165552023440lgao // 93530fdf1140b8d1ce93f3821d986fa165552023440lgao // Process until no more arguments 93630fdf1140b8d1ce93f3821d986fa165552023440lgao // 93730fdf1140b8d1ce93f3821d986fa165552023440lgao while (Argc > 0) { 93830fdf1140b8d1ce93f3821d986fa165552023440lgao if (Argv[0][0] == '-') { 93930fdf1140b8d1ce93f3821d986fa165552023440lgao // 94030fdf1140b8d1ce93f3821d986fa165552023440lgao // Vendor ID specified with -f 94130fdf1140b8d1ce93f3821d986fa165552023440lgao // 94230fdf1140b8d1ce93f3821d986fa165552023440lgao if (stricmp (Argv[0], "-f") == 0) { 94330fdf1140b8d1ce93f3821d986fa165552023440lgao // 94430fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure there's another parameter 94530fdf1140b8d1ce93f3821d986fa165552023440lgao // 94630fdf1140b8d1ce93f3821d986fa165552023440lgao Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue); 94730fdf1140b8d1ce93f3821d986fa165552023440lgao if (EFI_ERROR (Status)) { 94830fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]); 94930fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 95030fdf1140b8d1ce93f3821d986fa165552023440lgao } 95130fdf1140b8d1ce93f3821d986fa165552023440lgao if (TempValue >= 0x10000) { 95230fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "Vendor Id %s out of range!", Argv[1]); 95330fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 95430fdf1140b8d1ce93f3821d986fa165552023440lgao } 95530fdf1140b8d1ce93f3821d986fa165552023440lgao Options->VendId = (UINT16) TempValue; 95630fdf1140b8d1ce93f3821d986fa165552023440lgao Options->VendIdValid = 1; 95730fdf1140b8d1ce93f3821d986fa165552023440lgao 95830fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 95930fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 96030fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (stricmp (Argv[0], "-i") == 0) { 96130fdf1140b8d1ce93f3821d986fa165552023440lgao // 96230fdf1140b8d1ce93f3821d986fa165552023440lgao // Device ID specified with -i 96330fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure there's another parameter 96430fdf1140b8d1ce93f3821d986fa165552023440lgao // 96530fdf1140b8d1ce93f3821d986fa165552023440lgao Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue); 96630fdf1140b8d1ce93f3821d986fa165552023440lgao if (EFI_ERROR (Status)) { 96730fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]); 96830fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 96930fdf1140b8d1ce93f3821d986fa165552023440lgao } 97030fdf1140b8d1ce93f3821d986fa165552023440lgao if (TempValue >= 0x10000) { 97130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]); 97230fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 97330fdf1140b8d1ce93f3821d986fa165552023440lgao } 97430fdf1140b8d1ce93f3821d986fa165552023440lgao Options->DevId = (UINT16) TempValue; 97530fdf1140b8d1ce93f3821d986fa165552023440lgao Options->DevIdValid = 1; 97630fdf1140b8d1ce93f3821d986fa165552023440lgao 97730fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 97830fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 97930fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "-o") == 0) || (stricmp (Argv[0], "--output") == 0)) { 98030fdf1140b8d1ce93f3821d986fa165552023440lgao // 98130fdf1140b8d1ce93f3821d986fa165552023440lgao // Output filename specified with -o 98230fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure there's another parameter 98330fdf1140b8d1ce93f3821d986fa165552023440lgao // 98430fdf1140b8d1ce93f3821d986fa165552023440lgao if (Argv[1] == NULL || Argv[1][0] == '-') { 98530fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Missing output file name with %s option!", Argv[0]); 98630fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 98730fdf1140b8d1ce93f3821d986fa165552023440lgao } 98830fdf1140b8d1ce93f3821d986fa165552023440lgao strcpy (Options->OutFileName, Argv[1]); 98930fdf1140b8d1ce93f3821d986fa165552023440lgao 99030fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 99130fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 99230fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "-h") == 0) || (stricmp (Argv[0], "--help") == 0)) { 99330fdf1140b8d1ce93f3821d986fa165552023440lgao // 99430fdf1140b8d1ce93f3821d986fa165552023440lgao // Help option 99530fdf1140b8d1ce93f3821d986fa165552023440lgao // 99630fdf1140b8d1ce93f3821d986fa165552023440lgao Usage (); 99730fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 99830fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (stricmp (Argv[0], "-b") == 0) { 99930fdf1140b8d1ce93f3821d986fa165552023440lgao // 100030fdf1140b8d1ce93f3821d986fa165552023440lgao // Specify binary files with -b 100130fdf1140b8d1ce93f3821d986fa165552023440lgao // 100230fdf1140b8d1ce93f3821d986fa165552023440lgao FileFlags = FILE_FLAG_BINARY; 100330fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) { 100430fdf1140b8d1ce93f3821d986fa165552023440lgao // 100530fdf1140b8d1ce93f3821d986fa165552023440lgao // Specify EFI files with -e. Specify EFI-compressed with -c. 100630fdf1140b8d1ce93f3821d986fa165552023440lgao // 100730fdf1140b8d1ce93f3821d986fa165552023440lgao FileFlags = FILE_FLAG_EFI; 100830fdf1140b8d1ce93f3821d986fa165552023440lgao if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) { 100930fdf1140b8d1ce93f3821d986fa165552023440lgao FileFlags |= FILE_FLAG_COMPRESS; 101030fdf1140b8d1ce93f3821d986fa165552023440lgao } 101130fdf1140b8d1ce93f3821d986fa165552023440lgao // 101230fdf1140b8d1ce93f3821d986fa165552023440lgao // Specify not to set the LAST bit in the last file with -n 101330fdf1140b8d1ce93f3821d986fa165552023440lgao // 101430fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (stricmp (Argv[0], "-n") == 0) { 101530fdf1140b8d1ce93f3821d986fa165552023440lgao Options->NoLast = 1; 101630fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (((stricmp (Argv[0], "-v") == 0)) || ((stricmp (Argv[0], "--verbose") == 0))) { 101730fdf1140b8d1ce93f3821d986fa165552023440lgao // 101830fdf1140b8d1ce93f3821d986fa165552023440lgao // -v for verbose 101930fdf1140b8d1ce93f3821d986fa165552023440lgao // 102030fdf1140b8d1ce93f3821d986fa165552023440lgao Options->Verbose = 1; 102130fdf1140b8d1ce93f3821d986fa165552023440lgao } else if (stricmp (Argv[0], "--debug") == 0) { 102230fdf1140b8d1ce93f3821d986fa165552023440lgao Status = AsciiStringToUint64(Argv[1], FALSE, &DebugLevel); 102330fdf1140b8d1ce93f3821d986fa165552023440lgao if (EFI_ERROR (Status)) { 102430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]); 102530fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 102630fdf1140b8d1ce93f3821d986fa165552023440lgao } 102730fdf1140b8d1ce93f3821d986fa165552023440lgao if (DebugLevel > 9) { 1028fd171542e0aa89ac12a09d79608173f48019b14bvanjeff Error (NULL, 0, 2000, "Invalid option value", "Debug Level range is 0-9, current input level is %d", Argv[1]); 102930fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 103030fdf1140b8d1ce93f3821d986fa165552023440lgao } 103130fdf1140b8d1ce93f3821d986fa165552023440lgao if (DebugLevel>=5 && DebugLevel<=9) { 103230fdf1140b8d1ce93f3821d986fa165552023440lgao Options->Debug = TRUE; 103330fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 103430fdf1140b8d1ce93f3821d986fa165552023440lgao Options->Debug = FALSE; 103530fdf1140b8d1ce93f3821d986fa165552023440lgao } 103630fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 103730fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 103830fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "--quiet") == 0) || (stricmp (Argv[0], "-q") == 0)) { 103930fdf1140b8d1ce93f3821d986fa165552023440lgao Options->Quiet = TRUE; 104030fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "--dump") == 0) || (stricmp (Argv[0], "-d") == 0)) { 104130fdf1140b8d1ce93f3821d986fa165552023440lgao // 104230fdf1140b8d1ce93f3821d986fa165552023440lgao // -dump for dumping a ROM image. In this case, say that the device id 104330fdf1140b8d1ce93f3821d986fa165552023440lgao // and vendor id are valid so we don't have to specify bogus ones on the 104430fdf1140b8d1ce93f3821d986fa165552023440lgao // command line. 104530fdf1140b8d1ce93f3821d986fa165552023440lgao // 104630fdf1140b8d1ce93f3821d986fa165552023440lgao Options->DumpOption = 1; 104730fdf1140b8d1ce93f3821d986fa165552023440lgao 104830fdf1140b8d1ce93f3821d986fa165552023440lgao Options->VendIdValid = 1; 104930fdf1140b8d1ce93f3821d986fa165552023440lgao Options->DevIdValid = 1; 105030fdf1140b8d1ce93f3821d986fa165552023440lgao FileFlags = FILE_FLAG_BINARY; 105130fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "-l") == 0) || (stricmp (Argv[0], "--class-code") == 0)) { 105230fdf1140b8d1ce93f3821d986fa165552023440lgao // 105330fdf1140b8d1ce93f3821d986fa165552023440lgao // Class code value for the next file in the list. 105430fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure there's another parameter 105530fdf1140b8d1ce93f3821d986fa165552023440lgao // 105630fdf1140b8d1ce93f3821d986fa165552023440lgao Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue); 105730fdf1140b8d1ce93f3821d986fa165552023440lgao if (EFI_ERROR (Status)) { 105830fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]); 105930fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 106030fdf1140b8d1ce93f3821d986fa165552023440lgao } 106130fdf1140b8d1ce93f3821d986fa165552023440lgao ClassCode = (UINT32) TempValue; 106230fdf1140b8d1ce93f3821d986fa165552023440lgao if (ClassCode & 0xFF000000) { 106330fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Class code %s out of range!", Argv[1]); 106430fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 106530fdf1140b8d1ce93f3821d986fa165552023440lgao } 106630fdf1140b8d1ce93f3821d986fa165552023440lgao if (FileList != NULL && FileList->ClassCode == 0) { 106730fdf1140b8d1ce93f3821d986fa165552023440lgao FileList->ClassCode = ClassCode; 106830fdf1140b8d1ce93f3821d986fa165552023440lgao } 106930fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 107030fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 107130fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "-r") == 0) || (stricmp (Argv[0], "--Revision") == 0)) { 107230fdf1140b8d1ce93f3821d986fa165552023440lgao // 107330fdf1140b8d1ce93f3821d986fa165552023440lgao // Code revision in the PCI data structure. The value is for the next 107430fdf1140b8d1ce93f3821d986fa165552023440lgao // file in the list. 107530fdf1140b8d1ce93f3821d986fa165552023440lgao // Make sure there's another parameter 107630fdf1140b8d1ce93f3821d986fa165552023440lgao // 107730fdf1140b8d1ce93f3821d986fa165552023440lgao Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue); 107830fdf1140b8d1ce93f3821d986fa165552023440lgao if (EFI_ERROR (Status)) { 107930fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]); 108030fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 108130fdf1140b8d1ce93f3821d986fa165552023440lgao } 108230fdf1140b8d1ce93f3821d986fa165552023440lgao CodeRevision = (UINT32) TempValue; 108330fdf1140b8d1ce93f3821d986fa165552023440lgao if (CodeRevision & 0xFFFF0000) { 108430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Code revision %s out of range!", Argv[1]); 108530fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 108630fdf1140b8d1ce93f3821d986fa165552023440lgao } 108730fdf1140b8d1ce93f3821d986fa165552023440lgao if (FileList != NULL && FileList->CodeRevision == 0) { 108830fdf1140b8d1ce93f3821d986fa165552023440lgao FileList->CodeRevision = (UINT16) CodeRevision; 108930fdf1140b8d1ce93f3821d986fa165552023440lgao } 109030fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 109130fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 109230fdf1140b8d1ce93f3821d986fa165552023440lgao } else if ((stricmp (Argv[0], "-p") == 0) || (stricmp (Argv[0], "--pci23") == 0)) { 109330fdf1140b8d1ce93f3821d986fa165552023440lgao // 109430fdf1140b8d1ce93f3821d986fa165552023440lgao // Default layout meets PCI 3.0 specifications, specifying this flag will for a PCI 2.3 layout. 109530fdf1140b8d1ce93f3821d986fa165552023440lgao // 109630fdf1140b8d1ce93f3821d986fa165552023440lgao mOptions.Pci23 = 1; 109730fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 109830fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Invalid option specified: %s", Argv[0]); 109930fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 110030fdf1140b8d1ce93f3821d986fa165552023440lgao } 110130fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 110230fdf1140b8d1ce93f3821d986fa165552023440lgao // 110330fdf1140b8d1ce93f3821d986fa165552023440lgao // Not a slash-option argument. Must be a file name. Make sure they've specified 110430fdf1140b8d1ce93f3821d986fa165552023440lgao // -e or -b already. 110530fdf1140b8d1ce93f3821d986fa165552023440lgao // 110630fdf1140b8d1ce93f3821d986fa165552023440lgao if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) { 110730fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Missing -e or -b with input file %s!", Argv[0]); 110830fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 110930fdf1140b8d1ce93f3821d986fa165552023440lgao } 111030fdf1140b8d1ce93f3821d986fa165552023440lgao // 111130fdf1140b8d1ce93f3821d986fa165552023440lgao // Check Efi Option RomImage 111230fdf1140b8d1ce93f3821d986fa165552023440lgao // 111330fdf1140b8d1ce93f3821d986fa165552023440lgao if ((FileFlags & FILE_FLAG_EFI) == FILE_FLAG_EFI) { 111430fdf1140b8d1ce93f3821d986fa165552023440lgao EfiRomFlag = TRUE; 111530fdf1140b8d1ce93f3821d986fa165552023440lgao } 111630fdf1140b8d1ce93f3821d986fa165552023440lgao // 111730fdf1140b8d1ce93f3821d986fa165552023440lgao // Create a new file structure 111830fdf1140b8d1ce93f3821d986fa165552023440lgao // 111930fdf1140b8d1ce93f3821d986fa165552023440lgao FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST)); 112030fdf1140b8d1ce93f3821d986fa165552023440lgao if (FileList == NULL) { 112130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL); 112230fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 112330fdf1140b8d1ce93f3821d986fa165552023440lgao } 112430fdf1140b8d1ce93f3821d986fa165552023440lgao 112530fdf1140b8d1ce93f3821d986fa165552023440lgao // 112630fdf1140b8d1ce93f3821d986fa165552023440lgao // set flag and class code for this image. 112730fdf1140b8d1ce93f3821d986fa165552023440lgao // 112830fdf1140b8d1ce93f3821d986fa165552023440lgao memset ((char *) FileList, 0, sizeof (FILE_LIST)); 112930fdf1140b8d1ce93f3821d986fa165552023440lgao FileList->FileName = Argv[0]; 113030fdf1140b8d1ce93f3821d986fa165552023440lgao FileList->FileFlags = FileFlags; 113130fdf1140b8d1ce93f3821d986fa165552023440lgao FileList->ClassCode = ClassCode; 113230fdf1140b8d1ce93f3821d986fa165552023440lgao FileList->CodeRevision = (UINT16) CodeRevision; 113330fdf1140b8d1ce93f3821d986fa165552023440lgao ClassCode = 0; 113430fdf1140b8d1ce93f3821d986fa165552023440lgao CodeRevision = 0; 113530fdf1140b8d1ce93f3821d986fa165552023440lgao 113630fdf1140b8d1ce93f3821d986fa165552023440lgao if (Options->FileList == NULL) { 113730fdf1140b8d1ce93f3821d986fa165552023440lgao Options->FileList = FileList; 113830fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 113930fdf1140b8d1ce93f3821d986fa165552023440lgao if (PrevFileList == NULL) { 114030fdf1140b8d1ce93f3821d986fa165552023440lgao PrevFileList = FileList; 114130fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 114230fdf1140b8d1ce93f3821d986fa165552023440lgao PrevFileList->Next = FileList; 114330fdf1140b8d1ce93f3821d986fa165552023440lgao } 114430fdf1140b8d1ce93f3821d986fa165552023440lgao } 114530fdf1140b8d1ce93f3821d986fa165552023440lgao 114630fdf1140b8d1ce93f3821d986fa165552023440lgao PrevFileList = FileList; 114730fdf1140b8d1ce93f3821d986fa165552023440lgao } 114830fdf1140b8d1ce93f3821d986fa165552023440lgao // 114930fdf1140b8d1ce93f3821d986fa165552023440lgao // Next argument 115030fdf1140b8d1ce93f3821d986fa165552023440lgao // 115130fdf1140b8d1ce93f3821d986fa165552023440lgao Argv++; 115230fdf1140b8d1ce93f3821d986fa165552023440lgao Argc--; 115330fdf1140b8d1ce93f3821d986fa165552023440lgao } 115430fdf1140b8d1ce93f3821d986fa165552023440lgao 115530fdf1140b8d1ce93f3821d986fa165552023440lgao // 115630fdf1140b8d1ce93f3821d986fa165552023440lgao // Must have specified some files 115730fdf1140b8d1ce93f3821d986fa165552023440lgao // 115830fdf1140b8d1ce93f3821d986fa165552023440lgao if (Options->FileList == NULL) { 115930fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Invalid parameter", "Missing input file name!"); 116030fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 116130fdf1140b8d1ce93f3821d986fa165552023440lgao } 116230fdf1140b8d1ce93f3821d986fa165552023440lgao 116330fdf1140b8d1ce93f3821d986fa165552023440lgao // 116430fdf1140b8d1ce93f3821d986fa165552023440lgao // For EFI OptionRom image, Make sure a device ID and vendor ID are both specified. 116530fdf1140b8d1ce93f3821d986fa165552023440lgao // 116630fdf1140b8d1ce93f3821d986fa165552023440lgao if (EfiRomFlag) { 116730fdf1140b8d1ce93f3821d986fa165552023440lgao if (!Options->VendIdValid) { 116830fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Missing Vendor ID in command line", NULL); 116930fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 117030fdf1140b8d1ce93f3821d986fa165552023440lgao } 117130fdf1140b8d1ce93f3821d986fa165552023440lgao 117230fdf1140b8d1ce93f3821d986fa165552023440lgao if (!Options->DevIdValid) { 117330fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 2000, "Missing Device ID in command line", NULL); 117430fdf1140b8d1ce93f3821d986fa165552023440lgao return STATUS_ERROR; 117530fdf1140b8d1ce93f3821d986fa165552023440lgao } 117630fdf1140b8d1ce93f3821d986fa165552023440lgao } 117730fdf1140b8d1ce93f3821d986fa165552023440lgao 117830fdf1140b8d1ce93f3821d986fa165552023440lgao return 0; 117930fdf1140b8d1ce93f3821d986fa165552023440lgao} 118030fdf1140b8d1ce93f3821d986fa165552023440lgao 118130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 118230fdf1140b8d1ce93f3821d986fa165552023440lgaovoid 118330fdf1140b8d1ce93f3821d986fa165552023440lgaoVersion ( 118430fdf1140b8d1ce93f3821d986fa165552023440lgao VOID 118530fdf1140b8d1ce93f3821d986fa165552023440lgao ) 118630fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 118730fdf1140b8d1ce93f3821d986fa165552023440lgao 118830fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 118930fdf1140b8d1ce93f3821d986fa165552023440lgao 119030fdf1140b8d1ce93f3821d986fa165552023440lgao Print version information for this utility. 119130fdf1140b8d1ce93f3821d986fa165552023440lgao 119230fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 119330fdf1140b8d1ce93f3821d986fa165552023440lgao 119430fdf1140b8d1ce93f3821d986fa165552023440lgao None. 119530fdf1140b8d1ce93f3821d986fa165552023440lgao 119630fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 119730fdf1140b8d1ce93f3821d986fa165552023440lgao 119830fdf1140b8d1ce93f3821d986fa165552023440lgao Nothing. 119930fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 120030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 1201b36d134faf4305247830522b8e2bb255e98c5699lgao fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION); 120230fdf1140b8d1ce93f3821d986fa165552023440lgao} 120330fdf1140b8d1ce93f3821d986fa165552023440lgao 120430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 120530fdf1140b8d1ce93f3821d986fa165552023440lgaovoid 120630fdf1140b8d1ce93f3821d986fa165552023440lgaoUsage ( 120730fdf1140b8d1ce93f3821d986fa165552023440lgao VOID 120830fdf1140b8d1ce93f3821d986fa165552023440lgao ) 120930fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 121030fdf1140b8d1ce93f3821d986fa165552023440lgao 121130fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 121230fdf1140b8d1ce93f3821d986fa165552023440lgao 121330fdf1140b8d1ce93f3821d986fa165552023440lgao Print usage information for this utility. 121430fdf1140b8d1ce93f3821d986fa165552023440lgao 121530fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 121630fdf1140b8d1ce93f3821d986fa165552023440lgao 121730fdf1140b8d1ce93f3821d986fa165552023440lgao None. 121830fdf1140b8d1ce93f3821d986fa165552023440lgao 121930fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 122030fdf1140b8d1ce93f3821d986fa165552023440lgao 122130fdf1140b8d1ce93f3821d986fa165552023440lgao Nothing. 122230fdf1140b8d1ce93f3821d986fa165552023440lgao 122330fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 122430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 122530fdf1140b8d1ce93f3821d986fa165552023440lgao // 122630fdf1140b8d1ce93f3821d986fa165552023440lgao // Summary usage 122730fdf1140b8d1ce93f3821d986fa165552023440lgao // 1228d0acc87a41d9aa25fe87eb096efa62afacd1f865lgao fprintf (stdout, "Usage: %s -f VendorId -i DeviceId [options] [file name<s>] \n\n", UTILITY_NAME); 122930fdf1140b8d1ce93f3821d986fa165552023440lgao 123030fdf1140b8d1ce93f3821d986fa165552023440lgao // 123130fdf1140b8d1ce93f3821d986fa165552023440lgao // Copyright declaration 123230fdf1140b8d1ce93f3821d986fa165552023440lgao // 12331be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chen fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n"); 123430fdf1140b8d1ce93f3821d986fa165552023440lgao 123530fdf1140b8d1ce93f3821d986fa165552023440lgao // 123630fdf1140b8d1ce93f3821d986fa165552023440lgao // Details Option 123730fdf1140b8d1ce93f3821d986fa165552023440lgao // 123830fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, "Options:\n"); 123930fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -o FileName, --output FileName\n\ 1240d0acc87a41d9aa25fe87eb096efa62afacd1f865lgao File will be created to store the output content.\n"); 124130fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -e EfiFileName\n\ 124230fdf1140b8d1ce93f3821d986fa165552023440lgao EFI PE32 image files.\n"); 124330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -ec EfiFileName\n\ 124430fdf1140b8d1ce93f3821d986fa165552023440lgao EFI PE32 image files and will be compressed.\n"); 124530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -b BinFileName\n\ 124630fdf1140b8d1ce93f3821d986fa165552023440lgao Legacy binary files.\n"); 124730fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -l ClassCode\n\ 124830fdf1140b8d1ce93f3821d986fa165552023440lgao Hex ClassCode in the PCI data structure header.\n"); 124930fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -r Rev Hex Revision in the PCI data structure header.\n"); 125030fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -n Not to automatically set the LAST bit in the last file.\n"); 125130fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -f VendorId\n\ 1252d0acc87a41d9aa25fe87eb096efa62afacd1f865lgao Hex PCI Vendor ID for the device OpROM, must be specified\n"); 125330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -i DeviceId\n\ 1254d0acc87a41d9aa25fe87eb096efa62afacd1f865lgao Hex PCI Device ID for the device OpROM, must be specified\n"); 125530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -p, --pci23\n\ 125630fdf1140b8d1ce93f3821d986fa165552023440lgao Default layout meets PCI 3.0 specifications\n\ 125730fdf1140b8d1ce93f3821d986fa165552023440lgao specifying this flag will for a PCI 2.3 layout.\n"); 125830fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -d, --dump\n\ 125930fdf1140b8d1ce93f3821d986fa165552023440lgao Dump the headers of an existing option ROM image.\n"); 126030fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -v, --verbose\n\ 126130fdf1140b8d1ce93f3821d986fa165552023440lgao Turn on verbose output with informational messages.\n"); 126230fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " --version Show program's version number and exit.\n"); 126330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -h, --help\n\ 126430fdf1140b8d1ce93f3821d986fa165552023440lgao Show this help message and exit.\n"); 126530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " -q, --quiet\n\ 126630fdf1140b8d1ce93f3821d986fa165552023440lgao Disable all messages except FATAL ERRORS.\n"); 126730fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " --debug [#,0-9]\n\ 126830fdf1140b8d1ce93f3821d986fa165552023440lgao Enable debug messages at level #.\n"); 126930fdf1140b8d1ce93f3821d986fa165552023440lgao} 127030fdf1140b8d1ce93f3821d986fa165552023440lgao 127130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 127230fdf1140b8d1ce93f3821d986fa165552023440lgaovoid 127330fdf1140b8d1ce93f3821d986fa165552023440lgaoDumpImage ( 127430fdf1140b8d1ce93f3821d986fa165552023440lgao FILE_LIST *InFile 127530fdf1140b8d1ce93f3821d986fa165552023440lgao ) 127630fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 127730fdf1140b8d1ce93f3821d986fa165552023440lgao 127830fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 127930fdf1140b8d1ce93f3821d986fa165552023440lgao 128030fdf1140b8d1ce93f3821d986fa165552023440lgao Dump the headers of an existing option ROM image 128130fdf1140b8d1ce93f3821d986fa165552023440lgao 128230fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 128330fdf1140b8d1ce93f3821d986fa165552023440lgao 128430fdf1140b8d1ce93f3821d986fa165552023440lgao InFile - the file name of an existing option ROM image 128530fdf1140b8d1ce93f3821d986fa165552023440lgao 128630fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 128730fdf1140b8d1ce93f3821d986fa165552023440lgao 128830fdf1140b8d1ce93f3821d986fa165552023440lgao none 128930fdf1140b8d1ce93f3821d986fa165552023440lgao 129030fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 129130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 129230fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_EXPANSION_ROM_HEADER PciRomHdr; 129330fdf1140b8d1ce93f3821d986fa165552023440lgao FILE *InFptr; 129430fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 ImageStart; 129530fdf1140b8d1ce93f3821d986fa165552023440lgao UINT32 ImageCount; 129630fdf1140b8d1ce93f3821d986fa165552023440lgao EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr; 129730fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_DATA_STRUCTURE PciDs23; 129830fdf1140b8d1ce93f3821d986fa165552023440lgao PCI_3_0_DATA_STRUCTURE PciDs30; 129930fdf1140b8d1ce93f3821d986fa165552023440lgao 130030fdf1140b8d1ce93f3821d986fa165552023440lgao // 130130fdf1140b8d1ce93f3821d986fa165552023440lgao // Open the input file 130230fdf1140b8d1ce93f3821d986fa165552023440lgao // 13031be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chen if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) { 130430fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 0001, "Error opening file", InFile->FileName); 130530fdf1140b8d1ce93f3821d986fa165552023440lgao return ; 130630fdf1140b8d1ce93f3821d986fa165552023440lgao } 130730fdf1140b8d1ce93f3821d986fa165552023440lgao // 130830fdf1140b8d1ce93f3821d986fa165552023440lgao // Go through the image and dump the header stuff for each 130930fdf1140b8d1ce93f3821d986fa165552023440lgao // 131030fdf1140b8d1ce93f3821d986fa165552023440lgao ImageCount = 0; 131130fdf1140b8d1ce93f3821d986fa165552023440lgao for (;;) { 131230fdf1140b8d1ce93f3821d986fa165552023440lgao // 131330fdf1140b8d1ce93f3821d986fa165552023440lgao // Save our postition in the file, since offsets in the headers 131430fdf1140b8d1ce93f3821d986fa165552023440lgao // are relative to the particular image. 131530fdf1140b8d1ce93f3821d986fa165552023440lgao // 131630fdf1140b8d1ce93f3821d986fa165552023440lgao ImageStart = ftell (InFptr); 131730fdf1140b8d1ce93f3821d986fa165552023440lgao ImageCount++; 131830fdf1140b8d1ce93f3821d986fa165552023440lgao 131930fdf1140b8d1ce93f3821d986fa165552023440lgao // 132030fdf1140b8d1ce93f3821d986fa165552023440lgao // Read the option ROM header. Have to assume a raw binary image for now. 132130fdf1140b8d1ce93f3821d986fa165552023440lgao // 132230fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) { 132330fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Not supported", "Failed to read PCI ROM header from file!"); 132430fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 132530fdf1140b8d1ce93f3821d986fa165552023440lgao } 132630fdf1140b8d1ce93f3821d986fa165552023440lgao 132730fdf1140b8d1ce93f3821d986fa165552023440lgao // 132830fdf1140b8d1ce93f3821d986fa165552023440lgao // Dump the contents of the header 132930fdf1140b8d1ce93f3821d986fa165552023440lgao // 1330fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, "Image %u -- Offset 0x%X\n", (unsigned) ImageCount, (unsigned) ImageStart); 133130fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " ROM header contents\n"); 1332fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Signature 0x%04X\n", PciRomHdr.Signature); 1333fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " PCIR offset 0x%04X\n", PciRomHdr.PcirOffset); 133430fdf1140b8d1ce93f3821d986fa165552023440lgao // 133530fdf1140b8d1ce93f3821d986fa165552023440lgao // Find PCI data structure 133630fdf1140b8d1ce93f3821d986fa165552023440lgao // 133730fdf1140b8d1ce93f3821d986fa165552023440lgao if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) { 133830fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI data structure!"); 133930fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 134030fdf1140b8d1ce93f3821d986fa165552023440lgao } 134130fdf1140b8d1ce93f3821d986fa165552023440lgao // 134230fdf1140b8d1ce93f3821d986fa165552023440lgao // Read and dump the PCI data structure 134330fdf1140b8d1ce93f3821d986fa165552023440lgao // 134430fdf1140b8d1ce93f3821d986fa165552023440lgao memset (&PciDs23, 0, sizeof (PciDs23)); 134530fdf1140b8d1ce93f3821d986fa165552023440lgao memset (&PciDs30, 0, sizeof (PciDs30)); 134630fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 134730fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (&PciDs23, sizeof (PciDs23), 1, InFptr) != 1) { 134830fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile->FileName); 134930fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 135030fdf1140b8d1ce93f3821d986fa165552023440lgao } 135130fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 135230fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (&PciDs30, sizeof (PciDs30), 1, InFptr) != 1) { 135330fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Not supported", "Failed to read PCI data structure from file %s!", InFile->FileName); 135430fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 135530fdf1140b8d1ce93f3821d986fa165552023440lgao } 135630fdf1140b8d1ce93f3821d986fa165552023440lgao } 135730fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Verbose) { 135830fdf1140b8d1ce93f3821d986fa165552023440lgao VerboseMsg("Read PCI data structure from file %s", InFile->FileName); 135930fdf1140b8d1ce93f3821d986fa165552023440lgao } 136030fdf1140b8d1ce93f3821d986fa165552023440lgao 136130fdf1140b8d1ce93f3821d986fa165552023440lgao //fprintf (stdout, " PCI Data Structure\n"); 136230fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 136330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 136430fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 136530fdf1140b8d1ce93f3821d986fa165552023440lgao " Signature %c%c%c%c\n", 136630fdf1140b8d1ce93f3821d986fa165552023440lgao (char) PciDs23.Signature, 136730fdf1140b8d1ce93f3821d986fa165552023440lgao (char) (PciDs23.Signature >> 8), 136830fdf1140b8d1ce93f3821d986fa165552023440lgao (char) (PciDs23.Signature >> 16), 136930fdf1140b8d1ce93f3821d986fa165552023440lgao (char) (PciDs23.Signature >> 24) 137030fdf1140b8d1ce93f3821d986fa165552023440lgao ); 137130fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Vendor ID 0x%04X\n", PciDs23.VendorId); 137230fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Device ID 0x%04X\n", PciDs23.DeviceId); 137330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Length 0x%04X\n", PciDs23.Length); 137430fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Revision 0x%04X\n", PciDs23.Revision); 137530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 137630fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 137730fdf1140b8d1ce93f3821d986fa165552023440lgao " Class Code 0x%06X\n", 1378fd171542e0aa89ac12a09d79608173f48019b14bvanjeff (unsigned) (PciDs23.ClassCode[0] | (PciDs23.ClassCode[1] << 8) | (PciDs23.ClassCode[2] << 16)) 137930fdf1140b8d1ce93f3821d986fa165552023440lgao ); 1380fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Image size 0x%X\n", (unsigned) PciDs23.ImageLength * 512); 138130fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Code revision: 0x%04X\n", PciDs23.CodeRevision); 1382fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Indicator 0x%02X", PciDs23.Indicator); 138330fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 138430fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 138530fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 138630fdf1140b8d1ce93f3821d986fa165552023440lgao " Signature %c%c%c%c\n", 138730fdf1140b8d1ce93f3821d986fa165552023440lgao (char) PciDs30.Signature, 138830fdf1140b8d1ce93f3821d986fa165552023440lgao (char) (PciDs30.Signature >> 8), 138930fdf1140b8d1ce93f3821d986fa165552023440lgao (char) (PciDs30.Signature >> 16), 139030fdf1140b8d1ce93f3821d986fa165552023440lgao (char) (PciDs30.Signature >> 24) 139130fdf1140b8d1ce93f3821d986fa165552023440lgao ); 139230fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Vendor ID 0x%04X\n", PciDs30.VendorId); 139330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Device ID 0x%04X\n", PciDs30.DeviceId); 139430fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Length 0x%04X\n", PciDs30.Length); 139530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Revision 0x%04X\n", PciDs30.Revision); 1396fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " DeviceListOffset 0x%02X\n", PciDs30.DeviceListOffset); 139730fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 139830fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 139930fdf1140b8d1ce93f3821d986fa165552023440lgao " Class Code 0x%06X\n", 1400fd171542e0aa89ac12a09d79608173f48019b14bvanjeff (unsigned) (PciDs30.ClassCode[0] | (PciDs30.ClassCode[1] << 8) | (PciDs30.ClassCode[2] << 16)) 140130fdf1140b8d1ce93f3821d986fa165552023440lgao ); 1402fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Image size 0x%X\n", (unsigned) PciDs30.ImageLength * 512); 140330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " Code revision: 0x%04X\n", PciDs30.CodeRevision); 1404fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " MaxRuntimeImageLength 0x%02X\n", PciDs30.MaxRuntimeImageLength); 1405fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " ConfigUtilityCodeHeaderOffset 0x%02X\n", PciDs30.ConfigUtilityCodeHeaderOffset); 1406fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset); 1407fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Indicator 0x%02X", PciDs30.Indicator); 140830fdf1140b8d1ce93f3821d986fa165552023440lgao } 140930fdf1140b8d1ce93f3821d986fa165552023440lgao // 141030fdf1140b8d1ce93f3821d986fa165552023440lgao // Print the indicator, used to flag the last image 141130fdf1140b8d1ce93f3821d986fa165552023440lgao // 141230fdf1140b8d1ce93f3821d986fa165552023440lgao if (PciDs23.Indicator == INDICATOR_LAST || PciDs30.Indicator == INDICATOR_LAST) { 141330fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " (last image)\n"); 141430fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 141530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, "\n"); 141630fdf1140b8d1ce93f3821d986fa165552023440lgao } 141730fdf1140b8d1ce93f3821d986fa165552023440lgao // 141830fdf1140b8d1ce93f3821d986fa165552023440lgao // Print the code type. If EFI code, then we can provide more info. 141930fdf1140b8d1ce93f3821d986fa165552023440lgao // 142030fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 1421fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Code type 0x%02X", PciDs23.CodeType); 142230fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 1423fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " Code type 0x%02X", PciDs30.CodeType); 142430fdf1140b8d1ce93f3821d986fa165552023440lgao } 142530fdf1140b8d1ce93f3821d986fa165552023440lgao if (PciDs23.CodeType == PCI_CODE_TYPE_EFI_IMAGE || PciDs30.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { 142630fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " (EFI image)\n"); 142730fdf1140b8d1ce93f3821d986fa165552023440lgao // 142830fdf1140b8d1ce93f3821d986fa165552023440lgao // Re-read the header as an EFI ROM header, then dump more info 142930fdf1140b8d1ce93f3821d986fa165552023440lgao // 143030fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, " EFI ROM header contents\n"); 143130fdf1140b8d1ce93f3821d986fa165552023440lgao if (fseek (InFptr, ImageStart, SEEK_SET)) { 143230fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 5001, "Failed to re-seek to ROM header structure!", NULL); 143330fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 143430fdf1140b8d1ce93f3821d986fa165552023440lgao } 143530fdf1140b8d1ce93f3821d986fa165552023440lgao 143630fdf1140b8d1ce93f3821d986fa165552023440lgao if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) { 143730fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 5001, "Failed to read EFI PCI ROM header from file!", NULL); 143830fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 143930fdf1140b8d1ce93f3821d986fa165552023440lgao } 144030fdf1140b8d1ce93f3821d986fa165552023440lgao // 144130fdf1140b8d1ce93f3821d986fa165552023440lgao // Now dump more info 144230fdf1140b8d1ce93f3821d986fa165552023440lgao // 1443fd171542e0aa89ac12a09d79608173f48019b14bvanjeff fprintf (stdout, " EFI Signature 0x%04X\n", (unsigned) EfiRomHdr.EfiSignature); 144430fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 144530fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 144630fdf1140b8d1ce93f3821d986fa165552023440lgao " Compression Type 0x%04X ", 1447fd171542e0aa89ac12a09d79608173f48019b14bvanjeff EfiRomHdr.CompressionType 144830fdf1140b8d1ce93f3821d986fa165552023440lgao ); 144930fdf1140b8d1ce93f3821d986fa165552023440lgao if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { 145030fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, "(compressed)\n"); 145130fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 145230fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, "(not compressed)\n"); 145330fdf1140b8d1ce93f3821d986fa165552023440lgao } 145430fdf1140b8d1ce93f3821d986fa165552023440lgao 145530fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 145630fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 145730fdf1140b8d1ce93f3821d986fa165552023440lgao " Machine type 0x%04X (%s)\n", 145830fdf1140b8d1ce93f3821d986fa165552023440lgao EfiRomHdr.EfiMachineType, 145930fdf1140b8d1ce93f3821d986fa165552023440lgao GetMachineTypeStr (EfiRomHdr.EfiMachineType) 146030fdf1140b8d1ce93f3821d986fa165552023440lgao ); 146130fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 146230fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 146330fdf1140b8d1ce93f3821d986fa165552023440lgao " Subsystem 0x%04X (%s)\n", 146430fdf1140b8d1ce93f3821d986fa165552023440lgao EfiRomHdr.EfiSubsystem, 146530fdf1140b8d1ce93f3821d986fa165552023440lgao GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem) 146630fdf1140b8d1ce93f3821d986fa165552023440lgao ); 146730fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf ( 146830fdf1140b8d1ce93f3821d986fa165552023440lgao stdout, 146930fdf1140b8d1ce93f3821d986fa165552023440lgao " EFI image offset 0x%04X (@0x%X)\n", 1470fd171542e0aa89ac12a09d79608173f48019b14bvanjeff EfiRomHdr.EfiImageHeaderOffset, 1471fd171542e0aa89ac12a09d79608173f48019b14bvanjeff EfiRomHdr.EfiImageHeaderOffset + (unsigned) ImageStart 147230fdf1140b8d1ce93f3821d986fa165552023440lgao ); 147330fdf1140b8d1ce93f3821d986fa165552023440lgao 147430fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 147530fdf1140b8d1ce93f3821d986fa165552023440lgao // 147630fdf1140b8d1ce93f3821d986fa165552023440lgao // Not an EFI image 147730fdf1140b8d1ce93f3821d986fa165552023440lgao // 147830fdf1140b8d1ce93f3821d986fa165552023440lgao fprintf (stdout, "\n"); 147930fdf1140b8d1ce93f3821d986fa165552023440lgao } 148030fdf1140b8d1ce93f3821d986fa165552023440lgao // 148130fdf1140b8d1ce93f3821d986fa165552023440lgao // If code type is EFI image, then dump it as well? 148230fdf1140b8d1ce93f3821d986fa165552023440lgao // 148330fdf1140b8d1ce93f3821d986fa165552023440lgao // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { 148430fdf1140b8d1ce93f3821d986fa165552023440lgao // } 148530fdf1140b8d1ce93f3821d986fa165552023440lgao // 148630fdf1140b8d1ce93f3821d986fa165552023440lgao // If last image, then we're done 148730fdf1140b8d1ce93f3821d986fa165552023440lgao // 148830fdf1140b8d1ce93f3821d986fa165552023440lgao if (PciDs23.Indicator == INDICATOR_LAST || PciDs30.Indicator == INDICATOR_LAST) { 148930fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 149030fdf1140b8d1ce93f3821d986fa165552023440lgao } 149130fdf1140b8d1ce93f3821d986fa165552023440lgao // 149230fdf1140b8d1ce93f3821d986fa165552023440lgao // Seek to the start of the next image 149330fdf1140b8d1ce93f3821d986fa165552023440lgao // 149430fdf1140b8d1ce93f3821d986fa165552023440lgao if (mOptions.Pci23 == 1) { 149530fdf1140b8d1ce93f3821d986fa165552023440lgao if (fseek (InFptr, ImageStart + (PciDs23.ImageLength * 512), SEEK_SET)) { 149630fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Not supported", "Failed to seek to next image!"); 149730fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 149830fdf1140b8d1ce93f3821d986fa165552023440lgao } 149930fdf1140b8d1ce93f3821d986fa165552023440lgao } else { 150030fdf1140b8d1ce93f3821d986fa165552023440lgao if (fseek (InFptr, ImageStart + (PciDs30.ImageLength * 512), SEEK_SET)) { 150130fdf1140b8d1ce93f3821d986fa165552023440lgao Error (NULL, 0, 3001, "Not supported", "Failed to seek to next image!"); 150230fdf1140b8d1ce93f3821d986fa165552023440lgao goto BailOut; 150330fdf1140b8d1ce93f3821d986fa165552023440lgao } 150430fdf1140b8d1ce93f3821d986fa165552023440lgao } 150530fdf1140b8d1ce93f3821d986fa165552023440lgao } 150630fdf1140b8d1ce93f3821d986fa165552023440lgao 150730fdf1140b8d1ce93f3821d986fa165552023440lgaoBailOut: 150830fdf1140b8d1ce93f3821d986fa165552023440lgao fclose (InFptr); 150930fdf1140b8d1ce93f3821d986fa165552023440lgao} 151030fdf1140b8d1ce93f3821d986fa165552023440lgao 151130fdf1140b8d1ce93f3821d986fa165552023440lgaochar * 151230fdf1140b8d1ce93f3821d986fa165552023440lgaoGetMachineTypeStr ( 151330fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 MachineType 151430fdf1140b8d1ce93f3821d986fa165552023440lgao ) 151530fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 151630fdf1140b8d1ce93f3821d986fa165552023440lgao 151730fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 151830fdf1140b8d1ce93f3821d986fa165552023440lgao 151930fdf1140b8d1ce93f3821d986fa165552023440lgao GC_TODO: Add function description 152030fdf1140b8d1ce93f3821d986fa165552023440lgao 152130fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 152230fdf1140b8d1ce93f3821d986fa165552023440lgao 152330fdf1140b8d1ce93f3821d986fa165552023440lgao MachineType - GC_TODO: add argument description 152430fdf1140b8d1ce93f3821d986fa165552023440lgao 152530fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 152630fdf1140b8d1ce93f3821d986fa165552023440lgao 152730fdf1140b8d1ce93f3821d986fa165552023440lgao GC_TODO: add return values 152830fdf1140b8d1ce93f3821d986fa165552023440lgao 152930fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 153030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 153130fdf1140b8d1ce93f3821d986fa165552023440lgao int Index; 153230fdf1140b8d1ce93f3821d986fa165552023440lgao 153330fdf1140b8d1ce93f3821d986fa165552023440lgao for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) { 153430fdf1140b8d1ce93f3821d986fa165552023440lgao if (mMachineTypes[Index].Value == MachineType) { 153530fdf1140b8d1ce93f3821d986fa165552023440lgao return mMachineTypes[Index].Name; 153630fdf1140b8d1ce93f3821d986fa165552023440lgao } 153730fdf1140b8d1ce93f3821d986fa165552023440lgao } 153830fdf1140b8d1ce93f3821d986fa165552023440lgao 153930fdf1140b8d1ce93f3821d986fa165552023440lgao return "unknown"; 154030fdf1140b8d1ce93f3821d986fa165552023440lgao} 154130fdf1140b8d1ce93f3821d986fa165552023440lgao 154230fdf1140b8d1ce93f3821d986fa165552023440lgaostatic 154330fdf1140b8d1ce93f3821d986fa165552023440lgaochar * 154430fdf1140b8d1ce93f3821d986fa165552023440lgaoGetSubsystemTypeStr ( 154530fdf1140b8d1ce93f3821d986fa165552023440lgao UINT16 SubsystemType 154630fdf1140b8d1ce93f3821d986fa165552023440lgao ) 154730fdf1140b8d1ce93f3821d986fa165552023440lgao/*++ 154830fdf1140b8d1ce93f3821d986fa165552023440lgao 154930fdf1140b8d1ce93f3821d986fa165552023440lgaoRoutine Description: 155030fdf1140b8d1ce93f3821d986fa165552023440lgao 155130fdf1140b8d1ce93f3821d986fa165552023440lgao GC_TODO: Add function description 155230fdf1140b8d1ce93f3821d986fa165552023440lgao 155330fdf1140b8d1ce93f3821d986fa165552023440lgaoArguments: 155430fdf1140b8d1ce93f3821d986fa165552023440lgao 155530fdf1140b8d1ce93f3821d986fa165552023440lgao SubsystemType - GC_TODO: add argument description 155630fdf1140b8d1ce93f3821d986fa165552023440lgao 155730fdf1140b8d1ce93f3821d986fa165552023440lgaoReturns: 155830fdf1140b8d1ce93f3821d986fa165552023440lgao 155930fdf1140b8d1ce93f3821d986fa165552023440lgao GC_TODO: add return values 156030fdf1140b8d1ce93f3821d986fa165552023440lgao 156130fdf1140b8d1ce93f3821d986fa165552023440lgao--*/ 156230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 156330fdf1140b8d1ce93f3821d986fa165552023440lgao int Index; 156430fdf1140b8d1ce93f3821d986fa165552023440lgao 156530fdf1140b8d1ce93f3821d986fa165552023440lgao for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) { 156630fdf1140b8d1ce93f3821d986fa165552023440lgao if (mSubsystemTypes[Index].Value == SubsystemType) { 156730fdf1140b8d1ce93f3821d986fa165552023440lgao return mSubsystemTypes[Index].Name; 156830fdf1140b8d1ce93f3821d986fa165552023440lgao } 156930fdf1140b8d1ce93f3821d986fa165552023440lgao } 157030fdf1140b8d1ce93f3821d986fa165552023440lgao 157130fdf1140b8d1ce93f3821d986fa165552023440lgao return "unknown"; 157230fdf1140b8d1ce93f3821d986fa165552023440lgao} 1573