summaryrefslogtreecommitdiffstats
path: root/driver
diff options
context:
space:
mode:
authorJon Medhurst2013-01-14 02:34:37 -0600
committerJon Medhurst2013-01-15 05:01:37 -0600
commit10443d8e335e2ae4bb73d62f2e60484122fc6769 (patch)
tree8cc885bc69817dac112793467af0e37d7af5298c /driver
parentee4f56e0d75f42583505dd338d1b91e67ff0ab53 (diff)
downloadarm-ds5-gator-10443d8e335e2ae4bb73d62f2e60484122fc6769.tar.gz
arm-ds5-gator-10443d8e335e2ae4bb73d62f2e60484122fc6769.tar.xz
arm-ds5-gator-10443d8e335e2ae4bb73d62f2e60484122fc6769.zip
gator: Version 5.13
Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'driver')
-rw-r--r--driver/Makefile2
-rw-r--r--driver/gator.h52
-rw-r--r--driver/gator_annotate.c17
-rw-r--r--driver/gator_annotate_kernel.c132
-rw-r--r--driver/gator_backtrace.c36
-rw-r--r--driver/gator_cookies.c105
-rw-r--r--driver/gator_events_armv6.c6
-rw-r--r--driver/gator_events_armv7.c18
-rw-r--r--driver/gator_events_block.c5
-rw-r--r--driver/gator_events_irq.c11
-rw-r--r--driver/gator_events_l2c-310.c18
-rw-r--r--driver/gator_events_mali_400.c1009
-rw-r--r--driver/gator_events_mali_common.c90
-rw-r--r--driver/gator_events_mali_common.h14
-rw-r--r--driver/gator_events_mali_t6xx.c716
-rw-r--r--driver/gator_events_mali_t6xx_hw.c1007
-rw-r--r--driver/gator_events_mali_t6xx_hw_test.c20
-rw-r--r--driver/gator_events_meminfo.c14
-rw-r--r--driver/gator_events_mmaped.c34
-rw-r--r--driver/gator_events_net.c9
-rw-r--r--driver/gator_events_perf_pmu.c77
-rw-r--r--driver/gator_events_sched.c1
-rw-r--r--driver/gator_events_scorpion.c218
-rw-r--r--driver/gator_fs.c58
-rw-r--r--driver/gator_main.c372
-rw-r--r--driver/gator_marshaling.c179
-rw-r--r--driver/gator_pack.c110
-rw-r--r--driver/gator_trace_gpu.c76
-rw-r--r--driver/gator_trace_gpu.h60
-rw-r--r--driver/gator_trace_power.c46
-rw-r--r--driver/gator_trace_sched.c24
31 files changed, 2335 insertions, 2201 deletions
diff --git a/driver/Makefile b/driver/Makefile
index 6cafecf..d22d29d 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -27,7 +27,7 @@ gator-y += gator_events_mali_common.o
27EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) 27EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT)
28endif 28endif
29 29
30# GATOR_TEST controls whether to include (=1) or exclude (=0) test code. 30# GATOR_TEST controls whether to include (=1) or exclude (=0) test code.
31GATOR_TEST ?= 0 31GATOR_TEST ?= 0
32EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST) 32EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST)
33 33
diff --git a/driver/gator.h b/driver/gator.h
index 5a40e17..9a4617b 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -15,7 +15,7 @@
15#include <linux/list.h> 15#include <linux/list.h>
16 16
17#define GATOR_PERF_SUPPORT LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) 17#define GATOR_PERF_SUPPORT LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
18#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && defined(CONFIG_HW_PERF_EVENTS) 18#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && (!(defined(__arm__) || defined(__aarch64__)) || defined(CONFIG_HW_PERF_EVENTS))
19#define GATOR_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT)) 19#define GATOR_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT))
20#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ) 20#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ)
21 21
@@ -33,22 +33,39 @@
33#define SCORPIONMP 0x02d 33#define SCORPIONMP 0x02d
34#define KRAITSIM 0x049 34#define KRAITSIM 0x049
35#define KRAIT 0x04d 35#define KRAIT 0x04d
36#define KRAIT_S4_PRO 0x06f
37#define CORTEX_A53 0xd03
38#define CORTEX_A57 0xd07
36#define AARCH64 0xd0f 39#define AARCH64 0xd0f
40#define OTHER 0xfff
41
42#define MAXSIZE_CORE_NAME 32
43
44struct gator_cpu {
45 const int cpuid;
46 const char core_name[MAXSIZE_CORE_NAME];
47 const char * const pmnc_name;
48 const int pmnc_counters;
49 const int ccnt;
50};
51
52extern struct gator_cpu gator_cpus[];
37 53
38/****************************************************************************** 54/******************************************************************************
39 * Filesystem 55 * Filesystem
40 ******************************************************************************/ 56 ******************************************************************************/
41int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, 57int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
42 char const *name, const struct file_operations *fops, int perm); 58 char const *name,
59 const struct file_operations *fops, int perm);
43 60
44struct dentry *gatorfs_mkdir(struct super_block *sb, 61struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root,
45 struct dentry *root, char const *name); 62 char const *name);
46 63
47int gatorfs_create_ulong(struct super_block *sb, struct dentry *root, 64int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
48 char const *name, unsigned long *val); 65 char const *name, unsigned long *val);
49 66
50int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, 67int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
51 char const *name, unsigned long *val); 68 char const *name, unsigned long *val);
52 69
53void gator_op_create_files(struct super_block *sb, struct dentry *root); 70void gator_op_create_files(struct super_block *sb, struct dentry *root);
54 71
@@ -77,15 +94,16 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root);
77 * Events 94 * Events
78 ******************************************************************************/ 95 ******************************************************************************/
79struct gator_interface { 96struct gator_interface {
80 int (*create_files)(struct super_block *sb, struct dentry *root); 97 void (*shutdown)(void); // Complementary function to init
81 int (*start)(void); 98 int (*create_files)(struct super_block *sb, struct dentry *root);
82 void (*stop)(void); 99 int (*start)(void);
83 int (*online)(int** buffer); 100 void (*stop)(void); // Complementary function to start
84 int (*offline)(int** buffer); 101 int (*online)(int **buffer);
85 void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu' 102 int (*offline)(int **buffer);
86 void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu' 103 void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
87 int (*read)(int **buffer); 104 void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
88 int (*read64)(long long **buffer); 105 int (*read)(int **buffer);
106 int (*read64)(long long **buffer);
89 struct list_head list; 107 struct list_head list;
90}; 108};
91 109
@@ -96,8 +114,8 @@ struct gator_interface {
96 114
97int gator_events_install(struct gator_interface *interface); 115int gator_events_install(struct gator_interface *interface);
98int gator_events_get_key(void); 116int gator_events_get_key(void);
99extern u32 gator_cpuid(void); 117u32 gator_cpuid(void);
100 118
101void gator_backtrace_handler(struct pt_regs * const regs); 119void gator_backtrace_handler(struct pt_regs *const regs);
102 120
103#endif // GATOR_H_ 121#endif // GATOR_H_
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c
index 928e252..42f9951 100644
--- a/driver/gator_annotate.c
+++ b/driver/gator_annotate.c
@@ -44,8 +44,9 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
44 return -EINVAL; 44 return -EINVAL;
45 } 45 }
46 46
47 // Annotation is not supported in interrupt context 47 // Annotations are not supported in interrupt context
48 if (in_interrupt()) { 48 if (in_interrupt()) {
49 printk(KERN_WARNING "gator: Annotations are not supported in interrupt context\n");
49 return -EINVAL; 50 return -EINVAL;
50 } 51 }
51 52
@@ -58,7 +59,8 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
58 goto annotate_write_out; 59 goto annotate_write_out;
59 } 60 }
60 61
61 cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine 62 // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
63 cpu = 0;
62 64
63 if (current == NULL) { 65 if (current == NULL) {
64 pid = 0; 66 pid = 0;
@@ -129,18 +131,21 @@ static int annotate_release(struct inode *inode, struct file *file)
129 uint32_t pid = current->pid; 131 uint32_t pid = current->pid;
130 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); 132 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id());
131 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid); 133 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
132 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time 134 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
133 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size 135 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
134 } 136 }
135 137
138 // Check and commit; commit is set to occur once buffer is 3/4 full
139 buffer_check(cpu, ANNOTATE_BUF);
140
136 spin_unlock(&annotate_lock); 141 spin_unlock(&annotate_lock);
137 142
138 return 0; 143 return 0;
139} 144}
140 145
141static const struct file_operations annotate_fops = { 146static const struct file_operations annotate_fops = {
142 .write = annotate_write, 147 .write = annotate_write,
143 .release = annotate_release 148 .release = annotate_release
144}; 149};
145 150
146static int gator_annotate_create_files(struct super_block *sb, struct dentry *root) 151static int gator_annotate_create_files(struct super_block *sb, struct dentry *root)
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c
index bc68fa8..67d2d6c 100644
--- a/driver/gator_annotate_kernel.c
+++ b/driver/gator_annotate_kernel.c
@@ -8,11 +8,13 @@
8 */ 8 */
9 9
10#define ESCAPE_CODE 0x1c 10#define ESCAPE_CODE 0x1c
11#define STRING_ANNOTATION 0x03 11#define STRING_ANNOTATION 0x06
12#define NAME_CHANNEL_ANNOTATION 0x07
13#define NAME_GROUP_ANNOTATION 0x08
12#define VISUAL_ANNOTATION 0x04 14#define VISUAL_ANNOTATION 0x04
13#define MARKER_ANNOTATION 0x05 15#define MARKER_ANNOTATION 0x05
14 16
15static void kannotate_write(const char* ptr, unsigned int size) 17static void kannotate_write(const char *ptr, unsigned int size)
16{ 18{
17 int retval; 19 int retval;
18 int pos = 0; 20 int pos = 0;
@@ -27,91 +29,129 @@ static void kannotate_write(const char* ptr, unsigned int size)
27 } 29 }
28} 30}
29 31
30static void gator_annotate_code(char code) 32void gator_annotate_channel(int channel, const char *str)
31{ 33{
32 int header = ESCAPE_CODE | (code << 8); 34 int str_size = strlen(str) & 0xffff;
33 kannotate_write((char*)&header, sizeof(header)); 35 long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16) | ((long long)str_size << 48);
36 kannotate_write((char *)&header, sizeof(header));
37 kannotate_write(str, str_size);
34} 38}
35 39
36static void gator_annotate_code_str(char code, const char* string) 40EXPORT_SYMBOL(gator_annotate_channel);
37{
38 int str_size = strlen(string) & 0xffff;
39 int header = ESCAPE_CODE | (code << 8) | (str_size << 16);
40 kannotate_write((char*)&header, sizeof(header));
41 kannotate_write(string, str_size);
42}
43 41
44static void gator_annotate_code_color(char code, int color) 42void gator_annotate(const char *str)
45{ 43{
46 long long header = (ESCAPE_CODE | (code << 8) | 0x00040000 | ((long long)color << 32)); 44 gator_annotate_channel(0, str);
47 kannotate_write((char*)&header, sizeof(header));
48} 45}
49 46
50static void gator_annotate_code_color_str(char code, int color, const char* string) 47EXPORT_SYMBOL(gator_annotate);
48
49void gator_annotate_channel_color(int channel, int color, const char *str)
51{ 50{
52 int str_size = (strlen(string) + 4) & 0xffff; 51 int str_size = (strlen(str) + 4) & 0xffff;
53 long long header = ESCAPE_CODE | (code << 8) | (str_size << 16) | ((long long)color << 32); 52 char header[12];
54 kannotate_write((char*)&header, sizeof(header)); 53 header[0] = ESCAPE_CODE;
55 kannotate_write(string, str_size - 4); 54 header[1] = STRING_ANNOTATION;
55 *(u32 *)(&header[2]) = channel;
56 *(u16 *)(&header[6]) = str_size;
57 *(u32 *)(&header[8]) = color;
58 kannotate_write((char *)&header, sizeof(header));
59 kannotate_write(str, str_size - 4);
56} 60}
57 61
58// String annotation 62EXPORT_SYMBOL(gator_annotate_channel_color);
59void gator_annotate(const char* string) 63
64void gator_annotate_color(int color, const char *str)
60{ 65{
61 gator_annotate_code_str(STRING_ANNOTATION, string); 66 gator_annotate_channel_color(0, color, str);
62} 67}
63EXPORT_SYMBOL(gator_annotate);
64 68
65// String annotation with color 69EXPORT_SYMBOL(gator_annotate_color);
66void gator_annotate_color(int color, const char* string) 70
71void gator_annotate_channel_end(int channel)
67{ 72{
68 gator_annotate_code_color_str(STRING_ANNOTATION, color, string); 73 long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16);
74 kannotate_write((char *)&header, sizeof(header));
69} 75}
70EXPORT_SYMBOL(gator_annotate_color);
71 76
72// Terminate an annotation 77EXPORT_SYMBOL(gator_annotate_channel_end);
78
73void gator_annotate_end(void) 79void gator_annotate_end(void)
74{ 80{
75 gator_annotate_code(STRING_ANNOTATION); 81 gator_annotate_channel_end(0);
76} 82}
83
77EXPORT_SYMBOL(gator_annotate_end); 84EXPORT_SYMBOL(gator_annotate_end);
78 85
79// Image annotation with optional string 86void gator_annotate_name_channel(int channel, int group, const char* str)
80void gator_annotate_visual(const char* data, unsigned int length, const char* string) 87{
88 int str_size = strlen(str) & 0xffff;
89 char header[12];
90 header[0] = ESCAPE_CODE;
91 header[1] = NAME_CHANNEL_ANNOTATION;
92 *(u32 *)(&header[2]) = channel;
93 *(u32 *)(&header[6]) = group;
94 *(u16 *)(&header[10]) = str_size;
95 kannotate_write((char *)&header, sizeof(header));
96 kannotate_write(str, str_size);
97}
98
99EXPORT_SYMBOL(gator_annotate_name_channel);
100
101void gator_annotate_name_group(int group, const char* str)
102{
103 int str_size = strlen(str) & 0xffff;
104 long long header = ESCAPE_CODE | (NAME_GROUP_ANNOTATION << 8) | (group << 16) | ((long long)str_size << 48);
105 kannotate_write((char *)&header, sizeof(header));
106 kannotate_write(str, str_size);
107}
108
109EXPORT_SYMBOL(gator_annotate_name_group);
110
111void gator_annotate_visual(const char *data, unsigned int length, const char *str)
81{ 112{
82 int str_size = strlen(string) & 0xffff; 113 int str_size = strlen(str) & 0xffff;
83 int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16); 114 int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16);
84 kannotate_write((char*)&visual_annotation, sizeof(visual_annotation)); 115 kannotate_write((char *)&visual_annotation, sizeof(visual_annotation));
85 kannotate_write(string, str_size); 116 kannotate_write(str, str_size);
86 kannotate_write((char*)&length, sizeof(length)); 117 kannotate_write((char *)&length, sizeof(length));
87 kannotate_write(data, length); 118 kannotate_write(data, length);
88} 119}
120
89EXPORT_SYMBOL(gator_annotate_visual); 121EXPORT_SYMBOL(gator_annotate_visual);
90 122
91// Marker annotation
92void gator_annotate_marker(void) 123void gator_annotate_marker(void)
93{ 124{
94 gator_annotate_code(MARKER_ANNOTATION); 125 int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8);
126 kannotate_write((char *)&header, sizeof(header));
95} 127}
128
96EXPORT_SYMBOL(gator_annotate_marker); 129EXPORT_SYMBOL(gator_annotate_marker);
97 130
98// Marker annotation with a string 131void gator_annotate_marker_str(const char *str)
99void gator_annotate_marker_str(const char* string)
100{ 132{
101 gator_annotate_code_str(MARKER_ANNOTATION, string); 133 int str_size = strlen(str) & 0xffff;
134 int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16);
135 kannotate_write((char *)&header, sizeof(header));
136 kannotate_write(str, str_size);
102} 137}
138
103EXPORT_SYMBOL(gator_annotate_marker_str); 139EXPORT_SYMBOL(gator_annotate_marker_str);
104 140
105// Marker annotation with a color
106void gator_annotate_marker_color(int color) 141void gator_annotate_marker_color(int color)
107{ 142{
108 gator_annotate_code_color(MARKER_ANNOTATION, color); 143 long long header = (ESCAPE_CODE | (MARKER_ANNOTATION << 8) | 0x00040000 | ((long long)color << 32));
144 kannotate_write((char *)&header, sizeof(header));
109} 145}
146
110EXPORT_SYMBOL(gator_annotate_marker_color); 147EXPORT_SYMBOL(gator_annotate_marker_color);
111 148
112// Marker annotation with a string and color 149void gator_annotate_marker_color_str(int color, const char *str)
113void gator_annotate_marker_color_str(int color, const char* string)
114{ 150{
115 gator_annotate_code_color_str(MARKER_ANNOTATION, color, string); 151 int str_size = (strlen(str) + 4) & 0xffff;
152 long long header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16) | ((long long)color << 32);
153 kannotate_write((char *)&header, sizeof(header));
154 kannotate_write(str, str_size - 4);
116} 155}
156
117EXPORT_SYMBOL(gator_annotate_marker_color_str); 157EXPORT_SYMBOL(gator_annotate_marker_color_str);
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 2173d8a..e6125b3 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -11,20 +11,28 @@
11 * EABI backtrace stores {fp,lr} on the stack. 11 * EABI backtrace stores {fp,lr} on the stack.
12 */ 12 */
13struct frame_tail_eabi { 13struct frame_tail_eabi {
14 unsigned long fp; // points to prev_lr 14 unsigned long fp; // points to prev_lr
15 unsigned long lr; 15 unsigned long lr;
16}; 16};
17 17
18static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) 18static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth)
19{ 19{
20#if defined(__arm__) 20#if defined(__arm__) || defined(__aarch64__)
21 struct frame_tail_eabi *tail; 21 struct frame_tail_eabi *tail;
22 struct frame_tail_eabi *next; 22 struct frame_tail_eabi *next;
23 struct frame_tail_eabi *ptrtail; 23 struct frame_tail_eabi *ptrtail;
24 struct frame_tail_eabi buftail; 24 struct frame_tail_eabi buftail;
25#if defined(__arm__)
25 unsigned long fp = regs->ARM_fp; 26 unsigned long fp = regs->ARM_fp;
26 unsigned long sp = regs->ARM_sp; 27 unsigned long sp = regs->ARM_sp;
27 unsigned long lr = regs->ARM_lr; 28 unsigned long lr = regs->ARM_lr;
29 const int frame_offset = 4;
30#else
31 unsigned long fp = regs->regs[29];
32 unsigned long sp = regs->sp;
33 unsigned long lr = regs->regs[30];
34 const int frame_offset = 0;
35#endif
28 int is_user_mode = user_mode(regs); 36 int is_user_mode = user_mode(regs);
29 37
30 if (!is_user_mode) { 38 if (!is_user_mode) {
@@ -39,9 +47,9 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
39 return; 47 return;
40 } 48 }
41 49
42 tail = (struct frame_tail_eabi *)(fp - 4); 50 tail = (struct frame_tail_eabi *)(fp - frame_offset);
43 51
44 while (depth-- && tail && !((unsigned long) tail & 3)) { 52 while (depth-- && tail && !((unsigned long)tail & 3)) {
45 /* Also check accessibility of one struct frame_tail beyond */ 53 /* Also check accessibility of one struct frame_tail beyond */
46 if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi))) 54 if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi)))
47 return; 55 return;
@@ -53,10 +61,10 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
53 gator_add_trace(cpu, lr); 61 gator_add_trace(cpu, lr);
54 62
55 /* frame pointers should progress back up the stack, towards higher addresses */ 63 /* frame pointers should progress back up the stack, towards higher addresses */
56 next = (struct frame_tail_eabi *)(lr - 4); 64 next = (struct frame_tail_eabi *)(lr - frame_offset);
57 if (tail >= next || lr == 0) { 65 if (tail >= next || lr == 0) {
58 fp = ptrtail[0].fp; 66 fp = ptrtail[0].fp;
59 next = (struct frame_tail_eabi *)(fp - 4); 67 next = (struct frame_tail_eabi *)(fp - frame_offset);
60 /* check tail is valid */ 68 /* check tail is valid */
61 if (tail >= next || fp == 0) { 69 if (tail >= next || fp == 0) {
62 return; 70 return;
@@ -68,7 +76,7 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
68#endif 76#endif
69} 77}
70 78
71#if defined(__arm__) 79#if defined(__arm__) || defined(__aarch64__)
72static int report_trace(struct stackframe *frame, void *d) 80static int report_trace(struct stackframe *frame, void *d)
73{ 81{
74 struct module *mod; 82 struct module *mod;
@@ -78,7 +86,7 @@ static int report_trace(struct stackframe *frame, void *d)
78 if (*depth) { 86 if (*depth) {
79 mod = __module_address(addr); 87 mod = __module_address(addr);
80 if (mod) { 88 if (mod) {
81 cookie = get_cookie(cpu, current, NULL, mod, true); 89 cookie = get_cookie(cpu, current, mod->name, false);
82 addr = addr - (unsigned long)mod->module_core; 90 addr = addr - (unsigned long)mod->module_core;
83 } 91 }
84 marshal_backtrace(addr & ~1, cookie); 92 marshal_backtrace(addr & ~1, cookie);
@@ -91,9 +99,9 @@ static int report_trace(struct stackframe *frame, void *d)
91 99
92// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile 100// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile
93// #define GATOR_KERNEL_STACK_UNWINDING 101// #define GATOR_KERNEL_STACK_UNWINDING
94static void kernel_backtrace(int cpu, struct pt_regs * const regs) 102static void kernel_backtrace(int cpu, struct pt_regs *const regs)
95{ 103{
96#if defined(__arm__) 104#if defined(__arm__) || defined(__aarch64__)
97#ifdef GATOR_KERNEL_STACK_UNWINDING 105#ifdef GATOR_KERNEL_STACK_UNWINDING
98 int depth = gator_backtrace_depth; 106 int depth = gator_backtrace_depth;
99#else 107#else
@@ -102,10 +110,16 @@ static void kernel_backtrace(int cpu, struct pt_regs * const regs)
102 struct stackframe frame; 110 struct stackframe frame;
103 if (depth == 0) 111 if (depth == 0)
104 depth = 1; 112 depth = 1;
113#if defined(__arm__)
105 frame.fp = regs->ARM_fp; 114 frame.fp = regs->ARM_fp;
106 frame.sp = regs->ARM_sp; 115 frame.sp = regs->ARM_sp;
107 frame.lr = regs->ARM_lr; 116 frame.lr = regs->ARM_lr;
108 frame.pc = regs->ARM_pc; 117 frame.pc = regs->ARM_pc;
118#else
119 frame.fp = regs->regs[29];
120 frame.sp = regs->sp;
121 frame.pc = regs->pc;
122#endif
109 walk_stackframe(&frame, report_trace, &depth); 123 walk_stackframe(&frame, report_trace, &depth);
110#else 124#else
111 marshal_backtrace(PC_REG & ~1, NO_COOKIE); 125 marshal_backtrace(PC_REG & ~1, NO_COOKIE);
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index 21dc4eb..bb401bb 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -7,7 +7,7 @@
7 * 7 *
8 */ 8 */
9 9
10#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */ 10#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
11#define TRANSLATE_SIZE 256 11#define TRANSLATE_SIZE 256
12#define MAX_COLLISIONS 2 12#define MAX_COLLISIONS 2
13 13
@@ -20,28 +20,29 @@ static DEFINE_PER_CPU(uint64_t *, cookie_keys);
20static DEFINE_PER_CPU(uint32_t *, cookie_values); 20static DEFINE_PER_CPU(uint32_t *, cookie_values);
21static DEFINE_PER_CPU(int, translate_buffer_read); 21static DEFINE_PER_CPU(int, translate_buffer_read);
22static DEFINE_PER_CPU(int, translate_buffer_write); 22static DEFINE_PER_CPU(int, translate_buffer_write);
23static DEFINE_PER_CPU(void * *, translate_buffer); 23static DEFINE_PER_CPU(void **, translate_buffer);
24 24
25static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); 25static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq);
26static void wq_cookie_handler(struct work_struct *unused); 26static void wq_cookie_handler(struct work_struct *unused);
27DECLARE_WORK(cookie_work, wq_cookie_handler); 27DECLARE_WORK(cookie_work, wq_cookie_handler);
28static struct timer_list app_process_wake_up_timer; 28static struct timer_list app_process_wake_up_timer;
29static void app_process_wake_up_handler(unsigned long unused_data); 29static void app_process_wake_up_handler(unsigned long unused_data);
30 30
31static uint32_t cookiemap_code(uint64_t value64) { 31static uint32_t cookiemap_code(uint64_t value64)
32{
32 uint32_t value = (uint32_t)((value64 >> 32) + value64); 33 uint32_t value = (uint32_t)((value64 >> 32) + value64);
33 uint32_t cookiecode = (value >> 24) & 0xff; 34 uint32_t cookiecode = (value >> 24) & 0xff;
34 cookiecode = cookiecode * 31 + ((value >> 16) & 0xff); 35 cookiecode = cookiecode * 31 + ((value >> 16) & 0xff);
35 cookiecode = cookiecode * 31 + ((value >> 8) & 0xff); 36 cookiecode = cookiecode * 31 + ((value >> 8) & 0xff);
36 cookiecode = cookiecode * 31 + ((value >> 0) & 0xff); 37 cookiecode = cookiecode * 31 + ((value >> 0) & 0xff);
37 cookiecode &= (COOKIEMAP_ENTRIES-1); 38 cookiecode &= (COOKIEMAP_ENTRIES - 1);
38 return cookiecode * MAX_COLLISIONS; 39 return cookiecode * MAX_COLLISIONS;
39} 40}
40 41
41static uint32_t gator_chksum_crc32(char *data) 42static uint32_t gator_chksum_crc32(const char *data)
42{ 43{
43 register unsigned long crc; 44 register unsigned long crc;
44 unsigned char *block = data; 45 const unsigned char *block = data;
45 int i, length = strlen(data); 46 int i, length = strlen(data);
46 47
47 crc = 0xFFFFFFFF; 48 crc = 0xFFFFFFFF;
@@ -57,7 +58,8 @@ static uint32_t gator_chksum_crc32(char *data)
57 * Pre: [0][1][v][3]..[n-1] 58 * Pre: [0][1][v][3]..[n-1]
58 * Post: [v][0][1][3]..[n-1] 59 * Post: [v][0][1][3]..[n-1]
59 */ 60 */
60static uint32_t cookiemap_exists(uint64_t key) { 61static uint32_t cookiemap_exists(uint64_t key)
62{
61 unsigned long x, flags, retval = 0; 63 unsigned long x, flags, retval = 0;
62 int cpu = smp_processor_id(); 64 int cpu = smp_processor_id();
63 uint32_t cookiecode = cookiemap_code(key); 65 uint32_t cookiecode = cookiemap_code(key);
@@ -70,8 +72,8 @@ static uint32_t cookiemap_exists(uint64_t key) {
70 if (keys[x] == key) { 72 if (keys[x] == key) {
71 uint32_t value = values[x]; 73 uint32_t value = values[x];
72 for (; x > 0; x--) { 74 for (; x > 0; x--) {
73 keys[x] = keys[x-1]; 75 keys[x] = keys[x - 1];
74 values[x] = values[x-1]; 76 values[x] = values[x - 1];
75 } 77 }
76 keys[0] = key; 78 keys[0] = key;
77 values[0] = value; 79 values[0] = value;
@@ -89,30 +91,31 @@ static uint32_t cookiemap_exists(uint64_t key) {
89 * Pre: [0][1][2][3]..[n-1] 91 * Pre: [0][1][2][3]..[n-1]
90 * Post: [v][0][1][2]..[n-2] 92 * Post: [v][0][1][2]..[n-2]
91 */ 93 */
92static void cookiemap_add(uint64_t key, uint32_t value) { 94static void cookiemap_add(uint64_t key, uint32_t value)
95{
93 int cpu = smp_processor_id(); 96 int cpu = smp_processor_id();
94 int cookiecode = cookiemap_code(key); 97 int cookiecode = cookiemap_code(key);
95 uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]); 98 uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]);
96 uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]); 99 uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]);
97 int x; 100 int x;
98 101
99 for (x = MAX_COLLISIONS-1; x > 0; x--) { 102 for (x = MAX_COLLISIONS - 1; x > 0; x--) {
100 keys[x] = keys[x-1]; 103 keys[x] = keys[x - 1];
101 values[x] = values[x-1]; 104 values[x] = values[x - 1];
102 } 105 }
103 keys[0] = key; 106 keys[0] = key;
104 values[0] = value; 107 values[0] = value;
105} 108}
106 109
107static void translate_buffer_write_ptr(int cpu, void * x) 110static void translate_buffer_write_ptr(int cpu, void *x)
108{ 111{
109 per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; 112 per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
110 per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; 113 per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
111} 114}
112 115
113static void * translate_buffer_read_ptr(int cpu) 116static void *translate_buffer_read_ptr(int cpu)
114{ 117{
115 void * value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; 118 void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
116 per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; 119 per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
117 return value; 120 return value;
118} 121}
@@ -120,9 +123,9 @@ static void * translate_buffer_read_ptr(int cpu)
120static void wq_cookie_handler(struct work_struct *unused) 123static void wq_cookie_handler(struct work_struct *unused)
121{ 124{
122 struct task_struct *task; 125 struct task_struct *task;
123 struct vm_area_struct *vma; 126 char *text;
124 int cpu = smp_processor_id(); 127 int cpu = smp_processor_id();
125 unsigned int cookie, commit; 128 unsigned int commit;
126 129
127 mutex_lock(&start_mutex); 130 mutex_lock(&start_mutex);
128 131
@@ -130,8 +133,8 @@ static void wq_cookie_handler(struct work_struct *unused)
130 commit = per_cpu(translate_buffer_write, cpu); 133 commit = per_cpu(translate_buffer_write, cpu);
131 while (per_cpu(translate_buffer_read, cpu) != commit) { 134 while (per_cpu(translate_buffer_read, cpu) != commit) {
132 task = (struct task_struct *)translate_buffer_read_ptr(cpu); 135 task = (struct task_struct *)translate_buffer_read_ptr(cpu);
133 vma = (struct vm_area_struct *)translate_buffer_read_ptr(cpu); 136 text = (char *)translate_buffer_read_ptr(cpu);
134 cookie = get_cookie(cpu, task, vma, NULL, false); 137 get_cookie(cpu, task, text, true);
135 } 138 }
136 } 139 }
137 140
@@ -145,7 +148,7 @@ static void app_process_wake_up_handler(unsigned long unused_data)
145} 148}
146 149
147// Retrieve full name from proc/pid/cmdline for java processes on Android 150// Retrieve full name from proc/pid/cmdline for java processes on Android
148static int translate_app_process(char** text, int cpu, struct task_struct * task, struct vm_area_struct *vma, bool in_interrupt) 151static int translate_app_process(const char **text, int cpu, struct task_struct *task, bool from_wq)
149{ 152{
150 void *maddr; 153 void *maddr;
151 unsigned int len; 154 unsigned int len;
@@ -154,12 +157,12 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
154 struct page *page = NULL; 157 struct page *page = NULL;
155 struct vm_area_struct *page_vma; 158 struct vm_area_struct *page_vma;
156 int bytes, offset, retval = 0, ptr; 159 int bytes, offset, retval = 0, ptr;
157 char * buf = per_cpu(translate_text, cpu); 160 char *buf = per_cpu(translate_text, cpu);
158 161
159 // Push work into a work queue if in atomic context as the kernel functions below might sleep 162 // Push work into a work queue if in atomic context as the kernel functions below might sleep
160 // Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems 163 // Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems
161 // inconsistent during a context switch between android/linux versions 164 // inconsistent during a context switch between android/linux versions
162 if (in_interrupt) { 165 if (!from_wq) {
163 // Check if already in buffer 166 // Check if already in buffer
164 ptr = per_cpu(translate_buffer_read, cpu); 167 ptr = per_cpu(translate_buffer_read, cpu);
165 while (ptr != per_cpu(translate_buffer_write, cpu)) { 168 while (ptr != per_cpu(translate_buffer_write, cpu)) {
@@ -169,7 +172,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
169 } 172 }
170 173
171 translate_buffer_write_ptr(cpu, (void *)task); 174 translate_buffer_write_ptr(cpu, (void *)task);
172 translate_buffer_write_ptr(cpu, (void *)vma); 175 translate_buffer_write_ptr(cpu, (void *)*text);
173 176
174 mod_timer(&app_process_wake_up_timer, jiffies + 1); 177 mod_timer(&app_process_wake_up_timer, jiffies + 1);
175 goto out; 178 goto out;
@@ -192,7 +195,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
192 goto outsem; 195 goto outsem;
193 196
194 maddr = kmap(page); 197 maddr = kmap(page);
195 offset = addr & (PAGE_SIZE-1); 198 offset = addr & (PAGE_SIZE - 1);
196 bytes = len; 199 bytes = len;
197 if (bytes > PAGE_SIZE - offset) 200 if (bytes > PAGE_SIZE - offset)
198 bytes = PAGE_SIZE - offset; 201 bytes = PAGE_SIZE - offset;
@@ -222,29 +225,10 @@ out:
222 return retval; 225 return retval;
223} 226}
224 227
225static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) 228static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq)
226{ 229{
227 unsigned long flags, cookie; 230 unsigned long flags, cookie;
228 struct path *path;
229 uint64_t key; 231 uint64_t key;
230 char *text;
231
232 if (mod) {
233 text = mod->name;
234 } else {
235 if (vma && vma->vm_file) {
236 path = &vma->vm_file->f_path;
237 } else if (task && task->mm && task->mm->exe_file) {
238 path = &task->mm->exe_file->f_path;
239 } else {
240 return INVALID_COOKIE;
241 }
242 if (!path || !path->dentry) {
243 return INVALID_COOKIE;
244 }
245
246 text = (char*)path->dentry->d_name.name;
247 }
248 232
249 key = gator_chksum_crc32(text); 233 key = gator_chksum_crc32(text);
250 key = (key << 32) | (uint32_t)task->tgid; 234 key = (key << 32) | (uint32_t)task->tgid;
@@ -254,8 +238,8 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
254 return cookie; 238 return cookie;
255 } 239 }
256 240
257 if (strcmp(text, "app_process") == 0 && !mod) { 241 if (strcmp(text, "app_process") == 0) {
258 if (!translate_app_process(&text, cpu, task, vma, in_interrupt)) 242 if (!translate_app_process(&text, cpu, task, from_wq))
259 return INVALID_COOKIE; 243 return INVALID_COOKIE;
260 } 244 }
261 245
@@ -276,16 +260,19 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
276 260
277static int get_exec_cookie(int cpu, struct task_struct *task) 261static int get_exec_cookie(int cpu, struct task_struct *task)
278{ 262{
279 unsigned long cookie = NO_COOKIE;
280 struct mm_struct *mm = task->mm; 263 struct mm_struct *mm = task->mm;
264 const char *text;
281 265
282 // kernel threads have no address space 266 // kernel threads have no address space
283 if (!mm) 267 if (!mm)
284 return cookie; 268 return NO_COOKIE;
285 269
286 cookie = get_cookie(cpu, task, NULL, NULL, true); 270 if (task && task->mm && task->mm->exe_file) {
271 text = task->mm->exe_file->f_path.dentry->d_name.name;
272 return get_cookie(cpu, task, text, false);
273 }
287 274
288 return cookie; 275 return INVALID_COOKIE;
289} 276}
290 277
291static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset) 278static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset)
@@ -293,6 +280,7 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
293 unsigned long cookie = NO_COOKIE; 280 unsigned long cookie = NO_COOKIE;
294 struct mm_struct *mm = task->mm; 281 struct mm_struct *mm = task->mm;
295 struct vm_area_struct *vma; 282 struct vm_area_struct *vma;
283 const char *text;
296 284
297 if (!mm) 285 if (!mm)
298 return cookie; 286 return cookie;
@@ -302,7 +290,8 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
302 continue; 290 continue;
303 291
304 if (vma->vm_file) { 292 if (vma->vm_file) {
305 cookie = get_cookie(cpu, task, vma, NULL, true); 293 text = vma->vm_file->f_path.dentry->d_name.name;
294 cookie = get_cookie(cpu, task, text, false);
306 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; 295 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
307 } else { 296 } else {
308 /* must be an anonymous map */ 297 /* must be an anonymous map */
@@ -323,14 +312,14 @@ static int cookies_initialize(void)
323 uint32_t crc, poly; 312 uint32_t crc, poly;
324 int i, j, cpu, size, err = 0; 313 int i, j, cpu, size, err = 0;
325 314
326 int translate_buffer_size = 512; // must be a power of 2 315 int translate_buffer_size = 512; // must be a power of 2
327 translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1; 316 translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1;
328 317
329 for_each_present_cpu(cpu) { 318 for_each_present_cpu(cpu) {
330 per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu; 319 per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu;
331 320
332 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t); 321 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t);
333 per_cpu(cookie_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL); 322 per_cpu(cookie_keys, cpu) = (uint64_t *)kmalloc(size, GFP_KERNEL);
334 if (!per_cpu(cookie_keys, cpu)) { 323 if (!per_cpu(cookie_keys, cpu)) {
335 err = -ENOMEM; 324 err = -ENOMEM;
336 goto cookie_setup_error; 325 goto cookie_setup_error;
@@ -338,14 +327,14 @@ static int cookies_initialize(void)
338 memset(per_cpu(cookie_keys, cpu), 0, size); 327 memset(per_cpu(cookie_keys, cpu), 0, size);
339 328
340 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint32_t); 329 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint32_t);
341 per_cpu(cookie_values, cpu) = (uint32_t*)kmalloc(size, GFP_KERNEL); 330 per_cpu(cookie_values, cpu) = (uint32_t *)kmalloc(size, GFP_KERNEL);
342 if (!per_cpu(cookie_values, cpu)) { 331 if (!per_cpu(cookie_values, cpu)) {
343 err = -ENOMEM; 332 err = -ENOMEM;
344 goto cookie_setup_error; 333 goto cookie_setup_error;
345 } 334 }
346 memset(per_cpu(cookie_values, cpu), 0, size); 335 memset(per_cpu(cookie_values, cpu), 0, size);
347 336
348 per_cpu(translate_buffer, cpu) = (void * *)kmalloc(translate_buffer_size, GFP_KERNEL); 337 per_cpu(translate_buffer, cpu) = (void **)kmalloc(translate_buffer_size, GFP_KERNEL);
349 if (!per_cpu(translate_buffer, cpu)) { 338 if (!per_cpu(translate_buffer, cpu)) {
350 err = -ENOMEM; 339 err = -ENOMEM;
351 goto cookie_setup_error; 340 goto cookie_setup_error;
@@ -363,7 +352,7 @@ static int cookies_initialize(void)
363 352
364 // build CRC32 table 353 // build CRC32 table
365 poly = 0x04c11db7; 354 poly = 0x04c11db7;
366 gator_crc32_table = (uint32_t*)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL); 355 gator_crc32_table = (uint32_t *)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
367 for (i = 0; i < 256; i++) { 356 for (i = 0; i < 256; i++) {
368 crc = i; 357 crc = i;
369 for (j = 8; j > 0; j--) { 358 for (j = 8; j > 0; j--) {
diff --git a/driver/gator_events_armv6.c b/driver/gator_events_armv6.c
index 5f989ba..ee36dd0 100644
--- a/driver/gator_events_armv6.c
+++ b/driver/gator_events_armv6.c
@@ -93,7 +93,7 @@ int gator_events_armv6_create_files(struct super_block *sb, struct dentry *root)
93 return 0; 93 return 0;
94} 94}
95 95
96static int gator_events_armv6_online(int** buffer) 96static int gator_events_armv6_online(int **buffer)
97{ 97{
98 unsigned int cnt, len = 0, cpu = smp_processor_id(); 98 unsigned int cnt, len = 0, cpu = smp_processor_id();
99 u32 pmnc; 99 u32 pmnc;
@@ -104,7 +104,7 @@ static int gator_events_armv6_online(int** buffer)
104 104
105 /* initialize PMNC, reset overflow, D bit, C bit and P bit. */ 105 /* initialize PMNC, reset overflow, D bit, C bit and P bit. */
106 armv6_pmnc_write(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT | 106 armv6_pmnc_write(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
107 PMCR_C | PMCR_P); 107 PMCR_C | PMCR_P);
108 108
109 /* configure control register */ 109 /* configure control register */
110 for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) { 110 for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
@@ -141,7 +141,7 @@ static int gator_events_armv6_online(int** buffer)
141 return len; 141 return len;
142} 142}
143 143
144static int gator_events_armv6_offline(int** buffer) 144static int gator_events_armv6_offline(int **buffer)
145{ 145{
146 unsigned int cnt; 146 unsigned int cnt;
147 147
diff --git a/driver/gator_events_armv7.c b/driver/gator_events_armv7.c
index 590421d..212b17b 100644
--- a/driver/gator_events_armv7.c
+++ b/driver/gator_events_armv7.c
@@ -22,7 +22,7 @@
22#define PMNC_E (1 << 0) /* Enable all counters */ 22#define PMNC_E (1 << 0) /* Enable all counters */
23#define PMNC_P (1 << 1) /* Reset all counters */ 23#define PMNC_P (1 << 1) /* Reset all counters */
24#define PMNC_C (1 << 2) /* Cycle counter reset */ 24#define PMNC_C (1 << 2) /* Cycle counter reset */
25#define PMNC_MASK 0x3f /* Mask for writable bits */ 25#define PMNC_MASK 0x3f /* Mask for writable bits */
26 26
27// ccnt reg 27// ccnt reg
28#define CCNT_REG (1 << 31) 28#define CCNT_REG (1 << 31)
@@ -63,7 +63,7 @@ inline u32 armv7_ccnt_read(u32 reset_value)
63 local_irq_save(flags); 63 local_irq_save(flags);
64 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable 64 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
65 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); // read 65 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); // read
66 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval));// new value 66 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval)); // new value
67 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable 67 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
68 local_irq_restore(flags); 68 local_irq_restore(flags);
69 69
@@ -82,7 +82,7 @@ inline u32 armv7_cntn_read(unsigned int cnt, u32 reset_value)
82 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable 82 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
83 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (sel)); // select 83 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (sel)); // select
84 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (oldval)); // read 84 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (oldval)); // read
85 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval));// new value 85 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval)); // new value
86 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable 86 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
87 local_irq_restore(flags); 87 local_irq_restore(flags);
88 88
@@ -143,7 +143,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
143 if (i == 0) { 143 if (i == 0) {
144 snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name); 144 snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name);
145 } else { 145 } else {
146 snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i-1); 146 snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i - 1);
147 } 147 }
148 dir = gatorfs_mkdir(sb, root, buf); 148 dir = gatorfs_mkdir(sb, root, buf);
149 if (!dir) { 149 if (!dir) {
@@ -159,7 +159,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
159 return 0; 159 return 0;
160} 160}
161 161
162static int gator_events_armv7_online(int** buffer) 162static int gator_events_armv7_online(int **buffer)
163{ 163{
164 unsigned int cnt, len = 0, cpu = smp_processor_id(); 164 unsigned int cnt, len = 0, cpu = smp_processor_id();
165 165
@@ -214,11 +214,11 @@ static int gator_events_armv7_online(int** buffer)
214 return len; 214 return len;
215} 215}
216 216
217static int gator_events_armv7_offline(int** buffer) 217static int gator_events_armv7_offline(int **buffer)
218{ 218{
219 // disbale all counters, including PMCCNTR; overflow IRQs will not be signaled 219 // disable all counters, including PMCCNTR; overflow IRQs will not be signaled
220 armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E); 220 armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
221 221
222 return 0; 222 return 0;
223} 223}
224 224
@@ -298,7 +298,7 @@ int gator_events_armv7_init(void)
298 return -1; 298 return -1;
299 } 299 }
300 300
301 pmnc_counters++; // CNT[n] + CCNT 301 pmnc_counters++; // CNT[n] + CCNT
302 302
303 for (cnt = CCNT; cnt < CNTMAX; cnt++) { 303 for (cnt = CCNT; cnt < CNTMAX; cnt++) {
304 pmnc_enabled[cnt] = 0; 304 pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index b18c3ca..f512b13 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -119,7 +119,7 @@ static int gator_events_block_read(int **buffer)
119 if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) { 119 if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) {
120 atomic_sub(value, &blockCnt[BLOCK_RQ_WR]); 120 atomic_sub(value, &blockCnt[BLOCK_RQ_WR]);
121 blockGet[len++] = block_rq_wr_key; 121 blockGet[len++] = block_rq_wr_key;
122 blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message 122 blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
123 blockGet[len++] = block_rq_wr_key; 123 blockGet[len++] = block_rq_wr_key;
124 blockGet[len++] = value; 124 blockGet[len++] = value;
125 data += value; 125 data += value;
@@ -127,7 +127,7 @@ static int gator_events_block_read(int **buffer)
127 if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) { 127 if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) {
128 atomic_sub(value, &blockCnt[BLOCK_RQ_RD]); 128 atomic_sub(value, &blockCnt[BLOCK_RQ_RD]);
129 blockGet[len++] = block_rq_rd_key; 129 blockGet[len++] = block_rq_rd_key;
130 blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message 130 blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
131 blockGet[len++] = block_rq_rd_key; 131 blockGet[len++] = block_rq_rd_key;
132 blockGet[len++] = value; 132 blockGet[len++] = value;
133 data += value; 133 data += value;
@@ -156,4 +156,5 @@ int gator_events_block_init(void)
156 156
157 return gator_events_install(&gator_events_block_interface); 157 return gator_events_install(&gator_events_block_interface);
158} 158}
159
159gator_events_init(gator_events_block_init); 160gator_events_init(gator_events_block_init);
diff --git a/driver/gator_events_irq.c b/driver/gator_events_irq.c
index 435bc86..1221372 100644
--- a/driver/gator_events_irq.c
+++ b/driver/gator_events_irq.c
@@ -21,8 +21,8 @@ static ulong softirq_key;
21static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); 21static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt);
22static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); 22static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet);
23 23
24GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq, 24GATOR_DEFINE_PROBE(irq_handler_exit,
25 struct irqaction *action, int ret)) 25 TP_PROTO(int irq, struct irqaction *action, int ret))
26{ 26{
27 unsigned long flags; 27 unsigned long flags;
28 28
@@ -71,10 +71,10 @@ static int gator_events_irq_create_files(struct super_block *sb, struct dentry *
71 return 0; 71 return 0;
72} 72}
73 73
74static int gator_events_irq_online(int** buffer) 74static int gator_events_irq_online(int **buffer)
75{ 75{
76 int len = 0, cpu = smp_processor_id(); 76 int len = 0, cpu = smp_processor_id();
77 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt 77 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
78 78
79 // synchronization with the irq_exit functions is not necessary as the values are being reset 79 // synchronization with the irq_exit functions is not necessary as the values are being reset
80 if (hardirq_enabled) { 80 if (hardirq_enabled) {
@@ -136,7 +136,7 @@ static void gator_events_irq_stop(void)
136 136
137static int gator_events_irq_read(int **buffer) 137static int gator_events_irq_read(int **buffer)
138{ 138{
139 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt 139 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
140 int len, value; 140 int len, value;
141 int cpu = smp_processor_id(); 141 int cpu = smp_processor_id();
142 142
@@ -185,4 +185,5 @@ int gator_events_irq_init(void)
185 185
186 return gator_events_install(&gator_events_irq_interface); 186 return gator_events_install(&gator_events_irq_interface);
187} 187}
188
188gator_events_init(gator_events_irq_init); 189gator_events_init(gator_events_irq_init);
diff --git a/driver/gator_events_l2c-310.c b/driver/gator_events_l2c-310.c
index bd1c48a..197af04 100644
--- a/driver/gator_events_l2c-310.c
+++ b/driver/gator_events_l2c-310.c
@@ -26,8 +26,6 @@ static int l2c310_buffer[L2C310_COUNTERS_NUM * 2];
26 26
27static void __iomem *l2c310_base; 27static void __iomem *l2c310_base;
28 28
29
30
31static void gator_events_l2c310_reset_counters(void) 29static void gator_events_l2c310_reset_counters(void)
32{ 30{
33 u32 val = readl(l2c310_base + L2X0_EVENT_CNT_CTRL); 31 u32 val = readl(l2c310_base + L2X0_EVENT_CNT_CTRL);
@@ -37,9 +35,8 @@ static void gator_events_l2c310_reset_counters(void)
37 writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL); 35 writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL);
38} 36}
39 37
40
41static int gator_events_l2c310_create_files(struct super_block *sb, 38static int gator_events_l2c310_create_files(struct super_block *sb,
42 struct dentry *root) 39 struct dentry *root)
43{ 40{
44 int i; 41 int i;
45 42
@@ -52,11 +49,11 @@ static int gator_events_l2c310_create_files(struct super_block *sb,
52 if (WARN_ON(!dir)) 49 if (WARN_ON(!dir))
53 return -1; 50 return -1;
54 gatorfs_create_ulong(sb, dir, "enabled", 51 gatorfs_create_ulong(sb, dir, "enabled",
55 &l2c310_counters[i].enabled); 52 &l2c310_counters[i].enabled);
56 gatorfs_create_ulong(sb, dir, "event", 53 gatorfs_create_ulong(sb, dir, "event",
57 &l2c310_counters[i].event); 54 &l2c310_counters[i].event);
58 gatorfs_create_ro_ulong(sb, dir, "key", 55 gatorfs_create_ro_ulong(sb, dir, "key",
59 &l2c310_counters[i].key); 56 &l2c310_counters[i].key);
60 } 57 }
61 58
62 return 0; 59 return 0;
@@ -73,7 +70,7 @@ static int gator_events_l2c310_start(void)
73 /* Counter event sources */ 70 /* Counter event sources */
74 for (i = 0; i < L2C310_COUNTERS_NUM; i++) 71 for (i = 0; i < L2C310_COUNTERS_NUM; i++)
75 writel((l2c310_counters[i].event & 0xf) << 2, 72 writel((l2c310_counters[i].event & 0xf) << 2,
76 l2c310_base + l2x0_event_cntx_cfg[i]); 73 l2c310_base + l2x0_event_cntx_cfg[i]);
77 74
78 gator_events_l2c310_reset_counters(); 75 gator_events_l2c310_reset_counters();
79 76
@@ -105,10 +102,10 @@ static int gator_events_l2c310_read(int **buffer)
105 if (l2c310_counters[i].enabled) { 102 if (l2c310_counters[i].enabled) {
106 l2c310_buffer[len++] = l2c310_counters[i].key; 103 l2c310_buffer[len++] = l2c310_counters[i].key;
107 l2c310_buffer[len++] = readl(l2c310_base + 104 l2c310_buffer[len++] = readl(l2c310_base +
108 l2x0_event_cntx_val[i]); 105 l2x0_event_cntx_val[i]);
109 } 106 }
110 } 107 }
111 108
112 /* l2c310 counters are saturating, not wrapping in case of overflow */ 109 /* l2c310 counters are saturating, not wrapping in case of overflow */
113 gator_events_l2c310_reset_counters(); 110 gator_events_l2c310_reset_counters();
114 111
@@ -176,4 +173,5 @@ int gator_events_l2c310_init(void)
176 173
177 return gator_events_install(&gator_events_l2c310_interface); 174 return gator_events_install(&gator_events_l2c310_interface);
178} 175}
176
179gator_events_init(gator_events_l2c310_init); 177gator_events_init(gator_events_l2c310_init);
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c
index a44cd8e..34a73c8 100644
--- a/driver/gator_events_mali_400.c
+++ b/driver/gator_events_mali_400.c
@@ -17,14 +17,6 @@
17#include "gator_events_mali_common.h" 17#include "gator_events_mali_common.h"
18#include "gator_events_mali_400.h" 18#include "gator_events_mali_400.h"
19 19
20#if !defined(GATOR_MALI_INTERFACE_STYLE)
21/*
22 * At the moment, we only have users with the old style interface, so
23 * make our life easier by making it the default...
24 */
25#define GATOR_MALI_INTERFACE_STYLE (2)
26#endif
27
28/* 20/*
29 * There are (currently) three different variants of the comms between gator and Mali: 21 * There are (currently) three different variants of the comms between gator and Mali:
30 * 1 (deprecated): No software counter support 22 * 1 (deprecated): No software counter support
@@ -60,81 +52,81 @@
60#define NUM_FP_UNITS (4) 52#define NUM_FP_UNITS (4)
61 53
62enum counters { 54enum counters {
63 /* Timeline activity */ 55 /* Timeline activity */
64 ACTIVITY_VP = 0, 56 ACTIVITY_VP = 0,
65 ACTIVITY_FP0, 57 ACTIVITY_FP0,
66 ACTIVITY_FP1, 58 ACTIVITY_FP1,
67 ACTIVITY_FP2, 59 ACTIVITY_FP2,
68 ACTIVITY_FP3, 60 ACTIVITY_FP3,
69 61
70 /* L2 cache counters */ 62 /* L2 cache counters */
71 COUNTER_L2_C0, 63 COUNTER_L2_C0,
72 COUNTER_L2_C1, 64 COUNTER_L2_C1,
73 65
74 /* Vertex processor counters */ 66 /* Vertex processor counters */
75 COUNTER_VP_C0, 67 COUNTER_VP_C0,
76 COUNTER_VP_C1, 68 COUNTER_VP_C1,
77 69
78 /* Fragment processor counters */ 70 /* Fragment processor counters */
79 COUNTER_FP0_C0, 71 COUNTER_FP0_C0,
80 COUNTER_FP0_C1, 72 COUNTER_FP0_C1,
81 COUNTER_FP1_C0, 73 COUNTER_FP1_C0,
82 COUNTER_FP1_C1, 74 COUNTER_FP1_C1,
83 COUNTER_FP2_C0, 75 COUNTER_FP2_C0,
84 COUNTER_FP2_C1, 76 COUNTER_FP2_C1,
85 COUNTER_FP3_C0, 77 COUNTER_FP3_C0,
86 COUNTER_FP3_C1, 78 COUNTER_FP3_C1,
87 79
88 /* EGL Software Counters */ 80 /* EGL Software Counters */
89 COUNTER_EGL_BLIT_TIME, 81 COUNTER_EGL_BLIT_TIME,
90 82
91 /* GLES Software Counters */ 83 /* GLES Software Counters */
92 COUNTER_GLES_DRAW_ELEMENTS_CALLS, 84 COUNTER_GLES_DRAW_ELEMENTS_CALLS,
93 COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, 85 COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
94 COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, 86 COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
95 COUNTER_GLES_DRAW_ARRAYS_CALLS, 87 COUNTER_GLES_DRAW_ARRAYS_CALLS,
96 COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, 88 COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
97 COUNTER_GLES_DRAW_POINTS, 89 COUNTER_GLES_DRAW_POINTS,
98 COUNTER_GLES_DRAW_LINES, 90 COUNTER_GLES_DRAW_LINES,
99 COUNTER_GLES_DRAW_LINE_LOOP, 91 COUNTER_GLES_DRAW_LINE_LOOP,
100 COUNTER_GLES_DRAW_LINE_STRIP, 92 COUNTER_GLES_DRAW_LINE_STRIP,
101 COUNTER_GLES_DRAW_TRIANGLES, 93 COUNTER_GLES_DRAW_TRIANGLES,
102 COUNTER_GLES_DRAW_TRIANGLE_STRIP, 94 COUNTER_GLES_DRAW_TRIANGLE_STRIP,
103 COUNTER_GLES_DRAW_TRIANGLE_FAN, 95 COUNTER_GLES_DRAW_TRIANGLE_FAN,
104 COUNTER_GLES_NON_VBO_DATA_COPY_TIME, 96 COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
105 COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, 97 COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
106 COUNTER_GLES_UPLOAD_TEXTURE_TIME, 98 COUNTER_GLES_UPLOAD_TEXTURE_TIME,
107 COUNTER_GLES_UPLOAD_VBO_TIME, 99 COUNTER_GLES_UPLOAD_VBO_TIME,
108 COUNTER_GLES_NUM_FLUSHES, 100 COUNTER_GLES_NUM_FLUSHES,
109 COUNTER_GLES_NUM_VSHADERS_GENERATED, 101 COUNTER_GLES_NUM_VSHADERS_GENERATED,
110 COUNTER_GLES_NUM_FSHADERS_GENERATED, 102 COUNTER_GLES_NUM_FSHADERS_GENERATED,
111 COUNTER_GLES_VSHADER_GEN_TIME, 103 COUNTER_GLES_VSHADER_GEN_TIME,
112 COUNTER_GLES_FSHADER_GEN_TIME, 104 COUNTER_GLES_FSHADER_GEN_TIME,
113 COUNTER_GLES_INPUT_TRIANGLES, 105 COUNTER_GLES_INPUT_TRIANGLES,
114 COUNTER_GLES_VXCACHE_HIT, 106 COUNTER_GLES_VXCACHE_HIT,
115 COUNTER_GLES_VXCACHE_MISS, 107 COUNTER_GLES_VXCACHE_MISS,
116 COUNTER_GLES_VXCACHE_COLLISION, 108 COUNTER_GLES_VXCACHE_COLLISION,
117 COUNTER_GLES_CULLED_TRIANGLES, 109 COUNTER_GLES_CULLED_TRIANGLES,
118 COUNTER_GLES_CULLED_LINES, 110 COUNTER_GLES_CULLED_LINES,
119 COUNTER_GLES_BACKFACE_TRIANGLES, 111 COUNTER_GLES_BACKFACE_TRIANGLES,
120 COUNTER_GLES_GBCLIP_TRIANGLES, 112 COUNTER_GLES_GBCLIP_TRIANGLES,
121 COUNTER_GLES_GBCLIP_LINES, 113 COUNTER_GLES_GBCLIP_LINES,
122 COUNTER_GLES_TRIANGLES_DRAWN, 114 COUNTER_GLES_TRIANGLES_DRAWN,
123 COUNTER_GLES_DRAWCALL_TIME, 115 COUNTER_GLES_DRAWCALL_TIME,
124 COUNTER_GLES_TRIANGLES_COUNT, 116 COUNTER_GLES_TRIANGLES_COUNT,
125 COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, 117 COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
126 COUNTER_GLES_STRIP_TRIANGLES_COUNT, 118 COUNTER_GLES_STRIP_TRIANGLES_COUNT,
127 COUNTER_GLES_FAN_TRIANGLES_COUNT, 119 COUNTER_GLES_FAN_TRIANGLES_COUNT,
128 COUNTER_GLES_LINES_COUNT, 120 COUNTER_GLES_LINES_COUNT,
129 COUNTER_GLES_INDEPENDENT_LINES_COUNT, 121 COUNTER_GLES_INDEPENDENT_LINES_COUNT,
130 COUNTER_GLES_STRIP_LINES_COUNT, 122 COUNTER_GLES_STRIP_LINES_COUNT,
131 COUNTER_GLES_LOOP_LINES_COUNT, 123 COUNTER_GLES_LOOP_LINES_COUNT,
132 124
133 COUNTER_FILMSTRIP, 125 COUNTER_FILMSTRIP,
134 COUNTER_FREQUENCY, 126 COUNTER_FREQUENCY,
135 COUNTER_VOLTAGE, 127 COUNTER_VOLTAGE,
136 128
137 NUMBER_OF_EVENTS 129 NUMBER_OF_EVENTS
138}; 130};
139 131
140#define FIRST_ACTIVITY_EVENT ACTIVITY_VP 132#define FIRST_ACTIVITY_EVENT ACTIVITY_VP
@@ -161,7 +153,7 @@ static unsigned long counter_key[NUMBER_OF_EVENTS];
161/* The data we have recorded */ 153/* The data we have recorded */
162static u32 counter_data[NUMBER_OF_EVENTS]; 154static u32 counter_data[NUMBER_OF_EVENTS];
163/* The address to sample (or 0 if samples are sent to us) */ 155/* The address to sample (or 0 if samples are sent to us) */
164static u32* counter_address[NUMBER_OF_EVENTS]; 156static u32 *counter_address[NUMBER_OF_EVENTS];
165 157
166/* An array used to return the data we recorded 158/* An array used to return the data we recorded
167 * as key,value pairs hence the *2 159 * as key,value pairs hence the *2
@@ -177,13 +169,12 @@ static int trace_registered;
177 */ 169 */
178static u32 get_difference(u32 start, u32 end) 170static u32 get_difference(u32 start, u32 end)
179{ 171{
180 if (start - end >= 0) 172 if (start - end >= 0) {
181 { 173 return start - end;
182 return start - end; 174 }
183 }
184 175
185 // Mali counters are unsigned 32 bit values that wrap. 176 // Mali counters are unsigned 32 bit values that wrap.
186 return (4294967295u - end) + start; 177 return (4294967295u - end) + start;
187} 178}
188 179
189/** 180/**
@@ -191,8 +182,8 @@ static u32 get_difference(u32 start, u32 end)
191 */ 182 */
192static inline int is_activity_counter(unsigned int event_id) 183static inline int is_activity_counter(unsigned int event_id)
193{ 184{
194 return (event_id >= FIRST_ACTIVITY_EVENT && 185 return (event_id >= FIRST_ACTIVITY_EVENT &&
195 event_id <= LAST_ACTIVITY_EVENT); 186 event_id <= LAST_ACTIVITY_EVENT);
196} 187}
197 188
198/** 189/**
@@ -200,7 +191,7 @@ static inline int is_activity_counter(unsigned int event_id)
200 */ 191 */
201static inline int is_hw_counter(unsigned int event_id) 192static inline int is_hw_counter(unsigned int event_id)
202{ 193{
203 return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER); 194 return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
204} 195}
205 196
206#if GATOR_MALI_INTERFACE_STYLE == 2 197#if GATOR_MALI_INTERFACE_STYLE == 2
@@ -209,7 +200,7 @@ static inline int is_hw_counter(unsigned int event_id)
209 */ 200 */
210static inline int is_sw_counter(unsigned int event_id) 201static inline int is_sw_counter(unsigned int event_id)
211{ 202{
212 return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER); 203 return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
213} 204}
214#endif 205#endif
215 206
@@ -217,209 +208,204 @@ static inline int is_sw_counter(unsigned int event_id)
217/* 208/*
218 * The Mali DDK uses s64 types to contain software counter values, but gator 209 * The Mali DDK uses s64 types to contain software counter values, but gator
219 * can only use a maximum of 32 bits. This function scales a software counter 210 * can only use a maximum of 32 bits. This function scales a software counter
220 * to an appopriate range. 211 * to an appropriate range.
221 */ 212 */
222static u32 scale_sw_counter_value(unsigned int event_id, signed long long value) 213static u32 scale_sw_counter_value(unsigned int event_id, signed long long value)
223{ 214{
224 u32 scaled_value; 215 u32 scaled_value;
225 216
226 switch (event_id) { 217 switch (event_id) {
227 case COUNTER_GLES_UPLOAD_TEXTURE_TIME: 218 case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
228 case COUNTER_GLES_UPLOAD_VBO_TIME: 219 case COUNTER_GLES_UPLOAD_VBO_TIME:
229 scaled_value = (u32)div_s64(value, 1000000); 220 scaled_value = (u32)div_s64(value, 1000000);
230 break; 221 break;
231 default: 222 default:
232 scaled_value = (u32)value; 223 scaled_value = (u32)value;
233 break; 224 break;
234 } 225 }
235 226
236 return scaled_value; 227 return scaled_value;
237} 228}
238#endif 229#endif
239 230
240/* Probe for continuously sampled counter */ 231/* Probe for continuously sampled counter */
241#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING 232#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
242GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32* addr)) 233GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr))
243{ 234{
244 /* Turning on too many pr_debug statements in frequently called functions 235 /* Turning on too many pr_debug statements in frequently called functions
245 * can cause stability and/or performance problems 236 * can cause stability and/or performance problems
246 */ 237 */
247 //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr); 238 //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
248 if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) { 239 if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
249 counter_address[event_id] = addr; 240 counter_address[event_id] = addr;
250 } 241 }
251} 242}
252#endif 243#endif
253 244
254/* Probe for hardware counter events */ 245/* Probe for hardware counter events */
255GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value)) 246GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value))
256{ 247{
257 /* Turning on too many pr_debug statements in frequently called functions 248 /* Turning on too many pr_debug statements in frequently called functions
258 * can cause stability and/or performance problems 249 * can cause stability and/or performance problems
259 */ 250 */
260 //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value); 251 //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
261 if (is_hw_counter(event_id)) { 252 if (is_hw_counter(event_id)) {
262 counter_data[event_id] = value; 253 counter_data[event_id] = value;
263 } 254 }
264} 255}
265 256
266#if GATOR_MALI_INTERFACE_STYLE == 2 257#if GATOR_MALI_INTERFACE_STYLE == 2
267GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value)) 258GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value))
268{ 259{
269 if (is_sw_counter(event_id)) { 260 if (is_sw_counter(event_id)) {
270 counter_data[event_id] = scale_sw_counter_value(event_id, value); 261 counter_data[event_id] = scale_sw_counter_value(event_id, value);
271 } 262 }
272} 263}
273#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */ 264#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */
274 265
275
276#if GATOR_MALI_INTERFACE_STYLE == 3 266#if GATOR_MALI_INTERFACE_STYLE == 3
277GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters)) 267GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters))
278{ 268{
279 u32 i; 269 u32 i;
280 270
281 /* Copy over the values for those counters which are enabled. */ 271 /* Copy over the values for those counters which are enabled. */
282 for(i=FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) 272 for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
283 { 273 if (counter_enabled[i]) {
284 if(counter_enabled[i]) 274 counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
285 { 275 }
286 counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]); 276 }
287 }
288 }
289} 277}
290#endif /* GATOR_MALI_INTERFACE_STYLE == 3 */ 278#endif /* GATOR_MALI_INTERFACE_STYLE == 3 */
291 279
292static int create_files(struct super_block *sb, struct dentry *root) { 280static int create_files(struct super_block *sb, struct dentry *root)
293 struct dentry *dir; 281{
294 int event; 282 struct dentry *dir;
295 int n_fp = NUM_FP_UNITS; 283 int event;
296 284 int n_fp = NUM_FP_UNITS;
297 const char* mali_name = gator_mali_get_mali_name(); 285
298 286 const char *mali_name = gator_mali_get_mali_name();
299 /* 287
300 * Create the filesystem entries for vertex processor, fragement processor 288 /*
301 * and L2 cache timeline and hardware counters. Software counters get 289 * Create the filesystem entries for vertex processor, fragment processor
302 * special handling after this block. 290 * and L2 cache timeline and hardware counters. Software counters get
303 */ 291 * special handling after this block.
304 for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) 292 */
305 { 293 for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) {
306 char buf[40]; 294 char buf[40];
307 295
308 /* 296 /*
309 * We can skip this event if it's for a non-existent fragment 297 * We can skip this event if it's for a non-existent fragment
310 * processor. 298 * processor.
311 */ 299 */
312 if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) || 300 if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0))
313 (((event - COUNTER_FP0_C0)/2 >= n_fp))) 301 || (((event - COUNTER_FP0_C0) / 2 >= n_fp))) {
314 { 302 continue;
315 continue; 303 }
316 } 304
317 305 /* Otherwise, set up the filesystem entry for this event. */
318 /* Otherwise, set up the filesystem entry for this event. */ 306 switch (event) {
319 switch (event) { 307 case ACTIVITY_VP:
320 case ACTIVITY_VP: 308 snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
321 snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name); 309 break;
322 break; 310 case ACTIVITY_FP0:
323 case ACTIVITY_FP0: 311 case ACTIVITY_FP1:
324 case ACTIVITY_FP1: 312 case ACTIVITY_FP2:
325 case ACTIVITY_FP2: 313 case ACTIVITY_FP3:
326 case ACTIVITY_FP3: 314 snprintf(buf, sizeof buf, "ARM_%s_FP%d_active",
327 snprintf(buf, sizeof buf, "ARM_%s_FP%d_active", 315 mali_name, event - ACTIVITY_FP0);
328 mali_name, event - ACTIVITY_FP0); 316 break;
329 break; 317 case COUNTER_L2_C0:
330 case COUNTER_L2_C0: 318 case COUNTER_L2_C1:
331 case COUNTER_L2_C1: 319 snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d",
332 snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d", 320 mali_name, event - COUNTER_L2_C0);
333 mali_name, event - COUNTER_L2_C0); 321 break;
334 break; 322 case COUNTER_VP_C0:
335 case COUNTER_VP_C0: 323 case COUNTER_VP_C1:
336 case COUNTER_VP_C1: 324 snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d",
337 snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d", 325 mali_name, event - COUNTER_VP_C0);
338 mali_name, event - COUNTER_VP_C0); 326 break;
339 break; 327 case COUNTER_FP0_C0:
340 case COUNTER_FP0_C0: 328 case COUNTER_FP0_C1:
341 case COUNTER_FP0_C1: 329 case COUNTER_FP1_C0:
342 case COUNTER_FP1_C0: 330 case COUNTER_FP1_C1:
343 case COUNTER_FP1_C1: 331 case COUNTER_FP2_C0:
344 case COUNTER_FP2_C0: 332 case COUNTER_FP2_C1:
345 case COUNTER_FP2_C1: 333 case COUNTER_FP3_C0:
346 case COUNTER_FP3_C0: 334 case COUNTER_FP3_C1:
347 case COUNTER_FP3_C1: 335 snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d",
348 snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d", mali_name, 336 mali_name, (event - COUNTER_FP0_C0) / 2,
349 (event - COUNTER_FP0_C0) / 2, (event - COUNTER_FP0_C0) % 2); 337 (event - COUNTER_FP0_C0) % 2);
350 break; 338 break;
351 default: 339 default:
352 printk("gator: trying to create file for non-existent counter (%d)\n", event); 340 printk("gator: trying to create file for non-existent counter (%d)\n", event);
353 continue; 341 continue;
354 } 342 }
355 343
356 dir = gatorfs_mkdir(sb, root, buf); 344 dir = gatorfs_mkdir(sb, root, buf);
357 345
358 if (!dir) { 346 if (!dir) {
359 return -1; 347 return -1;
360 } 348 }
361 349
362 gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); 350 gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
363 351
364 /* Only create an event node for counters that can change what they count */ 352 /* Only create an event node for counters that can change what they count */
365 if (event >= COUNTER_L2_C0) { 353 if (event >= COUNTER_L2_C0) {
366 gatorfs_create_ulong(sb, dir, "event", &counter_event[event]); 354 gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
367 } 355 }
368 356
369 gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); 357 gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
370 } 358 }
371 359
372 /* Now set up the software counter entries */ 360 /* Now set up the software counter entries */
373 for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) 361 for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) {
374 { 362 char buf[40];
375 char buf[40]; 363
376 364 snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event);
377 snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event); 365
378 366 dir = gatorfs_mkdir(sb, root, buf);
379 dir = gatorfs_mkdir(sb, root, buf); 367
380 368 if (!dir) {
381 if (!dir) { 369 return -1;
382 return -1; 370 }
383 } 371
384 372 gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
385 gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); 373 gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
386 gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); 374 }
387 } 375
388 376 /* Now set up the special counter entries */
389 /* Now set up the special counter entries */ 377 for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++) {
390 for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++) 378 char buf[40];
391 { 379
392 char buf[40]; 380 switch (event) {
393 381 case COUNTER_FILMSTRIP:
394 switch(event) { 382 snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name);
395 case COUNTER_FILMSTRIP: 383 break;
396 snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name); 384
397 break; 385 case COUNTER_FREQUENCY:
398 386 snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name);
399 case COUNTER_FREQUENCY: 387 break;
400 snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name); 388
401 break; 389 case COUNTER_VOLTAGE:
402 390 snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name);
403 case COUNTER_VOLTAGE: 391 break;
404 snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name); 392
405 break; 393 default:
406 394 break;
407 default: 395 }
408 break; 396
409 } 397 dir = gatorfs_mkdir(sb, root, buf);
410 398
411 dir = gatorfs_mkdir(sb, root, buf); 399 if (!dir) {
412 400 return -1;
413 if (!dir) { 401 }
414 return -1; 402
415 } 403 gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
416 404 gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
417 gatorfs_create_ulong(sb, dir, "event", &counter_event[event]); 405 gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
418 gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); 406 }
419 gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); 407
420 } 408 return 0;
421
422 return 0;
423} 409}
424 410
425/* 411/*
@@ -434,312 +420,311 @@ static mali_profiling_get_counters_type *mali_get_counters = NULL;
434 */ 420 */
435static int is_any_sw_counter_enabled(void) 421static int is_any_sw_counter_enabled(void)
436{ 422{
437 unsigned int i; 423 unsigned int i;
438 424
439 for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) 425 for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
440 { 426 if (counter_enabled[i]) {
441 if (counter_enabled[i]) 427 return 1; /* At least one counter is enabled */
442 { 428 }
443 return 1; /* At least one counter is enabled */ 429 }
444 }
445 }
446 430
447 return 0; /* No s/w counters enabled */ 431 return 0; /* No s/w counters enabled */
448} 432}
449 433
450static void mali_counter_initialize(void) 434static void mali_counter_initialize(void)
451{ 435{
452 /* If a Mali driver is present and exporting the appropriate symbol 436 /* If a Mali driver is present and exporting the appropriate symbol
453 * then we can request the HW counters (of which there are only 2) 437 * then we can request the HW counters (of which there are only 2)
454 * be configured to count the desired events 438 * be configured to count the desired events
455 */ 439 */
456 mali_profiling_set_event_type *mali_set_hw_event; 440 mali_profiling_set_event_type *mali_set_hw_event;
457 mali_osk_fb_control_set_type *mali_set_fb_event; 441 mali_osk_fb_control_set_type *mali_set_fb_event;
458 mali_profiling_control_type *mali_control; 442 mali_profiling_control_type *mali_control;
459 443
460 mali_set_hw_event = symbol_get(_mali_profiling_set_event); 444 mali_set_hw_event = symbol_get(_mali_profiling_set_event);
461 445
462 if (mali_set_hw_event) { 446 if (mali_set_hw_event) {
463 int i; 447 int i;
464 448
465 pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event); 449 pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
466 450
467 for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { 451 for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
468 if (counter_enabled[i]) { 452 if (counter_enabled[i]) {
469 mali_set_hw_event(i, counter_event[i]); 453 mali_set_hw_event(i, counter_event[i]);
470 } else { 454 } else {
471 mali_set_hw_event(i, 0xFFFFFFFF); 455 mali_set_hw_event(i, 0xFFFFFFFF);
472 } 456 }
473 } 457 }
474 458
475 symbol_put(_mali_profiling_set_event); 459 symbol_put(_mali_profiling_set_event);
476 } else { 460 } else {
477 printk("gator: mali online _mali_profiling_set_event symbol not found\n"); 461 printk("gator: mali online _mali_profiling_set_event symbol not found\n");
478 } 462 }
479 463
480 mali_set_fb_event = symbol_get(_mali_osk_fb_control_set); 464 mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
481 465
482 if (mali_set_fb_event) { 466 if (mali_set_fb_event) {
483 pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event); 467 pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
484 468
485 mali_set_fb_event(0,(counter_enabled[COUNTER_FILMSTRIP]?1:0)); 469 mali_set_fb_event(0, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
486 470
487 symbol_put(_mali_osk_fb_control_set); 471 symbol_put(_mali_osk_fb_control_set);
488 } else { 472 } else {
489 printk("gator: mali online _mali_osk_fb_control_set symbol not found\n"); 473 printk("gator: mali online _mali_osk_fb_control_set symbol not found\n");
490 } 474 }
491 475
492 /* Generic control interface for Mali DDK. */ 476 /* Generic control interface for Mali DDK. */
493 mali_control = symbol_get(_mali_profiling_control); 477 mali_control = symbol_get(_mali_profiling_control);
494 if (mali_control) { 478 if (mali_control) {
495 /* The event attribute in the XML file keeps the actual frame rate. */ 479 /* The event attribute in the XML file keeps the actual frame rate. */
496 unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff; 480 unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
497 unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff; 481 unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;
498 482
499 pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control); 483 pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);
500 484
501 mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled()?1:0)); 485 mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled() ? 1 : 0));
502 mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP]?1:0)); 486 mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
503 mali_control(FBDUMP_CONTROL_RATE, rate); 487 mali_control(FBDUMP_CONTROL_RATE, rate);
504 mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor); 488 mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);
505 489
506 pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP]?1:0), rate); 490 pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0), rate);
507 491
508 symbol_put(_mali_profiling_control); 492 symbol_put(_mali_profiling_control);
509 } else { 493 } else {
510 printk("gator: mali online _mali_profiling_control symbol not found\n"); 494 printk("gator: mali online _mali_profiling_control symbol not found\n");
511 } 495 }
512 496
513 mali_get_counters = symbol_get(_mali_profiling_get_counters); 497 mali_get_counters = symbol_get(_mali_profiling_get_counters);
514 if (mali_get_counters){ 498 if (mali_get_counters) {
515 pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters); 499 pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters);
516 counter_prev[COUNTER_L2_C0] = 0; 500 counter_prev[COUNTER_L2_C0] = 0;
517 counter_prev[COUNTER_L2_C1] = 0; 501 counter_prev[COUNTER_L2_C1] = 0;
518 } 502 } else {
519 else{ 503 pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined");
520 pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined"); 504 }
521 }
522} 505}
523 506
524static void mali_counter_deinitialize(void) 507static void mali_counter_deinitialize(void)
525{ 508{
526 mali_profiling_set_event_type *mali_set_hw_event; 509 mali_profiling_set_event_type *mali_set_hw_event;
527 mali_osk_fb_control_set_type *mali_set_fb_event; 510 mali_osk_fb_control_set_type *mali_set_fb_event;
528 mali_profiling_control_type *mali_control; 511 mali_profiling_control_type *mali_control;
529 512
530 mali_set_hw_event = symbol_get(_mali_profiling_set_event); 513 mali_set_hw_event = symbol_get(_mali_profiling_set_event);
531 514
532 if (mali_set_hw_event) { 515 if (mali_set_hw_event) {
533 int i; 516 int i;
534
535 pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event);
536 for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
537 mali_set_hw_event(i, 0xFFFFFFFF);
538 }
539
540 symbol_put(_mali_profiling_set_event);
541 } else {
542 printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
543 }
544 517
545 mali_set_fb_event = symbol_get(_mali_osk_fb_control_set); 518 pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
519 for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
520 mali_set_hw_event(i, 0xFFFFFFFF);
521 }
546 522
547 if (mali_set_fb_event) { 523 symbol_put(_mali_profiling_set_event);
548 pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event); 524 } else {
525 printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
526 }
549 527
550 mali_set_fb_event(0,0); 528 mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
551 529
552 symbol_put(_mali_osk_fb_control_set); 530 if (mali_set_fb_event) {
553 } else { 531 pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
554 printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
555 }
556 532
557 /* Generic control interface for Mali DDK. */ 533 mali_set_fb_event(0, 0);
558 mali_control = symbol_get(_mali_profiling_control);
559 534
560 if (mali_control) { 535 symbol_put(_mali_osk_fb_control_set);
561 pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event); 536 } else {
537 printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
538 }
562 539
563 /* Reset the DDK state - disable counter collection */ 540 /* Generic control interface for Mali DDK. */
564 mali_control(SW_EVENTS_ENABLE, 0); 541 mali_control = symbol_get(_mali_profiling_control);
565 542
566 mali_control(FBDUMP_CONTROL_ENABLE, 0); 543 if (mali_control) {
544 pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event);
567 545
568 symbol_put(_mali_profiling_control); 546 /* Reset the DDK state - disable counter collection */
569 } else { 547 mali_control(SW_EVENTS_ENABLE, 0);
570 printk("gator: mali offline _mali_profiling_control symbol not found\n");
571 }
572 548
573 if (mali_get_counters){ 549 mali_control(FBDUMP_CONTROL_ENABLE, 0);
574 symbol_put(_mali_profiling_get_counters); 550
575 } 551 symbol_put(_mali_profiling_control);
552 } else {
553 printk("gator: mali offline _mali_profiling_control symbol not found\n");
554 }
555
556 if (mali_get_counters) {
557 symbol_put(_mali_profiling_get_counters);
558 }
576 559
577} 560}
578 561
579static int start(void) { 562static int start(void)
580 // register tracepoints 563{
581 if (GATOR_REGISTER_TRACE(mali_hw_counter)) { 564 // register tracepoints
582 printk("gator: mali_hw_counter tracepoint failed to activate\n"); 565 if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
583 return -1; 566 printk("gator: mali_hw_counter tracepoint failed to activate\n");
584 } 567 return -1;
568 }
585 569
586#if GATOR_MALI_INTERFACE_STYLE == 1 570#if GATOR_MALI_INTERFACE_STYLE == 1
587 /* None. */ 571 /* None. */
588#elif GATOR_MALI_INTERFACE_STYLE == 2 572#elif GATOR_MALI_INTERFACE_STYLE == 2
589 /* For patched Mali driver. */ 573 /* For patched Mali driver. */
590 if (GATOR_REGISTER_TRACE(mali_sw_counter)) { 574 if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
591 printk("gator: mali_sw_counter tracepoint failed to activate\n"); 575 printk("gator: mali_sw_counter tracepoint failed to activate\n");
592 return -1; 576 return -1;
593 } 577 }
594#elif GATOR_MALI_INTERFACE_STYLE == 3 578#elif GATOR_MALI_INTERFACE_STYLE == 3
595/* For Mali drivers with built-in support. */ 579/* For Mali drivers with built-in support. */
596 if (GATOR_REGISTER_TRACE(mali_sw_counters)) { 580 if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
597 printk("gator: mali_sw_counters tracepoint failed to activate\n"); 581 printk("gator: mali_sw_counters tracepoint failed to activate\n");
598 return -1; 582 return -1;
599 } 583 }
600#else 584#else
601#error Unknown GATOR_MALI_INTERFACE_STYLE option. 585#error Unknown GATOR_MALI_INTERFACE_STYLE option.
602#endif 586#endif
603 587
604 trace_registered = 1; 588 trace_registered = 1;
605 589
606 mali_counter_initialize(); 590 mali_counter_initialize();
607 return 0; 591 return 0;
608} 592}
609 593
610static void stop(void) { 594static void stop(void)
611 unsigned int cnt; 595{
596 unsigned int cnt;
612 597
613 pr_debug("gator: mali stop\n"); 598 pr_debug("gator: mali stop\n");
614 599
615 if (trace_registered) { 600 if (trace_registered) {
616 GATOR_UNREGISTER_TRACE(mali_hw_counter); 601 GATOR_UNREGISTER_TRACE(mali_hw_counter);
617 602
618#if GATOR_MALI_INTERFACE_STYLE == 1 603#if GATOR_MALI_INTERFACE_STYLE == 1
619 /* None. */ 604 /* None. */
620#elif GATOR_MALI_INTERFACE_STYLE == 2 605#elif GATOR_MALI_INTERFACE_STYLE == 2
621 /* For patched Mali driver. */ 606 /* For patched Mali driver. */
622 GATOR_UNREGISTER_TRACE(mali_sw_counter); 607 GATOR_UNREGISTER_TRACE(mali_sw_counter);
623#elif GATOR_MALI_INTERFACE_STYLE == 3 608#elif GATOR_MALI_INTERFACE_STYLE == 3
624 /* For Mali drivers with built-in support. */ 609 /* For Mali drivers with built-in support. */
625 GATOR_UNREGISTER_TRACE(mali_sw_counters); 610 GATOR_UNREGISTER_TRACE(mali_sw_counters);
626#else 611#else
627#error Unknown GATOR_MALI_INTERFACE_STYLE option. 612#error Unknown GATOR_MALI_INTERFACE_STYLE option.
628#endif 613#endif
629 614
630 pr_debug("gator: mali timeline tracepoint deactivated\n"); 615 pr_debug("gator: mali timeline tracepoint deactivated\n");
631
632 trace_registered = 0;
633 }
634 616
635 for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) { 617 trace_registered = 0;
636 counter_enabled[cnt] = 0; 618 }
637 counter_event[cnt] = 0;
638 counter_address[cnt] = NULL;
639 }
640 619
641 mali_counter_deinitialize(); 620 for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
621 counter_enabled[cnt] = 0;
622 counter_event[cnt] = 0;
623 counter_address[cnt] = NULL;
624 }
625
626 mali_counter_deinitialize();
642} 627}
643 628
644static int read(int **buffer) { 629static int read(int **buffer)
645 int cnt, len = 0; 630{
646 631 int cnt, len = 0;
647 if (smp_processor_id()) return 0; 632
648 633 if (smp_processor_id())
649 // Read the L2 C0 and C1 here. 634 return 0;
650 if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1] ) { 635
651 u32 src0 = 0; 636 // Read the L2 C0 and C1 here.
652 u32 val0 = 0; 637 if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1]) {
653 u32 src1 = 0; 638 u32 src0 = 0;
654 u32 val1 = 0; 639 u32 val0 = 0;
655 640 u32 src1 = 0;
656 // Poke the driver to get the counter values 641 u32 val1 = 0;
657 if (mali_get_counters){ 642
658 mali_get_counters(&src0, &val0, &src1, &val1); 643 // Poke the driver to get the counter values
659 } 644 if (mali_get_counters) {
660 645 mali_get_counters(&src0, &val0, &src1, &val1);
661 if (counter_enabled[COUNTER_L2_C0]) 646 }
662 { 647
663 // Calculate and save src0's counter val0 648 if (counter_enabled[COUNTER_L2_C0]) {
664 counter_dump[len++] = counter_key[COUNTER_L2_C0]; 649 // Calculate and save src0's counter val0
665 counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]); 650 counter_dump[len++] = counter_key[COUNTER_L2_C0];
666 } 651 counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]);
667 652 }
668 if (counter_enabled[COUNTER_L2_C1]) 653
669 { 654 if (counter_enabled[COUNTER_L2_C1]) {
670 // Calculate and save src1's counter val1 655 // Calculate and save src1's counter val1
671 counter_dump[len++] = counter_key[COUNTER_L2_C1]; 656 counter_dump[len++] = counter_key[COUNTER_L2_C1];
672 counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]); 657 counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]);
673 } 658 }
674 659
675 // Save the previous values for the counters. 660 // Save the previous values for the counters.
676 counter_prev[COUNTER_L2_C0] = val0; 661 counter_prev[COUNTER_L2_C0] = val0;
677 counter_prev[COUNTER_L2_C1] = val1; 662 counter_prev[COUNTER_L2_C1] = val1;
678 } 663 }
679 664
680 // Process other (non-timeline) counters. 665 // Process other (non-timeline) counters.
681 for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) { 666 for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) {
682 if (counter_enabled[cnt]) { 667 if (counter_enabled[cnt]) {
683 counter_dump[len++] = counter_key[cnt]; 668 counter_dump[len++] = counter_key[cnt];
684 counter_dump[len++] = counter_data[cnt]; 669 counter_dump[len++] = counter_data[cnt];
685 670
686 counter_data[cnt] = 0; 671 counter_data[cnt] = 0;
687 } 672 }
688 } 673 }
689 674
690 /* 675 /*
691 * Add in the voltage and frequency counters if enabled. Note that, since these are 676 * Add in the voltage and frequency counters if enabled. Note that, since these are
692 * actually passed as events, the counter value should not be cleared. 677 * actually passed as events, the counter value should not be cleared.
693 */ 678 */
694 cnt = COUNTER_FREQUENCY; 679 cnt = COUNTER_FREQUENCY;
695 if (counter_enabled[cnt]) { 680 if (counter_enabled[cnt]) {
696 counter_dump[len++] = counter_key[cnt]; 681 counter_dump[len++] = counter_key[cnt];
697 counter_dump[len++] = counter_data[cnt]; 682 counter_dump[len++] = counter_data[cnt];
698 } 683 }
699 684
700 cnt = COUNTER_VOLTAGE; 685 cnt = COUNTER_VOLTAGE;
701 if (counter_enabled[cnt]) { 686 if (counter_enabled[cnt]) {
702 counter_dump[len++] = counter_key[cnt]; 687 counter_dump[len++] = counter_key[cnt];
703 counter_dump[len++] = counter_data[cnt]; 688 counter_dump[len++] = counter_data[cnt];
704 } 689 }
705 690
706 691 if (buffer) {
707 if (buffer) { 692 *buffer = (int *)counter_dump;
708 *buffer = (int*) counter_dump; 693 }
709 } 694
710 695 return len;
711 return len;
712} 696}
713 697
714static struct gator_interface gator_events_mali_interface = { 698static struct gator_interface gator_events_mali_interface = {
715 .create_files = create_files, 699 .create_files = create_files,
716 .start = start, 700 .start = start,
717 .stop = stop, 701 .stop = stop,
718 .read = read, 702 .read = read,
719}; 703};
720 704
721extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv) { 705extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv)
706{
722 counter_data[COUNTER_FREQUENCY] = frequency_mhz; 707 counter_data[COUNTER_FREQUENCY] = frequency_mhz;
723 counter_data[COUNTER_VOLTAGE] = voltage_mv; 708 counter_data[COUNTER_VOLTAGE] = voltage_mv;
724} 709}
725 710
726int gator_events_mali_init(void) 711int gator_events_mali_init(void)
727{ 712{
728 unsigned int cnt; 713 unsigned int cnt;
729 714
730 pr_debug("gator: mali init\n"); 715 pr_debug("gator: mali init\n");
731 716
732 for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) { 717 for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
733 counter_enabled[cnt] = 0; 718 counter_enabled[cnt] = 0;
734 counter_event[cnt] = 0; 719 counter_event[cnt] = 0;
735 counter_key[cnt] = gator_events_get_key(); 720 counter_key[cnt] = gator_events_get_key();
736 counter_address[cnt] = NULL; 721 counter_address[cnt] = NULL;
737 counter_data[cnt] = 0; 722 counter_data[cnt] = 0;
738 } 723 }
739 724
740 trace_registered = 0; 725 trace_registered = 0;
741 726
742 return gator_events_install(&gator_events_mali_interface); 727 return gator_events_install(&gator_events_mali_interface);
743} 728}
744 729
745gator_events_init(gator_events_mali_init); 730gator_events_init(gator_events_mali_init);
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c
index 62e441c..2186eee 100644
--- a/driver/gator_events_mali_common.c
+++ b/driver/gator_events_mali_common.c
@@ -10,69 +10,65 @@
10 10
11static u32 gator_mali_get_id(void) 11static u32 gator_mali_get_id(void)
12{ 12{
13 return MALI_SUPPORT; 13 return MALI_SUPPORT;
14} 14}
15 15
16extern const char* gator_mali_get_mali_name(void) 16extern const char *gator_mali_get_mali_name(void)
17{ 17{
18 u32 id = gator_mali_get_id(); 18 u32 id = gator_mali_get_id();
19 19
20 switch (id) { 20 switch (id) {
21 case MALI_T6xx: 21 case MALI_T6xx:
22 return "Mali-T6xx"; 22 return "Mali-T6xx";
23 case MALI_400: 23 case MALI_400:
24 return "Mali-400"; 24 return "Mali-400";
25 default: 25 default:
26 pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id); 26 pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id);
27 return "Mali-Unknown"; 27 return "Mali-Unknown";
28 } 28 }
29} 29}
30 30
31extern int gator_mali_create_file_system(const char* mali_name, const char* event_name, struct super_block *sb, struct dentry *root, mali_counter *counter) 31extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter)
32{ 32{
33 int err; 33 int err;
34 char buf[255]; 34 char buf[255];
35 struct dentry *dir; 35 struct dentry *dir;
36 36
37 /* If the counter name is empty ignore it*/ 37 /* If the counter name is empty ignore it */
38 if (strlen(event_name) != 0) 38 if (strlen(event_name) != 0) {
39 { 39 /* Set up the filesystem entry for this event. */
40 /* Set up the filesystem entry for this event. */ 40 snprintf(buf, sizeof(buf), "ARM_%s_%s", mali_name, event_name);
41 snprintf(buf, sizeof(buf), "ARM_%s_%s", mali_name, event_name);
42 41
43 dir = gatorfs_mkdir(sb, root, buf); 42 dir = gatorfs_mkdir(sb, root, buf);
44 43
45 if (dir == NULL) 44 if (dir == NULL) {
46 { 45 pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf);
47 pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf); 46 return -1;
48 return -1; 47 }
49 }
50 48
51 err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled); 49 err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled);
52 if (err != 0) 50 if (err != 0) {
53 { 51 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf);
54 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf); 52 return -1;
55 return -1; 53 }
56 } 54 err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key);
57 err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key); 55 if (err != 0) {
58 if (err != 0) 56 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf);
59 { 57 return -1;
60 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf); 58 }
61 return -1; 59 }
62 }
63 }
64 60
65 return 0; 61 return 0;
66} 62}
67 63
68extern void gator_mali_initialise_counters(mali_counter counters[], unsigned int n_counters) 64extern void gator_mali_initialise_counters(mali_counter counters[], unsigned int n_counters)
69{ 65{
70 unsigned int cnt; 66 unsigned int cnt;
71 67
72 for (cnt = 0; cnt < n_counters; cnt++) { 68 for (cnt = 0; cnt < n_counters; cnt++) {
73 mali_counter *counter = &counters[cnt]; 69 mali_counter *counter = &counters[cnt];
74 70
75 counter->key = gator_events_get_key(); 71 counter->key = gator_events_get_key();
76 counter->enabled = 0; 72 counter->enabled = 0;
77 } 73 }
78} 74}
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h
index 2c9457f..8e33edf 100644
--- a/driver/gator_events_mali_common.h
+++ b/driver/gator_events_mali_common.h
@@ -35,8 +35,8 @@
35 * Runtime state information for a counter. 35 * Runtime state information for a counter.
36 */ 36 */
37typedef struct { 37typedef struct {
38 unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */ 38 unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */
39 unsigned long enabled; /* counter enable state */ 39 unsigned long enabled; /* counter enable state */
40} mali_counter; 40} mali_counter;
41 41
42/* 42/*
@@ -45,7 +45,7 @@ typedef struct {
45typedef void mali_profiling_set_event_type(unsigned int, unsigned int); 45typedef void mali_profiling_set_event_type(unsigned int, unsigned int);
46typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int); 46typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int);
47typedef void mali_profiling_control_type(unsigned int, unsigned int); 47typedef void mali_profiling_control_type(unsigned int, unsigned int);
48typedef void mali_profiling_get_counters_type(unsigned int*, unsigned int*, unsigned int*, unsigned int*); 48typedef void mali_profiling_get_counters_type(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
49 49
50/* 50/*
51 * Driver entry points for functions called directly by gator. 51 * Driver entry points for functions called directly by gator.
@@ -53,14 +53,14 @@ typedef void mali_profiling_get_counters_type(unsigned int*, unsigned int*, unsi
53extern void _mali_profiling_set_event(unsigned int, unsigned int); 53extern void _mali_profiling_set_event(unsigned int, unsigned int);
54extern void _mali_osk_fb_control_set(unsigned int, unsigned int); 54extern void _mali_osk_fb_control_set(unsigned int, unsigned int);
55extern void _mali_profiling_control(unsigned int, unsigned int); 55extern void _mali_profiling_control(unsigned int, unsigned int);
56extern void _mali_profiling_get_counters(unsigned int*, unsigned int*, unsigned int*, unsigned int*); 56extern void _mali_profiling_get_counters(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
57 57
58/** 58/**
59 * Returns a name which identifies the GPU type (eg Mali-400, Mali-T6xx). 59 * Returns a name which identifies the GPU type (eg Mali-400, Mali-T6xx).
60 * 60 *
61 * @return The name as a constant string. 61 * @return The name as a constant string.
62 */ 62 */
63extern const char* gator_mali_get_mali_name(void); 63extern const char *gator_mali_get_mali_name(void);
64 64
65/** 65/**
66 * Creates a filesystem entry under /dev/gator relating to the specified event name and key, and 66 * Creates a filesystem entry under /dev/gator relating to the specified event name and key, and
@@ -75,10 +75,10 @@ extern const char* gator_mali_get_mali_name(void);
75 * 75 *
76 * @return 0 if entry point was created, non-zero if not. 76 * @return 0 if entry point was created, non-zero if not.
77 */ 77 */
78extern int gator_mali_create_file_system(const char* mali_name, const char* event_name, struct super_block *sb, struct dentry *root, mali_counter *counter); 78extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter);
79 79
80/** 80/**
81 * Initialises the counter array. 81 * Initializes the counter array.
82 * 82 *
83 * @param keys The array of counters 83 * @param keys The array of counters
84 * @param n_counters The number of entries in each of the arrays. 84 * @param n_counters The number of entries in each of the arrays.
diff --git a/driver/gator_events_mali_t6xx.c b/driver/gator_events_mali_t6xx.c
index f8f868e..1b3a53d 100644
--- a/driver/gator_events_mali_t6xx.c
+++ b/driver/gator_events_mali_t6xx.c
@@ -17,7 +17,6 @@
17 17
18#include "linux/mali_linux_trace.h" 18#include "linux/mali_linux_trace.h"
19 19
20
21#include "gator_events_mali_common.h" 20#include "gator_events_mali_common.h"
22 21
23/* 22/*
@@ -27,7 +26,6 @@
27#error MALI_SUPPORT set to an invalid device code: expecting MALI_T6xx 26#error MALI_SUPPORT set to an invalid device code: expecting MALI_T6xx
28#endif 27#endif
29 28
30
31/* Counters for Mali-T6xx: 29/* Counters for Mali-T6xx:
32 * 30 *
33 * - Timeline events 31 * - Timeline events
@@ -43,72 +41,66 @@
43 */ 41 */
44 42
45/* Timeline (start/stop) activity */ 43/* Timeline (start/stop) activity */
46static const char* timeline_event_names [] = 44static const char *timeline_event_names[] = {
47{ 45 "PM_SHADER_0",
48 "PM_SHADER_0", 46 "PM_SHADER_1",
49 "PM_SHADER_1", 47 "PM_SHADER_2",
50 "PM_SHADER_2", 48 "PM_SHADER_3",
51 "PM_SHADER_3", 49 "PM_SHADER_4",
52 "PM_SHADER_4", 50 "PM_SHADER_5",
53 "PM_SHADER_5", 51 "PM_SHADER_6",
54 "PM_SHADER_6", 52 "PM_SHADER_7",
55 "PM_SHADER_7", 53 "PM_TILER_0",
56 "PM_TILER_0", 54 "PM_L2_0",
57 "PM_L2_0", 55 "PM_L2_1",
58 "PM_L2_1", 56 "MMU_AS_0",
59 "MMU_AS_0", 57 "MMU_AS_1",
60 "MMU_AS_1", 58 "MMU_AS_2",
61 "MMU_AS_2", 59 "MMU_AS_3"
62 "MMU_AS_3"
63}; 60};
64 61
65enum 62enum {
66{ 63 PM_SHADER_0 = 0,
67 PM_SHADER_0 = 0, 64 PM_SHADER_1,
68 PM_SHADER_1, 65 PM_SHADER_2,
69 PM_SHADER_2, 66 PM_SHADER_3,
70 PM_SHADER_3, 67 PM_SHADER_4,
71 PM_SHADER_4, 68 PM_SHADER_5,
72 PM_SHADER_5, 69 PM_SHADER_6,
73 PM_SHADER_6, 70 PM_SHADER_7,
74 PM_SHADER_7, 71 PM_TILER_0,
75 PM_TILER_0, 72 PM_L2_0,
76 PM_L2_0, 73 PM_L2_1,
77 PM_L2_1, 74 MMU_AS_0,
78 MMU_AS_0, 75 MMU_AS_1,
79 MMU_AS_1, 76 MMU_AS_2,
80 MMU_AS_2, 77 MMU_AS_3
81 MMU_AS_3
82}; 78};
83/* The number of shader blocks in the enum above */ 79/* The number of shader blocks in the enum above */
84#define NUM_PM_SHADER (8) 80#define NUM_PM_SHADER (8)
85 81
86/* Software Counters */ 82/* Software Counters */
87static const char* software_counter_names [] = 83static const char *software_counter_names[] = {
88{ 84 "MMU_PAGE_FAULT_0",
89 "MMU_PAGE_FAULT_0", 85 "MMU_PAGE_FAULT_1",
90 "MMU_PAGE_FAULT_1", 86 "MMU_PAGE_FAULT_2",
91 "MMU_PAGE_FAULT_2", 87 "MMU_PAGE_FAULT_3"
92 "MMU_PAGE_FAULT_3"
93}; 88};
94 89
95enum 90enum {
96{ 91 MMU_PAGE_FAULT_0 = 0,
97 MMU_PAGE_FAULT_0 = 0, 92 MMU_PAGE_FAULT_1,
98 MMU_PAGE_FAULT_1, 93 MMU_PAGE_FAULT_2,
99 MMU_PAGE_FAULT_2, 94 MMU_PAGE_FAULT_3
100 MMU_PAGE_FAULT_3
101}; 95};
102 96
103/* Software Counters */ 97/* Software Counters */
104static const char* accumulators_names [] = 98static const char *accumulators_names[] = {
105{ 99 "TOTAL_ALLOC_PAGES"
106 "TOTAL_ALLOC_PAGES"
107}; 100};
108 101
109enum 102enum {
110{ 103 TOTAL_ALLOC_PAGES = 0
111 TOTAL_ALLOC_PAGES = 0
112}; 104};
113 105
114#define FIRST_TIMELINE_EVENT (0) 106#define FIRST_TIMELINE_EVENT (0)
@@ -153,49 +145,46 @@ static struct timespec prev_timestamp;
153 */ 145 */
154static inline long get_duration_us(const struct timespec *start, const struct timespec *end) 146static inline long get_duration_us(const struct timespec *start, const struct timespec *end)
155{ 147{
156 long event_duration_us = (end->tv_nsec - start->tv_nsec)/1000; 148 long event_duration_us = (end->tv_nsec - start->tv_nsec) / 1000;
157 event_duration_us += (end->tv_sec - start->tv_sec) * 1000000; 149 event_duration_us += (end->tv_sec - start->tv_sec) * 1000000;
158 150
159 return event_duration_us; 151 return event_duration_us;
160} 152}
161 153
162static void record_timeline_event(unsigned int timeline_index, unsigned int type) 154static void record_timeline_event(unsigned int timeline_index, unsigned int type)
163{ 155{
164 struct timespec event_timestamp; 156 struct timespec event_timestamp;
165 struct timespec *event_start = &timeline_event_starttime[timeline_index]; 157 struct timespec *event_start = &timeline_event_starttime[timeline_index];
166 158
167 switch(type) 159 switch (type) {
168 { 160 case ACTIVITY_START:
169 case ACTIVITY_START: 161 /* Get the event time... */
170 /* Get the event time... */ 162 getnstimeofday(&event_timestamp);
171 getnstimeofday(&event_timestamp); 163
172 164 /* Remember the start time if the activity is not already started */
173 /* Remember the start time if the activity is not already started */ 165 if (event_start->tv_sec == 0) {
174 if(event_start->tv_sec == 0) 166 *event_start = event_timestamp; /* Structure copy */
175 { 167 }
176 *event_start = event_timestamp; /* Structure copy */ 168 break;
177 } 169
178 break; 170 case ACTIVITY_STOP:
179 171 /* if the counter was started... */
180 case ACTIVITY_STOP: 172 if (event_start->tv_sec != 0) {
181 /* if the counter was started... */ 173 /* Get the event time... */
182 if(event_start->tv_sec != 0) 174 getnstimeofday(&event_timestamp);
183 { 175
184 /* Get the event time... */ 176 /* Accumulate the duration in us */
185 getnstimeofday(&event_timestamp); 177 timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp);
186 178
187 /* Accumulate the duration in us */ 179 /* Reset the start time to indicate the activity is stopped. */
188 timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp); 180 event_start->tv_sec = 0;
189 181 }
190 /* Reset the start time to indicate the activity is stopped. */ 182 break;
191 event_start->tv_sec = 0; 183
192 } 184 default:
193 break; 185 /* Other activity events are ignored. */
194 186 break;
195 default: 187 }
196 /* Other activity events are ignored. */
197 break;
198 }
199} 188}
200 189
201/* 190/*
@@ -204,68 +193,62 @@ static void record_timeline_event(unsigned int timeline_index, unsigned int type
204 193
205GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long long value)) 194GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long long value))
206{ 195{
207#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */ 196#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */
208#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */ 197#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */
209#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */ 198#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */
210#define BIT_AT(value, pos) ((value >> pos) & 1) 199#define BIT_AT(value, pos) ((value >> pos) & 1)
211 200
212 static unsigned long long previous_shader_bitmask = 0; 201 static unsigned long long previous_shader_bitmask = 0;
213 static unsigned long long previous_tiler_bitmask = 0; 202 static unsigned long long previous_tiler_bitmask = 0;
214 static unsigned long long previous_l2_bitmask = 0; 203 static unsigned long long previous_l2_bitmask = 0;
215 204
216 switch (event_id) 205 switch (event_id) {
217 { 206 case SHADER_PRESENT_LO:
218 case SHADER_PRESENT_LO: 207 {
219 { 208 unsigned long long changed_bitmask = previous_shader_bitmask ^ value;
220 unsigned long long changed_bitmask = previous_shader_bitmask ^ value; 209 int pos;
221 int pos; 210
222 211 for (pos = 0; pos < NUM_PM_SHADER; ++pos) {
223 for (pos = 0; pos < NUM_PM_SHADER; ++pos) 212 if (BIT_AT(changed_bitmask, pos)) {
224 { 213 record_timeline_event(PM_SHADER_0 + pos, BIT_AT(value, pos) ? ACTIVITY_START : ACTIVITY_STOP);
225 if (BIT_AT(changed_bitmask, pos)) 214 }
226 { 215 }
227 record_timeline_event(PM_SHADER_0 + pos, BIT_AT(value, pos) ? ACTIVITY_START : ACTIVITY_STOP); 216
228 } 217 previous_shader_bitmask = value;
229 } 218 break;
230 219 }
231 previous_shader_bitmask = value; 220
232 break; 221 case TILER_PRESENT_LO:
233 } 222 {
234 223 unsigned long long changed = previous_tiler_bitmask ^ value;
235 case TILER_PRESENT_LO: 224
236 { 225 if (BIT_AT(changed, 0)) {
237 unsigned long long changed = previous_tiler_bitmask ^ value; 226 record_timeline_event(PM_TILER_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
238 227 }
239 if (BIT_AT(changed, 0)) 228
240 { 229 previous_tiler_bitmask = value;
241 record_timeline_event(PM_TILER_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP); 230 break;
242 } 231 }
243 232
244 previous_tiler_bitmask = value; 233 case L2_PRESENT_LO:
245 break; 234 {
246 } 235 unsigned long long changed = previous_l2_bitmask ^ value;
247 236
248 case L2_PRESENT_LO: 237 if (BIT_AT(changed, 0)) {
249 { 238 record_timeline_event(PM_L2_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
250 unsigned long long changed = previous_l2_bitmask ^ value; 239 }
251 240 if (BIT_AT(changed, 4)) {
252 if (BIT_AT(changed, 0)) 241 record_timeline_event(PM_L2_1, BIT_AT(value, 4) ? ACTIVITY_START : ACTIVITY_STOP);
253 { 242 }
254 record_timeline_event(PM_L2_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP); 243
255 } 244 previous_l2_bitmask = value;
256 if (BIT_AT(changed, 4)) 245 break;
257 { 246 }
258 record_timeline_event(PM_L2_1, BIT_AT(value, 4) ? ACTIVITY_START : ACTIVITY_STOP); 247
259 } 248 default:
260 249 /* No other blocks are supported at present */
261 previous_l2_bitmask = value; 250 break;
262 break; 251 }
263 }
264
265 default:
266 /* No other blocks are supported at present */
267 break;
268 }
269 252
270#undef SHADER_PRESENT_LO 253#undef SHADER_PRESENT_LO
271#undef TILER_PRESENT_LO 254#undef TILER_PRESENT_LO
@@ -275,278 +258,255 @@ GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long
275 258
276GATOR_DEFINE_PROBE(mali_page_fault_insert_pages, TP_PROTO(int event_id, unsigned long value)) 259GATOR_DEFINE_PROBE(mali_page_fault_insert_pages, TP_PROTO(int event_id, unsigned long value))
277{ 260{
278 /* We add to the previous since we may receive many tracepoints in one sample period */ 261 /* We add to the previous since we may receive many tracepoints in one sample period */
279 sw_counter_data[MMU_PAGE_FAULT_0 + event_id] += value; 262 sw_counter_data[MMU_PAGE_FAULT_0 + event_id] += value;
280} 263}
281 264
282GATOR_DEFINE_PROBE(mali_mmu_as_in_use, TP_PROTO(int event_id)) 265GATOR_DEFINE_PROBE(mali_mmu_as_in_use, TP_PROTO(int event_id))
283{ 266{
284 record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_START); 267 record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_START);
285} 268}
286 269
287GATOR_DEFINE_PROBE(mali_mmu_as_released, TP_PROTO(int event_id)) 270GATOR_DEFINE_PROBE(mali_mmu_as_released, TP_PROTO(int event_id))
288{ 271{
289 record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_STOP); 272 record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_STOP);
290} 273}
291 274
292GATOR_DEFINE_PROBE(mali_total_alloc_pages_change, TP_PROTO(long long int event_id)) 275GATOR_DEFINE_PROBE(mali_total_alloc_pages_change, TP_PROTO(long long int event_id))
293{ 276{
294 accumulators_data[TOTAL_ALLOC_PAGES] = event_id; 277 accumulators_data[TOTAL_ALLOC_PAGES] = event_id;
295} 278}
296 279
297static int create_files(struct super_block *sb, struct dentry *root) 280static int create_files(struct super_block *sb, struct dentry *root)
298{ 281{
299 int event; 282 int event;
300 /* 283 /*
301 * Create the filesystem for all events 284 * Create the filesystem for all events
302 */ 285 */
303 int counter_index = 0; 286 int counter_index = 0;
304 const char* mali_name = gator_mali_get_mali_name(); 287 const char *mali_name = gator_mali_get_mali_name();
305 288
306 for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++) 289 for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++) {
307 { 290 if (gator_mali_create_file_system(mali_name, timeline_event_names[counter_index], sb, root, &counters[event]) != 0) {
308 if (gator_mali_create_file_system(mali_name, timeline_event_names[counter_index], sb, root, &counters[event]) != 0) 291 return -1;
309 { 292 }
310 return -1; 293 counter_index++;
311 } 294 }
312 counter_index++; 295 counter_index = 0;
313 } 296 for (event = FIRST_SOFTWARE_COUNTER; event < FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS; event++) {
314 counter_index = 0; 297 if (gator_mali_create_file_system(mali_name, software_counter_names[counter_index], sb, root, &counters[event]) != 0) {
315 for (event = FIRST_SOFTWARE_COUNTER; event < FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS; event++) 298 return -1;
316 { 299 }
317 if (gator_mali_create_file_system(mali_name, software_counter_names[counter_index], sb, root, &counters[event]) != 0) 300 counter_index++;
318 { 301 }
319 return -1; 302 counter_index = 0;
320 } 303 for (event = FIRST_ACCUMULATOR; event < FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS; event++) {
321 counter_index++; 304 if (gator_mali_create_file_system(mali_name, accumulators_names[counter_index], sb, root, &counters[event]) != 0) {
322 } 305 return -1;
323 counter_index = 0; 306 }
324 for (event = FIRST_ACCUMULATOR; event < FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS; event++) 307 counter_index++;
325 { 308 }
326 if (gator_mali_create_file_system(mali_name, accumulators_names[counter_index], sb, root, &counters[event]) != 0) 309
327 { 310 return 0;
328 return -1;
329 }
330 counter_index++;
331 }
332
333 return 0;
334} 311}
335 312
336static int register_tracepoints(void) 313static int register_tracepoints(void)
337{ 314{
338 if (GATOR_REGISTER_TRACE(mali_pm_status)) 315 if (GATOR_REGISTER_TRACE(mali_pm_status)) {
339 { 316 pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint failed to activate\n");
340 pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint failed to activate\n"); 317 return 0;
341 return 0; 318 }
342 } 319
343 320 if (GATOR_REGISTER_TRACE(mali_page_fault_insert_pages)) {
344 if (GATOR_REGISTER_TRACE(mali_page_fault_insert_pages)) 321 pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint failed to activate\n");
345 { 322 return 0;
346 pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint failed to activate\n"); 323 }
347 return 0; 324
348 } 325 if (GATOR_REGISTER_TRACE(mali_mmu_as_in_use)) {
349 326 pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint failed to activate\n");
350 if (GATOR_REGISTER_TRACE(mali_mmu_as_in_use)) 327 return 0;
351 { 328 }
352 pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint failed to activate\n"); 329
353 return 0; 330 if (GATOR_REGISTER_TRACE(mali_mmu_as_released)) {
354 } 331 pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint failed to activate\n");
355 332 return 0;
356 if (GATOR_REGISTER_TRACE(mali_mmu_as_released)) 333 }
357 { 334
358 pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint failed to activate\n"); 335 if (GATOR_REGISTER_TRACE(mali_total_alloc_pages_change)) {
359 return 0; 336 pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint failed to activate\n");
360 } 337 return 0;
361 338 }
362 if (GATOR_REGISTER_TRACE(mali_total_alloc_pages_change)) 339
363 { 340 pr_debug("gator: Mali-T6xx: start\n");
364 pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint failed to activate\n"); 341 pr_debug("gator: Mali-T6xx: mali_pm_status probe is at %p\n", &probe_mali_pm_status);
365 return 0; 342 pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages probe is at %p\n", &probe_mali_page_fault_insert_pages);
366 } 343 pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use probe is at %p\n", &probe_mali_mmu_as_in_use);
367 344 pr_debug("gator: Mali-T6xx: mali_mmu_as_released probe is at %p\n", &probe_mali_mmu_as_released);
368 pr_debug("gator: Mali-T6xx: start\n"); 345 pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change probe is at %p\n", &probe_mali_total_alloc_pages_change);
369 pr_debug("gator: Mali-T6xx: mali_pm_status probe is at %p\n", &probe_mali_pm_status); 346
370 pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages probe is at %p\n", &probe_mali_page_fault_insert_pages); 347 return 1;
371 pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use probe is at %p\n", &probe_mali_mmu_as_in_use);
372 pr_debug("gator: Mali-T6xx: mali_mmu_as_released probe is at %p\n", &probe_mali_mmu_as_released);
373 pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change probe is at %p\n", &probe_mali_total_alloc_pages_change);
374
375 return 1;
376} 348}
377 349
378static int start(void) 350static int start(void)
379{ 351{
380 unsigned int cnt; 352 unsigned int cnt;
381 353
382 /* Clean all data for the next capture */ 354 /* Clean all data for the next capture */
383 for (cnt = 0; cnt < NUMBER_OF_TIMELINE_EVENTS; cnt++) 355 for (cnt = 0; cnt < NUMBER_OF_TIMELINE_EVENTS; cnt++) {
384 { 356 timeline_event_starttime[cnt].tv_sec = timeline_event_starttime[cnt].tv_nsec = 0;
385 timeline_event_starttime[cnt].tv_sec = timeline_event_starttime[cnt].tv_nsec = 0; 357 timeline_data[cnt] = 0;
386 timeline_data[cnt] = 0; 358 }
387 } 359
388 360 for (cnt = 0; cnt < NUMBER_OF_SOFTWARE_COUNTERS; cnt++) {
389 for (cnt = 0; cnt < NUMBER_OF_SOFTWARE_COUNTERS; cnt++) 361 sw_counter_data[cnt] = 0;
390 { 362 }
391 sw_counter_data[cnt] = 0; 363
392 } 364 for (cnt = 0; cnt < NUMBER_OF_ACCUMULATORS; cnt++) {
393 365 accumulators_data[cnt] = 0;
394 for (cnt = 0; cnt < NUMBER_OF_ACCUMULATORS; cnt++) 366 }
395 { 367
396 accumulators_data[cnt] = 0; 368 /* Register tracepoints */
397 } 369 if (register_tracepoints() == 0) {
398 370 return -1;
399 /* Register tracepoints */ 371 }
400 if (register_tracepoints() == 0) 372
401 { 373 /*
402 return -1; 374 * Set the first timestamp for calculating the sample interval. The first interval could be quite long,
403 } 375 * since it will be the time between 'start' and the first 'read'.
404 376 * This means that timeline values will be divided by a big number for the first sample.
405 /* 377 */
406 * Set the first timestamp for calculating the sample interval. The first interval could be quite long, 378 getnstimeofday(&prev_timestamp);
407 * since it will be the time between 'start' and the first 'read'. 379
408 * This means that timeline values will be divided by a big number for the first sample. 380 return 0;
409 */
410 getnstimeofday(&prev_timestamp);
411
412 return 0;
413} 381}
414 382
415static void stop(void) 383static void stop(void)
416{ 384{
417 pr_debug("gator: Mali-T6xx: stop\n"); 385 pr_debug("gator: Mali-T6xx: stop\n");
418 386
419 /* 387 /*
420 * It is safe to unregister traces even if they were not successfully 388 * It is safe to unregister traces even if they were not successfully
421 * registered, so no need to check. 389 * registered, so no need to check.
422 */ 390 */
423 GATOR_UNREGISTER_TRACE(mali_pm_status); 391 GATOR_UNREGISTER_TRACE(mali_pm_status);
424 pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint deactivated\n"); 392 pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint deactivated\n");
425 393
426 GATOR_UNREGISTER_TRACE(mali_page_fault_insert_pages); 394 GATOR_UNREGISTER_TRACE(mali_page_fault_insert_pages);
427 pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint deactivated\n"); 395 pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint deactivated\n");
428 396
429 GATOR_UNREGISTER_TRACE(mali_mmu_as_in_use); 397 GATOR_UNREGISTER_TRACE(mali_mmu_as_in_use);
430 pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint deactivated\n"); 398 pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint deactivated\n");
431 399
432 GATOR_UNREGISTER_TRACE(mali_mmu_as_released); 400 GATOR_UNREGISTER_TRACE(mali_mmu_as_released);
433 pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint deactivated\n"); 401 pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint deactivated\n");
434 402
435 GATOR_UNREGISTER_TRACE(mali_total_alloc_pages_change); 403 GATOR_UNREGISTER_TRACE(mali_total_alloc_pages_change);
436 pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint deactivated\n"); 404 pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint deactivated\n");
437} 405}
438 406
439static int read(int **buffer) 407static int read(int **buffer)
440{ 408{
441 int cnt; 409 int cnt;
442 int len = 0; 410 int len = 0;
443 long sample_interval_us = 0; 411 long sample_interval_us = 0;
444 struct timespec read_timestamp; 412 struct timespec read_timestamp;
445 413
446 if (smp_processor_id()!=0) 414 if (smp_processor_id() != 0) {
447 { 415 return 0;
448 return 0; 416 }
449 } 417
450 418 /* Get the start of this sample period. */
451 /* Get the start of this sample period. */ 419 getnstimeofday(&read_timestamp);
452 getnstimeofday(&read_timestamp); 420
453 421 /*
454 /* 422 * Calculate the sample interval if the previous sample time is valid.
455 * Calculate the sample interval if the previous sample time is valid. 423 * We use tv_sec since it will not be 0.
456 * We use tv_sec since it will not be 0. 424 */
457 */ 425 if (prev_timestamp.tv_sec != 0) {
458 if(prev_timestamp.tv_sec != 0) { 426 sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp);
459 sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp); 427 }
460 } 428
461 429 /* Structure copy. Update the previous timestamp. */
462 /* Structure copy. Update the previous timestamp. */ 430 prev_timestamp = read_timestamp;
463 prev_timestamp = read_timestamp; 431
464 432 /*
465 /* 433 * Report the timeline counters (ACTIVITY_START/STOP)
466 * Report the timeline counters (ACTIVITY_START/STOP) 434 */
467 */ 435 for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) {
468 for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) 436 mali_counter *counter = &counters[cnt];
469 { 437 if (counter->enabled) {
470 mali_counter *counter = &counters[cnt]; 438 const int index = cnt - FIRST_TIMELINE_EVENT;
471 if (counter->enabled) 439 unsigned int value;
472 { 440
473 const int index = cnt - FIRST_TIMELINE_EVENT; 441 /* If the activity is still running, reset its start time to the start of this sample period
474 unsigned int value; 442 * to correct the count. Add the time up to the end of the sample onto the count. */
475 443 if (timeline_event_starttime[index].tv_sec != 0) {
476 /* If the activity is still running, reset its start time to the start of this sample period 444 const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp);
477 * to correct the count. Add the time up to the end of the sample onto the count. */ 445 timeline_data[index] += event_duration;
478 if(timeline_event_starttime[index].tv_sec != 0) { 446 timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */
479 const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp); 447 }
480 timeline_data[index] += event_duration; 448
481 timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */ 449 if (sample_interval_us != 0) {
482 } 450 /* Convert the counter to a percent-of-sample value */
483 451 value = (timeline_data[index] * 100) / sample_interval_us;
484 if(sample_interval_us != 0) { 452 } else {
485 /* Convert the counter to a percent-of-sample value */ 453 pr_debug("gator: Mali-T6xx: setting value to zero\n");
486 value = (timeline_data[index] * 100) / sample_interval_us; 454 value = 0;
487 } else { 455 }
488 pr_debug("gator: Mali-T6xx: setting value to zero\n"); 456
489 value = 0; 457 /* Clear the counter value ready for the next sample. */
490 } 458 timeline_data[index] = 0;
491 459
492 /* Clear the counter value ready for the next sample. */ 460 counter_dump[len++] = counter->key;
493 timeline_data[index] = 0; 461 counter_dump[len++] = value;
494 462 }
495 counter_dump[len++] = counter->key; 463 }
496 counter_dump[len++] = value; 464
497 } 465 /* Report the software counters */
498 } 466 for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) {
499 467 const mali_counter *counter = &counters[cnt];
500 /* Report the software counters */ 468 if (counter->enabled) {
501 for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) 469 const int index = cnt - FIRST_SOFTWARE_COUNTER;
502 { 470 counter_dump[len++] = counter->key;
503 const mali_counter *counter = &counters[cnt]; 471 counter_dump[len++] = sw_counter_data[index];
504 if (counter->enabled) 472 /* Set the value to zero for the next time */
505 { 473 sw_counter_data[index] = 0;
506 const int index = cnt - FIRST_SOFTWARE_COUNTER; 474 }
507 counter_dump[len++] = counter->key; 475 }
508 counter_dump[len++] = sw_counter_data[index]; 476
509 /* Set the value to zero for the next time */ 477 /* Report the accumulators */
510 sw_counter_data[index] = 0; 478 for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) {
511 } 479 const mali_counter *counter = &counters[cnt];
512 } 480 if (counter->enabled) {
513 481 const int index = cnt - FIRST_ACCUMULATOR;
514 /* Report the accumulators */ 482 counter_dump[len++] = counter->key;
515 for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) 483 counter_dump[len++] = accumulators_data[index];
516 { 484 /* Do not zero the accumulator */
517 const mali_counter *counter = &counters[cnt]; 485 }
518 if (counter->enabled) 486 }
519 { 487
520 const int index = cnt - FIRST_ACCUMULATOR; 488 /* Update the buffer */
521 counter_dump[len++] = counter->key; 489 if (buffer) {
522 counter_dump[len++] = accumulators_data[index]; 490 *buffer = (int *)counter_dump;
523 /* Do not zero the accumulator */ 491 }
524 } 492
525 } 493 return len;
526
527 /* Update the buffer */
528 if (buffer)
529 {
530 *buffer = (int*) counter_dump;
531 }
532
533 return len;
534} 494}
535 495
536static struct gator_interface gator_events_mali_t6xx_interface = { 496static struct gator_interface gator_events_mali_t6xx_interface = {
537 .create_files = create_files, 497 .create_files = create_files,
538 .start = start, 498 .start = start,
539 .stop = stop, 499 .stop = stop,
540 .read = read 500 .read = read
541}; 501};
542 502
543extern int gator_events_mali_t6xx_init(void) 503extern int gator_events_mali_t6xx_init(void)
544{ 504{
545 pr_debug("gator: Mali-T6xx: sw_counters init\n"); 505 pr_debug("gator: Mali-T6xx: sw_counters init\n");
546 506
547 gator_mali_initialise_counters(counters, NUMBER_OF_EVENTS); 507 gator_mali_initialise_counters(counters, NUMBER_OF_EVENTS);
548 508
549 return gator_events_install(&gator_events_mali_t6xx_interface); 509 return gator_events_install(&gator_events_mali_t6xx_interface);
550} 510}
551 511
552gator_events_init(gator_events_mali_t6xx_init); 512gator_events_init(gator_events_mali_t6xx_init);
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c
index 854d02d..72498c8 100644
--- a/driver/gator_events_mali_t6xx_hw.c
+++ b/driver/gator_events_mali_t6xx_hw.c
@@ -26,7 +26,7 @@
26 * Mali-T6xx 26 * Mali-T6xx
27 */ 27 */
28typedef struct kbase_device *kbase_find_device_type(int); 28typedef struct kbase_device *kbase_find_device_type(int);
29typedef kbase_context *kbase_create_context_type(kbase_device*); 29typedef kbase_context *kbase_create_context_type(kbase_device *);
30typedef void kbase_destroy_context_type(kbase_context *); 30typedef void kbase_destroy_context_type(kbase_context *);
31typedef void *kbase_va_alloc_type(kbase_context *, u32); 31typedef void *kbase_va_alloc_type(kbase_context *, u32);
32typedef void kbase_va_free_type(kbase_context *, void *); 32typedef void kbase_va_free_type(kbase_context *, void *);
@@ -36,32 +36,41 @@ typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *);
36typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *); 36typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *);
37typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *); 37typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *);
38 38
39static kbase_find_device_type * kbase_find_device_symbol; 39static kbase_find_device_type *kbase_find_device_symbol;
40static kbase_create_context_type * kbase_create_context_symbol; 40static kbase_create_context_type *kbase_create_context_symbol;
41static kbase_va_alloc_type * kbase_va_alloc_symbol; 41static kbase_va_alloc_type *kbase_va_alloc_symbol;
42static kbase_instr_hwcnt_enable_type * kbase_instr_hwcnt_enable_symbol; 42static kbase_instr_hwcnt_enable_type *kbase_instr_hwcnt_enable_symbol;
43static kbase_instr_hwcnt_clear_type * kbase_instr_hwcnt_clear_symbol; 43static kbase_instr_hwcnt_clear_type *kbase_instr_hwcnt_clear_symbol;
44static kbase_instr_hwcnt_dump_irq_type * kbase_instr_hwcnt_dump_irq_symbol; 44static kbase_instr_hwcnt_dump_irq_type *kbase_instr_hwcnt_dump_irq_symbol;
45static kbase_instr_hwcnt_dump_complete_type * kbase_instr_hwcnt_dump_complete_symbol; 45static kbase_instr_hwcnt_dump_complete_type *kbase_instr_hwcnt_dump_complete_symbol;
46static kbase_instr_hwcnt_disable_type * kbase_instr_hwcnt_disable_symbol; 46static kbase_instr_hwcnt_disable_type *kbase_instr_hwcnt_disable_symbol;
47static kbase_va_free_type * kbase_va_free_symbol; 47static kbase_va_free_type *kbase_va_free_symbol;
48static kbase_destroy_context_type * kbase_destroy_context_symbol; 48static kbase_destroy_context_type *kbase_destroy_context_symbol;
49 49
50/** The interval between reads, in ns. */ 50/** The interval between reads, in ns.
51static const int READ_INTERVAL_NSEC = 1000000; 51 *
52 52 * Earlier we introduced
53 * a 'hold off for 1ms after last read' to resolve MIDBASE-2178 and MALINE-724.
54 * However, the 1ms hold off is too long if no context switches occur as there is a race
55 * between this value and the tick of the read clock in gator which is also 1ms. If we 'miss' the
56 * current read, the counter values are effectively 'spread' over 2ms and the values seen are half
57 * what they should be (since Streamline averages over sample time). In the presence of context switches
58 * this spread can vary and markedly affect the counters. Currently there is no 'proper' solution to
59 * this, but empirically we have found that reducing the minimum read interval to 950us causes the
60 * counts to be much more stable.
61 */
62static const int READ_INTERVAL_NSEC = 950000;
53 63
54#if GATOR_TEST 64#if GATOR_TEST
55#include "gator_events_mali_t6xx_hw_test.c" 65#include "gator_events_mali_t6xx_hw_test.c"
56#endif 66#endif
57 67
58/* Blocks for HW counters */ 68/* Blocks for HW counters */
59enum 69enum {
60{ 70 JM_BLOCK = 0,
61 JM_BLOCK = 0, 71 TILER_BLOCK,
62 TILER_BLOCK, 72 SHADER_BLOCK,
63 SHADER_BLOCK, 73 MMU_BLOCK
64 MMU_BLOCK
65}; 74};
66 75
67/* Counters for Mali-T6xx: 76/* Counters for Mali-T6xx:
@@ -75,271 +84,270 @@ enum
75 */ 84 */
76 85
77/* Hardware Counters */ 86/* Hardware Counters */
78static const char* const hardware_counter_names [] = 87static const char *const hardware_counter_names[] = {
79{ 88 /* Job Manager */
80 /* Job Manager */ 89 "",
81 "", 90 "",
82 "", 91 "",
83 "", 92 "",
84 "", 93 "MESSAGES_SENT",
85 "MESSAGES_SENT", 94 "MESSAGES_RECEIVED",
86 "MESSAGES_RECEIVED", 95 "GPU_ACTIVE", /* 6 */
87 "GPU_ACTIVE", /* 6 */ 96 "IRQ_ACTIVE",
88 "IRQ_ACTIVE", 97 "JS0_JOBS",
89 "JS0_JOBS", 98 "JS0_TASKS",
90 "JS0_TASKS", 99 "JS0_ACTIVE",
91 "JS0_ACTIVE", 100 "",
92 "", 101 "JS0_WAIT_READ",
93 "JS0_WAIT_READ", 102 "JS0_WAIT_ISSUE",
94 "JS0_WAIT_ISSUE", 103 "JS0_WAIT_DEPEND",
95 "JS0_WAIT_DEPEND", 104 "JS0_WAIT_FINISH",
96 "JS0_WAIT_FINISH", 105 "JS1_JOBS",
97 "JS1_JOBS", 106 "JS1_TASKS",
98 "JS1_TASKS", 107 "JS1_ACTIVE",
99 "JS1_ACTIVE", 108 "",
100 "", 109 "JS1_WAIT_READ",
101 "JS1_WAIT_READ", 110 "JS1_WAIT_ISSUE",
102 "JS1_WAIT_ISSUE", 111 "JS1_WAIT_DEPEND",
103 "JS1_WAIT_DEPEND", 112 "JS1_WAIT_FINISH",
104 "JS1_WAIT_FINISH", 113 "JS2_JOBS",
105 "JS2_JOBS", 114 "JS2_TASKS",
106 "JS2_TASKS", 115 "JS2_ACTIVE",
107 "JS2_ACTIVE", 116 "",
108 "", 117 "JS2_WAIT_READ",
109 "JS2_WAIT_READ", 118 "JS2_WAIT_ISSUE",
110 "JS2_WAIT_ISSUE", 119 "JS2_WAIT_DEPEND",
111 "JS2_WAIT_DEPEND", 120 "JS2_WAIT_FINISH",
112 "JS2_WAIT_FINISH", 121 "JS3_JOBS",
113 "JS3_JOBS", 122 "JS3_TASKS",
114 "JS3_TASKS", 123 "JS3_ACTIVE",
115 "JS3_ACTIVE", 124 "",
116 "", 125 "JS3_WAIT_READ",
117 "JS3_WAIT_READ", 126 "JS3_WAIT_ISSUE",
118 "JS3_WAIT_ISSUE", 127 "JS3_WAIT_DEPEND",
119 "JS3_WAIT_DEPEND", 128 "JS3_WAIT_FINISH",
120 "JS3_WAIT_FINISH", 129 "JS4_JOBS",
121 "JS4_JOBS", 130 "JS4_TASKS",
122 "JS4_TASKS", 131 "JS4_ACTIVE",
123 "JS4_ACTIVE", 132 "",
124 "", 133 "JS4_WAIT_READ",
125 "JS4_WAIT_READ", 134 "JS4_WAIT_ISSUE",
126 "JS4_WAIT_ISSUE", 135 "JS4_WAIT_DEPEND",
127 "JS4_WAIT_DEPEND", 136 "JS4_WAIT_FINISH",
128 "JS4_WAIT_FINISH", 137 "JS5_JOBS",
129 "JS5_JOBS", 138 "JS5_TASKS",
130 "JS5_TASKS", 139 "JS5_ACTIVE",
131 "JS5_ACTIVE", 140 "",
132 "", 141 "JS5_WAIT_READ",
133 "JS5_WAIT_READ", 142 "JS5_WAIT_ISSUE",
134 "JS5_WAIT_ISSUE", 143 "JS5_WAIT_DEPEND",
135 "JS5_WAIT_DEPEND", 144 "JS5_WAIT_FINISH",
136 "JS5_WAIT_FINISH", 145 "JS6_JOBS",
137 "JS6_JOBS", 146 "JS6_TASKS",
138 "JS6_TASKS", 147 "JS6_ACTIVE",
139 "JS6_ACTIVE", 148 "",
140 "", 149 "JS6_WAIT_READ",
141 "JS6_WAIT_READ", 150 "JS6_WAIT_ISSUE",
142 "JS6_WAIT_ISSUE", 151 "JS6_WAIT_DEPEND",
143 "JS6_WAIT_DEPEND", 152 "JS6_WAIT_FINISH",
144 "JS6_WAIT_FINISH", 153
145 154 /*Tiler */
146 /*Tiler*/ 155 "",
147 "", 156 "",
148 "", 157 "",
149 "", 158 "JOBS_PROCESSED",
150 "JOBS_PROCESSED", 159 "TRIANGLES",
151 "TRIANGLES", 160 "QUADS",
152 "QUADS", 161 "POLYGONS",
153 "POLYGONS", 162 "POINTS",
154 "POINTS", 163 "LINES",
155 "LINES", 164 "VCACHE_HIT",
156 "VCACHE_HIT", 165 "VCACHE_MISS",
157 "VCACHE_MISS", 166 "FRONT_FACING",
158 "FRONT_FACING", 167 "BACK_FACING",
159 "BACK_FACING", 168 "PRIM_VISIBLE",
160 "PRIM_VISIBLE", 169 "PRIM_CULLED",
161 "PRIM_CULLED", 170 "PRIM_CLIPPED",
162 "PRIM_CLIPPED", 171 "LEVEL0",
163 "LEVEL0", 172 "LEVEL1",
164 "LEVEL1", 173 "LEVEL2",
165 "LEVEL2", 174 "LEVEL3",
166 "LEVEL3", 175 "LEVEL4",
167 "LEVEL4", 176 "LEVEL5",
168 "LEVEL5", 177 "LEVEL6",
169 "LEVEL6", 178 "LEVEL7",
170 "LEVEL7", 179 "COMMAND_1",
171 "COMMAND_1", 180 "COMMAND_2",
172 "COMMAND_2", 181 "COMMAND_3",
173 "COMMAND_3", 182 "COMMAND_4",
174 "COMMAND_4", 183 "COMMAND_4_7",
175 "COMMAND_4_7", 184 "COMMAND_8_15",
176 "COMMAND_8_15", 185 "COMMAND_16_63",
177 "COMMAND_16_63", 186 "COMMAND_64",
178 "COMMAND_64", 187 "COMPRESS_IN",
179 "COMPRESS_IN", 188 "COMPRESS_OUT",
180 "COMPRESS_OUT", 189 "COMPRESS_FLUSH",
181 "COMPRESS_FLUSH", 190 "TIMESTAMPS",
182 "TIMESTAMPS", 191 "PCACHE_HIT",
183 "PCACHE_HIT", 192 "PCACHE_MISS",
184 "PCACHE_MISS", 193 "PCACHE_LINE",
185 "PCACHE_LINE", 194 "PCACHE_STALL",
186 "PCACHE_STALL", 195 "WRBUF_HIT",
187 "WRBUF_HIT", 196 "WRBUF_MISS",
188 "WRBUF_MISS", 197 "WRBUF_LINE",
189 "WRBUF_LINE", 198 "WRBUF_PARTIAL",
190 "WRBUF_PARTIAL", 199 "WRBUF_STALL",
191 "WRBUF_STALL", 200 "ACTIVE",
192 "ACTIVE", 201 "LOADING_DESC",
193 "LOADING_DESC", 202 "INDEX_WAIT",
194 "INDEX_WAIT", 203 "INDEX_RANGE_WAIT",
195 "INDEX_RANGE_WAIT", 204 "VERTEX_WAIT",
196 "VERTEX_WAIT", 205 "PCACHE_WAIT",
197 "PCACHE_WAIT", 206 "WRBUF_WAIT",
198 "WRBUF_WAIT", 207 "BUS_READ",
199 "BUS_READ", 208 "BUS_WRITE",
200 "BUS_WRITE", 209 "",
201 "", 210 "",
202 "", 211 "",
203 "", 212 "",
204 "", 213 "",
205 "", 214 "UTLB_STALL",
206 "UTLB_STALL", 215 "UTLB_REPLAY_MISS",
207 "UTLB_REPLAY_MISS", 216 "UTLB_REPLAY_FULL",
208 "UTLB_REPLAY_FULL", 217 "UTLB_NEW_MISS",
209 "UTLB_NEW_MISS", 218 "UTLB_HIT",
210 "UTLB_HIT", 219
211 220 /* Shader Core */
212 /* Shader Core */ 221 "",
213 "", 222 "",
214 "", 223 "",
215 "", 224 "SHADER_CORE_ACTIVE",
216 "SHADER_CORE_ACTIVE", 225 "FRAG_ACTIVE",
217 "FRAG_ACTIVE", 226 "FRAG_PRIMATIVES",
218 "FRAG_PRIMATIVES", 227 "FRAG_PRIMATIVES_DROPPED",
219 "FRAG_PRIMATIVES_DROPPED", 228 "FRAG_CYCLE_DESC",
220 "FRAG_CYCLE_DESC", 229 "FRAG_CYCLES_PLR",
221 "FRAG_CYCLES_PLR", 230 "FRAG_CYCLES_VERT",
222 "FRAG_CYCLES_VERT", 231 "FRAG_CYCLES_TRISETUP",
223 "FRAG_CYCLES_TRISETUP", 232 "FRAG_CYCLES_RAST",
224 "FRAG_CYCLES_RAST", 233 "FRAG_THREADS",
225 "FRAG_THREADS", 234 "FRAG_DUMMY_THREADS",
226 "FRAG_DUMMY_THREADS", 235 "FRAG_QUADS_RAST",
227 "FRAG_QUADS_RAST", 236 "FRAG_QUADS_EZS_TEST",
228 "FRAG_QUADS_EZS_TEST", 237 "FRAG_QUADS_EZS_KILLED",
229 "FRAG_QUADS_EZS_KILLED", 238 "FRAG_QUADS_LZS_TEST",
230 "FRAG_QUADS_LZS_TEST", 239 "FRAG_QUADS_LZS_KILLED",
231 "FRAG_QUADS_LZS_KILLED", 240 "FRAG_CYCLE_NO_TILE",
232 "FRAG_CYCLE_NO_TILE", 241 "FRAG_NUM_TILES",
233 "FRAG_NUM_TILES", 242 "FRAG_TRANS_ELIM",
234 "FRAG_TRANS_ELIM", 243 "COMPUTE_ACTIVE",
235 "COMPUTE_ACTIVE", 244 "COMPUTE_TASKS",
236 "COMPUTE_TASKS", 245 "COMPUTE_THREADS",
237 "COMPUTE_THREADS", 246 "COMPUTE_CYCLES_DESC",
238 "COMPUTE_CYCLES_DESC", 247 "TRIPIPE_ACTIVE",
239 "TRIPIPE_ACTIVE", 248 "ARITH_WORDS",
240 "ARITH_WORDS", 249 "ARITH_CYCLES_REG",
241 "ARITH_CYCLES_REG", 250 "ARITH_CYCLES_L0",
242 "ARITH_CYCLES_L0", 251 "ARITH_FRAG_DEPEND",
243 "ARITH_FRAG_DEPEND", 252 "LS_WORDS",
244 "LS_WORDS", 253 "LS_ISSUES",
245 "LS_ISSUES", 254 "LS_RESTARTS",
246 "LS_RESTARTS", 255 "LS_REISSUES_MISS",
247 "LS_REISSUES_MISS", 256 "LS_REISSUES_VD",
248 "LS_REISSUES_VD", 257 "LS_REISSUE_ATTRIB_MISS",
249 "LS_REISSUE_ATTRIB_MISS", 258 "LS_NO_WB",
250 "LS_NO_WB", 259 "TEX_WORDS",
251 "TEX_WORDS", 260 "TEX_BUBBLES",
252 "TEX_BUBBLES", 261 "TEX_WORDS_L0",
253 "TEX_WORDS_L0", 262 "TEX_WORDS_DESC",
254 "TEX_WORDS_DESC", 263 "TEX_THREADS",
255 "TEX_THREADS", 264 "TEX_RECIRC_FMISS",
256 "TEX_RECIRC_FMISS", 265 "TEX_RECIRC_DESC",
257 "TEX_RECIRC_DESC", 266 "TEX_RECIRC_MULTI",
258 "TEX_RECIRC_MULTI", 267 "TEX_RECIRC_PMISS",
259 "TEX_RECIRC_PMISS", 268 "TEX_RECIRC_CONF",
260 "TEX_RECIRC_CONF", 269 "LSC_READ_HITS",
261 "LSC_READ_HITS", 270 "LSC_READ_MISSES",
262 "LSC_READ_MISSES", 271 "LSC_WRITE_HITS",
263 "LSC_WRITE_HITS", 272 "LSC_WRITE_MISSES",
264 "LSC_WRITE_MISSES", 273 "LSC_ATOMIC_HITS",
265 "LSC_ATOMIC_HITS", 274 "LSC_ATOMIC_MISSES",
266 "LSC_ATOMIC_MISSES", 275 "LSC_LINE_FETCHES",
267 "LSC_LINE_FETCHES", 276 "LSC_DIRTY_LINE",
268 "LSC_DIRTY_LINE", 277 "LSC_SNOOPS",
269 "LSC_SNOOPS", 278 "AXI_TLB_STALL",
270 "AXI_TLB_STALL", 279 "AXI_TLB_MIESS",
271 "AXI_TLB_MIESS", 280 "AXI_TLB_TRANSACTION",
272 "AXI_TLB_TRANSACTION", 281 "LS_TLB_MISS",
273 "LS_TLB_MISS", 282 "LS_TLB_HIT",
274 "LS_TLB_HIT", 283 "AXI_BEATS_READ",
275 "AXI_BEATS_READ", 284 "AXI_BEATS_WRITTEN",
276 "AXI_BEATS_WRITTEN", 285
277 286 /*L2 and MMU */
278 /*L2 and MMU */ 287 "",
279 "", 288 "",
280 "", 289 "",
281 "", 290 "",
282 "", 291 "MMU_TABLE_WALK",
283 "MMU_TABLE_WALK", 292 "MMU_REPLAY_MISS",
284 "MMU_REPLAY_MISS", 293 "MMU_REPLAY_FULL",
285 "MMU_REPLAY_FULL", 294 "MMU_NEW_MISS",
286 "MMU_NEW_MISS", 295 "MMU_HIT",
287 "MMU_HIT", 296 "",
288 "", 297 "",
289 "", 298 "",
290 "", 299 "",
291 "", 300 "",
292 "", 301 "",
293 "", 302 "",
294 "", 303 "UTLB_STALL",
295 "UTLB_STALL", 304 "UTLB_REPLAY_MISS",
296 "UTLB_REPLAY_MISS", 305 "UTLB_REPLAY_FULL",
297 "UTLB_REPLAY_FULL", 306 "UTLB_NEW_MISS",
298 "UTLB_NEW_MISS", 307 "UTLB_HIT",
299 "UTLB_HIT", 308 "",
300 "", 309 "",
301 "", 310 "",
302 "", 311 "",
303 "", 312 "",
304 "", 313 "",
305 "", 314 "",
306 "", 315 "",
307 "", 316 "",
308 "", 317 "L2_WRITE_BEATS",
309 "L2_WRITE_BEATS", 318 "L2_READ_BEATS",
310 "L2_READ_BEATS", 319 "L2_ANY_LOOKUP",
311 "L2_ANY_LOOKUP", 320 "L2_READ_LOOKUP",
312 "L2_READ_LOOKUP", 321 "L2_SREAD_LOOKUP",
313 "L2_SREAD_LOOKUP", 322 "L2_READ_REPLAY",
314 "L2_READ_REPLAY", 323 "L2_READ_SNOOP",
315 "L2_READ_SNOOP", 324 "L2_READ_HIT",
316 "L2_READ_HIT", 325 "L2_CLEAN_MISS",
317 "L2_CLEAN_MISS", 326 "L2_WRITE_LOOKUP",
318 "L2_WRITE_LOOKUP", 327 "L2_SWRITE_LOOKUP",
319 "L2_SWRITE_LOOKUP", 328 "L2_WRITE_REPLAY",
320 "L2_WRITE_REPLAY", 329 "L2_WRITE_SNOOP",
321 "L2_WRITE_SNOOP", 330 "L2_WRITE_HIT",
322 "L2_WRITE_HIT", 331 "L2_EXT_READ_FULL",
323 "L2_EXT_READ_FULL", 332 "L2_EXT_READ_HALF",
324 "L2_EXT_READ_HALF", 333 "L2_EXT_WRITE_FULL",
325 "L2_EXT_WRITE_FULL", 334 "L2_EXT_WRITE_HALF",
326 "L2_EXT_WRITE_HALF", 335 "L2_EXT_READ",
327 "L2_EXT_READ", 336 "L2_EXT_READ_LINE",
328 "L2_EXT_READ_LINE", 337 "L2_EXT_WRITE",
329 "L2_EXT_WRITE", 338 "L2_EXT_WRITE_LINE",
330 "L2_EXT_WRITE_LINE", 339 "L2_EXT_WRITE_SMALL",
331 "L2_EXT_WRITE_SMALL", 340 "L2_EXT_BARRIER",
332 "L2_EXT_BARRIER", 341 "L2_EXT_AR_STALL",
333 "L2_EXT_AR_STALL", 342 "L2_EXT_R_BUF_FULL",
334 "L2_EXT_R_BUF_FULL", 343 "L2_EXT_RD_BUF_FULL",
335 "L2_EXT_RD_BUF_FULL", 344 "L2_EXT_R_RAW",
336 "L2_EXT_R_RAW", 345 "L2_EXT_W_STALL",
337 "L2_EXT_W_STALL", 346 "L2_EXT_W_BUF_FULL",
338 "L2_EXT_W_BUF_FULL", 347 "L2_EXT_R_W_HAZARD",
339 "L2_EXT_R_W_HAZARD", 348 "L2_TAG_HAZARD",
340 "L2_TAG_HAZARD", 349 "L2_SNOOP_FULL",
341 "L2_SNOOP_FULL", 350 "L2_REPLAY_FULL"
342 "L2_REPLAY_FULL"
343}; 351};
344 352
345#define NUMBER_OF_HARDWARE_COUNTERS (sizeof(hardware_counter_names) / sizeof(hardware_counter_names[0])) 353#define NUMBER_OF_HARDWARE_COUNTERS (sizeof(hardware_counter_names) / sizeof(hardware_counter_names[0]))
@@ -392,8 +400,8 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
392#define SYMBOL_CLEANUP(FUNCTION) \ 400#define SYMBOL_CLEANUP(FUNCTION) \
393 if(FUNCTION ## _symbol) \ 401 if(FUNCTION ## _symbol) \
394 { \ 402 { \
395 symbol_put(FUNCTION); \ 403 symbol_put(FUNCTION); \
396 FUNCTION ## _symbol = NULL; \ 404 FUNCTION ## _symbol = NULL; \
397 } 405 }
398 406
399/** 407/**
@@ -442,17 +450,15 @@ static void clean_symbols(void)
442 * 450 *
443 * Note that this function has been separated out here to allow it to be tested. 451 * Note that this function has been separated out here to allow it to be tested.
444 */ 452 */
445static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns) 453static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time_s, s32 *next_read_time_ns)
446{ 454{
447 /* If the current ns count rolls over a second, roll the next read time too. */ 455 /* If the current ns count rolls over a second, roll the next read time too. */
448 if(current_time->tv_sec != *prev_time_s) 456 if (current_time->tv_sec != *prev_time_s) {
449 {
450 *next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC; 457 *next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC;
451 } 458 }
452 459
453 /* Abort the read if the next read time has not arrived. */ 460 /* Abort the read if the next read time has not arrived. */
454 if(current_time->tv_nsec < *next_read_time_ns) 461 if (current_time->tv_nsec < *next_read_time_ns) {
455 {
456 return 0; 462 return 0;
457 } 463 }
458 464
@@ -465,154 +471,146 @@ static int is_read_scheduled(const struct timespec *current_time, u32* prev_time
465 471
466static int start(void) 472static int start(void)
467{ 473{
468 kbase_uk_hwcnt_setup setup; 474 kbase_uk_hwcnt_setup setup;
469 mali_error err; 475 mali_error err;
470 int cnt; 476 int cnt;
471 u16 bitmask[] = {0, 0, 0, 0}; 477 u16 bitmask[] = { 0, 0, 0, 0 };
472 478
473 /* Setup HW counters */ 479 /* Setup HW counters */
474 num_hardware_counters_enabled = 0; 480 num_hardware_counters_enabled = 0;
475