summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 2f08064..576582a 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -15894,6 +15894,17 @@ static void svc_gl_cb_upload_scan(struct nv_vgpu_device *vgpu, u32 h_object,
0xffffffffULL) |
((u64)w << 32);
svc_gl_cb_sel_seen = true;
+ } else if (addr == 0x3800u) {
+ /*
+ * MME-wrapper form (570.144): the driver emits
+ * CALL_MME_MACRO(0) = SETUP_FIXED_CONST as an
+ * IMMD whose payload is the VPC dword offset
+ * (VPC_CONSTANT_DWORD(offs) = offs << 2); the
+ * macro converts it to the byte address the
+ * following LOAD_CONSTANT_BUFFER run writes at.
+ */
+ svc_gl_cb_off = w << 2;
+ dirty = true;
}
off += 4u;
continue;
@@ -15960,6 +15971,44 @@ static void svc_gl_cb_upload_scan(struct nv_vgpu_device *vgpu, u32 h_object,
base = (u64)w << 8;
if (base && base != svc_gl_cb_img_base)
svc_gl_cb_img_reset(base);
+ } else if (addr == 0x39c8u) {
+ /*
+ * MME-wrapper form (570.144): the driver emits
+ * CALL_MME_MACRO(57) =
+ * mmeCodeOGL_C597_LOAD_CONSTANT_BUFFER_BUG2548370
+ * with the argument stream inline in the run:
+ * [count][count dwords]. The macro writes the data
+ * words at the current fixed-CB offset and
+ * auto-increments, exactly like the native
+ * LOAD_CONSTANT_BUFFER(i) form.
+ */
+ u32 n;
+
+ memcpy(&n, buf + off + 4u, 4);
+ if (n > cnt - 1u)
+ n = cnt - 1u;
+ for (i = 0; i < n; i++) {
+ u64 doff = (u64)svc_gl_cb_off +
+ 4ULL * (u64)i;
+
+ if (doff + 4ULL > SVC_GL_CB_IMG_LIMIT)
+ continue;
+ memcpy(&w, buf + off + 8u + 4u * i, 4);
+ memcpy(svc_gl_cb_img + doff, &w, 4);
+ words++;
+ dirty = true;
+ }
+ runs++;
+ svc_gl_cb_off += 4u * n;
+ } else if (addr == 0x39d0u) {
+ /*
+ * CALL_MME_MACRO(58) =
+ * mmeCodeOGL_C597_LOAD_CONSTANT_BUFFER_OFFSET:
+ * argument stream is [offsetBytes].
+ */
+ memcpy(&w, buf + off + 4u, 4);
+ svc_gl_cb_off = w;
+ dirty = true;
} else if (addr >= 0x2390u && addr < 0x2390u + 0x1000u) {
u32 idx = (addr - 0x2390u) / 4u;