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.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 5a5287f..8bf94d8 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -12707,6 +12707,46 @@ static int gsp_phys_rmcall_user_lane_notifier(void __iomem *bar0)
u64 base = 0;
int ret;
+ /*
+ * m83: host-visible sysmem error notifier (gsp_phys_rmcall_gr_notifier_sys;
+ * default 0). The RM writes asynchronous channel error records into the
+ * context's error notifier; with the FBMEM aperture nothing can read them
+ * (the m66..m82 GPC exception has never been decodable). A sysmem chunk
+ * registered as the hObjectError memory object makes the RM's own fault
+ * record readable from the host.
+ */
+ if (gsp_phys_rmcall_gr_notifier_sys_value()) {
+ struct gsp_phys_boot_chunk *n =
+ &boot_stage.rmcall_user_lane_notifier;
+
+ if (!boot_stage.pdev) {
+ pr_err("vgsp-boot: rm-call: mode 35 sysmem error-notifier: no claimed pci_dev\n");
+ return -EINVAL;
+ }
+ if (!n->pages) {
+ ret = gsp_phys_chunk_alloc(boot_stage.pdev, n,
+ GSP_PHYS_RMCALL_NOTIFIER_SIZE /
+ GSP_PHYS_PAGE_SIZE);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: mode 35 sysmem error-notifier chunk allocation failed (%d)\n",
+ ret);
+ return ret;
+ }
+ gsp_phys_chunk_zero(n);
+ }
+ ret = gsp_phys_rmcall_register_chunk(bar0, n,
+ GSP_PHYS_RMCALL_HANDLE_USER_LANE_NOTIFIER,
+ "mode 35 user-lane error notifier (sysmem m83)");
+ if (ret)
+ return ret;
+ base = (u64)gsp_phys_chunk_page_dma(n, 0);
+ boot_stage.rmcall_user_lane_notifier_pa = base;
+ pr_info("vgsp-boot: rm-call: mode 35 user-lane error notifier: hObject=0x%x SYSMEM pa=0x%llx size=0x%x (host-readable RM fault records; m83)\n",
+ GSP_PHYS_RMCALL_HANDLE_USER_LANE_NOTIFIER, base,
+ GSP_PHYS_RMCALL_NOTIFIER_SIZE);
+ return 0;
+ }
+
ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
GSP_PHYS_RMCALL_HANDLE_USER_LANE_NOTIFIER,
GSP_PHYS_RMCALL_NOTIFIER_SIZE, &base,
@@ -12869,7 +12909,9 @@ static int gsp_phys_rmcall_alloc_user_lane_channel(void __iomem *bar0)
ch.error_notifier_mem.size =
cpu_to_le64(GSP_PHYS_RMCALL_NOTIFIER_SIZE);
ch.error_notifier_mem.address_space =
- cpu_to_le32(GSP_PHYS_RMCALL_ADDR_FBMEM);
+ cpu_to_le32(gsp_phys_rmcall_gr_notifier_sys_value() ?
+ GSP_PHYS_RMCALL_ADDR_SYSMEM :
+ GSP_PHYS_RMCALL_ADDR_FBMEM);
ch.error_notifier_mem.cache_attrib =
cpu_to_le32(GSP_PHYS_RMCALL_CACHE_UNCACHED);
@@ -16660,6 +16702,31 @@ gr_page_unmapped:
p1[0], p1[1], p1[2], p1[3],
p1[4], p1[5], p1[6], p1[7]);
}
+ /*
+ * m83: the RM's asynchronous channel-error reports
+ * land in the error notifier; with the sysmem
+ * aperture they are host-readable after a failure.
+ */
+ if (gsp_phys_rmcall_gr_notifier_sys_value()) {
+ struct gsp_phys_boot_chunk *nt =
+ &boot_stage.rmcall_user_lane_notifier;
+ const u32 *np = nt->pages ?
+ gsp_phys_chunk_page_va(nt, 0) : NULL;
+ u32 i;
+
+ if (np) {
+ for (i = 0; i < 32; i += 8)
+ pr_info("vgsp-gr: post-mortem notifier w%u..%u = %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ i, i + 7,
+ np[i], np[i + 1],
+ np[i + 2],
+ np[i + 3],
+ np[i + 4],
+ np[i + 5],
+ np[i + 6],
+ np[i + 7]);
+ }
+ }
{
u8 *qp2 = qmd_dst_mem ? qmd_dst_mem :
(req->qmd_hpa ?