// vi:set ft=cpp: -*- Mode: C++ -*-
/* \file
 * IO-MMU interface description.
 */
#pragma once

#include <l4/sys/cxx/ipc_iface>

namespace L4 {
/**
 * Interface for IO-MMUs used for DMA remapping.
 *
 * \note This interface is only present in the kernel if the kernel
 * detected an IOMMU during boot.
 *
 * This interface allows to associate a DMA address space
 * with a platform dependent set of devices. The kernel automatically
 * keeps the memory spaces of associated DMA spaces in sync with the
 * respective page table structures in the IOMMU.
 */
class Iommu :
  public Kobject_x<Iommu, Proto_t<L4_PROTO_IOMMU>, Type_info::Demand_t<1> >
{
public:
  /**
   * Associate `dma_space` with the set of device(s) specified by `src_id`.
   * Updates the respective page table structures in the IOMMU and
   * keeps them in sync when memory is mapped to the `dma_space` or
   * revoked from it.
   *
   * \param src_id     Platform dependent source ID specifying the set of
   *                   devices that shall use `dma_space` for DMA remapping.
   * \param dma_space  The DMA space (L4::Task created with
   *                   L4_PROTO_DMA_SPACE) providing the mappings that
   *                   shall be used for the device(s).
   */
  L4_INLINE_RPC(
      l4_msgtag_t, bind, (l4_uint64_t src_id, Ipc::Cap<Task> dma_space));

  /**
   * Remove the association of the given DMA address space from the
   * device(s) specified by `src_id`. Clear the respective page stable
   * structures in the IOMMU.
   *
   * \param src_id     Platform dependent source ID specifying the set of
   *                   devices that shall no longer use `dma_space` for
   *                   DMA remapping.
   * \param dma_space  The DMA space formerly associated with bind().
   */
  L4_INLINE_RPC(
      l4_msgtag_t, unbind, (l4_uint64_t src_id, Ipc::Cap<Task> dma_space));

  typedef Typeid::Rpcs_code<l4_umword_t>::F<bind_t, unbind_t> Rpcs;
};

}
