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