Part Number: J784S4XEVM
Hi Team,
I am using UDMA to perform a memory-to-memory copy on an R5F core.
The destination buffer is located in a shared DDR region that is accessed from the R5F through RAT address translation. When I copy data to this region using CPU memcpy(), the data is written correctly and can be read from the expected DDR address.
However, when I use UDMA to copy data to the same buffer region, the transfer appears to complete successfully, but the data is not written to the expected memory location. The destination buffer contents remain unchanged.
From this behavior, I suspect that UDMA may not be using the R5F RAT-translated address view. In other words, the CPU can access the buffer through the RAT-mapped address, but UDMA may require the actual SoC/DDR physical address instead of the R5F RAT alias address.
Could you please confirm the following?
1. Does UDMA access memory through the R5F RAT mapping, or does RAT only apply to R5F CPU accesses?
2. Are there any additional settings required, such as firewall/board configuration or address translation settings, to allow UDMA to access a shared DDR region that is mapped through RAT for the R5F?
3. If the destination region is accessed by the R5F through a RAT-mapped 64-bit address, what is the recommended way to pass the correct address to UDMA?
For reference, the issue occurs only with UDMA. CPU memcpy() to the same region works correctly.
RAT Config: DDR address 0x900000000 mapping to 0xE0000000
#if defined(BUILD_MCU1_0)
//CSL_MCU_R5FSS0_RAT_CFG_BASE
#define RAT_BASE (0x40f90000UL)
#endif
#if defined(BUILD_MCU2_0)
//CSL_R5FSS0_RAT_CFG_BASE
#define RAT_BASE (0xff90000UL)
#endif
#if defined(BUILD_MCU3_0)
#define RAT_BASE (0xff90000UL)
#endif
#if defined(BUILD_MCU4_0)
#define RAT_BASE (0xff90000UL)
#endif
/* Set Ragion Address Translation */
void SetRAT()
{
#if defined(BUILD_MCU1_0) || defined(BUILD_MCU2_0) || defined(BUILD_MCU3_0) || defined(BUILD_MCU4_0)
uint32_t region_id = 0;
*(unsigned int *)(RAT_BASE + 0x44 + (region_id*0x10)) = BASE_ADDR; //IN ADDRESS
*(unsigned int *)(RAT_BASE + 0x48 + (region_id*0x10)) = PHY_ADDR_LO; //lower 32bits of the real physical address
*(unsigned int *)(RAT_BASE + 0x4C + (region_id*0x10)) = PHY_ADDR_HI; //Upper 16 bits of the real physical address.
*(unsigned int *)(RAT_BASE + 0x40 + (region_id*0x10)) = 0x8000001C; // bit[31:31] : enable bit[5:0] size (2^SIZE)
#endif
}
DestBuf, linker, MPU Config
I only changed the destBuf in the example code (udma_memcpy_test) to the mapped variable shown below.
uint8_t shared_buffer[SHARED_BUF_SIZE] __attribute__ ((section (".shared_data_buffer"), aligned (UDMA_CACHELINE_ALIGNMENT)));
>> linker memory setting
#define DDR_SHARED_BUFFER_START 0xE0000000 /* shard memory */
#define SHARD_BUFFER_CORE_SIZE 0x01000000 /* 16 MB */
#define SHARD_BUFFER_TOTAL_SIZE 0x04000000
/*--------------------------- Shared Memory --------------------------*/
#define SHARED_MEM_CORE1_BASE DDR_SHARED_BUFFER_START
#define SHARED_MEM_CORE2_BASE SHARED_MEM_CORE1_BASE + SHARD_BUFFER_CORE_SIZE
#define SHARED_MEM_CORE3_BASE SHARED_MEM_CORE2_BASE + SHARD_BUFFER_CORE_SIZE
#define SHARED_MEM_CORE4_BASE SHARED_MEM_CORE3_BASE + SHARD_BUFFER_CORE_SIZE
SHARED_MEM_CORE1 (RWIX) : ORIGIN = SHARED_MEM_CORE1_BASE LENGTH = SHARD_BUFFER_CORE_SIZE
SHARED_MEM_CORE2 (RWIX) : ORIGIN = SHARED_MEM_CORE2_BASE LENGTH = SHARD_BUFFER_CORE_SIZE
SHARED_MEM_CORE3 (RWIX) : ORIGIN = SHARED_MEM_CORE3_BASE LENGTH = SHARD_BUFFER_CORE_SIZE
SHARED_MEM_CORE4 (RWIX) : ORIGIN = SHARED_MEM_CORE4_BASE LENGTH = SHARD_BUFFER_CORE_SIZE
.shared_data_buffer (NOINIT) : {} palign(128) > __CORE_SHARED_MEM
>> MPU Region Setting
{
/* Region 10 configuration: shared buffer */
.regionId = 10U,
.enable = 1U,
.baseAddr = 0xE0000000,
.size = CSL_ARM_R5_MPU_REGION_SIZE_256MB,
.subRegionEnable = CSL_ARM_R5_MPU_SUB_REGION_ENABLE_ALL,
.exeNeverControl = 0U,
.accessPermission = CSL_ARM_R5_ACC_PERM_PRIV_USR_RD_WR,
.shareable = 1U,
.cacheable = (uint32_t)FALSE,
.cachePolicy = CSL_ARM_R5_CACHE_POLICY_NON_CACHEABLE,
.memAttr = 0U,
},
Use memcpy function Result:
root@j784s4-evm:~# devmem2 0x901000000
/dev/mem opened.
Memory mapped at address 0xffffa1d47000.
Read at address 0x901000000 (0xffffa1d47000): 0x03020100
root@j784s4-evm:~# devmem2 0x901000004
/dev/mem opened.
Memory mapped at address 0xffff810c6000.
Read at address 0x901000004 (0xffff810c6004): 0x07060504
root@j784s4-evm:~#
>>> R5F Core Print Result
[MCU2_0] UDMA:START
UDMA memcpy application started...
destBuf: 0xe1000000 //RAT map address = 0x901000000
[Error] Data mismatch!!
[Error] UDMA App memcpy test failed!!
[Error] UDMA App delete failed!!
[Error] UDMA App deinit failed!!
UDMA memcpy using TR15 block copy Failed!!
Some tests have failed!!
>>> Linux devmem2 read result
root@j784s4-evm:~# devmem2 0x901000000
/dev/mem opened.
Memory mapped at address 0xffff9b6d5000.
Read at address 0x901000000 (0xffff9b6d5000): 0x00000000
root@j784s4-evm:~# devmem2 0x901000004
/dev/mem opened.
Memory mapped at address 0xffff84fe4000.
Read at address 0x901000004 (0xffff84fe4004): 0x00000000
root@j784s4-evm:~#
The only error message in the test result is related to the source/destination comparison after the transfer. There are no errors related to UDMA configuration, creation, or the transfer itself.