JAJZ022A November 2024 – April 2025 AM2612
ICSS:LSW が読み取られるとき、64 ビット IEP タイマの読み取りにはロック MSW ロジックがありません
下位 32 ビットデータが 0xFFFFFFFC 以上の場合、IEPx 64 ビットのタイムスタンプが不正確になる可能性があります(250MHz の場合)。この場合、上位 32 ビットの値は更新されますが、下位の値は古い値です。この問題は、ICSS PRU コアから IEP カウンタ(IEP_COUNT_REG1:IEP_COUNT_REG0)を連続的に読み取ったときに見られます。
事例 1:
1st 読み取り値:0x000000D0(上位):0xFFFFFC(下位)
2nd 読み取り値:0x000000D0(上位):0x00000028(下位)
事例 2:
1st 読み取り値:0x000000D7(上位):0xFFFFFFFC(下位)
2nd 読み取り値:0x000000D7(上位):0x0000002C(下位)
事例 3:
1st 読み取り値:0x000000D6(上位):0xFFFFFFF0(下位)
2nd 読み取り値:0x000000D7(上位):0xFFFFFFFC(下位)
上に示したように、これにより、例 3 のように非単調またはタイマの差であるタイマ インクリメント動作が異常に大きくなります。これは、IEPx カウンタから 64 ビット値をロードするときの 1 サイクル競合状態によるものです。
注:これらの回避方法は SDK9.2 以降で存在します
PRU の C での回避方法:
uint64_t timestamp = (uint64_t) (0x2E0010);
/*回避方法ここから開始*/
if ((timestamp & 0xFFFFFFFF) >= 0xFFFFFFFC)
{ timestamp = *(uint64_t*) (0x2E0010); }
/*回避方法ここで終了*/
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:
R5F、A53 の C での回避方法:
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;
}
}