i.MX 8M Plus: Loading firmware via remoteproc fails

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX 8M Plus: Loading firmware via remoteproc fails

1,592 Views
RishabhPoddar
Contributor I

I am trying to enable remoteproc to control M7. imx_rproc driver seems to be working.  I am using the following device tree (at post end) . I have seen limited success , I am able stop start and load demo app firmware provided by mcuexprosso. How ever the existing firmware that we were using is not working. 

The firmware(.bin) works fine with u-boot. But when i try to use firmware(.elf) using remoteproc it fails to kick complaining about address translation failed  . I have looked into the issue and attached some relevent info below but i dont see any obvious issue. My guess is the linker script provided by MCUexpresso has some issue or i am not using it correctly.

[ 1683.199889] remoteproc remoteproc0: powering up imx-rproc
[ 1683.208037] remoteproc remoteproc0: Booting fw image ams2_app.elf, size 257324
[ 1683.215523] imx-rproc imx8mp-cm7: Translation failed: da = 0x14b38 len = 0x1ee78
[ 1683.222972] remoteproc remoteproc0: bad phdr da 0x14b38 mem 0x1ee78
[ 1683.229270] remoteproc remoteproc0: Failed to load program segments: -22
[ 1683.236023] remoteproc remoteproc0: Boot failed: -22
 
 
On examining this seems to data section 
 
Screenshot_20230624_002442.png
 
The memory layout of TCM is like this 
 
Screenshot_20230624_002755.png

 

Device tree used.

/ {
model = "Variscite VAR-SOM-ATOMS-MX8MP M7 on ATP_CB3 Aston-Board";
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
 
m7_reserved: m7@0x80000000 {
no-map;
reg = <0 0x80000000 0 0x1000000>;
};
 
vdev0vring0: vdev0vring0@40000000 {
reg = <0 0x40000000 0 0x8000>;
no-map;
};
 
vdev0vring1: vdev0vring1@40008000 {
reg = <0 0x40008000 0 0x8000>;
no-map;
};
 
vdevbuffer: vdevbuffer@40400000 {
compatible = "shared-dma-pool";
reg = <0 0x40400000 0 0x400000>;
no-map;
};
 
rsc_table: rsc_table@400ff000 {
reg = <0 0x400ff000 0 0x1000>;
no-map;
};
};
 
imx8mp-cm7 {
compatible = "fsl,imx8mn-cm7";
rsc-da = <0x40000000>;
clocks = <&clk IMX8MP_CLK_M7_DIV>;
mbox-names = "tx", "rx", "rxdb";
mboxes = <&mu 0 1
  &mu 1 1
  &mu 3 1>;
memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>;
status = "okay";
};
 
imx8mp-rpmsg {
compatible = "fsl,imx8mq-rpmsg";
reg = <0x0 0x40000000 0x0 0x10000>;
clocks = <&clk IMX8MP_CLK_M7_DIV>;
mbox-names = "tx", "rx", "rxdb";
mboxes = <&mu 0 1
  &mu 1 1
  &mu 3 1>;
status = "okay";
};
 
};

 

 

0 Kudos
Reply
6 Replies

1,558 Views
joanxie
NXP TechSupport
NXP TechSupport

refer to the application note, how about define TCM memory in the dts?

https://www.nxp.com.cn/docs/en/application-note/AN5317.pdf

you can refer to the page 11

and let me remind, if you kick in the uboot, don't forget stop in the kernel then kick again

 

0 Kudos
Reply

1,545 Views
RishabhPoddar
Contributor I

I stop the m7 before loading FW and kick

on your suggestion i have updated the device tree

relevant Device tree update to last one. is below
 
m7itcm: m7@0x7E0000 {
no-map;
reg = <0 0x7E0000 0 0x20000>;
};
 
m7dtcm: m7@0x800000 {
no-map;
reg = <0 0x800000 0 0x20000>;
};
.
.
.
memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>, <&m7itcm>, <&m7dtcm>;
 
The issue is still present. Again i am able to kick hello_world example provided but my elf fails.
 
My understanding is it should try to translate and load VirtualAddress . But it seems to be trying to load PhyAddress . Am i missing something? Please look At the screenshots attached.

Screenshot_20230626_142013.png

Screenshot_20230626_142120.png

 

 
0 Kudos
Reply

1,500 Views
joanxie
NXP TechSupport
NXP TechSupport

what elf do yo use? it seems that this is elf issue, could you reproduce this on nxp imx8mp board? if yes, give me the detailed reproduce steps

0 Kudos
Reply

1,493 Views
RishabhPoddar
Contributor I

Which elf did you use -> FreeRTOS based proprietary  application that we developed  It uses RPMSG-Lite to talk with host.

Since the elfs data section was not aligned with DTCM of iMX 8 Plus . It was crashing. We had 2 options.

Edit the linker script provided in MCUExpresso as mentioned in this thread https://community.toradex.com/t/error-in-m4-ocram-linker-file/8354/15

Or in the imx-rproc driver we could redefine ITCM and DTCM as a single TCM block. For now we have gone with the second option and are able to load FW. 

Thank you for your help . We are stuck with different issue currently I will start a new thread for that.

0 Kudos
Reply

1,463 Views
joanxie
NXP TechSupport
NXP TechSupport

this is tested elf list'

The i.MX8MN/P, the elf file list:

imx8m[n,p,m,q]_m[7,4]_TCM_hello_world.elf
imx8m[n,p,m,q]_m[7,4]_TCM_rpmsg_lite_pingpong_rtos_linux_remote.elf
imx8m[n,p,m,q]_m[7,4]_TCM_rpmsg_lite_str_echo_rtos.elf
imx8m[n,p,m]_m[7,4]_TCM_sai_low_power_audio.elf

so you can work with imx8mp_m7_TCM_hello_world.elf, but failed with your own elf, right?

0 Kudos
Reply

214 Views
s_sosin
Contributor III

I've hit the same problem as OP. Turned out there's bug in elf loader code. It uses physical address instead of virtual and puts stack+heap+bss in ITCM instead of DTCM. To hit that bug, your code+bss+stack+heap must be larger than the size of ITCM (0x20000 = 128K). You can modify stock examples by increasing stack and heap appropriately and they won't work either.

Here's the fix:
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -173,7 +173,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)

/* 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 da = elf_phdr_get_p_vaddr(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);

0 Kudos
Reply