summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c99
1 files changed, 91 insertions, 8 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 5639030..ef192be 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -1021,6 +1021,14 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_GR_DATA_PD1_MAX 4u
#define GSP_PHYS_RMCALL_GR_DATA_PD0_MAX 8u
#define GSP_PHYS_RMCALL_GR_DATA_PT_MAX 64u
+/*
+ * m106: fixed pre-installed data window pool: GSP_PHYS_RMCALL_GR_DATA_WINS
+ * windows starting at GSP_PHYS_RMCALL_VA_GR_DATA_BASE, inside the
+ * server-managed region [0x100000000, 0x11fffffff). Window k maps at
+ * BASE + k<<21; the last window is reserved for the mail injection.
+ */
+#define GSP_PHYS_RMCALL_VA_GR_DATA_BASE 0x100000000ULL
+#define GSP_PHYS_RMCALL_GR_DATA_WINS 32u
/*
* Rank-2 qmdwin diagnostic (gsp_phys_rmcall_gr_qmdwin=1): dedicated module
@@ -7314,6 +7322,65 @@ static int gsp_phys_rmcall_map_pt_window(void __iomem *bar0)
0x100u * 8),
get_unaligned_le64((u8 *)gsp_phys_chunk_page_va(pt, 0) +
0x101u * 8));
+ /*
+ * m106: pre-install the fixed data PT pool before the channel commit
+ * (see gsp_phys_rmcall_gr_data_prewin). Each pool window's PT page is
+ * installed through the server walker here; the leaf PTEs are written
+ * at launch, so the first kernel-time walk sees freshly installed
+ * tables. This mirrors the ctx-window installs above, which the
+ * engine honours (post-commit installs are accepted but ineffective).
+ */
+ if (gsp_phys_rmcall_gr_data_prewin_value()) {
+ struct gsp_phys_rmcall_update_pde2_params dp;
+ unsigned int k;
+
+ for (k = 0; k < GSP_PHYS_RMCALL_GR_DATA_WINS; k++) {
+ struct gsp_phys_boot_chunk *dpt =
+ &boot_stage.rmcall_gr_data_pt[k];
+ u32 didx = (u32)((GSP_PHYS_RMCALL_VA_GR_DATA_BASE >>
+ 21) + k);
+
+ if (!dpt->pages) {
+ if (gsp_phys_chunk_alloc(boot_stage.pdev, dpt,
+ 1u))
+ return -ENOMEM;
+ gsp_phys_chunk_zero(dpt);
+ }
+ memset(&dp, 0, sizeof(dp));
+ dp.pde_index = cpu_to_le32(didx);
+ dp.flags = cpu_to_le32(GSP_PHYS_RMCALL_PDE2_FLAG_FLUSH);
+ dp.pt[0].phys_addr = cpu_to_le64((u64)
+ gsp_phys_chunk_page_dma(dpt, 0));
+ dp.pt[0].aperture =
+ cpu_to_le32(GSP_PHYS_RMCALL_PDE2_APERTURE_SYS_COH);
+ dp.pt[1].aperture =
+ cpu_to_le32(GSP_PHYS_RMCALL_PDE2_APERTURE_INVALID);
+ dp.h_va_space = cpu_to_le32(boot_stage.rmcall_vas);
+ rpc_result = 0;
+ status = 0;
+ ret = gsp_phys_rmcall_control(bar0,
+ boot_stage.rmcall_device,
+ GSP_PHYS_RMCALL_CTRL_DMA_UPDATE_PDE_2,
+ &dp, sizeof(dp), sizeof(dp), &dp,
+ sizeof(dp), &rpc_result, &status,
+ "DMA_UPDATE_PDE_2 (data pool)");
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: data pool window %u rejected: status=0x%x rpc_result=0x%x ret=%d; aborting with no retry\n",
+ didx, status, rpc_result, ret);
+ return ret;
+ }
+ /* the install may zero the PT page; leaves come later */
+ gsp_phys_chunk_zero(dpt);
+ }
+ pr_info("vgsp-boot: rm-call: data PT pool installed: %u windows at pdeIndex %u..%u (VA 0x%llx..0x%llx)\n",
+ GSP_PHYS_RMCALL_GR_DATA_WINS,
+ (u32)(GSP_PHYS_RMCALL_VA_GR_DATA_BASE >> 21),
+ (u32)((GSP_PHYS_RMCALL_VA_GR_DATA_BASE >> 21) +
+ GSP_PHYS_RMCALL_GR_DATA_WINS - 1),
+ GSP_PHYS_RMCALL_VA_GR_DATA_BASE,
+ GSP_PHYS_RMCALL_VA_GR_DATA_BASE +
+ ((u64)GSP_PHYS_RMCALL_GR_DATA_WINS - 1) * 0x200000ULL);
+ }
return 0;
}
@@ -16205,13 +16272,27 @@ static void gsp_phys_gr_rewrite_data_vars(u32 *w, u32 n_words,
static int gsp_phys_rmcall_gr_data_map(void __iomem *bar0, u64 va, u64 hpa,
u32 epoch)
{
- int ret = gsp_phys_rmcall_gr_map_va_locked(bar0, va, hpa, epoch);
+ struct gsp_phys_boot_chunk *pt;
+ u32 k, ip;
+ u64 pte;
- if (ret) {
- pr_err_ratelimited("vgsp-gr: data Tier-1 map refused va=0x%llx hpa=0x%llx ret=%d\n",
- va, hpa, ret);
- return ret;
- }
+ (void)bar0;
+ (void)epoch;
+ if (va < GSP_PHYS_RMCALL_VA_GR_DATA_BASE)
+ return -ERANGE;
+ k = (u32)((va - GSP_PHYS_RMCALL_VA_GR_DATA_BASE) >> 21);
+ if (k >= GSP_PHYS_RMCALL_GR_DATA_WINS)
+ return -ERANGE;
+ pt = &boot_stage.rmcall_gr_data_pt[k];
+ if (!pt->pages)
+ return -EIO;
+ ip = (u32)((va >> 12) & 0x1ffu);
+ pte = gsp_phys_rmcall_pte(hpa);
+ if (gsp_phys_rmcall_gr_pte_kind_value())
+ pte |= (u64)gsp_phys_rmcall_gr_pte_kind_value() << 56;
+ put_unaligned_le64(pte, (u8 *)gsp_phys_chunk_page_va(pt, 0) +
+ (size_t)ip * 8);
+ dma_wmb();
boot_stage.rmcall_gr_data_pages++;
return 0;
}
@@ -16554,7 +16635,9 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
if (!w[0] && !w[1]) {
static const char mail[] =
"the little gpu man says you've got mail";
- u64 mva = 0x11ff00000ULL;
+ u64 mva = GSP_PHYS_RMCALL_VA_GR_DATA_BASE +
+ ((u64)GSP_PHYS_RMCALL_GR_DATA_WINS - 1)
+ << 21;
if (!boot_stage.rmcall_gr_mail.pages &&
!gsp_phys_chunk_alloc(boot_stage.pdev,
@@ -16568,7 +16651,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
dma_wmb();
}
if (boot_stage.rmcall_gr_mail.pages &&
- !gsp_phys_rmcall_gr_map_va_locked(
+ !gsp_phys_rmcall_gr_data_map(
bar0, mva,
(u64)gsp_phys_chunk_page_dma(
&boot_stage.rmcall_gr_mail, 0),