SPRZ576 November   2024 AM2612

ADVANCE INFORMATION  

  1.   1
  2.   Abstract
  3. 1Usage Notes and Advisories Matrices
  4. 2Silicon Revision 1.0 Usage Notes and Advisories
    1. 2.1 Silicon Revision 1.0 Usage Notes
      1.      i2324
    2. 2.2 Silicon Revision 1.0 Advisories
      1.      i2189
      2.      i2310
      3.      i2311
      4.      i2345
      5.      i2351
      6.      i2352
      7.      i2353
      8.      i2354
      9.      i2356
      10.      i2357
      11.      i2358
      12.      i2359
      13.      i2374
      14.      i2383
      15.      i2411
      16.      i2412
      17.      i2427
      18.      i2428
      19.      i2433
      20.      i2439
      21.      i2440
  5. 3Trademarks
  6. 4Revision History

i2433

ICSS: Reading the 64-bit IEP timer does not have a lock MSW logic when LSW is read

Details:

IEPx 64-bit timestamp can be incorrect when lower 32-bit data is 0xFFFFFFFC or above (at 250MHz). In this case the upper 32-bit value is updated but lower value is the old number. The issue is seen when IEP counter (IEP_COUNT_REG1 : IEP_COUNT_REG0) is read back-to-back from ICSS PRU cores.

Example 1:

1st read : 0x000000D0(Upper):0xFFFFFFFC(lower)

2nd read : 0x000000D0(Upper):0x00000028(lower)

Example 2:

1st read : 0x000000D7(Upper):0xFFFFFFFC(lower)

2nd read : 0x000000D7(Upper):0x0000002C(lower)

Example 3:

1st read : 0x000000D6(Upper):0xFFFFFFF0(lower)

2nd read : 0x000000D7(Upper):0xFFFFFFFC((lower)

As shown above, this leads to timer increment behavior that is non-monotonic or timer differences to be unusually large as in Example 3 . This is due to 1 cycle race condition when loading 64-bit value from IEPx counter.

Workaround(s):

Note: these workarounds exist in SDK9.2 and later

Workaround in C for PRU:

uint64_t timestamp = (uint64_t) (0x2E0010); 

/* Workaround starts here */

if ((timestamp & 0xFFFFFFFF) >= 0xFFFFFFFC)

{     timestamp = *(uint64_t*) (0x2E0010); } 

/* Workaround ends here */

Workaround in assembly for PRU:

 ldi32 r4, 0xFFFFFFFC ; 0-4 for 250MHz clock
    ;load 64-bit timestamp to r2:r3
    lbco &r2, c26, 0x10, 8
    qbgt skip_iep_read_errata. r2, r4
    ;re-read IEP if IEP_COUNTER_LOW >= 0xFFFF_FFFC
    lbco &r2, c26, 0x10, 8
skip_iep_read_errata: 

Workaround in C for R5F, A53:

uint64_t getIepTimeStamp64 (void)
{
    uint64_t u64Timestamp1 = (volatile uint64_t)(0x300AE010);
    uint64_t u64Timestamp2 = (volatile uint64_t)(0x300AE010);
    if (u64Timestamp2 > u64Timestamp1)
    {
#ifdef __DEBUG
        if (((u64Timestamp2 >> 32)-(u64Timestamp1 >> 32)) == 1)
        {
            /* HW errata fixed due to picking u64Timestamp1*/
            if ((u64Timestamp2 & 0xFFFFFFFF) >= (u64Timestamp1 & 0xFFFFFFFF))
           

{                 DebugP_log ("Errata fixed (1): %llx : %llx\r\n", 
        u64Timestamp1, u64Timestamp2);             }

        }
#endif
        return u64Timestamp1;
    }
    else
    {
#ifdef __DEBUG
        if ((u64Timestamp2 & 0xFFFFFFFF) < (u64Timestamp1 & 0xFFFFFFFF))
       

{             /* Adjust the IEP MSW in the case running into HW errata */             
    DebugP_log ("Errata fixed (2): %llx : %llx\r\n", u64Timestamp1, 
u64Timestamp2);         }

#endif
        /* HW errata fixed due to picking u64Timestamp2*/
        return u64Timestamp2;
    }
}