From nobody Sat Nov 2 12:18:48 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1490434140883338.79532368933087; Sat, 25 Mar 2017 02:29:00 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 7B1E021DFA7B8; Sat, 25 Mar 2017 02:28:57 -0700 (PDT) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 841F221DFA7B1 for ; Sat, 25 Mar 2017 02:28:54 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP; 25 Mar 2017 02:28:54 -0700 Received: from jyao1-mobl.ccr.corp.intel.com ([10.254.213.212]) by orsmga003.jf.intel.com with ESMTP; 25 Mar 2017 02:28:53 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,219,1486454400"; d="scan'208";a="948072143" From: Jiewen Yao To: edk2-devel@lists.01.org Date: Sat, 25 Mar 2017 17:28:42 +0800 Message-Id: <1490434122-16200-4-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1490434122-16200-1-git-send-email-jiewen.yao@intel.com> References: <1490434122-16200-1-git-send-email-jiewen.yao@intel.com> Subject: [edk2] [RFC] [PATCH 3/3] MdeModulePkg/PciBus: Add IOMMU support. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ruiyu Ni , Brijesh Singh , Leo Duran MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The responsibility of PciBus driver is to set IOMMU attribute, because only PciBus knows which device submits DMA access request. PciBus driver assumes that PciHostBridge driver can allocate IOMMU page aligned memory, if IOMMU protocol exists. Cc: Ruiyu Ni Cc: Leo Duran Cc: Brijesh Singh Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 12 +++ MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 10 ++ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 + MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 100 ++++++++++++++++++++ 4 files changed, 123 insertions(+) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci= /PciBusDxe/PciBus.c index f3be47a..c9ee4de 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c @@ -42,6 +42,8 @@ UINT64 gAllZero = =3D 0; =20 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol; +EDKII_IOMMU_PROTOCOL *gIoMmuProtocol; +UINTN mIoMmuPageSize =3D 1; =20 =20 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlug= Request =3D { @@ -256,6 +258,16 @@ PciBusDriverBindingStart ( } =20 gBS->LocateProtocol ( + &gEdkiiIoMmuProtocolGuid, + NULL, + (VOID **) &gIoMmuProtocol + ); + if (gIoMmuProtocol !=3D NULL) { + gIoMmuProtocol->GetPageSize (gIoMmuProtocol, &mIoMmuPageSize); + ASSERT ((mIoMmuPageSize & (mIoMmuPageSize - 1)) =3D=3D 0); + } + + gBS->LocateProtocol ( &gEfiIncompatiblePciDeviceSupportProtocolGuid, NULL, (VOID **) &gIncompatiblePciDeviceSupport diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci= /PciBusDxe/PciBus.h index 39ba8b9..6f96696 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 #include #include +#include =20 #include #include @@ -304,6 +305,13 @@ struct _PCI_IO_DEVICE { CR (a, PCI_IO_DEVICE, LoadFile2, PCI_IO_DEVICE_SIGNATURE) =20 =20 +#define PCI_IO_MAP_INFO_SIGNATURE SIGNATURE_32 ('p', 'm', 'a', 'p') +typedef struct { + UINT32 Signature; + UINTN NumberOfBytes; + EFI_PHYSICAL_ADDRESS DeviceAddress; + VOID *PciRootBridgeIoMapping; +} PCI_IO_MAP_INFO; =20 // // Global Variables @@ -319,6 +327,8 @@ extern UINT64 gAl= lOne; extern UINT64 gAllZero; extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; extern EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol; +extern EDKII_IOMMU_PROTOCOL *gIoMmuProtocol; +extern UINTN mIoMmuPageSize; extern BOOLEAN mReserveIsaAliases; extern BOOLEAN mReserveVgaAliases; =20 diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bu= s/Pci/PciBusDxe/PciBusDxe.inf index a3ab11f..5da094f 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 =20 [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CON= SUMES diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/= PciBusDxe/PciIo.c index f72598d..01786c1 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c @@ -967,6 +967,8 @@ PciIoMap ( { EFI_STATUS Status; PCI_IO_DEVICE *PciIoDevice; + PCI_IO_MAP_INFO *PciIoMapInfo; + UINT64 IoMmuAttribute; =20 PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); =20 @@ -999,6 +1001,46 @@ PciIoMap ( ); } =20 + if (gIoMmuProtocol !=3D NULL) { + if (!EFI_ERROR(Status)) { + PciIoMapInfo =3D AllocatePool (sizeof(*PciIoMapInfo)); + if (PciIoMapInfo =3D=3D NULL) { + PciIoDevice->PciRootBridgeIo->Unmap (PciIoDevice->PciRootBridgeIo,= *Mapping); + return EFI_OUT_OF_RESOURCES; + } + + PciIoMapInfo->Signature =3D PCI_IO_MAP_INFO_SIGNATURE; + PciIoMapInfo->NumberOfBytes =3D *NumberOfBytes; + PciIoMapInfo->DeviceAddress =3D *DeviceAddress; + PciIoMapInfo->PciRootBridgeIoMapping =3D *Mapping; + *Mapping =3D PciIoMapInfo; + + switch (Operation) { + case EfiPciIoOperationBusMasterRead: + IoMmuAttribute =3D EDKII_IOMMU_ATTRIBUTE_READ; + break; + case EfiPciIoOperationBusMasterWrite: + IoMmuAttribute =3D EDKII_IOMMU_ATTRIBUTE_WRITE; + break; + case EfiPciIoOperationBusMasterCommonBuffer: + IoMmuAttribute =3D EDKII_IOMMU_ATTRIBUTE_READ | EDKII_IOMMU_ATTRIB= UTE_WRITE; + break; + default: + ASSERT(FALSE); + return Status; + } + // + // PciHostBridge should map IOMMU page aligned HostAddress. + // + gIoMmuProtocol->SetAttribute ( + gIoMmuProtocol, + PciIoDevice->Handle, + PciIoMapInfo->DeviceAddress, + ALIGN_VALUE(PciIoMapInfo->NumberOfBytes, mIoMmuPag= eSize), + IoMmuAttribute + ); + } + } return Status; } =20 @@ -1021,9 +1063,19 @@ PciIoUnmap ( { EFI_STATUS Status; PCI_IO_DEVICE *PciIoDevice; + PCI_IO_MAP_INFO *PciIoMapInfo; =20 PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); =20 + PciIoMapInfo =3D NULL; + if (gIoMmuProtocol !=3D NULL) { + PciIoMapInfo =3D Mapping; + if (PciIoMapInfo->Signature !=3D PCI_IO_MAP_INFO_SIGNATURE) { + return EFI_INVALID_PARAMETER; + } + Mapping =3D PciIoMapInfo->PciRootBridgeIoMapping; + } + Status =3D PciIoDevice->PciRootBridgeIo->Unmap ( PciIoDevice->PciRootBridgeIo, Mapping @@ -1037,6 +1089,22 @@ PciIoUnmap ( ); } =20 + if (gIoMmuProtocol !=3D NULL) { + if (!EFI_ERROR(Status)) { + // + // PciHostBridge should map IOMMU page aligned HostAddress. + // + gIoMmuProtocol->SetAttribute ( + gIoMmuProtocol, + PciIoDevice->Handle, + PciIoMapInfo->DeviceAddress, + ALIGN_VALUE(PciIoMapInfo->NumberOfBytes, mIoMmuPag= eSize), + 0 + ); + FreePool (PciIoMapInfo); + } + } + return Status; } =20 @@ -1073,6 +1141,7 @@ PciIoAllocateBuffer ( { EFI_STATUS Status; PCI_IO_DEVICE *PciIoDevice; + UINTN Size; =20 if ((Attributes & (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY= _CACHED))) !=3D 0){ @@ -1102,6 +1171,21 @@ PciIoAllocateBuffer ( ); } =20 + if (gIoMmuProtocol !=3D NULL) { + if (!EFI_ERROR(Status)) { + // + // PciHostBridge should allocate IOMMU page aligned HostAddress. + // + Size =3D EFI_PAGES_TO_SIZE(Pages); + gIoMmuProtocol->SetAttribute ( + gIoMmuProtocol, + PciIoDevice->Handle, + (UINTN)*HostAddress, + ALIGN_VALUE(Size, mIoMmuPageSize), + EDKII_IOMMU_ATTRIBUTE_READ | EDKII_IOMMU_ATTRIBUTE= _WRITE + ); + } + } return Status; } =20 @@ -1127,6 +1211,7 @@ PciIoFreeBuffer ( { EFI_STATUS Status; PCI_IO_DEVICE *PciIoDevice; + UINTN Size; =20 PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); =20 @@ -1144,6 +1229,21 @@ PciIoFreeBuffer ( ); } =20 + if (gIoMmuProtocol !=3D NULL) { + if (!EFI_ERROR(Status)) { + // + // PciHostBridge should allocate IOMMU page aligned HostAddress. + // + Size =3D EFI_PAGES_TO_SIZE(Pages); + gIoMmuProtocol->SetAttribute ( + gIoMmuProtocol, + PciIoDevice->Handle, + (UINTN)HostAddress, + ALIGN_VALUE(Size, mIoMmuPageSize), + 0 + ); + } + } return Status; } =20 --=20 2.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel