// 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 Ktrace {
    // TODO(scottmg): This is another one where it's:
    //   (handle, data, offset, data_size)
    // rather than:
    //   (handle, data, data_size, offset).
    /// ## Summary
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_ktrace_read(zx_handle_t handle,
    ///                            void* data,
    ///                            uint32_t offset,
    ///                            size_t data_size,
    ///                            size_t* actual);
    /// ```
    ///
    /// ## Description
    ///
    /// To use the `zx_ktrace_read()` function, you must specify
    /// `kernel.enable-debugging-syscalls=true` on the kernel command line. Otherwise,
    /// the function returns `ZX_ERR_NOT_SUPPORTED`.
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Rights
    ///
    /// *handle* must have resource kind `ZX_RSRC_KIND_SYSTEM` with base
    /// `ZX_RSRC_SYSTEM_DEBUG_BASE`.
    ///
    /// ## Return value
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Errors
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## See also
    ///
    /// TODO(https://fxbug.dev/42108078)
    strict Read(resource struct {
        handle Handle:RESOURCE;
        @out
        @voidptr
        data experimental_pointer<byte>;
        offset uint32;
        data_size usize64;
    }) -> (struct {
        actual usize64;
    }) error Status;

    // TODO(scottmg): syscalls.banjo had the length of |ptr| being |action|?
    /// ## Summary
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_ktrace_control(zx_handle_t handle,
    ///                               uint32_t action,
    ///                               uint32_t options,
    ///                               void* ptr);
    /// ```
    ///
    /// ## Description
    ///
    /// To use the `zx_ktrace_control()` function, you must specify
    /// `kernel.enable-debugging-syscalls=true` on the kernel command line. Otherwise,
    /// the function returns `ZX_ERR_NOT_SUPPORTED`.
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Rights
    ///
    /// *handle* must have resource kind `ZX_RSRC_KIND_SYSTEM` with base
    /// `ZX_RSRC_SYSTEM_DEBUG_BASE`.
    ///
    /// ## Return value
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Errors
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## See also
    ///
    /// TODO(https://fxbug.dev/42108078)
    strict Control(resource struct {
        handle Handle:RESOURCE;
        action uint32;
        options uint32;

        @inout
        @voidptr
        ptr experimental_pointer<byte>;
    }) -> () error Status;

    /// ## Summary
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Declaration
    ///
    /// ```c
    /// #include <zircon/syscalls.h>
    ///
    /// zx_status_t zx_ktrace_write(zx_handle_t handle,
    ///                             uint32_t id,
    ///                             uint32_t arg0,
    ///                             uint32_t arg1);
    /// ```
    ///
    /// ## Description
    ///
    /// To use the `zx_ktrace_write()` function, you must specify
    /// `kernel.enable-debugging-syscalls=true` on the kernel command line. Otherwise,
    /// the function returns `ZX_ERR_NOT_SUPPORTED`.
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Rights
    ///
    /// *handle* must have resource kind `ZX_RSRC_KIND_SYSTEM` with base
    /// `ZX_RSRC_SYSTEM_DEBUG_BASE`.
    ///
    /// ## Return value
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## Errors
    ///
    /// TODO(https://fxbug.dev/42108078)
    ///
    /// ## See also
    ///
    /// TODO(https://fxbug.dev/42108078)
    strict Write(resource struct {
        handle Handle:RESOURCE;
        id uint32;
        arg0 uint32;
        arg1 uint32;
    }) -> () error Status;
};
