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