Part Number: PROCESSOR-SDK-AM64X
Other Parts Discussed in Thread: AM3358
Hello,
for a few days we try to port AM3358 PRU Software to the new AM64x-SK Board.
After we fit the new Register Names and adapt the recourceTable and intc_map.h to the actual pru-software-support-package, we are able to build the software in the CCS 11.1.
But when we tried to start the PRU software on the AM64x we got the following errors:
[ 3554.517870] remoteproc remoteproc5: powering up 30034000.pru [ 3554.523990] remoteproc remoteproc5: Booting fw image am64x-pru0_0-fw, size 138476 [ 3554.534494] remoteproc remoteproc5: PRU memory copy failed for da 0x100 memsz 0x6 [ 3554.542125] remoteproc remoteproc5: Failed to load program segments: -22 [ 3554.542171] remoteproc remoteproc5: Boot failed: -22
We think that this error occurs because of the following code in pru_rproc.c (from SDK 08.01.00.39):
/*
* Custom memory copy implementation for ICSSG PRU/RTU/Tx_PRU Cores
*
* The ICSSG PRU/RTU/Tx_PRU cores have a memory copying issue with IRAM
* memories, that is not seen on previous generation SoCs. The data is reflected
* properly in the IRAM memories only for integer (4-byte) copies. Any unaligned
* copies result in all the other pre-existing bytes zeroed out within that
* 4-byte boundary, thereby resulting in wrong text/code in the IRAMs. Also, the
* IRAM memory port interface does not allow any 8-byte copies (as commonly used
* by ARM64 memcpy implementation) and throws an exception. The DRAM memory
* ports do not show this behavior.
*/
static int pru_rproc_memcpy(void *dest, const void *src, size_t count)
{
const u32 *s = src;
u32 *d = dest;
size_t size = count / 4;
u32 *tmp_src = NULL;
/*
* TODO: relax limitation of 4-byte aligned dest addresses and copy
* sizes
*/
if ((long)dest % 4 || count % 4)
return -EINVAL;
/* src offsets in ELF firmware image can be non-aligned */
if ((long)src % 4) {
tmp_src = kmemdup(src, count, GFP_KERNEL);
if (!tmp_src)
return -ENOMEM;
s = tmp_src;
}
while (size--)
*d++ = *s++;
kfree(tmp_src);
return 0;
}
As Displayed in the error message above the data section has a size of 6 Bytes and this cannot divided with 4 Bytes, required in the pru_rproc_memcpy().
This error does not occur with the AM335 because the memcpy() function is used there:
if (pru->data->is_k3) {
ret = pru_rproc_memcpy(ptr, elf_data + phdr->p_offset,
filesz);
if (ret) {
dev_err(dev, "PRU memory copy failed for da 0x%x memsz 0x%x\n",
da, memsz);
break;
}
} else {
memcpy(ptr, elf_data + phdr->p_offset, filesz);
}
Is there a CCS Linker setting to avoid the Problem with the 6-Byte data section?
Otherwise, is it possible to resolve this Problem with an adapted Kernel driver. Maybe this suggestion would help
change:
size_t size = count / 4;
..
if ((long)dest % 4 || count % 4)
return -EINVAL;
to:
size_t size = (count + 3) / 4;
..
if ((long)dest % 4)
return -EINVAL;
Because the Destination Address is 4 Byte aligned it should be allways possible to use the next higher Size, if we are not 4 Byte aligned.
Regard
Steffen