blob: 49e5d164fc511d979b321dd50fec20d369a80eef [file] [log] [blame]
// 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(fxbug.dev/32803): 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;
};