From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (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 6007321A04830 for ; Tue, 2 May 2017 05:54:55 -0700 (PDT) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 May 2017 05:54:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.37,405,1488873600"; d="scan'208,217";a="96251412" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga005.fm.intel.com with ESMTP; 02 May 2017 05:54:54 -0700 Received: from fmsmsx154.amr.corp.intel.com (10.18.116.70) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 2 May 2017 05:54:54 -0700 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by FMSMSX154.amr.corp.intel.com (10.18.116.70) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 2 May 2017 05:54:54 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.246]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.224]) with mapi id 14.03.0319.002; Tue, 2 May 2017 20:54:50 +0800 From: "Yao, Jiewen" To: Ard Biesheuvel CC: "Ni, Ruiyu" , "edk2-devel@lists.01.org" , Leo Duran Thread-Topic: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition. Thread-Index: AQHSwypbrGj2zF1WA06U39ZM7LLw+qHg/g7g Date: Tue, 2 May 2017 12:54:49 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A936813@shsmsx102.ccr.corp.intel.com> References: <1493473694-5064-1-git-send-email-jiewen.yao@intel.com> <1493473694-5064-2-git-send-email-jiewen.yao@intel.com> In-Reply-To: Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 10.0.102.7 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 X-Content-Filtered-By: Mailman/MimeDel 2.1.22 Subject: Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition. 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: , X-List-Received-Date: Tue, 02 May 2017 12:54:55 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Thanks, Ard. It is a good open that if we really need both SetAttribute and SetMappingAt= tribute. Looking at code again, I prefer to remove SetAttribute(). I do not suggest we define MapInfo, because I want to make it DMA engine im= plementation choice. All we want is just to set an access attribute for this mapping, there is n= o need to input base/length. Because Map() should always be called by a device driver, no matter it is P= CI DMA, ISA DMA, or low power controller DMA, I think SetMappingAttribute i= s good enough. I will plan to remove SetAttribute() in V5. Thank you Yao Jiewen From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ard = Biesheuvel Sent: Tuesday, May 2, 2017 5:56 PM To: Yao, Jiewen Cc: Ni, Ruiyu ; edk2-devel@lists.01.org; Leo Duran Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol de= finition. Hello Jiewen, On 29 April 2017 at 14:48, Jiewen Yao > wrote: > This protocol is to abstract DMA access from IOMMU. > 1) Intel "DMAR" ACPI table. > 2) AMD "IVRS" ACPI table > 3) ARM "IORT" ACPI table. > > There might be multiple IOMMU engines on one platform. > For example, one for graphic and one for rest PCI devices > (such as ATA/USB). > All IOMMU engines are reported by one ACPI table. > > All IOMMU protocol provider should be based upon ACPI table. > This single IOMMU protocol can handle multiple IOMMU engines on one syste= m. > > This IOMMU protocol provider can use UEFI device path to distinguish > if the device is graphic or ATA/USB, and find out corresponding > IOMMU engine. > > The IOMMU protocol provides 2 capabilities: > A) Set DMA access attribute - such as write/read control. > B) Remap DMA memory - such as remap above 4GiB system memory address > to below 4GiB device address. > It provides AllocateBuffer/FreeBuffer/Map/Unmap for DMA memory. > The remapping can be static (fixed at build time) or dynamic (allocate > at runtime). > > 4) AMD "SEV" feature. > We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol, > and manage SEV bit. > > Cc: Ruiyu Ni > > Cc: Leo Duran > > Cc: Brijesh Singh > > Cc: Ard Biesheuvel > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Jiewen Yao > > --- > MdeModulePkg/Include/Protocol/IoMmu.h | 310 ++++++++++++++++++++ > MdeModulePkg/MdeModulePkg.dec | 3 + > 2 files changed, 313 insertions(+) > > diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h b/MdeModulePkg/Include= /Protocol/IoMmu.h > new file mode 100644 > index 0000000..3f62f46 > --- /dev/null > +++ b/MdeModulePkg/Include/Protocol/IoMmu.h > @@ -0,0 +1,310 @@ > +/** @file > + EFI IOMMU Protocol. > + > +Copyright (c) 2017, Intel Corporation. All rights reserved.
> +This program and the accompanying materials are licensed and made availa= ble under > +the terms and conditions of the BSD License that accompanies this distri= bution. > +The full text of the license may be found at > +http://opensource.org/licenses/bsd-license.php. > + > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. > + > +**/ > + > + > +#ifndef __IOMMU_H__ > +#define __IOMMU_H__ > + > +// > +// IOMMU Protocol GUID value > +// > +#define EDKII_IOMMU_PROTOCOL_GUID \ > + { \ > + 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, = 0x7c, 0x1e } \ > + } > + > +// > +// Forward reference for pure ANSI compatability > +// > +typedef struct _EDKII_IOMMU_PROTOCOL EDKII_IOMMU_PROTOCOL; > + > +// > +// Revision The revision to which the IOMMU interface adheres. > +// All future revisions must be backwards compatible. > +// If a future version is not back wards compatible it is not t= he same GUID. > +// > +#define EDKII_IOMMU_PROTOCOL_REVISION 0x00010000 > + > +// > +// IOMMU Access for SetAttribute > +// > +// These types can be "ORed" together as needed. > +// Any undefined bits are reserved and must be zero. > +// > +#define EDKII_IOMMU_ACCESS_READ 0x1 > +#define EDKII_IOMMU_ACCESS_WRITE 0x2 > + > +// > +// IOMMU Operation for Map > +// > +typedef enum { > + /// > + /// A read operation from system memory by a bus master that is not ca= pable of producing > + /// PCI dual address cycles. > + /// > + EdkiiIoMmuOperationBusMasterRead, > + /// > + /// A write operation from system memory by a bus master that is not c= apable of producing > + /// PCI dual address cycles. > + /// > + EdkiiIoMmuOperationBusMasterWrite, > + /// > + /// Provides both read and write access to system memory by both the p= rocessor and a bus > + /// master that is not capable of producing PCI dual address cycles. > + /// > + EdkiiIoMmuOperationBusMasterCommonBuffer, > + /// > + /// A read operation from system memory by a bus master that is capabl= e of producing PCI > + /// dual address cycles. > + /// > + EdkiiIoMmuOperationBusMasterRead64, > + /// > + /// A write operation to system memory by a bus master that is capable= of producing PCI > + /// dual address cycles. > + /// > + EdkiiIoMmuOperationBusMasterWrite64, > + /// > + /// Provides both read and write access to system memory by both the p= rocessor and a bus > + /// master that is capable of producing PCI dual address cycles. > + /// > + EdkiiIoMmuOperationBusMasterCommonBuffer64, > + EdkiiIoMmuOperationMaximum > +} EDKII_IOMMU_OPERATION; > + > +// > +// IOMMU attribute for AllocateBuffer > +// Any undefined bits are reserved and must be zero. > +// > +#define EDKII_IOMMU_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 > +#define EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED 0x0800 > +#define EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 > + > +#define EDKII_IOMMU_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER (EDKII_IOMMU_A= TTRIBUTE_MEMORY_WRITE_COMBINE | EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED | EDKII= _IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) > + > +#define EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER (~EDKII_IOMMU_= ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER) > + > +/** > + Set IOMMU attribute for a system memory. > + > + If the IOMMU protocol exists, the system memory cannot be used > + for DMA by default. > + > + When a device requests a DMA access for a system memory, > + the device driver need use SetAttribute() to update the IOMMU > + attribute to request DMA access (read and/or write). > + > + The DeviceHandle is used to identify which device submits the request. > + The IOMMU implementation need translate the device path to an IOMMU de= vice ID, > + and set IOMMU hardware register accordingly. > + 1) DeviceHandle can be a standard PCI device. > + The memory for BusMasterRead need set EDKII_IOMMU_ACCESS_READ. > + The memory for BusMasterWrite need set EDKII_IOMMU_ACCESS_WRITE. > + The memory for BusMasterCommonBuffer need set EDKII_IOMMU_ACCESS_RE= AD|EDKII_IOMMU_ACCESS_WRITE. > + After the memory is used, the memory need set 0 to keep it being pr= otected. > + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc). > + The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or E= DKII_IOMMU_ACCESS_WRITE. > + > + @param[in] This The protocol instance pointer. > + @param[in] DeviceHandle The device who initiates the DMA access = request. > + @param[in] DeviceAddress The base of device memory address to be = used as the DMA memory. > + @param[in] Length The length of device memory address to b= e used as the DMA memory. > + @param[in] IoMmuAccess The IOMMU access. > + > + @retval EFI_SUCCESS The IoMmuAccess is set for the memory r= ange specified by DeviceAddress and Length. > + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle. > + @retval EFI_INVALID_PARAMETER DeviceAddress is not IoMmu Page size al= igned. > + @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned. > + @retval EFI_INVALID_PARAMETER Length is 0. > + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combin= ation of access. > + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU. > + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supp= orted by the IOMMU. > + @retval EFI_UNSUPPORTED The IOMMU does not support the memory r= ange specified by DeviceAddress and Length. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources availabl= e to modify the IOMMU access. > + @retval EFI_DEVICE_ERROR The IOMMU device reported an error whil= e attempting the operation. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)( > + IN EDKII_IOMMU_PROTOCOL *This, > + IN EFI_HANDLE DeviceHandle, > + IN EFI_PHYSICAL_ADDRESS DeviceAddress, > + IN UINT64 Length, > + IN UINT64 IoMmuAccess > + ); > + It is a bit unfortunate that we need both SetAttribute and SetMappingAttribute. Could we instead make the MAPPING_INFO struct (or at least, some part of it) part of the protocol? This would allow the PCI bus driver to call SetAttribute() directly, taking the values from the struct. > +/** > + Provides the controller-specific addresses required to access system m= emory from a > + DMA bus master. > + > + @param This The protocol instance pointer. > + @param Operation Indicates if the bus master is going to = read or write to system memory. > + @param HostAddress The system memory address to map to the = PCI controller. > + @param NumberOfBytes On input the number of bytes to map. On = output the number of bytes > + that were mapped. > + @param DeviceAddress The resulting map address for the bus ma= ster PCI controller to use to > + access the hosts HostAddress. > + @param Mapping A resulting value to pass to Unmap(). > + > + @retval EFI_SUCCESS The range was mapped for the returned Nu= mberOfBytes. > + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a co= mmon buffer. > + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. > + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. > + @retval EFI_DEVICE_ERROR The system hardware could not map the re= quested address. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_IOMMU_MAP)( > + IN EDKII_IOMMU_PROTOCOL *This, > + IN EDKII_IOMMU_OPERATION Operation, > + IN VOID *HostAddress, > + IN OUT UINTN *NumberOfBytes, > + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, > + OUT VOID **Mapping > + ); > + > +/** > + Completes the Map() operation and releases any corresponding resources= . > + > + @param This The protocol instance pointer. > + @param Mapping The mapping value returned from Map(). > + > + @retval EFI_SUCCESS The range was unmapped. > + @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned= by Map(). > + @retval EFI_DEVICE_ERROR The data was not committed to the target= system memory. > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_IOMMU_UNMAP)( > + IN EDKII_IOMMU_PROTOCOL *This, > + IN VOID *Mapping > + ); > + > +/** > + Allocates pages that are suitable for an OperationBusMasterCommonBuffe= r or > + OperationBusMasterCommonBuffer64 mapping. > + > + @param This The protocol instance pointer. > + @param Type This parameter is not used and must be i= gnored. > + @param MemoryType The type of memory to allocate, EfiBootS= ervicesData or > + EfiRuntimeServicesData. > + @param Pages The number of pages to allocate. > + @param HostAddress A pointer to store the base system memor= y address of the > + allocated range. > + @param Attributes The requested bit mask of attributes for= the allocated range. > + > + @retval EFI_SUCCESS The requested memory pages were allocate= d. > + @retval EFI_UNSUPPORTED Attributes is unsupported. The only lega= l attribute bits are > + MEMORY_WRITE_COMBINE and MEMORY_CACHED. > + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. > + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_IOMMU_ALLOCATE_BUFFER)( > + IN EDKII_IOMMU_PROTOCOL *This, > + IN EFI_ALLOCATE_TYPE Type, > + IN EFI_MEMORY_TYPE MemoryType, > + IN UINTN Pages, > + IN OUT VOID **HostAddress, > + IN UINT64 Attributes > + ); > + > +/** > + Frees memory that was allocated with AllocateBuffer(). > + > + @param This The protocol instance pointer. > + @param Pages The number of pages to free. > + @param HostAddress The base system memory address of the al= located range. > + > + @retval EFI_SUCCESS The requested memory pages were freed. > + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddres= s and Pages > + was not allocated with AllocateBuffer(). > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_IOMMU_FREE_BUFFER)( > + IN EDKII_IOMMU_PROTOCOL *This, > + IN UINTN Pages, > + IN VOID *HostAddress > + ); > + > +/** > + Set IOMMU attribute for a system memory. > + > + If the IOMMU protocol exists, the system memory cannot be used > + for DMA by default. > + > + When a device requests a DMA access for a system memory, > + the device driver need use SetAttribute() to update the IOMMU > + attribute to request DMA access (read and/or write). > + > + The DeviceHandle is used to identify which device submits the request. > + The IOMMU implementation need translate the device path to an IOMMU de= vice ID, > + and set IOMMU hardware register accordingly. > + 1) DeviceHandle can be a standard PCI device. > + The memory for BusMasterRead need set EDKII_IOMMU_ACCESS_READ. > + The memory for BusMasterWrite need set EDKII_IOMMU_ACCESS_WRITE. > + The memory for BusMasterCommonBuffer need set EDKII_IOMMU_ACCESS_RE= AD|EDKII_IOMMU_ACCESS_WRITE. > + After the memory is used, the memory need set 0 to keep it being pr= otected. > + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc). > + The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or E= DKII_IOMMU_ACCESS_WRITE. > + > + @param[in] This The protocol instance pointer. > + @param[in] DeviceHandle The device who initiates the DMA access = request. > + @param[in] Mapping The mapping value returned from Map(). > + @param[in] IoMmuAccess The IOMMU access. > + > + @retval EFI_SUCCESS The IoMmuAccess is set for the memory r= ange specified by DeviceAddress and Length. > + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle. > + @retval EFI_INVALID_PARAMETER Mapping is not a value that was returne= d by Map(). > + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combin= ation of access. > + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU. > + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supp= orted by the IOMMU. > + @retval EFI_UNSUPPORTED The IOMMU does not support the memory r= ange specified by Mapping. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources availabl= e to modify the IOMMU access. > + @retval EFI_DEVICE_ERROR The IOMMU device reported an error whil= e attempting the operation. > + > +**/ > +typedef > +EFI_STATUS > +(EFIAPI *EDKII_IOMMU_SET_MAPPING_ATTRIBUTE)( > + IN EDKII_IOMMU_PROTOCOL *This, > + IN EFI_HANDLE DeviceHandle, > + IN VOID *Mapping, > + IN UINT64 IoMmuAccess > + ); > + > +/// > +/// IOMMU Protocol structure. > +/// > +struct _EDKII_IOMMU_PROTOCOL { > + UINT64 Revision; > + EDKII_IOMMU_SET_ATTRIBUTE SetAttribute; > + EDKII_IOMMU_MAP Map; > + EDKII_IOMMU_UNMAP Unmap; > + EDKII_IOMMU_ALLOCATE_BUFFER AllocateBuffer; > + EDKII_IOMMU_FREE_BUFFER FreeBuffer; > + EDKII_IOMMU_SET_MAPPING_ATTRIBUTE SetMappingAttribute; > +}; > + > +/// > +/// IOMMU Protocol GUID variable. > +/// > +extern EFI_GUID gEdkiiIoMmuProtocolGuid; > + > +#endif > diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.de= c > index 356b3e1..db596b6 100644 > --- a/MdeModulePkg/MdeModulePkg.dec > +++ b/MdeModulePkg/MdeModulePkg.dec > @@ -540,6 +540,9 @@ > ## Include/Protocol/NonDiscoverableDevice.h > gEdkiiNonDiscoverableDeviceProtocolGuid =3D { 0x0d51905b, 0xb77e, 0x45= 2a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } } > > + ## Include/Protocol/IoMmu.h > + gEdkiiIoMmuProtocolGuid =3D { 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed= , 0xe6, 0xe1, 0xce, 0x51, 0x7c, 0x1e } } > + > # > # [Error.gEfiMdeModulePkgTokenSpaceGuid] > # 0x80000001 | Invalid value provided. > -- > 2.7.4.windows.1 > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel