aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nvdebug.h30
-rw-r--r--runlist.c2
2 files changed, 23 insertions, 9 deletions
diff --git a/nvdebug.h b/nvdebug.h
index 8009b84..8db07ee 100644
--- a/nvdebug.h
+++ b/nvdebug.h
@@ -960,30 +960,42 @@ static inline int file2parentgpuidx(const struct file *f) {
960// Similar to nvgpu_readl() 960// Similar to nvgpu_readl()
961// (except we don't try to resolve situations where regs is NULL) 961// (except we don't try to resolve situations where regs is NULL)
962static inline u32 nvdebug_readl(struct nvdebug_state *s, u32 r) { 962static inline u32 nvdebug_readl(struct nvdebug_state *s, u32 r) {
963 u32 ret;
963 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { 964 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) {
964 printk(KERN_ERR "[nvdebug] Attempted nvgpu_readl on non-existent registers!\n"); 965 printk(KERN_ERR "[nvdebug] nvdebug_readl: Unable to read; registers unavailable. Is GPU on?\n");
965 return -1; 966 return -1;
966 } 967 }
967 return readl(s->regs + r); 968 ret = readl(s->regs + r);
969 // It seems like the GPU returns this as a flag value for bad addresses
970 if (ret == 0xbadf5040) {
971 printk(KERN_ERR "[nvdebug] nvdebug_readl: Unable to read from register offset %#x; bad data\n", r);
972 return -1;
973 }
974 return ret;
968} 975}
969 976
970// quadword version of nvdebug_readl() 977// quadword version of nvdebug_readl()
971static inline u64 nvdebug_readq(struct nvdebug_state *s, u32 r) { 978static inline u64 nvdebug_readq(struct nvdebug_state *s, u32 r) {
972 u64 ret; 979 u64 ret;
973 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { 980 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) {
974 printk(KERN_ERR "[nvdebug] Attempted nvgpu_readl on non-existent registers!\n"); 981 printk(KERN_ERR "[nvdebug] nvdebug_readq: Unable to read; registers unavailable. Is GPU on?\n");
975 return -1; 982 return -1;
976 } 983 }
977 // readq seems to always return the uppermost 32 bits as 0, so workaround with readl 984 // readq seems to always return the uppermost 32 bits as 0, so workaround with readl
978 ret = readl(s->regs + r); 985 ret = readl(s->regs + r);
979 ret |= ((u64)readl(s->regs + r + 4)) << 32; 986 ret |= ((u64)readl(s->regs + r + 4)) << 32;
987 // It seems like the GPU returns this as a flag value for bad addresses
988 if ((ret & 0xffffffffull) == 0xbadf5040ull) {
989 printk(KERN_ERR "[nvdebug] nvdebug_readq: Unable to read from register offset %#x; bad data\n", r);
990 return -1;
991 }
980 return ret; 992 return ret;
981} 993}
982 994
983// Similar to nvgpu_writel() 995// Similar to nvgpu_writel()
984static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) { 996static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) {
985 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { 997 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) {
986 printk(KERN_ERR "[nvdebug] Attempted nvgpu_writel on non-existent registers!\n"); 998 printk(KERN_ERR "[nvdebug] nvdebug_writel: Unable to write; registers unavailable. Is GPU on?\n");
987 return; 999 return;
988 } 1000 }
989 writel_relaxed(v, s->regs + r); 1001 writel_relaxed(v, s->regs + r);
@@ -994,9 +1006,9 @@ static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) {
994// XXX: This probably doesn't work XXX: Untested 1006// XXX: This probably doesn't work XXX: Untested
995static inline void nvdebug_writeq(struct nvdebug_state *s, u32 r, u64 v) { 1007static inline void nvdebug_writeq(struct nvdebug_state *s, u32 r, u64 v) {
996 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { 1008 if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) {
997 printk(KERN_ERR "[nvdebug] Attempted nvgpu_writel on non-existent registers!\n"); 1009 printk(KERN_ERR "[nvdebug] nvdebug_writeq: Unable to write; registers unavailable. Is GPU on?\n");
998 return; 1010 return;
999 } 1011 }
1000 writeq_relaxed(v, s->regs + r); 1012 writeq_relaxed(v, s->regs + r);
1001 wmb(); 1013 wmb();
1002} 1014}
diff --git a/runlist.c b/runlist.c
index 94be18e..f6a05ac 100644
--- a/runlist.c
+++ b/runlist.c
@@ -41,6 +41,8 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
41 // before because the GPU had simply gone to sleep and invalidated its 41 // before because the GPU had simply gone to sleep and invalidated its
42 // register state, so nvgpu_readl() was simply returning garbage. 42 // register state, so nvgpu_readl() was simply returning garbage.
43 rl_info.raw = nvdebug_readl(g, NV_PFIFO_ENG_RUNLIST(rl_id)); 43 rl_info.raw = nvdebug_readl(g, NV_PFIFO_ENG_RUNLIST(rl_id));
44 if (rl_info.raw == -1)
45 return -EIO;
44 runlist_iova = ((u64)rl_base.ptr) << 12; 46 runlist_iova = ((u64)rl_base.ptr) << 12;
45 printk(KERN_INFO "[nvdebug] Runlist %d @ %llx in %s (config raw: %x)\n", 47 printk(KERN_INFO "[nvdebug] Runlist %d @ %llx in %s (config raw: %x)\n",
46 rl_id, runlist_iova, target_to_text(rl_base.target), rl_base.raw); 48 rl_id, runlist_iova, target_to_text(rl_base.target), rl_base.raw);