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