[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200713132927.24925-5-abailon@baylibre.com>
Date: Mon, 13 Jul 2020 15:29:25 +0200
From: Alexandre Bailon <abailon@...libre.com>
To: ohad@...ery.com, bjorn.andersson@...aro.org, robh+dt@...nel.org,
matthias.bgg@...il.com
Cc: linux-remoteproc@...r.kernel.org, devicetree@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-mediatek@...ts.infradead.org, linux-kernel@...r.kernel.org,
Alexandre Bailon <abailon@...libre.com>
Subject: [PATCH 4/6] remoteproc: mtk_vpu_rproc: Don't try to load empty PT_LOAD segment
The firmware generated by our toolchain contains many empty PT_LOAD
segments. The elf loader don't manage it and will raise an error:
"bad phdr da 0x0 mem 0x0".
To workaround it, implement the sanity_check callback to detect the
empty PT_LOAD segment and change it to PT_NULL.
In that way, the elf load won't try to load the segment.
Signed-off-by: Alexandre Bailon <abailon@...libre.com>
---
drivers/remoteproc/mtk_apu_rproc.c | 35 +++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/remoteproc/mtk_apu_rproc.c b/drivers/remoteproc/mtk_apu_rproc.c
index f2342b747a35..565b3adca5de 100644
--- a/drivers/remoteproc/mtk_apu_rproc.c
+++ b/drivers/remoteproc/mtk_apu_rproc.c
@@ -137,10 +137,39 @@ static void mtk_vpu_rproc_kick(struct rproc *rproc, int vqid)
vpu_write32(vpu_rproc, CORE_CTL_XTENSA_INT, 1 << vqid);
}
+int mtk_vpu_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
+{
+ const u8 *elf_data = fw->data;
+ struct elf32_hdr *ehdr;
+ struct elf32_phdr *phdr;
+ int ret;
+ int i;
+
+ ret = rproc_elf_sanity_check(rproc, fw);
+ if (ret)
+ return ret;
+
+ ehdr = (struct elf32_hdr *)elf_data;
+ phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff);
+
+ for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+ /* Remove empty PT_LOAD section */
+ if (phdr->p_type == PT_LOAD && !phdr->p_paddr)
+ phdr->p_type = PT_NULL;
+ }
+
+ return 0;
+}
+
static const struct rproc_ops mtk_vpu_rproc_ops = {
- .start = mtk_vpu_rproc_start,
- .stop = mtk_vpu_rproc_stop,
- .kick = mtk_vpu_rproc_kick,
+ .start = mtk_vpu_rproc_start,
+ .stop = mtk_vpu_rproc_stop,
+ .kick = mtk_vpu_rproc_kick,
+ .load = rproc_elf_load_segments,
+ .parse_fw = rproc_elf_load_rsc_table,
+ .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+ .sanity_check = mtk_vpu_elf_sanity_check,
+ .get_boot_addr = rproc_elf_get_boot_addr,
};
static irqreturn_t mtk_vpu_rproc_callback(int irq, void *data)
--
2.26.2
Powered by blists - more mailing lists