06-27-2013 06:38 AM
Dear all,
I have a project with AXI Master GP0 enabled i PS and bram memmory placed in PL logic. I am trying to acces to the bram ctrl with bursts. From what i read i think that the only way to perform bursts is to use processor DMA (correct me if i am wrong). I successfully performed write burst transaction from Axi Master to Bram (checked in chipscope axi monitor) with this code:
#include "xil_types.h"
#include "xil_mmu.h"
#include "xdmaps.h"
#include "xil_printf.h"
#include "xbasic_types.h"
#include "xil_cache.h"
/* Write to memory location or register */
#define X_mWriteReg(BASE_ADDRESS, RegOffset, data) \
*(unsigned int *)(BASE_ADDRESS + RegOffset) = ((unsigned int) data);
/* Read from memory location or register */
#define X_mReadReg(BASE_ADDRESS, RegOffset) \
*(unsigned int *)(BASE_ADDRESS + RegOffset);
volatile static int *Src;
volatile static int *Dst;
void DmaDoneHandler(unsigned int Channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef);
XDmaPs DmaInstance;
int main()
{
Xuint32 Status, data=0xDEADBEED;
XStatus Stat;
unsigned int j, channels=0;
XDmaPs_Config *DmaCfg;
XDmaPs *DmaInst=&DmaInstance;
XDmaPs_Cmd DmaCmd;
memset(&DmaCmd, 0, sizeof(XDmaPs_Cmd));
while(1) {
Dst = (int *) XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR;
DmaCmd.ChanCtrl.SrcBurstSize = 4;
DmaCmd.ChanCtrl.SrcBurstLen = 16;
DmaCmd.ChanCtrl.SrcInc = 1;
DmaCmd.ChanCtrl.DstBurstSize = 4;
DmaCmd.ChanCtrl.DstBurstLen = 16;
DmaCmd.ChanCtrl.DstInc = 1;
DmaCmd.BD.SrcAddr = (u32) Src;
DmaCmd.BD.DstAddr = (u32) Dst;
DmaCmd.BD.Length = 16 * sizeof(int);
DmaCfg = XDmaPs_LookupConfig(XPAR_XDMAPS_1_DEVICE_ID);
if (DmaCfg == NULL) {
xil_printf("[zapis]DmaCfg is NULL");
}
Status=XDmaPs_CfgInitialize(DmaInst, DmaCfg, DmaCfg->BaseAddress);
if (Status) {
xil_printf("Init DMA failed\r\n");
return XST_FAILURE;
}
data=0xDEADBEED;
for (j = 0; j < 16; j++) {
Src[j] = data++;
};
XDmaPs_SetDoneHandler(DmaInst, channels, DmaDoneHandler, (void *)(Status));
Stat = XDmaPs_Start(DmaInst, channels, &DmaCmd, 0);
if (Stat != XST_SUCCESS) {
if (Stat == XST_FAILURE) {
xil_printf("DMA_Ps_START return status failure\t = %d on channel = %d a = %d\n\r",Status, channels, Stat);
}
else if (Stat==XST_DEVICE_BUSY) {
xil_printf("DMA_Ps_START return status busy\t = %d on channel = %d a = %d\n\r",Status, channels, Stat);
}
}
else if (Stat == XST_SUCCESS) {
xil_printf("DMA_Ps_START return status SUCESS\t = %d on channel = %d a = %d\n\r",Status, channels, Stat);
}
channels++;
if (channels==8) {
channels=0;
}
}
return 0;
}
void DmaDoneHandler(unsigned int Channel, XDmaPs_Cmd *DmaCmd, void *CallbackRef)
{
/* done handler */
volatile int *Checked = (volatile int *)CallbackRef;
int Index;
int Status = 1;
int *Src;
int *Dst;
src=(int *)DmaCmd->BD.SrcAddr;
Dst = (int *)DmaCmd->BD.DstAddr;
xil_printf("DMA on channel=%d src=0x%x Dst=0x%x Status=%d", Channel, *Src, *Dst, Status);
*Checked = Status;
}
First question is: Is this code is correct, and the second is how to perform read transaction. I tried to do it with the same code with some changes (like source address and destination address replacement), but according to chipscope it performs single writes.
Yd.
06-27-2013 01:59 PM
The ARM CPUs can perform cache line bursts if the region is marked as cacheable. You can at least change it from strongly ordered to bufferable to see a number of singles closely spaced (which may be good enough, depending on your data length).
For an example of changing the MMU, see this Answer Record:
http://www.xilinx.com/support/answers/47406.htm
J9E7F7
06-27-2013 04:38 PM
As Dylan points out, you need to change the MMU. The AR you were pointed to contains code.c which uses the function Xil_SetTlbAttributes() to set the mmu to either shared device or strong ordered device.
You could also use Xil_SetTlbAttributes() to setup the PL address range as memory (non-cached) which would use coalescing. So if you used the A9 to write incremental addresses, the accesses would generate a burst access.
Look at ARM's architectural reference manual. Here's a cheat sheet that I put together once upon a time regarding the MMU bits S, TEX, AP, C, and B settings as commented in the AR's code.c
// B3-1315 short description translation table format
//
// * B3-1317 (Section format)
//
// Using DDR OCM GP0 SRAM QSPI
// b0 b0 b0 b0 b0 b0 // [31:20] - Section base addr PA[31:20]
// b0 b0 b0 b0 b0 b0 // [19] - NS (Non Secure)
// b0 b0 b0 b0 b0 b0 // [18] - 0
// b0 b0 b0 b0 b0 b0 // [17] - nG (Not Global)
// b1 b1 b0 b0 b0 b0 // [16] - S (Sharable)
// b0 b0 b0 b0 b0 b0 // [15] - AP[2]
// b100 b101 b100 b000 b000 b000 // [14:12] - TEX[2:0] TEX Region type encoding. See the ARM Architecture Reference Manual.
// b11 b11 b11 b11 b11 b11 // [11:10] - AP[1:0]
// b0 b0 b0 b0 b0 b0 // [9] - implementation defined
// b1111 b1111 b0000 b0000 b0000 b0000 // [8:5] - Domain number of the TLB entry.
// b0 b0 b0 b0 b0 b0 // [4] - XN (execute never)
// b01 b01 b11 b00 b11 b10 // [3:2] - CB
// b1 b1 b1 b1 b1 b1 // [1] - 1
// b0 b0 b0 b0 b0 b0 // [0] - PXN
//
// 4 3 2 1 0
// 19:16 15:12 11:8 7:4 3:0
//
//
// page B3-1358 architecture reference manual
//
// TEX[2:0] C B Description | Memory type | Page Shareable
// 000 0 0 Strongly-ordered | Strongly-ordered | Shareable
// 1 Shareable Devicea | Device | Shareablea
// 1 0 Outer and Inner Write-Through, no Write-Allocate | Normal | S bitb
// 1 Outer and Inner Write-Back, no Write-Allocate | Normal | S bitb
// 001 0 0 Outer and Inner Non-cacheable | Normal | S bitb
// 1 Reserved | - | -
// 1 0 IMPLEMENTATION DEFINED | IMPLEMENTATION | IMPLEMENTATION
// | DEFINED | DEFINED
// 1 Outer and Inner Write-Back, Write-Allocate | Normal | S bitb
// 010 0 0 Non-shareable Devicea | Device | Non-shareablea
// 1 Reserved | - | -
// 1 x Reserved | - | -
// 011 x x Reserved | - | -
// 1BB A A Cacheable memory: AA = Inner attributec | Normal | S bitb
// BB = Outer attribute
// AA/BB
// 00 Non-cacheable
// 01 Write-Back, Write-Allocate
// 10 Write-Through, no Write-Allocate
// 11 Write-Back, no Write-Allocate
// AP[2] AP[1:0] PL1 and PL2 access Unprivileged access Description
// 0 00 No access No access All accesses generate Permission faults
// 01 Read/write No access Access only at PL1 or higher
// 10 Read/write Read-only Writes at PL0 generate Permission faults
// 11 Read/write Read/write Full access
// 1 00 - - Reserved
// 01 Read-only No access Read-only, only at PL1 or higher
// 10 Read-only Read-only Read-only at any privilege level, deprecateda
// 11 Read-only Read-only Read-only at any privilege levelb
06-25-2017 07:29 PM
hi John,
Is there a similar method for the Zynq MPSoC ?
06-27-2017 08:43 AM
Yes but I haven't dug to deeply yet. So far I've been cheating my marking the full PL address range as 'memory' by modifying translation_table.S.
I've only started a decoder ring for the A53 mmu. You can find known values for the mmu in the bsp xil_mmu.h file. And, Xil_SetTlbAttributes() is still available for the A53.