diff options
author | Jiewen Yao <jiewen.yao@intel.com> | 2017-04-29 16:57:54 +0800 |
---|---|---|
committer | Star Zeng <star.zeng@intel.com> | 2018-05-09 16:20:47 +0800 |
commit | d4fd304f8e6a98c686fb760ee5064b54e2dc61ae (patch) | |
tree | ff022703a47e0ed1768fc2838ec06bf2f3d972df /MdeModulePkg | |
parent | 87ed293135f1cd7974fb81973d4f9bafab1deff6 (diff) | |
download | edk2-d4fd304f8e6a98c686fb760ee5064b54e2dc61ae.tar.gz |
MdeModulePkg/PciBus: Add IOMMU support.
If IOMMU protocol is installed, PciBus need call IOMMU
to set access attribute for the PCI device in Map/Ummap.
Only after the access attribute is set, the PCI device can
access the DMA memory.
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>
Previous patch Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Previous patch Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Leo Duran <leo.duran@amd.com>
(cherry picked from commit 11a6cc5bda811513d2fbe47d8cb1a70b48077800)
Diffstat (limited to 'MdeModulePkg')
-rw-r--r-- | MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 47 |
4 files changed, 54 insertions, 4 deletions
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c index f3be47a496..950cacc120 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c @@ -42,6 +42,7 @@ UINT64 gAllZero = 0; EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
+EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {
@@ -284,6 +285,14 @@ PciBusDriverBindingStart ( );
}
+ if (mIoMmuProtocol == NULL) {
+ gBS->LocateProtocol (
+ &gEdkiiIoMmuProtocolGuid,
+ NULL,
+ (VOID **) &mIoMmuProtocol
+ );
+ }
+
if (PcdGetBool (PcdPciDisableBusEnumeration)) {
gFullEnumeration = FALSE;
} else {
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h index 39ba8b9f33..3bcc134d0b 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h @@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Protocol/IncompatiblePciDeviceSupport.h>
#include <Protocol/PciOverride.h>
#include <Protocol/PciEnumerationComplete.h>
+#include <Protocol/IoMmu.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf index a3ab11fd8d..5da094f582 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf @@ -95,6 +95,7 @@ gEfiPciRootBridgeIoProtocolGuid ## TO_START
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
+ gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c index f72598d3ae..3b3b53abce 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c @@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "PciBus.h"
+extern EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
+
//
// Pci Io Protocol Interface
//
@@ -965,8 +967,10 @@ PciIoMap ( OUT VOID **Mapping
)
{
- EFI_STATUS Status;
- PCI_IO_DEVICE *PciIoDevice;
+ EFI_STATUS Status;
+ PCI_IO_DEVICE *PciIoDevice;
+ UINT64 IoMmuAttribute;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION RootBridgeIoOperation;
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
@@ -978,13 +982,14 @@ PciIoMap ( return EFI_INVALID_PARAMETER;
}
+ RootBridgeIoOperation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)Operation;
if ((PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) != 0) {
- Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64);
+ RootBridgeIoOperation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)(Operation + EfiPciOperationBusMasterRead64);
}
Status = PciIoDevice->PciRootBridgeIo->Map (
PciIoDevice->PciRootBridgeIo,
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
+ RootBridgeIoOperation,
HostAddress,
NumberOfBytes,
DeviceAddress,
@@ -999,6 +1004,31 @@ PciIoMap ( );
}
+ if (mIoMmuProtocol != NULL) {
+ if (!EFI_ERROR (Status)) {
+ switch (Operation) {
+ case EfiPciIoOperationBusMasterRead:
+ IoMmuAttribute = EDKII_IOMMU_ACCESS_READ;
+ break;
+ case EfiPciIoOperationBusMasterWrite:
+ IoMmuAttribute = EDKII_IOMMU_ACCESS_WRITE;
+ break;
+ case EfiPciIoOperationBusMasterCommonBuffer:
+ IoMmuAttribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;
+ break;
+ default:
+ ASSERT(FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+ mIoMmuProtocol->SetAttribute (
+ mIoMmuProtocol,
+ PciIoDevice->Handle,
+ *Mapping,
+ IoMmuAttribute
+ );
+ }
+ }
+
return Status;
}
@@ -1024,6 +1054,15 @@ PciIoUnmap ( PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+ if (mIoMmuProtocol != NULL) {
+ mIoMmuProtocol->SetAttribute (
+ mIoMmuProtocol,
+ PciIoDevice->Handle,
+ Mapping,
+ 0
+ );
+ }
+
Status = PciIoDevice->PciRootBridgeIo->Unmap (
PciIoDevice->PciRootBridgeIo,
Mapping
|