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

// port_packet_t::type ZX_PKT_TYPE_USER.
type PacketUser = strict union {
    1: u64 array<uint64, 4>;
    2: u32 array<uint32, 8>;
    3: u16 array<uint16, 16>;
    4: c8 array<int8, 32>;
};

// port_packet_t::type ZX_PKT_TYPE_SIGNAL_ONE.
type PacketSignal = struct {
    trigger Signals;
    observed Signals;
    count uint64;
    reserved0 uint64;
    reserved1 uint64;
};

type PacketException = struct {
    pid uint64;
    tid uint64;
    reserved0 uint64;
    reserved1 uint64;
};

type PacketGuestBell = struct {
    addr Gpaddr;
    reserved0 uint64;
    reserved1 uint64;
    reserved2 uint64;
};

// TODO(scottmg): Arch-specific definition.
type PacketGuestMem = struct {
    addr Gpaddr;
    //#if __aarch64__
    //uint8_t access_size;
    //bool sign_extend;
    //uint8_t xt;
    //bool read;
    //uint64_t data;
    //uint64_t reserved;
    //#elif __x86_64__
    //// NOTE: x86 instructions are guaranteed to be 15 bytes or fewer.
    //#define X86_MAX_INST_LEN 15u
    //uint8_t inst_len;
    //uint8_t inst_buf[X86_MAX_INST_LEN];
    //// This is the default operand size as determined by the CS and EFER register (Volume 3,
    //// Section 5.2.1). If operating in 64-bit mode then near branches and all instructions, except
    //// far branches, that implicitly reference the RSP will actually have a default operand size of
    //// 64-bits (Volume 2, Section 2.2.1.7), and not the 32-bits that will be given here.
    //uint8_t default_operand_size;
    //uint8_t reserved[7];
    //#endif
};

type PacketGuestIo = struct {
    port uint16;
    access_size uint8;
    input bool;
    // TODO(scottmg): Unnamed union.
    //union {
    //  uint8_t u8;
    //  uint16_t u16;
    //  uint32_t u32;
    //  uint8_t data[4];
    //};
    reserved0 uint64;
    reserved1 uint64;
    reserved2 uint64;
};

type PacketGuestVcpu = struct {
    // TODO(scottmg): Unnamed union.
    //union {
    //  struct {
    //    uint64_t mask;
    //    uint8_t vector;
    //  } interrupt;
    //  struct {
    //    uint64_t id;
    //    zx_gpaddr_t entry;
    //  } startup;
    //};
    type uint8;
    reserved uint64;
};

type PacketInterrupt = struct {
    timestamp Time;
    reserved0 uint64;
    reserved1 uint64;
    reserved2 uint64;
};

type PacketPageRequest = struct {
    command uint16;
    flags uint16;
    reserved0 uint32;
    offset uint64;
    length uint64;
    reserved1 uint64;
};

type PortPacket = struct {
    key uint64;
    type uint32;
    status Status;
    // TODO(scottmg): Unnamed union.
    // union {
    user PacketUser;
    signal PacketSignal;
    exception PacketException;
    guest_bell PacketGuestBell;
    guest_mem PacketGuestMem;
    guest_io PacketGuestIo;
    guest_vcpu PacketGuestVcpu;
    interrupt PacketInterrupt;
    page_request PacketPageRequest;
    // };
};

