diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 170 |
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 |
