From 3aab3c220f3f0bcc3d3d58d0daf6fd6acf1819e2 Mon Sep 17 00:00:00 2001 From: Joshua J Bakita Date: Wed, 8 Nov 2023 14:41:47 -0500 Subject: Expand support for printing LCE<->PCE and GRCE->LCE configuration Tested working on Pascal, Volta, Volta Integrated, Turing, Ampere, and Ada. Also clean up minor spacing issues, an errantly added file (nvdebug.mod), and fix some inconsistencies with upstream. --- device_info_procfs.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'device_info_procfs.c') diff --git a/device_info_procfs.c b/device_info_procfs.c index d5350c8..168905f 100644 --- a/device_info_procfs.c +++ b/device_info_procfs.c @@ -9,7 +9,7 @@ // @param off Requested offset. Updated by number of characters written. // @return -errno on error, otherwise number of bytes written to *buf // Note: Parent `data` field MUST be the GPU index -static ssize_t nvdebug_reg32_read(struct file *f, char __user *buf, size_t size, loff_t *off){ +static ssize_t nvdebug_reg32_read(struct file *f, char __user *buf, size_t size, loff_t *off) { char out[16]; int chars_written; struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; @@ -22,37 +22,42 @@ static ssize_t nvdebug_reg32_read(struct file *f, char __user *buf, size_t size, *off += chars_written; return chars_written; } -static ssize_t nvdebug_read4_pascal(struct file *f, char __user *buf, size_t size, loff_t *off){ - char out[16]; + +static ssize_t nvdebug_reg_range_read(struct file *f, char __user *buf, size_t size, loff_t *off) { + char out[12]; int chars_written; + uint32_t read, mask; struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; - void* data = PDE_DATA(file_inode(f)); - struct combo local_combo = *(struct combo*) &data; + // See comment in nvdebug_entry.c to understand `union reg_range` + union reg_range range; + range.raw = (uintptr_t)PDE_DATA(file_inode(f)); - // 32 bit register will always take less than 16 characters to print - if (size < 16 || *off != 0) + // "0x" + up to 32-bit register as hex + "\n\0" is at most 12 characters + if (size < 12 || *off != 0) return 0; - if (local_combo.index % 2 == 0) - chars_written = scnprintf(out, 16, "%#0x\n", (nvdebug_readl(g, local_combo.offset) & 0x0f)); - else - chars_written = scnprintf(out, 16, "%#0x\n", (nvdebug_readl(g, local_combo.offset) & 0xf0) >> 4); + + // Print bits `start_bit` to `stop_bit` from 32 bits at address `offset` + if ((read = nvdebug_readl(g, range.offset)) == -1) + return -EOPNOTSUPP; + // Setup `mask` used to throw out unused upper bits + mask = -1u >> (32 - range.stop_bit + range.start_bit); + // Throw out unused lower bits via a shift, apply the mask, and print + chars_written = scnprintf(out, 12, "%#0x\n", (read >> range.start_bit) & mask); if (copy_to_user(buf, out, chars_written)) printk(KERN_WARNING "Unable to copy all data for %s\n", file_dentry(f)->d_name.name); *off += chars_written; return chars_written; - -//(nvdebug_readl(g,NV_LCE_FOR_PCE_GP100(*(int*)PDE_DATA(file_inode(f)))) - - - } + struct file_operations nvdebug_read_reg32_file_ops = { .read = nvdebug_reg32_read, .llseek = default_llseek, }; -// File operation for reading 4 bits in 32 bit register (used for Pascal copy engine offsets) -struct file_operations nvdebug_read4_pascal_file_ops = { - .read = nvdebug_read4_pascal, + +// Generic mechanism used for printing a subset of bits from a register +// Please store a `union reg_range` rather than a `uintptr_t` in the PDE_DATA +struct file_operations nvdebug_read_reg_range_file_ops = { + .read = nvdebug_reg_range_read, .llseek = default_llseek, }; -- cgit v1.2.2