summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c135
-rw-r--r--kernel/gsp_sema_service.c24
-rw-r--r--kernel/gsp_sema_service.h11
3 files changed, 170 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 40a8791..65ab874 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18461,6 +18461,91 @@ static int gsp_phys_gr_golden_slot(u32 j, u32 *entry, const u32 **words,
}
/*
+ * r1625 SEMANTIC-GAP (sema_gl_mme_sa_golden_fill): the golden overlay
+ * writes the golden bodies into the packed IR and fills its LOCAL SA pair
+ * table, but the per-launch SA re-arm (and the stub/call-drop walk)
+ * reads the service's live START-ADDRESS RAM table - the client's own
+ * 0x11c/0x120 capture. When that capture never supplied a slot (c772:
+ * slots 0..11 only, slot 34 absent), the re-arm emits no pair for it and
+ * the release window's CALL_MME_MACRO(34) keeps the engine's stale
+ * SA[34] (0 or another macro's entry): the DRAW_IAB CALL resolves to IR
+ * offset 0 / slot 0's body and the c772 replay ran mac=0x33/0x0/0x39,
+ * never mac=0x22. Fill every golden-served slot the client table cannot
+ * serve with the same instruction entry the overlay uses, so the re-arm
+ * points the CALL at the golden DRAW_IAB body (slot 34 -> 0x265).
+ * Default 0 = byte-identical legacy behaviour (A/B).
+ */
+static bool gsp_phys_rmcall_gr_mme_sa_golden_fill;
+module_param_named(sema_gl_mme_sa_golden_fill,
+ gsp_phys_rmcall_gr_mme_sa_golden_fill, bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_sa_golden_fill,
+ "Golden SA completion: publish a golden IR entry into the host START-ADDRESS RAM table for every golden-served slot the client capture left missing/zero, so the SA re-arm resolves CALL_MME_MACRO(j) to the golden body (default 0; A/B)");
+static u32 gsp_phys_gr_golden_fill_log;
+static u64 gsp_phys_gr_golden_fill_seen;
+static u32 gsp_phys_gr_golden_census_log;
+
+/*
+ * Fill the host SA table for all golden-served slots the client's capture
+ * cannot serve. Returns the number of entries filled this call; each slot
+ * is logged once per boot so a replayed window cannot spam the receipt.
+ */
+static u32 gsp_phys_gr_mme_sa_golden_fill(void)
+{
+ u32 j, filled = 0;
+
+ if (!READ_ONCE(gsp_phys_rmcall_gr_mme_sa_golden_fill))
+ return 0;
+ for (j = 0; j < 64u; j++) {
+ u32 gent, gn;
+ const u32 *gw;
+
+ if (!gsp_phys_gr_golden_slot(j, &gent, &gw, &gn))
+ continue;
+ if (!gsp_sema_mme_sa_fill(j, gent))
+ continue;
+ filled++;
+ if (!(gsp_phys_gr_golden_fill_seen & (1ull << j)) &&
+ gsp_phys_gr_golden_fill_log < 64u) {
+ gsp_phys_gr_golden_fill_seen |= 1ull << j;
+ gsp_phys_gr_golden_fill_log++;
+ pr_info("vgsp-gr: MME-GOLDEN sa-fill slot=%u entry=0x%x (client=missing)\n",
+ j, gent);
+ }
+ }
+ return filled;
+}
+
+/*
+ * r1625 receipt: for every slot the replayed window calls, print the
+ * client's captured entry, the golden entry and the entry the fill
+ * publishes (and the re-arm then emits). Called BEFORE the fill, so
+ * cli_mask / cli_ent are the client's own table; bounded per boot. A slot
+ * called through both the MACRO and DATA ports logs twice by design (the
+ * receipt is the raw walk, not a deduped view).
+ */
+static void gsp_phys_gr_mme_sa_census(u32 j, u64 cli_mask,
+ const u32 *cli_ent)
+{
+ u32 gent = 0, gn, used;
+ const u32 *gw;
+ bool have_cli;
+
+ if (!READ_ONCE(gsp_phys_rmcall_gr_mme_sa_golden_fill) ||
+ gsp_phys_gr_golden_census_log >= 64u || j >= 64u)
+ return;
+ have_cli = (cli_mask & (1ull << j)) && cli_ent[j];
+ if (gsp_phys_gr_golden_slot(j, &gent, &gw, &gn))
+ used = have_cli ? cli_ent[j] : gent;
+ else {
+ gent = 0;
+ used = have_cli ? cli_ent[j] : 0u;
+ }
+ gsp_phys_gr_golden_census_log++;
+ pr_info("vgsp-gr: MME-GOLDEN sa-census slot=%u client=0x%x golden=0x%x used=0x%x\n",
+ j, have_cli ? cli_ent[j] : 0u, gent, used);
+}
+
+/*
* r1448 STRATEGY 3.3 golden-only completion: with golden_force on and
* the golden_only knob on, a slot the golden library cannot serve must
* never execute. Returns true when the slot is outside the golden corpus
@@ -23432,6 +23517,15 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
u32 gj, goldn = 0, ginsp = 0;
u32 gblank = 0;
+ /*
+ * r1625: complete the host SA table
+ * from the same library before the
+ * pack emission, so the per-launch
+ * re-arm and the release window's
+ * CALL runs resolve to these bodies
+ * (sema_gl_mme_sa_golden_fill).
+ */
+ gsp_phys_gr_mme_sa_golden_fill();
for (gj = 0; gj < 64u; gj++) {
u32 gent, gn, q;
const u32 *gw;
@@ -24458,6 +24552,39 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
u64 sa_mask = gsp_sema_mme_sa_get(sa_ent, 64);
u32 r = 0, rearm = 0;
+ /*
+ * r1625 census: sa_ent/sa_mask are the client's own
+ * table here (pre-fill); the census prints the entry
+ * the fill publishes and the re-arm then emits.
+ */
+ while (r < win3d_n) {
+ u32 h = win3d[r];
+ u32 op = (h >> 29) & 7u;
+ u32 cnt = (h >> 16) & 0xfffu;
+ u32 span = ((op == 1u || op == 3u ||
+ op == 5u) && cnt &&
+ r + 1u + cnt <= win3d_n) ?
+ 1u + cnt : 1u;
+ u32 mb = (h & 0xfffu) << 2;
+
+ if (mb >= 0x3800u && mb <= 0x39fcu)
+ gsp_phys_gr_mme_sa_census(
+ (mb - 0x3800u) / 8u, sa_mask,
+ sa_ent);
+ r += span;
+ }
+ /*
+ * r1625: the saved-window release launch never emits
+ * the golden overlay (emit_prelude is off), and a
+ * client capture may have re-zeroed a slot after the
+ * overlay ran. Complete the host SA table here - the
+ * launch that actually runs the CALL runs - so the
+ * re-arm below points them at the golden bodies the
+ * pack holds (slot 34 -> DRAW_IAB at IR 0x265).
+ */
+ gsp_phys_gr_mme_sa_golden_fill();
+ sa_mask = gsp_sema_mme_sa_get(sa_ent, 64);
+ r = 0;
while (r < win3d_n && rearm < 32u) {
u32 h = win3d[r];
u32 op = (h >> 29) & 7u;
@@ -31715,6 +31842,14 @@ gr_page_unmapped:
win3d = stream_patch;
win3d_n = win_n;
/*
+ * r1625: publish the golden SA entries before the stub/drop
+ * walk reads the START-ADDRESS RAM table, so a golden-served
+ * slot the client capture never supplied (c772: slot 34) is
+ * present for both the drop decision here and the builder's
+ * per-launch re-arm. No-op with sema_gl_mme_sa_golden_fill=0.
+ */
+ gsp_phys_gr_mme_sa_golden_fill();
+ /*
* SESSION 153-CONTINUED-69: drop the CALL_MME_MACRO/DATA runs
* of stubbed slots (see gsp_phys_gr_mme_drop_calls). With the
* stub as a pure NOP terminator the parameter port no longer
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 26d3b1a..603e9f0 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -20364,6 +20364,30 @@ static void svc_mme_sa_record(u32 slot, u32 entry)
svc_mme_sa_present |= 1ull << slot;
}
+/*
+ * Golden SA completion (sema_gl_mme_sa_golden_fill): publish a slot's
+ * golden IR entry into the host-side START-ADDRESS RAM table when the
+ * client's own 0x11c/0x120 runs never supplied it (present bit clear, or
+ * present with entry 0 - the r1231 "SA[34]=0 lands last" shape). A
+ * nonzero client entry is never overwritten: the client's own upload is
+ * always the authority. The GR builder calls this before its per-launch
+ * SA re-arm and its stub/call-drop decisions, so a golden-served slot
+ * (e.g. DRAW_IAB slot 34 -> IR 0x265) resolves to the same IR offset the
+ * pack overlay wrote instead of jumping to macro 0.
+ */
+bool gsp_sema_mme_sa_fill(u32 slot, u32 entry)
+{
+ if (slot >= 64u)
+ return false;
+ if ((READ_ONCE(svc_mme_sa_present) & (1ull << slot)) &&
+ svc_mme_sa_entry[slot])
+ return false;
+ WRITE_ONCE(svc_mme_sa_entry[slot], entry);
+ WRITE_ONCE(svc_mme_sa_present,
+ READ_ONCE(svc_mme_sa_present) | (1ull << slot));
+ return true;
+}
+
static bool svc_mme_setup_run_addr(u32 addr)
{
return (addr >= 0x114u && addr <= 0x124u) || addr == 0x234u ||
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index ba1da96..5a1c491 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -630,6 +630,17 @@ bool gsp_sema_gr_surf_recs(u64 *va, u32 *n);
u64 gsp_sema_mme_sa_get(u32 *entries, u32 n);
/*
+ * Golden SA completion (sema_gl_mme_sa_golden_fill): set the host-side
+ * START-ADDRESS RAM entry for `slot` to `entry` and mark it present, but
+ * only when the client's own table has no usable entry for the slot
+ * (absent, or present with entry 0). Returns true when the entry was
+ * filled, false when a nonzero client entry was kept (or slot out of
+ * range). The GR builder uses it to point the held window's CALL runs at
+ * the golden bodies the pack overlay wrote.
+ */
+bool gsp_sema_mme_sa_fill(u32 slot, u32 entry);
+
+/*
* SESSION 153-CONTINUED-101: the client's own SET_MME_SHADOW_SCRATCH(0x18)
* write (method 0x3460) - mmeCodeOGL_C597_SETUP_FIXED_CONST (slot 0) reads
* shadow scratch 0x18/0xd18 via STATE and emits it as the fixed-function