@transport("Syscall")
closed protocol Port {
    /// ## Summary
    ///
    /// Create an IO port.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_port_create(uint32_t options, zx_handle_t* out);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_port_create()` creates a port: a waitable object that can be used to read
    /// packets queued by kernel or by user-mode.
    ///
    /// If you need this port to be bound to an interrupt, pass `ZX_PORT_BIND_TO_INTERRUPT` to *options*,
    /// otherwise it should be `0`.
    ///
    /// In the case where a port is bound to an interrupt, the interrupt packets are delivered via a
    /// dedicated queue on ports and are higher priority than other non-interrupt packets.
    ///
    /// The returned handle will have:
    ///
    ///   * `ZX_RIGHT_TRANSFER`: allowing them to be sent to another process through [`zx_channel_write()`].
    ///   * `ZX_RIGHT_WRITE`: allowing packets to be *queued*.
    ///   * `ZX_RIGHT_READ`: allowing packets to be *read*.
    ///   * `ZX_RIGHT_DUPLICATE`: allowing them to be *duplicated*.
    ///
    /// ## Rights
    ///
    /// Caller job policy must allow `ZX_POL_NEW_PORT`.
    ///
    /// ## Return value
    ///
    /// `zx_port_create()` returns `ZX_OK` and a valid IO port handle via *out* on
    /// success. In the event of failure, an error value is returned.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_INVALID_ARGS` *options* has an invalid value, or *out* is an
    /// invalid pointer or NULL.
    ///
    /// `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 builds this error will no longer occur.
    ///
    /// ## See also
    ///
    ///  - [`zx_handle_close()`]
    ///  - [`zx_handle_duplicate()`]
    ///  - [`zx_handle_replace()`]
    ///  - [`zx_object_wait_async()`]
    ///  - [`zx_port_queue()`]
    ///  - [`zx_port_wait()`]
    ///
    /// [`zx_channel_write()`]: channel_write.md
    /// [`zx_handle_close()`]: handle_close.md
    /// [`zx_handle_duplicate()`]: handle_duplicate.md
    /// [`zx_handle_replace()`]: handle_replace.md
    /// [`zx_object_wait_async()`]: object_wait_async.md
    /// [`zx_port_queue()`]: port_queue.md
    /// [`zx_port_wait()`]: port_wait.md
    strict Create(struct {
        options uint32;
    }) -> (resource struct {
        out Handle:PORT;
    }) error Status;

    /// ## Summary
    ///
    /// Queue a packet to a port.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    /// #include <zircon/syscalls/port.h>
    ///
    /// zx_status_t zx_port_queue(zx_handle_t handle, const zx_port_packet_t* packet);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_port_queue()` queues a user *packet* to the port specified by *handle*.
    ///
    /// User packets are drained by [`zx_port_wait()`]. Failure to drain packets in a
    /// timely fashion can cause excessive kernel memory to be used, which might generate
    /// an exception. See [ipc limits](/docs/concepts/kernel/ipc_limits.md) for details.
    ///
    /// ```
    /// typedef struct zx_port_packet {
    ///     uint64_t key;
    ///     uint32_t type;
    ///     zx_status_t status;
    ///     union {
    ///         zx_packet_user_t user;
    ///         zx_packet_signal_t signal;
    ///     };
    /// } zx_port_packet_t;
    ///
    /// ```
    ///
    /// In *packet* *type* should be `ZX_PKT_TYPE_USER` and only the `user`
    /// union element is considered valid:
    ///
    /// ```
    /// typedef union zx_packet_user {
    ///     uint64_t u64[4];
    ///     uint32_t u32[8];
    ///     uint16_t u16[16];
    ///     uint8_t   c8[32];
    /// } zx_packet_user_t;
    ///
    /// ```
    ///
    /// ## Rights
    ///
    /// *handle* must be of type `ZX_OBJ_TYPE_PORT` and have `ZX_RIGHT_WRITE`.
    ///
    /// ## Return value
    ///
    /// `zx_port_queue()` returns `ZX_OK` on successful queue of a packet.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_BAD_HANDLE` *handle* isn't a valid handle
    ///
    /// `ZX_ERR_INVALID_ARGS` *packet* is an invalid pointer.
    ///
    /// `ZX_ERR_WRONG_TYPE` *handle* is not a port handle.
    ///
    /// `ZX_ERR_ACCESS_DENIED` *handle* does not have `ZX_RIGHT_WRITE`.
    ///
    /// ## See also
    ///
    ///  - [`zx_port_create()`]
    ///  - [`zx_port_wait()`]
    ///
    /// [`zx_port_create()`]: port_create.md
    /// [`zx_port_wait()`]: port_wait.md
    strict Queue(resource struct {
        handle Handle:PORT;
        packet PortPacket;
    }) -> () error Status;

    /// ## Summary
    ///
    /// Wait for a packet arrival in a port.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    /// #include <zircon/syscalls/port.h>
    ///
    /// zx_status_t zx_port_wait(zx_handle_t handle,
    ///                          zx_time_t deadline,
    ///                          zx_port_packet_t* packet);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_port_wait()` is a blocking syscall, which causes the caller to wait until at least
    /// one packet is available.
    ///
    /// Upon return, if successful *packet* will contain the earliest (in FIFO order)
    /// available packet data.
    ///
    /// The *deadline* indicates when to stop waiting for a packet (with respect to
    /// `ZX_CLOCK_MONOTONIC`) and will be automatically adjusted according to the job's
    /// [timer slack] policy. If no packet has arrived by the deadline,
    /// `ZX_ERR_TIMED_OUT` is returned.  The value `ZX_TIME_INFINITE` will result in
    /// waiting forever.  A value in the past will result in an immediate timeout,
    /// unless a packet is already available for reading.
    ///
    /// Unlike [`zx_object_wait_one()`] and [`zx_object_wait_many()`] only one
    /// waiting thread is released (per available packet), which makes ports
    /// amenable to be serviced by thread pools.
    ///
    /// There are two classes of packets: packets queued by userspace with [`zx_port_queue()`]
    /// and packets queued by the kernel when objects a port is registered with change state. In both
    /// cases the packet is always of type `zx_port_packet_t`:
    ///
    /// ```
    /// struct zx_port_packet_t {
    ///     uint64_t key;
    ///     uint32_t type;
    ///     zx_status_t status;
    ///     union {
    ///         zx_packet_user_t user;
    ///         zx_packet_signal_t signal;
    ///         zx_packet_guest_bell_t guest_bell;
    ///         zx_packet_guest_mem_t guest_mem;
    ///         zx_packet_guest_io_t guest_io;
    ///         zx_packet_guest_vcpu_t guest_vcpu;
    ///         zx_packet_interrupt_t interrupt;
    ///         zx_packet_page_request_t page_request;
    ///     };
    /// };
    /// ```
    ///
    /// In the case of packets generated via [`zx_port_queue()`], *type* will be set to
    /// `ZX_PKT_TYPE_USER`, and the caller of [`zx_port_queue()`] controls all other values in the
    /// `zx_port_packet_t` structure. Access to the packet data is provided by the *user* member, with
    /// type `zx_packet_user_t`:
    ///
    /// ```
    /// typedef union zx_packet_user {
    ///     uint64_t u64[4];
    ///     uint32_t u32[8];
    ///     uint16_t u16[16];
    ///     uint8_t   c8[32];
    /// } zx_packet_user_t;
    /// ```
    ///
    /// For packets generated by the kernel, type can be one of the following values:
    ///
    /// `ZX_PKT_TYPE_SIGNAL_ONE` - generated by objects registered via
    /// [`zx_object_wait_async()`].
    ///
    /// `ZX_PKT_TYPE_GUEST_BELL`, `ZX_PKT_TYPE_GUEST_MEM`, `ZX_PKT_TYPE_GUEST_IO`,
    /// or `ZX_PKT_TYPE_GUEST_VCPU` - generated by objects registered via [`zx_guest_set_trap()`].
    ///
    /// `ZX_PKT_TYPE_INTERRUPT` - generated by objects registered via [`zx_interrupt_bind()`].
    ///
    /// `ZX_PKT_TYPE_PAGE_REQUEST` - generated by objects registered via [`zx_pager_create_vmo()`].
    ///
    /// All kernel queued packets will have *status* set to `ZX_OK` and *key* set to the
    /// value provided to the registration syscall. For details on how to interpret the union, see
    /// the corresponding registration syscall.
    ///
    /// ## Rights
    ///
    /// *handle* must be of type `ZX_OBJ_TYPE_PORT` and have `ZX_RIGHT_READ`.
    ///
    /// ## Return value
    ///
    /// `zx_port_wait()` returns `ZX_OK` on successful packet dequeuing.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle.
    ///
    /// `ZX_ERR_INVALID_ARGS` *packet* isn't a valid pointer
    ///
    /// `ZX_ERR_ACCESS_DENIED` *handle* does not have `ZX_RIGHT_READ` and may
    /// not be waited upon.
    ///
    /// `ZX_ERR_TIMED_OUT` *deadline* passed and no packet was available.
    ///
    /// ## See also
    ///
    ///  - [timer slack]
    ///  - [`zx_object_wait_async()`]
    ///  - [`zx_port_create()`]
    ///  - [`zx_port_queue()`]
    ///
    /// [timer slack]: /docs/concepts/kernel/timer_slack.md
    /// [`zx_guest_set_trap()`]: guest_set_trap.md
    /// [`zx_interrupt_bind()`]: interrupt_bind.md
    /// [`zx_object_wait_async()`]: object_wait_async.md
    /// [`zx_object_wait_many()`]: object_wait_many.md
    /// [`zx_object_wait_one()`]: object_wait_one.md
    /// [`zx_pager_create_vmo()`]: pager_create_vmo.md
    /// [`zx_port_create()`]: port_create.md
    /// [`zx_port_queue()`]: port_queue.md
    @blocking
    strict Wait(resource struct {
        handle Handle:PORT;
        deadline Time;
    }) -> (struct {
        packet PortPacket;
    }) error Status;

    /// ## Summary
    ///
    /// Cancels async port notifications on an object.
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_port_cancel(zx_handle_t handle,
    ///                            zx_handle_t source,
    ///                            uint64_t key);
    /// ```
    ///
    /// ## Description
    ///
    /// `zx_port_cancel()` is a non-blocking syscall that cancels
    /// all pending [`zx_object_wait_async()`] operations made with *source* and *key*.
    ///
    /// When this call succeeds no new packets from the object pointed by
    /// *source* with *key* will be delivered to *handle*, and pending queued
    /// packets that match *source* and *key* are removed from the port.
    ///
    /// ## Rights
    ///
    /// *handle* must be of type `ZX_OBJ_TYPE_PORT` and have `ZX_RIGHT_WRITE`.
    ///
    /// ## Return value
    ///
    /// `zx_port_cancel()` returns `ZX_OK` if cancellation succeeded and
    /// either queued packets were removed or pending [`zx_object_wait_async()`] were
    /// canceled.
    ///
    /// ## Errors
    ///
    /// `ZX_ERR_BAD_HANDLE`  *source* or *handle* is not a valid handle.
    ///
    /// `ZX_ERR_WRONG_TYPE`  *handle* is not a port handle.
    ///
    /// `ZX_ERR_ACCESS_DENIED`  *source* or *handle* does not have `ZX_RIGHT_WRITE`.
    ///
    /// `ZX_ERR_NOT_SUPPORTED`  *source* is a handle that cannot be waited on.
    ///
    /// `ZX_ERR_NOT_FOUND` if either no pending packets or pending
    /// [`zx_object_wait_async()`] calls with *source* and *key* were found.
    ///
    /// ## See also
    ///
    ///  - [`zx_port_wait()`]
    ///
    /// [`zx_object_wait_async()`]: object_wait_async.md
    /// [`zx_port_wait()`]: port_wait.md
    strict Cancel(resource struct {
        handle Handle:PORT;
        source Handle;
        key uint64;
    }) -> () error Status;
};
