|
@@ -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);
|