ARM: tegra: Add Tegra Profiler
[linux-2.6.git] / drivers / misc / tegra-profiler / debug.c
1 /*
2  * drivers/misc/tegra-profiler/debug.c
3  *
4  * Copyright (c) 2013, 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 #include <linux/module.h>
18 #include <asm/irq_regs.h>
19
20 #include <linux/tegra_profiler.h>
21
22 #include "debug.h"
23 #include "hrt.h"
24 #include "tegra.h"
25
26 #ifdef QM_DEBUG_SAMPLES_ENABLE
27
28 static inline void
29 init_sample(struct quadd_record_data *record, struct pt_regs *regs)
30 {
31         struct quadd_debug_data *s = &record->debug;
32
33         record->magic = QUADD_RECORD_MAGIC;
34         record->record_type = QUADD_RECORD_TYPE_DEBUG;
35
36         if (!regs)
37                 regs = get_irq_regs();
38
39         if (!regs)
40                 record->cpu_mode = QUADD_CPU_MODE_NONE;
41         else
42                 record->cpu_mode = user_mode(regs) ?
43                         QUADD_CPU_MODE_USER : QUADD_CPU_MODE_KERNEL;
44
45         s->cpu = quadd_get_processor_id();
46         s->pid = 0;
47         s->time = quadd_get_time();
48         s->timer_period = 0;
49
50         s->extra_value1 = 0;
51         s->extra_value2 = 0;
52         s->extra_value3 = 0;
53 }
54
55 void qm_debug_handler_sample(struct pt_regs *regs)
56 {
57         struct quadd_record_data record;
58         struct quadd_debug_data *s = &record.debug;
59
60         init_sample(&record, regs);
61
62         s->type = QM_DEBUG_SAMPLE_TYPE_TIMER_HANDLE;
63
64         quadd_put_sample(&record, NULL, 0);
65 }
66
67 void qm_debug_timer_forward(struct pt_regs *regs, u64 period)
68 {
69         struct quadd_record_data record;
70         struct quadd_debug_data *s = &record.debug;
71
72         init_sample(&record, regs);
73
74         s->type = QM_DEBUG_SAMPLE_TYPE_TIMER_FORWARD;
75         s->timer_period = period;
76
77         quadd_put_sample(&record, NULL, 0);
78 }
79
80 void qm_debug_timer_start(struct pt_regs *regs, u64 period)
81 {
82         struct quadd_record_data record;
83         struct quadd_debug_data *s = &record.debug;
84
85         init_sample(&record, regs);
86
87         s->type = QM_DEBUG_SAMPLE_TYPE_TIMER_START;
88         s->timer_period = period;
89
90         quadd_put_sample(&record, NULL, 0);
91 }
92
93 void qm_debug_timer_cancel(void)
94 {
95         struct quadd_record_data record;
96         struct quadd_debug_data *s = &record.debug;
97
98         init_sample(&record, NULL);
99
100         s->type = QM_DEBUG_SAMPLE_TYPE_TIMER_CANCEL;
101
102         quadd_put_sample(&record, NULL, 0);
103 }
104
105 void
106 qm_debug_task_sched_in(pid_t prev_pid, pid_t current_pid, int prev_nr_active)
107 {
108         struct quadd_record_data record;
109         struct quadd_debug_data *s = &record.debug;
110
111         init_sample(&record, NULL);
112
113         s->type = QM_DEBUG_SAMPLE_TYPE_SCHED_IN;
114
115         s->extra_value1 = prev_pid;
116         s->extra_value2 = current_pid;
117         s->extra_value3 = prev_nr_active;
118
119         quadd_put_sample(&record, NULL, 0);
120 }
121
122 void qm_debug_read_counter(int event_id, u32 prev_val, u32 val)
123 {
124         struct quadd_record_data record;
125         struct quadd_debug_data *s = &record.debug;
126
127         init_sample(&record, NULL);
128
129         s->type = QM_DEBUG_SAMPLE_TYPE_READ_COUNTER;
130
131         s->extra_value1 = event_id;
132         s->extra_value2 = prev_val;
133         s->extra_value3 = val;
134
135         quadd_put_sample(&record, NULL, 0);
136 }
137
138 void qm_debug_start_source(int source_type)
139 {
140         struct quadd_record_data record;
141         struct quadd_debug_data *s = &record.debug;
142
143         init_sample(&record, NULL);
144
145         s->type = QM_DEBUG_SAMPLE_TYPE_SOURCE_START;
146         s->extra_value1 = source_type;
147
148         quadd_put_sample(&record, NULL, 0);
149 }
150
151 void qm_debug_stop_source(int source_type)
152 {
153         struct quadd_record_data record;
154         struct quadd_debug_data *s = &record.debug;
155
156         init_sample(&record, NULL);
157
158         s->type = QM_DEBUG_SAMPLE_TYPE_SOURCE_STOP;
159         s->extra_value1 = source_type;
160
161         quadd_put_sample(&record, NULL, 0);
162 }
163
164 #endif  /* QM_DEBUG_SAMPLES_ENABLE */