// 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.
@available(added=HEAD)
library fuchsia.perfmon.cpu;

using zx;

// The type of the `rate` field of EventConfig.
alias EventRate = uint32;

// Trace buffer space is expensive, we want to keep records small.
// Having more than 64K different events for any one arch is unlikely
// so we use 16 bits for the event id.
// To help each arch manage the plethora of different events, the event id
// is split it two parts: 5 bit event group, and 11 bit event within that
// group.
// An event id of zero is defined to be unused.
alias EventId = uint16;

const API_VERSION uint16 = 0;

/// The maximum number of events we support simultaneously.
/// Typically the h/w supports less than this, e.g., 7 or so.
const MAX_NUM_EVENTS uint16 = 32;

/// Passed to `StageConfig()` to select the data to be collected.
type Config = struct {
    /// Events to collect data for.
    events array<@generated_name("EventConfig") struct {
        /// Event to collect data for.
        /// The values are architecture specific ids.
        /// Each event may appear at most once.
        event EventId;

        /// Sampling rate.
        /// - If rate is non-zero then when the event gets this many hits data is
        ///   collected (e.g., pc, time).
        ///   The rate can be non-zero for counting based events only.
        /// - If rate is zero then:
        ///     If there is a timebase event then data for this event is collected
        ///     when data for the timebase event is collected.
        ///     Otherwise data for the event is collected once, when tracing stops.
        rate EventRate;

        /// Flags for the event.
        // TODO(dje): hypervisor, host/guest os/user
        flags @generated_name("EventConfigFlags") strict bits : uint32 {
            /// Collect data when running in kernel mode.
            COLLECT_OS = 0x1;

            /// Collect data when running in userspace mode.
            COLLECT_USER = 0x2;

            /// Collect aspace+pc values.
            COLLECT_PC = 0x4;

            /// If set for an event then the event is used as the "timebase": data
            /// for events with a zero rate is collected when data for the timebase
            /// event is collected.
            /// It is an error to have this set and have the event's rate be zero.
            /// At most one event may be the timebase event.
            IS_TIMEBASE = 0x8;

            /// Collect the available set of last branches.
            /// Branch data is emitted as LastBranch records.
            /// This is only available when the underlying system supports it.
            // TODO(dje): Provide knob to specify how many branches.
            COLLECT_LAST_BRANCH = 0x10;
        };
    }, MAX_NUM_EVENTS>;
};

/// The allocation configuration for a data collection run.
/// This is generally the first call to allocate resources for a trace,
/// "trace" is used generically here: == "data collection run".
type Allocation = struct {
    /// The number of buffers to allocate for trace data.
    /// This must be #cpus for now.
    num_buffers uint32;

    /// The size of each buffer in 4K pages.
    /// Each cpu gets same buffer size.
    buffer_size_in_pages uint32;
};

closed protocol Controller {
    /// Fetch the performance monitor properties of the system.
    strict GetProperties() -> (struct {
        /// The properties of this system.
        properties @generated_name("Properties") struct {
            /// S/W API version = `API_VERSION`.
            api_version uint16;

            /// The H/W Performance Monitor version.
            /// This is the version defined by the architecture.
            pm_version uint16;

            /// The maximum number of events that can be simultaneously supported.
            /// The combination of events that can be simultaneously supported is
            /// architecture/model specific.
            max_num_events uint16;

            /// The maximum number of fixed events that can be simultaneously
            /// supported, and their maximum width.
            /// These values are for informational/display purposes.
            max_num_fixed_events uint16;
            max_fixed_counter_width uint16;

            /// The maximum number of programmable events that can be simultaneously
            /// supported, and their maximum width.
            /// These values are for informational/display purposes.
            max_num_programmable_events uint16;
            max_programmable_counter_width uint16;

            /// The maximum number of misc events that can be simultaneously
            /// supported, and their maximum width.
            /// These values are for informational/display purposes.
            max_num_misc_events uint16;
            max_misc_counter_width uint16;

            /// Various flags.
            flags @generated_name("PropertyFlags") strict bits : uint64 {
                /// The architecture supports LBR records (Last Branch Records).
                HAS_LAST_BRANCH = 0x1;
            };
        };
    });

    /// Create a trace, allocating the needed trace buffers and other resources.
    /// "other resources" is basically a catch-all for other things that will
    /// be needed. This does not include reserving the events, that is done
    /// later by `StageConfig()`.
    strict Initialize(struct {
        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.
    /// Tracing is first stopped if not already stopped.
    /// May be called multiple times.
    strict Terminate() -> ();

    /// Return the trace allocation configuration, if there is one.
    strict GetAllocation() -> (struct {
        allocation box<Allocation>;
    });

    /// Stage performance monitor specification for a cpu.
    /// Must be called with data collection off and after `Initialize()`.
    /// Note: This doesn't actually configure the h/w, this just stages
    /// the values for subsequent use by `Start()`.
    strict StageConfig(struct {
        config Config;
    }) -> () error zx.Status;

    /// Fetch performance monitor specification for a cpu, if it exists.
    /// Must be called with data collection off and after `StageConfig()`.
    strict GetConfig() -> (struct {
        config box<Config>;
    });

    /// Return a handle of a trace buffer, if it exists, and if `descriptor`
    /// is valid.
    /// `descriptor` is (0, 1, 2, ..., `num_buffers`-1)
    strict GetBufferHandle(struct {
        descriptor uint32;
    }) -> (resource struct {
        vmo zx.Handle:<VMO, optional>;
    });

    /// Turn on data collection.
    /// Must be called after `Initialize()` + `StageConfig()` and with data
    /// collection off.
    strict Start() -> () error zx.Status;

    /// Turn off data collection.
    /// May be called any time after `Initialize()` has been called and before
    /// `Terminate()`. If called at other times the call is ignored.
    /// May be called multiple times.
    strict Stop() -> ();
};

closed protocol Device {
    /// Opens a new session on the device.
    ///
    /// At most one session is permitted at one time; the server end will be
    /// closed with `ZX_ERR_ALREADY_BOUND` if a session already exists.
    strict OpenSession(resource struct {
        session server_end:Controller;
    });
};
