* [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-25 9:28 [RFC] [PATCH " Jiewen Yao
@ 2017-03-25 9:28 ` Jiewen Yao
2017-03-28 22:38 ` Ard Biesheuvel
0 siblings, 1 reply; 19+ messages in thread
From: Jiewen Yao @ 2017-03-25 9:28 UTC (permalink / raw)
To: edk2-devel; +Cc: Ruiyu Ni, Leo Duran, Brijesh Singh
This protocol is to abstract IOMMU access.
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Leo Duran <leo.duran@amd.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
MdeModulePkg/Include/Protocol/IoMmu.h | 132 ++++++++++++++++++++
MdeModulePkg/MdeModulePkg.dec | 3 +
2 files changed, 135 insertions(+)
diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h b/MdeModulePkg/Include/Protocol/IoMmu.h
new file mode 100644
index 0000000..55b9c78
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/IoMmu.h
@@ -0,0 +1,132 @@
+/** @file
+ EFI IOMMU Protocol.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+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 IMPLIED.
+
+**/
+
+
+#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 the same GUID.
+//
+#define EDKII_IOMMU_PROTOCOL_REVISION 0x00010000
+
+//
+// IOMMU attribute.
+// These types can be "ORed" together as needed.
+// Any undefined bits are reserved and must be zero.
+//
+#define EDKII_IOMMU_ATTRIBUTE_READ 0x1
+#define EDKII_IOMMU_ATTRIBUTE_WRITE 0x2
+
+/**
+ 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 it is.
+ The IOMMU implementation need translate the device path to an IOMMU device ID,
+ and set IOMMU hardware register accordingly.
+ 1) DeviceHandle can be a standard PCI device.
+ The memory for BusMasterRead need set EDKII_IOMMU_ATTRIBUTE_READ.
+ The memory for BusMasterWrite need set EDKII_IOMMU_ATTRIBUTE_WRITE.
+ The memory for BusMasterCommonBuffer need set EDKII_IOMMU_ATTRIBUTE_READ|EDKII_IOMMU_ATTRIBUTE_WRITE.
+ After the memory is used, the memory need set 0 to keep it being protected.
+ 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
+ The memory for DMA access need set EDKII_IOMMU_ATTRIBUTE_READ and/or EDKII_IOMMU_ATTRIBUTE_WRITE.
+
+ @param This The protocol instance pointer.
+ @param DeviceHandle The device who initiates the DMA access request.
+ @param BaseAddress The base of system memory address to be used as the DMA memory.
+ @param Length The length of system memory address to be used as the DMA memory.
+ @param IoMmuAttribute The IOMMU attribute.
+
+ @retval EFI_SUCCESS The IoMmuAttribute is set for the memory range specified by BaseAddress and Length.
+ @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
+ @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
+ @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
+ @retval EFI_INVALID_PARAMETER Length is 0.
+ @retval EFI_INVALID_PARAMETER IoMmuAttribute specified an illegal combination of attributes.
+ @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
+ @retval EFI_UNSUPPORTED The bit mask of IoMmuAttribute is not supported by the IOMMU.
+ @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU attribute.
+ @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)(
+ IN EDKII_IOMMU_PROTOCOL *This,
+ IN EFI_HANDLE DeviceHandle,
+ IN UINT64 BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 IoMmuAttribute
+ );
+
+/**
+ Get IOMMU page size.
+
+ This is the minimal supported page size for a IOMMU.
+ For example, if an IOMMU supports 4KiB, 2MiB and 1GiB,
+ 4KiB should be returned.
+
+ @param This Protocol instance pointer.
+ @param PageSize The minimal supported page size for a IOMMU.
+
+ @retval EFI_SUCCESS The page size is returned.
+ @retval EFI_INVALID_PARAMETER PageSize is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_IOMMU_GET_PAGE_SIZE)(
+ IN EDKII_IOMMU_PROTOCOL *This,
+ OUT UINTN *PageSize
+ );
+
+///
+/// IOMMU Protocol structure.
+///
+struct _EDKII_IOMMU_PROTOCOL {
+ UINT64 Revision;
+ EDKII_IOMMU_GET_PAGE_SIZE GetPageSize;
+ EDKII_IOMMU_SET_ATTRIBUTE SetAttribute;
+};
+
+///
+/// IOMMU Protocol GUID variable.
+///
+extern EFI_GUID gEdkiiIoMmuProtocolGuid;
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 356b3e1..db596b6 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -540,6 +540,9 @@
## Include/Protocol/NonDiscoverableDevice.h
gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
+ ## Include/Protocol/IoMmu.h
+ gEdkiiIoMmuProtocolGuid = { 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 0x1e } }
+
#
# [Error.gEfiMdeModulePkgTokenSpaceGuid]
# 0x80000001 | Invalid value provided.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-25 9:28 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
@ 2017-03-28 22:38 ` Ard Biesheuvel
2017-03-28 23:02 ` Kinney, Michael D
0 siblings, 1 reply; 19+ messages in thread
From: Ard Biesheuvel @ 2017-03-28 22:38 UTC (permalink / raw)
To: Jiewen Yao; +Cc: edk2-devel@lists.01.org, Ruiyu Ni, Brijesh Singh, Leo Duran
On 25 March 2017 at 09:28, Jiewen Yao <jiewen.yao@intel.com> wrote:
> This protocol is to abstract IOMMU access.
>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Leo Duran <leo.duran@amd.com>
> Cc: Brijesh Singh <brijesh.singh@amd.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Hello all,
It would be very useful for a IOMMU protocol such as this one to
support non-identity mappings between the host and the PCI bus.
On 64-bit ARM systems, no RAM may exist below 4 GB, and if a IOMMU is
available, it could be used to remap RAM for DMA in a way that makes
it 32-bit addressable for PCI masters that are not 64-bit capable.
The PCI protocols in UEFI already allow such non-identity mappings. If
a IOMMU protocol is introduced, it makes sense to allow it to be
involved in establishing the device address when performing a map
operation.
--
Ard.
> ---
> MdeModulePkg/Include/Protocol/IoMmu.h | 132 ++++++++++++++++++++
> MdeModulePkg/MdeModulePkg.dec | 3 +
> 2 files changed, 135 insertions(+)
>
> diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h b/MdeModulePkg/Include/Protocol/IoMmu.h
> new file mode 100644
> index 0000000..55b9c78
> --- /dev/null
> +++ b/MdeModulePkg/Include/Protocol/IoMmu.h
> @@ -0,0 +1,132 @@
> +/** @file
> + EFI IOMMU Protocol.
> +
> +Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials are licensed and made available under
> +the terms and conditions of the BSD License that accompanies this distribution.
> +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 IMPLIED.
> +
> +**/
> +
> +
> +#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 the same GUID.
> +//
> +#define EDKII_IOMMU_PROTOCOL_REVISION 0x00010000
> +
> +//
> +// IOMMU attribute.
> +// These types can be "ORed" together as needed.
> +// Any undefined bits are reserved and must be zero.
> +//
> +#define EDKII_IOMMU_ATTRIBUTE_READ 0x1
> +#define EDKII_IOMMU_ATTRIBUTE_WRITE 0x2
> +
> +/**
> + 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 it is.
> + The IOMMU implementation need translate the device path to an IOMMU device ID,
> + and set IOMMU hardware register accordingly.
> + 1) DeviceHandle can be a standard PCI device.
> + The memory for BusMasterRead need set EDKII_IOMMU_ATTRIBUTE_READ.
> + The memory for BusMasterWrite need set EDKII_IOMMU_ATTRIBUTE_WRITE.
> + The memory for BusMasterCommonBuffer need set EDKII_IOMMU_ATTRIBUTE_READ|EDKII_IOMMU_ATTRIBUTE_WRITE.
> + After the memory is used, the memory need set 0 to keep it being protected.
> + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> + The memory for DMA access need set EDKII_IOMMU_ATTRIBUTE_READ and/or EDKII_IOMMU_ATTRIBUTE_WRITE.
> +
> + @param This The protocol instance pointer.
> + @param DeviceHandle The device who initiates the DMA access request.
> + @param BaseAddress The base of system memory address to be used as the DMA memory.
> + @param Length The length of system memory address to be used as the DMA memory.
> + @param IoMmuAttribute The IOMMU attribute.
> +
> + @retval EFI_SUCCESS The IoMmuAttribute is set for the memory range specified by BaseAddress and Length.
> + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
> + @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
> + @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
> + @retval EFI_INVALID_PARAMETER Length is 0.
> + @retval EFI_INVALID_PARAMETER IoMmuAttribute specified an illegal combination of attributes.
> + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> + @retval EFI_UNSUPPORTED The bit mask of IoMmuAttribute is not supported by the IOMMU.
> + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU attribute.
> + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)(
> + IN EDKII_IOMMU_PROTOCOL *This,
> + IN EFI_HANDLE DeviceHandle,
> + IN UINT64 BaseAddress,
> + IN UINT64 Length,
> + IN UINT64 IoMmuAttribute
> + );
> +
> +/**
> + Get IOMMU page size.
> +
> + This is the minimal supported page size for a IOMMU.
> + For example, if an IOMMU supports 4KiB, 2MiB and 1GiB,
> + 4KiB should be returned.
> +
> + @param This Protocol instance pointer.
> + @param PageSize The minimal supported page size for a IOMMU.
> +
> + @retval EFI_SUCCESS The page size is returned.
> + @retval EFI_INVALID_PARAMETER PageSize is NULL.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_IOMMU_GET_PAGE_SIZE)(
> + IN EDKII_IOMMU_PROTOCOL *This,
> + OUT UINTN *PageSize
> + );
> +
> +///
> +/// IOMMU Protocol structure.
> +///
> +struct _EDKII_IOMMU_PROTOCOL {
> + UINT64 Revision;
> + EDKII_IOMMU_GET_PAGE_SIZE GetPageSize;
> + EDKII_IOMMU_SET_ATTRIBUTE SetAttribute;
> +};
> +
> +///
> +/// IOMMU Protocol GUID variable.
> +///
> +extern EFI_GUID gEdkiiIoMmuProtocolGuid;
> +
> +#endif
> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> index 356b3e1..db596b6 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -540,6 +540,9 @@
> ## Include/Protocol/NonDiscoverableDevice.h
> gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
>
> + ## Include/Protocol/IoMmu.h
> + gEdkiiIoMmuProtocolGuid = { 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
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-28 22:38 ` Ard Biesheuvel
@ 2017-03-28 23:02 ` Kinney, Michael D
2017-03-28 23:45 ` Yao, Jiewen
0 siblings, 1 reply; 19+ messages in thread
From: Kinney, Michael D @ 2017-03-28 23:02 UTC (permalink / raw)
To: Ard Biesheuvel, Yao, Jiewen, Kinney, Michael D
Cc: Ni, Ruiyu, Leo Duran, edk2-devel@lists.01.org, Brijesh Singh
Ard,
I agree. And I think the IOMMU protocol should also support flexible
double buffer operations so the extra copies by the host CPU can be
avoided if the logical DMA address can directly map to the original
buffer.
Mike
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ard
> Biesheuvel
> Sent: Tuesday, March 28, 2017 3:39 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>; edk2-
> devel@lists.01.org; Brijesh Singh <brijesh.singh@amd.com>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol
> definition.
>
> On 25 March 2017 at 09:28, Jiewen Yao <jiewen.yao@intel.com> wrote:
> > This protocol is to abstract IOMMU access.
> >
> > Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> > Cc: Leo Duran <leo.duran@amd.com>
> > Cc: Brijesh Singh <brijesh.singh@amd.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
>
> Hello all,
>
> It would be very useful for a IOMMU protocol such as this one to
> support non-identity mappings between the host and the PCI bus.
>
> On 64-bit ARM systems, no RAM may exist below 4 GB, and if a IOMMU is
> available, it could be used to remap RAM for DMA in a way that makes
> it 32-bit addressable for PCI masters that are not 64-bit capable.
>
> The PCI protocols in UEFI already allow such non-identity mappings. If
> a IOMMU protocol is introduced, it makes sense to allow it to be
> involved in establishing the device address when performing a map
> operation.
>
> --
> Ard.
>
>
> > ---
> > MdeModulePkg/Include/Protocol/IoMmu.h | 132 ++++++++++++++++++++
> > MdeModulePkg/MdeModulePkg.dec | 3 +
> > 2 files changed, 135 insertions(+)
> >
> > diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h
> b/MdeModulePkg/Include/Protocol/IoMmu.h
> > new file mode 100644
> > index 0000000..55b9c78
> > --- /dev/null
> > +++ b/MdeModulePkg/Include/Protocol/IoMmu.h
> > @@ -0,0 +1,132 @@
> > +/** @file
> > + EFI IOMMU Protocol.
> > +
> > +Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> > +This program and the accompanying materials are licensed and made available
> under
> > +the terms and conditions of the BSD License that accompanies this distribution.
> > +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 IMPLIED.
> > +
> > +**/
> > +
> > +
> > +#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 the same
> GUID.
> > +//
> > +#define EDKII_IOMMU_PROTOCOL_REVISION 0x00010000
> > +
> > +//
> > +// IOMMU attribute.
> > +// These types can be "ORed" together as needed.
> > +// Any undefined bits are reserved and must be zero.
> > +//
> > +#define EDKII_IOMMU_ATTRIBUTE_READ 0x1
> > +#define EDKII_IOMMU_ATTRIBUTE_WRITE 0x2
> > +
> > +/**
> > + 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 it is.
> > + The IOMMU implementation need translate the device path to an IOMMU device ID,
> > + and set IOMMU hardware register accordingly.
> > + 1) DeviceHandle can be a standard PCI device.
> > + The memory for BusMasterRead need set EDKII_IOMMU_ATTRIBUTE_READ.
> > + The memory for BusMasterWrite need set EDKII_IOMMU_ATTRIBUTE_WRITE.
> > + The memory for BusMasterCommonBuffer need set
> EDKII_IOMMU_ATTRIBUTE_READ|EDKII_IOMMU_ATTRIBUTE_WRITE.
> > + After the memory is used, the memory need set 0 to keep it being protected.
> > + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> > + The memory for DMA access need set EDKII_IOMMU_ATTRIBUTE_READ and/or
> EDKII_IOMMU_ATTRIBUTE_WRITE.
> > +
> > + @param This The protocol instance pointer.
> > + @param DeviceHandle The device who initiates the DMA access request.
> > + @param BaseAddress The base of system memory address to be used as the
> DMA memory.
> > + @param Length The length of system memory address to be used as
> the DMA memory.
> > + @param IoMmuAttribute The IOMMU attribute.
> > +
> > + @retval EFI_SUCCESS The IoMmuAttribute is set for the memory range
> specified by BaseAddress and Length.
> > + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
> > + @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
> > + @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
> > + @retval EFI_INVALID_PARAMETER Length is 0.
> > + @retval EFI_INVALID_PARAMETER IoMmuAttribute specified an illegal combination
> of attributes.
> > + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> > + @retval EFI_UNSUPPORTED The bit mask of IoMmuAttribute is not supported
> by the IOMMU.
> > + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range
> specified by BaseAddress and Length.
> > + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
> modify the IOMMU attribute.
> > + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while
> attempting the operation.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)(
> > + IN EDKII_IOMMU_PROTOCOL *This,
> > + IN EFI_HANDLE DeviceHandle,
> > + IN UINT64 BaseAddress,
> > + IN UINT64 Length,
> > + IN UINT64 IoMmuAttribute
> > + );
> > +
> > +/**
> > + Get IOMMU page size.
> > +
> > + This is the minimal supported page size for a IOMMU.
> > + For example, if an IOMMU supports 4KiB, 2MiB and 1GiB,
> > + 4KiB should be returned.
> > +
> > + @param This Protocol instance pointer.
> > + @param PageSize The minimal supported page size for a IOMMU.
> > +
> > + @retval EFI_SUCCESS The page size is returned.
> > + @retval EFI_INVALID_PARAMETER PageSize is NULL.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EDKII_IOMMU_GET_PAGE_SIZE)(
> > + IN EDKII_IOMMU_PROTOCOL *This,
> > + OUT UINTN *PageSize
> > + );
> > +
> > +///
> > +/// IOMMU Protocol structure.
> > +///
> > +struct _EDKII_IOMMU_PROTOCOL {
> > + UINT64 Revision;
> > + EDKII_IOMMU_GET_PAGE_SIZE GetPageSize;
> > + EDKII_IOMMU_SET_ATTRIBUTE SetAttribute;
> > +};
> > +
> > +///
> > +/// IOMMU Protocol GUID variable.
> > +///
> > +extern EFI_GUID gEdkiiIoMmuProtocolGuid;
> > +
> > +#endif
> > diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> > index 356b3e1..db596b6 100644
> > --- a/MdeModulePkg/MdeModulePkg.dec
> > +++ b/MdeModulePkg/MdeModulePkg.dec
> > @@ -540,6 +540,9 @@
> > ## Include/Protocol/NonDiscoverableDevice.h
> > gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2,
> 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
> >
> > + ## Include/Protocol/IoMmu.h
> > + gEdkiiIoMmuProtocolGuid = { 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
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-28 23:02 ` Kinney, Michael D
@ 2017-03-28 23:45 ` Yao, Jiewen
2017-03-29 14:22 ` Ard Biesheuvel
0 siblings, 1 reply; 19+ messages in thread
From: Yao, Jiewen @ 2017-03-28 23:45 UTC (permalink / raw)
To: Kinney, Michael D, Ard Biesheuvel
Cc: Ni, Ruiyu, Leo Duran, edk2-devel@lists.01.org, Brijesh Singh
Agree. That is a good idea.
I will add that in V2 patch.
Thank you
Yao Jiewen
From: Kinney, Michael D
Sent: Wednesday, March 29, 2017 7:03 AM
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Yao, Jiewen <jiewen.yao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>; edk2-devel@lists.01.org; Brijesh Singh <brijesh.singh@amd.com>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
Ard,
I agree. And I think the IOMMU protocol should also support flexible
double buffer operations so the extra copies by the host CPU can be
avoided if the logical DMA address can directly map to the original
buffer.
Mike
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ard
> Biesheuvel
> Sent: Tuesday, March 28, 2017 3:39 PM
> To: Yao, Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>; Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>; edk2-
> devel@lists.01.org<mailto:devel@lists.01.org>; Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol
> definition.
>
> On 25 March 2017 at 09:28, Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>> wrote:
> > This protocol is to abstract IOMMU access.
> >
> > Cc: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> > Cc: Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>
> > Cc: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
>
> Hello all,
>
> It would be very useful for a IOMMU protocol such as this one to
> support non-identity mappings between the host and the PCI bus.
>
> On 64-bit ARM systems, no RAM may exist below 4 GB, and if a IOMMU is
> available, it could be used to remap RAM for DMA in a way that makes
> it 32-bit addressable for PCI masters that are not 64-bit capable.
>
> The PCI protocols in UEFI already allow such non-identity mappings. If
> a IOMMU protocol is introduced, it makes sense to allow it to be
> involved in establishing the device address when performing a map
> operation.
>
> --
> Ard.
>
>
> > ---
> > MdeModulePkg/Include/Protocol/IoMmu.h | 132 ++++++++++++++++++++
> > MdeModulePkg/MdeModulePkg.dec | 3 +
> > 2 files changed, 135 insertions(+)
> >
> > diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h
> b/MdeModulePkg/Include/Protocol/IoMmu.h
> > new file mode 100644
> > index 0000000..55b9c78
> > --- /dev/null
> > +++ b/MdeModulePkg/Include/Protocol/IoMmu.h
> > @@ -0,0 +1,132 @@
> > +/** @file
> > + EFI IOMMU Protocol.
> > +
> > +Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> > +This program and the accompanying materials are licensed and made available
> under
> > +the terms and conditions of the BSD License that accompanies this distribution.
> > +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 IMPLIED.
> > +
> > +**/
> > +
> > +
> > +#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 the same
> GUID.
> > +//
> > +#define EDKII_IOMMU_PROTOCOL_REVISION 0x00010000
> > +
> > +//
> > +// IOMMU attribute.
> > +// These types can be "ORed" together as needed.
> > +// Any undefined bits are reserved and must be zero.
> > +//
> > +#define EDKII_IOMMU_ATTRIBUTE_READ 0x1
> > +#define EDKII_IOMMU_ATTRIBUTE_WRITE 0x2
> > +
> > +/**
> > + 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 it is.
> > + The IOMMU implementation need translate the device path to an IOMMU device ID,
> > + and set IOMMU hardware register accordingly.
> > + 1) DeviceHandle can be a standard PCI device.
> > + The memory for BusMasterRead need set EDKII_IOMMU_ATTRIBUTE_READ.
> > + The memory for BusMasterWrite need set EDKII_IOMMU_ATTRIBUTE_WRITE.
> > + The memory for BusMasterCommonBuffer need set
> EDKII_IOMMU_ATTRIBUTE_READ|EDKII_IOMMU_ATTRIBUTE_WRITE.
> > + After the memory is used, the memory need set 0 to keep it being protected.
> > + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> > + The memory for DMA access need set EDKII_IOMMU_ATTRIBUTE_READ and/or
> EDKII_IOMMU_ATTRIBUTE_WRITE.
> > +
> > + @param This The protocol instance pointer.
> > + @param DeviceHandle The device who initiates the DMA access request.
> > + @param BaseAddress The base of system memory address to be used as the
> DMA memory.
> > + @param Length The length of system memory address to be used as
> the DMA memory.
> > + @param IoMmuAttribute The IOMMU attribute.
> > +
> > + @retval EFI_SUCCESS The IoMmuAttribute is set for the memory range
> specified by BaseAddress and Length.
> > + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
> > + @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
> > + @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
> > + @retval EFI_INVALID_PARAMETER Length is 0.
> > + @retval EFI_INVALID_PARAMETER IoMmuAttribute specified an illegal combination
> of attributes.
> > + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> > + @retval EFI_UNSUPPORTED The bit mask of IoMmuAttribute is not supported
> by the IOMMU.
> > + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range
> specified by BaseAddress and Length.
> > + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
> modify the IOMMU attribute.
> > + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while
> attempting the operation.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)(
> > + IN EDKII_IOMMU_PROTOCOL *This,
> > + IN EFI_HANDLE DeviceHandle,
> > + IN UINT64 BaseAddress,
> > + IN UINT64 Length,
> > + IN UINT64 IoMmuAttribute
> > + );
> > +
> > +/**
> > + Get IOMMU page size.
> > +
> > + This is the minimal supported page size for a IOMMU.
> > + For example, if an IOMMU supports 4KiB, 2MiB and 1GiB,
> > + 4KiB should be returned.
> > +
> > + @param This Protocol instance pointer.
> > + @param PageSize The minimal supported page size for a IOMMU.
> > +
> > + @retval EFI_SUCCESS The page size is returned.
> > + @retval EFI_INVALID_PARAMETER PageSize is NULL.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EDKII_IOMMU_GET_PAGE_SIZE)(
> > + IN EDKII_IOMMU_PROTOCOL *This,
> > + OUT UINTN *PageSize
> > + );
> > +
> > +///
> > +/// IOMMU Protocol structure.
> > +///
> > +struct _EDKII_IOMMU_PROTOCOL {
> > + UINT64 Revision;
> > + EDKII_IOMMU_GET_PAGE_SIZE GetPageSize;
> > + EDKII_IOMMU_SET_ATTRIBUTE SetAttribute;
> > +};
> > +
> > +///
> > +/// IOMMU Protocol GUID variable.
> > +///
> > +extern EFI_GUID gEdkiiIoMmuProtocolGuid;
> > +
> > +#endif
> > diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> > index 356b3e1..db596b6 100644
> > --- a/MdeModulePkg/MdeModulePkg.dec
> > +++ b/MdeModulePkg/MdeModulePkg.dec
> > @@ -540,6 +540,9 @@
> > ## Include/Protocol/NonDiscoverableDevice.h
> > gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2,
> 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
> >
> > + ## Include/Protocol/IoMmu.h
> > + gEdkiiIoMmuProtocolGuid = { 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<mailto:edk2-devel@lists.01.org>
> > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-28 23:45 ` Yao, Jiewen
@ 2017-03-29 14:22 ` Ard Biesheuvel
2017-03-30 12:37 ` Yao, Jiewen
0 siblings, 1 reply; 19+ messages in thread
From: Ard Biesheuvel @ 2017-03-29 14:22 UTC (permalink / raw)
To: Yao, Jiewen
Cc: Kinney, Michael D, Ni, Ruiyu, Leo Duran, edk2-devel@lists.01.org,
Brijesh Singh
On 29 March 2017 at 00:45, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> Agree. That is a good idea.
>
>
>
> I will add that in V2 patch.
>
Hello Jiewen,
As a bit of background, what I have in mind is an enhancement of the
PCI root bridge I/O allocate, map and unmap methods so that situations
that would currently lead to failure or to suboptimal performance are
left for the IOMMU protocol to handle if one is present. Note that
this may imply having IOMMU protocol instances for each PCI root
bridge, and for other masters as well. (For example, AMD Seattle has
separate IOMMUs for PCI and for the networking controllers, which are
wired to the internal interconnect directly)
So in RootBridgeIoMap(), for instance, we have this condition
PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
if ((!RootBridge->DmaAbove4G ||
(Operation != EfiPciOperationBusMasterRead64 &&
Operation != EfiPciOperationBusMasterWrite64 &&
Operation != EfiPciOperationBusMasterCommonBuffer64)) &&
((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
to decide whether bounce buffering is necessary (or even possible).
The mapping between DeviceAddress and HostAddress could be supplied by
the IOMMU protocol instance, which also means we should reinterpret
DmaAbove4G and other variables related to 32-bit addressing to apply
to the device address and not the physical address.
Similarly, in RootBridgeIoAllocateBuffer(), a failure to allocate
below 4 GB may not be an error if the IOMMU protocol instance can
provide a 32-bit addressable mapping for it.
I am aware that this complicates matters for you, but having IOMMU
support in the generic PCI host bridge driver is extremely useful for
us. I am happy to help out in any way I can.
Thanks,
Ard.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-29 14:22 ` Ard Biesheuvel
@ 2017-03-30 12:37 ` Yao, Jiewen
2017-03-30 13:54 ` Ard Biesheuvel
0 siblings, 1 reply; 19+ messages in thread
From: Yao, Jiewen @ 2017-03-30 12:37 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Kinney, Michael D, Ni, Ruiyu, Leo Duran, edk2-devel@lists.01.org,
Brijesh Singh
Thanks for the info.
Comment inline.
From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
Sent: Wednesday, March 29, 2017 10:23 PM
To: Yao, Jiewen <jiewen.yao@intel.com>
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ruiyu <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>; edk2-devel@lists.01.org; Brijesh Singh <brijesh.singh@amd.com>
Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
On 29 March 2017 at 00:45, Yao, Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>> wrote:
> Agree. That is a good idea.
>
>
>
> I will add that in V2 patch.
>
Hello Jiewen,
As a bit of background, what I have in mind is an enhancement of the
PCI root bridge I/O allocate, map and unmap methods so that situations
that would currently lead to failure or to suboptimal performance are
left for the IOMMU protocol to handle if one is present. Note that
this may imply having IOMMU protocol instances for each PCI root
bridge, and for other masters as well. (For example, AMD Seattle has
separate IOMMUs for PCI and for the networking controllers, which are
wired to the internal interconnect directly)
[Jiewen] I am not very sure what do you mean.
Fist, let me explain Intel platform.
There might be multiple IOMMU engines on one platform. one for graphic and one for rest PCI device (such as ATA/USB).
But all IOMMU engines are reported by one “DMAR” ACPI table.
In such case, the Intel IOMMU driver just produces one IOMMU protocol, based upon DMAR ACPI table.
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.
I know AMD has “IVRS” ACPI table and ARM has “IORT” ACPI table.
In such case, I assume AMD may have one IOMMU protocol based upon IVRS table, and ARM may have one IOMMU protocol based upon IORT table.
And this single IOMMU protocol provider can handle multiple IOMMU engines on one system.
Is that understand same as yours?
So in RootBridgeIoMap(), for instance, we have this condition
PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
if ((!RootBridge->DmaAbove4G ||
(Operation != EfiPciOperationBusMasterRead64 &&
Operation != EfiPciOperationBusMasterWrite64 &&
Operation != EfiPciOperationBusMasterCommonBuffer64)) &&
((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
to decide whether bounce buffering is necessary (or even possible).
The mapping between DeviceAddress and HostAddress could be supplied by
the IOMMU protocol instance, which also means we should reinterpret
DmaAbove4G and other variables related to 32-bit addressing to apply
to the device address and not the physical address.
Similarly, in RootBridgeIoAllocateBuffer(), a failure to allocate
below 4 GB may not be an error if the IOMMU protocol instance can
provide a 32-bit addressable mapping for it.
[Jiewen] It is a good idea to remap based upon IOMMU.
However, one potential problem is that the memory size if not IOMMU page aligned.
In such case, PciRootBridge driver has to allocate another IOMMU page aligned memory for DMA buffer.
I believe the benefit will be got, only if the device driver who submit DMA request allocate IOMMU page aligned memory for DMA request.
I am aware that this complicates matters for you, but having IOMMU
support in the generic PCI host bridge driver is extremely useful for
us. I am happy to help out in any way I can.
[Jiewen] Yes, I definitely need comment for ARM/AMD/other system architecture.
Thanks,
Ard.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-03-30 12:37 ` Yao, Jiewen
@ 2017-03-30 13:54 ` Ard Biesheuvel
0 siblings, 0 replies; 19+ messages in thread
From: Ard Biesheuvel @ 2017-03-30 13:54 UTC (permalink / raw)
To: Yao, Jiewen
Cc: Kinney, Michael D, Ni, Ruiyu, Leo Duran, edk2-devel@lists.01.org,
Brijesh Singh
On 30 March 2017 at 13:37, Yao, Jiewen <jiewen.yao@intel.com> wrote:
> Thanks for the info.
>
>
>
> Comment inline.
>
>
>
>
>
>
>
>
>
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: Wednesday, March 29, 2017 10:23 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ruiyu
> <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>;
> edk2-devel@lists.01.org; Brijesh Singh <brijesh.singh@amd.com>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol
> definition.
>
>
>
> On 29 March 2017 at 00:45, Yao, Jiewen <jiewen.yao@intel.com> wrote:
>> Agree. That is a good idea.
>>
>>
>>
>> I will add that in V2 patch.
>>
>
> Hello Jiewen,
>
> As a bit of background, what I have in mind is an enhancement of the
> PCI root bridge I/O allocate, map and unmap methods so that situations
> that would currently lead to failure or to suboptimal performance are
> left for the IOMMU protocol to handle if one is present. Note that
> this may imply having IOMMU protocol instances for each PCI root
> bridge, and for other masters as well. (For example, AMD Seattle has
> separate IOMMUs for PCI and for the networking controllers, which are
> wired to the internal interconnect directly)
>
>
>
> [Jiewen] I am not very sure what do you mean.
>
>
>
> Fist, let me explain Intel platform.
>
>
>
> There might be multiple IOMMU engines on one platform. one for graphic and
> one for rest PCI device (such as ATA/USB).
>
> But all IOMMU engines are reported by one “DMAR” ACPI table.
>
>
>
> In such case, the Intel IOMMU driver just produces one IOMMU protocol, based
> upon DMAR ACPI table.
>
>
>
> 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.
>
>
>
> I know AMD has “IVRS” ACPI table and ARM has “IORT” ACPI table.
>
>
>
> In such case, I assume AMD may have one IOMMU protocol based upon IVRS
> table, and ARM may have one IOMMU protocol based upon IORT table.
>
> And this single IOMMU protocol provider can handle multiple IOMMU engines on
> one system.
>
>
>
> Is that understand same as yours?
>
OK, that works for me.
>
>
>
>
>
>
> So in RootBridgeIoMap(), for instance, we have this condition
>
> PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
> if ((!RootBridge->DmaAbove4G ||
> (Operation != EfiPciOperationBusMasterRead64 &&
> Operation != EfiPciOperationBusMasterWrite64 &&
> Operation != EfiPciOperationBusMasterCommonBuffer64)) &&
> ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
>
> to decide whether bounce buffering is necessary (or even possible).
> The mapping between DeviceAddress and HostAddress could be supplied by
> the IOMMU protocol instance, which also means we should reinterpret
> DmaAbove4G and other variables related to 32-bit addressing to apply
> to the device address and not the physical address.
>
> Similarly, in RootBridgeIoAllocateBuffer(), a failure to allocate
> below 4 GB may not be an error if the IOMMU protocol instance can
> provide a 32-bit addressable mapping for it.
>
> [Jiewen] It is a good idea to remap based upon IOMMU.
>
>
>
> However, one potential problem is that the memory size if not IOMMU page
> aligned.
>
> In such case, PciRootBridge driver has to allocate another IOMMU page
> aligned memory for DMA buffer.
>
>
>
> I believe the benefit will be got, only if the device driver who submit DMA
> request allocate IOMMU page aligned memory for DMA request.
>
Well, allocating memory and remapping host memory into the PCI address
space are not the same thing. In the absence of concerns about
isolation, I don't think it should be a problem to round up IOMMU
mappings to sizes it can handle [efficiently].
>
>
>
>
>
> I am aware that this complicates matters for you, but having IOMMU
> support in the generic PCI host bridge driver is extremely useful for
> us. I am happy to help out in any way I can.
> [Jiewen] Yes, I definitely need comment for ARM/AMD/other system
> architecture.
>
>
>
>
>
>
> Thanks,
> Ard.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC] [PATCH V4 0/3] Add IOMMU support.
@ 2017-04-29 13:48 Jiewen Yao
2017-04-29 13:48 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
` (4 more replies)
0 siblings, 5 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-04-29 13:48 UTC (permalink / raw)
To: edk2-devel; +Cc: Ruiyu Ni, Leo Duran, Brijesh Singh, Ard Biesheuvel
================ V4 ==============
Refine the EDKII_IOMMU_PROTOCOL.
1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
They are similar to DmaLib in EmbeddedPkg and
similar to the previous BmDmaLib (by leo.duran@amd.com).
These APIs are invoked by PciHostBridge driver
to allocate DMA memory.
The PciHostBridge driver (IOMMU consumer) is simplified:
It uses IOMMU, if IOMMU protocol is present.
Else it uses original logic.
2) Add SetMappingAttribute() API.
It is similar to SetAttribute() API in V1.
This API is invoked by PciBus driver to set DMA
access attribute (read/write) for device.
The PciBus driver (IOMMU consumer) is simplified:
It sets access attribute in Map/Unmap,
if IOMMU protocol is present.
3) Remove SetRemapAddress/GetRemapAddress() API.
Because PciHostBridge/PciBus can call the APIs defined
above, there is no need to provide remap capability.
-- Sample producer drivers:
1) The sample VTd driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe
It is added to show the concept. It is not fully implemented yet.
It will not be checked in in this patch.
2) The sample AMD SEV driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDxe
(code is borrowed from leo.duran@amd.com and brijesh.singh@amd.com)
This is not a right place to put this driver.
It is added to show the concept.
It is not fully implemented. It will not be checked in.
Please do not use it directly.
3) The sample STYX driver (IOMMU producer)
is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
(code is borrowed from ard.biesheuvel@linaro.org)
This is not a right place to put this driver.
It is added to show the concept.
It is not fully implemented. It will not be checked in.
Please do not use it directly.
================ V3 ==============
1) Add Remap capability (from Ard Biesheuvel)
Add EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.
NOTE: The code is not fully validated yet.
The purpose is to collect feedback to decide the next step.
================ V2 ==============
1) Enhance Unmap() in PciIo (From Ruiyu Ni)
Maintain a local list of MapInfo and match it in Unmap.
2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran)
Fix a bug in V1 that copy mem for read happen before SetAttribute,
which will break AMD SEV solution.
================ V1 ==============
This patch series adds IOMMU protocol and updates the consumer
to support IOMMU based DMA access in UEFI.
This patch series can support the BmDmaLib request for AMD SEV.
submitted by Duran, Leo <leo.duran@amd.com> and Brijesh Singh <brijesh.ksingh@gmail.com>.
https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
and clear SEV in IOMMU->SetAttribute().
This patch series can also support Intel VTd based DMA protection,
requested by Jiewen Yao <jiewen.yao@intel.com>, discussed in
https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
and update VTd engine to grant or deny access in IOMMU->SetAttribute().
This patch series does not provide a full Intel VTd driver, which
will be provide in other patch in the future.
The purpose of this patch series to review if this IOMMU protocol design
can meet all DMA access and management requirement.
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Jiewen Yao (3):
MdeModulePkg/Include: Add IOMMU protocol definition.
MdeModulePkg/PciHostBridge: Add IOMMU support.
MdeModulePkg/PciBus: Add IOMMU support.
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 +++
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 37 +++
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 +
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 2 +
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 61 ++++
MdeModulePkg/Include/Protocol/IoMmu.h | 310 ++++++++++++++++++++
MdeModulePkg/MdeModulePkg.dec | 3 +
10 files changed, 463 insertions(+)
create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h
--
2.7.4.windows.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-04-29 13:48 [RFC] [PATCH V4 0/3] Add IOMMU support Jiewen Yao
@ 2017-04-29 13:48 ` Jiewen Yao
2017-05-02 9:56 ` Ard Biesheuvel
2017-04-29 13:48 ` [PATCH 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support Jiewen Yao
` (3 subsequent siblings)
4 siblings, 1 reply; 19+ messages in thread
From: Jiewen Yao @ 2017-04-29 13:48 UTC (permalink / raw)
To: edk2-devel; +Cc: Ruiyu Ni, Leo Duran, Brijesh Singh, Ard Biesheuvel
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 system.
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 <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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
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.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+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 IMPLIED.
+
+**/
+
+
+#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 the 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 capable of producing
+ /// PCI dual address cycles.
+ ///
+ EdkiiIoMmuOperationBusMasterRead,
+ ///
+ /// A write operation from system memory by a bus master that is not capable of producing
+ /// PCI dual address cycles.
+ ///
+ EdkiiIoMmuOperationBusMasterWrite,
+ ///
+ /// Provides both read and write access to system memory by both the processor 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 capable 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 processor 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_ATTRIBUTE_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 device 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_READ|EDKII_IOMMU_ACCESS_WRITE.
+ After the memory is used, the memory need set 0 to keep it being protected.
+ 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
+ The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_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 be used as the DMA memory.
+ @param[in] IoMmuAccess The IOMMU access.
+
+ @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
+ @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
+ @retval EFI_INVALID_PARAMETER DeviceAddress is not IoMmu Page size aligned.
+ @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 combination of access.
+ @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
+ @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
+ @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by DeviceAddress and Length.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
+ @retval EFI_DEVICE_ERROR The IOMMU device reported an error while 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
+ );
+
+/**
+ Provides the controller-specific addresses required to access system memory 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 master 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 NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested 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 OperationBusMasterCommonBuffer or
+ OperationBusMasterCommonBuffer64 mapping.
+
+ @param This The protocol instance pointer.
+ @param Type This parameter is not used and must be ignored.
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or
+ EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory 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 allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal 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 allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress 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 device 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_READ|EDKII_IOMMU_ACCESS_WRITE.
+ After the memory is used, the memory need set 0 to keep it being protected.
+ 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
+ The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_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 range 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 returned by Map().
+ @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
+ @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
+ @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
+ @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
+ @retval EFI_DEVICE_ERROR The IOMMU device reported an error while 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.dec
index 356b3e1..db596b6 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -540,6 +540,9 @@
## Include/Protocol/NonDiscoverableDevice.h
gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
+ ## Include/Protocol/IoMmu.h
+ gEdkiiIoMmuProtocolGuid = { 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 0x1e } }
+
#
# [Error.gEfiMdeModulePkgTokenSpaceGuid]
# 0x80000001 | Invalid value provided.
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support.
2017-04-29 13:48 [RFC] [PATCH V4 0/3] Add IOMMU support Jiewen Yao
2017-04-29 13:48 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
@ 2017-04-29 13:48 ` Jiewen Yao
2017-04-29 13:48 ` [PATCH 3/3] MdeModulePkg/PciBus: " Jiewen Yao
` (2 subsequent siblings)
4 siblings, 0 replies; 19+ messages in thread
From: Jiewen Yao @ 2017-04-29 13:48 UTC (permalink / raw)
To: edk2-devel; +Cc: Ruiyu Ni, Leo Duran, Brijesh Singh, Ard Biesheuvel
If IOMMU protocol is installed, PciHostBridge just calls
IOMMU AllocateBuffer/FreeBuffer/Map/Unmap.
PciHostBridge does not set IOMMU access attribute,
because it does not know which device request the DMA.
This work is done by PciBus driver.
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 37 ++++++++++++
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 +
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 2 +
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 61 ++++++++++++++++++++
4 files changed, 102 insertions(+)
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
index 9005dee..70726a6 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
@@ -28,6 +28,10 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] = {
L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus"
};
+EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
+EFI_EVENT mIoMmuEvent;
+VOID *mIoMmuRegistration;
+
/**
Ensure the compatibility of an IO space descriptor with the IO aperture.
@@ -313,6 +317,28 @@ FreeMemorySpaceMap:
}
/**
+ 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);
+ }
+}
+
+/**
Entry point of this driver.
@@ -489,6 +515,17 @@ InitializePciHostBridge (
ASSERT_EFI_ERROR (Status);
}
PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
+
+ if (!EFI_ERROR (Status)) {
+ mIoMmuEvent = EfiCreateProtocolNotifyEvent (
+ &gEdkiiIoMmuProtocolGuid,
+ TPL_CALLBACK,
+ IoMmuProtocolCallback,
+ NULL,
+ &mIoMmuRegistration
+ );
+ }
+
return Status;
}
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
index d8b0439..42bd8a2 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -41,6 +41,7 @@
BaseMemoryLib
BaseLib
PciSegmentLib
+ UefiLib
PciHostBridgeLib
[Protocols]
@@ -49,6 +50,7 @@
gEfiDevicePathProtocolGuid ## BY_START
gEfiPciRootBridgeIoProtocolGuid ## BY_START
gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START
+ gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
[Depex]
gEfiCpuIo2ProtocolGuid AND
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
index 13185b4..1fec88b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/CpuIo2.h>
#include <Protocol/DevicePath.h>
#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/IoMmu.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/BaseMemoryLib.h>
@@ -34,6 +35,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/PciSegmentLib.h>
+#include <Library/UefiLib.h>
#include "PciHostResource.h"
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
index 8af131b..068295b 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -17,6 +17,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "PciRootBridge.h"
#include "PciHostResource.h"
+extern EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
+
#define NO_MAPPING (VOID *) (UINTN) -1
//
@@ -1072,6 +1074,26 @@ RootBridgeIoMap (
RootBridge = ROOT_BRIDGE_FROM_THIS (This);
+ if (mIoMmuProtocol != NULL) {
+ if (!RootBridge->DmaAbove4G) {
+ //
+ // Clear 64bit support
+ //
+ if (Operation > EfiPciOperationBusMasterCommonBuffer) {
+ Operation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) (Operation - EfiPciOperationBusMasterRead64);
+ }
+ }
+ Status = mIoMmuProtocol->Map (
+ mIoMmuProtocol,
+ Operation,
+ HostAddress,
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
+ return Status;
+ }
+
PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
if ((!RootBridge->DmaAbove4G ||
(Operation != EfiPciOperationBusMasterRead64 &&
@@ -1194,8 +1216,18 @@ RootBridgeIoUnmap (
MAP_INFO *MapInfo;
LIST_ENTRY *Link;
PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
+ EFI_STATUS Status;
+
+ if (mIoMmuProtocol != NULL) {
+ Status = mIoMmuProtocol->Unmap (
+ mIoMmuProtocol,
+ Mapping
+ );
+ return Status;
+ }
RootBridge = ROOT_BRIDGE_FROM_THIS (This);
+
//
// See if the Map() operation associated with this Unmap() required a mapping
// buffer. If a mapping buffer was not required, then this function simply
@@ -1312,6 +1344,24 @@ RootBridgeIoAllocateBuffer (
RootBridge = ROOT_BRIDGE_FROM_THIS (This);
+ if (mIoMmuProtocol != NULL) {
+ if (!RootBridge->DmaAbove4G) {
+ //
+ // Clear DUAL_ADDRESS_CYCLE
+ //
+ Attributes &= ~EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+ }
+ Status = mIoMmuProtocol->AllocateBuffer (
+ mIoMmuProtocol,
+ Type,
+ MemoryType,
+ Pages,
+ HostAddress,
+ Attributes
+ );
+ return Status;
+ }
+
AllocateType = AllocateAnyPages;
if (!RootBridge->DmaAbove4G ||
(Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
@@ -1356,6 +1406,17 @@ RootBridgeIoFreeBuffer (
OUT VOID *HostAddress
)
{
+ EFI_STATUS Status;
+
+ if (mIoMmuProtocol != NULL) {
+ Status = mIoMmuProtocol->FreeBuffer (
+ mIoMmuProtocol,
+ Pages,
+ HostAddress
+ );
+ return Status;
+ }
+
return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
}
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/3] MdeModulePkg/PciBus: Add IOMMU support.
2017-04-29 13:48 [RFC] [PATCH V4 0/3] Add IOMMU support Jiewen Yao
2017-04-29 13:48 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
2017-04-29 13:48 ` [PATCH 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support Jiewen Yao
@ 2017-04-29 13:48 ` Jiewen Yao
2017-05-02 10:04 ` Ard Biesheuvel
2017-05-02 10:14 ` [RFC] [PATCH V4 0/3] " Ard Biesheuvel
2017-05-04 7:02 ` Ni, Ruiyu
4 siblings, 1 reply; 19+ messages in thread
From: Jiewen Yao @ 2017-04-29 13:48 UTC (permalink / raw)
To: edk2-devel; +Cc: Ruiyu Ni, Leo Duran, Brijesh Singh, Ard Biesheuvel
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +++++
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 ++++++++++++++++++++
4 files changed, 48 insertions(+)
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
index f3be47a..950cacc 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 39ba8b9..3bcc134 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 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
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index f72598d..c0251c0 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
//
@@ -967,6 +969,7 @@ PciIoMap (
{
EFI_STATUS Status;
PCI_IO_DEVICE *PciIoDevice;
+ UINT64 IoMmuAttribute;
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
@@ -999,6 +1002,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->SetMappingAttribute (
+ mIoMmuProtocol,
+ PciIoDevice->Handle,
+ *Mapping,
+ IoMmuAttribute
+ );
+ }
+ }
+
return Status;
}
@@ -1024,6 +1052,15 @@ PciIoUnmap (
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
+ if (mIoMmuProtocol != NULL) {
+ mIoMmuProtocol->SetMappingAttribute (
+ mIoMmuProtocol,
+ PciIoDevice->Handle,
+ Mapping,
+ 0
+ );
+ }
+
Status = PciIoDevice->PciRootBridgeIo->Unmap (
PciIoDevice->PciRootBridgeIo,
Mapping
--
2.7.4.windows.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-04-29 13:48 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
@ 2017-05-02 9:56 ` Ard Biesheuvel
2017-05-02 12:54 ` Yao, Jiewen
0 siblings, 1 reply; 19+ messages in thread
From: Ard Biesheuvel @ 2017-05-02 9:56 UTC (permalink / raw)
To: Jiewen Yao; +Cc: edk2-devel@lists.01.org, Ruiyu Ni, Leo Duran, Brijesh Singh
Hello Jiewen,
On 29 April 2017 at 14:48, Jiewen Yao <jiewen.yao@intel.com> 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 system.
>
> 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 <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>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> 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.<BR>
> +This program and the accompanying materials are licensed and made available under
> +the terms and conditions of the BSD License that accompanies this distribution.
> +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 IMPLIED.
> +
> +**/
> +
> +
> +#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 the 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 capable of producing
> + /// PCI dual address cycles.
> + ///
> + EdkiiIoMmuOperationBusMasterRead,
> + ///
> + /// A write operation from system memory by a bus master that is not capable of producing
> + /// PCI dual address cycles.
> + ///
> + EdkiiIoMmuOperationBusMasterWrite,
> + ///
> + /// Provides both read and write access to system memory by both the processor 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 capable 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 processor 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_ATTRIBUTE_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 device 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_READ|EDKII_IOMMU_ACCESS_WRITE.
> + After the memory is used, the memory need set 0 to keep it being protected.
> + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> + The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_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 be used as the DMA memory.
> + @param[in] IoMmuAccess The IOMMU access.
> +
> + @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
> + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
> + @retval EFI_INVALID_PARAMETER DeviceAddress is not IoMmu Page size aligned.
> + @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 combination of access.
> + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
> + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by DeviceAddress and Length.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
> + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while 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 memory 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 master 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 NumberOfBytes.
> + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
> + @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
> + @retval EFI_DEVICE_ERROR The system hardware could not map the requested 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 OperationBusMasterCommonBuffer or
> + OperationBusMasterCommonBuffer64 mapping.
> +
> + @param This The protocol instance pointer.
> + @param Type This parameter is not used and must be ignored.
> + @param MemoryType The type of memory to allocate, EfiBootServicesData or
> + EfiRuntimeServicesData.
> + @param Pages The number of pages to allocate.
> + @param HostAddress A pointer to store the base system memory 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 allocated.
> + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal 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 allocated range.
> +
> + @retval EFI_SUCCESS The requested memory pages were freed.
> + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress 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 device 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_READ|EDKII_IOMMU_ACCESS_WRITE.
> + After the memory is used, the memory need set 0 to keep it being protected.
> + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> + The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_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 range 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 returned by Map().
> + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
> + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
> + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
> + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while 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.dec
> index 356b3e1..db596b6 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -540,6 +540,9 @@
> ## Include/Protocol/NonDiscoverableDevice.h
> gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
>
> + ## Include/Protocol/IoMmu.h
> + gEdkiiIoMmuProtocolGuid = { 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 0x1e } }
> +
> #
> # [Error.gEfiMdeModulePkgTokenSpaceGuid]
> # 0x80000001 | Invalid value provided.
> --
> 2.7.4.windows.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/3] MdeModulePkg/PciBus: Add IOMMU support.
2017-04-29 13:48 ` [PATCH 3/3] MdeModulePkg/PciBus: " Jiewen Yao
@ 2017-05-02 10:04 ` Ard Biesheuvel
2017-05-02 12:43 ` Yao, Jiewen
0 siblings, 1 reply; 19+ messages in thread
From: Ard Biesheuvel @ 2017-05-02 10:04 UTC (permalink / raw)
To: Jiewen Yao; +Cc: edk2-devel@lists.01.org, Ruiyu Ni, Leo Duran, Brijesh Singh
On 29 April 2017 at 14:48, Jiewen Yao <jiewen.yao@intel.com> wrote:
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
> ---
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +++++
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 ++++++++++++++++++++
> 4 files changed, 48 insertions(+)
>
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> index f3be47a..950cacc 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 39ba8b9..3bcc134 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 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
>
> [FeaturePcd]
> gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
> index f72598d..c0251c0 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
> //
> @@ -967,6 +969,7 @@ PciIoMap (
> {
> EFI_STATUS Status;
> PCI_IO_DEVICE *PciIoDevice;
> + UINT64 IoMmuAttribute;
>
> PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
>
> @@ -999,6 +1002,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;
I am hitting this assert(). The reason is that Operation is modified
if the EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute is set, and
so it does not have any of these values anymore.
> + }
> + mIoMmuProtocol->SetMappingAttribute (
> + mIoMmuProtocol,
> + PciIoDevice->Handle,
> + *Mapping,
> + IoMmuAttribute
> + );
> + }
> + }
> +
> return Status;
> }
>
> @@ -1024,6 +1052,15 @@ PciIoUnmap (
>
> PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
>
> + if (mIoMmuProtocol != NULL) {
> + mIoMmuProtocol->SetMappingAttribute (
> + mIoMmuProtocol,
> + PciIoDevice->Handle,
> + Mapping,
> + 0
> + );
> + }
> +
> Status = PciIoDevice->PciRootBridgeIo->Unmap (
> PciIoDevice->PciRootBridgeIo,
> Mapping
> --
> 2.7.4.windows.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH V4 0/3] Add IOMMU support.
2017-04-29 13:48 [RFC] [PATCH V4 0/3] Add IOMMU support Jiewen Yao
` (2 preceding siblings ...)
2017-04-29 13:48 ` [PATCH 3/3] MdeModulePkg/PciBus: " Jiewen Yao
@ 2017-05-02 10:14 ` Ard Biesheuvel
2017-05-02 12:59 ` Yao, Jiewen
2017-05-04 7:02 ` Ni, Ruiyu
4 siblings, 1 reply; 19+ messages in thread
From: Ard Biesheuvel @ 2017-05-02 10:14 UTC (permalink / raw)
To: Jiewen Yao; +Cc: edk2-devel@lists.01.org, Ruiyu Ni, Leo Duran, Brijesh Singh
On 29 April 2017 at 14:48, Jiewen Yao <jiewen.yao@intel.com> wrote:
> ================ V4 ==============
> Refine the EDKII_IOMMU_PROTOCOL.
>
> 1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
> They are similar to DmaLib in EmbeddedPkg and
> similar to the previous BmDmaLib (by leo.duran@amd.com).
>
> These APIs are invoked by PciHostBridge driver
> to allocate DMA memory.
>
> The PciHostBridge driver (IOMMU consumer) is simplified:
> It uses IOMMU, if IOMMU protocol is present.
> Else it uses original logic.
>
> 2) Add SetMappingAttribute() API.
> It is similar to SetAttribute() API in V1.
>
> This API is invoked by PciBus driver to set DMA
> access attribute (read/write) for device.
>
> The PciBus driver (IOMMU consumer) is simplified:
> It sets access attribute in Map/Unmap,
> if IOMMU protocol is present.
>
> 3) Remove SetRemapAddress/GetRemapAddress() API.
> Because PciHostBridge/PciBus can call the APIs defined
> above, there is no need to provide remap capability.
>
> -- Sample producer drivers:
> 1) The sample VTd driver (IOMMU producer)
> is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe
>
> It is added to show the concept. It is not fully implemented yet.
> It will not be checked in in this patch.
>
> 2) The sample AMD SEV driver (IOMMU producer)
> is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDxe
> (code is borrowed from leo.duran@amd.com and brijesh.singh@amd.com)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
> 3) The sample STYX driver (IOMMU producer)
> is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
> (code is borrowed from ard.biesheuvel@linaro.org)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
With the issue in 3/3 addressed:
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
on AMD Seattle, with a static remapping driver that I will send out shortly.
I am quite happy with this version, but I would like to continue the
discussion as to whether we really need SetAttribute() and
SetMappingAttribute()
--
Ard.
>
> ================ V3 ==============
> 1) Add Remap capability (from Ard Biesheuvel)
> Add EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.
>
> NOTE: The code is not fully validated yet.
> The purpose is to collect feedback to decide the next step.
>
> ================ V2 ==============
> 1) Enhance Unmap() in PciIo (From Ruiyu Ni)
> Maintain a local list of MapInfo and match it in Unmap.
>
> 2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran)
> Fix a bug in V1 that copy mem for read happen before SetAttribute,
> which will break AMD SEV solution.
>
> ================ V1 ==============
>
> This patch series adds IOMMU protocol and updates the consumer
> to support IOMMU based DMA access in UEFI.
>
> This patch series can support the BmDmaLib request for AMD SEV.
> submitted by Duran, Leo <leo.duran@amd.com> and Brijesh Singh <brijesh.ksingh@gmail.com>.
> https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
> https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
> We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
> and clear SEV in IOMMU->SetAttribute().
>
> This patch series can also support Intel VTd based DMA protection,
> requested by Jiewen Yao <jiewen.yao@intel.com>, discussed in
> https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
> We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
> and update VTd engine to grant or deny access in IOMMU->SetAttribute().
>
> This patch series does not provide a full Intel VTd driver, which
> will be provide in other patch in the future.
>
> The purpose of this patch series to review if this IOMMU protocol design
> can meet all DMA access and management requirement.
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
>
> Jiewen Yao (3):
> MdeModulePkg/Include: Add IOMMU protocol definition.
> MdeModulePkg/PciHostBridge: Add IOMMU support.
> MdeModulePkg/PciBus: Add IOMMU support.
>
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 61 ++++
> MdeModulePkg/Include/Protocol/IoMmu.h | 310 ++++++++++++++++++++
> MdeModulePkg/MdeModulePkg.dec | 3 +
> 10 files changed, 463 insertions(+)
> create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h
>
> --
> 2.7.4.windows.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/3] MdeModulePkg/PciBus: Add IOMMU support.
2017-05-02 10:04 ` Ard Biesheuvel
@ 2017-05-02 12:43 ` Yao, Jiewen
0 siblings, 0 replies; 19+ messages in thread
From: Yao, Jiewen @ 2017-05-02 12:43 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: edk2-devel@lists.01.org, Ni, Ruiyu, Leo Duran, Brijesh Singh
Thank you.
My mistake. It seems my test platform does not have such capability.
It is fixed in V5.
Thank you
Yao Jiewen
From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
Sent: Tuesday, May 2, 2017 6:04 PM
To: Yao, Jiewen <jiewen.yao@intel.com>
Cc: edk2-devel@lists.01.org; Ni, Ruiyu <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>; Brijesh Singh <brijesh.singh@amd.com>
Subject: Re: [PATCH 3/3] MdeModulePkg/PciBus: Add IOMMU support.
On 29 April 2017 at 14:48, Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>> wrote:
> 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<mailto:ruiyu.ni@intel.com>>
> Cc: Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>
> Cc: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> ---
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +++++
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 ++++++++++++++++++++
> 4 files changed, 48 insertions(+)
>
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> index f3be47a..950cacc 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 39ba8b9..3bcc134 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 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
>
> [FeaturePcd]
> gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
> index f72598d..c0251c0 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
> //
> @@ -967,6 +969,7 @@ PciIoMap (
> {
> EFI_STATUS Status;
> PCI_IO_DEVICE *PciIoDevice;
> + UINT64 IoMmuAttribute;
>
> PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
>
> @@ -999,6 +1002,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;
I am hitting this assert(). The reason is that Operation is modified
if the EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute is set, and
so it does not have any of these values anymore.
> + }
> + mIoMmuProtocol->SetMappingAttribute (
> + mIoMmuProtocol,
> + PciIoDevice->Handle,
> + *Mapping,
> + IoMmuAttribute
> + );
> + }
> + }
> +
> return Status;
> }
>
> @@ -1024,6 +1052,15 @@ PciIoUnmap (
>
> PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
>
> + if (mIoMmuProtocol != NULL) {
> + mIoMmuProtocol->SetMappingAttribute (
> + mIoMmuProtocol,
> + PciIoDevice->Handle,
> + Mapping,
> + 0
> + );
> + }
> +
> Status = PciIoDevice->PciRootBridgeIo->Unmap (
> PciIoDevice->PciRootBridgeIo,
> Mapping
> --
> 2.7.4.windows.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
2017-05-02 9:56 ` Ard Biesheuvel
@ 2017-05-02 12:54 ` Yao, Jiewen
0 siblings, 0 replies; 19+ messages in thread
From: Yao, Jiewen @ 2017-05-02 12:54 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: Ni, Ruiyu, edk2-devel@lists.01.org, Leo Duran
Thanks, Ard.
It is a good open that if we really need both SetAttribute and SetMappingAttribute.
Looking at code again, I prefer to remove SetAttribute().
I do not suggest we define MapInfo, because I want to make it DMA engine implementation choice.
All we want is just to set an access attribute for this mapping, there is no need to input base/length.
Because Map() should always be called by a device driver, no matter it is PCI DMA, ISA DMA, or low power controller DMA, I think SetMappingAttribute is 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 <jiewen.yao@intel.com>
Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; edk2-devel@lists.01.org; Leo Duran <leo.duran@amd.com>
Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.
Hello Jiewen,
On 29 April 2017 at 14:48, Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>> 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 system.
>
> 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 <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> Cc: Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>
> Cc: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> ---
> 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.<BR>
> +This program and the accompanying materials are licensed and made available under
> +the terms and conditions of the BSD License that accompanies this distribution.
> +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 IMPLIED.
> +
> +**/
> +
> +
> +#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 the 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 capable of producing
> + /// PCI dual address cycles.
> + ///
> + EdkiiIoMmuOperationBusMasterRead,
> + ///
> + /// A write operation from system memory by a bus master that is not capable of producing
> + /// PCI dual address cycles.
> + ///
> + EdkiiIoMmuOperationBusMasterWrite,
> + ///
> + /// Provides both read and write access to system memory by both the processor 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 capable 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 processor 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_ATTRIBUTE_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 device 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_READ|EDKII_IOMMU_ACCESS_WRITE.
> + After the memory is used, the memory need set 0 to keep it being protected.
> + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> + The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_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 be used as the DMA memory.
> + @param[in] IoMmuAccess The IOMMU access.
> +
> + @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
> + @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
> + @retval EFI_INVALID_PARAMETER DeviceAddress is not IoMmu Page size aligned.
> + @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 combination of access.
> + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
> + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by DeviceAddress and Length.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
> + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while 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 memory 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 master 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 NumberOfBytes.
> + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
> + @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
> + @retval EFI_DEVICE_ERROR The system hardware could not map the requested 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 OperationBusMasterCommonBuffer or
> + OperationBusMasterCommonBuffer64 mapping.
> +
> + @param This The protocol instance pointer.
> + @param Type This parameter is not used and must be ignored.
> + @param MemoryType The type of memory to allocate, EfiBootServicesData or
> + EfiRuntimeServicesData.
> + @param Pages The number of pages to allocate.
> + @param HostAddress A pointer to store the base system memory 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 allocated.
> + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal 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 allocated range.
> +
> + @retval EFI_SUCCESS The requested memory pages were freed.
> + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress 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 device 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_READ|EDKII_IOMMU_ACCESS_WRITE.
> + After the memory is used, the memory need set 0 to keep it being protected.
> + 2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
> + The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_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 range 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 returned by Map().
> + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
> + @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
> + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
> + @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
> + @retval EFI_DEVICE_ERROR The IOMMU device reported an error while 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.dec
> index 356b3e1..db596b6 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -540,6 +540,9 @@
> ## Include/Protocol/NonDiscoverableDevice.h
> gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } }
>
> + ## Include/Protocol/IoMmu.h
> + gEdkiiIoMmuProtocolGuid = { 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<mailto:edk2-devel@lists.01.org>
https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH V4 0/3] Add IOMMU support.
2017-05-02 10:14 ` [RFC] [PATCH V4 0/3] " Ard Biesheuvel
@ 2017-05-02 12:59 ` Yao, Jiewen
0 siblings, 0 replies; 19+ messages in thread
From: Yao, Jiewen @ 2017-05-02 12:59 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: Ni, Ruiyu, edk2-devel@lists.01.org, Leo Duran
That is awesome!
I am glad to see a real example - GenericSmmuStaticPciDmaDxe
Let's continue the discussion on if we can make it simpler.
Thank you
Yao Jiewen
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ard Biesheuvel
Sent: Tuesday, May 2, 2017 6:15 PM
To: Yao, Jiewen <jiewen.yao@intel.com>
Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; edk2-devel@lists.01.org; Leo Duran <leo.duran@amd.com>
Subject: Re: [edk2] [RFC] [PATCH V4 0/3] Add IOMMU support.
On 29 April 2017 at 14:48, Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>> wrote:
> ================ V4 ==============
> Refine the EDKII_IOMMU_PROTOCOL.
>
> 1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
> They are similar to DmaLib in EmbeddedPkg and
> similar to the previous BmDmaLib (by leo.duran@amd.com<mailto:leo.duran@amd.com>).
>
> These APIs are invoked by PciHostBridge driver
> to allocate DMA memory.
>
> The PciHostBridge driver (IOMMU consumer) is simplified:
> It uses IOMMU, if IOMMU protocol is present.
> Else it uses original logic.
>
> 2) Add SetMappingAttribute() API.
> It is similar to SetAttribute() API in V1.
>
> This API is invoked by PciBus driver to set DMA
> access attribute (read/write) for device.
>
> The PciBus driver (IOMMU consumer) is simplified:
> It sets access attribute in Map/Unmap,
> if IOMMU protocol is present.
>
> 3) Remove SetRemapAddress/GetRemapAddress() API.
> Because PciHostBridge/PciBus can call the APIs defined
> above, there is no need to provide remap capability.
>
> -- Sample producer drivers:
> 1) The sample VTd driver (IOMMU producer)
> is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe
>
> It is added to show the concept. It is not fully implemented yet.
> It will not be checked in in this patch.
>
> 2) The sample AMD SEV driver (IOMMU producer)
> is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDxe
> (code is borrowed from leo.duran@amd.com<mailto:leo.duran@amd.com> and brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
> 3) The sample STYX driver (IOMMU producer)
> is at https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
> (code is borrowed from ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
With the issue in 3/3 addressed:
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
on AMD Seattle, with a static remapping driver that I will send out shortly.
I am quite happy with this version, but I would like to continue the
discussion as to whether we really need SetAttribute() and
SetMappingAttribute()
--
Ard.
>
> ================ V3 ==============
> 1) Add Remap capability (from Ard Biesheuvel)
> Add EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.
>
> NOTE: The code is not fully validated yet.
> The purpose is to collect feedback to decide the next step.
>
> ================ V2 ==============
> 1) Enhance Unmap() in PciIo (From Ruiyu Ni)
> Maintain a local list of MapInfo and match it in Unmap.
>
> 2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran)
> Fix a bug in V1 that copy mem for read happen before SetAttribute,
> which will break AMD SEV solution.
>
> ================ V1 ==============
>
> This patch series adds IOMMU protocol and updates the consumer
> to support IOMMU based DMA access in UEFI.
>
> This patch series can support the BmDmaLib request for AMD SEV.
> submitted by Duran, Leo <leo.duran@amd.com<mailto:leo.duran@amd.com>> and Brijesh Singh <brijesh.ksingh@gmail.com<mailto:brijesh.ksingh@gmail.com>>.
> https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
> https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
> We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
> and clear SEV in IOMMU->SetAttribute().
>
> This patch series can also support Intel VTd based DMA protection,
> requested by Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>, discussed in
> https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
> We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
> and update VTd engine to grant or deny access in IOMMU->SetAttribute().
>
> This patch series does not provide a full Intel VTd driver, which
> will be provide in other patch in the future.
>
> The purpose of this patch series to review if this IOMMU protocol design
> can meet all DMA access and management requirement.
>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> Cc: Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>
> Cc: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
>
> Jiewen Yao (3):
> MdeModulePkg/Include: Add IOMMU protocol definition.
> MdeModulePkg/PciHostBridge: Add IOMMU support.
> MdeModulePkg/PciBus: Add IOMMU support.
>
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 61 ++++
> MdeModulePkg/Include/Protocol/IoMmu.h | 310 ++++++++++++++++++++
> MdeModulePkg/MdeModulePkg.dec | 3 +
> 10 files changed, 463 insertions(+)
> create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h
>
> --
> 2.7.4.windows.1
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH V4 0/3] Add IOMMU support.
2017-04-29 13:48 [RFC] [PATCH V4 0/3] Add IOMMU support Jiewen Yao
` (3 preceding siblings ...)
2017-05-02 10:14 ` [RFC] [PATCH V4 0/3] " Ard Biesheuvel
@ 2017-05-04 7:02 ` Ni, Ruiyu
2017-05-04 13:26 ` Yao, Jiewen
4 siblings, 1 reply; 19+ messages in thread
From: Ni, Ruiyu @ 2017-05-04 7:02 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org
Cc: Leo Duran, Brijesh Singh, Ard Biesheuvel
Jiewen,
All 3 patches are good to me.
When you post V5 to retire one of the SetxxxAttribute() interfaces from IO_MMU protocol,
I suggest we keep the Mapping version, but rename the function name to SetAttribute().
As the 2 changes in below:
typedef
EFI_STATUS
(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)( // <-- 1. Remove the _MAPPING
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;
// <-- 2. Remove the SetMappingAttribute interface.
};
Thanks/Ray
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Saturday, April 29, 2017 9:48 PM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>; Brijesh
> Singh <brijesh.singh@amd.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [RFC] [PATCH V4 0/3] Add IOMMU support.
>
> ================ V4 ==============
> Refine the EDKII_IOMMU_PROTOCOL.
>
> 1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
> They are similar to DmaLib in EmbeddedPkg and similar to the previous
> BmDmaLib (by leo.duran@amd.com).
>
> These APIs are invoked by PciHostBridge driver to allocate DMA memory.
>
> The PciHostBridge driver (IOMMU consumer) is simplified:
> It uses IOMMU, if IOMMU protocol is present.
> Else it uses original logic.
>
> 2) Add SetMappingAttribute() API.
> It is similar to SetAttribute() API in V1.
>
> This API is invoked by PciBus driver to set DMA access attribute (read/write) for
> device.
>
> The PciBus driver (IOMMU consumer) is simplified:
> It sets access attribute in Map/Unmap,
> if IOMMU protocol is present.
>
> 3) Remove SetRemapAddress/GetRemapAddress() API.
> Because PciHostBridge/PciBus can call the APIs defined above, there is no need
> to provide remap capability.
>
> -- Sample producer drivers:
> 1) The sample VTd driver (IOMMU producer) is at
> https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe
>
> It is added to show the concept. It is not fully implemented yet.
> It will not be checked in in this patch.
>
> 2) The sample AMD SEV driver (IOMMU producer) is at
> https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDx
> e
> (code is borrowed from leo.duran@amd.com and brijesh.singh@amd.com)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
> 3) The sample STYX driver (IOMMU producer) is at
> https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
> (code is borrowed from ard.biesheuvel@linaro.org)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
>
> ================ V3 ==============
> 1) Add Remap capability (from Ard Biesheuvel) Add
> EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.
>
> NOTE: The code is not fully validated yet.
> The purpose is to collect feedback to decide the next step.
>
> ================ V2 ==============
> 1) Enhance Unmap() in PciIo (From Ruiyu Ni) Maintain a local list of MapInfo and
> match it in Unmap.
>
> 2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran) Fix a bug
> in V1 that copy mem for read happen before SetAttribute, which will break AMD
> SEV solution.
>
> ================ V1 ==============
>
> This patch series adds IOMMU protocol and updates the consumer to support
> IOMMU based DMA access in UEFI.
>
> This patch series can support the BmDmaLib request for AMD SEV.
> submitted by Duran, Leo <leo.duran@amd.com> and Brijesh Singh
> <brijesh.ksingh@gmail.com>.
> https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
> https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
> We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
> and clear SEV in IOMMU->SetAttribute().
>
> This patch series can also support Intel VTd based DMA protection, requested by
> Jiewen Yao <jiewen.yao@intel.com>, discussed in
> https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
> We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
> and update VTd engine to grant or deny access in IOMMU->SetAttribute().
>
> This patch series does not provide a full Intel VTd driver, which will be provide in
> other patch in the future.
>
> The purpose of this patch series to review if this IOMMU protocol design can
> meet all DMA access and management requirement.
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
>
> Jiewen Yao (3):
> MdeModulePkg/Include: Add IOMMU protocol definition.
> MdeModulePkg/PciHostBridge: Add IOMMU support.
> MdeModulePkg/PciBus: Add IOMMU support.
>
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 61 ++++
> MdeModulePkg/Include/Protocol/IoMmu.h | 310
> ++++++++++++++++++++
> MdeModulePkg/MdeModulePkg.dec | 3 +
> 10 files changed, 463 insertions(+)
> create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h
>
> --
> 2.7.4.windows.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH V4 0/3] Add IOMMU support.
2017-05-04 7:02 ` Ni, Ruiyu
@ 2017-05-04 13:26 ` Yao, Jiewen
0 siblings, 0 replies; 19+ messages in thread
From: Yao, Jiewen @ 2017-05-04 13:26 UTC (permalink / raw)
To: Ni, Ruiyu, edk2-devel@lists.01.org
Cc: Leo Duran, Brijesh Singh, Ard Biesheuvel
Thanks. I agree.
From: Ni, Ruiyu
Sent: Thursday, May 4, 2017 3:02 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
Cc: Leo Duran <leo.duran@amd.com>; Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: RE: [RFC] [PATCH V4 0/3] Add IOMMU support.
Jiewen,
All 3 patches are good to me.
When you post V5 to retire one of the SetxxxAttribute() interfaces from IO_MMU protocol,
I suggest we keep the Mapping version, but rename the function name to SetAttribute().
As the 2 changes in below:
typedef
EFI_STATUS
(EFIAPI *EDKII_IOMMU_SET_ATTRIBUTE)( // <-- 1. Remove the _MAPPING
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;
// <-- 2. Remove the SetMappingAttribute interface.
};
Thanks/Ray
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Saturday, April 29, 2017 9:48 PM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>; Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>; Brijesh
> Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>; Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
> Subject: [RFC] [PATCH V4 0/3] Add IOMMU support.
>
> ================ V4 ==============
> Refine the EDKII_IOMMU_PROTOCOL.
>
> 1) Add AllocateBuffer/FreeBuffer/Map/Unmap() API.
> They are similar to DmaLib in EmbeddedPkg and similar to the previous
> BmDmaLib (by leo.duran@amd.com<mailto:leo.duran@amd.com>).
>
> These APIs are invoked by PciHostBridge driver to allocate DMA memory.
>
> The PciHostBridge driver (IOMMU consumer) is simplified:
> It uses IOMMU, if IOMMU protocol is present.
> Else it uses original logic.
>
> 2) Add SetMappingAttribute() API.
> It is similar to SetAttribute() API in V1.
>
> This API is invoked by PciBus driver to set DMA access attribute (read/write) for
> device.
>
> The PciBus driver (IOMMU consumer) is simplified:
> It sets access attribute in Map/Unmap,
> if IOMMU protocol is present.
>
> 3) Remove SetRemapAddress/GetRemapAddress() API.
> Because PciHostBridge/PciBus can call the APIs defined above, there is no need
> to provide remap capability.
>
> -- Sample producer drivers:
> 1) The sample VTd driver (IOMMU producer) is at
> https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/IntelVTdDxe
>
> It is added to show the concept. It is not fully implemented yet.
> It will not be checked in in this patch.
>
> 2) The sample AMD SEV driver (IOMMU producer) is at
> https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleAmdSevDx
> e
> (code is borrowed from leo.duran@amd.com<mailto:leo.duran@amd.com> and brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
> 3) The sample STYX driver (IOMMU producer) is at
> https://github.com/jyao1/edk2/tree/dma_v4/IntelSiliconPkg/SampleStyxDxe
> (code is borrowed from ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>)
>
> This is not a right place to put this driver.
>
> It is added to show the concept.
> It is not fully implemented. It will not be checked in.
> Please do not use it directly.
>
>
> ================ V3 ==============
> 1) Add Remap capability (from Ard Biesheuvel) Add
> EDKII_IOMMU_REMAP_ADDRESS API in IOMMU_PROTOCOL.
>
> NOTE: The code is not fully validated yet.
> The purpose is to collect feedback to decide the next step.
>
> ================ V2 ==============
> 1) Enhance Unmap() in PciIo (From Ruiyu Ni) Maintain a local list of MapInfo and
> match it in Unmap.
>
> 2) CopyMem for ReadOperation in PciIo after SetAttribute (Leo Duran) Fix a bug
> in V1 that copy mem for read happen before SetAttribute, which will break AMD
> SEV solution.
>
> ================ V1 ==============
>
> This patch series adds IOMMU protocol and updates the consumer to support
> IOMMU based DMA access in UEFI.
>
> This patch series can support the BmDmaLib request for AMD SEV.
> submitted by Duran, Leo <leo.duran@amd.com<mailto:leo.duran@amd.com>> and Brijesh Singh
> <brijesh.ksingh@gmail.com<mailto:brijesh.ksingh@gmail.com>>.
> https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html, and
> https://lists.01.org/pipermail/edk2-devel/2017-March/008820.html.
> We can have an AMD SEV specific IOMMU driver to produce IOMMU protocol,
> and clear SEV in IOMMU->SetAttribute().
>
> This patch series can also support Intel VTd based DMA protection, requested by
> Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>, discussed in
> https://lists.01.org/pipermail/edk2-devel/2017-March/008157.html.
> We can have an Intel VTd specific IOMMU driver to produce IOMMU protocol,
> and update VTd engine to grant or deny access in IOMMU->SetAttribute().
>
> This patch series does not provide a full Intel VTd driver, which will be provide in
> other patch in the future.
>
> The purpose of this patch series to review if this IOMMU protocol design can
> meet all DMA access and management requirement.
>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> Cc: Leo Duran <leo.duran@amd.com<mailto:leo.duran@amd.com>>
> Cc: Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
>
> Jiewen Yao (3):
> MdeModulePkg/Include: Add IOMMU protocol definition.
> MdeModulePkg/PciHostBridge: Add IOMMU support.
> MdeModulePkg/PciBus: Add IOMMU support.
>
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 9 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 +
> MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 37 +++
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 2 +
> MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 61 ++++
> MdeModulePkg/Include/Protocol/IoMmu.h | 310
> ++++++++++++++++++++
> MdeModulePkg/MdeModulePkg.dec | 3 +
> 10 files changed, 463 insertions(+)
> create mode 100644 MdeModulePkg/Include/Protocol/IoMmu.h
>
> --
> 2.7.4.windows.1
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2017-05-04 13:26 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-29 13:48 [RFC] [PATCH V4 0/3] Add IOMMU support Jiewen Yao
2017-04-29 13:48 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
2017-05-02 9:56 ` Ard Biesheuvel
2017-05-02 12:54 ` Yao, Jiewen
2017-04-29 13:48 ` [PATCH 2/3] MdeModulePkg/PciHostBridge: Add IOMMU support Jiewen Yao
2017-04-29 13:48 ` [PATCH 3/3] MdeModulePkg/PciBus: " Jiewen Yao
2017-05-02 10:04 ` Ard Biesheuvel
2017-05-02 12:43 ` Yao, Jiewen
2017-05-02 10:14 ` [RFC] [PATCH V4 0/3] " Ard Biesheuvel
2017-05-02 12:59 ` Yao, Jiewen
2017-05-04 7:02 ` Ni, Ruiyu
2017-05-04 13:26 ` Yao, Jiewen
-- strict thread matches above, loose matches on Subject: below --
2017-03-25 9:28 [RFC] [PATCH " Jiewen Yao
2017-03-25 9:28 ` [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition Jiewen Yao
2017-03-28 22:38 ` Ard Biesheuvel
2017-03-28 23:02 ` Kinney, Michael D
2017-03-28 23:45 ` Yao, Jiewen
2017-03-29 14:22 ` Ard Biesheuvel
2017-03-30 12:37 ` Yao, Jiewen
2017-03-30 13:54 ` Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox