aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--device_info_procfs.c24
-rw-r--r--nvdebug.h27
-rw-r--r--nvdebug_entry.c8
3 files changed, 59 insertions, 0 deletions
diff --git a/device_info_procfs.c b/device_info_procfs.c
index 8fe9709..c8903fc 100644
--- a/device_info_procfs.c
+++ b/device_info_procfs.c
@@ -61,6 +61,30 @@ struct file_operations nvdebug_read_reg_range_file_ops = {
61 .llseek = default_llseek, 61 .llseek = default_llseek,
62}; 62};
63 63
64static ssize_t local_memory_read(struct file *f, char __user *buf, size_t size, loff_t *off) {
65 struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)];
66 char out[30];
67 int chars_written;
68 memory_range_t mem_range;
69 if (size < 30 || *off != 0)
70 return 0;
71 mem_range.raw = nvdebug_readl(g, NV_FB_MMU_LOCAL_MEMORY_RANGE);
72 if (mem_range.raw == -1)
73 return -EIO;
74 // 64-bit size has at most 19 characters + 8 for text and termination
75 chars_written = scnprintf(out, 30, "%lld bytes\n", memory_range_to_bytes(mem_range));
76 if (copy_to_user(buf, out, chars_written))
77 printk(KERN_WARNING "Unable to copy all data for %s\n", file_dentry(f)->d_name.name);
78 *off += chars_written;
79 return chars_written;
80}
81
82// Read out size of on-device VRAM
83struct file_operations local_memory_file_ops = {
84 .read = local_memory_read,
85 .llseek = default_llseek,
86};
87
64typedef struct { 88typedef struct {
65 int idx; // Current index in the device_info table 89 int idx; // Current index in the device_info table
66 int length; // Length of device_info table (including unpopulated entries) 90 int length; // Length of device_info table (including unpopulated entries)
diff --git a/nvdebug.h b/nvdebug.h
index ff35f70..b13d311 100644
--- a/nvdebug.h
+++ b/nvdebug.h
@@ -1145,7 +1145,34 @@ typedef union {
1145} page_tbl_entry_v0_t; 1145} page_tbl_entry_v0_t;
1146*/ 1146*/
1147 1147
1148/* VRAM Information
1148 1149
1150 If ECC is disabled:
1151 bytes = (magnitude << scale) * 1024 * 1024
1152 If ECC is enabled:
1153 bytes = ((magnitude << scale) * 1024 * 1024) / 16 * 15
1154
1155 Support: Pascal, Volta, Turing, [more?]
1156 */
1157#define NV_FB_MMU_LOCAL_MEMORY_RANGE 0x00100ce0
1158typedef union {
1159 struct {
1160 uint32_t scale:4;
1161 uint32_t mag:6;
1162 uint32_t:20;
1163 bool is_ecc:1;
1164 uint32_t:1;
1165 } __attribute__((packed));
1166 uint32_t raw;
1167} memory_range_t;
1168
1169static inline uint64_t memory_range_to_bytes(memory_range_t range) {
1170 // ECC takes a byte out of available memory for parity data
1171 if (range.is_ecc)
1172 return ((range.mag << range.scale) * 1024ull * 1024ull) / 16 * 15;
1173 else
1174 return (range.mag << range.scale) * 1024ull * 1024ull;
1175}
1149 1176
1150/* Begin nvdebug types and functions */ 1177/* Begin nvdebug types and functions */
1151 1178
diff --git a/nvdebug_entry.c b/nvdebug_entry.c
index 0caa289..f3dcdbb 100644
--- a/nvdebug_entry.c
+++ b/nvdebug_entry.c
@@ -31,6 +31,7 @@ extern struct file_operations device_info_file_ops;
31extern struct file_operations copy_topology_file_ops; 31extern struct file_operations copy_topology_file_ops;
32extern struct file_operations nvdebug_read_reg32_file_ops; 32extern struct file_operations nvdebug_read_reg32_file_ops;
33extern struct file_operations nvdebug_read_reg_range_file_ops; 33extern struct file_operations nvdebug_read_reg_range_file_ops;
34extern struct file_operations local_memory_file_ops;
34 35
35struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES]; 36struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES];
36unsigned int g_nvdebug_devices = 0; 37unsigned int g_nvdebug_devices = 0;
@@ -303,6 +304,13 @@ int __init nvdebug_init(void) {
303 (void*)NV_FUSE_GPC_GM107)) 304 (void*)NV_FUSE_GPC_GM107))
304 goto out_nomem; 305 goto out_nomem;
305 } 306 }
307 // Create file `/proc/gpu#/local_memory`, world readable (Pascal+)
308 if (g_nvdebug_state[res].chip_id >= NV_CHIP_ID_PASCAL) {
309 if (!proc_create_data(
310 "local_memory", 0444, dir, compat_ops(&local_memory_file_ops),
311 (void*)0x00100ce0))
312 goto out_nomem;
313 }
306 // Create files exposing LCE and PCE configuration (Pascal+) 314 // Create files exposing LCE and PCE configuration (Pascal+)
307 if (g_nvdebug_state[res].chip_id >= NV_CHIP_ID_PASCAL) { 315 if (g_nvdebug_state[res].chip_id >= NV_CHIP_ID_PASCAL) {
308 // Create file `/proc/gpu#/copy_topology`, world readable 316 // Create file `/proc/gpu#/copy_topology`, world readable