diff options
-rw-r--r-- | nvdebug.h | 30 | ||||
-rw-r--r-- | runlist.c | 2 |
2 files changed, 23 insertions, 9 deletions
@@ -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) |
962 | static inline u32 nvdebug_readl(struct nvdebug_state *s, u32 r) { | 962 | static 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() |
971 | static inline u64 nvdebug_readq(struct nvdebug_state *s, u32 r) { | 978 | static 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() |
984 | static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) { | 996 | static 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 |
995 | static inline void nvdebug_writeq(struct nvdebug_state *s, u32 r, u64 v) { | 1007 | static 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 | } |
@@ -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); |