cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
3,719 Views
Registered: ‎03-03-2017

DDR memory share between CPU0 and CPU1 when using openAMP

I have a bare-metal code that captures some data and stores in an external DDR via DMA. My intention now is to run this code on CPU1 while having Linux in CPU0 (using openAMP).

 

In my original bare-metal code I have some definitions as:

 

#define DDR_BASE_ADDR     	0x0
#define MEM_BASE_ADDR    	(DDR_BASE_ADDR + (100*1024*1024))

which are used to define the location of the stored data in the DDR (and to put them far from the memory used by the code).

 

 

In order to create an openAMP boot, I use the proposed configurations, that is:

 

1.Run petalinux-config, and set the kernel base address to 0x10000000, as
follows: Subsystem AUTO Hardware Settings ---> Memory Settings ---> (0x10000000) kernel base address

And

 

 

For the Zynq-7000 All Programmable (AP) SoC (Zynq) only, set memory split to
2G/2G (or use 1G/3G user/kernel): Kernel Features---> Memory split (...)---> (x) 2G/2G user/kernel split

In system-user.dtsi, I use the following configuration:

 

/include/ "system-conf.dtsi"
/ {
	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
		rproc_0_reserved: rproc@3e000000 {
			no-map;
			reg =  <0x3e000000 0x01000000>;
		};
	};
	amba {
		elf_ddr_0: ddr@0 {
			compatible = "mmio-sram";
			reg = <0x3e000000 0x400000>;
		};
	};
	remoteproc0: remoteproc@0 {
		compatible = "xlnx,zynq_remoteproc";
		firmware = "firmware";
		vring0 = <15>;
		vring1 = <14>;
		srams = <&elf_ddr_0>;
	};
};

 

 

My question is, how should I modify in MEM_BASE_ADDR when running the code in CPU1 under these conditions? Should I add any configuration in system-user.dtsi?

 

And then, is it possible that Linux has a direct access to the same space of memory in order to avoid the transfer between CPU1 and CPU0?

 

Thank you very much in advance.

Tags (4)
0 Kudos
7 Replies
Highlighted
Contributor
Contributor
3,654 Views
Registered: ‎03-03-2017

Re: DDR memory share between CPU0 and CPU1 when using openAMP

Still trying to solve this issue. According to this post, reserving a block of memory should work to share the DDR between CPU0 (Linux) and CPU1 (bare-metal). I've tried reserving 16 MB at 0x10000000: 

 

/include/ "system-conf.dtsi"
/ {
	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
		rproc_0_reserved: rproc@3e000000 {
			no-map;
			reg =  <0x3e000000 0x01000000>;
		};
		vin_reserved: vin@0x10000000 {
                        reg = <0x10000000 0x01000000>;
                };
	};

	amba {
		elf_ddr_0: ddr@0 {
			compatible = "mmio-sram";
			reg = <0x3e000000 0x400000>;
		};
	};

	remoteproc0: remoteproc@0 {
		compatible = "xlnx,zynq_remoteproc";
		firmware = "firmware";
		vring0 = <15>;
		vring1 = <14>;
		srams = <&elf_ddr_0>;
	};

};

However, I do not see it when booting Linux:

 

OF: fdt:Machine model: xlnx,zynq-7000
OF: fdt:Ignoring memory range 0x0 - 0x10000000
bootconsole [earlycon0] enabled
cma: Reserved 16 MiB at 0x3f000000
Memory policy: Data cache writealloc

Besides, when I start the remote application at CPU1 the Linux crashes (even before running the Linux application that launches the first DMA read). Any clue on what is happening will be really appreciated. 

0 Kudos
Highlighted
Moderator
Moderator
3,647 Views
Registered: ‎05-10-2017

Re: DDR memory share between CPU0 and CPU1 when using openAMP

Could you share your baremetal application? Which version of the tools/document are you using? Is this test being done on an eval board?

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
Highlighted
Contributor
Contributor
3,630 Views
Registered: ‎03-03-2017

Re: DDR memory share between CPU0 and CPU1 when using openAMP

@jovitac, my application is based on the echo_test. I'm using Vivado/SDK/petalinux 2017.4, and I run the apps on a TE0720 with 1 GB RAM. I have attached the main.c file in this reply, although after some iterations I found where I guess I have my problem. At some point of the code, I request for memory allocation:

 

 

p_obj = (adc_t*) malloc(sizeof(adc_t));

If I comment the code from this line, I can start the remote CPU1 and Linux continues normally. But when I add this part of the code, then in the Linux terminal I see:

 

 

remoteproc remoteproc0: powering up remoteproc@0
remoteproc remoteproc0: Booting fw image ADC2DMACPU1, size 2609416
remoteproc remoteproc0: registered virtio0 (type 7)
virtio_rpmsg_bus virtio0: rpmsg host is online
CPU1: shutdown
remoStarting application...
Try to init remoteproc resource
Init remoteproc resource succeeded
Waiting for events...                                                                                                                             teproc remoteproc0: remote processor remoteproc@0 is now up

