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 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

Reply via email to