diff options
| author | Loic Pallardy <loic.pallardy@st.com> | 2017-11-06 12:09:55 -0500 |
|---|---|---|
| committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2017-11-07 00:57:21 -0500 |
| commit | bdd8edb9b0cd552f09a81c32d699af041155a390 (patch) | |
| tree | 99b6e2b20c38b71c9505c09f8d31473f5eabf28c | |
| parent | 9f058fa2efb10cd75884c4ee6c357bab07715f02 (diff) | |
remoteproc: debug: add resource table dump feature
This patch adds the capability to display the content of
the resource table associated to a remote processor firmware.
Signed-off-by: Loic Pallardy <loic.pallardy@st.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
| -rw-r--r-- | drivers/remoteproc/remoteproc_debugfs.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index 1c122e230cec..dc5e25943df7 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c | |||
| @@ -155,6 +155,103 @@ static const struct file_operations rproc_recovery_ops = { | |||
| 155 | .llseek = generic_file_llseek, | 155 | .llseek = generic_file_llseek, |
| 156 | }; | 156 | }; |
| 157 | 157 | ||
| 158 | /* Expose resource table content via debugfs */ | ||
| 159 | static int rproc_rsc_table_show(struct seq_file *seq, void *p) | ||
| 160 | { | ||
| 161 | static const char * const types[] = {"carveout", "devmem", "trace", "vdev"}; | ||
| 162 | struct rproc *rproc = seq->private; | ||
| 163 | struct resource_table *table = rproc->table_ptr; | ||
| 164 | struct fw_rsc_carveout *c; | ||
| 165 | struct fw_rsc_devmem *d; | ||
| 166 | struct fw_rsc_trace *t; | ||
| 167 | struct fw_rsc_vdev *v; | ||
| 168 | int i, j; | ||
| 169 | |||
| 170 | if (!table) { | ||
| 171 | seq_puts(seq, "No resource table found\n"); | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | for (i = 0; i < table->num; i++) { | ||
| 176 | int offset = table->offset[i]; | ||
| 177 | struct fw_rsc_hdr *hdr = (void *)table + offset; | ||
| 178 | void *rsc = (void *)hdr + sizeof(*hdr); | ||
| 179 | |||
| 180 | switch (hdr->type) { | ||
| 181 | case RSC_CARVEOUT: | ||
| 182 | c = rsc; | ||
| 183 | seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]); | ||
| 184 | seq_printf(seq, " Device Address 0x%x\n", c->da); | ||
| 185 | seq_printf(seq, " Physical Address 0x%x\n", c->pa); | ||
| 186 | seq_printf(seq, " Length 0x%x Bytes\n", c->len); | ||
| 187 | seq_printf(seq, " Flags 0x%x\n", c->flags); | ||
| 188 | seq_printf(seq, " Reserved (should be zero) [%d]\n", c->reserved); | ||
| 189 | seq_printf(seq, " Name %s\n\n", c->name); | ||
| 190 | break; | ||
| 191 | case RSC_DEVMEM: | ||
| 192 | d = rsc; | ||
| 193 | seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]); | ||
| 194 | seq_printf(seq, " Device Address 0x%x\n", d->da); | ||
| 195 | seq_printf(seq, " Physical Address 0x%x\n", d->pa); | ||
| 196 | seq_printf(seq, " Length 0x%x Bytes\n", d->len); | ||
| 197 | seq_printf(seq, " Flags 0x%x\n", d->flags); | ||
| 198 | seq_printf(seq, " Reserved (should be zero) [%d]\n", d->reserved); | ||
| 199 | seq_printf(seq, " Name %s\n\n", d->name); | ||
| 200 | break; | ||
| 201 | case RSC_TRACE: | ||
| 202 | t = rsc; | ||
| 203 | seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]); | ||
| 204 | seq_printf(seq, " Device Address 0x%x\n", t->da); | ||
| 205 | seq_printf(seq, " Length 0x%x Bytes\n", t->len); | ||
| 206 | seq_printf(seq, " Reserved (should be zero) [%d]\n", t->reserved); | ||
| 207 | seq_printf(seq, " Name %s\n\n", t->name); | ||
| 208 | break; | ||
| 209 | case RSC_VDEV: | ||
| 210 | v = rsc; | ||
| 211 | seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]); | ||
| 212 | |||
| 213 | seq_printf(seq, " ID %d\n", v->id); | ||
| 214 | seq_printf(seq, " Notify ID %d\n", v->notifyid); | ||
| 215 | seq_printf(seq, " Device features 0x%x\n", v->dfeatures); | ||
| 216 | seq_printf(seq, " Guest features 0x%x\n", v->gfeatures); | ||
| 217 | seq_printf(seq, " Config length 0x%x\n", v->config_len); | ||
| 218 | seq_printf(seq, " Status 0x%x\n", v->status); | ||
| 219 | seq_printf(seq, " Number of vrings %d\n", v->num_of_vrings); | ||
| 220 | seq_printf(seq, " Reserved (should be zero) [%d][%d]\n\n", | ||
| 221 | v->reserved[0], v->reserved[1]); | ||
| 222 | |||
| 223 | for (j = 0; j < v->num_of_vrings; j++) { | ||
| 224 | seq_printf(seq, " Vring %d\n", j); | ||
| 225 | seq_printf(seq, " Device Address 0x%x\n", v->vring[j].da); | ||
| 226 | seq_printf(seq, " Alignment %d\n", v->vring[j].align); | ||
| 227 | seq_printf(seq, " Number of buffers %d\n", v->vring[j].num); | ||
| 228 | seq_printf(seq, " Notify ID %d\n", v->vring[j].notifyid); | ||
| 229 | seq_printf(seq, " Physical Address 0x%x\n\n", | ||
| 230 | v->vring[j].pa); | ||
| 231 | } | ||
| 232 | break; | ||
| 233 | default: | ||
| 234 | seq_printf(seq, "Unknown resource type found: %d [hdr: %p]\n", | ||
| 235 | hdr->type, hdr); | ||
| 236 | break; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int rproc_rsc_table_open(struct inode *inode, struct file *file) | ||
| 244 | { | ||
| 245 | return single_open(file, rproc_rsc_table_show, inode->i_private); | ||
| 246 | } | ||
| 247 | |||
| 248 | static const struct file_operations rproc_rsc_table_ops = { | ||
| 249 | .open = rproc_rsc_table_open, | ||
| 250 | .read = seq_read, | ||
| 251 | .llseek = seq_lseek, | ||
| 252 | .release = single_release, | ||
| 253 | }; | ||
| 254 | |||
| 158 | void rproc_remove_trace_file(struct dentry *tfile) | 255 | void rproc_remove_trace_file(struct dentry *tfile) |
| 159 | { | 256 | { |
| 160 | debugfs_remove(tfile); | 257 | debugfs_remove(tfile); |
| @@ -198,6 +295,8 @@ void rproc_create_debug_dir(struct rproc *rproc) | |||
| 198 | rproc, &rproc_name_ops); | 295 | rproc, &rproc_name_ops); |
| 199 | debugfs_create_file("recovery", 0400, rproc->dbg_dir, | 296 | debugfs_create_file("recovery", 0400, rproc->dbg_dir, |
| 200 | rproc, &rproc_recovery_ops); | 297 | rproc, &rproc_recovery_ops); |
| 298 | debugfs_create_file("resource_table", 0400, rproc->dbg_dir, | ||
| 299 | rproc, &rproc_rsc_table_ops); | ||
| 201 | } | 300 | } |
| 202 | 301 | ||
| 203 | void __init rproc_init_debugfs(void) | 302 | void __init rproc_init_debugfs(void) |
