]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Some existing PCI adapters with UEFI option ROMs make unaligned requests through...
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 9 Nov 2010 03:41:03 +0000 (03:41 +0000)
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 9 Nov 2010 03:41:03 +0000 (03:41 +0000)
This solution defines a PCD Feature Flag to enabled support for unaligned requests through the PCI I/O Protocol.  This flag is disabled by default. Platforms that do want to support such EFI/UEFI drivers that make unaligned PCI I/O requests should enable this feature.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11016 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
MdeModulePkg/MdeModulePkg.dec

index 7096b116181777b5e4dde4082ad03f002d9a78ea..3c581ec27d9277802bbfd78415e1de5a4a1fe39c 100644 (file)
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUnalignedPciIoEnable\r
 \r
 [Pcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize\r
index 310cedad049c9d9e6497ff64bba7aec5d05b0bcc..e7d4ae3e5595ce71e87c3d1ce1f793d910ced358 100644 (file)
@@ -248,6 +248,39 @@ PciIoPollMem (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Status  = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if ((*Result & Mask) == Value || Delay == 0) {\r
+        return EFI_SUCCESS;\r
+      }\r
+      do {\r
+        //\r
+        // Stall 10 us = 100 * 100ns\r
+        //\r
+        gBS->Stall (10);\r
+\r
+        Status  = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+        if ((*Result & Mask) == Value) {\r
+          return EFI_SUCCESS;\r
+        }\r
+        if (Delay <= 100) {\r
+          return EFI_TIMEOUT;\r
+        }\r
+        Delay -= 100;\r
+      } while (TRUE);\r
+    }\r
+  }\r
+  \r
   Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
                                            PciIoDevice->PciRootBridgeIo,\r
                                            (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -314,6 +347,39 @@ PciIoPollIo (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Status  = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if ((*Result & Mask) == Value || Delay == 0) {\r
+        return EFI_SUCCESS;\r
+      }\r
+      do {\r
+        //\r
+        // Stall 10 us = 100 * 100ns\r
+        //\r
+        gBS->Stall (10);\r
+\r
+        Status  = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+        if ((*Result & Mask) == Value) {\r
+          return EFI_SUCCESS;\r
+        }\r
+        if (Delay <= 100) {\r
+          return EFI_TIMEOUT;\r
+        }\r
+        Delay -= 100;\r
+      } while (TRUE);\r
+    }\r
+  }\r
+  \r
   Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
                                            PciIoDevice->PciRootBridgeIo,\r
                                            (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -380,6 +446,17 @@ PciIoMemRead (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }  \r
+  \r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -444,6 +521,16 @@ PciIoMemWrite (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -508,6 +595,16 @@ PciIoIoRead (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }    \r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -572,6 +669,16 @@ PciIoIoWrite (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }  \r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -626,6 +733,16 @@ PciIoConfigRead (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+  \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }    \r
 \r
   Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
                                                PciIoDevice->PciRootBridgeIo,\r
@@ -682,6 +799,16 @@ PciIoConfigWrite (
     return Status;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }  \r
+  \r
   Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -767,6 +894,16 @@ PciIoCopyMem (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //  \r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((SrcOffset & ((1 << (Width & 0x03)) - 1)) != 0 || (DestOffset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Width &= (~0x03);\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+    }\r
+  }  \r
+\r
   Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
                                           PciIoDevice->PciRootBridgeIo,\r
                                           (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
index e26ff142c81d197a37bdd1268850a60313b047e9..aa805630c3159f427ace99ae724f0e10b91983f6 100644 (file)
   ## This PCD specified whether ACPI SDT protocol is installed.\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|FALSE|BOOLEAN|0x0001004d\r
 \r
+  ## If TRUE, then unaligned I/O, MMIO, and PCI Configuration cycles through the PCI I/O Protocol are enabled.\r
+  #  If FALSE, then unaligned I/O, MMIO, and PCI Configuration cycles through the PCI I/O Protocol are disabled.\r
+  #  The default value for this PCD is to disable support for unaligned PCI I/O Protocol requests.\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUnalignedPciIoEnable|FALSE|BOOLEAN|0x0001003e\r
+  \r
 [PcdsFeatureFlag.IA32, PcdsFeatureFlag.X64]\r
   ##\r
   # This feature flag specifies whether DxeIpl switches to long mode to enter DXE phase.\r