cancel
Showing results for 
Search instead for 
Did you mean: 

Resource Table getting Memory Adresses

YRink.1
Associate II

Hi,

iam trying to get a full understanding of remoteproc and its resource tabel. In the paper i read i understood it that the resource table is used to give the information about the vrings location to the master and the slave. The master parses the ressource table during starting. When i had a look at my code i saw that the adresse of the vrings are set to -1 (attached picture). So iam confused about it really works. Does the master knows the location from the device tree and give it through the slave? And how does the master knows where it has to load the elf-File from the M4, also from the device tree? In the linker script i saw that the regions of the memorys are define but i guess never really used in the code.

1 REPLY 1
ArnaudP
Senior

Hello,

All Information is contained in the elf file and the device tree.

1) The elf file contains the address and the size of the memory section to load, you can have this information with following command

$>  readelf -S ./STM32CubeIDE/CM4/Debug/OpenAMP_TTY_echo_CM4.elf
 
There are 27 section headers, starting at offset 0x294430:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .isr_vector       PROGBITS        00000000 010000 000298 00   A  0   0  1
  [ 2] .text             PROGBITS        10000000 020000 006f2c 00  AX  0   0 16
  [ 3] .startup_copro_fw.Reset_Handler PROGBITS        10006f2c 026f2c 000050 00  AX  0   0  4
  [ 4] .rodata           PROGBITS        10006f7c 026f7c 0005cc 00   A  0   0  4
  [ 5] .ARM.extab        PROGBITS        10007548 0301c4 000000 00   W  0   0  1
  [ 6] .ARM              PROGBITS        10007548 0301c4 000000 00   W  0   0  1
  [ 7] .preinit_array    PREINIT_ARRAY   10007548 0301c4 000000 04  WA  0   0  1
  [ 8] .init_array       INIT_ARRAY      10007548 027548 000004 04  WA  0   0  4
  [ 9] .fini_array       FINI_ARRAY      1000754c 02754c 000004 04  WA  0   0  4
  [10] .data             PROGBITS        10020000 030000 000138 00  WA  0   0  4
  [11] .resource_table   PROGBITS        10020138 030138 00008c 00   A  0   0  4
  [12] .bss              NOBITS          100201c4 0301c4 000de8 00  WA  0   0  4
  [13] ._user_heap_stack NOBITS          10020fac 0301c4 000604 00  WA  0   0  1
 
[...]
 
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

In this example the resource table is loaded at address 0x10020138.

This is the way the Linux remoteproc find the resource table address.

If the firmware is loaded by U-boot or OP-TEE, the resource table address is retrieved from a backup register written by the loading component.

Something important is that the resource table is read only for the Cortex-M4, only the Cortex-A7 should update it.

2) resource table initialization for RPMsg/virtio communication

The addresses of the Vrings and RPMsg buffers areas are allocated by the Linux thanks to information provided in the device tree memory regions. These addresses are computed by the Linux kernel remoteproc core for the vrings and by the rpmsg virtio bus for the RPMsg buffers.

	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
 
		mcuram2: mcuram2@10000000 {
			compatible = "shared-dma-pool";
			reg = <0x10000000 0x40000>;
			no-map;
		};
 
		vdev0vring0: vdev0vring0@10040000 {
			compatible = "shared-dma-pool";
			reg = <0x10040000 0x1000>;
			no-map;
		};
 
		vdev0vring1: vdev0vring1@10041000 {
			compatible = "shared-dma-pool";
			reg = <0x10041000 0x1000>;
			no-map;
		};
 
		vdev0buffer: vdev0buffer@10042000 {
			compatible = "shared-dma-pool";
			reg = <0x10042000 0x4000>;
			no-map;
		};
 
		mcu_rsc_table: mcu_rsc_table@10048000 {
			compatible = "shared-dma-pool";
			reg = <0x10048000 0x8000>;
			no-map;
		};
 
		mcuram: mcuram@30000000 {
			compatible = "shared-dma-pool";
			reg = <0x30000000 0x40000>;
			no-map;
		};
 
		retram: retram@38000000 {
			compatible = "shared-dma-pool";
			reg = <0x38000000 0x10000>;
			no-map;
		};
	};
 

vdev0vring0 is the memory region used to store the vring[0]

vdev0vring1 is the memory region used to store the vring[1]

vdev0buffer is the memory region used to store the Rpmsg/virtio buffers.

Other memory regions define the regions for the firmware code and data.

The -1 in the resource table means that the cortex-M4 doesn't impose an address. It's recommended for the stm32mp1 Socs not to change this value, and to use the memory region to update the addresses.

When the Linux kernel is ready to communicate ( resource table is updated), it sets the status field in the fw_rsc_vdev resource table structure. This informs the Cortex-M4 that the Vrings structures have been initialized and that the RPMsg communication can start.

If you want to go deep in the Linux remoteproc framework knowledge, i suggest you that you enable dynamic trace in kernel to help you to parse the source code:

echo -n 'file stm32_rproc.c +p' > /sys/kernel/debug/dynamic_debug/control
echo -n 'file stm32-ipcc.c +p' > /sys/kernel/debug/dynamic_debug/control
echo -n 'file remoteproc*.c +p' > /sys/kernel/debug/dynamic_debug/control
echo -n 'file virtio_rpmsg_bus.c +p' > /sys/kernel/debug/dynamic_debug/control
echo -n 'file virtio_ring.c +p' > /sys/kernel/debug/dynamic_debug/control