cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
3,116 Views
Registered: ‎01-24-2013

Force shared memory to be non-cachable for R5

Jump to solution

I've set up a small shared memory area between the APU (running Linux) and the RPU (bare metal), and I have a libmetal program that is pushing values from the APU into the shared memory.  The RPU code picks those values out of memory and drives some hardware (LEDs at the moment).

This works, except that I have to invalidate the R5 cache before it will read the correct values from shared memory.  I thought it should be automatically marked as uncached.  Am I doing something wrong?

 

My R5 code is here: https://pastebin.com/TtQ7feNa

 

The devicetree entry for the shared memory is:

    /* Shared memory */
    shm0: shm@0 {
        compatible = "shm_uio";
        reg = <0x0 0x3e800000 0x0 0x100000>;
    };



0 Kudos
1 Solution

Accepted Solutions
Highlighted
Contributor
Contributor
4,042 Views
Registered: ‎01-24-2013

Ah, I found the problem.  On line 45 of my R5 code, I was passing the base address of the memory region to be shared, rather than a pointer to the memory region.  I realized this while looking through the structure definition in libmetal's io.h, specifically the comment that "physmap" should be a table of addresses.

 

Thanks!

 

View solution in original post

9 Replies
Highlighted
Moderator
Moderator
3,033 Views
Registered: ‎05-10-2017

Hi Steven,

 

Could you please share your complete device-tree?

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Highlighted
Contributor
Contributor
3,029 Views
Registered: ‎01-24-2013

My dtsi for Petalinux is here: https://pastebin.com/BVTC2smg

It should contain everything related to shmem/libmetal/openAMP.  Let me know if you need the decompiled dtb with the entire tree.

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

I don't see the uio devices for ipi and shared memory in the dtsi. Is this in your final system.dtb?

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Highlighted
Contributor
Contributor
2,994 Views
Registered: ‎01-24-2013

My apologies -- I hastily grabbed the wrong dtsi file from a different project.  Here's the correct one: https://pastebin.com/rDPF4XBD (See line 87).

 

I'm not using IPI.  Is that a requirement to use shared memory?

0 Kudos
Highlighted
Moderator
Moderator
2,898 Views
Registered: ‎05-10-2017

Hi Steven,

 

So the metal_io_read without invalidate cache has stale values? 

It could be that the program is being optimized by the compiler and hence the values are not changing.

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Moderator
Moderator
2,893 Views
Registered: ‎05-10-2017

Additionally, without invalidate cache, can you print the value set to *led (to confirm if the shared memory is cached) ?

 

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Highlighted
Contributor
Contributor
2,873 Views
Registered: ‎01-24-2013

Thanks for the reply.

Optimization is off (-O0).

*leds writes to the LEDs on the dev board, and I'm getting stale values.  Trying to print causes lockups, I think because Linux is controlling the serial port.

 

After writing some values from Linux:

ubuntu@ubuntu-zynq:~$ sudo ./peek 0x3e800000 10
0x3e800000 : 0x7e017e01
0x3e800004 : 0x7e017e01
0x3e800008 : 0x7e017e01
0x3e80000c : 0x7e017e01
0x3e800010 : 0x7e017e01

But the R5 doesn't respond, and if I look at the memory, the values haven't changed.

xsct% target
  1  PS TAP
     2  PMU
     3  PL
  4  PSU
     5  RPU
        6* Cortex-R5 #0 (Running)
        7  Cortex-R5 #1 (Halted)
     8  APU
        9  Cortex-A53 #0 (Running)
       10  Cortex-A53 #1 (Running)
       11  Cortex-A53 #2 (Running)
       12  Cortex-A53 #3 (Running)
xsct% mrd 0x3e800000 10
3E800000:   00000000
3E800004:   00000000
3E800008:   00000000
3E80000C:   00000000
3E800010:   00000000

However, if I look outside the R5 scope, I see that the values have been pushed to memory and the R5 values are just stale.

xsct% target 4
xsct% mrd 0x3e800000 10
3E800000:   7E017E01
3E800004:   7E017E01
3E800008:   7E017E01
3E80000C:   7E017E01
3E800010:   7E017E01

 

 

0 Kudos
Highlighted
Moderator
Moderator
2,861 Views
Registered: ‎05-10-2017

Could you check in libmetal to see if the memory is mmapped: lib/system/generic/device.c

When you use xil_printf, it should work even the Linux is using serial port. Unless the print is too frequent, then there can be race condition issue.

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Highlighted
Contributor
Contributor
4,043 Views
Registered: ‎01-24-2013

Ah, I found the problem.  On line 45 of my R5 code, I was passing the base address of the memory region to be shared, rather than a pointer to the memory region.  I realized this while looking through the structure definition in libmetal's io.h, specifically the comment that "physmap" should be a table of addresses.

 

Thanks!

 

View solution in original post