diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-15 11:17:06 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-15 11:17:06 -0500 |
| commit | b9e7e84249a28a5e296a0f97e00a3bdf2e5ce6df (patch) | |
| tree | 6ddc4ee932ee6f505a744c94ff26ee23416c75e5 /kernel/gsp_phys_booter.c | |
| parent | 444ae2c1dfde6a66e414b7f2ff9c5813ec50942d (diff) | |
| download | open-iov-b9e7e84249a28a5e296a0f97e00a3bdf2e5ce6df.tar.gz open-iov-b9e7e84249a28a5e296a0f97e00a3bdf2e5ce6df.zip | |
vgsp: eng51 - emit the SPH-BIND stage block (budget fix), admit RT0-bearing draw-synth windows, preserve the last beef push, and default the DS stage-image A/B safe
- gsp_phys_booter.c: the synthesized SPH-BIND stage-block guard
double-counted the already-emitted raster words (101 > 96), silently
skipping j0/j2/j4/j5; pre=29 -> pre=84 and the DS stage VAs populate.
Add the SPH-BIND-STAGE-SKIP receipt.
- gsp_sema_service.c: sema_gl_win_rt0_admit (default 1) admits a beef
draw-synth window whose FIRST colour-target write is a usable
surface-class bind (RT0-FIRST-MISS witness); preserve the most recent
beef push (>=256 B) for the gsp-phys-last-push debugfs dump; skip the
non-RAM windows in the linear ring scan; fix the MME shadow-RAM index
shift to (mthd >> 2) & 0xfff.
- gsp_phys_booter.c: sema_gl_sph_vtg600 (default 0) and
sema_gl_sph_vtg_j1 (default 0) are the stage-image A/B: binding
family+0x600 poisons the DS (the engine-visible alias shadow there is
the client's SASS upload), so keep the historical +0x900 zero page
until a real VTG SPH is authored at an engine-visible VA.
- tools/guest-diag/params-r1624.txt: enable sema_gl_win_rt0_admit.
- wiki/Project-Status.md: 2026-11-15 status (MME chain completes and
executes DRAW_IAB; DS stage image is the named gate).
Diffstat (limited to 'kernel/gsp_phys_booter.c')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 124 |
1 files changed, 114 insertions, 10 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index cf3107f..e43ba23 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -5280,7 +5280,7 @@ MODULE_PARM_DESC(sema_mme_post_ms, */ static u32 gsp_phys_mme_shadow_read(void __iomem *bar0, u32 nvclass, u32 mthd) { - iowrite32(nvclass | ((mthd & 0xfffu) << 16) | (1u << 30), + iowrite32(nvclass | (((mthd >> 2) & 0xfffu) << 16) | (1u << 30), bar0 + 0x00404488u); return ioread32(bar0 + 0x0040448cu); } @@ -19957,6 +19957,35 @@ module_param_named(sema_sph_bind_mask, gsp_phys_rmcall_gr_sph_bind_mask, MODULE_PARM_DESC(sema_sph_bind_mask, "Synth SPH-BIND slot mask (bit j = slot j; 0x20 = PS only, 0x01/0x10 = VSA/GS VTG image, 0x25 = VSA+PS) used when sema_gl_sph_bind=0"); +/* + * eng51 (CONT.512): the synthesized VSA/GS (j0/j4) bind the VTG SPH image. + * The historical address was family+0x900, but the live direct-GL family + * page reads zero there (c716: DS 0x86040624 with stage=01df0900,...). + * family+0x600 was tried as the VTG image (INLINE-WRITER: 0x020a0481), but + * the engine-visible alias shadow at +0x600 is the client's SASS upload + * (0x0b0b7208), so binding it poisons the DS (c718/c720: badf1201 with the + * j1 override off too). Default 0 = keep the historical +0x900 zero page + * until a real VTG SPH is authored at an engine-visible VA; A/B with 1. + */ +static bool gsp_phys_rmcall_gr_sph_vtg600; +module_param_named(sema_gl_sph_vtg600, gsp_phys_rmcall_gr_sph_vtg600, + bool, 0644); +MODULE_PARM_DESC(sema_gl_sph_vtg600, + "Bind the synthesized VSA/GS (j0/j4) stages to family+0x600 instead of the historical family+0x900 page (default 0: the live +0x600 alias shadow is SASS and poisons the DS)"); + +/* + * eng51 A/B (c718): overriding the window's own slot-1 bind (j1) with the + * family+0x600 image is a separate question. c718 (override on) poisoned the + * DS (badf1201) while c716 (j0/j4 at 0x900, j1 at the client's 0x300 SASS + * pointer) reached 0x86040624, so the j1 override is default OFF until a + * same-boot A/B says otherwise. + */ +static bool gsp_phys_rmcall_gr_sph_vtg_j1; +module_param_named(sema_gl_sph_vtg_j1, gsp_phys_rmcall_gr_sph_vtg_j1, + bool, 0644); +MODULE_PARM_DESC(sema_gl_sph_vtg_j1, + "Also point the window's own slot-1 (VTG) bind at family+0x600 instead of the client's captured bind (default 0; c718 poison A/B)"); + bool gsp_phys_rmcall_gr_sph_bind_value(void) { return READ_ONCE(gsp_phys_rmcall_gr_sph_bind); @@ -30660,6 +30689,8 @@ gr_page_unmapped: static u32 sph_bind_log; u64 fam = req->prog_va & ~(u64)(GSP_PHYS_PAGE_SIZE - 1); + u64 vtg_va = READ_ONCE(gsp_phys_rmcall_gr_sph_vtg600) ? + (fam + 0x600u) : (fam + 0x900u); u32 in[96], out[96]; u32 nfin = 0, nrun = 0, on = 0, odrop = 0, orel; u32 bi; @@ -30960,6 +30991,16 @@ gr_page_unmapped: if (!va || nfin + 3u > 96u) continue; + /* + * eng51: the window's own slot-1 bind can be + * a SASS pointer (c716: family+0x300 starts + * 0x0d0d7623); the VTG SPH image is at + * family+0x600. Point the VTG slot at the + * real image when the knob is on. + */ + if (sl == 1u && + READ_ONCE(gsp_phys_rmcall_gr_sph_vtg_j1)) + va = vtg_va; in[nfin++] = 0x20000000u | (2u << 16) | ((0x2014u + sl * 0x40u) >> 2); in[nfin++] = (u32)(va >> 32) & 0xffu; @@ -30981,9 +31022,7 @@ gr_page_unmapped: (emit_j5 ? (bind_binding ? 8u : 7u) : 0u) + (emit_gsimg ? (9u + ((gs_mode & 1u) ? 11u : 0u) + ((gs_ctx & 1u) ? 2u : 0u) + - ((gs_ctx & 2u) ? 2u : 0u)) : 0u) + - (emit_raster ? 17u : 0u) + - (emit_raster_extra ? 16u : 0u) + ((gs_ctx & 2u) ? 2u : 0u)) : 0u) <= 96u) { /* * SESSION 155 CONT 9: pair_safe emits each @@ -31043,14 +31082,14 @@ gr_page_unmapped: if (emit_j0) { in[nfin++] = 0x20000000u | (2u << 16) | (0x2014u >> 2); - in[nfin++] = (u32)((fam + 0x900u) >> 32) & 0xffu; - in[nfin++] = (u32)(fam + 0x900u) & 0xfffffffcu; + in[nfin++] = (u32)(vtg_va >> 32) & 0xffu; + in[nfin++] = (u32)vtg_va & 0xfffffffcu; } if (emit_j4) { in[nfin++] = 0x20000000u | (2u << 16) | (0x2114u >> 2); - in[nfin++] = (u32)((fam + 0x900u) >> 32) & 0xffu; - in[nfin++] = (u32)(fam + 0x900u) & 0xfffffffcu; + in[nfin++] = (u32)(vtg_va >> 32) & 0xffu; + in[nfin++] = (u32)vtg_va & 0xfffffffcu; } if (emit_j2) { in[nfin++] = 0x20000000u | (2u << 16) | @@ -31259,6 +31298,19 @@ gr_page_unmapped: nrun++; if (emit_gsimg) nrun++; + } else if (sph_bind_log < 64u) { + /* + * eng51 (CONT.512): name the silent budget + * skip. Before this receipt the stage block + * (j0/j2/j4/j5/gsimg) could vanish while the + * prelude still emitted with only the j1 bind, + * leaving VSA/TCS/GS unbound and the DS latch + * at the a2040a04 class. + */ + sph_bind_log++; + pr_info("vgsp-gr: SPH-BIND-STAGE-SKIP reason=budget nfin=%u mask=0x%x h=0x%x push=0x%llx\n", + nfin, sph_bind_mask, req->h_object, + req->push_va); } orel = gsp_phys_rmcall_gr_3d_patch_window( in, nfin, out, &on, &odrop, req, &n_shadow, @@ -31272,8 +31324,8 @@ gr_page_unmapped: sph_bind_log++; pr_info("vgsp-gr: SPH-BIND emitted fam=0x%llx win-binds=%u j0=0x%llx j2=0x%llx j4=0x%llx j5=0x%llx j1-type=0x11 rc=0x1a initblk=17 win=%u (pre=%u) h=0x%x push=0x%llx\n", fam, req->n_prog_binds, - fam + 0x900u, fam + 0x200u, - fam + 0x900u, fam, + vtg_va, fam + 0x200u, + vtg_va, fam, win3d_n, nfin, req->h_object, req->push_va); @@ -37250,6 +37302,52 @@ static const struct file_operations gsp_phys_init_push_fops = { }; /* + * eng51 (CONT.512): gsp-phys-last-push - the most recent >=4 KiB beef push + * (the direct-GL draw stream; c714: 0x4250110). Same text format as the + * init-push dump so the RT bind / draw methods can be decoded offline after + * the guest recycles its pushbuffer. + */ +static int gsp_phys_last_push_show(struct seq_file *m, void *unused) +{ + const u8 *buf; + u32 len, h, off; + u64 va; + + buf = gsp_sema_last_cap_get(&len, &h, &va); + if (!len) { + seq_puts(m, "vgsp-last-push: empty (no later >=4 KiB beef push captured yet)\n"); + return 0; + } + seq_printf(m, "vgsp-last-push: h=0x%x va=0x%llx len=%u\n", h, va, len); + for (off = 0; off + 4u <= len; off += 16u) { + u32 k, n = min_t(u32, 4u, (len - off) / 4u); + + seq_printf(m, "%06x:", off); + for (k = 0; k < n; k++) { + u32 w; + + memcpy(&w, buf + off + k * 4u, 4); + seq_printf(m, " %08x", w); + } + seq_putc(m, '\n'); + } + return 0; +} + +static int gsp_phys_last_push_open(struct inode *inode, struct file *file) +{ + return single_open(file, gsp_phys_last_push_show, NULL); +} + +static const struct file_operations gsp_phys_last_push_fops = { + .owner = THIS_MODULE, + .open = gsp_phys_last_push_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* * SESSION 153-CONTINUED-95: gsp-phys-ctx-dump - raw binary readback of the * engine context buffer (see gsp_phys_ctx_readback_try). Empty until the * first launch of the boot has run the CE readback. @@ -37483,6 +37581,12 @@ int gsp_phys_boot_debugfs_init(void) &gsp_phys_init_push_fops); if (IS_ERR_OR_NULL(file)) pr_warn("vgsp-boot: debugfs file gsp-phys-init-push creation failed (init-push capture unavailable)\n"); + /* eng51 (CONT.512): the most recent large beef push (direct-GL draw). */ + file = debugfs_create_file("gsp-phys-last-push", 0444, + gsp_phys_debugfs_root, NULL, + &gsp_phys_last_push_fops); + if (IS_ERR_OR_NULL(file)) + pr_warn("vgsp-boot: debugfs file gsp-phys-last-push creation failed (last-push capture unavailable)\n"); /* * SESSION 153-CONTINUED-95: raw binary dump of the engine context * buffer readback (64 KB from GSP_PHYS_RMCALL_VA_GR_CTX, taken once |
