// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library zx;

@transport("Syscall")
closed protocol Bti {
    // TODO(https://fxbug.dev/42107929): This is an unusual rights spec.
    /// ## Summary
    ///
    /// Create a new bus transaction initiator.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_bti_create(zx_handle_t iommu,
    ///                           uint32_t options,
    ///                           uint64_t bti_id,
    ///                           zx_handle_t* out);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_bti_create()` creates a new [bus transaction initiator](/docs/reference/kernel_objects/bus_transaction_initiator.md)
    /// given a handle to an IOMMU and a hardware transaction identifier for a device
    /// downstream of that IOMMU.
    ///
    /// *options* must be 0 (reserved for future definition of creation flags).
    ///
    /// Upon success a handle for the new BTI is returned.  This handle will have rights
    /// `ZX_RIGHT_READ`, `ZX_RIGHT_WRITE`, `ZX_RIGHT_MAP`, `ZX_RIGHT_INSPECT`,
    /// `ZX_RIGHT_DUPLICATE`, and `ZX_RIGHT_TRANSFER`.
    ///
    /// ## Rights
    ///
    /// *iommu* must be of type `ZX_OBJ_TYPE_IOMMU` and have `ZX_RIGHT_NONE`.
    ///
    /// ## Return value
    ///
    /// `zx_bti_create()` returns `ZX_OK` and a handle to the new BTI
    /// (via *out*) on success.  In the event of failure, a negative error value
    /// is returned.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_BAD_HANDLE`  *iommu* is not a valid handle.
    ///
    /// `ZX_ERR_WRONG_TYPE`  *iommu* is not an iommu handle.
    ///
    /// `ZX_ERR_ACCESS_DENIED`  *iommu* handle does not have sufficient privileges.
    ///
    /// `ZX_ERR_INVALID_ARGS`  *bti_id* is invalid on the given IOMMU,
    /// *out* is an invalid pointer, or *options* is non-zero.
    ///
    /// `ZX_ERR_NO_MEMORY`  Failure due to lack of memory.
    /// There is no good way for userspace to handle this (unlikely) error.
    /// In a future build this error will no longer occur.
    ///
    /// ## See also
    ///
    ///  - [`zx_bti_pin()`]
    ///  - [`zx_bti_release_quarantine()`]
    ///  - [`zx_pmt_unpin()`]
    ///
    /// [`zx_bti_pin()`]: bti_pin.md
    /// [`zx_bti_release_quarantine()`]: bti_release_quarantine.md
    /// [`zx_pmt_unpin()`]: pmt_unpin.md
    strict Create(resource struct {
        iommu Handle:IOMMU;
        options uint32;
        bti_id uint64;
    }) -> (resource struct {
        out Handle:BTI;
    }) error Status;

    // READ is intentional in the EXECUTE condition.
    /// ## Summary
    ///
    /// Pin pages and grant devices access to them.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_bti_pin(zx_handle_t handle,
    ///                        uint32_t options,
    ///                        zx_handle_t vmo,
    ///                        uint64_t offset,
    ///                        uint64_t size,
    ///                        zx_paddr_t* addrs,
    ///                        size_t num_addrs,
    ///                        zx_handle_t* pmt);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_bti_pin()` pins pages of a VMO (i.e. prevents them from being decommitted
    /// with [`zx_vmo_op_range()`]) and grants the hardware
    /// transaction ID represented by the BTI the ability to access these pages,
    /// with the permissions specified in *options*.
    ///
    /// *offset* must be aligned to page boundaries.
    ///
    /// *options* is a bitfield that may contain one or more of `ZX_BTI_PERM_READ`,
    /// `ZX_BTI_PERM_WRITE`, `ZX_BTI_PERM_EXECUTE`, `ZX_BTI_COMPRESS`, and
    /// `ZX_BTI_CONTIGUOUS`.  In order for the call to succeed, *vmo* must have the
    /// READ/WRITE rights corresponding to the permissions flags set in *options*.
    /// (Note: `ZX_BTI_PERM_EXECUTE` requires `ZX_RIGHT_READ`, not `ZX_RIGHT_EXECUTE`.)
    /// `ZX_BTI_CONTIGUOUS` is only allowed if *vmo* was allocated via
    /// [`zx_vmo_create_contiguous()`] or [`zx_vmo_create_physical()`].
    /// `ZX_BTI_COMPRESS` and `ZX_BTI_CONTIGUOUS` are mutually exclusive.
    ///
    /// If the range in *vmo* specified by *offset* and *size* contains non-committed
    /// pages, a successful invocation of this function will result in those pages
    /// having been committed.  On failure, it is undefined whether they have been
    /// committed.
    ///
    /// *addrs* will be populated with the device-physical addresses of the requested
    /// VMO pages.  These addresses may be given to devices that issue memory
    /// transactions with the hardware transaction ID associated with the BTI.  The
    /// number of addresses returned depends on whether the `ZX_BTI_COMPRESS` or
    /// `ZX_BTI_CONTIGUOUS` options were given. The number of addresses will be one
    /// of three possibilities:
    ///
    /// 1. If neither is set, one per page (`size / PAGE_SIZE`).
    /// 2. If `ZX_BTI_COMPRESS` is set, `size / minimum-contiguity`, rounded up
    ///    (each address representing a run of *minimum-contiguity* run of bytes,
    ///    with the last one being potentially short if *size* is not a multiple of
    ///    *minimum-contiguity*).  It is guaranteed that all returned addresses will be
    ///    *minimum-contiguity*-aligned.  Note that *minimum-contiguity* is discoverable
    ///    via [`zx_object_get_info()`].
    /// 3. If `ZX_BTI_CONTIGUOUS` is set, the single address of the start of the memory.
    ///
    /// *num_addrs* is the number of entries in the *addrs* array.  It is an error for
    /// *num_addrs* to not match the value calculated above.
    ///
    /// The PMT retains a reference to the associated VMO, so the underlying VMO won't be
    /// destroyed until the PMT is unpinned.
    ///
    /// Resizable VMOs can be pinned. If a call to [`zx_vmo_set_size()`] would discard
    /// pinned pages, that call will fail.
    ///
    /// ## Options
    ///
    /// - `ZX_BTI_PERM_READ`, `ZX_BTI_PERM_WRITE`, and `ZX_BTI_PERM_EXECUTE` define
    ///   the access types that the hardware bus transaction initiator will be allowed
    ///   to use.
    /// - `ZX_BTI_COMPRESS` causes the returned address list to contain one entry per
    ///   block of *minimum-contiguity* bytes, rather than one per *PAGE_SIZE*.
    ///
    /// ## Rights
    ///
    /// *handle* must be of type `ZX_OBJ_TYPE_BTI` and have `ZX_RIGHT_MAP`.
    ///
    /// *vmo* must be of type `ZX_OBJ_TYPE_VMO` and have `ZX_RIGHT_MAP`.
    ///
    /// If *options* & `ZX_BTI_PERM_READ`, *vmo* must be of type `ZX_OBJ_TYPE_VMO` and have `ZX_RIGHT_READ`.
    ///
    /// If *options* & `ZX_BTI_PERM_WRITE`, *vmo* must be of type `ZX_OBJ_TYPE_VMO` and have `ZX_RIGHT_WRITE`.
    ///
    /// If *options* & `ZX_BTI_PERM_EXECUTE`, *vmo* must be of type `ZX_OBJ_TYPE_VMO` and have `ZX_RIGHT_READ`.
    ///
    /// ## Return value
    ///
    /// On success, `zx_bti_pin()` returns `ZX_OK`.  The device-physical addresses of the
    /// requested VMO pages will be written in *addrs*.  A handle to the created Pinned
    /// Memory Token is returned via *pmt*.  When the PMT is no longer needed,
    /// [`zx_pmt_unpin()`] should be invoked.
    ///
    /// In the event of failure, a negative error value is returned.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_BAD_HANDLE`  *handle* or *vmo* is not a valid handle.
    ///
    /// `ZX_ERR_WRONG_TYPE`  *handle* is not a BTI handle or *vmo* is not a VMO
    /// handle.
    ///
    /// `ZX_ERR_ACCESS_DENIED` *handle* or *vmo* does not have the `ZX_RIGHT_MAP`,
    /// or *options* contained a permissions flag corresponding to a right that *vmo*
    /// does not have.
    ///
    /// `ZX_ERR_INVALID_ARGS` *options* is 0 or contains an undefined flag, either
    /// *addrs* or *pmt* is not a valid pointer, *num_addrs* is not the same as the
    /// number of entries that would be returned, or *offset* or *size* is not
    /// page-aligned.
    ///
    /// `ZX_ERR_OUT_OF_RANGE` `offset + size` is out of the bounds of *vmo*.
    ///
    /// `ZX_ERR_UNAVAILABLE` (Temporary) At least one page in the requested range
    /// could not be pinned at this time.
    ///
    /// `ZX_ERR_NO_MEMORY`  Failure due to lack of memory. There is no good way for
    /// userspace to handle this (unlikely) error. In a future build this error will no
    /// longer occur.
    ///
    /// ## See also
    ///
    ///  - [`zx_bti_create()`]
    ///  - [`zx_object_get_info()`]
    ///  - [`zx_pmt_unpin()`]
    ///
    /// [`zx_bti_create()`]: bti_create.md
    /// [`zx_object_get_info()`]: object_get_info.md
    /// [`zx_pmt_unpin()`]: pmt_unpin.md
    /// [`zx_vmo_create_contiguous()`]: vmo_create_contiguous.md
    /// [`zx_vmo_create_physical()`]: vmo_create_physical.md
    /// [`zx_vmo_op_range()`]: vmo_op_range.md
    /// [`zx_vmo_set_size()`]: vmo_set_size.md
    strict Pin(resource struct {
        handle Handle:BTI;
        options uint32;
        vmo Handle:VMO;
        offset uint64;
        size uint64;
    }) -> (resource struct {
        @embedded_alias("zx/Paddr")
        addrs vector<Paddr>:MAX;
        pmt Handle:PMT;
    }) error Status;

    /// ## Summary
    ///
    /// Releases all quarantined PMTs.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_bti_release_quarantine(zx_handle_t handle);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_bti_release_quarantine()` releases all quarantined PMTs for the given BTI.
    /// This will release the PMTs' underlying references to VMOs and physical page
    /// pins.  The underlying physical pages may be eligible to be reallocated
    /// afterwards.
    ///
    /// ## Rights
    ///
    /// *handle* must be of type `ZX_OBJ_TYPE_BTI` and have `ZX_RIGHT_WRITE`.
    ///
    /// ## Return value
    ///
    /// `zx_bti_release_quarantine()` returns `ZX_OK` on success.
    /// In the event of failure, a negative error value is returned.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_BAD_HANDLE`  *handle* is not a valid handle.
    ///
    /// `ZX_ERR_WRONG_TYPE`  *handle* is not a BTI handle.
    ///
    /// `ZX_ERR_ACCESS_DENIED` *handle* does not have the `ZX_RIGHT_WRITE` right.
    ///
    /// ## See also
    ///
    ///  - [`zx_bti_pin()`]
    ///  - [`zx_pmt_unpin()`]
    ///
    /// [`zx_bti_pin()`]: bti_pin.md
    /// [`zx_pmt_unpin()`]: pmt_unpin.md
    strict ReleaseQuarantine(resource struct {
        handle Handle:BTI;
    }) -> () error Status;
};
