summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 5c124ef..e8df827 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -413,6 +413,13 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_VA_GOLDEN9_ATTRIBUTE_CB (GSP_PHYS_RMCALL_VA_GR_CTX + 0x2b0000ULL)
#define GSP_PHYS_RMCALL_VA_GOLDEN9_RTV_CB_GLOBAL (GSP_PHYS_RMCALL_VA_GR_CTX + 0xab0000ULL)
/*
+ * Mode 35 / R1: the PM ctxsw buffer has no VA in any earlier promote (the
+ * ladder's lane promote is PA-only), but the construct's per-VAS ctx-buffer
+ * VAS map (vaListFindVa, KGC shared +0x370) needs a booking entry for it;
+ * 0x170000 is the free slot between PRIV and UNR in the ctx window.
+ */
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_PM (GSP_PHYS_RMCALL_VA_GR_CTX + 0x170000ULL)
+/*
* Golden9k: every promoted context buffer is allocated with the size
* GET_ENGINE_CONTEXT_PROPERTIES reports for its engine (the client's own
* source for those sizes is the GSP static info; the same control returns
@@ -12943,6 +12950,85 @@ static int gsp_phys_rmcall_user_lane_main_promote(void __iomem *bar0)
return ret;
}
+/*
+ * Mode 35 / R1: the R2 capture's #879-shape VA-only promote on V7 - ten
+ * entries {5,11,9,10,4,6,0,3,1,2} with only gpu_virt_addr set (pa=0,
+ * size=0, physAttr=0, bInitialize=0, bNonmapped=0), exactly as the real
+ * client books its context buffers on the user channel after the construct.
+ * The server's per-entry mapped path writes {VAS -> VA} entries into the
+ * KernelGraphicsContext shared ctx-buffer VA lists; the 0xc5c0 construct's
+ * lookup (0x52cf9c0 -> vaListFindVa at pShared+0x370) needs the channel VAS
+ * present in those lists, which F2's mapped MAIN promote does not book (it
+ * writes the per-TSG ENGINE_CTX_DESCRIPTOR vaList instead). Sent after F2
+ * and before the TURING_COMPUTE_A construct; a refusal is logged and the
+ * construct still runs (best-effort).
+ */
+static int gsp_phys_rmcall_user_lane_va_promote(void __iomem *bar0)
+{
+ static const struct {
+ u16 buffer_id;
+ u64 va;
+ } entries[] = {
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_ATTRIBUTE_CB,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_ATTRIBUTE_CB },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_UNR_PRIV_MAP,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_UNR },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_FECS_EVENT,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_FECS },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PRIV_MAP,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PAGEPOOL,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_PAGEPOOL },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_RTV_CB_GLOBAL,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_RTV_CB_GLOBAL },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_MAIN,
+ GSP_PHYS_RMCALL_VA_GR_CTX },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_BUNDLE_CB,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_BUNDLE_CB },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PM,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_PM },
+ { GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PATCH,
+ GSP_PHYS_RMCALL_VA_GR_PATCH },
+ };
+ struct gsp_phys_rmcall_promote_params *p;
+ u32 rpc_result = 0, status = 0;
+ unsigned int i;
+ int ret;
+
+ p = kvzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+ p->engine_type = cpu_to_le32(GSP_PHYS_RMCALL_ENGINE_GR0);
+ p->h_client = cpu_to_le32(0);
+ p->ch_id = cpu_to_le32(0);
+ p->h_chan_client = cpu_to_le32(boot_stage.rmcall_client);
+ p->h_object = cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_USER_LANE);
+ p->h_virt_memory = cpu_to_le32(0);
+ p->virt_address = cpu_to_le64(0);
+ p->size = cpu_to_le64(0);
+ for (i = 0; i < ARRAY_SIZE(entries); i++)
+ gsp_phys_rmcall_promote_entry_fill(p, i, entries[i].buffer_id,
+ 0, entries[i].va, 0, 0, 0, 0);
+ p->entry_count = cpu_to_le32(ARRAY_SIZE(entries));
+
+ for (i = 0; i < ARRAY_SIZE(entries); i++)
+ pr_info("vgsp-boot: rm-call: mode 35 VA-only promote entry[%u]: bufferId=%u pa=0 va=0x%llx size=0 physAttr=0 bInitialize=0 bNonmapped=0 (R2 #879 shape)\n",
+ i, le16_to_cpu(p->entry[i].buffer_id),
+ le64_to_cpu(p->entry[i].gpu_virt_addr));
+
+ ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_subdevice,
+ GSP_PHYS_RMCALL_CTRL_GPU_PROMOTE_CTX,
+ p, sizeof(*p), 24, NULL, 0, &rpc_result, &status,
+ "GPU_PROMOTE_CTX (mode 35 VA-only booking, R1)");
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX mode 35 VA-only booking (R1): entryCount=%zu status=0x%x rpc_result=0x%x (hObject=V7 0x%x hChanClient=0x%x engineType=0x%x mainVa=0x%llx pmVa=0x%llx patchVa=0x%llx)\n",
+ ARRAY_SIZE(entries), status, rpc_result,
+ GSP_PHYS_RMCALL_HANDLE_USER_LANE, boot_stage.rmcall_client,
+ GSP_PHYS_RMCALL_ENGINE_GR0, GSP_PHYS_RMCALL_VA_GR_CTX,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_PM, GSP_PHYS_RMCALL_VA_GR_PATCH);
+ kvfree(p);
+ return ret;
+}
+
static int gsp_phys_rmcall_stage3(void __iomem *bar0)
{
struct gsp_phys_rmcall_vas_params vas;
@@ -13374,6 +13460,10 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0)
if (ret)
pr_err("vgsp-boot: rm-call: mode 35 MAIN mapped promote (F2) failed (%d); continuing best-effort (the construct result shows whether the initialized flag was set)\n",
ret);
+ ret = gsp_phys_rmcall_user_lane_va_promote(bar0);
+ if (ret)
+ pr_err("vgsp-boot: rm-call: mode 35 VA-only booking promote (R1) failed (%d); continuing best-effort (the construct result shows whether the per-VAS ctx-buffer maps were the gate)\n",
+ ret);
ret = gsp_phys_rmcall_alloc_gr_object_class(bar0,
GSP_PHYS_RMCALL_CLASS_COMPUTE,
GSP_PHYS_RMCALL_HANDLE_USER_LANE_GR_OBJ,