x86: de-assembler-ize asm/desc.h
[linux-2.6] / arch / x86 / include / asm / ds.h
1 /*
2  * Debug Store (DS) support
3  *
4  * This provides a low-level interface to the hardware's Debug Store
5  * feature that is used for branch trace store (BTS) and
6  * precise-event based sampling (PEBS).
7  *
8  * It manages:
9  * - DS and BTS hardware configuration
10  * - buffer overflow handling (to be done)
11  * - buffer access
12  *
13  * It does not do:
14  * - security checking (is the caller allowed to trace the task)
15  * - buffer allocation (memory accounting)
16  *
17  *
18  * Copyright (C) 2007-2009 Intel Corporation.
19  * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
20  */
21
22 #ifndef _ASM_X86_DS_H
23 #define _ASM_X86_DS_H
24
25
26 #include <linux/types.h>
27 #include <linux/init.h>
28 #include <linux/err.h>
29
30
31 #ifdef CONFIG_X86_DS
32
33 struct task_struct;
34 struct ds_context;
35 struct ds_tracer;
36 struct bts_tracer;
37 struct pebs_tracer;
38
39 typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
40 typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
41
42
43 /*
44  * A list of features plus corresponding macros to talk about them in
45  * the ds_request function's flags parameter.
46  *
47  * We use the enum to index an array of corresponding control bits;
48  * we use the macro to index a flags bit-vector.
49  */
50 enum ds_feature {
51         dsf_bts = 0,
52         dsf_bts_kernel,
53 #define BTS_KERNEL (1 << dsf_bts_kernel)
54         /* trace kernel-mode branches */
55
56         dsf_bts_user,
57 #define BTS_USER (1 << dsf_bts_user)
58         /* trace user-mode branches */
59
60         dsf_bts_overflow,
61         dsf_bts_max,
62         dsf_pebs = dsf_bts_max,
63
64         dsf_pebs_max,
65         dsf_ctl_max = dsf_pebs_max,
66         dsf_bts_timestamps = dsf_ctl_max,
67 #define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
68         /* add timestamps into BTS trace */
69
70 #define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
71 };
72
73
74 /*
75  * Request BTS or PEBS
76  *
77  * Due to alignement constraints, the actual buffer may be slightly
78  * smaller than the requested or provided buffer.
79  *
80  * Returns a pointer to a tracer structure on success, or
81  * ERR_PTR(errcode) on failure.
82  *
83  * The interrupt threshold is independent from the overflow callback
84  * to allow users to use their own overflow interrupt handling mechanism.
85  *
86  * The function might sleep.
87  *
88  * task: the task to request recording for
89  * cpu:  the cpu to request recording for
90  * base: the base pointer for the (non-pageable) buffer;
91  * size: the size of the provided buffer in bytes
92  * ovfl: pointer to a function to be called on buffer overflow;
93  *       NULL if cyclic buffer requested
94  * th: the interrupt threshold in records from the end of the buffer;
95  *     -1 if no interrupt threshold is requested.
96  * flags: a bit-mask of the above flags
97  */
98 extern struct bts_tracer *ds_request_bts_task(struct task_struct *task,
99                                               void *base, size_t size,
100                                               bts_ovfl_callback_t ovfl,
101                                               size_t th, unsigned int flags);
102 extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
103                                              bts_ovfl_callback_t ovfl,
104                                              size_t th, unsigned int flags);
105 extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
106                                                 void *base, size_t size,
107                                                 pebs_ovfl_callback_t ovfl,
108                                                 size_t th, unsigned int flags);
109 extern struct pebs_tracer *ds_request_pebs_cpu(int cpu,
110                                                void *base, size_t size,
111                                                pebs_ovfl_callback_t ovfl,
112                                                size_t th, unsigned int flags);
113
114 /*
115  * Release BTS or PEBS resources
116  * Suspend and resume BTS or PEBS tracing
117  *
118  * Must be called with irq's enabled.
119  *
120  * tracer: the tracer handle returned from ds_request_~()
121  */
122 extern void ds_release_bts(struct bts_tracer *tracer);
123 extern void ds_suspend_bts(struct bts_tracer *tracer);
124 extern void ds_resume_bts(struct bts_tracer *tracer);
125 extern void ds_release_pebs(struct pebs_tracer *tracer);
126 extern void ds_suspend_pebs(struct pebs_tracer *tracer);
127 extern void ds_resume_pebs(struct pebs_tracer *tracer);
128
129 /*
130  * Release BTS or PEBS resources
131  * Suspend and resume BTS or PEBS tracing
132  *
133  * Cpu tracers must call this on the traced cpu.
134  * Task tracers must call ds_release_~_noirq() for themselves.
135  *
136  * May be called with irq's disabled.
137  *
138  * Returns 0 if successful;
139  * -EPERM if the cpu tracer does not trace the current cpu.
140  * -EPERM if the task tracer does not trace itself.
141  *
142  * tracer: the tracer handle returned from ds_request_~()
143  */
144 extern int ds_release_bts_noirq(struct bts_tracer *tracer);
145 extern int ds_suspend_bts_noirq(struct bts_tracer *tracer);
146 extern int ds_resume_bts_noirq(struct bts_tracer *tracer);
147 extern int ds_release_pebs_noirq(struct pebs_tracer *tracer);
148 extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer);
149 extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer);
150
151
152 /*
153  * The raw DS buffer state as it is used for BTS and PEBS recording.
154  *
155  * This is the low-level, arch-dependent interface for working
156  * directly on the raw trace data.
157  */
158 struct ds_trace {
159         /* the number of bts/pebs records */
160         size_t n;
161         /* the size of a bts/pebs record in bytes */
162         size_t size;
163         /* pointers into the raw buffer:
164            - to the first entry */
165         void *begin;
166         /* - one beyond the last entry */
167         void *end;
168         /* - one beyond the newest entry */
169         void *top;
170         /* - the interrupt threshold */
171         void *ith;
172         /* flags given on ds_request() */
173         unsigned int flags;
174 };
175
176 /*
177  * An arch-independent view on branch trace data.
178  */
179 enum bts_qualifier {
180         bts_invalid,
181 #define BTS_INVALID bts_invalid
182
183         bts_branch,
184 #define BTS_BRANCH bts_branch
185
186         bts_task_arrives,
187 #define BTS_TASK_ARRIVES bts_task_arrives
188
189         bts_task_departs,
190 #define BTS_TASK_DEPARTS bts_task_departs
191
192         bts_qual_bit_size = 4,
193         bts_qual_max = (1 << bts_qual_bit_size),
194 };
195
196 struct bts_struct {
197         __u64 qualifier;
198         union {
199                 /* BTS_BRANCH */
200                 struct {
201                         __u64 from;
202                         __u64 to;
203                 } lbr;
204                 /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
205                 struct {
206                         __u64 clock;
207                         pid_t pid;
208                 } event;
209         } variant;
210 };
211
212
213 /*
214  * The BTS state.
215  *
216  * This gives access to the raw DS state and adds functions to provide
217  * an arch-independent view of the BTS data.
218  */
219 struct bts_trace {
220         struct ds_trace ds;
221
222         int (*read)(struct bts_tracer *tracer, const void *at,
223                     struct bts_struct *out);
224         int (*write)(struct bts_tracer *tracer, const struct bts_struct *in);
225 };
226
227
228 /*
229  * The PEBS state.
230  *
231  * This gives access to the raw DS state and the PEBS-specific counter
232  * reset value.
233  */
234 struct pebs_trace {
235         struct ds_trace ds;
236
237         /* the number of valid counters in the below array */
238         unsigned int counters;
239
240 #define MAX_PEBS_COUNTERS 4
241         /* the counter reset value */
242         unsigned long long counter_reset[MAX_PEBS_COUNTERS];
243 };
244
245
246 /*
247  * Read the BTS or PEBS trace.
248  *
249  * Returns a view on the trace collected for the parameter tracer.
250  *
251  * The view remains valid as long as the traced task is not running or
252  * the tracer is suspended.
253  * Writes into the trace buffer are not reflected.
254  *
255  * tracer: the tracer handle returned from ds_request_~()
256  */
257 extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer);
258 extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer);
259
260
261 /*
262  * Reset the write pointer of the BTS/PEBS buffer.
263  *
264  * Returns 0 on success; -Eerrno on error
265  *
266  * tracer: the tracer handle returned from ds_request_~()
267  */
268 extern int ds_reset_bts(struct bts_tracer *tracer);
269 extern int ds_reset_pebs(struct pebs_tracer *tracer);
270
271 /*
272  * Set the PEBS counter reset value.
273  *
274  * Returns 0 on success; -Eerrno on error
275  *
276  * tracer: the tracer handle returned from ds_request_pebs()
277  * counter: the index of the counter
278  * value: the new counter reset value
279  */
280 extern int ds_set_pebs_reset(struct pebs_tracer *tracer,
281                              unsigned int counter, u64 value);
282
283 /*
284  * Initialization
285  */
286 struct cpuinfo_x86;
287 extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
288
289 /*
290  * Context switch work
291  */
292 extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);
293
294 #else /* CONFIG_X86_DS */
295
296 struct cpuinfo_x86;
297 static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
298 static inline void ds_switch_to(struct task_struct *prev,
299                                 struct task_struct *next) {}
300
301 #endif /* CONFIG_X86_DS */
302 #endif /* _ASM_X86_DS_H */