summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 234932c..a3ee6f3 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -14738,6 +14738,88 @@ static void svc_mme_census(const u8 *buf, u32 len, u64 push_va, u32 h_object)
}
/*
+ * SESSION 153-CONTINUED-101: MME fixed-constant-buffer scratch watch.
+ *
+ * mmeCodeOGL_C597_SETUP_FIXED_CONST (macro slot 0) is the only reader of
+ * MME shadow scratch 0x18/0xd18 (MME_SCRATCH_FIXED_CONSTANT_BUFFER =
+ * 0x10 + RM_MME_FIRST_USABLE_SHADOW_SCRATCH); its compiled C597 form DOES
+ * NOT include the bug2548370 branch, so it unconditionally emits
+ * SET_CONSTANT_BUFFER_SELECTOR_B/C = cbAddr[31:24]/[23:0]<<8 from that
+ * scratch. The value is written once per channel/context by the client's
+ * own gf100InitConstantBuffers: method 0x3460 (SET_MME_SHADOW_SCRATCH
+ * (0x18)) <- (u32)(fixed constant buffer VA >> 8). The replayed ladder
+ * context never receives that once-per-channel write, so the macro reads
+ * 0 and emits an empty CB selector; the draw then fetches constants from
+ * address 0. This watch records the client's own write (any channel, any
+ * push that decodes) and publishes the first value so the GR launch
+ * builder can seed scratch 0x18 ahead of the window (sema_gl_mme_seed).
+ * Value is stored exactly as pushed (client VA >> 8). Read-only.
+ */
+static u32 svc_scratch18_val;
+static bool svc_scratch18_seen;
+static u32 svc_scratch18_log;
+
+bool gsp_sema_mme_scratch18_get(u32 *val)
+{
+ if (svc_scratch18_seen && val)
+ *val = READ_ONCE(svc_scratch18_val);
+ return svc_scratch18_seen;
+}
+
+static void svc_scratch18_watch(const u8 *buf, u32 len, u64 push_va,
+ u32 h_object)
+{
+ u32 off = 0;
+
+ if (svc_scratch18_seen && svc_scratch18_log >= 24u)
+ return;
+ while (off + 4u <= len) {
+ u32 hdr, op, cnt, addr;
+
+ memcpy(&hdr, buf + off, 4);
+ op = (hdr >> 29) & 7u;
+ cnt = (hdr >> 16) & 0xfffu;
+ addr = (hdr & 0xfffu) << 2;
+ if ((op == 1u || op == 3u || op == 5u) && cnt &&
+ off + 4u + cnt * 4u <= len) {
+ if (addr == 0x3460u) {
+ u32 val;
+
+ memcpy(&val, buf + off + 4, 4);
+ if (!svc_scratch18_seen) {
+ svc_scratch18_seen = true;
+ WRITE_ONCE(svc_scratch18_val, val);
+ }
+ if (svc_scratch18_log < 24u) {
+ svc_scratch18_log++;
+ pr_info("sema-scratch18: h=0x%x va=0x%llx off=0x%x op=%u cnt=%u val=0x%08x (SET_MME_SHADOW_SCRATCH(0x18); fixed-CB base>>8)\n",
+ h_object, push_va, off, op, cnt,
+ val);
+ }
+ off += 4u + cnt * 4u;
+ continue;
+ }
+ off += 4u + cnt * 4u;
+ continue;
+ }
+ if (op == 4u && addr == 0x3460u) {
+ u32 val = (hdr >> 16) & 0x1fffu;
+
+ if (!svc_scratch18_seen) {
+ svc_scratch18_seen = true;
+ WRITE_ONCE(svc_scratch18_val, val);
+ }
+ if (svc_scratch18_log < 24u) {
+ svc_scratch18_log++;
+ pr_info("sema-scratch18: h=0x%x va=0x%llx off=0x%x op=4 immd val=0x%08x (SET_MME_SHADOW_SCRATCH(0x18))\n",
+ h_object, push_va, off, val);
+ }
+ }
+ off += 4u;
+ }
+}
+
+/*
* SESSION 153-CONTINUED-94: client init-push capture + local-memory census.
*
* CONT-93's "single most concrete next fix" was that the GL driver's
@@ -16241,6 +16323,10 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
if (ch)
svc_mme_census(buf, len, push_va, ch->h_object);
+ /* SESSION 153-CONTINUED-101: fixed-CB scratch (0x3460) watch, any channel. */
+ if (ch)
+ svc_scratch18_watch(buf, len, push_va, ch->h_object);
+
/* SESSION 153-CONTINUED-94: init-push capture + local-memory census. */
if (ch)
svc_init_push_scan(buf, len, push_va, ch->h_object);