[edk2] [Patch][edk2-platforms/devel-IntelAtomProcessorE3900] Enhance Implementation of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.

zwei4 posted 1 patch 5 years, 9 months ago
Failed in applying to current master (apply log)
.../NorthCluster/PciHostBridge/Dxe/PciHostBridge.c | 34 +++++++++++
.../PciHostBridge/Dxe/PciHostBridge.inf            |  2 +
.../NorthCluster/PciHostBridge/Dxe/PciRootBridge.h |  1 +
.../PciHostBridge/Dxe/PciRootBridgeIo.c            | 71 +++++++++++++++++++---
4 files changed, 99 insertions(+), 9 deletions(-)
[edk2] [Patch][edk2-platforms/devel-IntelAtomProcessorE3900] Enhance Implementation of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
Posted by zwei4 5 years, 9 months ago
Enhance implementation of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL by introducing EDKII_IOMMU_PROTOCOL to support DMA remapping when VT-d is enabled.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david.wei@intel.com>
CC: Mang Guo <mang.guo@intel.com>
---
 .../NorthCluster/PciHostBridge/Dxe/PciHostBridge.c | 34 +++++++++++
 .../PciHostBridge/Dxe/PciHostBridge.inf            |  2 +
 .../NorthCluster/PciHostBridge/Dxe/PciRootBridge.h |  1 +
 .../PciHostBridge/Dxe/PciRootBridgeIo.c            | 71 +++++++++++++++++++---
 4 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.c b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.c
index 3f7a51d275..2cace7be07 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.c
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.c
@@ -22,6 +22,9 @@
 #include <ScRegs/RegsUsb.h>
 #include <Library/SteppingLib.h>
 
+EDKII_IOMMU_PROTOCOL        *mIoMmuProtocol;
+EFI_EVENT                   mIoMmuEvent;
+VOID                        *mIoMmuRegistration;
 //
 // Support 64 K IO space
 //
