]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/EfiRom/EfiRom.c
BaseTools: Various typo
[mirror_edk2.git] / BaseTools / Source / C / EfiRom / EfiRom.c
index c58c1523e95a5368db4f43217219399faaa71534..0c52eb74845947de772bbfd2ebf41e5073d81ab3 100644 (file)
@@ -1,9 +1,9 @@
 /** @file\r
 Utility program to create an EFI option ROM image from binary and EFI PE32 files.\r
 \r
-Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available \r
-under the terms and conditions of the BSD License which accompanies this \r
+Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available\r
+under the terms and conditions of the BSD License which accompanies this\r
 distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
@@ -26,8 +26,8 @@ main (
 /*++\r
 \r
 Routine Description:\r
-  \r
-  Given an EFI image filename, create a ROM-able image by creating an option \r
+\r
+  Given an EFI image filename, create a ROM-able image by creating an option\r
   ROM header and PCI data structure, filling them in, and then writing the\r
   option ROM header + PCI data structure + EFI image out to the output file.\r
 \r
@@ -71,11 +71,11 @@ Returns:
   } else if (mOptions.Debug) {\r
     SetPrintLevel(DebugLevel);\r
   }\r
-  \r
+\r
   if (mOptions.Verbose) {\r
     VerboseMsg("%s tool start.\n", UTILITY_NAME);\r
   }\r
-  \r
+\r
   //\r
   // If dumping an image, then do that and quit\r
   //\r
@@ -96,16 +96,24 @@ Returns:
   //\r
   if (!mOptions.OutFileName[0]) {\r
     if (mOptions.FileList != NULL) {\r
-      strcpy (mOptions.OutFileName, mOptions.FileList->FileName);\r
+      if (strlen (mOptions.FileList->FileName) >= MAX_PATH) {\r
+        Status = STATUS_ERROR;\r
+        Error (NULL, 0, 2000, "Invalid parameter", "Input file name is too long - %s.", mOptions.FileList->FileName);\r
+        goto BailOut;\r
+      }\r
+      strncpy (mOptions.OutFileName, mOptions.FileList->FileName, MAX_PATH - 1);\r
+      mOptions.OutFileName[MAX_PATH - 1] = 0;\r
       //\r
       // Find the last . on the line and replace the filename extension with\r
       // the default\r
       //\r
-      for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;\r
-           (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');\r
-           Ext--\r
-          )\r
-        ;\r
+      Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;\r
+      while (Ext >= mOptions.OutFileName) {\r
+        if ((*Ext == '.') || (*Ext == '\\')) {\r
+          break;\r
+        }\r
+        Ext--;\r
+      }\r
       //\r
       // If dot here, then insert extension here, otherwise append\r
       //\r
@@ -144,7 +152,7 @@ Returns:
         VerboseMsg("Processing EFI file    %s\n", FList->FileName);\r
       }\r
 \r
-      Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size);\r
+      Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevIdList[0], &Size);\r
     } else if ((FList->FileFlags & FILE_FLAG_BINARY) !=0 ) {\r
       if (mOptions.Verbose) {\r
         VerboseMsg("Processing binary file %s\n", FList->FileName);\r
@@ -184,8 +192,14 @@ BailOut:
       free (mOptions.FileList);\r
       mOptions.FileList = FList;\r
     }\r
-  }\r
 \r
+    //\r
+    // Clean up device ID list\r
+    //\r
+    if (mOptions.DevIdList != NULL) {\r
+      free (mOptions.DevIdList);\r
+    }\r
+  }\r
   if (FptrOut != NULL) {\r
     fclose (FptrOut);\r
   }\r
@@ -194,7 +208,7 @@ BailOut:
     VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());\r
   }\r
 \r
-  return GetUtilityStatus (); \r
+  return GetUtilityStatus ();\r
 }\r
 \r
 static\r
@@ -207,7 +221,7 @@ ProcessBinFile (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Process a binary input file.\r
 \r
 Arguments:\r
@@ -233,7 +247,7 @@ Returns:
   UINT32                    Index;\r
   UINT8                     ByteCheckSum;\r
   UINT16                    CodeType;\r
\r
+\r
   PciDs23 = NULL;\r
   PciDs30 = NULL;\r
   Status = STATUS_SUCCESS;\r
@@ -242,7 +256,7 @@ Returns:
   // Try to open the input file\r
   //\r
   if ((InFptr = fopen (LongFilePath (InFile->FileName), "rb")) == NULL) {\r
-    Error (NULL, 0, 0001, "Error opening file", InFile->FileName);\r
+    Error (NULL, 0, 0001, "Error opening file", "%s", InFile->FileName);\r
     return STATUS_ERROR;\r
   }\r
   //\r
@@ -337,7 +351,7 @@ Returns:
   } else {\r
     PciDs30->ImageLength = (UINT16) (TotalSize / 512);\r
     CodeType = PciDs30->CodeType;\r
-       }\r
+  }\r
 \r
   //\r
   // If this is the last image, then set the LAST bit unless requested not\r
@@ -348,13 +362,13 @@ Returns:
       PciDs23->Indicator = INDICATOR_LAST;\r
     } else {\r
       PciDs30->Indicator = INDICATOR_LAST;\r
-               }\r
+    }\r
   } else {\r
     if (mOptions.Pci23 == 1) {\r
       PciDs23->Indicator = 0;\r
     } else {\r
       PciDs30->Indicator = 0;\r
-               }\r
+    }\r
   }\r
 \r
   if (CodeType != PCI_CODE_TYPE_EFI_IMAGE) {\r
@@ -417,7 +431,7 @@ ProcessEfiFile (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Process a PE32 EFI file.\r
 \r
 Arguments:\r
@@ -451,6 +465,7 @@ Returns:
   UINT32                        HeaderPadBytes;\r
   UINT32                        PadBytesBeforeImage;\r
   UINT32                        PadBytesAfterImage;\r
+  UINT32                        DevIdListSize;\r
 \r
   //\r
   // Try to open the input file\r
@@ -487,14 +502,23 @@ Returns:
   } else {\r
     HeaderPadBytes = 0;\r
   }\r
-  \r
+\r
   //\r
   // For Pci3.0 to use the different data structure.\r
   //\r
   if (mOptions.Pci23 == 1) {\r
     HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);\r
   } else {\r
-    HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);\r
+    if (mOptions.DevIdCount > 1) {\r
+      //\r
+      // Write device ID list when more than one device ID is specified.\r
+      // Leave space for list plus terminator.\r
+      //\r
+      DevIdListSize = (mOptions.DevIdCount + 1) * sizeof (UINT16);\r
+    } else {\r
+      DevIdListSize = 0;\r
+    }\r
+    HeaderSize = sizeof (PCI_3_0_DATA_STRUCTURE) + HeaderPadBytes + DevIdListSize + sizeof (EFI_PCI_EXPANSION_ROM_HEADER);\r
   }\r
 \r
   if (mOptions.Verbose) {\r
@@ -576,7 +600,7 @@ Returns:
   // Check size\r
   //\r
   if (TotalSize > MAX_OPTION_ROM_SIZE) {\r
-    Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);  \r
+    Error (NULL, 0, 2000, "Invalid", "Option ROM image %s size exceeds limit of 0x%X bytes.", InFile->FileName, MAX_OPTION_ROM_SIZE);\r
     Status = STATUS_ERROR;\r
     goto BailOut;\r
   }\r
@@ -631,7 +655,14 @@ Returns:
     PciDs30.Signature = PCI_DATA_STRUCTURE_SIGNATURE;\r
     PciDs30.VendorId  = VendId;\r
     PciDs30.DeviceId  = DevId;\r
-    PciDs30.DeviceListOffset = 0; // to be fixed\r
+    if (mOptions.DevIdCount > 1) {\r
+      //\r
+      // Place device list immediately after PCI structure\r
+      //\r
+      PciDs30.DeviceListOffset = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);\r
+    } else {\r
+      PciDs30.DeviceListOffset = 0;\r
+    }\r
     PciDs30.Length    = (UINT16) sizeof (PCI_3_0_DATA_STRUCTURE);\r
     PciDs30.Revision  = 0x3;\r
     //\r
@@ -654,12 +685,12 @@ Returns:
   if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) {\r
     if (mOptions.Pci23 == 1) {\r
       PciDs23.Indicator = INDICATOR_LAST;\r
-         } else {\r
+    } else {\r
     PciDs30.Indicator = INDICATOR_LAST;}\r
   } else {\r
     if (mOptions.Pci23 == 1) {\r
       PciDs23.Indicator = 0;\r
-       } else {\r
+  } else {\r
       PciDs30.Indicator = 0;\r
     }\r
   }\r
@@ -692,15 +723,35 @@ Returns:
       Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);\r
       Status = STATUS_ERROR;\r
       goto BailOut;\r
-    } \r
+    }\r
   } else {\r
     if (fwrite (&PciDs30, sizeof (PciDs30), 1, OutFptr) != 1) {\r
       Error (NULL, 0, 0002, "Failed to write PCI ROM header to output file!", NULL);\r
       Status = STATUS_ERROR;\r
       goto BailOut;\r
-    } \r
+    }\r
+  }\r
+\r
+  //\r
+  // Write the Device ID list to the output file\r
+  //\r
+  if (mOptions.DevIdCount > 1) {\r
+    if (fwrite (mOptions.DevIdList, sizeof (UINT16), mOptions.DevIdCount, OutFptr) != mOptions.DevIdCount) {\r
+      Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);\r
+      Status = STATUS_ERROR;\r
+      goto BailOut;\r
+    }\r
+    //\r
+    // Write two-byte terminating 0 at the end of the device list\r
+    //\r
+    if (putc (0, OutFptr) == EOF || putc (0, OutFptr) == EOF) {\r
+      Error (NULL, 0, 0002, "Failed to write PCI device list to output file!", NULL);\r
+      Status = STATUS_ERROR;\r
+      goto BailOut;\r
+    }\r
   }\r
 \r
+\r
   //\r
   // Pad head to make it a multiple of 512 bytes\r
   //\r
@@ -768,7 +819,7 @@ CheckPE32File (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Given a file pointer to a supposed PE32 image file, verify that it is indeed a\r
   PE32 image file, and then return the machine type in the supplied pointer.\r
 \r
@@ -860,7 +911,7 @@ ParseCommandLine (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Given the Argc/Argv program arguments, and a pointer to an options structure,\r
   parse the command-line options and check their validity.\r
 \r
@@ -887,6 +938,8 @@ Returns:
   INTN       ReturnStatus;\r
   BOOLEAN    EfiRomFlag;\r
   UINT64     TempValue;\r
+  char       *OptionName;\r
+  UINT16     *DevIdList;\r
 \r
   ReturnStatus = 0;\r
   FileFlags = 0;\r
@@ -902,6 +955,9 @@ Returns:
   //\r
   FileList                = PrevFileList = NULL;\r
 \r
+  Options->DevIdList      = NULL;\r
+  Options->DevIdCount     = 0;\r
+\r
   ClassCode               = 0;\r
   CodeRevision            = 0;\r
   //\r
@@ -917,12 +973,12 @@ Returns:
     Usage ();\r
     return STATUS_ERROR;\r
   }\r
-  \r
+\r
   if ((stricmp(Argv[0], "-h") == 0) || (stricmp(Argv[0], "--help") == 0)) {\r
     Usage();\r
     return STATUS_ERROR;\r
   }\r
-  \r
+\r
   if ((stricmp(Argv[0], "--version") == 0)) {\r
     Version();\r
     return STATUS_ERROR;\r
@@ -957,26 +1013,53 @@ Returns:
         Argv++;\r
         Argc--;\r
       } else if (stricmp (Argv[0], "-i") == 0) {\r
+\r
+        OptionName = Argv[0];\r
+\r
         //\r
-        // Device ID specified with -i\r
-        // Make sure there's another parameter\r
+        // Device IDs specified with -i\r
+        // Make sure there's at least one more parameter\r
         //\r
-        Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);\r
-        if (EFI_ERROR (Status)) {\r
-          Error (NULL, 0, 2000, "Invalid option value", "%s = %s", Argv[0], Argv[1]);\r
+        if (Argc < 1) {\r
+          Error (NULL, 0, 2000, "Invalid parameter", "Missing Device Id with %s option!", OptionName);\r
           ReturnStatus = 1;\r
           goto Done;\r
         }\r
-        if (TempValue >= 0x10000) {\r
-          Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);\r
-          ReturnStatus = 1;\r
-          goto Done;\r
+\r
+        //\r
+        // Process until another dash-argument parameter or the end of the list\r
+        //\r
+        while (Argc > 1 && Argv[1][0] != '-') {\r
+          Status = AsciiStringToUint64(Argv[1], FALSE, &TempValue);\r
+          if (EFI_ERROR (Status)) {\r
+            Error (NULL, 0, 2000, "Invalid option value", "%s = %s", OptionName, Argv[1]);\r
+            ReturnStatus = 1;\r
+            goto Done;\r
+          }\r
+          //\r
+          // Don't allow device IDs greater than 16 bits\r
+          // Don't allow 0, since it is used as a list terminator\r
+          //\r
+          if (TempValue >= 0x10000 || TempValue == 0) {\r
+            Error (NULL, 0, 2000, "Invalid option value", "Device Id %s out of range!", Argv[1]);\r
+            ReturnStatus = 1;\r
+            goto Done;\r
+          }\r
+\r
+          DevIdList = (UINT16*) realloc (Options->DevIdList, (Options->DevIdCount + 1) * sizeof (UINT16));\r
+          if (DevIdList == NULL) {\r
+            Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!", NULL);\r
+            ReturnStatus = 1;\r
+            goto Done;\r
+          }\r
+          Options->DevIdList = DevIdList;\r
+\r
+          Options->DevIdList[Options->DevIdCount++] = (UINT16) TempValue;\r
+\r
+          Argv++;\r
+          Argc--;\r
         }\r
-        Options->DevId      = (UINT16) TempValue;\r
-        Options->DevIdValid = 1;\r
 \r
-        Argv++;\r
-        Argc--;\r
       } else if ((stricmp (Argv[0], "-o") == 0) || (stricmp (Argv[0], "--output") == 0)) {\r
         //\r
         // Output filename specified with -o\r
@@ -1057,7 +1140,7 @@ Returns:
         Options->DumpOption   = 1;\r
 \r
         Options->VendIdValid  = 1;\r
-        Options->DevIdValid   = 1;\r
+        Options->DevIdCount   = 1;\r
         FileFlags             = FILE_FLAG_BINARY;\r
       } else if ((stricmp (Argv[0], "-l") == 0) || (stricmp (Argv[0], "--class-code") == 0)) {\r
         //\r
@@ -1139,7 +1222,7 @@ Returns:
         ReturnStatus = STATUS_ERROR;\r
         goto Done;\r
       }\r
-      \r
+\r
       //\r
       // set flag and class code for this image.\r
       //\r
@@ -1156,7 +1239,7 @@ Returns:
       } else {\r
         if (PrevFileList == NULL) {\r
           PrevFileList = FileList;\r
-        } else {          \r
+        } else {\r
           PrevFileList->Next = FileList;\r
         }\r
       }\r
@@ -1190,14 +1273,20 @@ Returns:
       ReturnStatus = STATUS_ERROR;\r
       goto Done;\r
     }\r
-  \r
-    if (!Options->DevIdValid) {\r
+\r
+    if (!Options->DevIdCount) {\r
       Error (NULL, 0, 2000, "Missing Device ID in command line", NULL);\r
       ReturnStatus = STATUS_ERROR;\r
       goto Done;\r
     }\r
   }\r
 \r
+   if (Options->DevIdCount > 1 && Options->Pci23) {\r
+     Error (NULL, 0, 2000, "Invalid parameter", "PCI 3.0 is required when specifying multiple Device IDs");\r
+     ReturnStatus = STATUS_ERROR;\r
+     goto Done;\r
+   }\r
+\r
 Done:\r
   if (ReturnStatus != 0) {\r
     while (Options->FileList != NULL) {\r
@@ -1218,7 +1307,7 @@ Version (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Print version information for this utility.\r
 \r
 Arguments:\r
@@ -1232,7 +1321,7 @@ Returns:
 {\r
  fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
 }\r
-   \r
+\r
 static\r
 void\r
 Usage (\r
@@ -1241,7 +1330,7 @@ Usage (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Print usage information for this utility.\r
 \r
 Arguments:\r
@@ -1258,11 +1347,11 @@ Returns:
   // Summary usage\r
   //\r
   fprintf (stdout, "Usage: %s -f VendorId -i DeviceId [options] [file name<s>] \n\n", UTILITY_NAME);\r
-  \r
+\r
   //\r
   // Copyright declaration\r
-  // \r
-  fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
+  //\r
+  fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
@@ -1283,7 +1372,7 @@ Returns:
   fprintf (stdout, "  -f VendorId\n\\r
             Hex PCI Vendor ID for the device OpROM, must be specified\n");\r
   fprintf (stdout, "  -i DeviceId\n\\r
-            Hex PCI Device ID for the device OpROM, must be specified\n");\r
+            One or more hex PCI Device IDs for the device OpROM, must be specified\n");\r
   fprintf (stdout, "  -p, --pci23\n\\r
             Default layout meets PCI 3.0 specifications\n\\r
             specifying this flag will for a PCI 2.3 layout.\n");\r
@@ -1297,7 +1386,7 @@ Returns:
   fprintf (stdout, "  -q, --quiet\n\\r
             Disable all messages except FATAL ERRORS.\n");\r
   fprintf (stdout, "  --debug [#,0-9]\n\\r
-            Enable debug messages at level #.\n");  \r
+            Enable debug messages at level #.\n");\r
 }\r
 \r
 static\r
@@ -1328,6 +1417,7 @@ Returns:
   EFI_PCI_EXPANSION_ROM_HEADER  EfiRomHdr;\r
   PCI_DATA_STRUCTURE            PciDs23;\r
   PCI_3_0_DATA_STRUCTURE        PciDs30;\r
+  UINT16                        DevId;\r
 \r
   //\r
   // Open the input file\r
@@ -1342,7 +1432,7 @@ Returns:
   ImageCount = 0;\r
   for (;;) {\r
     //\r
-    // Save our postition in the file, since offsets in the headers\r
+    // Save our position in the file, since offsets in the headers\r
     // are relative to the particular image.\r
     //\r
     ImageStart = ftell (InFptr);\r
@@ -1425,7 +1515,31 @@ Returns:
     fprintf (stdout, "    Device ID               0x%04X\n", PciDs30.DeviceId);\r
     fprintf (stdout, "    Length                  0x%04X\n", PciDs30.Length);\r
     fprintf (stdout, "    Revision                0x%04X\n", PciDs30.Revision);\r
-    fprintf (stdout, "    DeviceListOffset        0x%02X\n", PciDs30.DeviceListOffset);    \r
+    fprintf (stdout, "    DeviceListOffset        0x%02X\n", PciDs30.DeviceListOffset);\r
+    if (PciDs30.DeviceListOffset) {\r
+      //\r
+      // Print device ID list\r
+      //\r
+      fprintf (stdout, "    Device list contents\n");\r
+      if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset + PciDs30.DeviceListOffset, SEEK_SET)) {\r
+        Error (NULL, 0, 3001, "Not supported", "Failed to seek to PCI device ID list!");\r
+        goto BailOut;\r
+      }\r
+\r
+      //\r
+      // Loop until terminating 0\r
+      //\r
+      do {\r
+        if (fread (&DevId, sizeof (DevId), 1, InFptr) != 1) {\r
+          Error (NULL, 0, 3001, "Not supported", "Failed to read PCI device ID list from file %s!", InFile->FileName);\r
+          goto BailOut;\r
+        }\r
+        if (DevId) {\r
+          fprintf (stdout, "      0x%04X\n", DevId);\r
+        }\r
+      } while (DevId);\r
+\r
+    }\r
     fprintf (\r
       stdout,\r
       "    Class Code              0x%06X\n",\r
@@ -1435,8 +1549,8 @@ Returns:
     fprintf (stdout, "    Code revision:          0x%04X\n", PciDs30.CodeRevision);\r
     fprintf (stdout, "    MaxRuntimeImageLength   0x%02X\n", PciDs30.MaxRuntimeImageLength);\r
     fprintf (stdout, "    ConfigUtilityCodeHeaderOffset 0x%02X\n", PciDs30.ConfigUtilityCodeHeaderOffset);\r
-    fprintf (stdout, "    DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset);   \r
-    fprintf (stdout, "    Indicator               0x%02X", PciDs30.Indicator);    \r
+    fprintf (stdout, "    DMTFCLPEntryPointOffset 0x%02X\n", PciDs30.DMTFCLPEntryPointOffset);\r
+    fprintf (stdout, "    Indicator               0x%02X", PciDs30.Indicator);\r
     }\r
     //\r
     // Print the indicator, used to flag the last image\r
@@ -1452,7 +1566,7 @@ Returns:
     if (mOptions.Pci23 == 1) {\r
       fprintf (stdout, "    Code type              0x%02X", PciDs23.CodeType);\r
     } else {\r
-      fprintf (stdout, "    Code type               0x%02X", PciDs30.CodeType); \r
+      fprintf (stdout, "    Code type               0x%02X", PciDs30.CodeType);\r
     }\r
     if (PciDs23.CodeType == PCI_CODE_TYPE_EFI_IMAGE || PciDs30.CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
       fprintf (stdout, "   (EFI image)\n");\r