This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM64X: Porting PRU Software

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

  • Hello Steffen,

    Please note that the Linux RemoteProc driver is different in Linux kernel 5.10 than in earlier Linux releases, so the linker command file and the resource table & INTC map will also look different. You can find more information about the changes in the PRU Software Support Package (PSSP) commits: https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/commit/?id=56d8b147d6d9df2f68654d353e106638291d1a4b

    1) Does your project use RPMsg? The resource table is only needed if RPMsg is used. Note the different linker command files in these different projects:
    Example project without RPMsg, but with RemoteProc driver doing INTC mapping: PSSP/examples/am64x/PRU_Direct_Connect0
    Example project without RPMsg, and RemoteProc driver does not do INTC mapping: PSSP/examples/am64x/PRU_Halt

    2) If using RPMsg, make sure the linker command file aligns the resource table on an 8-byte address and includes the IRQ map. See the SECTIONS portion of
    PSSP/examples/am64x/PRU_RPMsg_Echo_Interrupt0/AM64x_PRU0_intc_rscTbl.cmd

    Regards,

    Nick

  • Hi Nick,

    thanks for your answer.

    We have a running setup of our PRU Code. The only Problem we have is, that the linker generates .data sections with a size not 4 Byte aligned (in our case the size was 6 Bytes).

    And this will be rejected from the pru_rproc while starting the program.

    What we actual do is to manual modify our variables and structs to get a .data section size which is 4 Byte aligned.

    Now we want a solution to avoid this manual modification. In our opinion there can be two possible ways to do that:

    1. set the correct Linker Settings

    2. modify the Kernel source of pru_rproc.

    To avoid any mistakes on our Settings here are the two files for ICSSG0_PRU0:

    ICSSG0_PRU0.zip

    and for ICSSG0_PRU1:

    ICSSG0_PRU1.zip

    Regards

    Steffen