diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_emulation.c | 11 | ||||
| -rw-r--r-- | kernel/gsp_emulation.h | 5 | ||||
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 20 |
3 files changed, 28 insertions, 8 deletions
diff --git a/kernel/gsp_emulation.c b/kernel/gsp_emulation.c index bca8a52..7b3b261 100644 --- a/kernel/gsp_emulation.c +++ b/kernel/gsp_emulation.c @@ -178,6 +178,17 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx) u32 gsp_cpuctl = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_GSP_CPUCTL); u32 sec2_cpuctl = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_SEC2_CPUCTL); u32 engine = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_GSP_ENGINE); + u32 mmu_inv = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_MMU_INVALIDATE); + + /* TLB invalidate auto-complete: the driver sets TRIGGER then spins + * polling for it to clear (kgmmuCheckPendingInvalidates). Report + * instant completion or the driver wedges the open/init path. */ + if (mmu_inv & GSP_EMU_MMU_INVALIDATE_TRIGGER) { + gsp_emu_shadow_write32(ctx, GSP_EMU_REG_MMU_INVALIDATE, + mmu_inv & ~GSP_EMU_MMU_INVALIDATE_TRIGGER); + pr_info_ratelimited("GSP-BOOT: MMU_INVALIDATE trigger auto-cleared (val=0x%x)\n", + mmu_inv); + } /* GSP ENGINE reset asserted -> falcon rebooted, restart stage tracking */ if ((engine & 0x1) && ctx->boot_stage != GSP_BOOT_STAGE_IDLE) { diff --git a/kernel/gsp_emulation.h b/kernel/gsp_emulation.h index fe4186e..156499a 100644 --- a/kernel/gsp_emulation.h +++ b/kernel/gsp_emulation.h @@ -58,6 +58,11 @@ #define GSP_EMU_REG_SEC2_MAILBOX0 0x840040 #define GSP_EMU_REG_SEC2_ENGINE 0x8403c0 +/* NV_VIRTUAL_FUNCTION_PRIV_MMU_INVALIDATE: driver sets TRIGGER(bit31) to + * start a TLB invalidate, then polls for bit31==0 (done). We auto-clear it. */ +#define GSP_EMU_REG_MMU_INVALIDATE 0x0030b0 +#define GSP_EMU_MMU_INVALIDATE_TRIGGER (1U << 31) + #define GSP_EMU_CPUCTL_STARTCPU 0x2 #define GSP_EMU_CPUCTL_HALTED 0x10 diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 0a040d5..67115b3 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -1289,18 +1289,22 @@ static void gsp_rm_handle_element(struct gsp_emu_context *ctx, const u8 *elem) * driver's rpcRecvPoll completes. */ rm->unknown_rpcs++; if (function == 10 || function == 47) { - /* FREE/UNLOADING: log hObject for unload-cycle debugging */ + /* FREE/UNLOADING: log hObject + queue positions for + * unload-cycle debugging. driver_rp = the peer's status + * read pointer (swap-rx): if it lags stat_write, the + * driver isn't draining our replies. */ const u8 *p = elem + GSPRM_ELEM_HDR_SIZE + sizeof(struct gsprm_rpc_header); - u32 hc = 0, ho = 0; + u32 hc = 0, ho = 0, driver_rp = 0; - if (hdr->length >= sizeof(*hdr) + 8) { - memcpy(&hc, p, 4); - memcpy(&ho, p + 4, 4); - } - nv_vgpu_info(ctx->vgpu, "GSPRM: RPC %s(%u) seq=%u hClient=0x%x hObject=0x%x cmd_read=%u", + if (hdr->length >= sizeof(*hdr) + 12) + memcpy(&ho, p + 8, 4); /* hObjectOld */ + gsp_rm_read_buf(ctx, rm->cmd_off + 0x20, + &driver_rp, sizeof(driver_rp)); + nv_vgpu_info(ctx->vgpu, "GSPRM: RPC %s(%u) seq=%u hRoot=0x%x hObjOld=0x%x cmd_read=%u stat_write=%u drv_rp=%u stat_seq=%u", gsp_rm_rpc_name(function), function, sequence, - hc, ho, rm->cmd_read); + hc, ho, rm->cmd_read, rm->stat_write, + driver_rp, rm->stat_seq); } else { nv_vgpu_info(ctx->vgpu, "GSPRM: RPC %s(%u) seq=%u len=%u -> generic SUCCESS reply (unknown #%llu)", gsp_rm_rpc_name(function), function, sequence, |
