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 | } |
