10d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek/**
20d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * @file oprofile.h
30d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * Main driver code
40d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek *
50d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * @remark Copyright 2002 OProfile authors
60d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * @remark Read the file COPYING
70d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek *
80d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * @author John Levon
90d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * @author Philippe Elie
100d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek */
110d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
120d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#ifndef OPROFILE_H
130d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#define OPROFILE_H
140d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
150d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/version.h>
160d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/module.h>
170d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/config.h>
180d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/kernel.h>
190d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/init.h>
200d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/slab.h>
210d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/delay.h>
220d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/vmalloc.h>
230d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/sched.h>
2413493ea1583f39d62a66e2b2a0802f08d8ec32caTed Kremenek#include <linux/sysctl.h>
250d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <linux/smp_lock.h>
260d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
270d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include <asm/uaccess.h>
280d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
290d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include "compat.h"
300d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
310d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include "op_config_24.h"
320d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include "op_hw_config.h"
330d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include "op_interface.h"
340d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#include "op_cpu_type.h"
350d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
360d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#undef min
370d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#undef max
380d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
390d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek#define streq(a, b) (!strcmp((a), (b)))
400d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
410d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek/* per-cpu dynamic data */
420d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenekstruct _oprof_data {
430d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* eviction buffer */
440d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	struct op_sample * buffer;
450d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* nr. in buffer */
460d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	uint buf_size;
470d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* we try to wakeup when nextbuf >= buf_watermark */
480d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	uint buf_watermark;
4913493ea1583f39d62a66e2b2a0802f08d8ec32caTed Kremenek	/* next in buffer (atomic) */
5013493ea1583f39d62a66e2b2a0802f08d8ec32caTed Kremenek	uint nextbuf;
510d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* number of IRQs for this CPU */
520d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	uint nr_irq;
53d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner	/* buffer overflow cumulated size */
540d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	uint nr_buffer_overflow;
55d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner	/* reset counter values */
560d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	uint ctr_count[OP_MAX_COUNTERS];
57077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner};
580d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
590d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek/* reflect /proc/sys/dev/oprofile/#counter files */
60e4773eb6398acb03ad692050cb84b53ca1750b5bTed Kremenekstruct oprof_counter {
61e4773eb6398acb03ad692050cb84b53ca1750b5bTed Kremenek	int count;
62d9d22dd9c94618490dbffb0e2caf222530ca39d3Chris Lattner	int enabled;
63e4773eb6398acb03ad692050cb84b53ca1750b5bTed Kremenek	int event;
640d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int kernel;
650d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int user;
660d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int unit_mask;
670d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek};
6813493ea1583f39d62a66e2b2a0802f08d8ec32caTed Kremenek
6957202071e477530e9348bc76671ee369b2399b92Ted Kremenek/* reflect /proc/sys/dev/oprofile files */
700d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenekstruct oprof_sysctl {
710d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* nr. in eviction buffser */
720d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int buf_size;
730d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* sysctl dump */
740d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int dump;
750d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* dump and stop */
760d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int dump_stop;
770d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* nr. in note buffer */
780d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int note_size;
790d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* nr. interrupts occured */
800d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int nr_interrupts;
810d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* the cpu core type: CPU_PPRO, CPU_PII ... */
820d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int cpu_type;
830d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* nr note buffer overflow */
840d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int nr_note_buffer_overflow;
850d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* nr buffer overflow */
860d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int nr_buffer_overflow;
870d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* counter setup */
880d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	struct oprof_counter ctr[OP_MAX_COUNTERS];
890d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek};
900d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek
910d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek/**
920d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * A interrupt handler must implement these routines.
930d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * When an interrupt arrives, it must eventually call
940d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek * op_do_profile().
950d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek */
960d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenekstruct op_int_operations {
970d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* initialise the interrupt handler on module load.
980d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	 * On failure deinit handler is not called so all resources
990d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	 * allocated by init() must be freed before returning an error code
1000d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	 * (or 0 on success)
1010d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	 */
1020d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int (*init)(void);
1030d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* deinitialise on module unload */
1040d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	void (*deinit)(void);
1050d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* add any handler-specific sysctls at the position given by @next. Return 0 on success */
1060d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int (*add_sysctls)(ctl_table * next);
1070d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* remove handler-specific sysctls */
1080d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	void (*remove_sysctls)(ctl_table * next);
1090d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* check given profiling parameters are correct. Return 0 on success */
1100d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int (*check_params)(void);
1110d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* setup the handler from profiling parameters. Return 0 on success */
1120d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	int (*setup)(void);
1130d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* start profiling on all CPUs */
1140d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	void (*start)(void);
1150d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* stop profiling on all CPUs */
1160d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	void (*stop)(void);
1170d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* start profiling on the given CPU */
1180d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	void (*start_cpu)(uint);
1190d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	/* stop profiling on the given CPU */
1200d8019e55c0f465bafc11b04aed691de95b9131dTed Kremenek	void (*stop_cpu)(uint);
121};
122
123/* maximum depth of dname trees - this is just a page */
124#define DNAME_STACK_MAX 1024
125
126/* oprof_start() copy here the sysctl settable parameters */
127extern struct oprof_sysctl sysctl;
128
129int oprof_init(void);
130void oprof_exit(void);
131unsigned long is_map_ready(void);
132int oprof_hash_map_open(void);
133int oprof_hash_map_release(void);
134int oprof_hash_map_mmap(struct file * file, struct vm_area_struct * vma);
135int oprof_map_open(void);
136int oprof_map_release(void);
137int oprof_init_hashmap(void);
138void oprof_free_hashmap(void);
139
140/* used by interrupt handlers if the underlined harware doesn't support
141 * performance counter */
142extern struct op_int_operations op_rtc_ops;
143
144void op_do_profile(uint cpu, long eip, long irq_enabled, int ctr);
145extern struct _oprof_data oprof_data[NR_CPUS];
146extern struct oprof_sysctl sysctl_parms;
147extern int lproc_dointvec(ctl_table * table, int write, struct file * filp, void * buffer, size_t * lenp);
148
149/* functionality provided by the architecture dependent file */
150/* must return OP_RTC if the hardware doesn't support something like
151 * perf counter */
152op_cpu get_cpu_type(void);
153/* return an interface pointer, this function is called only if get_cpu_type
154 * doesn't return OP_RTC */
155struct op_int_operations const * op_int_interface(void);
156/* intercept the needed syscall */
157void op_intercept_syscalls(void);
158void op_restore_syscalls(void);
159void op_save_syscalls(void);
160
161#endif /* OPROFILE_H */
162