diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 171 |
1 files changed, 155 insertions, 16 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 0764e1b..a94bbef 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -5114,18 +5114,21 @@ static const char *gsp_phys_pbdma_type_name(u32 t) */ static void gsp_phys_mme_regs_log(void __iomem *bar0, const char *tag) { - u32 esr, info, info2, trapped; + u32 esr, info, info2, info3, info4, trapped; if (!bar0) return; esr = ioread32(bar0 + 0x00404490u); info = ioread32(bar0 + 0x00404494u); - info2 = ioread32(bar0 + 0x00404498u); + /* SESSION 153-CONTINUED-106: INFO2 is 0x40449c (0x404498 is CONFIG). */ + info2 = ioread32(bar0 + 0x0040449cu); + info3 = ioread32(bar0 + 0x004044a8u); + info4 = ioread32(bar0 + 0x004044acu); trapped = ioread32(bar0 + 0x00400704u); - pr_warn("vgsp-gr: MME-REGS %s esr=%08x(pc_valid=%u illegal=%u miss=%u extra=%u) pc=%u macro_addr=0x%x info2_ir=%08x trapped=%08x\n", + pr_warn("vgsp-gr: MME-REGS %s esr=%08x(pc_valid=%u illegal=%u miss=%u extra=%u) pc=%u macro_addr=0x%x ir=%08x,%08x,%08x trapped=%08x\n", tag, esr, (info >> 28) & 1u, (esr >> 2) & 1u, (esr >> 0) & 1u, (esr >> 1) & 1u, info & 0xfffu, - (info >> 12) & 0xffu, info2, trapped); + (info >> 12) & 0xffu, info2, info3, info4, trapped); } /* @@ -5150,6 +5153,19 @@ MODULE_PARM_DESC(sema_mme_fast_ms, "Spin-sample the MME fault registers right after each GR launch doorbell for this many ms, logging every transition before the GSP-RM clears them (0 = off; default 400)"); /* + * SESSION 153-CONTINUED-106: post-timeout re-spin. The r1363 chronology + * shows the MME ILLEGAL_OPCODE relay arriving up to ~2.6 s AFTER the sem + * wait failed (launch failed 403088.34, ILLEGAL_OPCODE relayed 403090.96); + * every launch-window spin had already ended, so the latch was never seen + * with its INFO/IR. This bounded second spin runs on the first timeout + * exits of a boot, exactly where the r1363 trap sat. + */ +static u32 gsp_phys_mme_post_ms = 2000u; +module_param_named(sema_mme_post_ms, gsp_phys_mme_post_ms, uint, 0644); +MODULE_PARM_DESC(sema_mme_post_ms, + "Post-timeout MME fault-register re-spin length in ms on the first GR launch-timeout exits (0 = off; default 2000)"); + +/* * SESSION 153-CONTINUED-83: store-side emission forensics. * * The store wall: draws retire but `output retirement wait: 0/N pages @@ -5261,16 +5277,24 @@ static void gsp_phys_store_side_log(void __iomem *bar0, const char *tag, } static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag, - u32 h_object) + u32 h_object, u32 ms_override) { static u32 fast_boot_n; - u32 ms = READ_ONCE(gsp_phys_mme_fast_ms); + u32 ms = ms_override ? ms_override : READ_ONCE(gsp_phys_mme_fast_ms); u32 esr_p, ds_p, gf_p, tr_p, n = 0; u32 fed0_p, fed1_p; + u32 ds_log_n = 0; ktime_t t_end; bool poisoned = false; - if (!bar0 || !ms || fast_boot_n >= 48u) + /* + * SESSION 153-CONTINUED-106: the budget was 48, which a beef-lane boot + * with the wedged-engine relaunch train exhausts long before the + * first MME trap is relayed (r1363: 27 launch spins used by +300 s, + * trap traffic still arriving). Raised so every beef-family launch + * of a diagnostic boot keeps its spin. + */ + if (!bar0 || !ms || fast_boot_n >= 256u) return false; /* * Beef-family channels get the full budget (the draw-class windows @@ -5308,10 +5332,29 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag, fed0 != fed0_p || fed1 != fed1_p) { if (n < 12u) { u32 info = ioread32(bar0 + 0x00404494u); - u32 info2 = ioread32(bar0 + 0x00404498u); + /* + * SESSION 153-CONTINUED-106: the IR word + * registers are 0x40449c (INFO2), 0x4044a8 + * (INFO3), 0x4044ac (INFO4). The old read at + * 0x404498 was NV_PGRAPH_PRI_MME_CONFIG + * (RW), which is why every "info2_ir" line so + * far showed the shadow-filter enable, not the + * rejected instruction. + */ + u32 info2 = ioread32(bar0 + 0x0040449cu); + u32 info3 = ioread32(bar0 + 0x004044a8u); + u32 info4 = ioread32(bar0 + 0x004044acu); u32 mmeir = ioread32(bar0 + 0x0040a630u); u32 mmeir1 = ioread32(bar0 + 0x0040a634u); u32 mmedata = ioread32(bar0 + 0x00400708u); + /* + * SESSION 153-CONTINUED-106: the MME's own + * macro PC/state at the transition instant + * (0x4044b4: PC 11:0, MACRO 19:12, RUNNING + * 20) - the "is the MME mid-macro at the + * trap" witness. + */ + u32 mmemac = ioread32(bar0 + 0x004044b4u); /* * r1151 (SESSION 153-CONTINUED-72): @@ -5324,11 +5367,12 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag, * the launch; slot 1 is the second * lane of the same record set. */ - pr_warn("vgsp-gr: MME-FAST %s h=0x%x esr %08x->%08x info=%08x(pc_valid=%u pc=%u mac=0x%x) info2_ir=%08x ds %08x->%08x grfifo %08x->%08x trap=%08x data=%08x fed=%08x,%08x (pc0=%u mac0=0x%x gen0=%u) fe1=%08x (pc1=%u mac1=0x%x gen1=%u)\n", + pr_warn("vgsp-gr: MME-FAST %s h=0x%x esr %08x->%08x info=%08x(pc_valid=%u pc=%u mac=0x%x) ir=%08x,%08x,%08x ds %08x->%08x grfifo %08x->%08x trap=%08x data=%08x fed=%08x,%08x (pc0=%u mac0=0x%x gen0=%u) fe1=%08x (pc1=%u mac1=0x%x gen1=%u)\n", tag, h_object, esr_p, esr, info, (info >> 28) & 1u, info & 0xfffu, - (info >> 12) & 0xffu, info2, + (info >> 12) & 0xffu, + info2, info3, info4, ds_p, ds, gf_p, gf, tr, mmedata, mmeir, mmeir1, mmeir & 0xfffu, @@ -5338,6 +5382,82 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag, fed1 & 0xfffu, (fed1 >> 12) & 0x3ffu, (fed1 >> 31) & 1u); + pr_warn("vgsp-gr: MME-FAST %s h=0x%x macro-status=%08x(mpc=%u mac=0x%x run=%u)\n", + tag, h_object, mmemac, + mmemac & 0xfffu, + (mmemac >> 12) & 0xffu, + (mmemac >> 20) & 1u); + } + /* + * SESSION 153-CONTINUED-106: when the DS latch CHANGES + * into a fault (the SPH validation miss at draw + * dispatch), read the per-stage SPH_INFO START/UPPER + * and PROGRAM_REGION pair IMMEDIATELY - the FECS + * clears the whole block within ~1 ms (r1364: + * 404004.338 poison seen, 404004.339 clean), so this + * is the only in-flight window that names the VA each + * failing stage fetched. + */ + if (ds != ds_p && (ds & 0x7fffffffu) && ds_log_n < 8u) { + ds_log_n++; + u32 s0 = ioread32(bar0 + 0x00405c00u); + u32 s1 = ioread32(bar0 + 0x00405c04u); + u32 s2 = ioread32(bar0 + 0x00405c08u); + u32 s3 = ioread32(bar0 + 0x00405c0cu); + u32 s4 = ioread32(bar0 + 0x00405c10u); + u32 s5 = ioread32(bar0 + 0x00405c14u); + u32 u0 = ioread32(bar0 + 0x00405c24u); + u32 u1 = ioread32(bar0 + 0x00405c28u); + u32 u2 = ioread32(bar0 + 0x00405c2cu); + u32 u3 = ioread32(bar0 + 0x00405c30u); + u32 u4 = ioread32(bar0 + 0x00405c34u); + u32 u5 = ioread32(bar0 + 0x00405c38u); + u32 rr_a = ioread32(bar0 + 0x00405c1cu); + u32 rr_b = ioread32(bar0 + 0x00405c20u); + + pr_warn("vgsp-gr: DS-FAST %s h=0x%x ds %08x->%08x stage=%08x,%08x,%08x,%08x,%08x,%08x upper=%02x,%02x,%02x,%02x,%02x,%02x region=%08x,%08x esr=%08x\n", + tag, h_object, ds_p, ds, + s0, s1, s2, s3, s4, s5, + u0 & 0xffu, u1 & 0xffu, u2 & 0xffu, + u3 & 0xffu, u4 & 0xffu, u5 & 0xffu, + rr_a, rr_b, + ioread32(bar0 + 0x00404490u)); + /* + * SESSION 153-CONTINUED-106: the pending DS + * report poisons the whole PRI block + * (every register reads 0xbadf1201 - the + * first-capture above shows exactly that). + * Clear the report masks and re-read: the + * CONT-91 rule says a DS miss with the masks + * cleared latches without the poison, so the + * per-stage SPH snapshot should become + * readable. + */ + { + u32 m0 = ioread32(bar0 + 0x00405844u); + u32 m2 = ioread32(bar0 + 0x0040584cu); + + iowrite32(0u, bar0 + 0x00405844u); + iowrite32(0u, bar0 + 0x0040584cu); + udelay(80); + pr_warn("vgsp-gr: DS-FAST2 %s h=0x%x masks=%08x/%08x ds_after=%08x stage=%08x,%08x,%08x,%08x,%08x,%08x upper=%02x,%02x,%02x,%02x,%02x,%02x region=%08x,%08x\n", + tag, h_object, m0, m2, + ioread32(bar0 + 0x00405840u), + ioread32(bar0 + 0x00405c00u), + ioread32(bar0 + 0x00405c04u), + ioread32(bar0 + 0x00405c08u), + ioread32(bar0 + 0x00405c0cu), + ioread32(bar0 + 0x00405c10u), + ioread32(bar0 + 0x00405c14u), + ioread32(bar0 + 0x00405c24u) & 0xffu, + ioread32(bar0 + 0x00405c28u) & 0xffu, + ioread32(bar0 + 0x00405c2cu) & 0xffu, + ioread32(bar0 + 0x00405c30u) & 0xffu, + ioread32(bar0 + 0x00405c34u) & 0xffu, + ioread32(bar0 + 0x00405c38u) & 0xffu, + ioread32(bar0 + 0x00405c1cu), + ioread32(bar0 + 0x00405c20u)); + } } n++; esr_p = esr; @@ -5539,7 +5659,8 @@ static void gsp_phys_fault_regs_log(u32 except_type) frl_n++; esr = ioread32(bar0 + 0x00404490u); info = ioread32(bar0 + 0x00404494u); - info2 = ioread32(bar0 + 0x00404498u); + /* SESSION 153-CONTINUED-106: INFO2 is 0x40449c (0x404498 is CONFIG). */ + info2 = ioread32(bar0 + 0x0040449cu); ds = ioread32(bar0 + 0x00405840u); ds2 = ioread32(bar0 + 0x00405848u); for (si = 0; si < 6u; si++) @@ -22232,7 +22353,8 @@ static noinline void gsp_phys_gr_state_rb_log(u32 h_object) fed3 = ioread32(bar0 + 0x0040a63cu); esr = ioread32(bar0 + 0x00404490u); info = ioread32(bar0 + 0x00404494u); - ir2 = ioread32(bar0 + 0x00404498u); + /* SESSION 153-CONTINUED-106: INFO2 is 0x40449c (0x404498 is CONFIG). */ + ir2 = ioread32(bar0 + 0x0040449cu); trap = ioread32(bar0 + 0x00400704u); data = ioread32(bar0 + 0x00400708u); ds = ioread32(bar0 + 0x00405840u); @@ -24883,6 +25005,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req, u8 *qmd_dst_mem = NULL; u32 qmd_rel_off = 0, ch_rel_off = 0; u32 poll = 0, w0 = 0, w1 = 0, grpoll_n = 0; + static u32 post_spin_n; bool sem_gated = false; static u32 sked_prev[28]; static u32 sked_sample[28]; @@ -27173,7 +27296,7 @@ gr_page_unmapped: */ if (stream3d && bar0) fast_poison = gsp_phys_mme_fast_sample(bar0, "launch", - req->h_object); + req->h_object, 0); poll_start_us = (u32)ktime_to_us(ktime_get()); deadline = jiffies + msecs_to_jiffies(poll_ms); @@ -27218,7 +27341,8 @@ gr_page_unmapped: * The DS shader-program-header error latch (0x405840), * the MME exception latch (0x404490) with its PC/macro * address (0x404494) and instruction register - * (0x404498) are cleared by the real RM within ~ms of + * (0x40449c, fixed in SESSION 153-CONTINUED-106) are + * cleared by the real RM within ~ms of * the fault, so the post-timeout reads are all clean. * Sampling them every poll tick records the faulting * values at the first change. @@ -27226,7 +27350,8 @@ gr_page_unmapped: sked_sample[14] = ioread32(bar0 + 0x00405840u); sked_sample[15] = ioread32(bar0 + 0x00404490u); sked_sample[16] = ioread32(bar0 + 0x00404494u); - sked_sample[17] = ioread32(bar0 + 0x00404498u); + /* SESSION 153-CONTINUED-106: INFO2 0x40449c (was CONFIG). */ + sked_sample[17] = ioread32(bar0 + 0x0040449cu); /* * SESSION 153-CONTINUED-52: the PBDMA host-software * METHOD latch (NV_PPBDMA_METHOD0 0x4000c0: ADDR @@ -27542,6 +27667,20 @@ gr_page_unmapped: gsp_phys_gr_fetch_miss_log(req->h_object, &sub, "timeout"); /* + * SESSION 153-CONTINUED-106: the r1363 trap sat in the + * ~2.6 s window AFTER this timeout (launch failed + * 403088.34, ILLEGAL_OPCODE relayed 403090.96). Re-spin + * once here, bounded to the first few timeouts of the + * boot, so the latch is caught at first sight with its + * INFO/IR word instead of being missed between spins. + */ + if (gsp_phys_mme_post_ms && post_spin_n < 8u) { + post_spin_n++; + (void)gsp_phys_mme_fast_sample(bar0, "post", + req->h_object, + gsp_phys_mme_post_ms); + } + /* * F4-b: one-shot deposit readback at the FIRST timeout * (the old post-mortem only ran after attempt 3, which * a recovered launch never reached). Reading the @@ -31519,7 +31658,7 @@ static int gsp_phys_reg_probe_show(struct seq_file *m, void *unused) 0x00404494u); (void)gsp_phys_reg_probe_line(m, bar0, "PGRAPH_PRI_MME_HWW_ESR_INFO2", - 0x00404498u); + 0x0040449cu); fe_chip_def = gsp_phys_reg_probe_line(m, bar0, "FE_CHIP_DEF_INFO", 0x00404030u); fe_go_idle = gsp_phys_reg_probe_line(m, bar0, "FE_GO_IDLE_INFO", |
