UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer @bucky
Observer
3,950 Views
Registered: ‎11-22-2018

ZYNQ Peripheral Access & Cache

Jump to solution

Hi guys,

I'm using a ZYNQ device that uses both PS peripherals and custom IP peripherals available through AXI bus.
I've seen that Cortex-A9 core is equipped with its own data and instruction cache.

To access peripheral's registers, do I have to uncache the areas where peripherals' register are mapped to?
Or is enough to use e.g. Xil_Out32, Xil_In32 that dereferences a volatile pointer to bypass the cache?

Fully disabling the data cache probably clears the issue but also reduces system performance, if possible I would avoid it.

Thanks in advance for the support,

Bucky

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Observer @bucky
Observer
3,878 Views
Registered: ‎11-22-2018

Re: ZYNQ Peripheral Access & Cache

Jump to solution

[EDIT] After receving the demo board an doing some tests...

Does the standalone BSP already do the job?  [EDIT] Yes!
I'm referring to translation_table.s source.

.rept	0x0400			/* 0x40000000 - 0x7fffffff (FPGA slave0) */
.word	SECT + 0xc02		/* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */
.set	SECT, SECT+0x100000
.endr
.rept 0x0400 /* 0x80000000 - 0xbfffffff (FPGA slave1) */ .word SECT + 0xc02 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ .set SECT, SECT+0x100000 .endr
.rept 0x003 /* 0xe0000000 - 0xe02fffff (Memory mapped devices) * UART/USB/IIC/SPI/CAN/GEM/GPIO/QSPI/SD/NAND */ .word SECT + 0xc06 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ .set SECT, SECT+0x100000 .endr

Looking at the ZYNQ technical reference manual another doubt comes to me :\
The TRM in paragraph "3.2.4 Memory Ordering" states that Strongly Ordered Memory region do not support unaligned accesses.

[EDIT] Aligned access to Strongly Ordered Memory region depends to access type and it's not related to processor word size (32-bit) as I've first mistook.

  • 8-bit memory accesses can be done to any address be it even or odd
  • 16-bit  memory accesses can be done only to even addresses
  • 32-bit  memory accesses can be done only to 4-byte aligned addresses
struct PL_PERIPH_REG __attribute__((packed))
{
volatile u16 REG_A;
volatile u16 REG_B;
};

/* peripheral axi memory mapped to M_AXI_GP0 base */
#define PL_PERIPH_BASE 0x40000000

/* [EDIT] successful accesses */
*((volatile u8*) PL_PERIPH_BASE) = 0x32;
*((volatile u8*) (PL_PERIPH_BASE + 1)) = 0x33;
*((volatile u16*) PL_PERIPH_BASE) = 0xAA55; *((volatile u16*) (PL_PERIPH_BASE + 2u)) = 0xCAFE;
*((volatile u32*) (PL_PERIPH_BASE)) = 0xAA55CAFE;

/* [EDIT] failing accesses */
*((volatile u16*) (PL_PERIPH_BASE + 1))  = 0xAA55;
*((volatile u32*) (PL_PERIPH_BASE + 2))  = 0xAA55CAFE;

Thanks in advance for the support.

0 Kudos
3 Replies
Xilinx Employee
Xilinx Employee
3,908 Views
Registered: ‎09-01-2014

Re: ZYNQ Peripheral Access & Cache

Jump to solution
Normally memory attributes of peripheral register area should be set as device or strongly-ordered. You don’t need to disable the whole cache.
Xil_SetTlbAttributes can be used to change memory attributers.
Here is an example.
https://www.xilinx.com/support/answers/68191.html
Observer @bucky
Observer
3,839 Views
Registered: ‎11-22-2018

Re: ZYNQ Peripheral Access & Cache

Jump to solution

Hi ritakur,

thanks for your answer.
Following the hints that you gave me I've looked both to documentation and Xilinx BSP generated code.
As far as I've understood the PS memory-mapped peripherals and AXI ports, where PL peripherals can be mapped, are already set as Strongly Ordered Memory Region.
The stand-alone BSP already does the work.

* First thing -> Am I right on this point?

