From nobody Tue Apr 30 08:54:20 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1503386829848928.0808995910977; Tue, 22 Aug 2017 00:27:09 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 5914521E49BD3; Tue, 22 Aug 2017 00:24:35 -0700 (PDT) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 58D7721E49BA6 for ; Tue, 22 Aug 2017 00:24:34 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga104.jf.intel.com with ESMTP; 22 Aug 2017 00:27:06 -0700 Received: from shwdeopenpsi168.ccr.corp.intel.com ([10.239.158.121]) by orsmga002.jf.intel.com with ESMTP; 22 Aug 2017 00:27:05 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,411,1498546800"; d="scan'208";a="126824988" From: Yonghong Zhu To: edk2-devel@lists.01.org Date: Tue, 22 Aug 2017 15:27:01 +0800 Message-Id: <1503386821-50364-1-git-send-email-yonghong.zhu@intel.com> X-Mailer: git-send-email 2.6.1.windows.1 Subject: [edk2] [Patch] BaseTools/EfiRom: Add multiple device id support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Liming Gao , Daniel Verkamp MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Daniel Verkamp This is a patch to implement writing and dumping of PCI 3.0 Device ID lists in EFI option ROMs in the EfiRom tool. Using this modification, multiple space-delimited device IDs can be specified after -i. The first device in the list is used for the main PCI ROM header Device ID field and is also written in the list. The list is only written when more than one device ID has been specified; when only one device ID is given on the command line, the EfiRom output should be identical to the current code. Fixes: https://bugzilla.tianocore.org/show_bug.cgi?id=3D666 Cc: Liming Gao Cc: Tomas Pilar Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daniel Verkamp Reviewed-by: Liming Gao --- BaseTools/Source/C/EfiRom/EfiRom.c | 146 ++++++++++++++++++++++++++++++++-= ---- BaseTools/Source/C/EfiRom/EfiRom.h | 6 +- 2 files changed, 129 insertions(+), 23 deletions(-) diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom= /EfiRom.c index 84322e3..6b30596 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -142,11 +142,11 @@ Returns: if ((FList->FileFlags & FILE_FLAG_EFI) !=3D 0) { if (mOptions.Verbose) { VerboseMsg("Processing EFI file %s\n", FList->FileName); } =20 - Status =3D ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions= .DevId, &Size); + Status =3D ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions= .DevIdList[0], &Size); } else if ((FList->FileFlags & FILE_FLAG_BINARY) !=3D0 ) { if (mOptions.Verbose) { VerboseMsg("Processing binary file %s\n", FList->FileName); } =20 @@ -182,12 +182,18 @@ BailOut: while (mOptions.FileList !=3D NULL) { FList =3D mOptions.FileList->Next; free (mOptions.FileList); mOptions.FileList =3D FList; } + + // + // Clean up device ID list + // + if (mOptions.DevIdList !=3D NULL) { + free (mOptions.DevIdList); + } } - if (FptrOut !=3D NULL) { fclose (FptrOut); } =20 if (mOptions.Verbose) { @@ -449,10 +455,11 @@ Returns: UINT16 MachineType; UINT16 SubSystem; UINT32 HeaderPadBytes; UINT32 PadBytesBeforeImage; UINT32 PadBytesAfterImage; + UINT32 DevIdListSize; =20 // // Try to open the input file // if ((InFptr =3D fopen (LongFilePath (InFile->FileName), "rb")) =3D=3D NU= LL) { @@ -492,11 +499,20 @@ Returns: // For Pci3.0 to use the different data structure. // if (mOptions.Pci23 =3D=3D 1) { HeaderSize =3D sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (= EFI_PCI_EXPANSION_ROM_HEADER); } else { - HeaderSize =3D sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + size= of (EFI_PCI_EXPANSION_ROM_HEADER); + if (mOptions.DevIdCount > 1) { + // + // Write device ID list when more than one device ID is specified. + // Leave space for list plus terminator. + // + DevIdListSize =3D (mOptions.DevIdCount + 1) * sizeof (UINT16); + } else { + DevIdListSize =3D 0; + } + HeaderSize =3D sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + DevI= dListSize + sizeof (EFI_PCI_EXPANSION_ROM_HEADER); } =20 if (mOptions.Verbose) { VerboseMsg(" File size =3D 0x%X\n", (unsigned) FileSize); } @@ -629,11 +645,18 @@ Returns: PciDs23.CodeType =3D PCI_CODE_TYPE_EFI_IMAGE; } else { PciDs30.Signature =3D PCI_DATA_STRUCTURE_SIGNATURE; PciDs30.VendorId =3D VendId; PciDs30.DeviceId =3D DevId; - PciDs30.DeviceListOffset =3D 0; // to be fixed + if (mOptions.DevIdCount > 1) { + // + // Place device list immediately after PCI structure + // + PciDs30.DeviceListOffset =3D (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE= ); + } else { + PciDs30.DeviceListOffset =3D 0; + } PciDs30.Length =3D (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE); PciDs30.Revision =3D 0x3; // // Class code and code revision from the command line (optional) // @@ -699,10 +722,30 @@ Returns: Status =3D STATUS_ERROR; goto BailOut; }=20 } =20 + // + // Write the Device ID list to the output file + // + if (mOptions.DevIdCount > 1) { + if (fwrite (mOptions.DevIdList, sizeof (UINT16), mOptions.DevIdCount, = OutFptr) !=3D mOptions.DevIdCount) { + Error (NULL, 0, 0002, "Failed to write PCI device list to output fil= e!", NULL); + Status =3D STATUS_ERROR; + goto BailOut; + } + // + // Write two-byte terminating 0 at the end of the device list + // + if (putc (0, OutFptr) =3D=3D EOF || putc (0, OutFptr) =3D=3D EOF) { + Error (NULL, 0, 0002, "Failed to write PCI device list to output fil= e!", NULL); + Status =3D STATUS_ERROR; + goto BailOut; + } + } + + // // Pad head to make it a multiple of 512 bytes // while (PadBytesBeforeImage > 0) { if (putc (~0, OutFptr) =3D=3D EOF) { @@ -885,10 +928,12 @@ Returns: UINT32 CodeRevision; EFI_STATUS Status; INTN ReturnStatus; BOOLEAN EfiRomFlag; UINT64 TempValue; + char *OptionName; + UINT16 *DevIdList; =20 ReturnStatus =3D 0; FileFlags =3D 0; EfiRomFlag =3D FALSE; =20 @@ -900,10 +945,13 @@ Returns: // // To avoid compile warnings // FileList =3D PrevFileList =3D NULL; =20 + Options->DevIdList =3D NULL; + Options->DevIdCount =3D 0; + ClassCode =3D 0; CodeRevision =3D 0; // // Skip over the program name // @@ -955,30 +1003,57 @@ Returns: Options->VendIdValid =3D 1; =20 Argv++; Argc--; } else if (stricmp (Argv[0], "-i") =3D=3D 0) { + + OptionName =3D Argv[0]; + // - // Device ID specified with -i - // Make sure there's another parameter + // Device IDs specified with -i + // Make sure there's at least one more parameter // - Status =3D AsciiStringToUint64(Argv[1], FALSE, &TempValue); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 2000, "Invalid option value", "%s =3D %s", Argv[= 0], Argv[1]); + if (Argc < 1) { + Error (NULL, 0, 2000, "Invalid parameter", "Missing Device Id wi= th %s option!", OptionName); ReturnStatus =3D 1; goto Done; } - if (TempValue >=3D 0x10000) { - Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out = of range!", Argv[1]); - ReturnStatus =3D 1; - goto Done; + + // + // Process until another dash-argument parameter or the end of the= list + // + while (Argc > 1 && Argv[1][0] !=3D '-') { + Status =3D AsciiStringToUint64(Argv[1], FALSE, &TempValue); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 2000, "Invalid option value", "%s =3D %s", Opt= ionName, Argv[1]); + ReturnStatus =3D 1; + goto Done; + } + // + // Don't allow device IDs greater than 16 bits + // Don't allow 0, since it is used as a list terminator + // + if (TempValue >=3D 0x10000 || TempValue =3D=3D 0) { + Error (NULL, 0, 2000, "Invalid option value", "Device Id %s ou= t of range!", Argv[1]); + ReturnStatus =3D 1; + goto Done; + } + + DevIdList =3D (UINT16*) realloc (Options->DevIdList, (Options->D= evIdCount + 1) * sizeof (UINT16)); + if (DevIdList =3D=3D NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!= ", NULL); + ReturnStatus =3D 1; + goto Done; + } + Options->DevIdList =3D DevIdList; + + Options->DevIdList[Options->DevIdCount++] =3D (UINT16) TempValue; + + Argv++; + Argc--; } - Options->DevId =3D (UINT16) TempValue; - Options->DevIdValid =3D 1; =20 - Argv++; - Argc--; } else if ((stricmp (Argv[0], "-o") =3D=3D 0) || (stricmp (Argv[0], = "--output") =3D=3D 0)) { // // Output filename specified with -o // Make sure there's another parameter // @@ -1055,11 +1130,11 @@ Returns: // command line. // Options->DumpOption =3D 1; =20 Options->VendIdValid =3D 1; - Options->DevIdValid =3D 1; + Options->DevIdCount =3D 1; FileFlags =3D FILE_FLAG_BINARY; } else if ((stricmp (Argv[0], "-l") =3D=3D 0) || (stricmp (Argv[0], = "--class-code") =3D=3D 0)) { // // Class code value for the next file in the list. // Make sure there's another parameter @@ -1189,16 +1264,22 @@ Returns: Error (NULL, 0, 2000, "Missing Vendor ID in command line", NULL); ReturnStatus =3D STATUS_ERROR; goto Done; } =20 - if (!Options->DevIdValid) { + if (!Options->DevIdCount) { Error (NULL, 0, 2000, "Missing Device ID in command line", NULL); ReturnStatus =3D STATUS_ERROR; goto Done; } } + + if (Options->DevIdCount > 1 && Options->Pci23) { + Error (NULL, 0, 2000, "Invalid parameter", "PCI 3.0 is required when = specifying multiple Device IDs"); + ReturnStatus =3D STATUS_ERROR; + goto Done; + } =20 Done: if (ReturnStatus !=3D 0) { while (Options->FileList !=3D NULL) { FileList =3D Options->FileList->Next; @@ -1281,11 +1362,11 @@ Returns: fprintf (stdout, " -r Rev Hex Revision in the PCI data structure hea= der.\n"); fprintf (stdout, " -n Not to automatically set the LAST bit in t= he last file.\n"); fprintf (stdout, " -f VendorId\n\ Hex PCI Vendor ID for the device OpROM, must be specified\n"); fprintf (stdout, " -i DeviceId\n\ - Hex PCI Device ID for the device OpROM, must be specified\n"); + One or more hex PCI Device IDs for the device OpROM, must be s= pecified\n"); fprintf (stdout, " -p, --pci23\n\ Default layout meets PCI 3.0 specifications\n\ specifying this flag will for a PCI 2.3 layout.\n"); fprintf (stdout, " -d, --dump\n\ Dump the headers of an existing option ROM image.\n"); @@ -1326,10 +1407,11 @@ Returns: UINT32 ImageStart; UINT32 ImageCount; EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr; PCI_DATA_STRUCTURE PciDs23; PCI_3_0_DATA_STRUCTURE PciDs30; + UINT16 DevId; =20 // // Open the input file // if ((InFptr =3D fopen (LongFilePath (InFile->FileName), "rb")) =3D=3D NU= LL) { @@ -1424,10 +1506,34 @@ Returns: fprintf (stdout, " Vendor ID 0x%04X\n", PciDs30.Vendo= rId); fprintf (stdout, " Device ID 0x%04X\n", PciDs30.Devic= eId); fprintf (stdout, " Length 0x%04X\n", PciDs30.Lengt= h); fprintf (stdout, " Revision 0x%04X\n", PciDs30.Revis= ion); fprintf (stdout, " DeviceListOffset 0x%02X\n", PciDs30.Devic= eListOffset); =20 + if (PciDs30.DeviceListOffset) { + // + // Print device ID list + // + fprintf (stdout, " Device list contents\n"); + if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs30.Devic= eListOffset, SEEK_SET)) { + Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI devi= ce ID list!"); + goto BailOut; + } + + // + // Loop until terminating 0 + // + do { + if (fread (&DevId, sizeof (DevId), 1, InFptr) !=3D 1) { + Error (NULL, 0, 3001, "Not supported", "Failed to read PCI devic= e ID list from file %s!", InFile->FileName); + goto BailOut; + } + if (DevId) { + fprintf (stdout, " 0x%04X\n", DevId); + } + } while (DevId); + + } fprintf ( stdout, " Class Code 0x%06X\n", (unsigned) (PciDs30.ClassCode[0] | (PciDs30.ClassCode[1] << 8) | (Pc= iDs30.ClassCode[2] << 16)) ); diff --git a/BaseTools/Source/C/EfiRom/EfiRom.h b/BaseTools/Source/C/EfiRom= /EfiRom.h index 6763d6b..f90c63f 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.h +++ b/BaseTools/Source/C/EfiRom/EfiRom.h @@ -1,9 +1,9 @@ /** @file This file contains the relevant declarations required to generate Option R= om File =20 -Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.
+Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made availabl= e=20 under the terms and conditions of the BSD License which accompanies this=20 distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php =20 @@ -81,13 +81,13 @@ typedef struct { CHAR8 OutFileName[MAX_PATH]; INT8 NoLast; UINT16 ClassCode; UINT16 PciRevision; UINT16 VendId; - UINT16 DevId; + UINT16 *DevIdList; + UINT32 DevIdCount; UINT8 VendIdValid; - UINT8 DevIdValid; INT8 Verbose; INT8 Quiet; INT8 Debug; INT8 Pci23; INT8 Pci30; --=20 2.6.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel