diff options
Diffstat (limited to 'device_info_procfs.c')
| -rw-r--r-- | device_info_procfs.c | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/device_info_procfs.c b/device_info_procfs.c index 4e4ab03..105e731 100644 --- a/device_info_procfs.c +++ b/device_info_procfs.c | |||
| @@ -18,7 +18,7 @@ static ssize_t nvdebug_reg32_read(struct file *f, char __user *buf, size_t size, | |||
| 18 | return 0; | 18 | return 0; |
| 19 | 19 | ||
| 20 | if ((read = nvdebug_readl(g, (uintptr_t)pde_data(file_inode(f)))) == -1) | 20 | if ((read = nvdebug_readl(g, (uintptr_t)pde_data(file_inode(f)))) == -1) |
| 21 | return -EOPNOTSUPP; | 21 | return -EIO; |
| 22 | // 32 bit register will always take less than 16 characters to print | 22 | // 32 bit register will always take less than 16 characters to print |
| 23 | chars_written = scnprintf(out, 16, "%#0x\n", read); | 23 | chars_written = scnprintf(out, 16, "%#0x\n", read); |
| 24 | if (copy_to_user(buf, out, chars_written)) | 24 | if (copy_to_user(buf, out, chars_written)) |
| @@ -32,12 +32,85 @@ struct file_operations nvdebug_read_reg32_file_ops = { | |||
| 32 | .llseek = default_llseek, | 32 | .llseek = default_llseek, |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | typedef union { | ||
| 36 | struct { | ||
| 37 | uint8_t partitioning_select:2; | ||
| 38 | uint8_t table_select:2; | ||
| 39 | uint32_t pad_1:12; | ||
| 40 | uint8_t veid_offset:6; | ||
| 41 | uint32_t pad_2:2; | ||
| 42 | uint8_t table_offset:6; | ||
| 43 | uint32_t pad_3:2; | ||
| 44 | }; | ||
| 45 | uint32_t raw; | ||
| 46 | } partition_ctl_t; | ||
| 47 | |||
| 48 | static ssize_t nvdebug_read_part(struct file *f, char __user *buf, size_t size, loff_t *off) { | ||
| 49 | char out[12*64+2]; | ||
| 50 | int i, chars_written = 0; | ||
| 51 | partition_ctl_t part_ctl; | ||
| 52 | struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; | ||
| 53 | if (size < 16 || *off != 0) | ||
| 54 | return 0; | ||
| 55 | // 32 bit register will always take less than 16 characters to print | ||
| 56 | part_ctl.raw = nvdebug_readl(g, 0x00405b2c); | ||
| 57 | //part_ctl.partitioning_select = 0; // XXX XXX XXX Temp; 06/18/2024 | ||
| 58 | //part_ctl.table_select = 3; // 3 == ??? | ||
| 59 | //part_ctl.table_select = 2; // 2 == TBL_SEL_PARTITIONING_LMEM_BLK | ||
| 60 | part_ctl.table_select = 1; // 1 == TBL_SEL_PARTITIONING_ENABLE | ||
| 61 | //part_ctl.table_select = 0; // 0 == TBL_SEL_NONE | ||
| 62 | part_ctl.veid_offset = (uintptr_t)pde_data(file_inode(f)); // Range of [0, 0x3f], aka [0, 63] | ||
| 63 | for (i = 0; i < 64; i++) { | ||
| 64 | // Increment to next table offset in PARTITION_CTL | ||
| 65 | part_ctl.table_offset = i; | ||
| 66 | nvdebug_writel(g, 0x00405b2c, part_ctl.raw); | ||
| 67 | // Verify write applied to PARTITION_CTL | ||
| 68 | part_ctl.raw = nvdebug_readl(g, 0x00405b2c); | ||
| 69 | if (part_ctl.table_offset != i) | ||
| 70 | return -ENOTRECOVERABLE; | ||
| 71 | // Read PARTITION_DATA and print | ||
| 72 | // --- | ||
| 73 | // I get back 0x000000ff on Volta and 0x00000003 on Turing from | ||
| 74 | // PARTITION_DATA for all possible VEID_OFFSET, TBL_OFFSET, and TBL_SEL | ||
| 75 | // combinations. | ||
| 76 | // --- | ||
| 77 | // There's a 48-byte (12-word) gap after the address for PARTITION_DATA. | ||
| 78 | // Exploring this on Turing for TBL_SEL_PARTITIONING_ENABLE, VEID 1, 62, and | ||
| 79 | // 63, with CUDA_MPS_ACTIVE_THREAD_PERCENTAGE=5 for constant_cycles_kernel | ||
| 80 | // running under MPS: | ||
| 81 | // +0x0: 0x3 | ||
| 82 | // +0x4: 0 | ||
| 83 | // +0x8: 0x100 | ||
| 84 | // +0xC: 0 | ||
| 85 | // +0x10: 0xffffffff | ||
| 86 | // +0x14: 0 | ||
| 87 | // +0x18: 0 | ||
| 88 | // +0x1C: 0xffffffff | ||
| 89 | // +0x20: 0 | ||
| 90 | // +0x24: 0xffffffff | ||
| 91 | // +0x28: 0xffffffff | ||
| 92 | // +0x2C: 0xffffffff | ||
| 93 | chars_written += scnprintf(out + chars_written, 12, "%#010x ", nvdebug_readl(g, 0x00405b30)); | ||
| 94 | } | ||
| 95 | chars_written += scnprintf(out + chars_written, 2, "\n"); | ||
| 96 | if (copy_to_user(buf, out, chars_written)) | ||
| 97 | printk(KERN_WARNING "Unable to copy all data for %s\n", file_dentry(f)->d_name.name); | ||
| 98 | *off += chars_written; | ||
| 99 | return chars_written; | ||
| 100 | } | ||
| 101 | |||
| 102 | struct file_operations nvdebug_read_part_file_ops = { | ||
| 103 | .read = nvdebug_read_part, | ||
| 104 | .llseek = default_llseek, | ||
| 105 | }; | ||
| 106 | |||
| 35 | static ssize_t nvdebug_reg_range_read(struct file *f, char __user *buf, size_t size, loff_t *off) { | 107 | static ssize_t nvdebug_reg_range_read(struct file *f, char __user *buf, size_t size, loff_t *off) { |
| 36 | char out[12]; | 108 | char out[12]; |
| 37 | int chars_written; | 109 | int chars_written; |
| 38 | uint32_t read, mask; | 110 | uint32_t read, mask; |
| 39 | struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; | 111 | struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)]; |
| 40 | // See comment in nvdebug_entry.c to understand `union reg_range` | 112 | // `start_bit` is included, `stop_bit` is not, so to print lower eight bits |
| 113 | // from a register, use `start_bit = 0` and `stop_bit = 8`. | ||
| 41 | union reg_range range; | 114 | union reg_range range; |
| 42 | range.raw = (uintptr_t)pde_data(file_inode(f)); | 115 | range.raw = (uintptr_t)pde_data(file_inode(f)); |
| 43 | 116 | ||
| @@ -47,7 +120,7 @@ static ssize_t nvdebug_reg_range_read(struct file *f, char __user *buf, size_t s | |||
| 47 | 120 | ||
| 48 | // Print bits `start_bit` to `stop_bit` from 32 bits at address `offset` | 121 | // Print bits `start_bit` to `stop_bit` from 32 bits at address `offset` |
| 49 | if ((read = nvdebug_readl(g, range.offset)) == -1) | 122 | if ((read = nvdebug_readl(g, range.offset)) == -1) |
| 50 | return -EOPNOTSUPP; | 123 | return -EIO; |
| 51 | // Setup `mask` used to throw out unused upper bits | 124 | // Setup `mask` used to throw out unused upper bits |
| 52 | mask = -1u >> (32 - range.stop_bit + range.start_bit); | 125 | mask = -1u >> (32 - range.stop_bit + range.start_bit); |
| 53 | // Throw out unused lower bits via a shift, apply the mask, and print | 126 | // Throw out unused lower bits via a shift, apply the mask, and print |
