// 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 fuchsia.hardware.cpu.insntrace;

using zx;

const uint16 API_VERSION = 0;

/// The maximum number of traces that can be collected at once.
/// A "trace" is the instruction stream for one entity, cpu or thread.
const uint16 MAX_NUM_TRACES = 64;

/// The maximum number of supported address ranges.
const uint16 MAX_NUM_ADDR_RANGES = 2;

/// Tracing modes
enum Mode : uint8 {
    // Trace each cpu, regardless of what's running on it.
    CPU = 0;
    // Trace specific threads.
    THREAD = 1;
};

/// The allocation configuration of a trace.
struct Allocation {
    Mode mode;

    // The number of traces to create.
    // In CPU mode this must be zx_system_get_num_cpus().
    // In THREAD mode this is the maximum number of threads for which traces
    // will be collected. Buffer space is allocated on demand, but the
    // underlying data structure has a maximum. This value can be at most
    // MAX_NUM_TRACES.
    uint16 num_traces;
};

/// An address range, as [start,end].
struct AddressRange {
    uint64 start;
    uint64 end;
};

/// A buffer's configuration.
struct BufferConfig {
    /// A "buffer" is made up of `num_chunks` chunks with each chunk having
    /// size `1<<chunk_order` pages.
    uint32 num_chunks;

    /// log2 of the number of pages
    uint32 chunk_order;

    /// If true then use circular buffering.
    bool is_circular;

    /// The value of the control register.
    uint64 ctl;

    /// If non-zero then the address space of the instruction must match in
    /// order for the instruction to be traced. On x86 architectures the
    /// address space is specified by CR3.
    uint64 address_space_match;

    /// If non-zero, tracing is restricted to these address ranges.
    /// TODO(dje): There's only two, and vectors don't currently work here,
    /// so spell these out individually
    AddressRange address_range_0;
    AddressRange address_range_1;
};

/// A buffer's runtime state.
struct BufferState {
    /// This is the offset in the buffer where tracing stopped (treating all
    /// buffers as one large one). If using a circular buffer then all of the
    /// buffer may contain data, there's no current way to know if tracing
    /// wrapped without scanning records.
    uint64 capture_end;
};

alias BufferDescriptor = uint32;

protocol Controller {
    /// Initialize the trace.
    /// This does not include allocating space for the trace buffers, that is
    /// done later by `AllocateBuffer()`.
    Initialize(Allocation allocation) -> () error zx.status;

    /// Free all trace buffers and any other resources allocated for the trace.
    /// This is also done when the connection is closed (as well as stopping
    /// the trace).
    /// May be called multiple times.
    /// This can only fail when tracing in THREAD mode where tracing is
    /// terminated differently, in which case the error is `ZX_ERR_BAD_STATE`.
    // TODO(fxbug.dev/30840): Support terminating the trace in THREAD mode.
    Terminate() -> () error zx.status;

    /// Return the trace allocation configuration.
    GetAllocation() -> (Allocation? allocation);

    /// Allocate a trace buffer.
    /// When tracing cpus, buffers are auto-assigned to cpus: the resulting
    /// trace buffer descriptor is the number of the cpu using the buffer.
    AllocateBuffer(BufferConfig config) -> (BufferDescriptor descriptor) error zx.status;

    /// Assign a buffer to a thread.
    AssignThreadBuffer(BufferDescriptor descriptor, zx.handle:THREAD thread) -> () error zx.status;

    /// Release a previously assigned buffer from a thread.
    ReleaseThreadBuffer(BufferDescriptor descriptor, zx.handle:THREAD thread) -> () error zx.status;

    /// Fetch a buffer's configuration.
    GetBufferConfig(BufferDescriptor descriptor) -> (BufferConfig? config);

    /// Fetch runtime information about a buffer.
    GetBufferState(BufferDescriptor descriptor) -> (BufferState? state);

    /// Fetch the handle of a chunk of a trace buffer.
    GetChunkHandle(BufferDescriptor descriptor, uint32 chunk_num) -> (zx.handle:VMO? buffer);

    /// Free a previously allocated trace buffer.
    FreeBuffer(BufferDescriptor descriptor) -> ();

    /// Start tracing.
    /// Must be called after `Initialize()` + `AllocateBuffer()`,
    /// with tracing off.
    Start() -> ();

    /// Stop tracing.
    /// May be called any time after `Allocate()` has been called and before
    /// `Free()`. If called at other times the call is ignored.
    /// May be called multiple times.
    // TODO(fxbug.dev/30840): Support terminating the trace in THREAD mode.
    Stop() -> ();
};
