| From 3af86613ff5de8c46804c96754048104eecae55c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 30 Dec 2020 12:50:05 +0200 |
| Subject: remoteproc: pru: Fix loading of GNU Binutils ELF |
| |
| From: Dimitar Dimitrov <dimitar@dinux.eu> |
| |
| [ Upstream commit e6d9423d31b2f9bdd0220fd0584e3bb6ed2c4e52 ] |
| |
| PRU port of GNU Binutils lacks support for separate address spaces. |
| PRU IRAM addresses are marked with artificial offset to differentiate |
| them from DRAM addresses. Hence remoteproc must mask IRAM addresses |
| coming from GNU ELF in order to get the true hardware address. |
| |
| PRU firmware used for testing was the example in: |
| https://github.com/dinuxbg/pru-gcc-examples/tree/master/blinking-led/pru |
| |
| Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu> |
| Link: https://lore.kernel.org/r/20201230105005.30492-1-dimitar@dinux.eu |
| Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/remoteproc/pru_rproc.c | 18 ++++++++++++++++++ |
| 1 file changed, 18 insertions(+) |
| |
| diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c |
| index 16979c1cd2f4..dcb380e868df 100644 |
| --- a/drivers/remoteproc/pru_rproc.c |
| +++ b/drivers/remoteproc/pru_rproc.c |
| @@ -450,6 +450,24 @@ static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, size_t len) |
| if (len == 0) |
| return NULL; |
| |
| + /* |
| + * GNU binutils do not support multiple address spaces. The GNU |
| + * linker's default linker script places IRAM at an arbitrary high |
| + * offset, in order to differentiate it from DRAM. Hence we need to |
| + * strip the artificial offset in the IRAM addresses coming from the |
| + * ELF file. |
| + * |
| + * The TI proprietary linker would never set those higher IRAM address |
| + * bits anyway. PRU architecture limits the program counter to 16-bit |
| + * word-address range. This in turn corresponds to 18-bit IRAM |
| + * byte-address range for ELF. |
| + * |
| + * Two more bits are added just in case to make the final 20-bit mask. |
| + * Idea is to have a safeguard in case TI decides to add banking |
| + * in future SoCs. |
| + */ |
| + da &= 0xfffff; |
| + |
| if (da >= PRU_IRAM_DA && |
| da + len <= PRU_IRAM_DA + pru->mem_regions[PRU_IOMEM_IRAM].size) { |
| offset = da - PRU_IRAM_DA; |
| -- |
| 2.30.2 |
| |