.rept    0x0400            /* 0x40000000 - 0x7fffffff (FPGA slave0) */
.word    SECT + 0xc02        /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */
.set    SECT, SECT+0x100000
.endr

.rept    0x0400            /* 0x80000000 - 0xbfffffff (FPGA slave1) */
.word    SECT + 0xc02        /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */
.set    SECT, SECT+0x100000
.endr

.rept    0x003            /* 0xe0000000 - 0xe02fffff (Memory mapped devices)
                 * UART/USB/IIC/SPI/CAN/GEM/GPIO/QSPI/SD/NAND */
.word    SECT + 0xc06        /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */
.set    SECT, SECT+0x100000
.endr


* Second thing
The ZYNQ technical reference manual states that Strongly Ordered Memory region cannot support unaligned accesses.
If I have a peripheral that is exported to AXI as 16-bit registers, is correct to say that registers cannot be R/W using 16-bit accessing mode.

The following example to best explain myself.

struct AXI_PL_REG
{
    volatile u16 RegA;
    volatile u16 RegB;
} __attribute__((packed))

/* mapped to M_AXI_GP */
#define PL_PER_ADDR 0x40000000u

/* Setting Register A of Peripheral to 0xAA - 16 bit access should FAIL! */
Xil_Out16(PL_PER       , 0x00AA);

/* Setting Register B of Peripheral to 0x55 - 16 bit access should FAIL! */
Xil_Out16(PL_PER + 0x02, 0x5500);

/* Setting whole data -> should be OK */
Xil_Out32(PL_PER, 0x550000AA)

 

0 Kudos
Highlighted
Observer @bucky
Observer
3,879 Views
Registered: ‎11-22-2018

Re: ZYNQ Peripheral Access & Cache

Jump to solution

[EDIT] After receving the demo board an doing some tests...

Does the standalone BSP already do the job?  [EDIT] Yes!
I'm referring to translation_table.s source.

.rept	0x0400			/* 0x40000000 - 0x7fffffff (FPGA slave0) */
.word	SECT + 0xc02		/* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */
.set	SECT, SECT+0x100000
.endr
.rept 0x0400 /* 0x80000000 - 0xbfffffff (FPGA slave1) */ .word SECT + 0xc02 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ .set SECT, SECT+0x100000 .endr
.rept 0x003 /* 0xe0000000 - 0xe02fffff (Memory mapped devices) * UART/USB/IIC/SPI/CAN/GEM/GPIO/QSPI/SD/NAND */ .word SECT + 0xc06 /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b1 */ .set SECT, SECT+0x100000 .endr

Looking at the ZYNQ technical reference manual another doubt comes to me :\
The TRM in paragraph "3.2.4 Memory Ordering" states that Strongly Ordered Memory region do not support unaligned accesses.

[EDIT] Aligned access to Strongly Ordered Memory region depends to access type and it's not related to processor word size (32-bit) as I've first mistook.

  • 8-bit memory accesses can be done to any address be it even or odd
  • 16-bit  memory accesses can be done only to even addresses
  • 32-bit  memory accesses can be done only to 4-byte aligned addresses
struct PL_PERIPH_REG __attribute__((packed))
{
volatile u16 REG_A;
volatile u16 REG_B;
};

/* peripheral axi memory mapped to M_AXI_GP0 base */
#define PL_PERIPH_BASE 0x40000000

/* [EDIT] successful accesses */
*((volatile u8*) PL_PERIPH_BASE) = 0x32;
*((volatile u8*) (PL_PERIPH_BASE + 1)) = 0x33;
*((volatile u16*) PL_PERIPH_BASE) = 0xAA55; *((volatile u16*) (PL_PERIPH_BASE + 2u)) = 0xCAFE;
*((volatile u32*) (PL_PERIPH_BASE)) = 0xAA55CAFE;

/* [EDIT] failing accesses */
*((volatile u16*) (PL_PERIPH_BASE + 1))  = 0xAA55;
*((volatile u32*) (PL_PERIPH_BASE + 2))  = 0xAA55CAFE;

Thanks in advance for the support.

0 Kudos