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.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 7ba74ce..d43430b 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -16744,6 +16744,61 @@ static u32 *gsp_phys_rmcall_build_gr_init(u32 *p)
}
/*
+ * r597: extract the SEM_EXECUTE ACQUIRE groups from the captured guest
+ * prelude and copy them, verbatim, ahead of the rebuilt inline-QMD window.
+ * Two encodings are recognised:
+ * - C46F host-semaphore group: INC_METHOD addr 0x5c count>=5, words
+ * {LO, HI, PAYLOAD_LO, PAYLOAD_HI, EXECUTE}; EXECUTE & 7 != 1 is an
+ * acquire (the pump's own op decode).
+ * - C5C0 SET_REPORT_SEMAPHORE A..D: addr 0x1b00 count>=4, word D's low
+ * two bits select release (0) / acquire (non-zero).
+ * Only the wait methods are taken, so the proven window (init + inline QMD
+ * + PCAS + release) is untouched. Returns the number of words emitted.
+ */
+static u32 gsp_phys_rmcall_gr_emit_acquires(u32 *p,
+ const struct gsp_phys_gr_submit *req,
+ u32 budget)
+{
+ u32 off = 0, words = 0;
+
+ if (!gsp_phys_rmcall_gr_acq_value() || !req || !req->raw)
+ return 0;
+ while (off < req->raw_qmd_hdr && words + 8 < budget) {
+ u32 hdr = req->raw[off];
+ u32 op = (hdr >> 29) & 0x7;
+ u32 count = (hdr >> 16) & 0xfff;
+ u32 addr = (hdr & 0x1fff) << 2;
+ u32 n = 1 + count;
+
+ if ((op != 1 && op != 3) || !count ||
+ off + n > req->raw_qmd_hdr) {
+ off++;
+ continue;
+ }
+ if (addr == 0x5c && count >= 5) {
+ u32 v4 = req->raw[off + 5];
+ u64 va = ((u64)(req->raw[off + 2] & 0xff) << 32) |
+ (u64)(req->raw[off + 1] & 0xfffffffc);
+
+ if ((v4 & 0x7) != 1 && va) {
+ memcpy(p + words, &req->raw[off], n * 4);
+ words += n;
+ }
+ } else if (addr >= 0x1b00 && addr <= 0x1b0c &&
+ count >= 4) {
+ u32 d = req->raw[off + 4] & 0x3;
+
+ if (d != 0) {
+ memcpy(p + words, &req->raw[off], n * 4);
+ words += n;
+ }
+ }
+ off += n;
+ }
+ return words;
+}
+
+/*
* GR launch method block: the inline QMD run at its original shape and the
* channel REPORT_SEMAPHORE release. The stock guest push does NOT emit
* SET_OBJECT before the inline run (the compute class is bound on the
@@ -16776,6 +16831,25 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
GSP_PHYS_RMCALL_GR_SET_QMD_VIRT_CONTROL,
GSP_PHYS_RMCALL_GR_QMD_VIRT_IQ2M_SEND_PCAS);
/*
+ * r597: the prelude's acquire groups (if any) go before the QMD run
+ * so the engine cannot read the launch's data pages until the copy
+ * channel's semaphore has advanced.
+ */
+ {
+ u32 w = gsp_phys_rmcall_gr_emit_acquires(p, req,
+ 128u);
+ static u32 acq_log;
+
+ if (w) {
+ p += w;
+ if (acq_log < 16) {
+ acq_log++;
+ pr_info("vgsp-gr: prelude acquire groups emitted words=%u h=0x%x push=0x%llx\n",
+ w, req->h_object, req->push_va);
+ }
+ }
+ }
+ /*
* Verbatim replay: copy the captured GRCE prelude and the guest's
* own inline-QMD run, keeping the method headers, and relocate only
* the ADDRESS_A/B data words and the 64 QMD words exactly like the
@@ -20544,6 +20618,28 @@ gr_page_unmapped:
gsp_phys_rmcall_gr_qmdvirt_value(),
boot_stage.rmcall_token,
qmd_rel, want_ch, poll_ms, qmdwin_note);
+ {
+ /*
+ * r596 diag: the raw-prelude geometry the verbatim gate tests.
+ * The verbatim replay needs
+ * raw && raw_words >= hdr + 67 &&
+ * raw_qmd_end == hdr + 67 &&
+ * INIT_WORDS + hdr + 67 + TAIL_WORDS <= METHOD_WORDS
+ * Bounded to the first eight launches so the geometry is on
+ * record without flooding a battery run.
+ */
+ static u32 prelude_geom_log;
+
+ if (gsp_phys_rmcall_gr_prelude_value() && prelude_geom_log < 8) {
+ prelude_geom_log++;
+ pr_info("vgsp-gr: prelude geom raw=%u raw_words=%u hdr=%u end=%u want_end=%u v=%d\n",
+ req->raw ? 1u : 0u, req->raw_words,
+ req->raw_qmd_hdr, req->raw_qmd_end,
+ req->raw_qmd_hdr +
+ GSP_PHYS_RMCALL_GR_QMD_WINDOW_WORDS,
+ gsp_phys_rmcall_gr_prelude_value());
+ }
+ }
if (qmd_win_diag)
pr_info("vgsp-gr: qmd dest va=0x%llx pdeIndex=%u installed=%u win_mask=0x%llx ensure_ret=%d\n",
qmd_dst, qmd_win_pde, qmd_win_installed,