public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Jiewen Yao <jiewen.yao@intel.com>
To: edk2-devel@lists.01.org
Cc: Ruiyu Ni <ruiyu.ni@intel.com>, Leo Duran <leo.duran@amd.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: [PATCH V5 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support.
Date: Fri,  5 May 2017 00:32:40 +0800	[thread overview]
Message-ID: <1493915561-8500-3-git-send-email-jiewen.yao@intel.com> (raw)
In-Reply-To: <1493915561-8500-1-git-send-email-jiewen.yao@intel.com>

If IOMMU protocol is installed, PciHostBridge just calls
IOMMU AllocateBuffer/FreeBuffer/Map/Unmap.

PciHostBridge does not set IOMMU access attribute,
because it does not know which device request the DMA.
This work is done by PciBus driver.

Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Leo Duran <leo.duran@amd.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c      | 37 ++++++++++++
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |  2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h      |  2 +
 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 61 ++++++++++++++++++++
 4 files changed, 102 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
index 9005dee..70726a6 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
@@ -28,6 +28,10 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] = {
   L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus"
 };
 
+EDKII_IOMMU_PROTOCOL        *mIoMmuProtocol;
+EFI_EVENT                   mIoMmuEvent;
+VOID                        *mIoMmuRegistration;
+
 /**
   Ensure the compatibility of an IO space descriptor with the IO aperture.
 
@@ -313,6 +317,28 @@ FreeMemorySpaceMap:
 }
 
 /**
+  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);
+  }
+}
+
+/**
 
   Entry point of this driver.
 
@@ -489,6 +515,17 @@ InitializePciHostBridge (
     ASSERT_EFI_ERROR (Status);
   }
   PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
+
+  if (!EFI_ERROR (Status)) {
+    mIoMmuEvent = EfiCreateProtocolNotifyEvent (
+                    &gEdkiiIoMmuProtocolGuid,
+                    TPL_CALLBACK,
+                    IoMmuProtocolCallback,
+                    NULL,
+                    &mIoMmuRegistration
+                    );
+  }
+
   return Status;
 }
 
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
index d8b0439..42bd8a2 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -41,6 +41,7 @@
   BaseMemoryLib
   BaseLib
   PciSegmentLib
+  UefiLib
   PciHostBridgeLib
 
 [Protocols]
@@ -49,6 +50,7 @@
   gEfiDevicePathProtocolGuid                      ## BY_START
   gEfiPciRootBridgeIoProtocolGuid                 ## BY_START
   gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START
+  gEdkiiIoMmuProtocolGuid                         ## SOMETIMES_CONSUMES
 
 [Depex]
   gEfiCpuIo2ProtocolGuid AND
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
index 13185b4..1fec88b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/CpuIo2.h>
 #include <Protocol/DevicePath.h>
 #include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/IoMmu.h>
 #include <Library/DebugLib.h>
 #include <Library/DevicePathLib.h>
 #include <Library/BaseMemoryLib.h>
@@ -34,6 +35,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/BaseLib.h>
 #include <Library/PciSegmentLib.h>
+#include <Library/UefiLib.h>
 #include "PciHostResource.h"
 
 
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
index 8af131b..068295b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -17,6 +17,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "PciRootBridge.h"
 #include "PciHostResource.h"
 
+extern EDKII_IOMMU_PROTOCOL        *mIoMmuProtocol;
+
 #define NO_MAPPING  (VOID *) (UINTN) -1
 
 //
@@ -1072,6 +1074,26 @@ RootBridgeIoMap (
 
   RootBridge = ROOT_BRIDGE_FROM_THIS (This);
 
+  if (mIoMmuProtocol != NULL) {
+    if (!RootBridge->DmaAbove4G) {
+      //
+      // Clear 64bit support
+      //
+      if (Operation > EfiPciOperationBusMasterCommonBuffer) {
+        Operation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) (Operation - EfiPciOperationBusMasterRead64);
+      }
+    }
+    Status = mIoMmuProtocol->Map (
+                               mIoMmuProtocol,
+                               Operation,
+                               HostAddress,
+                               NumberOfBytes,
+                               DeviceAddress,
+                               Mapping
+                               );
+    return Status;
+  }
+
   PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
   if ((!RootBridge->DmaAbove4G ||
        (Operation != EfiPciOperationBusMasterRead64 &&
@@ -1194,8 +1216,18 @@ RootBridgeIoUnmap (
   MAP_INFO                 *MapInfo;
   LIST_ENTRY               *Link;
   PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
+  EFI_STATUS                Status;
+
+  if (mIoMmuProtocol != NULL) {
+    Status = mIoMmuProtocol->Unmap (
+                               mIoMmuProtocol,
+                               Mapping
+                               );
+    return Status;
+  }
 
   RootBridge = ROOT_BRIDGE_FROM_THIS (This);
+
   //
   // See if the Map() operation associated with this Unmap() required a mapping
   // buffer. If a mapping buffer was not required, then this function simply
@@ -1312,6 +1344,24 @@ RootBridgeIoAllocateBuffer (
 
   RootBridge = ROOT_BRIDGE_FROM_THIS (This);
 
+  if (mIoMmuProtocol != NULL) {
+    if (!RootBridge->DmaAbove4G) {
+      //
+      // Clear DUAL_ADDRESS_CYCLE
+      //
+      Attributes &= ~EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+    }
+    Status = mIoMmuProtocol->AllocateBuffer (
+                               mIoMmuProtocol,
+                               Type,
+                               MemoryType,
+                               Pages,
+                               HostAddress,
+                               Attributes
+                               );
+    return Status;
+  }
+
   AllocateType = AllocateAnyPages;
   if (!RootBridge->DmaAbove4G ||
       (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
@@ -1356,6 +1406,17 @@ RootBridgeIoFreeBuffer (
   OUT VOID                             *HostAddress
   )
 {
+  EFI_STATUS                Status;
+
+  if (mIoMmuProtocol != NULL) {
+    Status = mIoMmuProtocol->FreeBuffer (
+                               mIoMmuProtocol,
+                               Pages,
+                               HostAddress
+                               );
+    return Status;
+  }
+
   return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
 }
 
-- 
2.7.4.windows.1



  parent reply	other threads:[~2017-05-04 16:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-04 16:32 [PATCH V5 0/3] Add IOMMU support Jiewen Yao
2017-05-04 16:32 ` [PATCH V5 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
2017-05-04 16:32 ` Jiewen Yao [this message]
2017-05-04 16:32 ` [PATCH V5 3/3] MdeModulePkg/PciBus: Add IOMMU support Jiewen Yao
2017-05-05  1:32 ` [PATCH V5 0/3] " Ni, Ruiyu
2017-05-11 20:51 ` Jordan Justen
2017-05-12  1:36   ` Yao, Jiewen
2017-05-13 19:27 ` Duran, Leo
2017-05-18  8:37   ` Ard Biesheuvel
2017-05-18  8:40     ` Yao, Jiewen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1493915561-8500-3-git-send-email-jiewen.yao@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox