summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_fwsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_fwsec.c')
-rw-r--r--kernel/gsp_phys_fwsec.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/kernel/gsp_phys_fwsec.c b/kernel/gsp_phys_fwsec.c
index 83a68ed..c20758b 100644
--- a/kernel/gsp_phys_fwsec.c
+++ b/kernel/gsp_phys_fwsec.c
@@ -875,6 +875,28 @@ static int gsp_phys_fwsec_exec_with_loader(void __iomem *bar0,
GSP_PHYS_SEC2_BL_CODE_SIZE, bl_dst, block_count,
GSP_PHYS_SEC2_BL_START_TAG);
+ /*
+ * Read both staged regions back before the kick. A silent DMA failure
+ * leaves the falcon reading zeros, burns the full halt timeout and the
+ * boot only fails much later with no useful evidence; a mismatch here
+ * means the falcon is not accepting DMA, so fail open before STARTCPU.
+ */
+ {
+ u32 dmem_rd[4], imem_rd[4];
+
+ gsp_phys_falcon_dmem_read(bar0, GSP_PHYS_GSP_BASE, 0,
+ dmem_rd, 4);
+ gsp_phys_falcon_imem_read(bar0, GSP_PHYS_GSP_BASE, bl_dst,
+ imem_rd, 4);
+ if (memcmp(dmem_rd, &bl, sizeof(dmem_rd)) ||
+ memcmp(imem_rd, gsp_phys_sec2_bl_image, sizeof(imem_rd))) {
+ pr_err("gsp-phys-fwsec: staging not visible before kick (DMEM0 %08x/%08x/%08x/%08x IMEM %08x/%08x/%08x/%08x); the falcon is not accepting DMA - aborting before STARTCPU\n",
+ dmem_rd[0], dmem_rd[1], dmem_rd[2], dmem_rd[3],
+ imem_rd[0], imem_rd[1], imem_rd[2], imem_rd[3]);
+ return -EIO;
+ }
+ }
+
writel(GSP_PHYS_SEC2_BL_START_TAG << 8,
bar0 + GSP_PHYS_GSP_BASE + GSP_PHYS_FALCON_BOOTVEC);
cpuctl = readl(bar0 + GSP_PHYS_GSP_BASE + GSP_PHYS_FALCON_CPUCTL);