summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-06 15:19:49 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-06 15:19:49 -0500
commitc822fa346e2feb1b9f57160beeffc6f69ab0c923 (patch)
tree24c179ffc76b02bd25b15753fbf8033fa1718179
parent5fad0adb166138b4096494b186e9405902ab9ab6 (diff)
downloadopen-iov-c822fa346e2feb1b9f57160beeffc6f69ab0c923.tar.gz
open-iov-c822fa346e2feb1b9f57160beeffc6f69ab0c923.zip
vgsp-gl: engine-visible MME selector seed + RT0 third-dimension seed
sema_gl_mme_selector_seed (default 0) emits engine-visible 0x2380/0x2384/ 0x2388/0x238c (fixed-CB selector base>>8, d29) before the draw window; the old state seed only wrote MME shadow scratch, so with the selector programmer elided LOAD_CONSTANT_BUFFER (0x2390 <- 0xbf800000) failed with EC 0x03. r1545: 27 beef launches, 0 errors at 0x2390. sema_gl_rt0_third_dim (default 0) writes RT0 0x818 THIRD_DIMENSION=1 so the layered-RT validation matches the driver's layer-mode ONE; r1548: the 0x17e0/EC 0xd2 illegal color-target layer-vs-third-dimension error is gone and the DS reached validation with stage5 bound (0x19a0000). Both default-off; legacy bytes unchanged. Evidence: Handoff cont 5/6.
-rw-r--r--kernel/gsp_phys_booter.c158
1 files changed, 146 insertions, 12 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 40afca1..17925b6 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -19482,7 +19482,35 @@ MODULE_PARM_DESC(sema_mme_state_d24, "Seed value for STATE 0xD24 slow-path input
static u32 gsp_phys_rmcall_gr_mme_state_d25;
module_param_named(sema_mme_state_d25, gsp_phys_rmcall_gr_mme_state_d25,
uint, 0644);
-MODULE_PARM_DESC(sema_mme_state_d25, "Seed value for STATE 0xD25 slow-path input (method 0x3494); 0 = use the client's captured 0x3494 write");
+MODULE_PARM_DESC(sema_mme_state_d25, "Seed value for STATE 0xD25 BUG2548370_CONSTANT_BUFFER_SELECTOR_A / CB size (method 0x3494); 0 = use the client's captured 0x3494 write");
+
+/*
+ * SESSION 155-CONT-5: engine-visible constant-buffer selector seed.
+ *
+ * The STATE seed above only writes MME *shadow scratch* (0x3460/0x3464/
+ * 0x3498..0x34a8). The bug2548370 loadConstantBuffer macro (slot 57)
+ * only *reads* that scratch to track page changes; it never emits
+ * SET_CONSTANT_BUFFER_SELECTOR_A/B/C itself. The selector is programmed
+ * by SETUP_FIXED_CONST (slot 0) from scratch 0x18. When a replayed
+ * window carries a CALL macro 57 run but no CALL macro 0 (the driver
+ * legitimately elides it while the selector is already bound, e.g. the
+ * r1541 68-word tail), the engine executes LOAD_CONSTANT_BUFFER with no
+ * valid selector and the C597 class raises
+ * "Offset 00002390, Data bf800000, ErrorCode 00000003" (the r1456/
+ * r1485/r1541 poison). With this knob the builder emits the same
+ * 4-method group macro 0 would emit - SET_CONSTANT_BUFFER_SELECTOR_A
+ * (size = MME_VPC_CONSTANT_BUFFER_SIZE 0x7000), B/C (the fixed-CB
+ * base>>8, translated through the launch's page set exactly like the
+ * scratch seed) and LOAD_CONSTANT_BUFFER_OFFSET (sema_mme_state_d29) -
+ * ahead of every replayed 3D window. Idempotent when macro 0 is also in
+ * the stream (it re-programs the same selector). Default off; requires
+ * sema_gl_mme_state_seed; legacy bytes unchanged when off.
+ */
+static bool gsp_phys_rmcall_gr_mme_selector_seed;
+module_param_named(sema_gl_mme_selector_seed,
+ gsp_phys_rmcall_gr_mme_selector_seed, bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_selector_seed,
+ "Emit SET_CONSTANT_BUFFER_SELECTOR_A/B/C + LOAD_CONSTANT_BUFFER_OFFSET (0x2380..0x238c) from the fixed-CB scratch ahead of replayed 3D windows (default 0; requires sema_gl_mme_state_seed)");
/*
* SESSION 153-CONTINUED-105: split the packed MME prelude emission across
@@ -19770,6 +19798,38 @@ static const u32 gsp_phys_gr_rt0_bind[GSP_PHYS_GR_RT0_BIND_WORDS] = {
0x000000e6u, 0x00000040u, 0x20010487u, 0x0fac6882u,
};
+/*
+ * SESSION 155-CONT-6: the synthesized RT0 bind above writes
+ * SET_COLOR_TARGET_A..MEMORY (0x800..0x814) but not
+ * SET_COLOR_TARGET_THIRD_DIMENSION (0x818). The client's own full
+ * colour-target group is the 8-method form (gf100pushbuf.c / the
+ * gf100commandList.c 6-word push from WIDTH through ARRAY_PITCH, which
+ * includes THIRD_DIMENSION and ARRAY_PITCH); those load-only windows are
+ * not replayed, so the channel's 0x818 stays 0 while 0x814 carries
+ * THIRD_DIMENSION_CONTROL = DEFINES_ARRAY_SIZE. On the first native
+ * DRAW_INDEX_BUFFER (0x17e0) the C597 class then reports
+ * "ErrorCode 000000d2" =
+ * NV_PGRAPH_CLASS_ERROR_CODE_ERROR_ILLEGAL_COLOR_TARGET0_LAYER_OFFSET_VS_THIRD_DIMENSION
+ * (tu104/dev_graphics_nobundle.h:563): layer offset 0 is not below the
+ * array size 0. The driver's layer-mode ONE path writes depth 1 with
+ * ARRAY_SIZE control (gf100commandList.c:1232-1235), so widen the
+ * inserted group to the 8-method form with THIRD_DIMENSION(0)=1 and
+ * ARRAY_PITCH(0)=0. Default off; legacy bytes and count unchanged.
+ */
+#define GSP_PHYS_GR_RT0_BIND_EXT_WORDS 11u
+static const u32 gsp_phys_gr_rt0_bind_ext[GSP_PHYS_GR_RT0_BIND_EXT_WORDS] = {
+ 0x20080200u, 0x00000000u, 0x0a000000u, 0x00000500u, 0x000002d0u,
+ 0x000000e6u, 0x00000040u, 0x00000001u, 0x00000000u,
+ 0x20010487u, 0x0fac6882u,
+};
+
+static bool gsp_phys_rmcall_gr_rt0_third_dim;
+module_param_named(sema_gl_rt0_third_dim,
+ gsp_phys_rmcall_gr_rt0_third_dim, bool, 0644);
+MODULE_PARM_DESC(sema_gl_rt0_third_dim,
+ "Extend the synthesized RT0 bind with SET_COLOR_TARGET_THIRD_DIMENSION(0)=1 and ARRAY_PITCH(0)=0 (0x818/0x81c) so DRAW_INDEX_BUFFER does not raise class error 0xd2 (default 0)");
+
+
static int gsp_phys_rmcall_gr_rt0_bind;
module_param_named(sema_gl_rt0_bind, gsp_phys_rmcall_gr_rt0_bind, int,
0644);
@@ -21480,6 +21540,68 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
}
}
/*
+ * SESSION 155-CONT-5: engine-visible CB selector seed (see
+ * the sema_gl_mme_selector_seed comment). Emits the exact
+ * 4-method group SETUP_FIXED_CONST would emit, so a window
+ * that calls macro 57 without a preceding macro 0 has a
+ * valid selector instead of poisoning at 0x2390. Size is
+ * MME_VPC_CONSTANT_BUFFER_SIZE (0x7000, gf100mme.h); B/C
+ * carry the same fixed-CB base>>8 and translation as the
+ * 0x3460 scratch seed; the offset is the seeded d29.
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_selector_seed) &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_state_seed)) {
+ static u32 mme_sel_seed_log;
+ u32 sv = READ_ONCE(gsp_phys_rmcall_gr_mme_seed_val);
+ bool have = sv != 0u;
+
+ if (!have)
+ have = gsp_sema_mme_scratch18_get(&sv);
+ if (have && sv &&
+ (u32)(p - pb) + 8u <
+ GSP_PHYS_RMCALL_GR_METHOD_WORDS) {
+ u64 va = (u64)sv << 8;
+ bool xl = false;
+ u32 off;
+
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_seed_xlat)
+ && va) {
+ u32 up_w = (u32)((va >> 32) & 0xffu);
+ u32 lo_w = (u32)va & 0xfffffffcu;
+ u32 n_sh = 0;
+
+ if (gsp_phys_rmcall_gr_3d_reloc(
+ &up_w, &lo_w, req, &n_sh)) {
+ va = ((u64)(up_w & 0xffu)
+ << 32) |
+ (u64)(lo_w & 0xfffffffcu);
+ sv = (u32)(va >> 8);
+ xl = true;
+ }
+ }
+ off = READ_ONCE(gsp_phys_rmcall_gr_mme_state_d29);
+ *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM << 29) |
+ (1u << 16) | (0x2380u >> 2);
+ *p++ = 0x7000u;
+ *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM << 29) |
+ (1u << 16) | (0x2384u >> 2);
+ *p++ = (sv >> 24) & 0xffu;
+ *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM << 29) |
+ (1u << 16) | (0x2388u >> 2);
+ *p++ = sv & 0xffffffu;
+ *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM << 29) |
+ (1u << 16) | (0x238cu >> 2);
+ *p++ = off & 0xffffu;
+ if (mme_sel_seed_log < 64u) {
+ mme_sel_seed_log++;
+ pr_info("vgsp-gr: MME-SELECTOR-SEED size=0x7000 addr=0x%06x off=0x%04x (va=0x%llx xlat=%u) h=0x%x push=0x%llx\n",
+ sv & 0xffffffu, off & 0xffffu,
+ va, xl, req->h_object,
+ req->push_va);
+ }
+ }
+ }
+ /*
* SESSION 153-CONTINUED-93: the LEGACY program-region pair
* (0x1608/0x160c = the pre-Volta SET_PROGRAM_REGION_A/B whose
* names the DS's own snapshot registers
@@ -29980,14 +30102,26 @@ gr_page_unmapped:
pr_info("vgsp-gr: RT0-BIND skipped (no 0x840 run) window=%u\n",
win3d_n);
}
- } else if (win3d_n + GSP_PHYS_GR_RT0_BIND_WORDS +
+ } else if (win3d_n +
+ (READ_ONCE(gsp_phys_rmcall_gr_rt0_third_dim) ?
+ GSP_PHYS_GR_RT0_BIND_EXT_WORDS :
+ GSP_PHYS_GR_RT0_BIND_WORDS) +
2u + 8u <=
GSP_PHYS_RMCALL_GR_METHOD_WORDS) {
u32 rt0_old = win3d_n;
- u32 rt0_words[GSP_PHYS_GR_RT0_BIND_WORDS];
-
- memcpy(rt0_words, gsp_phys_gr_rt0_bind,
- sizeof(rt0_words));
+ bool rt0_td =
+ READ_ONCE(gsp_phys_rmcall_gr_rt0_third_dim);
+ u32 rt0_n = rt0_td ?
+ GSP_PHYS_GR_RT0_BIND_EXT_WORDS :
+ GSP_PHYS_GR_RT0_BIND_WORDS;
+ u32 rt0_words[GSP_PHYS_GR_RT0_BIND_EXT_WORDS];
+
+ if (rt0_td)
+ memcpy(rt0_words, gsp_phys_gr_rt0_bind_ext,
+ sizeof(gsp_phys_gr_rt0_bind_ext));
+ else
+ memcpy(rt0_words, gsp_phys_gr_rt0_bind,
+ sizeof(gsp_phys_gr_rt0_bind));
/*
* r1483: RT0 and RT1 must name the SAME
* surface. The SURF prelude just emitted
@@ -30007,20 +30141,20 @@ gr_page_unmapped:
memcpy(&rt0_words[1],
&gsp_phys_gr_surf_pre[1],
6u * sizeof(u32));
- memmove(&stream_patch[rt0_at +
- GSP_PHYS_GR_RT0_BIND_WORDS],
+ memmove(&stream_patch[rt0_at + rt0_n],
&stream_patch[rt0_at],
(size_t)(win3d_n - rt0_at) * 4u);
memcpy(&stream_patch[rt0_at], rt0_words,
- sizeof(rt0_words));
- win3d_n += GSP_PHYS_GR_RT0_BIND_WORDS;
+ rt0_n * 4u);
+ win3d_n += rt0_n;
if (rt0_emit_log < 16u) {
rt0_emit_log++;
- pr_info("vgsp-gr: RT0-BIND emitted window=%u->%u at=%u target=0x%llx surf=%u\n",
+ pr_info("vgsp-gr: RT0-BIND emitted window=%u->%u at=%u target=0x%llx surf=%u td=%u\n",
rt0_old, win3d_n, rt0_at,
((u64)(rt0_words[1] & 0xffu) << 32) |
(u64)(rt0_words[2] & 0xfffffffcu),
- surf_pre_emitted ? 1u : 0u);
+ surf_pre_emitted ? 1u : 0u,
+ rt0_td ? 1u : 0u);
}
} else {
if (rt0_skip_log < 8u) {