cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
2,232 Views
Registered: ‎04-04-2018

Reading from the ACP

Jump to solution

Hi,

I am trying to use the ACP to read data produced by the ARM cores in a Linux
system on Zynq UltraScale+. In a device driver I create a buffer whose physical
address is passed to my IP block which is connected to the ACP. I do read
accesses to the ACP with these settings:

        assign M_AXI_ARBURST = 1;       // INCR
        assign M_AXI_ARCACHE = 15;
        assign M_AXI_ARID = 0;
        assign M_AXI_ARLEN = 3;         // 4 beats == 64B
        assign M_AXI_ARLOCK = 0;
        assign M_AXI_ARPROT = 0;
        assign M_AXI_ARQOS = 0;
        assign M_AXI_ARSIZE = 4;        // 16B per beat
        assign M_AXI_ARUSER = 1;        // Inner sharable

When I mmap the buffer created by the device driver in user space and write
some data to the buffer I do not see it in the waveforms between on the ACP
interface. The data that I see in the waveform are either values that I used
in the driver to initialize the buffer or garbage. If I read the buffer
from user space then I read the initialization values so the mmaping seems
to be OK.

When I flush user data from cache to memory with a 'dc civac' instruction
then the data becomes visable in the waveforms.

When I use ARCACHE == 3 instead of 15 as suggested in comments of

generated master interface code then ACP returns SLVERR.

So from this I conclude that there is something wrong with the cache
coherency: ACP reads do not seem to snoop the caches. Is there something
wrong with the settings above? Do I need to do something in the OS/driver
to enable sharing between cores and an ACP connect IP? Is there something
more that I configure in Vivado (2017.4) than just enabling ACP.

Best regards,
Jan.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Xilinx Employee
Xilinx Employee
1,979 Views
Registered: ‎10-04-2016

Hi @jan.h,

Other customers have been successful in using the ACP on MPSoC.

 

What is the alignment of the address you are sending to the ACP? Per the A53 TRM, ARADDR must be aligned to match the transaction.

 