And then it crashes (it doesn't answer anymore). It seems that CPU1 is working as expected (I have checked it using some LEDs of the board) but CPU0 stops. It seems to me I may be writing into a forbidden memory address affecting Linux execution¿?

 

 

Considering the kind answer from @ewong3 here, I have modified system-user.dtsi as follows:

 

/include/ "system-conf.dtsi"
/ {
	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
		rproc_0_reserved: rproc@3e000000 {
			no-map;
			reg =  <0x3e000000 0x01000000>;
		};
	};

	amba {
		elf_ddr_0: ddr@0 {
			compatible = "mmio-sram";
			reg = <0x3e000000 0x400000>;
		};
	};

	remoteproc0: remoteproc@0 {
		compatible = "xlnx,zynq_remoteproc";
		firmware = "ADC2DMACPU1.elf";
		vring0 = <15>;
		vring1 = <14>;
		srams = <&elf_ddr_0>;
	};

	dmabuf {
		compatible = "dmem-uio";
		reg = < 0x3e800000 0x800000>;
	};

};

And in the bare-metal code I added the following definition:

#define TX_BUFFER_BASE		0x3e800000

which is the address where the DMA should write the data. But I have not get to this point yet.

0 Kudos
Highlighted
Adventurer
Adventurer
3,625 Views
Registered: ‎11-05-2014

Re: DDR memory share between CPU0 and CPU1 when using openAMP

The dmem-uio node creates a UIO device (/dev/uioX) that can be opened and mmap'ed for access to the specified memory region from Linux userspace.  I'm not sure if it does anything with the MMU/cache settings.

Highlighted
Contributor
Contributor
3,597 Views
Registered: ‎03-03-2017

Re: DDR memory share between CPU0 and CPU1 when using openAMP

Please, let me check if I understand the DDR partition (since I think I don't). The kernel configuration for the Linux in CPU0 is:

 

1.Run petalinux-config, and set the kernel base address to 0x10000000, as
follows: Subsystem AUTO Hardware Settings ---> Memory Settings ---> (0x10000000) kernel base address

That means that Linux is placed above the address 0x10000000. Is that correct? Then, the addresses between 0x0 and 0x10000000 should be used by bare-metal apps in CPU1. In that case I could replace the malloc calls (since apparently are causing some kind of problem) by libmetal APIS as explained here, or by direct assignments to the available memory for the bare-metal, as for instance: 

#define FRAME_BUFFER_BASEADDR        0x01D00000
u32 *fb0 = (u32 *)FRAME_BUFFER_BASEADDR;

On the other hand, I have defined the region for the DMA transfers in the device tree (and done in the bare-metal) as:

dmabuf {
		compatible = "dmem-uio";
		reg = < 0x3e800000 0x800000>;
	};

Again, I use direct assignments in the bare-metal to transfer the data of the DMA (in my case S2MM) and in the Linux user space I need to use the following to access the data:

value_rec = mmap(NULL, 0x800000, PROT_READ|PROT_WRITE, MAP_SHARED, -1, 0x3e800000 );

Please, tell me if I said something correct. Probably not.

 

0 Kudos
Highlighted
Contributor
Contributor
3,566 Views
Registered: ‎03-03-2017

Re: DDR memory share between CPU0 and CPU1 when using openAMP

Changing mallocs by direct assignments to ddr worked (although I doubt this is a good solution), but I'm still stuck since Linux still crashes when I run the bare-metal remote application in CPU1 due to interrupt initialization (if I comment the call to "XScuGic_CfgInitialize" present in the bare-metal CPU1 code, Linux in CPU0 doesn't crash). I added the S2MM interrupt that I need in the device tree as shown below:

remoteproc0: remoteproc@0 {
		compatible = "xlnx,zynq_remoteproc";
		interrupt-parent = <&intc>;
    		interrupts = < 0 29 4 >;
		firmware = "ADC2DMACPU1.elf";
		vring0 = <15>;
		vring1 = <14>;
		srams = <&elf_ddr_0>;
	};

Cannot see the light at the end of the tunnel :(

0 Kudos
Highlighted
Contributor
Contributor
3,360 Views
Registered: ‎01-18-2018

Re: DDR memory share between CPU0 and CPU1 when using openAMP

Hi amsanchez,

 

just give a look here. The XScuGic_InterruptMaptoCpu might be your issue

 

https://forums.xilinx.com/t5/OpenAMP/OpenAMP-CPU0-with-LInux-and-CPU-1-with-baremetal-Interrupt-not/m-p/827510#M388

 

Luca

0 Kudos