blob: 66a69500a6174f2b32deaef63614c95b129fe14a [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 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;
});
};