mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
c15da8eb35
commit
11a6cc5bda
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
gEfiPciRootBridgeIoProtocolGuid ## TO_START
|
||||
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
||||
gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[FeaturePcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue