/* * Meta performance counter support. * Copyright (C) 2012 Imagination Technologies Ltd * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #ifndef METAG_PERF_EVENT_H_ #define METAG_PERF_EVENT_H_ #include #include #include /* For performance counter definitions */ #include /* * The Meta core has two performance counters, with 24-bit resolution. Newer * cores generate an overflow interrupt on transition from 0xffffff to 0. * * Each counter consists of the counter id, hardware thread id, and the count * itself; each counter can be assigned to multiple hardware threads at any * one time, with the returned count being an aggregate of events. A small * number of events are thread global, i.e. they count the aggregate of all * threads' events, regardless of the thread selected. * * Newer cores can store an arbitrary 24-bit number in the counter, whereas * older cores will clear the counter bits on write. * * We also have a pseudo-counter in the form of the thread active cycles * counter (which, incidentally, is also bound to */ #define MAX_HWEVENTS 3 #define MAX_PERIOD ((1UL << 24) - 1) #define METAG_INST_COUNTER (MAX_HWEVENTS - 1) /** * struct cpu_hw_events - a processor core's performance events * @events: an array of perf_events active for a given index. * @used_mask: a bitmap of in-use counters. * @pmu_lock: a perf counter lock * * This is a per-cpu/core structure that maintains a record of its * performance counters' state. */ struct cpu_hw_events { struct perf_event *events[MAX_HWEVENTS]; unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; raw_spinlock_t pmu_lock; }; /** * struct metag_pmu - the Meta PMU structure * @pmu: core pmu structure * @name: pmu name * @version: core version * @handle_irq: overflow interrupt handler * @enable: enable a counter * @disable: disable a counter * @read: read the value of a counter * @write: write a value to a counter * @event_map: kernel event to counter event id map * @cache_events: kernel cache counter to core cache counter map * @max_period: maximum value of the counter before overflow * @max_events: maximum number of counters available at any one time * @active_events: number of active counters * @reserve_mutex: counter reservation mutex * * This describes the main functionality and data used by the performance * event core. */ struct metag_pmu { struct pmu pmu; const char *name; u32 version; irqreturn_t (*handle_irq)(int irq_num, void *dev); void (*enable)(struct hw_perf_event *evt, int idx); void (*disable)(struct hw_perf_event *evt, int idx); u64 (*read)(int idx); void (*write)(int idx, u32 val); int (*event_map)(int idx); const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX]; u32 max_period; int max_events; atomic_t active_events; struct mutex reserve_mutex; }; /* Convenience macros for accessing the perf counters */ /* Define some convenience accessors */ #define PERF_COUNT(x) (PERF_COUNT0 + (sizeof(u64) * (x))) #define PERF_ICORE(x) (PERF_ICORE0 + (sizeof(u64) * (x))) #define PERF_CHAN(x) (PERF_CHAN0 + (sizeof(u64) * (x))) /* Cache index macros */ #define C(x) PERF_COUNT_HW_CACHE_##x #define CACHE_OP_UNSUPPORTED 0xfffe #define CACHE_OP_NONSENSE 0xffff #endif