]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Loaded Image device paths for EFI Drivers loaded from PCI Option ROM
authorgikidy <gikidy@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 3 Apr 2009 08:18:43 +0000 (08:18 +0000)
committergikidy <gikidy@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 3 Apr 2009 08:18:43 +0000 (08:18 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8025 6f19259b-4bc3-4df7-8a09-765794883524

13 files changed:
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBus.h
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.h
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c
IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h
IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c

index 9dfdbe62d77ea664f03062c6ce11add937e80391..5b0428bec4f811ed606c9e5b3f8a7605a3af4774 100644 (file)
@@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/LoadedImage.h>\r
 #include <Protocol/PciHostBridgeResourceAllocation.h>\r
 #include <Protocol/PciIo.h>\r
+#include <Protocol/LoadFile2.h>\r
 #include <Guid/PciHotplugDevice.h>\r
 #include <Protocol/PciRootBridgeIo.h>\r
 #include <Protocol/PciHotPlugRequest.h>\r
@@ -129,6 +130,7 @@ typedef struct _PCI_IO_DEVICE {
   EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride;\r
   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;\r
   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *PciRootBridgeIo;\r
+  EFI_LOAD_FILE2_PROTOCOL                   LoadFile2;\r
 \r
   //\r
   // PCI configuration space header type\r
@@ -230,6 +232,9 @@ typedef struct _PCI_IO_DEVICE {
 #define PCI_IO_DEVICE_FROM_LINK(a) \\r
   CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE)\r
 \r
+#define PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS(a) \\r
+  CR (a, PCI_IO_DEVICE, LoadFile2, PCI_IO_DEVICE_SIGNATURE)\r
+\r
 //\r
 // Global Variables\r
 //\r
index 8fa69ec72951f205eb33245e90d528bfc62c05e6..b5fa1e1f32130330c52247e4a1c55236e25f5c7c 100644 (file)
   gEfiDevicePathProtocolGuid                    # PROTOCOL TO_START\r
   gEfiIncompatiblePciDeviceSupportProtocolGuid  # PROTOCOL TO_START\r
   gEfiUgaIoProtocolGuid                         # ALWAYS_CONSUMED     System Table\r
+  gEfiLoadFile2ProtocolGuid                                            # SOMETIMES_CONSUMED\r
 \r
 [FeaturePcd.common]\r
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciVgaEnable\r
index 3f72a71d731c6ffbbf96f091ea5b769715f351e0..d461aef4d0dff846eeeb8b825613c940b09e746d 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
+Copyright (c) 2006 - 2009, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -220,6 +220,7 @@ RegisterPciDevice (
   UINT8               PciExpressCapRegOffset;\r
   EFI_PCI_IO_PROTOCOL *PciIo;\r
   UINT8               Data8;\r
+  BOOLEAN             HasEfiImage;\r
 \r
   //\r
   // Install the pciio protocol, device path protocol\r
@@ -261,7 +262,6 @@ RegisterPciDevice (
   // Process OpRom\r
   //\r
   if (!PciIoDevice->AllOpRomProcessed) {\r
-    PciIoDevice->AllOpRomProcessed = TRUE;\r
 \r
     //\r
     // Get the OpRom provided by platform\r
@@ -279,7 +279,7 @@ RegisterPciDevice (
         PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;\r
         //\r
         // For OpROM read from gPciPlatformProtocol:\r
-        //   Add the Rom Image to internal database for later PCI light enumeration\r
+        // Add the Rom Image to internal database for later PCI light enumeration\r
         //\r
         PciRomAddImageMapping (\r
           NULL,\r
@@ -290,16 +290,46 @@ RegisterPciDevice (
           (UINT64) (UINTN) PciIoDevice->PciIo.RomImage,\r
           PciIoDevice->PciIo.RomSize\r
           );\r
-        \r
       }\r
     }\r
+  }\r
+\r
+  //\r
+  // Determine if there are EFI images in the option rom\r
+  //\r
+  HasEfiImage = ContainEfiImage (PciIoDevice->PciIo.RomImage, PciIoDevice->PciIo.RomSize);\r
+\r
+  if (HasEfiImage) {\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &PciIoDevice->Handle,\r
+                    &gEfiLoadFile2ProtocolGuid,\r
+                    &PciIoDevice->LoadFile2,\r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->UninstallMultipleProtocolInterfaces (\r
+             &PciIoDevice->Handle,\r
+             &gEfiDevicePathProtocolGuid,\r
+             PciIoDevice->DevicePath,\r
+             &gEfiPciIoProtocolGuid,\r
+             &PciIoDevice->PciIo,\r
+             NULL\r
+             );\r
+      return Status;\r
+    }\r
+  }\r
+\r
+\r
+  if (!PciIoDevice->AllOpRomProcessed) {\r
+\r
+    PciIoDevice->AllOpRomProcessed = TRUE;\r
 \r
     //\r
     // Dispatch the EFI OpRom for the PCI device.\r
     // The OpRom is got from platform in the above code\r
-    //   or loaded from device in previous bus enumeration\r
+    // or loaded from device in the previous round of bus enumeration\r
     //\r
-    if (PciIoDevice->RomSize > 0) {\r
+    if (HasEfiImage) {\r
       ProcessOpRomImage (PciIoDevice);\r
     }\r
   }\r
@@ -323,6 +353,14 @@ RegisterPciDevice (
              &PciIoDevice->PciIo,\r
              NULL\r
              );\r
+      if (HasEfiImage) {\r
+        gBS->UninstallMultipleProtocolInterfaces (\r
+               &PciIoDevice->Handle,\r
+               &gEfiLoadFile2ProtocolGuid,\r
+               &PciIoDevice->LoadFile2,\r
+               NULL\r
+               );\r
+      }\r
 \r
       return Status;\r
     }\r
@@ -507,6 +545,33 @@ DeRegisterPciDevice (
                       );\r
     }\r
 \r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Try to uninstall LoadFile2 protocol if exists\r
+      //\r
+      Status = gBS->OpenProtocol (\r
+                      Handle,\r
+                      &gEfiLoadFile2ProtocolGuid,\r
+                      NULL,\r
+                      gPciBusDriverBinding.DriverBindingHandle,\r
+                      Controller,\r
+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                        Handle,\r
+                        &gEfiLoadFile2ProtocolGuid,\r
+                        &PciIoDevice->LoadFile2,\r
+                        NULL\r
+                        );\r
+      }\r
+      //\r
+      // Restore Status\r
+      //\r
+      Status = EFI_SUCCESS;\r
+    }\r
+\r
+\r
     if (EFI_ERROR (Status)) {\r
       gBS->OpenProtocol (\r
             Controller,\r
@@ -825,8 +890,9 @@ CreateRootBridge (
   //\r
   // Initialize the PCI I/O instance structure\r
   //\r
-  Status  = InitializePciIoInstance (Dev);\r
-  Status  = InitializePciDriverOverrideInstance (Dev);\r
+  InitializePciIoInstance (Dev);\r
+  InitializePciDriverOverrideInstance (Dev);\r
+  InitializePciLoadFile2 (Dev);\r
 \r
   //\r
   // Initialize reserved resource list and\r
index 6ec208453e91be79d93edf1dfd97651a4f864fd1..d8faf8f7e45083d86213ac146a702b66fb884260 100644 (file)
@@ -19,15 +19,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
   @param  PciIoDevice   Device instance.\r
 \r
-  @retval EFI_SUCCESS Operation success.\r
 **/\r
-EFI_STATUS\r
+VOID\r
 InitializePciDriverOverrideInstance (\r
   PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
   PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
-  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
index c30d4e1c561e5879fe4b0f0be4ea1a82b805d8a3..4c402b2a47c44b956736b2cdb131146b06b9f7ec 100644 (file)
@@ -32,9 +32,8 @@ typedef struct {
 \r
   @param  PciIoDevice   Device instance.\r
 \r
-  @retval EFI_SUCCESS Operation success.\r
 **/\r
-EFI_STATUS\r
+VOID\r
 InitializePciDriverOverrideInstance (\r
   PCI_IO_DEVICE  *PciIoDevice\r
   );\r
index 47f2fe1afd5accf0c428f4a7b4cdfbfdbffe2466..ae5b7db8da8105797f8f4332c060a6df9ff4f13a 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006, Intel Corporation\r
+Copyright (c) 2006 - 2009, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -1664,13 +1664,10 @@ CreatePciIoDevice (
   // Initialize the PCI I/O instance structure\r
   //\r
 \r
-  Status  = InitializePciIoInstance (PciIoDevice);\r
-  Status  = InitializePciDriverOverrideInstance (PciIoDevice);\r
+  InitializePciIoInstance (PciIoDevice);\r
+  InitializePciDriverOverrideInstance (PciIoDevice);\r
+  InitializePciLoadFile2 (PciIoDevice);\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (PciIoDevice);\r
-    return NULL;\r
-  }\r
 \r
   //\r
   // Initialize the reserved resource list\r
index 43a8fb34bbc5392c653c017a3aee5e100e3f157a..f92a5beeca42a749085f948595ac2f932ba7d086 100644 (file)
@@ -90,15 +90,13 @@ ReportErrorStatusCode (
   \r
   @param PciIoDevice  Pci device instance.\r
   \r
-  @retval EFI_SUCCESS  Success operation.\r
 **/\r
-EFI_STATUS\r
+VOID\r
 InitializePciIoInstance (\r
   PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
   CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));\r
-  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
index 5d7b8b340948bd34fc64a576126068a669adf2d1..43612d7e1c7b0543435ccd88a2ee337a7295ce91 100644 (file)
@@ -20,9 +20,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   \r
   @param PciIoDevice  Pci device instance.\r
   \r
-  @retval EFI_SUCCESS  Success operation.\r
 **/\r
-EFI_STATUS\r
+VOID\r
 InitializePciIoInstance (\r
   PCI_IO_DEVICE  *PciIoDevice\r
   );\r
index ea9ac25b13195ce6ce7d3d154d263bb28e2bdf4b..f12b566098c6f49cc63b6f22cdd6816dafab3239 100644 (file)
@@ -16,6 +16,202 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <IndustryStandard/Pci23.h>\r
 \r
+/**\r
+  Load the EFI Image from Option ROM\r
+  \r
+  @param PciIoDevice   PCI IO Device\r
+  @param FilePath      The file path of the EFI Image\r
+  @param BufferSize    On input the size of Buffer in bytes. On output with a return \r
+                       code of EFI_SUCCESS, the amount of data transferred to Buffer. \r
+                       On output with a return code of EFI_BUFFER_TOO_SMALL, \r
+                       the size of Buffer required to retrieve the requested file. \r
+  @param Buffer        The memory buffer to transfer the file to. If Buffer is NULL, \r
+                       then no the size of the requested file is returned in BufferSize.\r
+\r
+  @retval EFI_SUCCESS           The file was loaded. \r
+  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.\r
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current directory entry.\r
+                                BufferSize has been updated with the size needed to complete the request.\r
+**/\r
+EFI_STATUS\r
+LocalLoadFile2 (\r
+  IN PCI_IO_DEVICE            *PciIoDevice,\r
+  IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+  IN OUT UINTN                *BufferSize,\r
+  IN VOID                     *Buffer      OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                                Status;\r
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH   *EfiOpRomImageNode;\r
+  EFI_PCI_EXPANSION_ROM_HEADER              *EfiRomHeader;\r
+  PCI_DATA_STRUCTURE                        *Pcir;\r
+  UINT32                                    ImageSize;\r
+  UINT8                                     *ImageBuffer;\r
+  UINT32                                    ImageLength;\r
+  UINT32                                    DestinationSize;\r
+  UINT32                                    ScratchSize;\r
+  VOID                                      *Scratch;\r
+  EFI_DECOMPRESS_PROTOCOL                   *Decompress;\r
+\r
+  EfiOpRomImageNode = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) FilePath;\r
+  if ((EfiOpRomImageNode == NULL) ||\r
+      (DevicePathType (FilePath) != MEDIA_DEVICE_PATH) ||\r
+      (DevicePathSubType (FilePath) != MEDIA_RELATIVE_OFFSET_RANGE_DP) ||\r
+      (DevicePathNodeLength (FilePath) != sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)) ||\r
+      (!IsDevicePathEnd (NextDevicePathNode (FilePath))) ||\r
+      (EfiOpRomImageNode->StartingOffset > EfiOpRomImageNode->EndingOffset) ||\r
+      (EfiOpRomImageNode->EndingOffset >= PciIoDevice->RomSize) ||\r
+      (BufferSize == NULL)\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (\r
+      (UINT8 *) PciIoDevice->PciIo.RomImage + EfiOpRomImageNode->StartingOffset\r
+      );\r
+  if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  \r
+  Pcir = (PCI_DATA_STRUCTURE *) ((UINT8 *) EfiRomHeader + EfiRomHeader->PcirOffset);\r
+\r
+  \r
+  if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && \r
+      (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&\r
+      ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+       (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) &&\r
+      (EfiRomHeader->CompressionType <= EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED)\r
+       ) {\r
+\r
+    ImageSize               = (UINT32) EfiRomHeader->InitializationSize * 512;\r
+    \r
+    ImageBuffer             = (UINT8 *) EfiRomHeader + EfiRomHeader->EfiImageHeaderOffset;\r
+    ImageLength             = ImageSize - EfiRomHeader->EfiImageHeaderOffset;\r
+\r
+    if (EfiRomHeader->CompressionType != EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+      //\r
+      // Uncompressed: Copy the EFI Image directly to user's buffer\r
+      //\r
+      if (Buffer == NULL || *BufferSize < ImageLength) {\r
+        *BufferSize = ImageLength;\r
+        return EFI_BUFFER_TOO_SMALL;\r
+      }\r
+\r
+      *BufferSize = ImageLength;\r
+      CopyMem (Buffer, ImageBuffer, ImageLength);\r
+      return EFI_SUCCESS;\r
+\r
+    } else {\r
+      //\r
+      // Compressed: Uncompress before copying\r
+      //\r
+      Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, &Decompress);\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      Status = Decompress->GetInfo (\r
+                             Decompress,\r
+                             ImageBuffer,\r
+                             ImageLength,\r
+                             &DestinationSize,\r
+                             &ScratchSize\r
+                             );\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_DEVICE_ERROR;\r
+      } \r
+      \r
+      if (Buffer == NULL || *BufferSize < DestinationSize) {\r
+        *BufferSize = DestinationSize;\r
+        return EFI_BUFFER_TOO_SMALL;\r
+      }      \r
+\r
+      *BufferSize = DestinationSize;\r
+      Scratch = AllocatePool (ScratchSize);\r
+      if (Scratch == NULL) {\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      \r
+      Status = Decompress->Decompress (\r
+                             Decompress,\r
+                             ImageBuffer,\r
+                             ImageLength,\r
+                             Buffer,\r
+                             DestinationSize,\r
+                             Scratch,\r
+                             ScratchSize\r
+                             );\r
+      gBS->FreePool (Scratch);\r
+      \r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Initialize a PCI LoadFile2 instance\r
+  \r
+  @param PciIoDevice - PCI IO Device\r
+\r
+**/\r
+VOID\r
+InitializePciLoadFile2 (\r
+  PCI_IO_DEVICE       *PciIoDevice\r
+  )\r
+{\r
+  PciIoDevice->LoadFile2.LoadFile = LoadFile2;\r
+}\r
+\r
+/**\r
+  Causes the driver to load a specified file.\r
+  \r
+  @param This        Indicates a pointer to the calling context.\r
+  @param FilePath    The device specific path of the file to load.\r
+  @param BootPolicy  Should always be FALSE.\r
+  @param BufferSize  On input the size of Buffer in bytes. On output with a return \r
+                     code of EFI_SUCCESS, the amount of data transferred to Buffer. \r
+                     On output with a return code of EFI_BUFFER_TOO_SMALL, \r
+                     the size of Buffer required to retrieve the requested file. \r
+  @param Buffer      The memory buffer to transfer the file to. If Buffer is NULL, \r
+                    then no the size of the requested file is returned in BufferSize.\r
+\r
+  @retval EFI_SUCCESS           The file was loaded. \r
+  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.\r
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current directory entry.\r
+                                BufferSize has been updated with the size needed to complete the request.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LoadFile2 (\r
+  IN EFI_LOAD_FILE2_PROTOCOL  *This,\r
+  IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+  IN BOOLEAN                  BootPolicy,\r
+  IN OUT UINTN                *BufferSize,\r
+  IN VOID                     *Buffer      OPTIONAL\r
+  )\r
+{\r
+  PCI_IO_DEVICE                             *PciIoDevice;\r
+\r
+  if (BootPolicy) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS (This);\r
+\r
+  return LocalLoadFile2 (\r
+           PciIoDevice,\r
+           FilePath,\r
+           BufferSize,\r
+           Buffer\r
+           );\r
+}\r
+\r
+\r
 //\r
 // Module global for a template of the PCI option ROM Image Device Path Node\r
 //\r
@@ -124,6 +320,54 @@ GetOpRomInfo (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+\r
+  Check if the RomImage contains EFI Images.\r
+\r
+  @param  RomImage  The ROM address of Image for check. \r
+  @param  RomSize   Size of ROM for check.\r
+\r
+  @retval TRUE     ROM contain EFI Image.\r
+  @retval FALSE    ROM not contain EFI Image.\r
+  \r
+**/\r
+BOOLEAN\r
+ContainEfiImage (\r
+  IN VOID            *RomImage,\r
+  IN UINT64          RomSize\r
+  )  \r
+{\r
+  PCI_EXPANSION_ROM_HEADER  *RomHeader;\r
+  PCI_DATA_STRUCTURE        *RomPcir;\r
+  BOOLEAN                   FirstCheck;\r
+\r
+  FirstCheck = TRUE;\r
+  RomHeader  = RomImage;\r
+  \r
+  while ((UINT8 *) RomHeader < (UINT8 *) RomImage + RomSize) {\r
+    if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+      if (FirstCheck) {\r
+        return FALSE;\r
+      } else {\r
+        RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + 512);\r
+        continue;\r
+      }\r
+    }\r
+\r
+    FirstCheck = FALSE;\r
+    RomPcir    = (PCI_DATA_STRUCTURE *) ((UINT8 *) RomHeader + RomHeader->PcirOffset);\r
+    \r
+    if (RomPcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
+      return TRUE;\r
+    }\r
+\r
+    RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + RomPcir->Length * 512);\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
 /**\r
   Load option rom image for specified PCI device\r
   \r
@@ -396,25 +640,20 @@ ProcessOpRomImage (
 {\r
   UINT8                         Indicator;\r
   UINT32                        ImageSize;\r
-  UINT16                        ImageOffset;\r
   VOID                          *RomBar;\r
   UINT8                         *RomBarOffset;\r
   EFI_HANDLE                    ImageHandle;\r
   EFI_STATUS                    Status;\r
   EFI_STATUS                    RetStatus;\r
   BOOLEAN                       FirstCheck;\r
-  BOOLEAN                       SkipImage;\r
-  UINT32                        DestinationSize;\r
-  UINT32                        ScratchSize;\r
-  UINT8                         *Scratch;\r
-  VOID                          *ImageBuffer;\r
-  VOID                          *DecompressedImageBuffer;\r
-  UINT32                        ImageLength;\r
-  EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
   EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;\r
   PCI_DATA_STRUCTURE            *Pcir;\r
   EFI_DEVICE_PATH_PROTOCOL      *PciOptionRomImageDevicePath;\r
 \r
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH  EfiOpRomImageNode;                            \r
+  VOID                          *Buffer;\r
+  UINTN                         BufferSize;\r
+\r
   Indicator = 0;\r
 \r
   //\r
@@ -428,7 +667,7 @@ ProcessOpRomImage (
   do {\r
     EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
     if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
-      RomBarOffset = RomBarOffset + 512;\r
+      RomBarOffset += 512;\r
       if (FirstCheck) {\r
         break;\r
       } else {\r
@@ -441,120 +680,73 @@ ProcessOpRomImage (
     ImageSize   = (UINT32) (Pcir->ImageLength * 512);\r
     Indicator   = Pcir->Indicator;\r
 \r
-    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
-        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {\r
-\r
-      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)  ||\r
-          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) {\r
-\r
-        ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;\r
-        ImageSize               = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
-\r
-        ImageBuffer             = (VOID *) (RomBarOffset + ImageOffset);\r
-        ImageLength             = ImageSize - (UINT32)ImageOffset;\r
-        DecompressedImageBuffer = NULL;\r
-\r
-        //\r
-        // decompress here if needed\r
-        //\r
-        SkipImage = FALSE;\r
-        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
-          SkipImage = TRUE;\r
-        }\r
-\r
-        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
-          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
-          if (EFI_ERROR (Status)) {\r
-            SkipImage = TRUE;\r
-          } else {\r
-            SkipImage = TRUE;\r
-            Status = Decompress->GetInfo (\r
-                                  Decompress,\r
-                                  ImageBuffer,\r
-                                  ImageLength,\r
-                                  &DestinationSize,\r
-                                  &ScratchSize\r
-                                  );\r
-            if (!EFI_ERROR (Status)) {\r
-              DecompressedImageBuffer = NULL;\r
-              DecompressedImageBuffer = AllocatePool (DestinationSize);\r
-              if (DecompressedImageBuffer != NULL) {\r
-                Scratch = AllocatePool (ScratchSize);\r
-                if (Scratch != NULL) {\r
-                  Status = Decompress->Decompress (\r
-                                        Decompress,\r
-                                        ImageBuffer,\r
-                                        ImageLength,\r
-                                        DecompressedImageBuffer,\r
-                                        DestinationSize,\r
-                                        Scratch,\r
-                                        ScratchSize\r
-                                        );\r
-                  if (!EFI_ERROR (Status)) {\r
-                    ImageBuffer = DecompressedImageBuffer;\r
-                    ImageLength = DestinationSize;\r
-                    SkipImage   = FALSE;\r
-                  }\r
-\r
-                  gBS->FreePool (Scratch);\r
-                }\r
-              }\r
-            }\r
-          }\r
-        }\r
-\r
-        if (!SkipImage) {\r
-          //\r
-          // Build Memory Mapped device path node to record the image offset into the PCI Option ROM\r
-          //\r
-          mPciOptionRomImageDevicePathNodeTemplate.StartingAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (RomBarOffset - (UINT8 *) RomBar);\r
-          mPciOptionRomImageDevicePathNodeTemplate.EndingAddress   = (EFI_PHYSICAL_ADDRESS) (UINTN) (RomBarOffset + ImageSize - 1 - (UINT8 *) RomBar);\r
-          PciOptionRomImageDevicePath = AppendDevicePathNode (PciDevice->DevicePath, (const EFI_DEVICE_PATH_PROTOCOL *)&mPciOptionRomImageDevicePathNodeTemplate);\r
-          ASSERT (PciOptionRomImageDevicePath != NULL);\r
-\r
-          //\r
-          // load image and start image\r
-          //\r
-          Status = gBS->LoadImage (\r
-                          FALSE,\r
-                          gPciBusDriverBinding.DriverBindingHandle,\r
-                          PciOptionRomImageDevicePath,\r
-                          ImageBuffer,\r
-                          ImageLength,\r
-                          &ImageHandle\r
-                          );\r
-\r
-          //\r
-          // Free the device path after it has been used by LoadImage\r
-          //\r
-          gBS->FreePool (PciOptionRomImageDevicePath);\r
-\r
-          if (!EFI_ERROR (Status)) {\r
-            Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
-            if (!EFI_ERROR (Status)) {\r
-              AddDriver (PciDevice, ImageHandle);\r
-              PciRomAddImageMapping (\r
-                ImageHandle,\r
-                PciDevice->PciRootBridgeIo->SegmentNumber,\r
-                PciDevice->BusNumber,\r
-                PciDevice->DeviceNumber,\r
-                PciDevice->FunctionNumber,\r
-                (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
-                PciDevice->PciIo.RomSize\r
-                );\r
-              RetStatus = EFI_SUCCESS;\r
-            }\r
-          }\r
-        }\r
+    //\r
+    // Create Pci Option Rom Image device path header\r
+    //\r
+    EfiOpRomImageNode.Header.Type     = MEDIA_DEVICE_PATH;\r
+    EfiOpRomImageNode.Header.SubType  = MEDIA_RELATIVE_OFFSET_RANGE_DP;\r
+    SetDevicePathNodeLength (&EfiOpRomImageNode.Header, sizeof (EfiOpRomImageNode));\r
+    EfiOpRomImageNode.StartingOffset  = (UINTN) RomBarOffset - (UINTN) RomBar;\r
+    EfiOpRomImageNode.EndingOffset    = (UINTN) RomBarOffset + ImageSize - 1 - (UINTN) RomBar;\r
 \r
-        RomBarOffset = RomBarOffset + ImageSize;\r
-      } else {\r
-        RomBarOffset = RomBarOffset + ImageSize;\r
+    PciOptionRomImageDevicePath = AppendDevicePathNode (PciDevice->DevicePath, &EfiOpRomImageNode.Header);\r
+    ASSERT (PciOptionRomImageDevicePath != NULL);\r
+\r
+    //\r
+    // load image and start image\r
+    //\r
+\r
+    BufferSize  = 0;\r
+    Buffer      = NULL;\r
+    Status      = EFI_SUCCESS;\r
+    ImageHandle = NULL;\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gBS->LoadImage (\r
+                      FALSE,\r
+                      gPciBusDriverBinding.DriverBindingHandle,\r
+                      PciOptionRomImageDevicePath,\r
+                      Buffer,\r
+                      BufferSize,\r
+                      &ImageHandle\r
+                      );\r
+    }\r
+\r
+    //\r
+    // load image and start image\r
+    //\r
+     if (!EFI_ERROR (Status)) {\r
+      Status = gBS->LoadImage (\r
+                      FALSE,\r
+                      gPciBusDriverBinding.DriverBindingHandle,\r
+                      PciOptionRomImageDevicePath,\r
+                      Buffer,\r
+                      BufferSize,\r
+                      &ImageHandle\r
+                      );\r
+    }\r
+\r
+    gBS->FreePool (PciOptionRomImageDevicePath);\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+      if (!EFI_ERROR (Status)) {\r
+        AddDriver (PciDevice, ImageHandle);\r
+        PciRomAddImageMapping (\r
+          ImageHandle,\r
+          PciDevice->PciRootBridgeIo->SegmentNumber,\r
+          PciDevice->BusNumber,\r
+          PciDevice->DeviceNumber,\r
+          PciDevice->FunctionNumber,\r
+          (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
+          PciDevice->PciIo.RomSize\r
+          );\r
+        RetStatus = EFI_SUCCESS;\r
       }\r
-    } else {\r
-      RomBarOffset = RomBarOffset + ImageSize;\r
     }\r
 \r
+    RomBarOffset += ImageSize;\r
+\r
   } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
 \r
   return RetStatus;\r
index de84f2825b573da191d20fdd6cfd970cfc24a278..d245f3e0f13703339c26baff4b280cc40a85a463 100644 (file)
@@ -14,6 +14,66 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #ifndef _EFI_PCI_OP_ROM_SUPPORT_H_\r
 #define _EFI_PCI_OP_ROM_SUPPORT_H_\r
 \r
+#include <Protocol/LoadFile2.h>\r
+\r
+/**\r
+  Initialize a PCI LoadFile2 instance\r
+  \r
+  @param PciIoDevice - PCI IO Device\r
+\r
+**/\r
+VOID\r
+InitializePciLoadFile2 (\r
+  PCI_IO_DEVICE       *PciIoDevice\r
+  );\r
+\r
+/**\r
+  Causes the driver to load a specified file.\r
+  \r
+  @param This        Indicates a pointer to the calling context.\r
+  @param FilePath    The device specific path of the file to load.\r
+  @param BootPolicy  Should always be FALSE.\r
+  @param BufferSize  On input the size of Buffer in bytes. On output with a return \r
+                     code of EFI_SUCCESS, the amount of data transferred to Buffer. \r
+                     On output with a return code of EFI_BUFFER_TOO_SMALL, \r
+                     the size of Buffer required to retrieve the requested file. \r
+  @param Buffer      The memory buffer to transfer the file to. If Buffer is NULL, \r
+                    then no the size of the requested file is returned in BufferSize.\r
+\r
+  @retval EFI_SUCCESS           The file was loaded. \r
+  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.\r
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current directory entry.\r
+                                BufferSize has been updated with the size needed to complete the request.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LoadFile2 (\r
+  IN EFI_LOAD_FILE2_PROTOCOL  *This,\r
+  IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+  IN BOOLEAN                  BootPolicy,\r
+  IN OUT UINTN                *BufferSize,\r
+  IN VOID                     *Buffer      OPTIONAL\r
+  );\r
+\r
+/**\r
+\r
+  Check if the RomImage contains EFI Images.\r
+\r
+  @param  RomImage  The ROM address of Image for check. \r
+  @param  RomSize   Size of ROM for check.\r
+\r
+  @retval TRUE     ROM contain EFI Image.\r
+  @retval FALSE    ROM not contain EFI Image.\r
+  \r
+**/\r
+BOOLEAN\r
+ContainEfiImage (\r
+  IN VOID            *RomImage,\r
+  IN UINT64          RomSize\r
+  ); \r
+\r
+\r
 /**\r
   Get Pci device's oprom infor bits.\r
   \r
index f64c64ee39b5a61d799e818bf1e2a73f7e973b97..aef3e956c380512b20e6ed283f094b62aa4f4788 100644 (file)
@@ -82,76 +82,33 @@ PciRomAddImageMapping (
   mNumberOfPciRomImages++;\r
 }\r
 \r
-/**\r
-  Load all option rom image to PCI driver list.\r
-  \r
-  @param This             Pointer to protocol instance EFI_DRIVER_BINDING_PROTOCOL\r
-  @param PciRootBridgeIo  Root bridge Io instance\r
-  @param PciIoDevice      device instance\r
-**/\r
-EFI_STATUS\r
-PciRomGetRomResourceFromPciOptionRomTable (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL      *This,\r
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,\r
-  PCI_IO_DEVICE                       *PciIoDevice\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  EFI_PCI_OPTION_ROM_TABLE      *PciOptionRomTable;\r
-  EFI_PCI_OPTION_ROM_DESCRIPTOR *PciOptionRomDescriptor;\r
-  UINTN                         Index;\r
-\r
-  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {\r
-    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];\r
-    if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber &&\r
-        PciOptionRomDescriptor->Bus == PciIoDevice->BusNumber         &&\r
-        PciOptionRomDescriptor->Dev == PciIoDevice->DeviceNumber      &&\r
-        PciOptionRomDescriptor->Func == PciIoDevice->FunctionNumber ) {\r
-\r
-      PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
-      PciIoDevice->PciIo.RomSize  = (UINTN) PciOptionRomDescriptor->RomLength;\r
-    }\r
-  }\r
-\r
-  for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
-    if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&\r
-        mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&\r
-        mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&\r
-        mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {\r
-\r
-      AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
 /**\r
   Get Option rom driver's mapping for PCI device.\r
   \r
   @param PciIoDevice Device instance.\r
 \r
+  @retval TRUE   Found Image mapping.\r
+  @retval FALSE\r
+\r
 **/\r
-EFI_STATUS\r
+BOOLEAN\r
 PciRomGetImageMapping (\r
   PCI_IO_DEVICE                       *PciIoDevice\r
   )\r
 {\r
   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
   UINTN                           Index;\r
+  BOOLEAN                         Found;\r
 \r
   PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
+  Found           = FALSE;\r
 \r
   for (Index = 0; Index < mNumberOfPciRomImages; Index++) {\r
     if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&\r
         mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&\r
         mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&\r
         mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {\r
+        Found = TRUE;\r
 \r
       if (mRomImageTable[Index].ImageHandle != NULL) {\r
         AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);\r
@@ -162,5 +119,5 @@ PciRomGetImageMapping (
     }\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  return Found;\r
 }\r
index 5b475cd0cc5de032ba77e02c1d9065fac5286edd..dc3d8fd64dce4f60f6381e7e39f91f6ae578fc0d 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Option Rom Support for PCI Bus Driver\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
+Copyright (c) 2006 - 2009, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -36,27 +36,17 @@ PciRomAddImageMapping (
   IN UINT64      RomAddress,\r
   IN UINT64      RomLength\r
   );\r
-/**\r
-  Load all option rom image to PCI driver list.\r
-  \r
-  @param This             Pointer to protocol instance EFI_DRIVER_BINDING_PROTOCOL.\r
-  @param PciRootBridgeIo  Root bridge Io instance.\r
-  @param PciIoDevice      device instance.\r
-**/\r
-EFI_STATUS\r
-PciRomGetRomResourceFromPciOptionRomTable (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL      *This,\r
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,\r
-  PCI_IO_DEVICE                       *PciIoDevice\r
-  );\r
 \r
 /**\r
   Get Option rom driver's mapping for PCI device.\r
   \r
   @param PciIoDevice Device instance.\r
 \r
+  @retval TRUE   Found Image mapping.\r
+  @retval FALSE\r
+\r
 **/\r
-EFI_STATUS\r
+BOOLEAN\r
 PciRomGetImageMapping (\r
   PCI_IO_DEVICE                       *PciIoDevice\r
   );\r
index 1ec682262ced708449432f5659ffbcd804848845..c51137f57a34599254e8fe2e7293d738a3c9783c 100644 (file)
@@ -1123,6 +1123,33 @@ DevPathFvFilePath (
   CatPrint (Str, L"%g", &FvFilePath->FvFileName);\r
 }\r
 \r
+/**\r
+  Convert Device Path to a Unicode string for printing.\r
+\r
+  @param Str             The buffer holding the output string.\r
+                         This buffer contains the length of the\r
+                         string and the maixmum length reserved\r
+                         for the string buffer.\r
+  @param DevPath         The device path.\r
+\r
+**/\r
+VOID\r
+DevPathRelativeOffsetRange (\r
+  IN OUT POOL_PRINT       *Str,\r
+  IN VOID                 *DevPath\r
+  )\r
+{\r
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;\r
+\r
+  Offset = DevPath;\r
+  CatPrint (\r
+    Str,\r
+    L"Offset(%lx,%lx)",\r
+    Offset->StartingOffset,\r
+    Offset->EndingOffset\r
+    );\r
+}\r
+\r
 /**\r
   Convert Device Path to a Unicode string for printing.\r
 \r
@@ -1399,6 +1426,11 @@ DEVICE_PATH_STRING_TABLE  DevPathTable[] = {
     MEDIA_PIWG_FW_FILE_DP,\r
     DevPathFvFilePath\r
   },\r
+  {\r
+    MEDIA_DEVICE_PATH,\r
+    MEDIA_RELATIVE_OFFSET_RANGE_DP,\r
+    DevPathRelativeOffsetRange,\r
+  },\r
   {\r
     BBS_DEVICE_PATH,\r
     BBS_BBS_DP,\r