diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-06 20:09:42 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-06 20:09:42 -0500 |
| commit | 88e0b15326a7bacb6c02f351b26a4b28a7933ad8 (patch) | |
| tree | 3701b1176742ece74f41d7db229a68bed1cb8aaa /kernel/gsp_sema_service.c | |
| parent | 630a8a9fbadc4e6be2f21b162071157ccfc12664 (diff) | |
| download | open-iov-88e0b15326a7bacb6c02f351b26a4b28a7933ad8.tar.gz open-iov-88e0b15326a7bacb6c02f351b26a4b28a7933ad8.zip | |
vgsp-gl: synthesized GS SPH image + map variants for the SPH18 gate
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index dafbad6..d8aa4dc 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -10579,14 +10579,16 @@ static void svc_gl_flush(struct nv_vgpu_device *vgpu, * channels only, and only when the window does not already * bind that exact VA. */ - if (gsp_phys_rmcall_gr_sph_bind_value() && + if ((gsp_phys_rmcall_gr_sph_bind_value() || + gsp_phys_rmcall_gr_sph_gs_img_value()) && (ch->h_object & 0xfffff000u) == 0xbeef0000u && svc_gl.progs[0]) { u64 fam = svc_gl.progs[0] & ~(u64)(SEMA_PAGE_SIZE - 1); u32 k; - for (k = 0; k < 2u && n_recs < SVC_GL_PROG_MAX; k++) { + for (k = 0; gsp_phys_rmcall_gr_sph_bind_value() && + k < 2u && n_recs < SVC_GL_PROG_MAX; k++) { u64 dst = fam + (k ? 0x200u : 0x0u); const u8 *b = k ? svc_gl_vs : svc_gl_ps; u32 bl = k ? svc_gl_vs_len : svc_gl_ps_len; @@ -10619,6 +10621,83 @@ static void svc_gl_flush(struct nv_vgpu_device *vgpu, get_unaligned_le32(prs[n_recs - 1].data)); } } + /* + * SESSION 155 CONT 11: the synthesized header-only + * GEOMETRY SPH at family+0x780. The client never + * emits a geometry program, but the DS validates + * the GS stage anyway (SPH18 = GS check2 attribute + * map) even when the stage is disabled. The booter + * binds this page to stage 4 with ENABLE=0, so the + * engine does not execute it. SPH V4T1 header with + * SHADER_TYPE=GEOMETRY (4), SASS_VERSION=5 and + * pass-through maps (IMAP = the VTG OMAP = + * POSITION+COLOR; OMAP = the PS IMAP superset + * POSITION+COLOR). 128 bytes, same 4K family page + * as the bound VTG/TCS/PS images. + */ + if (gsp_phys_rmcall_gr_sph_gs_img_value() && + n_recs < SVC_GL_PROG_MAX) { + u32 gs_words[32] = { + 0x000a1081u, 0x00000000u, + 0x01000000u, 0x07000000u, + 0x00000003u, 0xf0000000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + 0x0000000fu, 0x00000000u, + 0x00000000u, 0x0000f000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x000f0000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, + }; + u32 gs_maps = + gsp_phys_rmcall_gr_sph_gs_maps_value(); + u64 dst = fam + 0x780u; + bool dup = false; + u32 pi4; + + /* + * SESSION 155 CONT 12: map A/B (see the + * sema_gl_sph_gs_maps comment). 0 keeps the + * pass-through header above. + */ + if (gs_maps == 1u) { + gs_words[5] = 0u; + gs_words[10] = 0u; + gs_words[13] = 0u; + gs_words[17] = 0u; + } else if (gs_maps == 2u) { + gs_words[5] = 0x80000000u; + gs_words[10] = 0u; + gs_words[13] = 0x0000f000u; + gs_words[17] = 0u; + } else if (gs_maps == 3u) { + gs_words[17] = 0u; + } + + for (pi4 = 0; pi4 < svc_gl.n_progs; pi4++) + if (svc_gl.progs[pi4] == dst) + dup = true; + if (!dup) { + memset(&prs[n_recs], 0, + sizeof(prs[n_recs])); + prs[n_recs].dst_va = dst; + prs[n_recs].len = 128u; + memcpy(prs[n_recs].data, gs_words, + sizeof(gs_words)); + n_recs++; + if (gsp_sema_dbg && + svc_gl_prog_log < 64) + pr_info("sema-gl: stage-image dst=0x%llx slot=4 len=128 maps=%u first=%08x w5=%08x w13=%08x\n", + dst, gs_maps, gs_words[0], + gs_words[5], gs_words[13]); + } + } } if (n_recs && gsp_sema_dbg && svc_gl_prog_log < 64) { u32 pi2; |
