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.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 8bf94d8..de546d4 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -14412,6 +14412,121 @@ static int gsp_phys_rmcall_gr_sem_push_locked(void __iomem *bar0)
}
/*
+ * m84 diagnostic (gsp_phys_rmcall_gr_img_probe; default 0). Reads the first
+ * 4 KB of the GR MAIN context image (promoted at VA_GR_CTX, FBMEM) and of the
+ * per-VEID subcontext header (image + 0xf3000) through the real COPY engine.
+ * The rmcall channel is GR-bound in this mode, so the probe re-binds it to
+ * COPY0, submits one CE copy block per region into the DST sysmem chunk,
+ * polls the module semaphore, re-binds GR0 and dumps the image header
+ * pointers. Any rejection or timeout is logged and changes nothing else;
+ * the forwarded launch path then runs as usual. Must be called from stage 4
+ * (gsp_phys_rm_lock held).
+ */
+static void gsp_phys_rmcall_ctx_image_probe(void __iomem *bar0)
+{
+ struct gsp_phys_boot_chunk *sem =
+ &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_SEM];
+ struct gsp_phys_boot_chunk *dst =
+ &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_DST];
+ struct gsp_phys_rmcall_ce_submit sub;
+ u64 regions[2];
+ u32 bind_params;
+ int r;
+
+ if (!boot_stage.rmcall_ctx_pa || boot_stage.rmcall_stage < 3)
+ return;
+
+ bind_params = GSP_PHYS_RMCALL_ENGINE_COPY0;
+ {
+ u32 rpc_result = 0, status = 0;
+
+ r = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_channel,
+ GSP_PHYS_RMCALL_CTRL_BIND_CHANNEL,
+ &bind_params, sizeof(bind_params), 16, NULL, 0,
+ &rpc_result, &status,
+ "BIND_CHANNEL COPY0 (m84 image probe)");
+ pr_info("vgsp-boot: rm-call: m84 image probe: BIND COPY0 status=0x%x rpc_result=0x%x ret=%d\n",
+ status, rpc_result, r);
+ }
+
+ regions[0] = GSP_PHYS_RMCALL_VA_GR_CTX; /* image header */
+ regions[1] = GSP_PHYS_RMCALL_VA_GR_CTX + 0xf3000ULL; /* subctx hdr VEID0 */
+ if (!r) {
+ u32 k;
+
+ for (k = 0; k < 2; k++) {
+ u32 rpc_result = 0, status = 0, poll = 0;
+ unsigned long deadline;
+ u8 *d;
+
+ WRITE_ONCE(*(u32 *)gsp_phys_chunk_page_va(sem, 0), 0);
+ wmb();
+ r = gsp_phys_rmcall_ce_submit_locked(bar0,
+ regions[k], GSP_PHYS_RMCALL_VA_DST,
+ GSP_PHYS_RMCALL_VA_SEM,
+ GSP_PHYS_PAGE_SIZE,
+ GSP_PHYS_RMCALL_SEM_PAYLOAD, false,
+ &sub);
+ (void)rpc_result;
+ (void)status;
+ if (r) {
+ pr_err("vgsp-boot: rm-call: m84 image probe: CE submit for region %u refused (%d)\n",
+ k, r);
+ break;
+ }
+ deadline = jiffies +
+ msecs_to_jiffies(GSP_PHYS_RMCALL_TIMEOUT_MS);
+ for (;;) {
+ poll = READ_ONCE(*(u32 *)gsp_phys_chunk_page_va(sem, 0));
+ if (poll == GSP_PHYS_RMCALL_SEM_PAYLOAD)
+ break;
+ if (time_after_eq(jiffies, deadline)) {
+ pr_err("vgsp-boot: rm-call: m84 image probe: region %u CE copy TIMEOUT (sem=0x%08x) - an engine-side walk of VA 0x%llx failed or the CE did not run\n",
+ k, poll, regions[k]);
+ break;
+ }
+ msleep(GSP_PHYS_RMCALL_POLL_MS);
+ }
+ if (poll != GSP_PHYS_RMCALL_SEM_PAYLOAD)
+ break;
+ d = gsp_phys_chunk_page_va(dst, 0);
+ if (!d)
+ break;
+ pr_info("vgsp-boot: rm-call: m84 image probe: region %u VA=0x%llx copied OK\n",
+ k, regions[k]);
+ {
+ u32 i;
+
+ for (i = 0; i < 0x80; i += 8)
+ pr_info("vgsp-ctximg[%u] [%03x] = %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ k, i * 4,
+ get_unaligned_le32(d + i * 4),
+ get_unaligned_le32(d + (i + 1) * 4),
+ get_unaligned_le32(d + (i + 2) * 4),
+ get_unaligned_le32(d + (i + 3) * 4),
+ get_unaligned_le32(d + (i + 4) * 4),
+ get_unaligned_le32(d + (i + 5) * 4),
+ get_unaligned_le32(d + (i + 6) * 4),
+ get_unaligned_le32(d + (i + 7) * 4));
+ }
+ }
+ }
+
+ bind_params = GSP_PHYS_RMCALL_ENGINE_GR0;
+ {
+ u32 rpc_result = 0, status = 0;
+
+ r = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_channel,
+ GSP_PHYS_RMCALL_CTRL_BIND_CHANNEL,
+ &bind_params, sizeof(bind_params), 16, NULL, 0,
+ &rpc_result, &status,
+ "BIND_CHANNEL GR0 (m84 image probe)");
+ pr_info("vgsp-boot: rm-call: m84 image probe: rebind GR0 status=0x%x rpc_result=0x%x ret=%d\n",
+ status, rpc_result, r);
+ }
+}
+
+/*
* P6a guest-memory CE helper: run one CE copy with explicit operand VAs on
* the ladder channel and poll the module semaphore outside gsp_phys_rm_lock
* (the same lock discipline as the P5 shadow API, so a guest copy can never
@@ -17182,6 +17297,8 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0)
if (ret)
pr_err("vgsp-boot: rm-call: stage 4 GR path failed (%d); no retry\n",
ret);
+ else if (gsp_phys_rmcall_gr_img_probe_value())
+ gsp_phys_rmcall_ctx_image_probe(bar0);
return ret;
}