summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_emulation.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_emulation.c')
-rw-r--r--kernel/gsp_emulation.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/kernel/gsp_emulation.c b/kernel/gsp_emulation.c
index 3b6f6e5..5522bf3 100644
--- a/kernel/gsp_emulation.c
+++ b/kernel/gsp_emulation.c
@@ -138,6 +138,32 @@ enum gsp_emu_boot_stage {
};
/*
+ * gsp_emu_clear_boot_state - return the emulated GSP to a cold state.
+ *
+ * On real hardware, driver unload tears down WPR2 (Booter Unload) so the
+ * next probe's _kgspBootGspRm WPR2-up check passes. Turing guests produce
+ * no observable BAR0 writes on unload, so callers must trigger this on
+ * indirect death signals (ENGINE reset, GSP-RM queue going stale).
+ * Clears WPR2, RISCV active status and the falcon stage tracker, and
+ * drops the parsed GSP-RM queue state.
+ */
+void gsp_emu_clear_boot_state(struct gsp_emu_context *ctx, const char *reason)
+{
+ nv_vgpu_info(ctx->vgpu, "GSP-BOOT: clearing boot state (%s)", reason);
+
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_WPR2_ADDR_LO, 0);
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_WPR2_ADDR_HI, 0);
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_RISCV_STATUS, 0);
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_GSP_MAILBOX0, 0);
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_GSP_MAILBOX1, 0);
+
+ ctx->boot_stage = GSP_BOOT_STAGE_IDLE;
+ ctx->flcn_kick_count = 0;
+
+ gsp_rm_emu_reset(ctx);
+}
+
+/*
* gsp_emu_poll_boot - drive the guest's physical GSP boot to completion.
*
* The guest driver kicks falcon ucodes (FWSEC for FRTS, then Booter Load for
@@ -155,12 +181,10 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx)
/* GSP ENGINE reset asserted -> falcon rebooted, restart stage tracking */
if ((engine & 0x1) && ctx->boot_stage != GSP_BOOT_STAGE_IDLE) {
- ctx->boot_stage = GSP_BOOT_STAGE_IDLE;
- ctx->flcn_kick_count = 0;
nv_vgpu_info(ctx->vgpu, "GSP-BOOT: falcon reset, back to IDLE");
/* The guest is rebooting the GSP (new probe or unload): the
* GSP-RM queue state is stale, reset it too. */
- gsp_rm_emu_reset(ctx);
+ gsp_emu_clear_boot_state(ctx, "ENGINE reset");
return;
}