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