]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - include/linux/tegra_profiler.h
misc: tegra-profiler: fix broken backtraces
[sojka/nv-tegra/linux-3.10.git] / include / linux / tegra_profiler.h
1 /*
2  * include/linux/tegra_profiler.h
3  *
4  * Copyright (c) 2015, 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   33
23 #define QUADD_IO_VERSION        18
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 #define QUADD_IO_VERSION_ARCH_TIMER_OPT         13
34 #define QUADD_IO_VERSION_DATA_MMAP              14
35 #define QUADD_IO_VERSION_BT_LOWER_BOUND         15
36 #define QUADD_IO_VERSION_STACK_OFFSET           16
37 #define QUADD_IO_VERSION_SECTIONS_INFO          17
38 #define QUADD_IO_VERSION_UNW_METHODS_OPT        18
39
40 #define QUADD_SAMPLE_VERSION_THUMB_MODE_FLAG    17
41 #define QUADD_SAMPLE_VERSION_GROUP_SAMPLES      18
42 #define QUADD_SAMPLE_VERSION_THREAD_STATE_FLD   19
43 #define QUADD_SAMPLE_VERSION_BT_UNWIND_TABLES   22
44 #define QUADD_SAMPLE_VERSION_SUPPORT_IP64       23
45 #define QUADD_SAMPLE_VERSION_SPECIAL_MMAP       24
46 #define QUADD_SAMPLE_VERSION_UNWIND_MIXED       25
47 #define QUADD_SAMPLE_VERSION_UNW_ENTRY_TYPE     26
48 #define QUADD_SAMPLE_VERSION_USE_ARCH_TIMER     27
49 #define QUADD_SAMPLE_VERSION_SCHED_SAMPLES      28
50 #define QUADD_SAMPLE_VERSION_HDR_UNW_METHOD     29
51 #define QUADD_SAMPLE_VERSION_HDR_ARCH_TIMER     30
52 #define QUADD_SAMPLE_VERSION_STACK_OFFSET       31
53 #define QUADD_SAMPLE_VERSION_SCHED_TASK_STATE   32
54 #define QUADD_SAMPLE_VERSION_URCS               33
55
56 #define QUADD_MMAP_HEADER_VERSION               1
57
58 #define QUADD_MAX_COUNTERS      32
59 #define QUADD_MAX_PROCESS       64
60
61 #define QUADD_DEVICE_NAME       "quadd"
62 #define QUADD_AUTH_DEVICE_NAME  "quadd_auth"
63
64 #define QUADD_MOD_DEVICE_NAME           "quadd_mod"
65 #define QUADD_MOD_AUTH_DEVICE_NAME      "quadd_mod_auth"
66
67 #define QUADD_IOCTL     100
68
69 /*
70  * Setup params (profiling frequency, etc.)
71  */
72 #define IOCTL_SETUP _IOW(QUADD_IOCTL, 0, struct quadd_parameters)
73
74 /*
75  * Start profiling.
76  */
77 #define IOCTL_START _IO(QUADD_IOCTL, 1)
78
79 /*
80  * Stop profiling.
81  */
82 #define IOCTL_STOP _IO(QUADD_IOCTL, 2)
83
84 /*
85  * Getting capabilities
86  */
87 #define IOCTL_GET_CAP _IOR(QUADD_IOCTL, 3, struct quadd_comm_cap)
88
89 /*
90  * Getting state of module
91  */
92 #define IOCTL_GET_STATE _IOR(QUADD_IOCTL, 4, struct quadd_module_state)
93
94 /*
95  * Getting version of module
96  */
97 #define IOCTL_GET_VERSION _IOR(QUADD_IOCTL, 5, struct quadd_module_version)
98
99 /*
100  * Send exception-handling tables info
101  * This ioctl is obsolete
102  */
103 /*#define IOCTL_SET_EXTAB _IOW(QUADD_IOCTL, 6, struct quadd_extables)*/
104
105 /*
106  * Send ring buffer mmap info
107  */
108 #define IOCTL_SET_MMAP_RB _IOW(QUADD_IOCTL, 7, struct quadd_mmap_rb_info)
109
110 /*
111  * Send sections info
112  */
113 #define IOCTL_SET_SECTIONS_INFO _IOW(QUADD_IOCTL, 8, struct quadd_sections)
114
115 #define QUADD_CPUMODE_TEGRA_POWER_CLUSTER_LP    (1 << 29)       /* LP CPU */
116 #define QUADD_CPUMODE_THUMB                     (1 << 30)       /* thumb mode */
117
118 enum quadd_events_id {
119         QUADD_EVENT_TYPE_CPU_CYCLES = 0,
120
121         QUADD_EVENT_TYPE_INSTRUCTIONS,
122         QUADD_EVENT_TYPE_BRANCH_INSTRUCTIONS,
123         QUADD_EVENT_TYPE_BRANCH_MISSES,
124         QUADD_EVENT_TYPE_BUS_CYCLES,
125
126         QUADD_EVENT_TYPE_L1_DCACHE_READ_MISSES,
127         QUADD_EVENT_TYPE_L1_DCACHE_WRITE_MISSES,
128         QUADD_EVENT_TYPE_L1_ICACHE_MISSES,
129
130         QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES,
131         QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES,
132         QUADD_EVENT_TYPE_L2_ICACHE_MISSES,
133
134         QUADD_EVENT_TYPE_MAX,
135 };
136
137 struct event_data {
138         int event_source;
139         int event_id;
140
141         u32 val;
142         u32 prev_val;
143 };
144
145 enum quadd_record_type {
146         QUADD_RECORD_TYPE_SAMPLE = 1,
147         QUADD_RECORD_TYPE_MMAP,
148         QUADD_RECORD_TYPE_MA,
149         QUADD_RECORD_TYPE_COMM,
150         QUADD_RECORD_TYPE_DEBUG,
151         QUADD_RECORD_TYPE_HEADER,
152         QUADD_RECORD_TYPE_POWER_RATE,
153         QUADD_RECORD_TYPE_ADDITIONAL_SAMPLE,
154         QUADD_RECORD_TYPE_SCHED,
155 };
156
157 enum quadd_event_source {
158         QUADD_EVENT_SOURCE_PMU = 1,
159         QUADD_EVENT_SOURCE_PL310,
160 };
161
162 enum quadd_cpu_mode {
163         QUADD_CPU_MODE_KERNEL = 1,
164         QUADD_CPU_MODE_USER,
165         QUADD_CPU_MODE_NONE,
166 };
167
168 #pragma pack(push, 1)
169
170 #define QUADD_SAMPLE_RES_URCS_ENABLED   (1 << 0)
171
172 #define QUADD_SAMPLE_URC_MASK           0xff
173
174 #define QUADD_SAMPLE_URC_SHIFT_FP       0
175 #define QUADD_SAMPLE_URC_SHIFT_UT       (1 * 8)
176 #define QUADD_SAMPLE_URC_SHIFT_DWARF    (2 * 8)
177
178 enum {
179         QUADD_URC_SUCCESS = 0,
180         QUADD_URC_FAILURE,
181         QUADD_URC_IDX_NOT_FOUND,
182         QUADD_URC_TBL_NOT_EXIST,
183         QUADD_URC_EACCESS,
184         QUADD_URC_TBL_IS_CORRUPT,
185         QUADD_URC_CANTUNWIND,
186         QUADD_URC_UNHANDLED_INSTRUCTION,
187         QUADD_URC_REFUSE_TO_UNWIND,
188         QUADD_URC_SP_INCORRECT,
189         QUADD_URC_SPARE_ENCODING,
190         QUADD_URC_UNSUPPORTED_PR,
191         QUADD_URC_PC_INCORRECT,
192         QUADD_URC_LEVEL_TOO_DEEP,
193         QUADD_URC_FP_INCORRECT,
194         QUADD_URC_NONE,
195         QUADD_URC_UNWIND_MISMATCH,
196         QUADD_URC_TBL_LINK_INCORRECT,
197         QUADD_URC_MAX,
198 };
199
200 #define QUADD_SED_IP64                  (1 << 0)
201
202 #define QUADD_SED_STACK_OFFSET_SHIFT    1
203 #define QUADD_SED_STACK_OFFSET_MASK     (0xffff << QUADD_SED_STACK_OFFSET_SHIFT)
204
205 enum {
206         QUADD_UNW_TYPE_FP = 0,
207         QUADD_UNW_TYPE_UT,
208         QUADD_UNW_TYPE_LR_FP,
209         QUADD_UNW_TYPE_LR_UT,
210         QUADD_UNW_TYPE_KCTX,
211         QUADD_UNW_TYPE_DWARF_EH,
212         QUADD_UNW_TYPE_DWARF_DF,
213 };
214
215 struct quadd_sample_data {
216         u64 ip;
217         u32 pid;
218         u64 time;
219
220         u16     cpu:6,
221                 user_mode:1,
222                 lp_mode:1,
223                 thumb_mode:1,
224                 state:1,
225                 in_interrupt:1,
226                 reserved:5;
227
228         u8 callchain_nr;
229         u32 events_flags;
230 };
231
232 #define QUADD_MMAP_ED_IS_FILE_EXISTS    (1 << 0)
233
234 struct quadd_mmap_data {
235         u32 pid;
236
237         u64 addr;
238         u64 len;
239
240         u8 user_mode:1;
241         u16 filename_length;
242 };
243
244 struct quadd_ma_data {
245         u32 pid;
246         u64 time;
247
248         u32 vm_size;
249         u32 rss_size;
250 };
251
252 struct quadd_power_rate_data {
253         u64 time;
254
255         u8 nr_cpus;
256
257         u32 gpu;
258         u32 emc;
259 };
260
261 struct quadd_additional_sample {
262         u8 type;
263
264         u32 values[6];
265         u16 extra_length;
266 };
267
268 enum {
269         QUADD_SCHED_IDX_TASK_STATE = 0,
270         QUADD_SCHED_IDX_RESERVED,
271 };
272
273 struct quadd_sched_data {
274         u32 pid;
275         u64 time;
276
277         u32     cpu:6,
278                 lp_mode:1,
279                 sched_in:1,
280                 reserved:24;
281
282         u32 data[2];
283 };
284
285 enum {
286         QM_DEBUG_SAMPLE_TYPE_SCHED_IN = 1,
287         QM_DEBUG_SAMPLE_TYPE_SCHED_OUT,
288
289         QM_DEBUG_SAMPLE_TYPE_TIMER_HANDLE,
290         QM_DEBUG_SAMPLE_TYPE_TIMER_START,
291         QM_DEBUG_SAMPLE_TYPE_TIMER_CANCEL,
292         QM_DEBUG_SAMPLE_TYPE_TIMER_FORWARD,
293
294         QM_DEBUG_SAMPLE_TYPE_READ_COUNTER,
295
296         QM_DEBUG_SAMPLE_TYPE_SOURCE_START,
297         QM_DEBUG_SAMPLE_TYPE_SOURCE_STOP,
298 };
299
300 struct quadd_debug_data {
301         u8 type;
302
303         u32 pid;
304         u64 time;
305
306         u16     cpu:6,
307                 user_mode:1,
308                 lp_mode:1,
309                 thumb_mode:1,
310                 reserved:7;
311
312         u32 extra_value[2];
313         u16 extra_length;
314 };
315
316 #define QUADD_HEADER_MAGIC      0x1122
317
318 #define QUADD_HDR_BT_FP                 (1 << 0)
319 #define QUADD_HDR_BT_UT                 (1 << 1)
320 #define QUADD_HDR_BT_UT_CE              (1 << 2)
321 #define QUADD_HDR_USE_ARCH_TIMER        (1 << 3)
322 #define QUADD_HDR_STACK_OFFSET          (1 << 4)
323 #define QUADD_HDR_BT_DWARF              (1 << 5)
324
325 struct quadd_header_data {
326         u16 magic;
327         u16 version;
328
329         u32     backtrace:1,
330                 use_freq:1,
331                 system_wide:1,
332                 power_rate:1,
333                 debug_samples:1,
334                 get_mmap:1,
335                 reserved:26;    /* reserved fields for future extensions */
336
337         u32 freq;
338         u16 ma_freq;
339         u16 power_rate_freq;
340
341         u8 nr_events;
342         u16 extra_length;
343 };
344
345 struct quadd_record_data {
346         u8 record_type;
347
348         /* sample: it should be the biggest size */
349         union {
350                 struct quadd_sample_data        sample;
351                 struct quadd_mmap_data          mmap;
352                 struct quadd_ma_data            ma;
353                 struct quadd_debug_data         debug;
354                 struct quadd_header_data        hdr;
355                 struct quadd_power_rate_data    power_rate;
356                 struct quadd_sched_data         sched;
357                 struct quadd_additional_sample  additional_sample;
358         };
359 } __aligned(4);
360
361 #pragma pack(4)
362
363 #define QUADD_MAX_PACKAGE_NAME  320
364
365 enum {
366         QUADD_PARAM_IDX_SIZE_OF_RB      = 0,
367         QUADD_PARAM_IDX_EXTRA           = 1,
368         QUADD_PARAM_IDX_BT_LOWER_BOUND  = 2,
369 };
370
371 #define QUADD_PARAM_EXTRA_GET_MMAP              (1 << 0)
372 #define QUADD_PARAM_EXTRA_BT_FP                 (1 << 1)
373 #define QUADD_PARAM_EXTRA_BT_UT                 (1 << 2)
374 #define QUADD_PARAM_EXTRA_BT_MIXED              (1 << 3)
375 #define QUADD_PARAM_EXTRA_USE_ARCH_TIMER        (1 << 4)
376 #define QUADD_PARAM_EXTRA_STACK_OFFSET          (1 << 5)
377 #define QUADD_PARAM_EXTRA_BT_UT_CE              (1 << 6)
378 #define QUADD_PARAM_EXTRA_BT_DWARF              (1 << 7)
379
380 struct quadd_parameters {
381         u32 freq;
382         u32 ma_freq;
383         u32 power_rate_freq;
384
385         u64     backtrace:1,
386                 use_freq:1,
387                 system_wide:1,
388                 debug_samples:1;
389
390         u32 pids[QUADD_MAX_PROCESS];
391         u32 nr_pids;
392
393         u8 package_name[QUADD_MAX_PACKAGE_NAME];
394
395         u32 events[QUADD_MAX_COUNTERS];
396         u32 nr_events;
397
398         u32 reserved[16];       /* reserved fields for future extensions */
399 };
400
401 struct quadd_events_cap {
402         u32     cpu_cycles:1,
403                 instructions:1,
404                 branch_instructions:1,
405                 branch_misses:1,
406                 bus_cycles:1,
407
408                 l1_dcache_read_misses:1,
409                 l1_dcache_write_misses:1,
410                 l1_icache_misses:1,
411
412                 l2_dcache_read_misses:1,
413                 l2_dcache_write_misses:1,
414                 l2_icache_misses:1;
415 };
416
417 enum {
418         QUADD_COMM_CAP_IDX_EXTRA = 0,
419 };
420
421 #define QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX      (1 << 0)
422 #define QUADD_COMM_CAP_EXTRA_GET_MMAP           (1 << 1)
423 #define QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES      (1 << 2)
424 #define QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES   (1 << 3)
425 #define QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64    (1 << 4)
426 #define QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP  (1 << 5)
427 #define QUADD_COMM_CAP_EXTRA_UNWIND_MIXED       (1 << 6)
428 #define QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE     (1 << 7)
429 #define QUADD_COMM_CAP_EXTRA_ARCH_TIMER         (1 << 8)
430 #define QUADD_COMM_CAP_EXTRA_RB_MMAP_OP         (1 << 9)
431
432 struct quadd_comm_cap {
433         u32     pmu:1,
434                 power_rate:1,
435                 l2_cache:1,
436                 l2_multiple_events:1,
437                 tegra_lp_cluster:1,
438                 blocked_read:1;
439
440         struct quadd_events_cap events_cap;
441
442         u32 reserved[16];       /* reserved fields for future extensions */
443 };
444
445 enum {
446         QUADD_MOD_STATE_IDX_RB_MAX_FILL_COUNT = 0,
447         QUADD_MOD_STATE_IDX_STATUS,
448 };
449
450 #define QUADD_MOD_STATE_STATUS_IS_ACTIVE        (1 << 0)
451 #define QUADD_MOD_STATE_STATUS_IS_AUTH_OPEN     (1 << 1)
452
453 struct quadd_module_state {
454         u64 nr_all_samples;
455         u64 nr_skipped_samples;
456
457         u32 buffer_size;
458         u32 buffer_fill_size;
459
460         u32 reserved[16];       /* reserved fields for future extensions */
461 };
462
463 struct quadd_module_version {
464         u8 branch[32];
465         u8 version[16];
466
467         u32 samples_version;
468         u32 io_version;
469
470         u32 reserved[4];        /* reserved fields for future extensions */
471 };
472
473 enum {
474         QUADD_SEC_TYPE_EXTAB = 0,
475         QUADD_SEC_TYPE_EXIDX,
476
477         QUADD_SEC_TYPE_EH_FRAME,
478         QUADD_SEC_TYPE_EH_FRAME_HDR,
479
480         QUADD_SEC_TYPE_DEBUG_FRAME,
481         QUADD_SEC_TYPE_DEBUG_FRAME_HDR,
482
483         QUADD_SEC_TYPE_MAX,
484 };
485
486 struct quadd_sec_info {
487         u64 addr;
488         u64 length;
489
490         u64 mmap_offset;
491 };
492
493 struct quadd_sections {
494         u64 vm_start;
495         u64 vm_end;
496
497         struct quadd_sec_info sec[QUADD_SEC_TYPE_MAX];
498
499         u64 user_mmap_start;
500
501         u64 reserved[4];        /* reserved fields for future extensions */
502 };
503
504 struct quadd_mmap_rb_info {
505         u32 cpu_id;
506
507         u64 vm_start;
508         u64 vm_end;
509
510         u32 reserved[4];        /* reserved fields for future extensions */
511 };
512
513 #define QUADD_MMAP_HEADER_MAGIC         0x33445566
514
515 struct quadd_mmap_header {
516         u32 magic;
517         u32 version;
518
519         u32 cpu_id;
520         u32 samples_version;
521
522         u32 reserved[4];        /* reserved fields for future extensions */
523 } __aligned(8);
524
525 enum {
526         QUADD_RB_STATE_NONE = 0,
527         QUADD_RB_STATE_ACTIVE,
528         QUADD_RB_STATE_STOPPED,
529 };
530
531 struct quadd_ring_buffer_hdr {
532         u32 state;
533         u32 size;
534
535         u32 pos_read;
536         u32 pos_write;
537
538         u32 max_fill_count;
539         u32 skipped_samples;
540
541         u32 reserved[4];        /* reserved fields for future extensions */
542 } __aligned(8);
543
544 #pragma pack(pop)
545
546 #ifdef __KERNEL__
547
548 struct task_struct;
549 struct vm_area_struct;
550
551 #ifdef CONFIG_TEGRA_PROFILER
552 extern void __quadd_task_sched_in(struct task_struct *prev,
553                                   struct task_struct *task);
554 extern void __quadd_task_sched_out(struct task_struct *prev,
555                                    struct task_struct *next);
556
557 extern void __quadd_event_mmap(struct vm_area_struct *vma);
558
559 static inline void quadd_task_sched_in(struct task_struct *prev,
560                                        struct task_struct *task)
561 {
562         __quadd_task_sched_in(prev, task);
563 }
564
565 static inline void quadd_task_sched_out(struct task_struct *prev,
566                                         struct task_struct *next)
567 {
568         __quadd_task_sched_out(prev, next);
569 }
570
571 static inline void quadd_event_mmap(struct vm_area_struct *vma)
572 {
573         __quadd_event_mmap(vma);
574 }
575
576 #else   /* CONFIG_TEGRA_PROFILER */
577
578 static inline void quadd_task_sched_in(struct task_struct *prev,
579                                        struct task_struct *task)
580 {
581 }
582
583 static inline void quadd_task_sched_out(struct task_struct *prev,
584                                         struct task_struct *next)
585 {
586 }
587
588 static inline void quadd_event_mmap(struct vm_area_struct *vma)
589 {
590 }
591
592 #endif  /* CONFIG_TEGRA_PROFILER */
593
594 #endif  /* __KERNEL__ */
595
596 #endif  /* __TEGRA_PROFILER_H */