summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_rm_emulation.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 55bd6ff..b338a6f 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -3456,6 +3456,42 @@ static uint gsp_rm_a097_v48c;
module_param_named(wall2_a097_v48c, gsp_rm_a097_v48c, uint, 0644);
MODULE_PARM_DESC(wall2_a097_v48c, "0x2080a097 reply word at params+0x48c (default 0)");
+/*
+ * session 76: the 0x2080a097 reply's RECORD area (params+4..+0x23). The
+ * real host RM handler overwrites up to four {u32, u32} mode pairs there
+ * (per-mode engine status + a x1000 clock/percent value); the client
+ * (count=1) copies back the first 16 bytes into its per-engine query
+ * buffer, and the second word of the first pair is consumed as the
+ * "engine progress" word (libnvidia-eglcore d5e3e0: *(inner+4) ->
+ * session+0xe104, compared against per-boot config thresholds).
+ * Each word defaults to 0xffffffff = leave the echoed request word
+ * untouched; any other value replaces it, so one boot can sweep the
+ * record matrix without rebuilding.
+ */
+static uint gsp_rm_a097_count = ~0u;
+module_param_named(wall2_a097_count, gsp_rm_a097_count, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_count, "0x2080a097 reply count word at params+0 (0xffffffff = echo)");
+static uint gsp_rm_a097_rec0 = ~0u, gsp_rm_a097_rec1 = ~0u;
+static uint gsp_rm_a097_rec2 = ~0u, gsp_rm_a097_rec3 = ~0u;
+static uint gsp_rm_a097_rec4 = ~0u, gsp_rm_a097_rec5 = ~0u;
+static uint gsp_rm_a097_rec6 = ~0u, gsp_rm_a097_rec7 = ~0u;
+module_param_named(wall2_a097_rec0, gsp_rm_a097_rec0, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec0, "0x2080a097 reply word at params+0x4 (0xffffffff = echo)");
+module_param_named(wall2_a097_rec1, gsp_rm_a097_rec1, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec1, "0x2080a097 reply word at params+0x8 (0xffffffff = echo)");
+module_param_named(wall2_a097_rec2, gsp_rm_a097_rec2, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec2, "0x2080a097 reply word at params+0xc (0xffffffff = echo)");
+module_param_named(wall2_a097_rec3, gsp_rm_a097_rec3, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec3, "0x2080a097 reply word at params+0x10 (0xffffffff = echo)");
+module_param_named(wall2_a097_rec4, gsp_rm_a097_rec4, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec4, "0x2080a097 reply word at params+0x14 (0xffffffff = echo)");
+module_param_named(wall2_a097_rec5, gsp_rm_a097_rec5, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec5, "0x2080a097 reply word at params+0x18 (0xffffffff = echo)");
+module_param_named(wall2_a097_rec6, gsp_rm_a097_rec6, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec6, "0x2080a097 reply word at params+0x1c (0xffffffff = echo)");
+module_param_named(wall2_a097_rec7, gsp_rm_a097_rec7, uint, 0644);
+MODULE_PARM_DESC(wall2_a097_rec7, "0x2080a097 reply word at params+0x20 (0xffffffff = echo)");
+
/*
* The live session's oracle client/object for the 0x20810107 experiment,
@@ -4264,10 +4300,23 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
req.paramsSize + GSP_RM_CTRL_HDR_SIZE <=
GSPRM_MAX_SINGLE_ELEM_DATA) {
u32 count = 0, flag;
+ static const u32 *const recp[8] = {
+ &gsp_rm_a097_rec0, &gsp_rm_a097_rec1,
+ &gsp_rm_a097_rec2, &gsp_rm_a097_rec3,
+ &gsp_rm_a097_rec4, &gsp_rm_a097_rec5,
+ &gsp_rm_a097_rec6, &gsp_rm_a097_rec7,
+ };
+ int i;
memcpy(rp, pp, req.paramsSize);
memcpy(&count, pp, 4);
memcpy(&flag, pp + 0x204, 4);
+ if (gsp_rm_a097_count != ~0u)
+ *(u32 *)(rp + 0) = gsp_rm_a097_count;
+ for (i = 0; i < 8; i++) {
+ if (*recp[i] != ~0u)
+ *(u32 *)(rp + 4 + i * 4) = *recp[i];
+ }
*(u32 *)(rp + 0x204) = gsp_rm_a097_flag;
*(u32 *)(rp + 0x488) = gsp_rm_a097_v488;
*(u32 *)(rp + 0x48c) = gsp_rm_a097_v48c;