]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - include/linux/tegra_profiler.h
misc: tegra-profiler: add unwind information
[sojka/nv-tegra/linux-3.10.git] / include / linux / tegra_profiler.h
1 /*
2  * include/linux/tegra_profiler.h
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16
17 #ifndef __TEGRA_PROFILER_H
18 #define __TEGRA_PROFILER_H
19
20 #include <linux/ioctl.h>
21
22 #define QUADD_SAMPLES_VERSION   26
23 #define QUADD_IO_VERSION        12
24
25 #define QUADD_IO_VERSION_DYNAMIC_RB             5
26 #define QUADD_IO_VERSION_RB_MAX_FILL_COUNT      6
27 #define QUADD_IO_VERSION_MOD_STATE_STATUS_FIELD 7
28 #define QUADD_IO_VERSION_BT_KERNEL_CTX          8
29 #define QUADD_IO_VERSION_GET_MMAP               9
30 #define QUADD_IO_VERSION_BT_UNWIND_TABLES       10
31 #define QUADD_IO_VERSION_UNWIND_MIXED           11
32 #define QUADD_IO_VERSION_EXTABLES_MMAP          12
33
34 #define QUADD_SAMPLE_VERSION_THUMB_MODE_FLAG    17
35 #define QUADD_SAMPLE_VERSION_GROUP_SAMPLES      18
36 #define QUADD_SAMPLE_VERSION_THREAD_STATE_FLD   19
37 #define QUADD_SAMPLE_VERSION_BT_UNWIND_TABLES   22
38 #define QUADD_SAMPLE_VERSION_SUPPORT_IP64       23
39 #define QUADD_SAMPLE_VERSION_SPECIAL_MMAP       24
40 #define QUADD_SAMPLE_VERSION_UNWIND_MIXED       25
41 #define QUADD_SAMPLE_VERSION_UNW_ENTRY_TYPE     26
42
43 #define QUADD_MAX_COUNTERS      32
44 #define QUADD_MAX_PROCESS       64
45
46 #define QUADD_DEVICE_NAME       "quadd"
47 #define QUADD_AUTH_DEVICE_NAME  "quadd_auth"
48
49 #define QUADD_MOD_DEVICE_NAME           "quadd_mod"
50 #define QUADD_MOD_AUTH_DEVICE_NAME      "quadd_mod_auth"
51
52 #define QUADD_IOCTL     100
53
54 /*
55  * Setup params (profiling frequency, etc.)
56  */
57 #define IOCTL_SETUP _IOW(QUADD_IOCTL, 0, struct quadd_parameters)
58
59 /*
60  * Start profiling.
61  */
62 #define IOCTL_START _IO(QUADD_IOCTL, 1)
63
64 /*
65  * Stop profiling.
66  */
67 #define IOCTL_STOP _IO(QUADD_IOCTL, 2)
68
69 /*
70  * Getting capabilities
71  */
72 #define IOCTL_GET_CAP _IOR(QUADD_IOCTL, 3, struct quadd_comm_cap)
73
74 /*
75  * Getting state of module
76  */
77 #define IOCTL_GET_STATE _IOR(QUADD_IOCTL, 4, struct quadd_module_state)
78
79 /*
80  * Getting version of module
81  */
82 #define IOCTL_GET_VERSION _IOR(QUADD_IOCTL, 5, struct quadd_module_version)
83
84 /*
85  * Send exception-handling tables info
86  */
87 #define IOCTL_SET_EXTAB _IOW(QUADD_IOCTL, 6, struct quadd_extables)
88
89 #define QUADD_CPUMODE_TEGRA_POWER_CLUSTER_LP    (1 << 29)       /* LP CPU */
90 #define QUADD_CPUMODE_THUMB                     (1 << 30)       /* thumb mode */
91
92 enum quadd_events_id {
93         QUADD_EVENT_TYPE_CPU_CYCLES = 0,
94
95         QUADD_EVENT_TYPE_INSTRUCTIONS,
96         QUADD_EVENT_TYPE_BRANCH_INSTRUCTIONS,
97         QUADD_EVENT_TYPE_BRANCH_MISSES,
98         QUADD_EVENT_TYPE_BUS_CYCLES,
99
100         QUADD_EVENT_TYPE_L1_DCACHE_READ_MISSES,
101         QUADD_EVENT_TYPE_L1_DCACHE_WRITE_MISSES,
102         QUADD_EVENT_TYPE_L1_ICACHE_MISSES,
103
104         QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES,
105         QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES,
106         QUADD_EVENT_TYPE_L2_ICACHE_MISSES,
107
108         QUADD_EVENT_TYPE_MAX,
109 };
110
111 struct event_data {
112         int event_source;
113         int event_id;
114
115         u32 val;
116         u32 prev_val;
117 };
118
119 enum quadd_record_type {
120         QUADD_RECORD_TYPE_SAMPLE = 1,
121         QUADD_RECORD_TYPE_MMAP,
122         QUADD_RECORD_TYPE_MA,
123         QUADD_RECORD_TYPE_COMM,
124         QUADD_RECORD_TYPE_DEBUG,
125         QUADD_RECORD_TYPE_HEADER,
126         QUADD_RECORD_TYPE_POWER_RATE,
127         QUADD_RECORD_TYPE_ADDITIONAL_SAMPLE,
128 };
129
130 enum quadd_event_source {
131         QUADD_EVENT_SOURCE_PMU = 1,
132         QUADD_EVENT_SOURCE_PL310,
133 };
134
135 enum quadd_cpu_mode {
136         QUADD_CPU_MODE_KERNEL = 1,
137         QUADD_CPU_MODE_USER,
138         QUADD_CPU_MODE_NONE,
139 };
140
141 #pragma pack(push, 1)
142
143 #define QUADD_SAMPLE_UNW_METHOD_SHIFT   0
144 #define QUADD_SAMPLE_UNW_METHOD_MASK    (1 << QUADD_SAMPLE_UNW_METHOD_SHIFT)
145
146 enum {
147         QUADD_UNW_METHOD_FP = 0,
148         QUADD_UNW_METHOD_EHT,
149         QUADD_UNW_METHOD_MIXED,
150 };
151
152 #define QUADD_SAMPLE_URC_SHIFT          1
153 #define QUADD_SAMPLE_URC_MASK           (0x0f << QUADD_SAMPLE_URC_SHIFT)
154
155 enum {
156         QUADD_URC_SUCCESS = 0,
157         QUADD_URC_FAILURE,
158         QUADD_URC_IDX_NOT_FOUND,
159         QUADD_URC_TBL_NOT_EXIST,
160         QUADD_URC_EACCESS,
161         QUADD_URC_TBL_IS_CORRUPT,
162         QUADD_URC_CANTUNWIND,
163         QUADD_URC_UNHANDLED_INSTRUCTION,
164         QUADD_URC_REFUSE_TO_UNWIND,
165         QUADD_URC_SP_INCORRECT,
166         QUADD_URC_SPARE_ENCODING,
167         QUADD_URC_UNSUPPORTED_PR,
168         QUADD_URC_PC_INCORRECT,
169         QUADD_URC_LEVEL_TOO_DEEP,
170         QUADD_URC_FP_INCORRECT,
171         QUADD_URC_MAX,
172 };
173
174 #define QUADD_SED_IP64                  (1 << 0)
175
176 #define QUADD_SED_UNW_METHOD_SHIFT      1
177 #define QUADD_SED_UNW_METHOD_MASK       (0x07 << QUADD_SED_UNW_METHOD_SHIFT)
178
179 enum {
180         QUADD_UNW_TYPE_FP = 0,
181         QUADD_UNW_TYPE_UT,
182         QUADD_UNW_TYPE_LR_FP,
183         QUADD_UNW_TYPE_LR_UT,
184         QUADD_UNW_TYPE_KCTX,
185 };
186
187 struct quadd_sample_data {
188         u64 ip;
189         u32 pid;
190         u64 time;
191
192         u16     cpu:6,
193                 user_mode:1,
194                 lp_mode:1,
195                 thumb_mode:1,
196                 state:1,
197                 in_interrupt:1,
198                 reserved:5;
199
200         u8 callchain_nr;
201         u32 events_flags;
202 };
203
204 #define QUADD_MMAP_ED_IS_FILE_EXISTS    (1 << 0)
205
206 struct quadd_mmap_data {
207         u32 pid;
208
209         u64 addr;
210         u64 len;
211
212         u8 user_mode:1;
213         u16 filename_length;
214 };
215
216 struct quadd_ma_data {
217         u32 pid;
218         u64 time;
219
220         u32 vm_size;
221         u32 rss_size;
222 };
223
224 struct quadd_power_rate_data {
225         u64 time;
226
227         u8 nr_cpus;
228
229         u32 gpu;
230         u32 emc;
231 };
232
233 struct quadd_additional_sample {
234         u8 type;
235
236         u32 values[6];
237         u16 extra_length;
238 };
239
240 enum {
241         QM_DEBUG_SAMPLE_TYPE_SCHED_IN = 1,
242         QM_DEBUG_SAMPLE_TYPE_SCHED_OUT,
243
244         QM_DEBUG_SAMPLE_TYPE_TIMER_HANDLE,
245         QM_DEBUG_SAMPLE_TYPE_TIMER_START,
246         QM_DEBUG_SAMPLE_TYPE_TIMER_CANCEL,
247         QM_DEBUG_SAMPLE_TYPE_TIMER_FORWARD,
248
249         QM_DEBUG_SAMPLE_TYPE_READ_COUNTER,
250
251         QM_DEBUG_SAMPLE_TYPE_SOURCE_START,
252         QM_DEBUG_SAMPLE_TYPE_SOURCE_STOP,
253 };
254
255 struct quadd_debug_data {
256         u8 type;
257
258         u32 pid;
259         u64 time;
260
261         u16     cpu:6,
262                 user_mode:1,
263                 lp_mode:1,
264                 thumb_mode:1,
265                 reserved:7;
266
267         u32 extra_value[2];
268         u16 extra_length;
269 };
270
271 #define QUADD_HEADER_MAGIC      0x1122
272
273 struct quadd_header_data {
274         u16 magic;
275         u16 version;
276
277         u32     backtrace:1,
278                 use_freq:1,
279                 system_wide:1,
280                 power_rate:1,
281                 debug_samples:1,
282                 get_mmap:1,
283                 reserved:26;    /* reserved fields for future extensions */
284
285         u32 freq;
286         u16 ma_freq;
287         u16 power_rate_freq;
288
289         u8 nr_events;
290         u16 extra_length;
291 };
292
293 struct quadd_record_data {
294         u8 record_type;
295
296         /* sample: it should be the biggest size */
297         union {
298                 struct quadd_sample_data        sample;
299                 struct quadd_mmap_data          mmap;
300                 struct quadd_ma_data            ma;
301                 struct quadd_debug_data         debug;
302                 struct quadd_header_data        hdr;
303                 struct quadd_power_rate_data    power_rate;
304                 struct quadd_additional_sample  additional_sample;
305         };
306 } __aligned(4);
307
308 #pragma pack(4)
309
310 #define QUADD_MAX_PACKAGE_NAME  320
311
312 enum {
313         QUADD_PARAM_IDX_SIZE_OF_RB      = 0,
314         QUADD_PARAM_IDX_EXTRA           = 1,
315 };
316
317 #define QUADD_PARAM_EXTRA_GET_MMAP              (1 << 0)
318 #define QUADD_PARAM_EXTRA_BT_FP                 (1 << 1)
319 #define QUADD_PARAM_EXTRA_BT_UNWIND_TABLES      (1 << 2)
320 #define QUADD_PARAM_EXTRA_BT_MIXED              (1 << 3)
321
322 struct quadd_parameters {
323         u32 freq;
324         u32 ma_freq;
325         u32 power_rate_freq;
326
327         u64     backtrace:1,
328                 use_freq:1,
329                 system_wide:1,
330                 debug_samples:1;
331
332         u32 pids[QUADD_MAX_PROCESS];
333         u32 nr_pids;
334
335         u8 package_name[QUADD_MAX_PACKAGE_NAME];
336
337         u32 events[QUADD_MAX_COUNTERS];
338         u32 nr_events;
339
340         u32 reserved[16];       /* reserved fields for future extensions */
341 };
342
343 struct quadd_events_cap {
344         u32     cpu_cycles:1,
345                 instructions:1,
346                 branch_instructions:1,
347                 branch_misses:1,
348                 bus_cycles:1,
349
350                 l1_dcache_read_misses:1,
351                 l1_dcache_write_misses:1,
352                 l1_icache_misses:1,
353
354                 l2_dcache_read_misses:1,
355                 l2_dcache_write_misses:1,
356                 l2_icache_misses:1;
357 };
358
359 enum {
360         QUADD_COMM_CAP_IDX_EXTRA = 0,
361 };
362
363 #define QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX      (1 << 0)
364 #define QUADD_COMM_CAP_EXTRA_GET_MMAP           (1 << 1)
365 #define QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES      (1 << 2)
366 #define QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES   (1 << 3)
367 #define QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64    (1 << 4)
368 #define QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP  (1 << 5)
369 #define QUADD_COMM_CAP_EXTRA_UNWIND_MIXED       (1 << 6)
370 #define QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE     (1 << 7)
371
372 struct quadd_comm_cap {
373         u32     pmu:1,
374                 power_rate:1,
375                 l2_cache:1,
376                 l2_multiple_events:1,
377                 tegra_lp_cluster:1,
378                 blocked_read:1;
379
380         struct quadd_events_cap events_cap;
381
382         u32 reserved[16];       /* reserved fields for future extensions */
383 };
384
385 enum {
386         QUADD_MOD_STATE_IDX_RB_MAX_FILL_COUNT = 0,
387         QUADD_MOD_STATE_IDX_STATUS,
388 };
389
390 #define QUADD_MOD_STATE_STATUS_IS_ACTIVE        (1 << 0)
391 #define QUADD_MOD_STATE_STATUS_IS_AUTH_OPEN     (1 << 1)
392
393 struct quadd_module_state {
394         u64 nr_all_samples;
395         u64 nr_skipped_samples;
396
397         u32 buffer_size;
398         u32 buffer_fill_size;
399
400         u32 reserved[16];       /* reserved fields for future extensions */
401 };
402
403 struct quadd_module_version {
404         u8 branch[32];
405         u8 version[16];
406
407         u32 samples_version;
408         u32 io_version;
409
410         u32 reserved[4];        /* reserved fields for future extensions */
411 };
412
413 struct quadd_sec_info {
414         u64 addr;
415         u64 length;
416 };
417
418 enum {
419         QUADD_EXT_IDX_EXTAB_OFFSET = 0,
420         QUADD_EXT_IDX_EXIDX_OFFSET = 1,
421         QUADD_EXT_IDX_MMAP_VM_START = 2,
422 };
423
424 struct quadd_extables {
425         u64 vm_start;
426         u64 vm_end;
427
428         struct quadd_sec_info extab;
429         struct quadd_sec_info exidx;
430
431         u32 reserved[4];        /* reserved fields for future extensions */
432 };
433
434 #pragma pack(pop)
435
436 #ifdef __KERNEL__
437
438 struct task_struct;
439 struct vm_area_struct;
440
441 #ifdef CONFIG_TEGRA_PROFILER
442 extern void __quadd_task_sched_in(struct task_struct *prev,
443                                   struct task_struct *task);
444 extern void __quadd_task_sched_out(struct task_struct *prev,
445                                    struct task_struct *next);
446
447 extern void __quadd_event_mmap(struct vm_area_struct *vma);
448
449 static inline void quadd_task_sched_in(struct task_struct *prev,
450                                        struct task_struct *task)
451 {
452         __quadd_task_sched_in(prev, task);
453 }
454
455 static inline void quadd_task_sched_out(struct task_struct *prev,
456                                         struct task_struct *next)
457 {
458         __quadd_task_sched_out(prev, next);
459 }
460
461 static inline void quadd_event_mmap(struct vm_area_struct *vma)
462 {
463         __quadd_event_mmap(vma);
464 }
465
466 #else   /* CONFIG_TEGRA_PROFILER */
467
468 static inline void quadd_task_sched_in(struct task_struct *prev,
469                                        struct task_struct *task)
470 {
471 }
472
473 static inline void quadd_task_sched_out(struct task_struct *prev,
474                                         struct task_struct *next)
475 {
476 }
477
478 static inline void quadd_event_mmap(struct vm_area_struct *vma)
479 {
480 }
481
482 #endif  /* CONFIG_TEGRA_PROFILER */
483
484 #endif  /* __KERNEL__ */
485
486 #endif  /* __TEGRA_PROFILER_H */