107 lines
3.4 KiB
C
107 lines
3.4 KiB
C
|
/*
|
||
|
* 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 <linux/kernel.h>
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/perf_event.h>
|
||
|
|
||
|
/* For performance counter definitions */
|
||
|
#include <asm/metag_mem.h>
|
||
|
|
||
|
/*
|
||
|
* 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
|