diff options
Diffstat (limited to 'device_info_procfs.c')
-rw-r--r-- | device_info_procfs.c | 43 |
1 files changed, 24 insertions, 19 deletions
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 @@ | |||
9 | // @param off Requested offset. Updated by number of characters written. | 9 | // @param off Requested offset. Updated by number of characters written. |
10 | // @return -errno on error, otherwise number of bytes written to *buf | 10 | // @return -errno on error, otherwise number of bytes written to *buf |
11 | // Note: Parent `data` field MUST be the GPU index | 11 | // Note: Parent `data` field MUST be the GPU index |
12 | static ssize_t nvdebug_reg32_read(struct file *f, char __user *buf, size_t size, loff_t *off){ | 12 | static ssize_t nvdebug_reg32_read(struct file *f, char __user *buf, size_t size, loff_t *off) { |
13 | char out[16]; | 13 | char out[16]; |
14 | int chars_written; | 14 | int chars_written; |
15 | struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; | 15 | 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, | |||
22 | *off += chars_written; | 22 | *off += chars_written; |
23 | return chars_written; | 23 | return chars_written; |
24 | } | 24 | } |
25 | static ssize_t nvdebug_read4_pascal(struct file *f, char __user *buf, size_t size, loff_t *off){ | 25 | |
26 | char out[16]; | 26 | static ssize_t nvdebug_reg_range_read(struct file *f, char __user *buf, size_t size, loff_t *off) { |
27 | char out[12]; | ||
27 | int chars_written; | 28 | int chars_written; |
29 | uint32_t read, mask; | ||
28 | struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; | 30 | struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; |
29 | void* data = PDE_DATA(file_inode(f)); | 31 | // See comment in nvdebug_entry.c to understand `union reg_range` |
30 | struct combo local_combo = *(struct combo*) &data; | 32 | union reg_range range; |
33 | range.raw = (uintptr_t)PDE_DATA(file_inode(f)); | ||
31 | 34 | ||
32 | // 32 bit register will always take less than 16 characters to print | 35 | // "0x" + up to 32-bit register as hex + "\n\0" is at most 12 characters |
33 | if (size < 16 || *off != 0) | 36 | if (size < 12 || *off != 0) |
34 | return 0; | 37 | return 0; |
35 | if (local_combo.index % 2 == 0) | 38 | |
36 | chars_written = scnprintf(out, 16, "%#0x\n", (nvdebug_readl(g, local_combo.offset) & 0x0f)); | 39 | // Print bits `start_bit` to `stop_bit` from 32 bits at address `offset` |
37 | else | 40 | if ((read = nvdebug_readl(g, range.offset)) == -1) |
38 | chars_written = scnprintf(out, 16, "%#0x\n", (nvdebug_readl(g, local_combo.offset) & 0xf0) >> 4); | 41 | return -EOPNOTSUPP; |
42 | // Setup `mask` used to throw out unused upper bits | ||
43 | mask = -1u >> (32 - range.stop_bit + range.start_bit); | ||
44 | // Throw out unused lower bits via a shift, apply the mask, and print | ||
45 | chars_written = scnprintf(out, 12, "%#0x\n", (read >> range.start_bit) & mask); | ||
39 | if (copy_to_user(buf, out, chars_written)) | 46 | if (copy_to_user(buf, out, chars_written)) |
40 | printk(KERN_WARNING "Unable to copy all data for %s\n", file_dentry(f)->d_name.name); | 47 | printk(KERN_WARNING "Unable to copy all data for %s\n", file_dentry(f)->d_name.name); |
41 | *off += chars_written; | 48 | *off += chars_written; |
42 | return chars_written; | 49 | return chars_written; |
43 | |||
44 | //(nvdebug_readl(g,NV_LCE_FOR_PCE_GP100(*(int*)PDE_DATA(file_inode(f)))) | ||
45 | |||
46 | |||
47 | |||
48 | } | 50 | } |
51 | |||
49 | struct file_operations nvdebug_read_reg32_file_ops = { | 52 | struct file_operations nvdebug_read_reg32_file_ops = { |
50 | .read = nvdebug_reg32_read, | 53 | .read = nvdebug_reg32_read, |
51 | .llseek = default_llseek, | 54 | .llseek = default_llseek, |
52 | }; | 55 | }; |
53 | // File operation for reading 4 bits in 32 bit register (used for Pascal copy engine offsets) | 56 | |
54 | struct file_operations nvdebug_read4_pascal_file_ops = { | 57 | // Generic mechanism used for printing a subset of bits from a register |
55 | .read = nvdebug_read4_pascal, | 58 | // Please store a `union reg_range` rather than a `uintptr_t` in the PDE_DATA |
59 | struct file_operations nvdebug_read_reg_range_file_ops = { | ||
60 | .read = nvdebug_reg_range_read, | ||
56 | .llseek = default_llseek, | 61 | .llseek = default_llseek, |
57 | }; | 62 | }; |
58 | 63 | ||