]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/arm-ds5-gator.git/blob - driver/gator_marshaling.c
gator: Version 5.17
[android-sdk/arm-ds5-gator.git] / driver / gator_marshaling.c
1 /**
2  * Copyright (C) ARM Limited 2012-2013. 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 #define NEWLINE_CANARY \
11         /* Unix */ \
12         "1\n" \
13         /* Windows */ \
14         "2\r\n" \
15         /* Mac OS */ \
16         "3\r" \
17         /* RISC OS */ \
18         "4\n\r" \
19         /* Add another character so the length isn't 0x0a bytes */ \
20         "5"
22 #ifdef MALI_SUPPORT
23 #include "gator_events_mali_common.h"
24 #endif
26 static void marshal_summary(long long timestamp, long long uptime, long long monotonic_delta, const char * uname)
27 {
28         unsigned long flags;
29         int cpu = 0;
31         local_irq_save(flags);
32         gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
33         gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
34         gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
35         gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, monotonic_delta);
36         gator_buffer_write_string(cpu, SUMMARY_BUF, "uname");
37         gator_buffer_write_string(cpu, SUMMARY_BUF, uname);
38 #if GATOR_IKS_SUPPORT
39         gator_buffer_write_string(cpu, SUMMARY_BUF, "iks");
40         gator_buffer_write_string(cpu, SUMMARY_BUF, "");
41 #endif
42         // Let Streamline know which GPU is used so that it can label the GPU Activity appropriately. This is a temporary fix, to be improved in a future release.
43 #ifdef MALI_SUPPORT
44         gator_buffer_write_string(cpu, SUMMARY_BUF, "mali_type");
45 #if (MALI_SUPPORT == MALI_4xx)
46         gator_buffer_write_string(cpu, SUMMARY_BUF, "4xx");
47 #elif (MALI_SUPPORT == MALI_T6xx)
48         gator_buffer_write_string(cpu, SUMMARY_BUF, "6xx");
49 #else
50         gator_buffer_write_string(cpu, SUMMARY_BUF, "unknown");
51 #endif
52 #endif
53         gator_buffer_write_string(cpu, SUMMARY_BUF, "");
54         // Commit the buffer now so it can be one of the first frames read by Streamline
55         gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
56         local_irq_restore(flags);
57 }
59 static bool marshal_cookie_header(const char *text)
60 {
61         int cpu = get_physical_cpu();
62         return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
63 }
65 static void marshal_cookie(int cookie, const char *text)
66 {
67         int cpu = get_physical_cpu();
68         // buffer_check_space already called by marshal_cookie_header
69         gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
70         gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
71         gator_buffer_write_string(cpu, NAME_BUF, text);
72         buffer_check(cpu, NAME_BUF, gator_get_time());
73 }
75 static void marshal_thread_name(int pid, char *name)
76 {
77         unsigned long flags, cpu;
78         u64 time;
79         local_irq_save(flags);
80         cpu = get_physical_cpu();
81         time = gator_get_time();
82         if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
83                 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
84                 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
85                 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
86                 gator_buffer_write_string(cpu, NAME_BUF, name);
87         }
88         buffer_check(cpu, NAME_BUF, time);
89         local_irq_restore(flags);
90 }
92 static void marshal_link(int cookie, int tgid, int pid)
93 {
94         unsigned long cpu = get_physical_cpu(), flags;
95         u64 time;
97         local_irq_save(flags);
98         time = gator_get_time();
99         if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
100                 gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_LINK);
101                 gator_buffer_write_packed_int64(cpu, NAME_BUF, time);
102                 gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
103                 gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
104                 gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
105         }
106         // Check and commit; commit is set to occur once buffer is 3/4 full
107         buffer_check(cpu, NAME_BUF, time);
108         local_irq_restore(flags);
111 static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel, u64 time)
113         int cpu = get_physical_cpu();
114         if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
115                 // Check and commit; commit is set to occur once buffer is 3/4 full
116                 buffer_check(cpu, BACKTRACE_BUF, time);
118                 return false;
119         }
121         gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, time);
122         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
123         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
124         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
125         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
127         return true;
130 static void marshal_backtrace(unsigned long address, int cookie)
132         int cpu = get_physical_cpu();
133         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
134         gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
137 static void marshal_backtrace_footer(u64 time)
139         int cpu = get_physical_cpu();
140         gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
142         // Check and commit; commit is set to occur once buffer is 3/4 full
143         buffer_check(cpu, BACKTRACE_BUF, time);
146 static bool marshal_event_header(u64 time)
148         unsigned long flags, cpu = get_physical_cpu();
149         bool retval = false;
151         local_irq_save(flags);
152         if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
153                 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0);       // key of zero indicates a timestamp
154                 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, time);
155                 retval = true;
156         }
157         local_irq_restore(flags);
159         return retval;
162 static void marshal_event(int len, int *buffer)
164         unsigned long i, flags, cpu = get_physical_cpu();
166         if (len <= 0)
167                 return;
169         // length must be even since all data is a (key, value) pair
170         if (len & 0x1) {
171                 pr_err("gator: invalid counter data detected and discarded");
172                 return;
173         }
175         // events must be written in key,value pairs
176         local_irq_save(flags);
177         for (i = 0; i < len; i += 2) {
178                 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
179                         break;
180                 }
181                 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
182                 gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
183         }
184         local_irq_restore(flags);
187 static void marshal_event64(int len, long long *buffer64)
189         unsigned long i, flags, cpu = get_physical_cpu();
191         if (len <= 0)
192                 return;
194         // length must be even since all data is a (key, value) pair
195         if (len & 0x1) {
196                 pr_err("gator: invalid counter data detected and discarded");
197                 return;
198         }
200         // events must be written in key,value pairs
201         local_irq_save(flags);
202         for (i = 0; i < len; i += 2) {
203                 if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
204                         break;
205                 }
206                 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
207                 gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
208         }
209         local_irq_restore(flags);
212 #if GATOR_CPU_FREQ_SUPPORT
213 static void marshal_event_single(int core, int key, int value)
215         unsigned long flags, cpu;
216         u64 time;
218         local_irq_save(flags);
219         cpu = get_physical_cpu();
220         time = gator_get_time();
221         if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
222                 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
223                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
224                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
225                 gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
226         }
227         // Check and commit; commit is set to occur once buffer is 3/4 full
228         buffer_check(cpu, COUNTER_BUF, time);
229         local_irq_restore(flags);
231 #endif
233 static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
235         unsigned long cpu = get_physical_cpu(), flags;
236         u64 time;
238         if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
239                 return;
241         local_irq_save(flags);
242         time = gator_get_time();
243         if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
244                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
245                 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
246                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
247                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
248                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
249                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
250         }
251         // Check and commit; commit is set to occur once buffer is 3/4 full
252         buffer_check(cpu, GPU_TRACE_BUF, time);
253         local_irq_restore(flags);
256 static void marshal_sched_gpu_stop(int unit, int core)
258         unsigned long cpu = get_physical_cpu(), flags;
259         u64 time;
261         if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
262                 return;
264         local_irq_save(flags);
265         time = gator_get_time();
266         if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
267                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
268                 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
269                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
270                 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
271         }
272         // Check and commit; commit is set to occur once buffer is 3/4 full
273         buffer_check(cpu, GPU_TRACE_BUF, time);
274         local_irq_restore(flags);
277 static void marshal_sched_trace_start(int tgid, int pid, int cookie)
279         unsigned long cpu = get_physical_cpu(), flags;
280         u64 time;
282         if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
283                 return;
285         local_irq_save(flags);
286         time = gator_get_time();
287         if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
288                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_START);
289                 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
290                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
291                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
292                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
293         }
294         // Check and commit; commit is set to occur once buffer is 3/4 full
295         buffer_check(cpu, SCHED_TRACE_BUF, time);
296         local_irq_restore(flags);
299 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
301         unsigned long cpu = get_physical_cpu(), flags;
302         u64 time;
304         if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
305                 return;
307         local_irq_save(flags);
308         time = gator_get_time();
309         if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
310                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
311                 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
312                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
313                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
314                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
315                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
316         }
317         // Check and commit; commit is set to occur once buffer is 3/4 full
318         buffer_check(cpu, SCHED_TRACE_BUF, time);
319         local_irq_restore(flags);
322 static void marshal_sched_trace_exit(int tgid, int pid)
324         unsigned long cpu = get_physical_cpu(), flags;
325         u64 time;
327         if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
328                 return;
330         local_irq_save(flags);
331         time = gator_get_time();
332         if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
333                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
334                 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
335                 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
336         }
337         // Check and commit; commit is set to occur once buffer is 3/4 full
338         buffer_check(cpu, SCHED_TRACE_BUF, time);
339         local_irq_restore(flags);
342 #if GATOR_CPU_FREQ_SUPPORT
343 static void marshal_idle(int core, int state)
345         unsigned long flags, cpu;
346         u64 time;
348         local_irq_save(flags);
349         cpu = get_physical_cpu();
350         time = gator_get_time();
351         if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
352                 gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
353                 gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
354                 gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
355         }
356         // Check and commit; commit is set to occur once buffer is 3/4 full
357         buffer_check(cpu, IDLE_BUF, time);
358         local_irq_restore(flags);
360 #endif
362 static void marshal_frame(int cpu, int buftype)
364         int frame;
366         if (!per_cpu(gator_buffer, cpu)[buftype]) {
367                 return;
368         }
370         switch (buftype) {
371         case SUMMARY_BUF:
372                 frame = FRAME_SUMMARY;
373                 break;
374         case BACKTRACE_BUF:
375                 frame = FRAME_BACKTRACE;
376                 break;
377         case NAME_BUF:
378                 frame = FRAME_NAME;
379                 break;
380         case COUNTER_BUF:
381                 frame = FRAME_COUNTER;
382                 break;
383         case BLOCK_COUNTER_BUF:
384                 frame = FRAME_BLOCK_COUNTER;
385                 break;
386         case ANNOTATE_BUF:
387                 frame = FRAME_ANNOTATE;
388                 break;
389         case SCHED_TRACE_BUF:
390                 frame = FRAME_SCHED_TRACE;
391                 break;
392         case GPU_TRACE_BUF:
393                 frame = FRAME_GPU_TRACE;
394                 break;
395         case IDLE_BUF:
396                 frame = FRAME_IDLE;
397                 break;
398         default:
399                 frame = -1;
400                 break;
401         }
403         // add response type
404         if (gator_response_type > 0) {
405                 gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
406         }
408         // leave space for 4-byte unpacked length
409         per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];
411         // add frame type and core number
412         gator_buffer_write_packed_int(cpu, buftype, frame);
413         gator_buffer_write_packed_int(cpu, buftype, cpu);
416 #if defined(__arm__) || defined(__aarch64__)
417 static void marshal_core_name(const int core, const int cpuid, const char *name)
419         int cpu = get_physical_cpu();
420         unsigned long flags;
421         local_irq_save(flags);
422         if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
423                 gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
424                 gator_buffer_write_packed_int(cpu, NAME_BUF, core);
425                 gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid);
426                 gator_buffer_write_string(cpu, NAME_BUF, name);
427         }
428         // Commit core names now so that they can show up in live
429         gator_commit_buffer(cpu, NAME_BUF, gator_get_time());
430         local_irq_restore(flags);
432 #endif