A 64 byte transaction should be aligned to a 64 byte boundary (ARADDR[5:0] is 6'b000000).

A 16 byte transaction should be aligned to a 16 byte boundary (ARADDR[3:0] is 4'b0000).

 

A SLVERR is expected when ARCACHE is set to 4'h3. The only accepted values for ARCACHE are 4'h7, 4'B and 4'hF.

 

The ARUSER setting has me scratching my head. Linux defaults to inner shareable, which would suggest an ARUSER of 2'b01. 

 

I am wondering if you will need to enable the broadcasting of inner shareable transactions, though. Section 5.2 of this Wiki entry describes how to do this.

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842098/Zynq+UltraScale+MPSoC+Cache+Coherency

 

Finally, the setting of the ARPROT bits may need some adjustment. Linux is non-secure, so ARPROT[1] should be 1'b1.

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

10 Replies
Highlighted
Visitor
Visitor
2,197 Views
Registered: ‎04-04-2018

A few more details that might help to figure out what I am doing wrong:

- I allocate the buffer with kmalloc(..., GFP_USER). The buffer gets allocated
  in the 'DDR High' address region.
- I map the buffer to user memory with remap_pfn_range.
- All M_AXI_XXUSER signals are 2 bits wide.
- I connected acpinact to zero.
- I tried allocation in the 0.5GB DDR4 of ZCU102. Same results.
- 'Validate Design' reports OK.
- All signals in the waveforms except for RDATA look as expected.
- Setting ARUSER to inner or outer sharable gives the same results. If I set
  both ARUSER bits to 1 then I get SLVERR as expected. So the ARUSER bits
  seem to be arriving at the ACP

 

Help is highly appreciated!


Best regards,
Jan.

0 Kudos
Highlighted
2,164 Views
Registered: ‎03-13-2018

Hi,

 

When I search for other experiences with ACP/Zynq/Linux I only found success stories

for Zynq 7000 but not not for Zynq Ultrascale+. For example, here is someone with a

similar experience as I have:

 

  https://forums.xilinx.com/t5/Embedded-Processor-System-Design/Using-ACP-from-Linux-on-Zynq-Ultrascale/td-p/743377

 

Can somebody from Xilinx confirm that ACP is working correctly on Ultrascale+ (when it is running Linux

and caching is enabled) or tell us that it is not working so that I do not have to waste more time on it?

 

Best regards,

Jan.

 

0 Kudos
Highlighted
Scholar
Scholar
2,110 Views
Registered: ‎06-10-2008

Hello Jan,

 

I have no experience with the Zynq Ultrascale, so I'm not sure if this will help you, but on a Zynq 7000 I always set ARCACHE and AWCACHE to 3 (0011). And in the PS-PL Configuration of the Zynq I set "Tie off AxUSER to high" to true.

 

Maarten

0 Kudos
Highlighted
2,099 Views
Registered: ‎03-13-2018

Hi Maarten,

 

I tried to set ARCACHE to 3 but then ACP returns SLVERR.

 

The "Tie off AxUSER to high" option is not available in Vivado 2017.4, at least not when it is configured

for Ultrascale.

 

Best regards,

Jan

 

PS. I guess that we are not living far away from each other ;-).

0 Kudos
Highlighted
Moderator
Moderator
2,014 Views
Registered: ‎09-12-2007
0 Kudos
Highlighted
Visitor
Visitor
1,998 Views
Registered: ‎04-04-2018

Hi,

 

The wiki describes cache coherent interfacing via the HPC ports and not via the ACP port. I need the ACP

port because I am prototyping an idea for usage in an ASIC design setting where ACP is available and HPC

not. Therefore the question remains, is the ACP working on Ultrascale (I do not see signs of it when I google

for it) and if is working what could be wrong with the settings that I use (see above)?

 

Regards,

Jan (NXP Semiconductors).

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
1,980 Views
Registered: ‎10-04-2016

Hi @jan.h,

Other customers have been successful in using the ACP on MPSoC.

 

What is the alignment of the address you are sending to the ACP? Per the A53 TRM, ARADDR must be aligned to match the transaction.

 

A 64 byte transaction should be aligned to a 64 byte boundary (ARADDR[5:0] is 6'b000000).

A 16 byte transaction should be aligned to a 16 byte boundary (ARADDR[3:0] is 4'b0000).

 

A SLVERR is expected when ARCACHE is set to 4'h3. The only accepted values for ARCACHE are 4'h7, 4'B and 4'hF.

 

The ARUSER setting has me scratching my head. Linux defaults to inner shareable, which would suggest an ARUSER of 2'b01. 

 

I am wondering if you will need to enable the broadcasting of inner shareable transactions, though. Section 5.2 of this Wiki entry describes how to do this.

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842098/Zynq+UltraScale+MPSoC+Cache+Coherency

 

Finally, the setting of the ARPROT bits may need some adjustment. Linux is non-secure, so ARPROT[1] should be 1'b1.

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------

View solution in original post

Highlighted
Visitor
Visitor
1,953 Views
Registered: ‎04-04-2018

Hi Deanna,

 

Thanks. It works. I changed ARPROT/AWPROT from 0 to 2 (secure access to non-secure access).

 

The strange thing is that I could read my data when it arrived in DDR but not when it was still in cached. So

it seems that there is no cache hit when the security bit of the access equals one and the security bit associated

with the cache line equals zero. However, reading data from DDR with the security bit equal to one from a non

secure memory location is OK. Anyway, it is working. I can continue.

 

Regards,

Jan.

0 Kudos
Highlighted
Visitor
Visitor
1,951 Views
Registered: ‎04-04-2018

One more thing...

 

This is generated code for a master interface:

 

        //Update value to 4'b0011 if coherent accesses to be used via the Zynq ACP port. Not Allocated, Modifiable, not Bufferable. Not Bufferable since this example is meant to test memory, not intermediate cache.
        assign M_AXI_ARCACHE    = 4'b0010;
        assign M_AXI_ARPROT     = 3'h0;

 

It might be good to add a comment above ARPROT to change the value to 3'h2 if one wants to use it for coherent access via ACP similar to the comment above ARCACHE. And of course the same for AWPROT.

 

Regards,

Jan.

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
1,852 Views
Registered: ‎10-04-2016

Hi @jan.h,

I'm glad to hear this is now working for you.

 

The behavior with regards to ARPROT[2:0] is expected. The tags in the A53 caches track whether an entry is secure/non-secure. A transaction only hits in the cache when the address and secure/non-secure setting matches.

 

The DDR memory does not track whether an address was written as part of a secure or non-secure transaction. The setting of AxPROT is generally a don't care when going to DRAM. (There are exceptions, but the XMPU would have to be enabled.)

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------