2 * drivers/misc/tegra-profiler/quadd_proc.c
4 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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.
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
19 #include <linux/proc_fs.h>
20 #include <linux/seq_file.h>
22 #include <linux/tegra_profiler.h>
26 #include "quadd_proc.h"
29 #define YES_NO(x) ((x) ? "yes" : "no")
31 static struct quadd_ctx *ctx;
33 #define QUADD_PROC_DEV QUADD_DEVICE_NAME
35 static int show_version(struct seq_file *f, void *offset)
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);
45 static int show_version_proc_open(struct inode *inode, struct file *file)
47 return single_open(file, show_version, NULL);
50 static const struct file_operations version_proc_fops = {
51 .open = show_version_proc_open,
54 .release = single_release,
57 static int show_capabilities(struct seq_file *f, void *offset)
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;
65 arch = ctx->pmu->get_arch();
67 seq_printf(f, "pmu: %s\n",
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));
74 seq_printf(f, "l2 cache: %s\n",
75 YES_NO(cap->l2_cache));
77 seq_printf(f, "multiple l2 events: %s\n",
78 YES_NO(cap->l2_multiple_events));
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));
103 seq_printf(f, "pmu arch: %s\n",
105 seq_printf(f, "pmu arch version: %d\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));
137 static int show_capabilities_proc_open(struct inode *inode, struct file *file)
139 return single_open(file, show_capabilities, NULL);
142 static const struct file_operations capabilities_proc_fops = {
143 .open = show_capabilities_proc_open,
146 .release = single_release,
149 static int show_status(struct seq_file *f, void *offset)
152 unsigned int is_auth_open, active;
153 struct quadd_module_state s;
156 status = s.reserved[QUADD_MOD_STATE_IDX_STATUS];
158 active = status & QUADD_MOD_STATE_STATUS_IS_ACTIVE;
159 is_auth_open = status & QUADD_MOD_STATE_STATUS_IS_AUTH_OPEN;
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);
169 static int show_status_proc_open(struct inode *inode, struct file *file)
171 return single_open(file, show_status, NULL);
174 static const struct file_operations status_proc_fops = {
175 .open = show_status_proc_open,
178 .release = single_release,
181 void quadd_proc_init(struct quadd_ctx *context)
185 proc_mkdir(QUADD_PROC_DEV, NULL);
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);
193 void quadd_proc_deinit(void)
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);
201 #endif /* CONFIG_PROC_FS */