]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/misc/tegra-profiler/quadd_proc.c
b7993e8ac8e6046e43cb7f94b0eca6f033ba53f7
[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
28 #define YES_NO(x) ((x) ? "yes" : "no")
29
30 static struct quadd_ctx *ctx;
31
32 #define QUADD_PROC_DEV QUADD_DEVICE_NAME
33
34 static int show_version(struct seq_file *f, void *offset)
35 {
36         seq_printf(f, "version:         %s\n", QUADD_MODULE_VERSION);
37         seq_printf(f, "branch:          %s\n", QUADD_MODULE_BRANCH);
38         seq_printf(f, "samples version: %d\n", QUADD_SAMPLES_VERSION);
39         seq_printf(f, "io version:      %d\n", QUADD_IO_VERSION);
40
41         return 0;
42 }
43
44 static int show_version_proc_open(struct inode *inode, struct file *file)
45 {
46         return single_open(file, show_version, NULL);
47 }
48
49 static const struct file_operations version_proc_fops = {
50         .open           = show_version_proc_open,
51         .read           = seq_read,
52         .llseek         = seq_lseek,
53         .release        = single_release,
54 };
55
56 static int show_capabilities(struct seq_file *f, void *offset)
57 {
58         struct quadd_comm_cap *cap = &ctx->cap;
59         struct quadd_events_cap *event = &cap->events_cap;
60         unsigned int extra = cap->reserved[QUADD_COMM_CAP_IDX_EXTRA];
61
62         seq_printf(f, "pmu:                                   %s\n",
63                    YES_NO(cap->pmu));
64         seq_printf(f, "tegra 3 LP cluster:                    %s\n",
65                    YES_NO(cap->tegra_lp_cluster));
66         seq_printf(f, "power rate samples:                    %s\n",
67                    YES_NO(cap->power_rate));
68
69         seq_printf(f, "l2 cache:                              %s\n",
70                    YES_NO(cap->l2_cache));
71         if (cap->l2_cache) {
72                 seq_printf(f, "multiple l2 events:             %s\n",
73                            YES_NO(cap->l2_multiple_events));
74         }
75
76         seq_printf(f, "support polling mode:                  %s\n",
77                    YES_NO(cap->blocked_read));
78         seq_printf(f, "backtrace from the kernel ctx:         %s\n",
79                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX));
80         seq_printf(f, "send mmap regions at the start:        %s\n",
81                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_GET_MMAP));
82         seq_printf(f, "group samples:                         %s\n",
83                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES));
84         seq_printf(f, "unwinding based on ex-handling tables: %s\n",
85                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES));
86         seq_printf(f, "support AArch64 architecture:          %s\n",
87                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64));
88         seq_printf(f, "support special architecture mappings: %s\n",
89                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP));
90         seq_printf(f, "support mixed unwinding mode:          %s\n",
91                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNWIND_MIXED));
92         seq_printf(f, "information about unwind entry:        %s\n",
93                    YES_NO(extra & QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE));
94
95         seq_puts(f, "\n");
96         seq_puts(f, "Supported events:\n");
97         seq_printf(f, "cpu_cycles:                     %s\n",
98                    YES_NO(event->cpu_cycles));
99         seq_printf(f, "instructions:                   %s\n",
100                    YES_NO(event->instructions));
101         seq_printf(f, "branch_instructions:            %s\n",
102                    YES_NO(event->branch_instructions));
103         seq_printf(f, "branch_misses:                  %s\n",
104                    YES_NO(event->branch_misses));
105         seq_printf(f, "bus_cycles:                     %s\n",
106                    YES_NO(event->bus_cycles));
107         seq_printf(f, "l1_dcache_read_misses:          %s\n",
108                    YES_NO(event->l1_dcache_read_misses));
109         seq_printf(f, "l1_dcache_write_misses:         %s\n",
110                    YES_NO(event->l1_dcache_write_misses));
111         seq_printf(f, "l1_icache_misses:               %s\n",
112                    YES_NO(event->l1_icache_misses));
113         seq_printf(f, "l2_dcache_read_misses:          %s\n",
114                    YES_NO(event->l2_dcache_read_misses));
115         seq_printf(f, "l2_dcache_write_misses:         %s\n",
116                    YES_NO(event->l2_dcache_write_misses));
117         seq_printf(f, "l2_icache_misses:               %s\n",
118                    YES_NO(event->l2_icache_misses));
119
120         return 0;
121 }
122
123 static int show_capabilities_proc_open(struct inode *inode, struct file *file)
124 {
125         return single_open(file, show_capabilities, NULL);
126 }
127
128 static const struct file_operations capabilities_proc_fops = {
129         .open           = show_capabilities_proc_open,
130         .read           = seq_read,
131         .llseek         = seq_lseek,
132         .release        = single_release,
133 };
134
135 static int show_status(struct seq_file *f, void *offset)
136 {
137         unsigned int status;
138         unsigned int is_auth_open, active;
139         struct quadd_module_state s;
140
141         quadd_get_state(&s);
142         status = s.reserved[QUADD_MOD_STATE_IDX_STATUS];
143
144         active = status & QUADD_MOD_STATE_STATUS_IS_ACTIVE;
145         is_auth_open = status & QUADD_MOD_STATE_STATUS_IS_AUTH_OPEN;
146
147         seq_printf(f, "status:          %s\n", active ? "active" : "waiting");
148         seq_printf(f, "auth:            %s\n", YES_NO(is_auth_open));
149         seq_printf(f, "all samples:     %llu\n", s.nr_all_samples);
150         seq_printf(f, "skipped samples: %llu\n", s.nr_skipped_samples);
151
152         return 0;
153 }
154
155 static int show_status_proc_open(struct inode *inode, struct file *file)
156 {
157         return single_open(file, show_status, NULL);
158 }
159
160 static const struct file_operations status_proc_fops = {
161         .open           = show_status_proc_open,
162         .read           = seq_read,
163         .llseek         = seq_lseek,
164         .release        = single_release,
165 };
166
167 void quadd_proc_init(struct quadd_ctx *context)
168 {
169         ctx = context;
170
171         proc_mkdir(QUADD_PROC_DEV, NULL);
172
173         proc_create(QUADD_PROC_DEV "/version", 0, NULL, &version_proc_fops);
174         proc_create(QUADD_PROC_DEV "/capabilities", 0, NULL,
175                     &capabilities_proc_fops);
176         proc_create(QUADD_PROC_DEV "/status", 0, NULL, &status_proc_fops);
177 }
178
179 void quadd_proc_deinit(void)
180 {
181         remove_proc_entry(QUADD_PROC_DEV "/version", NULL);
182         remove_proc_entry(QUADD_PROC_DEV "/capabilities", NULL);
183         remove_proc_entry(QUADD_PROC_DEV "/status", NULL);
184         remove_proc_entry(QUADD_PROC_DEV, NULL);
185 }
186
187 #endif  /* CONFIG_PROC_FS */