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
next prev 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