@@ -75,6 +78,28 @@ static PCI_ROOT_BRIDGE_RESOURCE_APPETURE  mResAppeture[1][1] = { {{ 0, 255, 0, 0
 
 static EFI_HANDLE                         mDriverImageHandle;
 
+/**
+  Event notification that is fired when IOMMU protocol is installed.
+
+  @param  Event                 The Event that is being processed.
+  @param  Context               Event Context.
+
+**/
+VOID
+EFIAPI
+IoMmuProtocolCallback (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_STATUS   Status;
+
+  Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmuProtocol);
+  if (!EFI_ERROR(Status)) {
+    gBS->CloseEvent (mIoMmuEvent);
+  }
+}
+
 //
 // Implementation
 //
@@ -241,6 +266,15 @@ PciHostBridgeEntryPoint (
   ASSERT_EFI_ERROR (Status);
   DEBUG ((EFI_D_INFO, "Successfully changed memory attribute for PCIe\n"));
 
+
+  mIoMmuEvent = EfiCreateProtocolNotifyEvent (
+                  &gEdkiiIoMmuProtocolGuid,
+                  TPL_CALLBACK,
+                  IoMmuProtocolCallback,
+                  NULL,
+                  &mIoMmuRegistration
+                  );
+
   return EFI_SUCCESS;
 }
 
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.inf
index de77fd1552..ec0c593d5b 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.inf
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciHostBridge.inf
@@ -35,6 +35,7 @@
 
 [Packages]
   MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
   BroxtonSiPkg/BroxtonSiPkg.dec
 
 [LibraryClasses]
@@ -55,6 +56,7 @@
   gEfiPciHostBridgeResourceAllocationProtocolGuid     ## PRODUCES
   gEfiMetronomeArchProtocolGuid                       ## CONSUMES
   gEfiCpuIo2ProtocolGuid                              ## CONSUMES
+  gEdkiiIoMmuProtocolGuid                             ## SOMETIMES_CONSUMES
 
 [Depex]
   gEfiCpuIo2ProtocolGuid  AND
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridge.h b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridge.h
index 81c143e6d1..1db17fc2da 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridge.h
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridge.h
@@ -23,6 +23,7 @@
 #include <Protocol/PciHostBridgeResourceAllocation.h>
 #include <Protocol/Metronome.h>
 #include <Protocol/CpuIo.h>
+#include <Protocol/IoMmu.h>
 #include <Library/UefiLib.h>
 #include <Library/DevicePathLib.h>
 #include <Library/DebugLib.h>
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridgeIo.c b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridgeIo.c
index e5e2e8605f..d8bdc20de1 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridgeIo.c
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/NorthCluster/PciHostBridge/Dxe/PciRootBridgeIo.c
@@ -16,6 +16,8 @@
 #include "PciRootBridge.h"
 #include <IndustryStandard/Pci22.h>
 
+extern EDKII_IOMMU_PROTOCOL        *mIoMmuProtocol;
+
 typedef struct {
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[TypeMax];
   EFI_ACPI_END_TAG_DESCRIPTOR       EndDesp;
@@ -1093,11 +1095,29 @@ RootBridgeIoMap (
   if (Operation < 0 || Operation >= EfiPciOperationMaximum) {
     return EFI_INVALID_PARAMETER;
   }
-  //
-  // Most PCAT like chipsets can not handle performing DMA above 4GB.
-  // If any part of the DMA transfer being mapped is above 4GB, then
-  // map the DMA transfer to a buffer below 4GB.
-  //
+
+  if (mIoMmuProtocol != NULL) {
+    //
+    // Clear 64bit support
+    //
+    if (Operation > EfiPciOperationBusMasterCommonBuffer) {
+      Operation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) (Operation - EfiPciOperationBusMasterRead64);
+    }
+    return mIoMmuProtocol->Map (
+                               mIoMmuProtocol,
+                               (EDKII_IOMMU_OPERATION) Operation,
+                               HostAddress,
+                               NumberOfBytes,
+                               DeviceAddress,
+                               Mapping
+                               );
+  }
+
+  ///
+  /// Most PCAT like chipsets can not handle performing DMA above 4GB.
+  /// If any part of the DMA transfer being mapped is above 4GB, then
+  /// map the DMA transfer to a buffer below 4GB.
+  ///
   PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
   if ((PhysicalAddress + *NumberOfBytes) > 0x100000000) {
     //
@@ -1186,10 +1206,17 @@ RootBridgeIoUnmap (
 {
   MAP_INFO    *MapInfo;
 
-  //
-  // See if the Map() operation associated with this Unmap() required a mapping buffer.
-  // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
-  //
+  if (mIoMmuProtocol != NULL) {
+    return mIoMmuProtocol->Unmap (
+                               mIoMmuProtocol,
+                               Mapping
+                               );
+  }
+
+  ///
+  /// See if the Map() operation associated with this Unmap() required a mapping buffer.
+  /// If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
+  ///
   if (Mapping != NULL) {
     //
     // Get the MAP_INFO structure from Mapping
@@ -1277,6 +1304,22 @@ RootBridgeIoAllocateBuffer (
   if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {
     return EFI_INVALID_PARAMETER;
   }
+
+  if (mIoMmuProtocol != NULL) {
+    //
+    // Clear DUAL_ADDRESS_CYCLE
+    //
+    Attributes &= ~((UINT64) EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE);
+    Status = mIoMmuProtocol->AllocateBuffer (
+                               mIoMmuProtocol,
+                               Type,
+                               MemoryType,
+                               Pages,
+                               HostAddress,
+                               Attributes
+                               );
+    return Status;
+  }
   //
   // Limit allocations to memory below 4GB
   //
@@ -1314,6 +1357,16 @@ RootBridgeIoFreeBuffer (
   OUT VOID                             *HostAddress
   )
 {
+  EFI_STATUS                Status;
+
+  if (mIoMmuProtocol != NULL) {
+    Status = mIoMmuProtocol->FreeBuffer (
+                               mIoMmuProtocol,
+                               Pages,
+                               HostAddress
+                               );
+    return Status;
+  }
   FreePages ((VOID *) HostAddress, Pages);
   return EFI_SUCCESS;
 }
-- 
2.14.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel