[PATCH 2/2] remoteproc: imx_dsp_rproc: Implement .memcpy_tova()
From: Uwe Kleine-König
Date: Mon Oct 26 2026 - 06:15:14 EST
This callback allows to use the core's rproc_elf_load_segments()
function instead of reimplementing it for very minor changes.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxx>
---
drivers/remoteproc/imx_dsp_rproc.c | 120 ++++++++---------------------
1 file changed, 30 insertions(+), 90 deletions(-)
diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
index 96d619daf3f5..324c10f18507 100644
--- a/drivers/remoteproc/imx_dsp_rproc.c
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -864,97 +864,41 @@ static int imx_dsp_rproc_memset(void *addr, u8 value, size_t size)
return 0;
}
-/*
- * imx_dsp_rproc_elf_load_segments() - load firmware segments to memory
- * @rproc: remote processor which will be booted using these fw segments
- * @fw: the ELF firmware image
- *
- * This function loads the firmware segments to memory, where the remote
- * processor expects them.
- *
- * Return: 0 on success and an appropriate error code otherwise
- */
-static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
+static int imx_dsp_rproc_memcpy_tova(struct rproc *rproc, u64 da, const void *src,
+ size_t filesz, size_t memsz)
{
struct device *dev = &rproc->dev;
- const void *ehdr, *phdr;
- int i, ret = 0;
- u16 phnum;
- const u8 *elf_data = fw->data;
- u8 class = fw_elf_get_class(fw);
- u32 elf_phdr_get_size = elf_size_of_phdr(class);
+ void *ptr;
+ int ret;
- ehdr = elf_data;
- phnum = elf_hdr_get_e_phnum(class, ehdr);
- phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr);
+ /* grab the kernel address for this device address */
+ ptr = rproc_da_to_va(rproc, da, memsz, NULL);
+ if (!ptr) {
+ dev_err(dev, "bad phdr da 0x%llx mem 0x%zx\n", da, memsz);
+ return -EINVAL;
+ }
- /* go through the available ELF segments */
- for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) {
- u64 da = elf_phdr_get_p_paddr(class, phdr);
- u64 memsz = elf_phdr_get_p_memsz(class, phdr);
- u64 filesz = elf_phdr_get_p_filesz(class, phdr);
- u64 offset = elf_phdr_get_p_offset(class, phdr);
- u32 type = elf_phdr_get_p_type(class, phdr);
- void *ptr;
-
- if (type != PT_LOAD || !memsz)
- continue;
-
- dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
- type, da, memsz, filesz);
-
- if (filesz > memsz) {
- dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n",
- filesz, memsz);
- ret = -EINVAL;
- break;
- }
-
- if (offset + filesz > fw->size) {
- dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n",
- offset + filesz, fw->size);
- ret = -EINVAL;
- break;
- }
-
- if (!rproc_u64_fit_in_size_t(memsz)) {
- dev_err(dev, "size (%llx) does not fit in size_t type\n",
- memsz);
- ret = -EOVERFLOW;
- break;
- }
-
- /* grab the kernel address for this device address */
- ptr = rproc_da_to_va(rproc, da, memsz, NULL);
- if (!ptr) {
- dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
- memsz);
- ret = -EINVAL;
- break;
- }
-
- /* put the segment where the remote processor expects it */
- if (filesz) {
- ret = imx_dsp_rproc_memcpy(ptr, elf_data + offset, filesz);
- if (ret) {
- dev_err(dev, "memory copy failed for da 0x%llx memsz 0x%llx\n",
- da, memsz);
- break;
- }
- }
-
- /* zero out remaining memory for this segment */
- if (memsz > filesz) {
- ret = imx_dsp_rproc_memset(ptr + filesz, 0, memsz - filesz);
- if (ret) {
- dev_err(dev, "memset failed for da 0x%llx memsz 0x%llx\n",
- da, memsz);
- break;
- }
+ /* put the segment where the remote processor expects it */
+ if (filesz) {
+ ret = imx_dsp_rproc_memcpy(ptr, src, filesz);
+ if (ret) {
+ dev_err(dev, "memory copy failed for da 0x%llx memsz 0x%zx\n",
+ da, memsz);
+ return ret;
}
}
- return ret;
+ /* zero out remaining memory for this segment */
+ if (memsz > filesz) {
+ ret = imx_dsp_rproc_memset(ptr + filesz, 0, memsz - filesz);
+ if (ret) {
+ dev_err(dev, "memset failed for da 0x%llx memsz 0x%zx\n",
+ da, memsz);
+ return ret;
+ }
+ }
+
+ return 0;
}
static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
@@ -969,7 +913,6 @@ static int imx_dsp_rproc_load(struct rproc *rproc, const struct firmware *fw)
struct imx_dsp_rproc *priv = rproc->priv;
const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
struct rproc_mem_entry *carveout;
- int ret;
/* Reset DSP if needed */
if (dsp_dcfg->reset)
@@ -985,11 +928,7 @@ static int imx_dsp_rproc_load(struct rproc *rproc, const struct firmware *fw)
}
}
- ret = imx_dsp_rproc_elf_load_segments(rproc, fw);
- if (ret)
- return ret;
-
- return 0;
+ return rproc_elf_load_segments(rproc, fw);
}
static const struct rproc_ops imx_dsp_rproc_ops = {
@@ -998,6 +937,7 @@ static const struct rproc_ops imx_dsp_rproc_ops = {
.start = imx_dsp_rproc_start,
.stop = imx_dsp_rproc_stop,
.kick = imx_dsp_rproc_kick,
+ .memcpy_tova = imx_dsp_rproc_memcpy_tova,
.load = imx_dsp_rproc_load,
.parse_fw = imx_dsp_rproc_parse_fw,
.handle_rsc = imx_dsp_rproc_handle_rsc,
--
2.47.3