I’m trying to implement the allocation of shared DDR memory between CortexM7 and CortexA53 for the IMX8MP processor. I’m using the “Remote Core Share driver” from the NXP example - rmtcore_shm (files in attachment). It is based on the standard memory allocation approach:
buf_addr = dma_alloc_coherent(drvdata->dev, buf_size, &phy_addr, GFP_KERNEL);
The driver also works with the buffer as a file descriptor - open, read, write, seek, ioctl and close operations.
I use reference multimedia image (BSP 6.3.0, kernel 5.15.77) and added this driver to the compilation of kernel modules. I also added changes to the DTS file:
compatible = “fsl,rmtcore-shm”;
status = “okay”;
After starting the system, I see that the driver started without errors:
[ 4.637647] RMTCORE module started!
[ OK ] Mounted 4.641354] RMTCORE_SHM device major: 508
Now I can work with the data buffer in my Qt demo app as a file descriptor, which is made available in /dev/rmtcore_shm. I deduced the information available to me:
unsigned long long buf_addr_phys = 0; unsigned long long buf_addr_virt = 0; unsigned long long set_buf_size = DDR_CMA_BUF_SIZE; // 4096 unsigned long long get_buf_size = 0; fdi = open(RMTCORE_SHM_DEV, O_RDWR); ioctl(fdi, RMTCORE_SHM_CHG_BUF_SIZE, &set_buf_size); ioctl(fdi, RMTCORE_SHM_GET_BUF_SIZE, &get_buf_size); ioctl(fdi, RMTCORE_SHM_GET_BUF_ADDR_PHY, &buf_addr_phys); ioctl(fdi, RMTCORE_SHM_GET_BUF_ADDR_VIRT, &buf_addr_virt); fprintf(stderr, "Set buffer size: 0x%llx\r\n", set_buf_size); fprintf(stderr, "Get buffer size: 0x%llx\r\n", get_buf_size); fprintf(stderr, "Phys address: 0x%llx\r\n", buf_addr_phys); fprintf(stderr, "Virtual address: 0x%llx\r\n", buf_addr_virt);
When I allocate a buffer size from 1 to 4096 bytes everything works correctly and I can see the physical address of the available space:
Set buffer size: 0x1000
Get buffer size: 0x1000
Phys address: 0x400aa000
Virtual address: 0xffff80000a132000
But when I exceed the buffer size of 4096 (4097) I get an invalid physical address that is out of scope of CortexM (similar to the spare address scope):
Set buffer size: 0x1001
Get buffer size: 0x1001
Phys address: 0xee290000
Virtual address: 0xffff80000a237000
Please tell me what could be the reason?
I also paid attention to the information when starting the system:
DMA: preallocated 512 KiB GFP_KERNEL pool for atomic allocations
As far as I understand, this applies to all memory allocations for DMA, i.e. and for dma_alloc_coherent() in particular. The rmtcore_shm driver used allocates a predefined buffer size when opening a handle - RMTCORE_SHARE_MEM_DEFAULT_SIZE = (1 * 1024 * 1024) = 1MB. I assumed that this might be the problem and reduced this size to 256 kb and recompiled the image. But this did not solve the problem.
The question also arose, where can I change the value for “DMA: preallocated 512 KiB GFP_KERNEL” since I need to allocate 16 MB inside the CMA area using dma_alloc_coherent().
Thank you in advance for your time and help.