/* Copyright 2024 Joshua Bakita * SPDX-License-Identifier: MIT * * Helpers which are kernel-specific */ #include "nvdebug.h" #include // For dev_get_drvdata() #include // For struct seq_file #include // For pde_data() macro #include // For KERNEL_VERSION and LINUX_VERSION_CODE static inline struct gk20a *get_gk20a(struct device *dev) { // Only works because gk20a* is the first member of gk20a_platform return *((struct gk20a**)dev_get_drvdata(dev)); } // PDE_DATA was Renamed to pde_data in Linux 5.17 to deconflict with a driver #if LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0) #define pde_data PDE_DATA #endif // We us the data field of the proc_dir_entry ("PDE" in this function) to store // our index into the g_nvdebug_state array static inline int seq2gpuidx(struct seq_file *s) { const struct file *f = s->file; return (uintptr_t)pde_data(file_inode(f)); } static inline int file2gpuidx(const struct file *f) { return (uintptr_t)pde_data(file_inode(f)); } static inline int file2parentgpuidx(const struct file *f) { // Should be safe to call on ProcFS entries, as our parent should (?) // still exist if we're called. If not, there are worse races in this // module. return (uintptr_t)pde_data(file_dentry(f)->d_parent->d_inode); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) // Commit 643eb158a3 in nvgpu moved the mapped registers to the second entry // of the gk20a struct (after a function pointer). This change was made as L4T // was upgraded from Linux 4.9 to 5.10 (r32 -> r34+) // Note that this is wrong if nvgpu was built without CONFIG_NVGPU_NON_FUSA // i.e. if FUSA was enabled, this is wrong. #define gk20a_regs(gk20a) (*(void**)((void*)gk20a + sizeof(void(*)(void)))) #else #include // For struct nvgpu_os_linux, which holds regs #define gk20a_regs(gk20a) (container_of(gk20a, struct nvgpu_os_linux, g)->regs) #endif