diff options
-rw-r--r-- | nvdebug.h | 41 | ||||
-rw-r--r-- | runlist_procfs.c | 36 |
2 files changed, 42 insertions, 35 deletions
@@ -365,7 +365,32 @@ enum CHANNEL_STATUS { | |||
365 | 365 | ||
366 | 512-entry array of channel control and status data structures. | 366 | 512-entry array of channel control and status data structures. |
367 | 367 | ||
368 | Support: Fermi, Maxwell, Pascal, Volta, Turing, [more?] | 368 | === Read/Write Fields === |
369 | INST_PTR : Top 28 of 40 bits of page-aligned channel instance block. | ||
370 | Instance Block = (uint64_t)inst_ptr << 12. | ||
371 | INST_TARGET : Aperture of INST_PTR. | ||
372 | INST_BIND : Is the channel instance bound? | ||
373 | NEXT : Is this the next channel to be scheduled in the runlist? | ||
374 | |||
375 | === Read-Only Fields === | ||
376 | ENABLE : Is this channel enabled? (Disabled channels are skipped | ||
377 | over by the runlist scheduler.) | ||
378 | PBDMA_FAULTED^ : [UNKNOWN] | ||
379 | ENG_FAULTED^ : [UNKNOWN] | ||
380 | STATUS : Status of this channel in regards to hardware. See enum | ||
381 | CHANNEL_STATUS. | ||
382 | BUSY : [UNKNOWN] | ||
383 | ^Field can be reset with a non-zero write. | ||
384 | |||
385 | === Write-Only Fields === | ||
386 | FORCE_CTX_RELOAD : [UNKNOWN] | ||
387 | ENABLE_SET : Enables the channel upon non-zero write. | ||
388 | ENABLE_CLEAR : Disables the channel upon non-zero write. | ||
389 | FORCE_PBDMA_FAULTED* : [UNKNOWN] | ||
390 | FORCE_ENG_FAULTED* : [UNKNOWN] | ||
391 | *Field only available on Turing. | ||
392 | |||
393 | Support: Fermi, Maxwell, Pascal, Volta, Turing | ||
369 | */ | 394 | */ |
370 | #define NV_PCCSR_CHANNEL_INST(i) (0x00800000+(i)*8) | 395 | #define NV_PCCSR_CHANNEL_INST(i) (0x00800000+(i)*8) |
371 | #define MAX_CHID 512 | 396 | #define MAX_CHID 512 |
@@ -374,22 +399,24 @@ typedef union { | |||
374 | // 0:31 | 399 | // 0:31 |
375 | uint32_t inst_ptr:28; | 400 | uint32_t inst_ptr:28; |
376 | enum INST_TARGET inst_target:2; | 401 | enum INST_TARGET inst_target:2; |
377 | uint32_t padding0:1; | 402 | uint32_t :1; |
378 | bool inst_bind:1; | 403 | bool inst_bind:1; |
379 | // 32:64 | 404 | // 32:63 |
380 | bool enable:1; | 405 | bool enable:1; |
381 | bool next:1; | 406 | bool next:1; |
382 | uint32_t padding:6; | 407 | uint32_t :6; |
383 | bool force_ctx_reload:1; | 408 | bool force_ctx_reload:1; |
384 | uint32_t padding2:1; | 409 | uint32_t :1; |
385 | bool enable_set:1; | 410 | bool enable_set:1; |
386 | bool enable_clear:1; | 411 | bool enable_clear:1; |
387 | uint32_t padding3:10; | 412 | uint32_t :8; |
413 | bool force_pbdma_faulted:1; | ||
414 | bool force_eng_faulted:1; | ||
388 | bool pbdma_faulted:1; | 415 | bool pbdma_faulted:1; |
389 | bool eng_faulted:1; | 416 | bool eng_faulted:1; |
390 | enum CHANNEL_STATUS status:4; | 417 | enum CHANNEL_STATUS status:4; |
391 | bool busy:1; | 418 | bool busy:1; |
392 | uint32_t padding4:3; | 419 | uint32_t :3; |
393 | } __attribute__((packed)); | 420 | } __attribute__((packed)); |
394 | uint64_t raw; | 421 | uint64_t raw; |
395 | } channel_ctrl_t; | 422 | } channel_ctrl_t; |
diff --git a/runlist_procfs.c b/runlist_procfs.c index f569c77..986465d 100644 --- a/runlist_procfs.c +++ b/runlist_procfs.c | |||
@@ -6,51 +6,32 @@ | |||
6 | #define RUNLIST_PROCFS_NAME "runlist" | 6 | #define RUNLIST_PROCFS_NAME "runlist" |
7 | #define DETAILED_CHANNEL_INFO | 7 | #define DETAILED_CHANNEL_INFO |
8 | 8 | ||
9 | #ifdef DETAILED_CHANNEL_INFO | ||
9 | /* Print channel details using PCCSR (Programmable Channel Control System RAM?) | 10 | /* Print channel details using PCCSR (Programmable Channel Control System RAM?) |
10 | * @param s Pointer to state from seq_file subsystem to pass to seq_printf | 11 | * @param s Pointer to state from seq_file subsystem to pass to seq_printf |
11 | * @param g Pointer to our internal GPU state | 12 | * @param g Pointer to our internal GPU state |
12 | * @param chid ID of channel to print details on, range [0, 512) | 13 | * @param chid ID of channel to print details on, range [0, 512) |
13 | * @param prefix Text string to prefix each line with, or empty string | 14 | * @param prefix Text string to prefix each line with, or empty string |
14 | */ | 15 | */ |
15 | #ifdef DETAILED_CHANNEL_INFO | ||
16 | static int runlist_detail_seq_show_chan(struct seq_file *s, struct nvdebug_state *g, uint32_t chid, char *prefix) { | 16 | static int runlist_detail_seq_show_chan(struct seq_file *s, struct nvdebug_state *g, uint32_t chid, char *prefix) { |
17 | channel_ctrl_t chan; | 17 | channel_ctrl_t chan; |
18 | const char *loc_txt; | ||
19 | uint64_t instance_ptr; | 18 | uint64_t instance_ptr; |
20 | 19 | ||
21 | chan.raw = nvdebug_readq(g, NV_PCCSR_CHANNEL_INST(chid)); | 20 | if ((chan.raw = nvdebug_readq(g, NV_PCCSR_CHANNEL_INST(chid))) == -1) |
22 | loc_txt = target_to_text(chan.inst_target); | ||
23 | if (!loc_txt) | ||
24 | return -EIO; | 21 | return -EIO; |
25 | instance_ptr = chan.inst_ptr; | 22 | instance_ptr = (uint64_t)chan.inst_ptr << 12; |
26 | instance_ptr <<= 12; | 23 | // Don't print write-only fields |
27 | seq_printf(s, "%s+- Channel Info %-4d -+\n", prefix, chid); | 24 | seq_printf(s, "%s+- Channel Info %-4d -+\n", prefix, chid); |
28 | seq_printf(s, "%s| Enabled: %d|\n", prefix, chan.enable); | 25 | seq_printf(s, "%s| Enabled: %d|\n", prefix, chan.enable); |
29 | seq_printf(s, "%s| Next: %d|\n", prefix, chan.next); | 26 | seq_printf(s, "%s| Next: %d|\n", prefix, chan.next); |
30 | seq_printf(s, "%s| Force CTX Reload: %d|\n", prefix, chan.force_ctx_reload); | ||
31 | seq_printf(s, "%s| Enable set: %d|\n", prefix, chan.enable_set); | ||
32 | seq_printf(s, "%s| Enable clear: %d|\n", prefix, chan.enable_clear); | ||
33 | seq_printf(s, "%s| PBDMA Faulted: %d|\n", prefix, chan.pbdma_faulted); | 27 | seq_printf(s, "%s| PBDMA Faulted: %d|\n", prefix, chan.pbdma_faulted); |
34 | seq_printf(s, "%s| ENG Faulted: %d|\n", prefix, chan.eng_faulted); | 28 | seq_printf(s, "%s| ENG Faulted: %d|\n", prefix, chan.eng_faulted); |
35 | seq_printf(s, "%s| Status: %2d|\n", prefix, chan.status); | 29 | seq_printf(s, "%s| Status: %2d|\n", prefix, chan.status); |
36 | seq_printf(s, "%s| Busy: %d|\n", prefix, chan.busy); | 30 | seq_printf(s, "%s| Busy: %d|\n", prefix, chan.busy); |
37 | seq_printf(s, "%s| Instance PTR: |\n", prefix); | 31 | seq_printf(s, "%s| Instance PTR: |\n", prefix); |
38 | seq_printf(s, "%s| %#018llx|\n", prefix, instance_ptr); | 32 | seq_printf(s, "%s| %#018llx|\n", prefix, instance_ptr); |
39 | seq_printf(s, "%s| %20s|\n", prefix, loc_txt); | 33 | seq_printf(s, "%s| %20s|\n", prefix, target_to_text(chan.inst_target)); |
40 | seq_printf(s, "%s| Instance bound: %d|\n", prefix, chan.inst_bind); | 34 | seq_printf(s, "%s| Instance bound: %d|\n", prefix, chan.inst_bind); |
41 | // START TEMP | ||
42 | // "runlist_id -1 is synonym for the ENGINE_GR_GK20A runlist id" | ||
43 | // GR, GRCE, and ASYNC_CE | ||
44 | // Note that this appears to be broken?? | ||
45 | // Peek into the channel instance RAM | ||
46 | if (chan.inst_target == TARGET_SYS_MEM_COHERENT) { | ||
47 | seq_printf(s, "%s| Target Engine: %2d|\n", prefix, *(uint32_t*)phys_to_virt(instance_ptr + 4/*bytes for 32bits*/*43/*NV_RAMFC_TARGET*/) & 0x1f); | ||
48 | seq_printf(s, "%s| PDB LO: %#08x|\n", prefix, *(uint32_t*)phys_to_virt(instance_ptr + 4/*bytes for 32bits*/*128/*NV_RAMIN_PAGE_DIR_BASE_LO*/) & 0xfffff000); | ||
49 | seq_printf(s, "%s| Num subcontexts: %2ld|\n", prefix, hweight64(*(uint64_t*)phys_to_virt(instance_ptr + 4/*bytes for 32bits*/*166/*NV_RAMIN_SC_PDB_VALID*/))); | ||
50 | // This appears to be unset on Xavier | ||
51 | //seq_printf(s, "%s| PAS ID: %8ld|\n", prefix, *(uint32_t*)phys_to_virt(instance_ptr + 4/*bytes for 32bits*/*135/*NV_RAMIN_PASID*/) & 0xfffff); | ||
52 | } | ||
53 | // END TEMP | ||
54 | seq_printf(s, "%s+---------------------+\n", prefix); | 35 | seq_printf(s, "%s+---------------------+\n", prefix); |
55 | return 0; | 36 | return 0; |
56 | } | 37 | } |
@@ -136,14 +117,14 @@ static int runlist_file_seq_show(struct seq_file *s, void *raw_rl_iter) { | |||
136 | seq_printf(s, "+---------------------+\n"); | 117 | seq_printf(s, "+---------------------+\n"); |
137 | } else { | 118 | } else { |
138 | char *indt = ""; | 119 | char *indt = ""; |
139 | #ifndef DETAILED_CHANNEL_INFO | ||
140 | u64 instance_ptr = 0; | 120 | u64 instance_ptr = 0; |
141 | #endif | 121 | |
142 | if (rl_iter->entries_left_in_tsg) | 122 | if (rl_iter->entries_left_in_tsg) |
143 | indt = " "; | 123 | indt = " "; |
144 | #ifdef DETAILED_CHANNEL_INFO | 124 | #ifdef DETAILED_CHANNEL_INFO |
145 | runlist_detail_seq_show_chan(s, g, chid(g, entry), indt); | 125 | runlist_detail_seq_show_chan(s, g, chid(g, entry), indt); |
146 | #else | 126 | return 0; |
127 | #endif | ||
147 | // Reconstruct pointer to channel instance block | 128 | // Reconstruct pointer to channel instance block |
148 | if (g->chip_id >= NV_CHIP_ID_VOLTA) { | 129 | if (g->chip_id >= NV_CHIP_ID_VOLTA) { |
149 | instance_ptr = ((struct gv100_runlist_chan*)entry)->inst_ptr_hi; | 130 | instance_ptr = ((struct gv100_runlist_chan*)entry)->inst_ptr_hi; |
@@ -159,7 +140,6 @@ static int runlist_file_seq_show(struct seq_file *s, void *raw_rl_iter) { | |||
159 | seq_printf(s, "%s| %#018llx|\n", indt, instance_ptr); | 140 | seq_printf(s, "%s| %#018llx|\n", indt, instance_ptr); |
160 | seq_printf(s, "%s| %20s|\n", indt, target_to_text(inst_target(g, entry))); | 141 | seq_printf(s, "%s| %20s|\n", indt, target_to_text(inst_target(g, entry))); |
161 | seq_printf(s, "%s+---------------------+\n", indt); | 142 | seq_printf(s, "%s+---------------------+\n", indt); |
162 | #endif | ||
163 | } | 143 | } |
164 | return 0; | 144 | return 0; |
165 | } | 145 | } |