diff options
author | Joshua Bakita <jbakita@cs.unc.edu> | 2021-08-26 18:53:29 -0400 |
---|---|---|
committer | Joshua Bakita <jbakita@cs.unc.edu> | 2021-08-26 18:53:29 -0400 |
commit | 54e783959b5d3622556bbf34a3a7ad8e481d9e25 (patch) | |
tree | 3221f3d93c6a12d2098ddd6ef95a39b2c2b69347 /nvdebug.h | |
parent | 5f661d8a5db3f7875f6bf36b4843a71fd08ecbea (diff) |
Use procfs instead of dmesg to print runlist
`cat /proc/runlist` to print the current runlist.
Also break nvdebug.c into nvdebug_entry.c, runlist.c, and
runlist_procfs.c.
Diffstat (limited to 'nvdebug.h')
-rw-r--r-- | nvdebug.h | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -2,6 +2,10 @@ | |||
2 | * SPDX-License-Identifier: MIT | 2 | * SPDX-License-Identifier: MIT |
3 | */ | 3 | */ |
4 | 4 | ||
5 | // TODO(jbakita): Don't depend on these. | ||
6 | #include <nvgpu/gk20a.h> // For struct gk20a | ||
7 | #include <os/linux/os_linux.h> // For struct nvgpu_os_linux | ||
8 | |||
5 | /* Runlist Channel | 9 | /* Runlist Channel |
6 | A timeslice group (TSG) is composed of channels. Each channel is a FIFO queue | 10 | A timeslice group (TSG) is composed of channels. Each channel is a FIFO queue |
7 | of GPU commands. These commands are typically queued from userspace. | 11 | of GPU commands. These commands are typically queued from userspace. |
@@ -125,3 +129,48 @@ typedef union { | |||
125 | } __attribute__((packed)); | 129 | } __attribute__((packed)); |
126 | uint32_t raw; | 130 | uint32_t raw; |
127 | } runlist_info_t; | 131 | } runlist_info_t; |
132 | |||
133 | // TODO(jbakita): Maybe put the above GPU types in a different file. | ||
134 | |||
135 | #define for_chan_in_tsg(chan, tsg) \ | ||
136 | for (chan = (struct runlist_chan*)(tsg + 1); \ | ||
137 | (void*)chan < (void*)(tsg + 1) + sizeof(struct runlist_chan) * tsg->tsg_length; \ | ||
138 | chan++) | ||
139 | |||
140 | #define next_tsg(tsg) \ | ||
141 | (void*)(tsg + 1) + sizeof(struct runlist_chan) * tsg->tsg_length | ||
142 | |||
143 | struct runlist_iter { | ||
144 | struct entry_tsg *curr_tsg; | ||
145 | runlist_info_t rl_info; | ||
146 | }; | ||
147 | |||
148 | // Defined in runlist.c | ||
149 | int get_runlist_iter(struct runlist_iter *rl_iter); | ||
150 | |||
151 | static inline struct gk20a *get_gk20a(struct device *dev) { | ||
152 | // XXX: Only works because gk20a* is the first member of gk20a_platform | ||
153 | return *((struct gk20a**)dev_get_drvdata(dev)); | ||
154 | } | ||
155 | |||
156 | // Functionally identical to nvgpu_readl() | ||
157 | // (except we don't try to resolve situations where regs is NULL) | ||
158 | static inline u32 nvdebug_readl(struct gk20a* g, u32 r) { | ||
159 | struct nvgpu_os_linux* g_os = container_of(g, struct nvgpu_os_linux, g); | ||
160 | if (unlikely(!g_os->regs)) { | ||
161 | printk(KERN_ERR "[nvdebug] Attempted nvgpu_readl on non-existent registers!\n"); | ||
162 | return -1; | ||
163 | } | ||
164 | return readl(g_os->regs + r); | ||
165 | } | ||
166 | |||
167 | // Functionally identical to nvgpu_writel() | ||
168 | static inline void nvdebug_writel(struct gk20a* g, u32 r, u32 v) { | ||
169 | struct nvgpu_os_linux* g_os = container_of(g, struct nvgpu_os_linux, g); | ||
170 | if (unlikely(!g_os->regs)) { | ||
171 | printk(KERN_ERR "[nvdebug] Attempted nvgpu_writel on non-existent registers!\n"); | ||
172 | return; | ||
173 | } | ||
174 | writel_relaxed(v, g_os->regs + r); | ||
175 | wmb(); | ||
176 | } | ||