Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcb57ed4 authored by Sarangdhar Joshi's avatar Sarangdhar Joshi Committed by Bjorn Andersson
Browse files

remoteproc: qcom: Register segments for core dump



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: default avatarSarangdhar Joshi <spjoshi@codeaurora.org>
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
parent 4dd27f54
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
};

+44 −0
Original line number Diff line number Diff line
@@ -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"
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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);

+1 −0
Original line number Diff line number Diff line
@@ -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,
};