summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c195
1 files changed, 183 insertions, 12 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 36a71d0..daf0714 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -390,6 +390,29 @@ bool gsp_phys_boot_requested(void)
* 32 MB but the live server MAIN is 0x133000; PATCH lives at +0x140000 to
* stay clear of MAIN's tail). */
#define GSP_PHYS_RMCALL_VA_GR_PATCH (GSP_PHYS_RMCALL_VA_GR_CTX + 0x140000ULL)
+/*
+ * Golden9e (mode 25): the promoted FECS/PRIV/UNR buffers and the VA-only
+ * 3D globals are placed inside the same 2 MB window as MAIN/PATCH so every
+ * promoted VA is backed by the ctx PDB page tables (the real golden client
+ * mapped all of them in its VAS; the earlier mode-25 replay wrote unmapped
+ * VAs, which can fault the engine context load).
+ */
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_FECS (GSP_PHYS_RMCALL_VA_GR_CTX + 0x150000ULL)
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV (GSP_PHYS_RMCALL_VA_GR_CTX + 0x151000ULL)
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_UNR (GSP_PHYS_RMCALL_VA_GR_CTX + 0x152000ULL)
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_BUNDLE_CB (GSP_PHYS_RMCALL_VA_GR_CTX + 0x153000ULL)
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_PAGEPOOL (GSP_PHYS_RMCALL_VA_GR_CTX + 0x154000ULL)
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_ATTRIBUTE_CB (GSP_PHYS_RMCALL_VA_GR_CTX + 0x155000ULL)
+#define GSP_PHYS_RMCALL_VA_GOLDEN9_RTV_CB_GLOBAL (GSP_PHYS_RMCALL_VA_GR_CTX + 0x156000ULL)
+/*
+ * Golden9e server FBMEM allocations for the small promoted buffers (PATCH is
+ * sized by the PATCH engine geometry query; FECS/PRIV/UNR are one 4 KB page
+ * each). The real golden wire carried all of them in FBMEM.
+ */
+#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PATCH 0xcaf00064u
+#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_FECS 0xcaf00068u
+#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PRIV 0xcaf0006cu
+#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_UNR 0xcaf00070u
/* GR context-promote bisection modes (gsp_phys_rmcall_gr_promote). */
#define GSP_PHYS_RMCALL_GR_PROMOTE_OFF 0u
@@ -1483,6 +1506,8 @@ static struct gsp_phys_boot_stage {
bool rmcall_ctx_valid;
/* mode 11: the context buffer is a server-owned FBMEM allocation */
bool rmcall_ctx_fbmem;
+ /* mode 25 golden9e: PATCH/FECS/PRIV/UNR are server-owned FBMEM too */
+ bool rmcall_golden_fb_aux;
u64 rmcall_ctx_pa; /* context buffer DMA base */
u64 rmcall_ctx_va; /* promoted GPU VA window base */
u32 rmcall_ctx_size; /* promoted total size */
@@ -2175,6 +2200,7 @@ static void gsp_phys_rmcall_reset(void)
boot_stage.rmcall_ctx_prepared = false;
boot_stage.rmcall_ctx_valid = false;
boot_stage.rmcall_ctx_fbmem = false;
+ boot_stage.rmcall_golden_fb_aux = false;
boot_stage.rmcall_ctx_pa = 0;
boot_stage.rmcall_ctx_va = 0;
boot_stage.rmcall_ctx_size = 0;
@@ -8280,6 +8306,55 @@ static void gsp_phys_rmcall_pdb_build(void)
&boot_stage.rmcall_ctx_pt[pt_page],
0) + (size_t)pt_slot * 8);
}
+ /*
+ * Golden9e: map the FBMEM PATCH/FECS/PRIV/UNR buffers at their
+ * promoted VAs in the same 2 MB window as MAIN (window 17) with
+ * VIDMEM PTEs. Every slot used here is above MAIN's tail
+ * (0x2200000 + 0x133000 = slot 0x133) and distinct.
+ */
+ if (boot_stage.rmcall_golden_fb_aux) {
+ u8 *ptv = gsp_phys_chunk_page_va(
+ &boot_stage.rmcall_ctx_pt[0], 0);
+ u32 slot, npages;
+
+ npages = DIV_ROUND_UP(boot_stage.rmcall_patch_size,
+ GSP_PHYS_PAGE_SIZE);
+ slot = (u32)((GSP_PHYS_RMCALL_VA_GR_PATCH >> 12) &
+ 0x1ffu);
+ for (i = 0; i < npages; i++)
+ put_unaligned_le64(
+ gsp_phys_rmcall_pte_vid(
+ boot_stage.rmcall_patch_pa +
+ (u64)i * GSP_PHYS_PAGE_SIZE),
+ ptv + (size_t)(slot + i) * 8);
+ slot = (u32)((GSP_PHYS_RMCALL_VA_GOLDEN9_FECS >> 12) &
+ 0x1ffu);
+ put_unaligned_le64(
+ gsp_phys_rmcall_pte_vid(
+ boot_stage.rmcall_fecs_pa),
+ ptv + (size_t)slot * 8);
+ slot = (u32)((GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV >> 12) &
+ 0x1ffu);
+ put_unaligned_le64(
+ gsp_phys_rmcall_pte_vid(
+ boot_stage.rmcall_priv_pa),
+ ptv + (size_t)slot * 8);
+ slot = (u32)((GSP_PHYS_RMCALL_VA_GOLDEN9_UNR >> 12) &
+ 0x1ffu);
+ put_unaligned_le64(
+ gsp_phys_rmcall_pte_vid(
+ boot_stage.rmcall_unrestricted_pa),
+ ptv + (size_t)slot * 8);
+ pr_info("vgsp-boot: rm-call: GOLDEN9E PDB aux mapped: patch va=0x%llx pages=%u (pa=0x%llx) fecs va=0x%llx (pa=0x%llx) priv va=0x%llx (pa=0x%llx) unr va=0x%llx (pa=0x%llx) (VIDMEM PTEs)\n",
+ GSP_PHYS_RMCALL_VA_GR_PATCH, npages,
+ boot_stage.rmcall_patch_pa,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_FECS,
+ boot_stage.rmcall_fecs_pa,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV,
+ boot_stage.rmcall_priv_pa,
+ GSP_PHYS_RMCALL_VA_GOLDEN9_UNR,
+ boot_stage.rmcall_unrestricted_pa);
+ }
pr_info("vgsp-boot: rm-call: GR ctx PDB mapped: va=0x%llx size=0x%x pages=%u ptPages=%u pd0Entries=%u..%u (%s; fresh slots above the scratch pool; no fetched line rewritten)\n",
GSP_PHYS_RMCALL_VA_GR_CTX, boot_stage.rmcall_ctx_size,
boot_stage.rmcall_ctx_pages,
@@ -8338,6 +8413,82 @@ static void gsp_phys_rmcall_pdb_build(void)
}
/*
+ * Mode-25 golden9e: allocate the promoted PATCH/FECS/PRIV/UNR context
+ * buffers in server FBMEM (the real golden wire carried FBMEM for every
+ * context buffer; the earlier host-sysmem substitution is a documented
+ * deviation that leaves the engine's context load reading host memory).
+ * PATCH is sized by the PATCH engine geometry query (engineId 0x10); the
+ * three global buffers are one 4 KB page each. Runs before
+ * gsp_phys_rmcall_pdb_build() so the PDB can map every promoted VA in the
+ * same 2 MB window as MAIN. Idempotent; a failure aborts the ladder.
+ */
+static int gsp_phys_rmcall_golden9_fb_aux_prepare(void __iomem *bar0)
+{
+ struct gsp_phys_rmcall_engine_ctx_props props;
+ u32 raw, rpc_result = 0, status = 0;
+ u64 fb = 0;
+ int ret;
+
+ if (boot_stage.rmcall_golden_fb_aux)
+ return 0;
+
+ memset(&props, 0, sizeof(props));
+ props.engine_id = cpu_to_le32(GSP_PHYS_RMCALL_GR_PATCH_ENGINE_ID);
+ ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_device,
+ GSP_PHYS_RMCALL_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES,
+ &props, sizeof(props), 24 + sizeof(props),
+ &props, sizeof(props), &rpc_result, &status,
+ "GR_GET_ENGINE_CONTEXT_PROPERTIES (golden9e PATCH)");
+ raw = le32_to_cpu(props.size);
+ pr_info("vgsp-boot: rm-call: GOLDEN9E PATCH geometry: engineId=0x%x rawSize=0x%x alignment=0x%x status=0x%x rpc_result=0x%x\n",
+ GSP_PHYS_RMCALL_GR_PATCH_ENGINE_ID, raw,
+ le32_to_cpu(props.alignment), status, rpc_result);
+ if (ret)
+ return ret;
+ if (!raw || raw > GSP_PHYS_RMCALL_GR_CTX_MAX_SIZE) {
+ pr_err("vgsp-boot: rm-call: GOLDEN9E PATCH size 0x%x is outside the sanity bound; aborting the ladder with no retry\n",
+ raw);
+ return -E2BIG;
+ }
+ ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PATCH, raw, &fb,
+ "GOLDEN9E PATCH");
+ if (ret)
+ return ret;
+ boot_stage.rmcall_patch_pa = fb;
+ boot_stage.rmcall_patch_size = raw;
+ boot_stage.rmcall_patch_prepared = true;
+
+ ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_FECS, 0x1000, &fb,
+ "GOLDEN9E FECS_EVENT");
+ if (ret)
+ return ret;
+ boot_stage.rmcall_fecs_pa = fb;
+
+ ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PRIV, 0x1000, &fb,
+ "GOLDEN9E PRIV_ACCESS_MAP");
+ if (ret)
+ return ret;
+ boot_stage.rmcall_priv_pa = fb;
+
+ ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_UNR, 0x1000, &fb,
+ "GOLDEN9E UNR_PRIV_ACCESS_MAP");
+ if (ret)
+ return ret;
+ boot_stage.rmcall_unrestricted_pa = fb;
+
+ boot_stage.rmcall_golden_fb_aux = true;
+ pr_info("vgsp-boot: rm-call: GOLDEN9E FBMEM aux buffers ready: patch pa=0x%llx size=0x%x fecs=0x%llx priv=0x%llx unr=0x%llx (server FBMEM, all mapped in the ctx PDB window)\n",
+ boot_stage.rmcall_patch_pa, boot_stage.rmcall_patch_size,
+ boot_stage.rmcall_fecs_pa, boot_stage.rmcall_priv_pa,
+ boot_stage.rmcall_unrestricted_pa);
+ return 0;
+}
+
+/*
* H1 GR context bind, step 1-2: query the engine-context geometry, then
* allocate the zeroed, physically contiguous sysmem context buffer the
* promote installs. GR0 only (the caller gates); any failure aborts the
@@ -8522,6 +8673,19 @@ static int gsp_phys_rmcall_gr_ctx_prepare(void __iomem *bar0)
boot_stage.rmcall_ctx_fbmem ?
"server FBMEM, VIDMEM aperture PTEs" :
"host sysmem, contiguous, zeroed");
+ /*
+ * Mode-25 golden9e: prepare the FBMEM PATCH/FECS/PRIV/UNR buffers now,
+ * before the PDB build maps their promoted VAs.
+ */
+ if (boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9) {
+ ret = gsp_phys_rmcall_golden9_fb_aux_prepare(bar0);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: GOLDEN9E FBMEM aux prepare failed (%d); aborting the ladder with no retry\n",
+ ret);
+ return ret;
+ }
+ }
return 0;
err_free:
@@ -8787,8 +8951,8 @@ static void gsp_phys_rmcall_gr_fwclient_small_prepare(void)
static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0)
{
struct gsp_phys_rmcall_promote_params *p;
- u64 bk = GSP_PHYS_RMCALL_VA_GR_CTX + 0x400000ULL;
u32 attr = GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR;
+ u32 fattr;
u32 rpc_result = 0, status = 0;
unsigned int i;
int ret;
@@ -8800,10 +8964,13 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0)
boot_stage.rmcall_ctx_pa, boot_stage.rmcall_ctx_size);
return -EINVAL;
}
- ret = gsp_phys_rmcall_gr_patch_prepare(bar0);
+ /*
+ * Golden9e: PATCH/FECS/PRIV/UNR are server FBMEM allocations prepared
+ * with the MAIN (gr_ctx_prepare, before the PDB build). Idempotent.
+ */
+ ret = gsp_phys_rmcall_golden9_fb_aux_prepare(bar0);
if (ret)
return ret;
- gsp_phys_rmcall_gr_fwclient_small_prepare();
if (!boot_stage.rmcall_patch_pa || !boot_stage.rmcall_fecs_pa ||
!boot_stage.rmcall_priv_pa ||
!boot_stage.rmcall_unrestricted_pa) {
@@ -8813,6 +8980,8 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0)
boot_stage.rmcall_unrestricted_pa);
return -ENOMEM;
}
+ fattr = boot_stage.rmcall_golden_fb_aux ?
+ GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR_FB : attr;
p = kvzalloc(sizeof(*p), GFP_KERNEL);
if (!p)
@@ -8834,29 +9003,31 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0)
gsp_phys_rmcall_promote_entry_fill(p, 1,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PATCH,
boot_stage.rmcall_patch_pa, GSP_PHYS_RMCALL_VA_GR_PATCH,
- boot_stage.rmcall_patch_size, attr, 1, 0);
+ boot_stage.rmcall_patch_size, fattr, 1, 0);
gsp_phys_rmcall_promote_entry_fill(p, 2,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_BUNDLE_CB,
- 0, bk + 0x2000ULL, 0, 0, 0, 0);
+ 0, GSP_PHYS_RMCALL_VA_GOLDEN9_BUNDLE_CB, 0, 0, 0, 0);
gsp_phys_rmcall_promote_entry_fill(p, 3,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PAGEPOOL,
- 0, bk + 0x3000ULL, 0, 0, 0, 0);
+ 0, GSP_PHYS_RMCALL_VA_GOLDEN9_PAGEPOOL, 0, 0, 0, 0);
gsp_phys_rmcall_promote_entry_fill(p, 4,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_ATTRIBUTE_CB,
- 0, bk + 0x4000ULL, 0, 0, 0, 0);
+ 0, GSP_PHYS_RMCALL_VA_GOLDEN9_ATTRIBUTE_CB, 0, 0, 0, 0);
gsp_phys_rmcall_promote_entry_fill(p, 5,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_RTV_CB_GLOBAL,
- 0, bk + 0x5000ULL, 0, 0, 0, 0);
+ 0, GSP_PHYS_RMCALL_VA_GOLDEN9_RTV_CB_GLOBAL, 0, 0, 0, 0);
gsp_phys_rmcall_promote_entry_fill(p, 6,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_FECS_EVENT,
- boot_stage.rmcall_fecs_pa, bk + 0x6000ULL, 0x1000u, attr, 1, 0);
+ boot_stage.rmcall_fecs_pa, GSP_PHYS_RMCALL_VA_GOLDEN9_FECS,
+ 0x1000u, fattr, 1, 0);
gsp_phys_rmcall_promote_entry_fill(p, 7,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PRIV_MAP,
- boot_stage.rmcall_priv_pa, bk + 0x7000ULL, 0x1000u, attr, 1, 0);
+ boot_stage.rmcall_priv_pa, GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV,
+ 0x1000u, fattr, 1, 0);
gsp_phys_rmcall_promote_entry_fill(p, 8,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_UNR_PRIV_MAP,
- boot_stage.rmcall_unrestricted_pa, bk + 0x8000ULL,
- 0x1000u, attr, 1, 0);
+ boot_stage.rmcall_unrestricted_pa, GSP_PHYS_RMCALL_VA_GOLDEN9_UNR,
+ 0x1000u, fattr, 1, 0);
for (i = 0; i < 9; i++)
pr_info("vgsp-boot: rm-call: PROMOTE_CTX golden9 entry[%u]: bufferId=%u pa=0x%llx va=0x%llx size=0x%llx physAttr=0x%x bInitialize=%u bNonmapped=%u%s\n",