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.

Compiler/TDA4VMXEVM: TDA4VM: C7x memcpy doesn't work properly

Part Number: TDA4VMXEVM

Tool/software: TI C/C++ Compiler

Hi~

Recently we found that func memcpy in C7x did  not work properly,especially at the moment that C7x was receving IPC messages  in a high frequency.

we produced a memcpy_test like this:

void memcoy_test()

{

    int size, offset1, offset2;

    int data1[DATA_LEN_TEST*2];

    int data2[DATA_LEN_TEST*2];

    for ( size = 1; size < DATA_LEN_TEST; size++) {

        for ( offset1= 1; offset1< DATA_LEN_TEST; offset1++) {

            for ( offset2= 1; offset2< DATA_LEN_TEST; offset2++) {

               memset(data1, 0, sizeof(data1));

               memset(data2, 0xa3, sizeof(data2));

               // Hwi_disable()

               memcpy(&data1[offset1], &data2[offset2], size);

               // mymemcpy(&data1[offset1], &data2[offset2], size);

               //Hwi_enable();

               checkout(data1, data2, size, offset1, offset2);

            }

        }

    }

}

especially at the moment that C7x was receving IPC messages  in a high frequency, we sometimes got results likes this:.

data1 =>> |  0 0 0 0 0 ...0  |  0xa3 0xa3 0xa3 (copy from data2, length = size)... | 0xa3 0xa3(overflow, which was wrong)....| 0 0 0 0 .... |

data2 =>> | 0xa3 0xa3 0xa3 .......................................................................................................................................................................|

If we did Hwi_disable/Hwi_enable, func memcpy could work well, result:

data1 =>> |  0 0 0 0 0 ...0  |  0xa3 0xa3 0xa3 (copy from data2, length = size)... | 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 .... |

data2 =>> | 0xa3 0xa3 0xa3 .......................................................................................................................................................................|

Or, we used func mymemcpy,  also work well.

int mymemcpy(void* dst, void* src, int size)

{

  char *p, *q;

  int k = 0;

  p = (char*)dst;

  q = (char*)src;

  for (k=0; k<size; k++) {

    p[k] = q[k];

  }

  return size;

}

So, wo doubted that memcpy do not work properly, while it enter/exit  a Interrupt context..

We need promptly  support to solve this problem, please reply as soon as possible.

  • Hi,

    Yes this is known issue and we are working on a fix to be available by SDK 7.0 release (mid June)

    The issue is because of a bug in  bios_6_76_03_01 which is shipped part of psdk_rtos_auto_j7_06_02_00_21. 

    When you are using memcpy function, under the hood there is a vectorized implementation which uses predicated stores to handle non-multiple of 64 byte copies. But as the memcpy runs in the context of a task, the BIOS task handler is expected to save a restore the predicate registers appropriately, but this does not happen.

    This results in the copy being incorrect as a stale predicate register might be restored.

    We saw this issue in our existing AVP demos as well running TIDL. The workaround was to disable interrupts as you have done.

    In your own implementation of memcpy you dont observe any issue as you are not using vector operations to do the copy. As you are copying elements one by one, you dont see the issue.

    Regards,
    Shyam

  • Hi Shyam,

      Thanks a lot!

      Is it possible to temporarily provide a patch so that we can temporarily bypass this problem ?
    Regards,
    Lvan.zhang
  • Hi Lvan.zhang,

    The patch right now is to either disable interrupts or write a scalar copy function. The fix is very complex and requires a new BIOS version. We are in the process of bringing it up and should be available only by SDK 7.0

    Regards,
    Shyam