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.c170
1 files changed, 164 insertions, 6 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index f8208d6..9e04c22 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18565,6 +18565,45 @@ module_param_named(sema_gl_pair_close_entry,
gsp_phys_rmcall_gr_pair_close_entry, bool, 0644);
MODULE_PARM_DESC(sema_gl_pair_close_entry,
"Emit an END (0x1614) for a BEGIN..END pair carried open into the window before its first run (default 0; A/B)");
+/*
+ * SESSION 155 CONT 9: the synthesized SPH-BIND prelude (j0/j2/j4/j5) is
+ * PREPENDED ahead of the window, so when the previous window left a
+ * BEGIN..END pair carried open the prelude's method runs land inside it -
+ * r1558 (mask=0x35) took EC 0x0d ILLEGAL_METHOD_IN_BEGIN_END at 0x2018.
+ * sema_gl_pair_close_entry closes the pair but is applied to the WHOLE
+ * window (prepends included) at the end of the pass; this knob makes the
+ * prelude itself self-contained: when the tracker says a pair is open, the
+ * END (0x1614 + event word, event 1 for split chains 1/2) is emitted as the
+ * FIRST word of the prelude, and each synthesized stage's
+ * SET_PIPELINE_SHADER TYPE and REGISTER_COUNT are emitted BEFORE its SPH
+ * address pair (the client's own stage-1 order). Default 0 = legacy bytes.
+ */
+static bool gsp_phys_rmcall_gr_sph_bind_pair_safe;
+module_param_named(sema_gl_sph_bind_pair_safe,
+ gsp_phys_rmcall_gr_sph_bind_pair_safe, bool, 0644);
+MODULE_PARM_DESC(sema_gl_sph_bind_pair_safe,
+ "Make the synthesized SPH-BIND prelude BEGIN/END-safe: close a carried-open pair with END(0x1614) before the prelude and emit TYPE/REGISTER_COUNT before each stage address pair (default 0; legacy bytes)");
+/*
+ * SESSION 155 CONT 9 (TASK B): the window replayed for a non-tessellated,
+ * non-geometry draw carries only the VSB (j=1) record; the client's
+ * channel state leaves VSA/TCS/TES/GS explicitly DISABLED. The replay
+ * channel instead inherits the setup-push program records (TCS enabled,
+ * 0x2080 <- 0x20 is a disable the ATTR-PRELUDE drops), so the DS validates
+ * VSB in tessellation mode and GS against a stale program - the r1560
+ * 0x900400a0 SPH5/7/18 bits. Emit the client's own disable records, each
+ * value quoted from the driver's unchanged-program path:
+ * 0x2000 <- 0x00 SET_PIPELINE_SHADER(0) ENABLE=FALSE|TYPE=VERTEX_CULL_BEFORE_FETCH
+ * 0x2080 <- 0x20 SET_PIPELINE_SHADER(2) ENABLE=FALSE|TYPE=TESSELLATION_INIT
+ * 0x20c0 <- 0x30 SET_PIPELINE_SHADER(3) ENABLE=FALSE|TYPE=TESSELLATION
+ * 0x2100 <- 0x40 SET_PIPELINE_SHADER(4) ENABLE=FALSE|TYPE=GEOMETRY
+ * and suppress the synthesized j0/j2/j4 binds (a disabled stage has no
+ * program to bind). Default 0 = legacy bytes.
+ */
+static bool gsp_phys_rmcall_gr_sph_stage_disable;
+module_param_named(sema_gl_sph_stage_disable,
+ gsp_phys_rmcall_gr_sph_stage_disable, bool, 0644);
+MODULE_PARM_DESC(sema_gl_sph_stage_disable,
+ "Emit the client's SET_PIPELINE_SHADER disable records for VSA/TCS/TES/GS before the synthesized binds and skip their binds (default 0; legacy bytes)");
static bool gsp_phys_gr_mme_pairs_emitted; /* launch emitted a pair run */
static u32 gsp_phys_gr_mme_pairs_gen; /* gen whose pairs retired OK */
static u32 gsp_phys_gr_mme_launch_gen; /* last built launch's gen */
@@ -29584,8 +29623,13 @@ gr_page_unmapped:
u32 bi;
bool bind_binding =
READ_ONCE(gsp_phys_rmcall_gr_sph_bind_binding);
- bool emit_j2 = sph_bind_all ||
- (sph_bind_mask & 0x04u);
+ bool pair_safe =
+ READ_ONCE(gsp_phys_rmcall_gr_sph_bind_pair_safe);
+ bool stage_disable =
+ READ_ONCE(gsp_phys_rmcall_gr_sph_stage_disable) &&
+ !sph_bind_all;
+ bool emit_j2 = !stage_disable &&
+ (sph_bind_all || (sph_bind_mask & 0x04u));
bool emit_j5 = sph_bind_all ||
(sph_bind_mask & 0x20u);
/*
@@ -29595,11 +29639,68 @@ gr_page_unmapped:
* per-stage record for VSA (j=0) and GS (j=4), binding
* the client's own VTG image (family+0x900) with the
* GS/VS-CULL types. Default off: bits 0/4 were unused.
+ * CONT 9: stage_disable suppresses j0/j2/j4 (a disabled
+ * stage has no program to bind).
*/
- bool emit_j0 = sph_bind_all ||
- (sph_bind_mask & 0x01u);
- bool emit_j4 = sph_bind_all ||
- (sph_bind_mask & 0x10u);
+ bool emit_j0 = !stage_disable &&
+ (sph_bind_all || (sph_bind_mask & 0x01u));
+ bool emit_j4 = !stage_disable &&
+ (sph_bind_all || (sph_bind_mask & 0x10u));
+
+ /*
+ * SESSION 155 CONT 9: the prelude is prepended ahead of
+ * the window, so if the tracker still holds a pair open
+ * from the previous emitted window every synthesized
+ * method would run inside BEGIN/END (r1558 EC 0x0d at
+ * 0x2018). Emit the class's own END as the FIRST word
+ * of the prelude, matching the event the open BEGIN's
+ * split mode requires. The pair-chain walk later sees
+ * this END close the open pair and starts a fresh one at
+ * the window's own BEGIN. Skipped when
+ * sema_gl_pair_close_entry is on: that helper inserts
+ * the same END ahead of the whole window (preludes
+ * included), so emitting both would double-close.
+ */
+ if (pair_safe &&
+ !READ_ONCE(gsp_phys_rmcall_gr_pair_close_entry) &&
+ READ_ONCE(gsp_phys_gr_mme_pair_open)) {
+ u32 osplit =
+ READ_ONCE(gsp_phys_gr_mme_pair_open_split);
+ u32 ev = (osplit == 1u || osplit == 2u) ? 1u : 0u;
+
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x1614u >> 2);
+ in[nfin++] = ev;
+ pr_info_ratelimited("vgsp-gr: SPH-BIND-PAIR-SAFE close split=%u ev=%u h=0x%x push=0x%llx\n",
+ osplit, ev, req->h_object, req->push_va);
+ }
+
+ /*
+ * SESSION 155 CONT 9: the window is a non-tessellated,
+ * non-geometry draw. The client's own state disables
+ * VSA/TCS/TES/GS; the replay channel inherits the
+ * setup-push records instead, so the DS validates VSB
+ * in tessellation mode (SPH5/7) and a stale GS program
+ * (SPH18). Emit the client's disable records FIRST (so
+ * no later synth bind re-enables them), with the exact
+ * values the driver's disabled-stage paths write.
+ */
+ if (stage_disable) {
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2000u >> 2);
+ in[nfin++] = 0x00u;
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2080u >> 2);
+ in[nfin++] = 0x20u;
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x20c0u >> 2);
+ in[nfin++] = 0x30u;
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2100u >> 2);
+ in[nfin++] = 0x40u;
+ pr_info_ratelimited("vgsp-gr: SPH-STAGE-DISABLE VSA/TCS/TES/GS h=0x%x push=0x%llx\n",
+ req->h_object, req->push_va);
+ }
/*
* SESSION 153-CONTINUED-89 (2nd half): the client's
@@ -29735,6 +29836,61 @@ gr_page_unmapped:
(emit_j2 ? (bind_binding ? 8u : 7u) : 0u) +
(emit_j4 ? (bind_binding ? 8u : 7u) : 0u) +
(emit_j5 ? (bind_binding ? 8u : 7u) : 0u) <= 96u) {
+ /*
+ * SESSION 155 CONT 9: pair_safe emits each
+ * synthesized stage's SET_PIPELINE_SHADER
+ * TYPE and REGISTER_COUNT *before* its SPH
+ * address pair, the order the client's own
+ * stage-1 init push uses. The legacy path
+ * below stays address-first (bytes
+ * unchanged when the knob is off).
+ */
+ if (pair_safe) {
+ if (emit_j0) {
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2000u >> 2);
+ in[nfin++] = 1u | (0u << 4);
+ in[nfin++] = 0x20000000u |
+ ((bind_binding ? 2u : 1u) << 16) |
+ (0x200cu >> 2);
+ in[nfin++] = 0x1au;
+ if (bind_binding)
+ in[nfin++] = 0x0u;
+ }
+ if (emit_j4) {
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2100u >> 2);
+ in[nfin++] = 1u | (4u << 4);
+ in[nfin++] = 0x20000000u |
+ ((bind_binding ? 2u : 1u) << 16) |
+ (0x210cu >> 2);
+ in[nfin++] = 0x1au;
+ if (bind_binding)
+ in[nfin++] = 0x0u;
+ }
+ if (emit_j2) {
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2080u >> 2);
+ in[nfin++] = 1u | (2u << 4);
+ in[nfin++] = 0x20000000u |
+ ((bind_binding ? 2u : 1u) << 16) |
+ (0x208cu >> 2);
+ in[nfin++] = 0x1au;
+ if (bind_binding)
+ in[nfin++] = 0x0u;
+ }
+ if (emit_j5) {
+ in[nfin++] = 0x20000000u | (1u << 16) |
+ (0x2140u >> 2);
+ in[nfin++] = 1u | (5u << 4);
+ in[nfin++] = 0x20000000u |
+ ((bind_binding ? 2u : 1u) << 16) |
+ (0x214cu >> 2);
+ in[nfin++] = 0x1au;
+ if (bind_binding)
+ in[nfin++] = 0x0u;
+ }
+ }
if (emit_j0) {
in[nfin++] = 0x20000000u | (2u << 16) |
(0x2014u >> 2);
@@ -29759,6 +29915,7 @@ gr_page_unmapped:
in[nfin++] = (u32)(fam >> 32) & 0xffu;
in[nfin++] = (u32)fam & 0xfffffffcu;
}
+ if (!pair_safe) {
/*
* SESSION 153-CONTINUED-88: the per-slot
* SET_PIPELINE_SHADER(j) TYPE state. The
@@ -29855,6 +30012,7 @@ gr_page_unmapped:
in[nfin++] = 0x1au;
}
}
+ }
/*
* SESSION 153-CONTINUED-89: the client's
* init-push stage-1 REGISTER_COUNT/BINDING