Loading drivers/soc/qcom/peripheral-loader.c +88 −37 Original line number Diff line number Diff line Loading @@ -141,28 +141,50 @@ struct pil_priv { static int pil_do_minidump(struct pil_desc *desc, void *ramdump_dev) { struct md_ss_region __iomem *region_info; struct md_ss_region __iomem *region_info_ss; struct md_ss_region __iomem *region_info_pdr; struct ramdump_segment *ramdump_segs, *s; struct pil_priv *priv = desc->priv; void __iomem *subsys_segtable_base; void __iomem *subsys_segtable_base_ss; void __iomem *subsys_segtable_base_pdr; u64 ss_region_ptr = 0; void __iomem *offset; int ss_mdump_seg_cnt; void __iomem *offset_ss; void __iomem *offset_pdr; int ss_mdump_seg_cnt_ss = 0, ss_mdump_seg_cnt_pdr = 0, total_segs; int ss_valid_seg_cnt; int ret, i; ss_region_ptr = desc->minidump->md_ss_smem_regions_baseptr; if (!ramdump_dev) return -ENODEV; ss_mdump_seg_cnt = desc->minidump->ss_region_count; subsys_segtable_base = ss_region_ptr = desc->minidump_ss->md_ss_smem_regions_baseptr; ss_mdump_seg_cnt_ss = desc->minidump_ss->ss_region_count; subsys_segtable_base_ss = ioremap((unsigned long)ss_region_ptr, ss_mdump_seg_cnt_ss * sizeof(struct md_ss_region)); region_info_ss = (struct md_ss_region __iomem *)subsys_segtable_base_ss; if (!region_info_ss) return -EINVAL; pr_info("Minidump : SS Segments in minidump 0x%x\n", ss_mdump_seg_cnt_ss); if (desc->minidump_pdr && (desc->minidump_pdr->md_ss_enable_status == MD_SS_ENABLED)) { ss_region_ptr = desc->minidump_pdr->md_ss_smem_regions_baseptr; ss_mdump_seg_cnt_pdr = desc->minidump_pdr->ss_region_count; subsys_segtable_base_pdr = ioremap((unsigned long)ss_region_ptr, ss_mdump_seg_cnt * sizeof(struct md_ss_region)); region_info = (struct md_ss_region __iomem *)subsys_segtable_base; if (!region_info) ss_mdump_seg_cnt_pdr * sizeof(struct md_ss_region)); region_info_pdr = (struct md_ss_region __iomem *)subsys_segtable_base_pdr; if (!region_info_pdr) return -EINVAL; pr_info("Minidump : Segments in minidump 0x%x\n", ss_mdump_seg_cnt); ramdump_segs = kcalloc(ss_mdump_seg_cnt, pr_info("Minidump : PDR Segments in minidump 0x%x\n", ss_mdump_seg_cnt_pdr); } total_segs = ss_mdump_seg_cnt_ss + ss_mdump_seg_cnt_pdr; ramdump_segs = kcalloc(total_segs, sizeof(*ramdump_segs), GFP_KERNEL); if (!ramdump_segs) return -ENOMEM; Loading @@ -172,24 +194,47 @@ static int pil_do_minidump(struct pil_desc *desc, void *ramdump_dev) (priv->region_end - priv->region_start)); s = ramdump_segs; ss_valid_seg_cnt = ss_mdump_seg_cnt; for (i = 0; i < ss_mdump_seg_cnt; i++) { memcpy(&offset, ®ion_info, sizeof(region_info)); offset = offset + sizeof(region_info->name) + sizeof(region_info->seq_num); if (__raw_readl(offset) == MD_REGION_VALID) { memcpy(&s->name, ®ion_info, sizeof(region_info)); offset = offset + sizeof(region_info->md_valid); s->address = __raw_readl(offset); offset = offset + sizeof(region_info->region_base_address); s->size = __raw_readl(offset); ss_valid_seg_cnt = total_segs; for (i = 0; i < ss_mdump_seg_cnt_ss; i++) { memcpy(&offset_ss, ®ion_info_ss, sizeof(region_info_ss)); offset_ss = offset_ss + sizeof(region_info_ss->name) + sizeof(region_info_ss->seq_num); if (__raw_readl(offset_ss) == MD_REGION_VALID) { memcpy(&s->name, ®ion_info_ss, sizeof(region_info_ss)); offset_ss = offset_ss + sizeof(region_info_ss->md_valid); s->address = __raw_readl(offset_ss); offset_ss = offset_ss + sizeof(region_info_ss->region_base_address); s->size = __raw_readl(offset_ss); pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n", s->name, s->address, (unsigned int)s->size); } else ss_valid_seg_cnt--; s++; region_info++; region_info_ss++; } for (i = 0; i < ss_mdump_seg_cnt_pdr; i++) { memcpy(&offset_pdr, ®ion_info_pdr, sizeof(region_info_pdr)); offset_pdr = offset_pdr + sizeof(region_info_pdr->name) + sizeof(region_info_pdr->seq_num); if (__raw_readl(offset_pdr) == MD_REGION_VALID) { memcpy(&s->name, ®ion_info_pdr, sizeof(region_info_pdr)); offset_pdr = offset_pdr + sizeof(region_info_pdr->md_valid); s->address = __raw_readl(offset_pdr); offset_pdr = offset_pdr + sizeof(region_info_pdr->region_base_address); s->size = __raw_readl(offset_pdr); pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n", s->name, s->address, (unsigned int)s->size); } else ss_valid_seg_cnt--; s++; region_info_pdr++; } ret = do_minidump(ramdump_dev, ramdump_segs, ss_valid_seg_cnt); kfree(ramdump_segs); Loading Loading @@ -219,27 +264,27 @@ int pil_do_ramdump(struct pil_desc *desc, struct pil_seg *seg; int count = 0, ret; if (desc->minidump) { if (desc->minidump_ss) { pr_info("Minidump : md_ss_toc->md_ss_toc_init is 0x%x\n", (unsigned int)desc->minidump->md_ss_toc_init); (unsigned int)desc->minidump_ss->md_ss_toc_init); pr_info("Minidump : md_ss_toc->md_ss_enable_status is 0x%x\n", (unsigned int)desc->minidump->md_ss_enable_status); (unsigned int)desc->minidump_ss->md_ss_enable_status); pr_info("Minidump : md_ss_toc->encryption_status is 0x%x\n", (unsigned int)desc->minidump->encryption_status); (unsigned int)desc->minidump_ss->encryption_status); pr_info("Minidump : md_ss_toc->ss_region_count is 0x%x\n", (unsigned int)desc->minidump->ss_region_count); (unsigned int)desc->minidump_ss->ss_region_count); pr_info("Minidump : md_ss_toc->md_ss_smem_regions_baseptr is 0x%x\n", (unsigned int) desc->minidump->md_ss_smem_regions_baseptr); desc->minidump_ss->md_ss_smem_regions_baseptr); /** * Collect minidump if SS ToC is valid and segment table * is initialized in memory and encryption status is set. */ if ((desc->minidump->md_ss_smem_regions_baseptr != 0) && (desc->minidump->md_ss_toc_init == true) && (desc->minidump->md_ss_enable_status == if ((desc->minidump_ss->md_ss_smem_regions_baseptr != 0) && (desc->minidump_ss->md_ss_toc_init == true) && (desc->minidump_ss->md_ss_enable_status == MD_SS_ENABLED)) { if (desc->minidump->encryption_status == if (desc->minidump_ss->encryption_status == MD_SS_ENCR_DONE) { pr_info("Minidump : Dumping for %s\n", desc->name); Loading Loading @@ -1184,9 +1229,15 @@ int pil_desc_init(struct pil_desc *desc) else { if (g_md_toc && g_md_toc->md_toc_init == true) { ss_toc_addr = &g_md_toc->md_ss_toc[desc->minidump_id]; pr_debug("Minidump : ss_toc_addr is %pa and desc->minidump_id is %d\n", pr_debug("Minidump : ss_toc_addr for ss is %pa and desc->minidump_id is %d\n", &ss_toc_addr, desc->minidump_id); memcpy(&desc->minidump_ss, &ss_toc_addr, sizeof(ss_toc_addr)); ss_toc_addr = &g_md_toc->md_ss_toc[desc->minidump_id + 1]; pr_debug("Minidump : ss_toc_addr for pdr is %pa and desc->minidump_id is %d\n", &ss_toc_addr, desc->minidump_id); memcpy(&desc->minidump, &ss_toc_addr, memcpy(&desc->minidump_pdr, &ss_toc_addr, sizeof(ss_toc_addr)); } } Loading drivers/soc/qcom/peripheral-loader.h +2 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,8 @@ struct pil_desc { bool signal_aop; struct mbox_client cl; struct mbox_chan *mbox; struct md_ss_toc *minidump; struct md_ss_toc *minidump_ss; struct md_ss_toc *minidump_pdr; int minidump_id; }; Loading drivers/soc/qcom/pil-msa.c +7 −7 Original line number Diff line number Diff line Loading @@ -582,7 +582,7 @@ static int pil_mss_reset(struct pil_desc *pil) if (ret) goto err_clks; if (!pil->minidump || !pil->modem_ssr) { if (!pil->minidump_ss || !pil->modem_ssr) { /* Save state of modem debug register before full reset */ debug_val = readl_relaxed(drv->reg_base + QDSP6SS_DBG_CFG); } Loading @@ -595,7 +595,7 @@ static int pil_mss_reset(struct pil_desc *pil) if (ret) goto err_restart; if (!pil->minidump || !pil->modem_ssr) { if (!pil->minidump_ss || !pil->modem_ssr) { writel_relaxed(debug_val, drv->reg_base + QDSP6SS_DBG_CFG); if (modem_dbg_cfg) writel_relaxed(modem_dbg_cfg, Loading Loading @@ -799,10 +799,10 @@ int pil_mss_debug_reset(struct pil_desc *pil) struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc); int ret; if (!pil->minidump) if (!pil->minidump_ss) return 0; if (pil->minidump) { if (pil->minidump->md_ss_enable_status != MD_SS_ENABLED) if (pil->minidump_ss) { if (pil->minidump_ss->md_ss_enable_status != MD_SS_ENABLED) return 0; } Loading @@ -814,7 +814,7 @@ int pil_mss_debug_reset(struct pil_desc *pil) if (ret) return ret; if (pil->minidump) { if (pil->minidump_ss) { writel_relaxed(0x1, drv->reg_base + QDSP6SS_NMI_CFG); /* Let write complete before proceeding */ mb(); Loading @@ -837,7 +837,7 @@ int pil_mss_debug_reset(struct pil_desc *pil) */ pr_info("Minidump: waiting encryption to complete\n"); msleep(10000); if (pil->minidump) { if (pil->minidump_ss) { writel_relaxed(0x2, drv->reg_base + QDSP6SS_NMI_CFG); /* Let write complete before proceeding */ mb(); Loading Loading
drivers/soc/qcom/peripheral-loader.c +88 −37 Original line number Diff line number Diff line Loading @@ -141,28 +141,50 @@ struct pil_priv { static int pil_do_minidump(struct pil_desc *desc, void *ramdump_dev) { struct md_ss_region __iomem *region_info; struct md_ss_region __iomem *region_info_ss; struct md_ss_region __iomem *region_info_pdr; struct ramdump_segment *ramdump_segs, *s; struct pil_priv *priv = desc->priv; void __iomem *subsys_segtable_base; void __iomem *subsys_segtable_base_ss; void __iomem *subsys_segtable_base_pdr; u64 ss_region_ptr = 0; void __iomem *offset; int ss_mdump_seg_cnt; void __iomem *offset_ss; void __iomem *offset_pdr; int ss_mdump_seg_cnt_ss = 0, ss_mdump_seg_cnt_pdr = 0, total_segs; int ss_valid_seg_cnt; int ret, i; ss_region_ptr = desc->minidump->md_ss_smem_regions_baseptr; if (!ramdump_dev) return -ENODEV; ss_mdump_seg_cnt = desc->minidump->ss_region_count; subsys_segtable_base = ss_region_ptr = desc->minidump_ss->md_ss_smem_regions_baseptr; ss_mdump_seg_cnt_ss = desc->minidump_ss->ss_region_count; subsys_segtable_base_ss = ioremap((unsigned long)ss_region_ptr, ss_mdump_seg_cnt_ss * sizeof(struct md_ss_region)); region_info_ss = (struct md_ss_region __iomem *)subsys_segtable_base_ss; if (!region_info_ss) return -EINVAL; pr_info("Minidump : SS Segments in minidump 0x%x\n", ss_mdump_seg_cnt_ss); if (desc->minidump_pdr && (desc->minidump_pdr->md_ss_enable_status == MD_SS_ENABLED)) { ss_region_ptr = desc->minidump_pdr->md_ss_smem_regions_baseptr; ss_mdump_seg_cnt_pdr = desc->minidump_pdr->ss_region_count; subsys_segtable_base_pdr = ioremap((unsigned long)ss_region_ptr, ss_mdump_seg_cnt * sizeof(struct md_ss_region)); region_info = (struct md_ss_region __iomem *)subsys_segtable_base; if (!region_info) ss_mdump_seg_cnt_pdr * sizeof(struct md_ss_region)); region_info_pdr = (struct md_ss_region __iomem *)subsys_segtable_base_pdr; if (!region_info_pdr) return -EINVAL; pr_info("Minidump : Segments in minidump 0x%x\n", ss_mdump_seg_cnt); ramdump_segs = kcalloc(ss_mdump_seg_cnt, pr_info("Minidump : PDR Segments in minidump 0x%x\n", ss_mdump_seg_cnt_pdr); } total_segs = ss_mdump_seg_cnt_ss + ss_mdump_seg_cnt_pdr; ramdump_segs = kcalloc(total_segs, sizeof(*ramdump_segs), GFP_KERNEL); if (!ramdump_segs) return -ENOMEM; Loading @@ -172,24 +194,47 @@ static int pil_do_minidump(struct pil_desc *desc, void *ramdump_dev) (priv->region_end - priv->region_start)); s = ramdump_segs; ss_valid_seg_cnt = ss_mdump_seg_cnt; for (i = 0; i < ss_mdump_seg_cnt; i++) { memcpy(&offset, ®ion_info, sizeof(region_info)); offset = offset + sizeof(region_info->name) + sizeof(region_info->seq_num); if (__raw_readl(offset) == MD_REGION_VALID) { memcpy(&s->name, ®ion_info, sizeof(region_info)); offset = offset + sizeof(region_info->md_valid); s->address = __raw_readl(offset); offset = offset + sizeof(region_info->region_base_address); s->size = __raw_readl(offset); ss_valid_seg_cnt = total_segs; for (i = 0; i < ss_mdump_seg_cnt_ss; i++) { memcpy(&offset_ss, ®ion_info_ss, sizeof(region_info_ss)); offset_ss = offset_ss + sizeof(region_info_ss->name) + sizeof(region_info_ss->seq_num); if (__raw_readl(offset_ss) == MD_REGION_VALID) { memcpy(&s->name, ®ion_info_ss, sizeof(region_info_ss)); offset_ss = offset_ss + sizeof(region_info_ss->md_valid); s->address = __raw_readl(offset_ss); offset_ss = offset_ss + sizeof(region_info_ss->region_base_address); s->size = __raw_readl(offset_ss); pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n", s->name, s->address, (unsigned int)s->size); } else ss_valid_seg_cnt--; s++; region_info++; region_info_ss++; } for (i = 0; i < ss_mdump_seg_cnt_pdr; i++) { memcpy(&offset_pdr, ®ion_info_pdr, sizeof(region_info_pdr)); offset_pdr = offset_pdr + sizeof(region_info_pdr->name) + sizeof(region_info_pdr->seq_num); if (__raw_readl(offset_pdr) == MD_REGION_VALID) { memcpy(&s->name, ®ion_info_pdr, sizeof(region_info_pdr)); offset_pdr = offset_pdr + sizeof(region_info_pdr->md_valid); s->address = __raw_readl(offset_pdr); offset_pdr = offset_pdr + sizeof(region_info_pdr->region_base_address); s->size = __raw_readl(offset_pdr); pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n", s->name, s->address, (unsigned int)s->size); } else ss_valid_seg_cnt--; s++; region_info_pdr++; } ret = do_minidump(ramdump_dev, ramdump_segs, ss_valid_seg_cnt); kfree(ramdump_segs); Loading Loading @@ -219,27 +264,27 @@ int pil_do_ramdump(struct pil_desc *desc, struct pil_seg *seg; int count = 0, ret; if (desc->minidump) { if (desc->minidump_ss) { pr_info("Minidump : md_ss_toc->md_ss_toc_init is 0x%x\n", (unsigned int)desc->minidump->md_ss_toc_init); (unsigned int)desc->minidump_ss->md_ss_toc_init); pr_info("Minidump : md_ss_toc->md_ss_enable_status is 0x%x\n", (unsigned int)desc->minidump->md_ss_enable_status); (unsigned int)desc->minidump_ss->md_ss_enable_status); pr_info("Minidump : md_ss_toc->encryption_status is 0x%x\n", (unsigned int)desc->minidump->encryption_status); (unsigned int)desc->minidump_ss->encryption_status); pr_info("Minidump : md_ss_toc->ss_region_count is 0x%x\n", (unsigned int)desc->minidump->ss_region_count); (unsigned int)desc->minidump_ss->ss_region_count); pr_info("Minidump : md_ss_toc->md_ss_smem_regions_baseptr is 0x%x\n", (unsigned int) desc->minidump->md_ss_smem_regions_baseptr); desc->minidump_ss->md_ss_smem_regions_baseptr); /** * Collect minidump if SS ToC is valid and segment table * is initialized in memory and encryption status is set. */ if ((desc->minidump->md_ss_smem_regions_baseptr != 0) && (desc->minidump->md_ss_toc_init == true) && (desc->minidump->md_ss_enable_status == if ((desc->minidump_ss->md_ss_smem_regions_baseptr != 0) && (desc->minidump_ss->md_ss_toc_init == true) && (desc->minidump_ss->md_ss_enable_status == MD_SS_ENABLED)) { if (desc->minidump->encryption_status == if (desc->minidump_ss->encryption_status == MD_SS_ENCR_DONE) { pr_info("Minidump : Dumping for %s\n", desc->name); Loading Loading @@ -1184,9 +1229,15 @@ int pil_desc_init(struct pil_desc *desc) else { if (g_md_toc && g_md_toc->md_toc_init == true) { ss_toc_addr = &g_md_toc->md_ss_toc[desc->minidump_id]; pr_debug("Minidump : ss_toc_addr is %pa and desc->minidump_id is %d\n", pr_debug("Minidump : ss_toc_addr for ss is %pa and desc->minidump_id is %d\n", &ss_toc_addr, desc->minidump_id); memcpy(&desc->minidump_ss, &ss_toc_addr, sizeof(ss_toc_addr)); ss_toc_addr = &g_md_toc->md_ss_toc[desc->minidump_id + 1]; pr_debug("Minidump : ss_toc_addr for pdr is %pa and desc->minidump_id is %d\n", &ss_toc_addr, desc->minidump_id); memcpy(&desc->minidump, &ss_toc_addr, memcpy(&desc->minidump_pdr, &ss_toc_addr, sizeof(ss_toc_addr)); } } Loading
drivers/soc/qcom/peripheral-loader.h +2 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,8 @@ struct pil_desc { bool signal_aop; struct mbox_client cl; struct mbox_chan *mbox; struct md_ss_toc *minidump; struct md_ss_toc *minidump_ss; struct md_ss_toc *minidump_pdr; int minidump_id; }; Loading
drivers/soc/qcom/pil-msa.c +7 −7 Original line number Diff line number Diff line Loading @@ -582,7 +582,7 @@ static int pil_mss_reset(struct pil_desc *pil) if (ret) goto err_clks; if (!pil->minidump || !pil->modem_ssr) { if (!pil->minidump_ss || !pil->modem_ssr) { /* Save state of modem debug register before full reset */ debug_val = readl_relaxed(drv->reg_base + QDSP6SS_DBG_CFG); } Loading @@ -595,7 +595,7 @@ static int pil_mss_reset(struct pil_desc *pil) if (ret) goto err_restart; if (!pil->minidump || !pil->modem_ssr) { if (!pil->minidump_ss || !pil->modem_ssr) { writel_relaxed(debug_val, drv->reg_base + QDSP6SS_DBG_CFG); if (modem_dbg_cfg) writel_relaxed(modem_dbg_cfg, Loading Loading @@ -799,10 +799,10 @@ int pil_mss_debug_reset(struct pil_desc *pil) struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc); int ret; if (!pil->minidump) if (!pil->minidump_ss) return 0; if (pil->minidump) { if (pil->minidump->md_ss_enable_status != MD_SS_ENABLED) if (pil->minidump_ss) { if (pil->minidump_ss->md_ss_enable_status != MD_SS_ENABLED) return 0; } Loading @@ -814,7 +814,7 @@ int pil_mss_debug_reset(struct pil_desc *pil) if (ret) return ret; if (pil->minidump) { if (pil->minidump_ss) { writel_relaxed(0x1, drv->reg_base + QDSP6SS_NMI_CFG); /* Let write complete before proceeding */ mb(); Loading @@ -837,7 +837,7 @@ int pil_mss_debug_reset(struct pil_desc *pil) */ pr_info("Minidump: waiting encryption to complete\n"); msleep(10000); if (pil->minidump) { if (pil->minidump_ss) { writel_relaxed(0x2, drv->reg_base + QDSP6SS_NMI_CFG); /* Let write complete before proceeding */ mb(); Loading