]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/misc/tegra-profiler/quadd_proc.c
misc: tegra-profiler: get perfmon extension
[sojka/nv-tegra/linux-3.10.git] / drivers / misc / tegra-profiler / quadd_proc.c
1 /*
2  * drivers/misc/tegra-profiler/quadd_proc.c
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16
17 #ifdef CONFIG_PROC_FS
18
19 #include <linux/proc_fs.h>
20 #include <linux/seq_file.h>
21
22 #include <linux/tegra_profiler.h>
23
24 #include "quadd.h"
25 #include "version.h"
26 #include "quadd_proc.h"
27 #include "arm_pmu.h"
28
29 #define YES_NO(x) ((x) ? "yes" : "no")
30
31 static struct quadd_ctx *ctx;
32
33 #define QUADD_PROC_DEV QUADD_DEVICE_NAME
34
35 static int show_version(struct seq_file *f, void *offset)
36 {
37         seq_printf(f, "version:         %s\n", QUADD_MODULE_VERSION);
38         seq_printf(f, "branch:          %s\n", QUADD_MODULE_BRANCH);
39         seq_printf(f, "samples version: %d\n", QUADD_SAMPLES_VERSION);
40         seq_printf(f, "io version:      %d\n", QUADD_IO_VERSION);
41
42         return 0;
43 }
44
45 static int show_version_proc_open(struct inode *inode, struct file *file)
46 {
47         return single_open(file, show_version, NULL);
48 }
49
50 static const struct file_operations version_proc_fops = {
51         .open           = show_version_proc_open,
52         .read           = seq_read,
53         .llseek         = seq_lseek,
54         .release        = single_release,
55 };
56
57 static int show_capabilities(struct seq_file *f, void *offset)
58 {
59         struct quadd_comm_cap *cap = &ctx->cap;
60         struct quadd_events_cap *event = &cap->events_cap;
61         unsigned int extra = cap->reserved[QUADD_COMM_CAP_IDX_EXTRA];
62         struct quadd_arch_info *arch = NULL;
63
64         if (ctx->pmu)
65                 arch = ctx->pmu->get_arch();
66
67         seq_printf(f, "pmu:                                   %s\n",
68                    YES_NO(cap->pmu));
69         seq_printf(f, "tegra 3 LP cluster:                    %s\n",
70                    YES_NO(cap->tegra_lp_cluster));
71         seq_printf(f, "power rate samples:                    %s\n",
72                    YES_NO(cap->power_rate));
73
74         seq_printf(f, "l2 cache:                              %s\n",
75                    YES_NO(cap->l2_cache));
76         if (cap->l2_cache) {
77                 seq_printf(f, "multiple l2 events:                    %s\n",
78                            YES_NO(cap->l2_multiple_events));
79         }
80
81         seq_printf(f, "support polling mode:                  %s\n",
82                    YES_NO(cap->blocked_read));
83         seq_printf(f, "backtrace from the kernel ctx:         %s\n",
84                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX));
85         seq_printf(f, "send mmap regions at the start:        %s\n",
86                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_GET_MMAP));
87         seq_printf(f, "group samples:                         %s\n",
88                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES));
89         seq_printf(f, "unwinding based on ex-handling tables: %s\n",
90                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES));
91         seq_printf(f, "support AArch64 architecture:          %s\n",
92                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64));
93         seq_printf(f, "support special architecture mappings: %s\n",
94                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP));
95         seq_printf(f, "support mixed unwinding mode:          %s\n",
96                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNWIND_MIXED));
97         seq_printf(f, "information about unwind entry:        %s\n",
98                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE));
99
100         seq_puts(f, "\n");
101
102         if (arch) {
103                 seq_printf(f, "pmu arch:                              %s\n",
104                         arch->name);
105                 seq_printf(f, "pmu arch version:                      %d\n",
106                         arch->ver);
107         }
108
109         seq_puts(f, "\n");
110         seq_puts(f, "Supported events:\n");
111         seq_printf(f, "cpu_cycles:                     %s\n",
112                    YES_NO(event->cpu_cycles));
113         seq_printf(f, "instructions:                   %s\n",
114                    YES_NO(event->instructions));
115         seq_printf(f, "branch_instructions:            %s\n",
116                    YES_NO(event->branch_instructions));
117         seq_printf(f, "branch_misses:                  %s\n",
118                    YES_NO(event->branch_misses));
119         seq_printf(f, "bus_cycles:                     %s\n",
120                    YES_NO(event->bus_cycles));
121         seq_printf(f, "l1_dcache_read_misses:          %s\n",
122                    YES_NO(event->l1_dcache_read_misses));
123         seq_printf(f, "l1_dcache_write_misses:         %s\n",
124                    YES_NO(event->l1_dcache_write_misses));
125         seq_printf(f, "l1_icache_misses:               %s\n",
126                    YES_NO(event->l1_icache_misses));
127         seq_printf(f, "l2_dcache_read_misses:          %s\n",
128                    YES_NO(event->l2_dcache_read_misses));
129         seq_printf(f, "l2_dcache_write_misses:         %s\n",
130                    YES_NO(event->l2_dcache_write_misses));
131         seq_printf(f, "l2_icache_misses:               %s\n",
132                    YES_NO(event->l2_icache_misses));
133
134         return 0;
135 }
136
137 static int show_capabilities_proc_open(struct inode *inode, struct file *file)
138 {
139         return single_open(file, show_capabilities, NULL);
140 }
141
142 static const struct file_operations capabilities_proc_fops = {
143         .open           = show_capabilities_proc_open,
144         .read           = seq_read,
145         .llseek         = seq_lseek,
146         .release        = single_release,
147 };
148
149 static int show_status(struct seq_file *f, void *offset)
150 {
151         unsigned int status;
152         unsigned int is_auth_open, active;
153         struct quadd_module_state s;
154
155         quadd_get_state(&s);
156         status = s.reserved[QUADD_MOD_STATE_IDX_STATUS];
157
158         active = status & QUADD_MOD_STATE_STATUS_IS_ACTIVE;
159         is_auth_open = status & QUADD_MOD_STATE_STATUS_IS_AUTH_OPEN;
160
161         seq_printf(f, "status:          %s\n", active ? "active" : "waiting");
162         seq_printf(f, "auth:            %s\n", YES_NO(is_auth_open));
163         seq_printf(f, "all samples:     %llu\n", s.nr_all_samples);
164         seq_printf(f, "skipped samples: %llu\n", s.nr_skipped_samples);
165
166         return 0;
167 }
168
169 static int show_status_proc_open(struct inode *inode, struct file *file)
170 {
171         return single_open(file, show_status, NULL);
172 }
173
174 static const struct file_operations status_proc_fops = {
175         .open           = show_status_proc_open,
176         .read           = seq_read,
177         .llseek         = seq_lseek,
178         .release        = single_release,
179 };
180
181 void quadd_proc_init(struct quadd_ctx *context)
182 {
183         ctx = context;
184
185         proc_mkdir(QUADD_PROC_DEV, NULL);
186
187         proc_create(QUADD_PROC_DEV "/version", 0, NULL, &version_proc_fops);
188         proc_create(QUADD_PROC_DEV "/capabilities", 0, NULL,
189                     &capabilities_proc_fops);
190         proc_create(QUADD_PROC_DEV "/status", 0, NULL, &status_proc_fops);
191 }
192
193 void quadd_proc_deinit(void)
194 {
195         remove_proc_entry(QUADD_PROC_DEV "/version", NULL);
196         remove_proc_entry(QUADD_PROC_DEV "/capabilities", NULL);
197         remove_proc_entry(QUADD_PROC_DEV "/status", NULL);
198         remove_proc_entry(QUADD_PROC_DEV, NULL);
199 }
200
201 #endif  /* CONFIG_PROC_FS */