diff options
Diffstat (limited to 'bus.c')
-rw-r--r-- | bus.c | 50 |
1 files changed, 13 insertions, 37 deletions
@@ -57,35 +57,25 @@ relocate: | |||
57 | window.base = (u32)(addr >> 16); // Safe, due to above range check | 57 | window.base = (u32)(addr >> 16); // Safe, due to above range check |
58 | window.target = target; | 58 | window.target = target; |
59 | nvdebug_writel(g, NV_PBUS_BAR0_WINDOW, window.raw); | 59 | nvdebug_writel(g, NV_PBUS_BAR0_WINDOW, window.raw); |
60 | // Wait for the window to move by re-reading (as done in nvgpu driver) | ||
61 | (void) nvdebug_readl(g, NV_PBUS_BAR0_WINDOW); | ||
60 | return (int)(addr & 0xffffull); | 62 | return (int)(addr & 0xffffull); |
61 | } | 63 | } |
62 | 64 | ||
63 | 65 | /* Get a copy of the BAR2 page directory configuration (base and aperture) | |
64 | /* Get a persistent pointer to the page directory base | 66 | @param pd Pointer at which to store the configuration, including a pointer |
65 | @param pdb Dereferencable pointer to the zeroeth entry of top-level page | 67 | and aperture for the zeroth entry of the top-level page directory |
66 | directory (PD3) for the BAR2 register region. | 68 | (PD3 for V2 page tables). This pointer **may not** be directly |
67 | Note: The returned pointer will be into the PRAMIN space. If the PRAMIN | 69 | dereferencable, and the caller may need to shift the BAR2 window. |
68 | window is moved to a region that does not cover the BAR2 page table, | 70 | @return 0 on success, -errno on error. |
69 | this ***will move the window***. | 71 | Note: This may move the PRAMIN window. |
70 | Note: Even if the page table is located in SYS_MEM, we route reads/writes via | ||
71 | PRAMIN. This ensures that we always see what the GPU sees, and that | ||
72 | includes any passes through I/O MMUs or IOVA spaces. | ||
73 | */ | 72 | */ |
74 | int get_bar2_pdb(struct nvdebug_state *g, void **pdb, bool *is_v2_pdb) { | 73 | int get_bar2_pdb(struct nvdebug_state *g, page_dir_config_t* pd) { |
75 | static void* cached_pdb = NULL; | ||
76 | static bool cached_is_v2_pdb = false; | ||
77 | static long pd_hash = 0; | ||
78 | int ret; | 74 | int ret; |
79 | bar_config_block_t bar2_block; | 75 | bar_config_block_t bar2_block; |
80 | page_dir_config_t pd_config; | ||
81 | uint64_t pdb_vram; | ||
82 | 76 | ||
83 | // Use cached base as long as it's still pointing to the same thing | 77 | if (!pd) |
84 | if (cached_pdb && readl(cached_pdb) == pd_hash) { | 78 | return -EINVAL; |
85 | *pdb = cached_pdb; | ||
86 | *is_v2_pdb = cached_is_v2_pdb; | ||
87 | return 0; | ||
88 | } | ||
89 | 79 | ||
90 | if (!g->bar2) | 80 | if (!g->bar2) |
91 | return -ENXIO; | 81 | return -ENXIO; |
@@ -107,24 +97,10 @@ int get_bar2_pdb(struct nvdebug_state *g, void **pdb, bool *is_v2_pdb) { | |||
107 | } | 97 | } |
108 | printk(KERN_INFO "[nvdebug] BAR2 inst block at off %x in PRAMIN\n", ret); | 98 | printk(KERN_INFO "[nvdebug] BAR2 inst block at off %x in PRAMIN\n", ret); |
109 | // Pull the page directory base configuration from the instance block | 99 | // Pull the page directory base configuration from the instance block |
110 | if ((pd_config.raw = nvdebug_readq(g, NV_PRAMIN + ret + NV_PRAMIN_PDB_CONFIG_OFF)) == -1) { | 100 | if ((pd->raw = nvdebug_readq(g, NV_PRAMIN + ret + NV_PRAMIN_PDB_CONFIG_OFF)) == -1) { |
111 | printk(KERN_ERR "[nvdebug] Unable to read BAR2/3 PDB configuration! BAR2/3 inaccessible.\n"); | 101 | printk(KERN_ERR "[nvdebug] Unable to read BAR2/3 PDB configuration! BAR2/3 inaccessible.\n"); |
112 | return -ENOTSUPP; | 102 | return -ENOTSUPP; |
113 | } | 103 | } |
114 | pdb_vram = pd_config.page_dir_hi; | ||
115 | pdb_vram <<= 20; | ||
116 | pdb_vram |= pd_config.page_dir_lo; | ||
117 | pdb_vram <<= 12; | ||
118 | printk(KERN_INFO "[nvdebug] BAR2 PDB @ %llx (config raw: %llx)\n", pdb_vram, pd_config.raw); | ||
119 | // Setup PRAMIN to point at the page directory | ||
120 | if ((ret = addr_to_pramin_mut(g, pdb_vram, pd_config.target)) < 0) { | ||
121 | printk(KERN_ERR "[nvdebug] Invalid BAR2/3 PDB configuration! BAR2/3 inaccessible.\n"); | ||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | *pdb = cached_pdb = g->regs + NV_PRAMIN + ret; | ||
126 | pd_hash = readl(cached_pdb); | ||
127 | *is_v2_pdb = cached_is_v2_pdb = pd_config.is_ver2; | ||
128 | 104 | ||
129 | return 0; | 105 | return 0; |
130 | } | 106 | } |