Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-05-02 Thread Yao, Jiewen
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-boun...@lists.01.org] On Behalf Of Ard 
Biesheuvel
Sent: Tuesday, May 2, 2017 5:56 PM
To: Yao, Jiewen <jiewen@intel.com>
Cc: Ni, Ruiyu <ruiyu...@intel.com>; edk2-devel@lists.01.org; Leo Duran 
<leo.du...@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@intel.com<mailto:jiewen@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...@intel.com<mailto:ruiyu...@intel.com>>
> Cc: Leo Duran <leo.du...@amd.com<mailto:leo.du...@amd.com>>
> Cc: Brijesh Singh <brijesh.si...@amd.com<mailto:brijesh.si...@amd.com>>
> Cc: Ard Biesheuvel 
> <ard.biesheu...@linaro.org<mailto:ard.biesheu...@linaro.org>>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao <jiewen@intel.com<mailto:jiewen@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 000..3f62f46
> --- /dev/null
> +++ b/MdeModulePkg/Include/Protocol/IoMmu.h
> @@ -0,0 +1,310 @@
> +/** @file
> +  EFI IOMMU Protocol.
> +
> +Copyright (c) 2017, Intel Corporation. All rights reserved.
> +This program and the accompanying materials are licensed and made 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 0x0001
> +
> +//
> +// 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 {
> +  ///
> +  /// 

Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-05-02 Thread Ard Biesheuvel
Hello Jiewen,

On 29 April 2017 at 14:48, Jiewen Yao  wrote:
> This protocol is to abstract DMA access from IOMMU.
> 1) Intel "DMAR" ACPI table.
> 2) AMD "IVRS" ACPI table
> 3) ARM "IORT" ACPI table.
>
> There might be multiple IOMMU engines on one platform.
> For example, one for graphic and one for rest PCI devices
> (such as ATA/USB).
> All IOMMU engines are reported by one ACPI table.
>
> All IOMMU protocol provider should be based upon ACPI table.
> This single IOMMU protocol can handle multiple IOMMU engines on one 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 
> Cc: Leo Duran 
> Cc: Brijesh Singh 
> Cc: Ard Biesheuvel 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao 
> ---
>  MdeModulePkg/Include/Protocol/IoMmu.h | 310 
>  MdeModulePkg/MdeModulePkg.dec |   3 +
>  2 files changed, 313 insertions(+)
>
> diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h 
> b/MdeModulePkg/Include/Protocol/IoMmu.h
> new file mode 100644
> index 000..3f62f46
> --- /dev/null
> +++ b/MdeModulePkg/Include/Protocol/IoMmu.h
> @@ -0,0 +1,310 @@
> +/** @file
> +  EFI IOMMU Protocol.
> +
> +Copyright (c) 2017, Intel Corporation. All rights reserved.
> +This program and the accompanying materials are licensed and made 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 0x0001
> +
> +//
> +// 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_COMBINE0x0080
> +#define EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED   0x0800
> +#define EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE  0x8000
> 

[edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-04-29 Thread Jiewen Yao
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 
Cc: Leo Duran 
Cc: Brijesh Singh 
Cc: Ard Biesheuvel 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 MdeModulePkg/Include/Protocol/IoMmu.h | 310 
 MdeModulePkg/MdeModulePkg.dec |   3 +
 2 files changed, 313 insertions(+)

diff --git a/MdeModulePkg/Include/Protocol/IoMmu.h 
b/MdeModulePkg/Include/Protocol/IoMmu.h
new file mode 100644
index 000..3f62f46
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/IoMmu.h
@@ -0,0 +1,310 @@
+/** @file
+  EFI IOMMU Protocol.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made 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 0x0001
+
+//
+// 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_COMBINE0x0080
+#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 

Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-30 Thread Ard Biesheuvel
On 30 March 2017 at 13:37, Yao, Jiewen <jiewen@intel.com> wrote:
> Thanks for the info.
>
>
>
> Comment inline.
>
>
>
>
>
>
>
>
>
> From: Ard Biesheuvel [mailto:ard.biesheu...@linaro.org]
> Sent: Wednesday, March 29, 2017 10:23 PM
> To: Yao, Jiewen <jiewen@intel.com>
> Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Ni, Ruiyu
> <ruiyu...@intel.com>; Leo Duran <leo.du...@amd.com>;
> edk2-devel@lists.01.org; Brijesh Singh <brijesh.si...@amd.com>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol
> definition.
>
>
>
> On 29 March 2017 at 00:45, Yao, Jiewen <jiewen@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.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-30 Thread Yao, Jiewen
Thanks for the info.

Comment inline.




From: Ard Biesheuvel [mailto:ard.biesheu...@linaro.org]
Sent: Wednesday, March 29, 2017 10:23 PM
To: Yao, Jiewen <jiewen@intel.com>
Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Ni, Ruiyu 
<ruiyu...@intel.com>; Leo Duran <leo.du...@amd.com>; edk2-devel@lists.01.org; 
Brijesh Singh <brijesh.si...@amd.com>
Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol 
definition.

On 29 March 2017 at 00:45, Yao, Jiewen 
<jiewen@intel.com<mailto:jiewen@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.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-29 Thread Ard Biesheuvel
On 29 March 2017 at 00:45, Yao, Jiewen  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.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-28 Thread Yao, Jiewen
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.biesheu...@linaro.org>; Yao, Jiewen 
<jiewen@intel.com>; Kinney, Michael D <michael.d.kin...@intel.com>
Cc: Ni, Ruiyu <ruiyu...@intel.com>; Leo Duran <leo.du...@amd.com>; 
edk2-devel@lists.01.org; Brijesh Singh <brijesh.si...@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-boun...@lists.01.org] On Behalf Of Ard
> Biesheuvel
> Sent: Tuesday, March 28, 2017 3:39 PM
> To: Yao, Jiewen <jiewen@intel.com<mailto:jiewen@intel.com>>
> Cc: Ni, Ruiyu <ruiyu...@intel.com<mailto:ruiyu...@intel.com>>; Leo Duran 
> <leo.du...@amd.com<mailto:leo.du...@amd.com>>; edk2-
> de...@lists.01.org<mailto:de...@lists.01.org>; Brijesh Singh 
> <brijesh.si...@amd.com<mailto:brijesh.si...@amd.com>>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol
> definition.
>
> On 25 March 2017 at 09:28, Jiewen Yao 
> <jiewen@intel.com<mailto:jiewen@intel.com>> wrote:
> > This protocol is to abstract IOMMU access.
> >
> > Cc: Ruiyu Ni <ruiyu...@intel.com<mailto:ruiyu...@intel.com>>
> > Cc: Leo Duran <leo.du...@amd.com<mailto:leo.du...@amd.com>>
> > Cc: Brijesh Singh <brijesh.si...@amd.com<mailto:brijesh.si...@amd.com>>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Jiewen Yao 
> > <jiewen@intel.com<mailto:jiewen@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 000..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.
> > +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 0x0001
> > +
> > +//
> > +// IOMMU attribute.
> > +// These types can be "ORed" together as needed.
> > +// Any undefined bits are reserved and must be zero.
> > +//
> > +#define EDKII_IOMMU_ATTRIB

Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-28 Thread Kinney, Michael D
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-boun...@lists.01.org] On Behalf Of Ard
> Biesheuvel
> Sent: Tuesday, March 28, 2017 3:39 PM
> To: Yao, Jiewen <jiewen@intel.com>
> Cc: Ni, Ruiyu <ruiyu...@intel.com>; Leo Duran <leo.du...@amd.com>; edk2-
> de...@lists.01.org; Brijesh Singh <brijesh.si...@amd.com>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol
> definition.
> 
> On 25 March 2017 at 09:28, Jiewen Yao <jiewen@intel.com> wrote:
> > This protocol is to abstract IOMMU access.
> >
> > Cc: Ruiyu Ni <ruiyu...@intel.com>
> > Cc: Leo Duran <leo.du...@amd.com>
> > Cc: Brijesh Singh <brijesh.si...@amd.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Jiewen Yao <jiewen@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 000..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.
> > +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 0x0001
> > +
> > +//
> > +// 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.
> > +   

Re: [edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-28 Thread Ard Biesheuvel
On 25 March 2017 at 09:28, Jiewen Yao  wrote:
> This protocol is to abstract IOMMU access.
>
> Cc: Ruiyu Ni 
> Cc: Leo Duran 
> Cc: Brijesh Singh 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Jiewen Yao 

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 000..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.
> +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 0x0001
> +
> +//
> +// 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  LengthThe length of system memory address to be used 
> as the DMA memory.
> +  @param  IoMmuAttributeThe IOMMU attribute.
> +
> +  @retval EFI_SUCCESSThe 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_UNSUPPORTEDDeviceHandle is unknown by the IOMMU.
> +  @retval EFI_UNSUPPORTEDThe bit mask of IoMmuAttribute is not 
> supported by the IOMMU.
> +  @retval EFI_UNSUPPORTED

[edk2] [PATCH 1/3] MdeModulePkg/Include: Add IOMMU protocol definition.

2017-03-25 Thread Jiewen Yao
This protocol is to abstract IOMMU access.

Cc: Ruiyu Ni 
Cc: Leo Duran 
Cc: Brijesh Singh 
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao 
---
 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 000..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.
+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 0x0001
+
+//
+// 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  LengthThe length of system memory address to be used as 
the DMA memory.
+  @param  IoMmuAttributeThe IOMMU attribute.
+
+  @retval EFI_SUCCESSThe 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_UNSUPPORTEDDeviceHandle is unknown by the IOMMU.
+  @retval EFI_UNSUPPORTEDThe bit mask of IoMmuAttribute is not 
supported by the IOMMU.
+  @retval EFI_UNSUPPORTEDThe 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_HANDLEDeviceHandle,
+  IN UINT64BaseAddress,
+  IN UINT64Length,
+  IN UINT64IoMmuAttribute
+  );
+
+/**
+  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