diff options
Diffstat (limited to 'include/os/linux/debug_fecs_trace.c')
-rw-r--r-- | include/os/linux/debug_fecs_trace.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/include/os/linux/debug_fecs_trace.c b/include/os/linux/debug_fecs_trace.c new file mode 100644 index 0000000..7786053 --- /dev/null +++ b/include/os/linux/debug_fecs_trace.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/debugfs.h> | ||
18 | |||
19 | #include <nvgpu/fecs_trace.h> | ||
20 | |||
21 | #include "os_linux.h" | ||
22 | |||
23 | /* | ||
24 | * The sequence iterator functions. We simply use the count of the | ||
25 | * next line as our internal position. | ||
26 | */ | ||
27 | static void *gk20a_fecs_trace_debugfs_ring_seq_start( | ||
28 | struct seq_file *s, loff_t *pos) | ||
29 | { | ||
30 | if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) | ||
31 | return NULL; | ||
32 | |||
33 | return pos; | ||
34 | } | ||
35 | |||
36 | static void *gk20a_fecs_trace_debugfs_ring_seq_next( | ||
37 | struct seq_file *s, void *v, loff_t *pos) | ||
38 | { | ||
39 | ++(*pos); | ||
40 | if (*pos >= GK20A_FECS_TRACE_NUM_RECORDS) | ||
41 | return NULL; | ||
42 | return pos; | ||
43 | } | ||
44 | |||
45 | static void gk20a_fecs_trace_debugfs_ring_seq_stop( | ||
46 | struct seq_file *s, void *v) | ||
47 | { | ||
48 | } | ||
49 | |||
50 | static int gk20a_fecs_trace_debugfs_ring_seq_show( | ||
51 | struct seq_file *s, void *v) | ||
52 | { | ||
53 | loff_t *pos = (loff_t *) v; | ||
54 | struct gk20a *g = *(struct gk20a **)s->private; | ||
55 | struct gk20a_fecs_trace_record *r = | ||
56 | gk20a_fecs_trace_get_record(g, *pos); | ||
57 | int i; | ||
58 | const u32 invalid_tag = gk20a_fecs_trace_record_ts_tag_invalid_ts_v(); | ||
59 | u32 tag; | ||
60 | u64 timestamp; | ||
61 | |||
62 | seq_printf(s, "record #%lld (%p)\n", *pos, r); | ||
63 | seq_printf(s, "\tmagic_lo=%08x\n", r->magic_lo); | ||
64 | seq_printf(s, "\tmagic_hi=%08x\n", r->magic_hi); | ||
65 | if (gk20a_fecs_trace_is_valid_record(r)) { | ||
66 | seq_printf(s, "\tcontext_ptr=%08x\n", r->context_ptr); | ||
67 | seq_printf(s, "\tcontext_id=%08x\n", r->context_id); | ||
68 | seq_printf(s, "\tnew_context_ptr=%08x\n", r->new_context_ptr); | ||
69 | seq_printf(s, "\tnew_context_id=%08x\n", r->new_context_id); | ||
70 | for (i = 0; i < gk20a_fecs_trace_num_ts(); i++) { | ||
71 | tag = gk20a_fecs_trace_record_ts_tag_v(r->ts[i]); | ||
72 | if (tag == invalid_tag) | ||
73 | continue; | ||
74 | timestamp = gk20a_fecs_trace_record_ts_timestamp_v(r->ts[i]); | ||
75 | timestamp <<= GK20A_FECS_TRACE_PTIMER_SHIFT; | ||
76 | seq_printf(s, "\ttag=%02x timestamp=%012llx\n", tag, timestamp); | ||
77 | } | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Tie them all together into a set of seq_operations. | ||
84 | */ | ||
85 | static const struct seq_operations gk20a_fecs_trace_debugfs_ring_seq_ops = { | ||
86 | .start = gk20a_fecs_trace_debugfs_ring_seq_start, | ||
87 | .next = gk20a_fecs_trace_debugfs_ring_seq_next, | ||
88 | .stop = gk20a_fecs_trace_debugfs_ring_seq_stop, | ||
89 | .show = gk20a_fecs_trace_debugfs_ring_seq_show | ||
90 | }; | ||
91 | |||
92 | /* | ||
93 | * Time to set up the file operations for our /proc file. In this case, | ||
94 | * all we need is an open function which sets up the sequence ops. | ||
95 | */ | ||
96 | |||
97 | static int gk20a_ctxsw_debugfs_ring_open(struct inode *inode, | ||
98 | struct file *file) | ||
99 | { | ||
100 | struct gk20a **p; | ||
101 | |||
102 | p = __seq_open_private(file, &gk20a_fecs_trace_debugfs_ring_seq_ops, | ||
103 | sizeof(struct gk20a *)); | ||
104 | if (!p) | ||
105 | return -ENOMEM; | ||
106 | |||
107 | *p = (struct gk20a *)inode->i_private; | ||
108 | return 0; | ||
109 | }; | ||
110 | |||
111 | /* | ||
112 | * The file operations structure contains our open function along with | ||
113 | * set of the canned seq_ ops. | ||
114 | */ | ||
115 | static const struct file_operations gk20a_fecs_trace_debugfs_ring_fops = { | ||
116 | .owner = THIS_MODULE, | ||
117 | .open = gk20a_ctxsw_debugfs_ring_open, | ||
118 | .read = seq_read, | ||
119 | .llseek = seq_lseek, | ||
120 | .release = seq_release_private | ||
121 | }; | ||
122 | |||
123 | static int gk20a_fecs_trace_debugfs_read(void *arg, u64 *val) | ||
124 | { | ||
125 | *val = gk20a_fecs_trace_get_read_index((struct gk20a *)arg); | ||
126 | return 0; | ||
127 | } | ||
128 | DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_read_fops, | ||
129 | gk20a_fecs_trace_debugfs_read, NULL, "%llu\n"); | ||
130 | |||
131 | static int gk20a_fecs_trace_debugfs_write(void *arg, u64 *val) | ||
132 | { | ||
133 | *val = gk20a_fecs_trace_get_write_index((struct gk20a *)arg); | ||
134 | return 0; | ||
135 | } | ||
136 | DEFINE_SIMPLE_ATTRIBUTE(gk20a_fecs_trace_debugfs_write_fops, | ||
137 | gk20a_fecs_trace_debugfs_write, NULL, "%llu\n"); | ||
138 | |||
139 | int nvgpu_fecs_trace_init_debugfs(struct gk20a *g) | ||
140 | { | ||
141 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
142 | |||
143 | debugfs_create_file("ctxsw_trace_read", 0600, l->debugfs, g, | ||
144 | &gk20a_fecs_trace_debugfs_read_fops); | ||
145 | debugfs_create_file("ctxsw_trace_write", 0600, l->debugfs, g, | ||
146 | &gk20a_fecs_trace_debugfs_write_fops); | ||
147 | debugfs_create_file("ctxsw_trace_ring", 0600, l->debugfs, g, | ||
148 | &gk20a_fecs_trace_debugfs_ring_fops); | ||
149 | |||
150 | return 0; | ||
151 | } | ||