|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* PPC64 Performance-Monitoring Counters driver
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Copyright (C) 2004 David Gibson, IBM Corporation.
|
|
Packit |
577717 |
* Copyright (C) 2004 Mikael Pettersson
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#ifndef _ASM_PPC64_PERFCTR_H
|
|
Packit |
577717 |
#define _ASM_PPC64_PERFCTR_H
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <asm/types.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct perfctr_sum_ctrs {
|
|
Packit |
577717 |
__u64 tsc;
|
|
Packit |
577717 |
__u64 pmc[8]; /* the size is not part of the user ABI */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct perfctr_cpu_control_header {
|
|
Packit |
577717 |
__u32 tsc_on;
|
|
Packit |
577717 |
__u32 nractrs; /* number of accumulation-mode counters */
|
|
Packit |
577717 |
__u32 nrictrs; /* number of interrupt-mode counters */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct perfctr_cpu_state_user {
|
|
Packit |
577717 |
__u32 cstatus;
|
|
Packit |
577717 |
/* This is a sequence counter to ensure atomic reads by
|
|
Packit |
577717 |
* userspace. The mechanism is identical to that used for
|
|
Packit |
577717 |
* seqcount_t in include/linux/seqlock.h. */
|
|
Packit |
577717 |
__u32 sequence;
|
|
Packit |
577717 |
__u64 tsc_start;
|
|
Packit |
577717 |
__u64 tsc_sum;
|
|
Packit |
577717 |
struct {
|
|
Packit |
577717 |
__u64 start;
|
|
Packit |
577717 |
__u64 sum;
|
|
Packit |
577717 |
} pmc[8]; /* the size is not part of the user ABI */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* cstatus is a re-encoding of control.tsc_on/nractrs/nrictrs
|
|
Packit |
577717 |
which should have less overhead in most cases */
|
|
Packit |
577717 |
/* XXX: ppc driver internally also uses cstatus&(1<<30) */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline
|
|
Packit |
577717 |
unsigned int perfctr_mk_cstatus(unsigned int tsc_on, unsigned int nractrs,
|
|
Packit |
577717 |
unsigned int nrictrs)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return (tsc_on<<31) | (nrictrs<<16) | ((nractrs+nrictrs)<<8) | nractrs;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned int perfctr_cstatus_enabled(unsigned int cstatus)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return cstatus;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline int perfctr_cstatus_has_tsc(unsigned int cstatus)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return (int)cstatus < 0; /* test and jump on sign */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned int perfctr_cstatus_nractrs(unsigned int cstatus)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return cstatus & 0x7F; /* and with imm8 */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned int perfctr_cstatus_nrctrs(unsigned int cstatus)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return (cstatus >> 8) & 0x7F;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned int perfctr_cstatus_has_ictrs(unsigned int cstatus)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return cstatus & (0x7F << 16);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* 'struct siginfo' support for perfctr overflow signals.
|
|
Packit |
577717 |
* In unbuffered mode, si_code is set to SI_PMC_OVF and a bitmask
|
|
Packit |
577717 |
* describing which perfctrs overflowed is put in si_pmc_ovf_mask.
|
|
Packit |
577717 |
* A bitmask is used since more than one perfctr can have overflowed
|
|
Packit |
577717 |
* by the time the interrupt handler runs.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#define SI_PMC_OVF -8
|
|
Packit |
577717 |
#define si_pmc_ovf_mask _sifields._pad[0] /* XXX: use an unsigned field later */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef __KERNEL__
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(CONFIG_PERFCTR)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct perfctr_cpu_control {
|
|
Packit |
577717 |
struct perfctr_cpu_control_header header;
|
|
Packit |
577717 |
u64 mmcr0;
|
|
Packit |
577717 |
u64 mmcr1;
|
|
Packit |
577717 |
u64 mmcra;
|
|
Packit |
577717 |
unsigned int ireset[8]; /* [0,0x7fffffff], for i-mode counters, physical indices */
|
|
Packit |
577717 |
unsigned int pmc_map[8]; /* virtual to physical index map */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct perfctr_cpu_state {
|
|
Packit |
577717 |
/* Don't change field order here without first considering the number
|
|
Packit |
577717 |
of cache lines touched during sampling and context switching. */
|
|
Packit |
577717 |
unsigned int id;
|
|
Packit |
577717 |
int isuspend_cpu;
|
|
Packit |
577717 |
struct perfctr_cpu_state_user user;
|
|
Packit |
577717 |
unsigned int unused_pmcs;
|
|
Packit |
577717 |
struct perfctr_cpu_control control;
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Driver init/exit. */
|
|
Packit |
577717 |
extern int perfctr_cpu_init(void);
|
|
Packit |
577717 |
extern void perfctr_cpu_exit(void);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* CPU type name. */
|
|
Packit |
577717 |
extern char *perfctr_cpu_name;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Hardware reservation. */
|
|
Packit |
577717 |
extern const char *perfctr_cpu_reserve(const char *service);
|
|
Packit |
577717 |
extern void perfctr_cpu_release(const char *service);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* PRE: state has no running interrupt-mode counters.
|
|
Packit |
577717 |
Check that the new control data is valid.
|
|
Packit |
577717 |
Update the driver's private control data.
|
|
Packit |
577717 |
Returns a negative error code if the control data is invalid. */
|
|
Packit |
577717 |
extern int perfctr_cpu_update_control(struct perfctr_cpu_state *state, int is_global);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Parse and update control for the given domain. */
|
|
Packit |
577717 |
extern int perfctr_cpu_control_write(struct perfctr_cpu_control *control,
|
|
Packit |
577717 |
unsigned int domain,
|
|
Packit |
577717 |
const void *srcp, unsigned int srcbytes);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Retrieve and format control for the given domain.
|
|
Packit |
577717 |
Returns number of bytes written. */
|
|
Packit |
577717 |
extern int perfctr_cpu_control_read(const struct perfctr_cpu_control *control,
|
|
Packit |
577717 |
unsigned int domain,
|
|
Packit |
577717 |
void *dstp, unsigned int dstbytes);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Read a-mode counters. Subtract from start and accumulate into sums.
|
|
Packit |
577717 |
Must be called with preemption disabled. */
|
|
Packit |
577717 |
extern void perfctr_cpu_suspend(struct perfctr_cpu_state *state);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Write control registers. Read a-mode counters into start.
|
|
Packit |
577717 |
Must be called with preemption disabled. */
|
|
Packit |
577717 |
extern void perfctr_cpu_resume(struct perfctr_cpu_state *state);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Perform an efficient combined suspend/resume operation.
|
|
Packit |
577717 |
Must be called with preemption disabled. */
|
|
Packit |
577717 |
extern void perfctr_cpu_sample(struct perfctr_cpu_state *state);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* The type of a perfctr overflow interrupt handler.
|
|
Packit |
577717 |
It will be called in IRQ context, with preemption disabled. */
|
|
Packit |
577717 |
typedef void (*perfctr_ihandler_t)(unsigned long pc);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Operations related to overflow interrupt handling. */
|
|
Packit |
577717 |
#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
|
|
Packit |
577717 |
extern void perfctr_cpu_set_ihandler(perfctr_ihandler_t);
|
|
Packit |
577717 |
extern void perfctr_cpu_ireload(struct perfctr_cpu_state*);
|
|
Packit |
577717 |
extern unsigned int perfctr_cpu_identify_overflow(struct perfctr_cpu_state*);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
static inline void perfctr_cpu_set_ihandler(perfctr_ihandler_t x) { }
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
static inline int perfctr_cpu_has_pending_interrupt(const struct perfctr_cpu_state *state)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif /* CONFIG_PERFCTR */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif /* __KERNEL__ */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif /* _ASM_PPC64_PERFCTR_H */
|