* [Patch][edk2-platforms/devel-IntelAtomProcessorE3900] Enhance Implementation of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
@ 2018-07-17 1:37 zwei4
0 siblings, 0 replies; only message in thread
From: zwei4 @ 2018-07-17 1:37 UTC (permalink / raw)
To: edk2-devel; +Cc: David Wei, Mang Guo
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
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2018-07-17 1:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-17 1:37 [Patch][edk2-platforms/devel-IntelAtomProcessorE3900] Enhance Implementation of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL zwei4
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox