1 /**
2 * Copyright (C) ARM Limited 2012. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 */
10 static void marshal_summary(long long timestamp, long long uptime) {
11 int cpu = 0;
12 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_SUMMARY);
13 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, timestamp);
14 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, uptime);
15 }
17 static bool marshal_cookie_header(char* text) {
18 int cpu = smp_processor_id();
19 return buffer_check_space(cpu, BACKTRACE_BUF, strlen(text) + 2 * MAXSIZE_PACK32);
20 }
22 static void marshal_cookie(int cookie, char* text) {
23 int cpu = smp_processor_id();
24 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_COOKIE);
25 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
26 gator_buffer_write_string(cpu, BACKTRACE_BUF, text);
27 }
29 static void marshal_pid_name(int pid, char* name) {
30 unsigned long flags, cpu;
31 local_irq_save(flags);
32 cpu = smp_processor_id();
33 if (buffer_check_space(cpu, BACKTRACE_BUF, TASK_COMM_LEN + 2 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
34 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_PID_NAME);
35 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, gator_get_time());
36 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
37 gator_buffer_write_string(cpu, BACKTRACE_BUF, name);
38 }
39 local_irq_restore(flags);
40 }
42 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel) {
43 int cpu = smp_processor_id();
44 if (buffer_check_space(cpu, BACKTRACE_BUF, gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
45 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_START_BACKTRACE);
46 gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, gator_get_time());
47 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
48 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
49 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
50 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
51 return true;
52 }
54 // Check and commit; commit is set to occur once buffer is 3/4 full
55 buffer_check(cpu, BACKTRACE_BUF);
57 return false;
58 }
60 static void marshal_backtrace(int address, int cookie) {
61 int cpu = smp_processor_id();
62 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, address);
63 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
64 }
66 static void marshal_backtrace_footer(void) {
67 int cpu = smp_processor_id();
68 gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
70 // Check and commit; commit is set to occur once buffer is 3/4 full
71 buffer_check(cpu, BACKTRACE_BUF);
72 }
74 static bool marshal_event_header(void) {
75 unsigned long flags, cpu = smp_processor_id();
76 bool retval = false;
78 local_irq_save(flags);
79 if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
80 gator_buffer_write_packed_int(cpu, COUNTER_BUF, 0); // key of zero indicates a timestamp
81 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, gator_get_time());
82 retval = true;
83 }
84 local_irq_restore(flags);
86 // Check and commit; commit is set to occur once buffer is 3/4 full
87 buffer_check(cpu, COUNTER_BUF);
89 return retval;
90 }
92 static void marshal_event(int len, int* buffer) {
93 unsigned long i, flags, cpu = smp_processor_id();
95 if (len <= 0)
96 return;
98 // length must be even since all data is a (key, value) pair
99 if (len & 0x1) {
100 pr_err("gator: invalid counter data detected and discarded");
101 return;
102 }
104 // events must be written in key,value pairs
105 for (i = 0; i < len; i += 2) {
106 local_irq_save(flags);
107 if (!buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK32 * 2)) {
108 local_irq_restore(flags);
109 break;
110 }
111 gator_buffer_write_packed_int(cpu, COUNTER_BUF, buffer[i]);
112 gator_buffer_write_packed_int(cpu, COUNTER_BUF, buffer[i + 1]);
113 local_irq_restore(flags);
114 }
116 // Check and commit; commit is set to occur once buffer is 3/4 full
117 buffer_check(cpu, COUNTER_BUF);
118 }
120 static void marshal_event64(int len, long long* buffer64) {
121 unsigned long i, flags, cpu = smp_processor_id();
123 if (len <= 0)
124 return;
126 // length must be even since all data is a (key, value) pair
127 if (len & 0x1) {
128 pr_err("gator: invalid counter data detected and discarded");
129 return;
130 }
132 // events must be written in key,value pairs
133 for (i = 0; i < len; i += 2) {
134 local_irq_save(flags);
135 if (!buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 * 2)) {
136 local_irq_restore(flags);
137 break;
138 }
139 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, buffer64[i]);
140 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, buffer64[i + 1]);
141 local_irq_restore(flags);
142 }
144 // Check and commit; commit is set to occur once buffer is 3/4 full
145 buffer_check(cpu, COUNTER_BUF);
146 }
148 #if GATOR_CPU_FREQ_SUPPORT
149 static void marshal_event_single(int core, int key, int value) {
150 unsigned long flags, cpu;
152 local_irq_save(flags);
153 cpu = smp_processor_id();
154 if (buffer_check_space(cpu, COUNTER2_BUF, MAXSIZE_PACK64 + MAXSIZE_PACK32 * 3)) {
155 gator_buffer_write_packed_int64(cpu, COUNTER2_BUF, gator_get_time());
156 gator_buffer_write_packed_int(cpu, COUNTER2_BUF, core);
157 gator_buffer_write_packed_int(cpu, COUNTER2_BUF, key);
158 gator_buffer_write_packed_int(cpu, COUNTER2_BUF, value);
159 }
160 local_irq_restore(flags);
162 // Check and commit; commit is set to occur once buffer is 3/4 full
163 buffer_check(cpu, COUNTER2_BUF);
164 }
165 #endif
167 static void marshal_sched_gpu(int type, int unit, int core, int tgid, int pid) {
168 unsigned long cpu = smp_processor_id(), flags;
170 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
171 return;
173 local_irq_save(flags);
174 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
175 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, type);
176 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
177 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
178 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
179 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
180 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
181 }
182 local_irq_restore(flags);
184 // Check and commit; commit is set to occur once buffer is 3/4 full
185 buffer_check(cpu, GPU_TRACE_BUF);
186 }
188 static void marshal_sched_trace(int type, int pid, int tgid, int cookie, int state) {
189 unsigned long cpu = smp_processor_id(), flags;
191 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
192 return;
194 local_irq_save(flags);
195 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
196 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, type);
197 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_time());
198 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
199 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
200 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
201 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
202 }
203 local_irq_restore(flags);
205 // Check and commit; commit is set to occur once buffer is 3/4 full
206 buffer_check(cpu, SCHED_TRACE_BUF);
207 }
209 #if GATOR_CPU_FREQ_SUPPORT
210 static void marshal_wfi(int core, int state) {
211 unsigned long flags, cpu;
213 local_irq_save(flags);
214 cpu = smp_processor_id();
215 if (buffer_check_space(cpu, WFI_BUF, MAXSIZE_PACK64 + MAXSIZE_PACK32 * 2)) {
216 gator_buffer_write_packed_int64(cpu, WFI_BUF, gator_get_time());
217 gator_buffer_write_packed_int(cpu, WFI_BUF, core);
218 gator_buffer_write_packed_int(cpu, WFI_BUF, state);
219 }
220 local_irq_restore(flags);
222 // Check and commit; commit is set to occur once buffer is 3/4 full
223 buffer_check(cpu, WFI_BUF);
224 }
225 #endif
227 static void marshal_frame(int cpu, int buftype, int frame) {
228 // add response type
229 if (gator_response_type > 0) {
230 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
231 }
233 // leave space for 4-byte unpacked length
234 per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + 4) & gator_buffer_mask[buftype];
236 // add frame type and core number
237 gator_buffer_write_packed_int(cpu, buftype, frame);
238 gator_buffer_write_packed_int(cpu, buftype, cpu);
239 }