From: Yogesh Lal Date: Wed, 2 Nov 2022 17:12:09 +0000 (+0530) Subject: remoteproc: qcom: pas: Adjust the phys addr wrt the mem region X-Git-Tag: v6.6.17~5415^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a376c10d45a8e6ee5ea55791193f90625b35e156;p=platform%2Fkernel%2Flinux-rpi.git remoteproc: qcom: pas: Adjust the phys addr wrt the mem region The minidump table in the toc contains physical addresses that may lie before the physical address of the first elf segment in relocatable images. This change adds a custom dump function for minidumps which calculates the offset into the carveout region using the start of the physical address instead of the start of the first elf segment. Signed-off-by: Yogesh Lal Reviewed-by: Sibi Sankar Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/1667409129-6254-1-git-send-email-quic_ylal@quicinc.com --- diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index abf66c6..a0d4238 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -101,7 +101,9 @@ static void qcom_minidump_cleanup(struct rproc *rproc) } } -static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsystem *subsystem) +static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsystem *subsystem, + void (*rproc_dumpfn_t)(struct rproc *rproc, struct rproc_dump_segment *segment, + void *dest, size_t offset, size_t size)) { struct minidump_region __iomem *ptr; struct minidump_region region; @@ -131,7 +133,7 @@ static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsy } da = le64_to_cpu(region.address); size = le64_to_cpu(region.size); - rproc_coredump_add_custom_segment(rproc, da, size, NULL, name); + rproc_coredump_add_custom_segment(rproc, da, size, rproc_dumpfn_t, name); } } @@ -139,7 +141,10 @@ static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsy return 0; } -void qcom_minidump(struct rproc *rproc, unsigned int minidump_id) +void qcom_minidump(struct rproc *rproc, unsigned int minidump_id, + void (*rproc_dumpfn_t)(struct rproc *rproc, + struct rproc_dump_segment *segment, void *dest, size_t offset, + size_t size)) { int ret; struct minidump_subsystem *subsystem; @@ -169,7 +174,7 @@ void qcom_minidump(struct rproc *rproc, unsigned int minidump_id) return; } - ret = qcom_add_minidump_segments(rproc, subsystem); + ret = qcom_add_minidump_segments(rproc, subsystem, rproc_dumpfn_t); if (ret) { dev_err(&rproc->dev, "Failed with error: %d while adding minidump entries\n", ret); goto clean_minidump; diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index c35adf7..c3cc619 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -33,7 +33,10 @@ struct qcom_rproc_ssr { struct qcom_ssr_subsystem *info; }; -void qcom_minidump(struct rproc *rproc, unsigned int minidump_id); +void qcom_minidump(struct rproc *rproc, unsigned int minidump_id, + void (*rproc_dumpfn_t)(struct rproc *rproc, + struct rproc_dump_segment *segment, void *dest, size_t offset, + size_t size)); void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink, const char *ssr_name); diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 4e1d9b0..7418f0e 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -105,6 +105,24 @@ struct qcom_adsp { struct qcom_scm_pas_metadata dtb_pas_metadata; }; +void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment, + void *dest, size_t offset, size_t size) +{ + struct qcom_adsp *adsp = rproc->priv; + int total_offset; + + total_offset = segment->da + segment->offset + offset - adsp->mem_phys; + if (total_offset < 0 || total_offset + size > adsp->mem_size) { + dev_err(adsp->dev, + "invalid copy request for segment %pad with offset %zu and size %zu)\n", + &segment->da, offset, size); + memset(dest, 0xff, size); + return; + } + + memcpy_fromio(dest, adsp->mem_region + total_offset, size); +} + static void adsp_minidump(struct rproc *rproc) { struct qcom_adsp *adsp = rproc->priv; @@ -112,7 +130,7 @@ static void adsp_minidump(struct rproc *rproc) if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) return; - qcom_minidump(rproc, adsp->minidump_id); + qcom_minidump(rproc, adsp->minidump_id, adsp_segment_dump); } static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,