Skip to content

Commit

Permalink
remoteproc: qcom: Register segments for core dump
Browse files Browse the repository at this point in the history
Register MDT segments with the remoteproc core dump functionality in
order to include them in a core dump, in case of a recovery of the remote
processor.

Signed-off-by: Sarangdhar Joshi <spjoshi@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
  • Loading branch information
Sarangdhar Joshi authored and Bjorn Andersson committed Feb 12, 2018
1 parent 4dd27f5 commit dcb57ed
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/remoteproc/qcom_adsp_pil.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ static const struct rproc_ops adsp_ops = {
.start = adsp_start,
.stop = adsp_stop,
.da_to_va = adsp_da_to_va,
.parse_fw = qcom_register_dump_segments,
.load = adsp_load,
};

Expand Down
44 changes: 44 additions & 0 deletions drivers/remoteproc/qcom_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/remoteproc.h>
#include <linux/rpmsg/qcom_glink.h>
#include <linux/rpmsg/qcom_smd.h>
#include <linux/soc/qcom/mdt_loader.h>

#include "remoteproc_internal.h"
#include "qcom_common.h"
Expand Down Expand Up @@ -79,6 +80,49 @@ void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glin
}
EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev);

/**
* qcom_register_dump_segments() - register segments for coredump
* @rproc: remoteproc handle
* @fw: firmware header
*
* Register all segments of the ELF in the remoteproc coredump segment list
*
* Return: 0 on success, negative errno on failure.
*/
int qcom_register_dump_segments(struct rproc *rproc,
const struct firmware *fw)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
const struct elf32_hdr *ehdr;
int ret;
int i;

ehdr = (struct elf32_hdr *)fw->data;
phdrs = (struct elf32_phdr *)(ehdr + 1);

for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];

if (phdr->p_type != PT_LOAD)
continue;

if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
continue;

if (!phdr->p_memsz)
continue;

ret = rproc_coredump_add_segment(rproc, phdr->p_paddr,
phdr->p_memsz);
if (ret)
return ret;
}

return 0;
}
EXPORT_SYMBOL_GPL(qcom_register_dump_segments);

static int smd_subdev_probe(struct rproc_subdev *subdev)
{
struct qcom_rproc_subdev *smd = to_smd_subdev(subdev);
Expand Down
2 changes: 2 additions & 0 deletions drivers/remoteproc/qcom_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ struct qcom_rproc_ssr {
void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);

int qcom_register_dump_segments(struct rproc *rproc, const struct firmware *fw);

void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd);
void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd);

Expand Down
1 change: 1 addition & 0 deletions drivers/remoteproc/qcom_wcnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ static const struct rproc_ops wcnss_ops = {
.start = wcnss_start,
.stop = wcnss_stop,
.da_to_va = wcnss_da_to_va,
.parse_fw = qcom_register_dump_segments,
.load = wcnss_load,
};

Expand Down

0 comments on commit dcb57ed

Please sign in to comment.