工具与软件:
是否可以对 R5F 内部高速缓存存储器进行 ECC (SEC/DED)测试? 如果是、请提供相关步骤。
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.
工具与软件:
是否可以对 R5F 内部高速缓存存储器进行 ECC (SEC/DED)测试? 如果是、请提供相关步骤。
以下是在 AM6x/AM243器件上的 R5F 缓存存储器上测试 SEC/DED 的步骤:
1. 通过在启动序列中设置 ACTLR 寄存器来为 R5缓存存储器启用 ECC。
(请注意、启用缓存之前启用 ECC 很重要、因为启用缓存后启用 ECC 会导致意外中止)
分配给该寄存器的值完全取决于您的特定用例。 我们不建议为此寄存器使用任何严格的值。 但是 、考虑到 single-bit 错误会自动纠正、因此应避免中止可纠正的错误。 因此、您可以考虑将 ACTLR 寄存器设置为101、这将导致仅适用于不可纠正的错误的中止。

(屏幕截图取自 R5F TRM)
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register BIC r0, r0, #0x1 << 2 // Disable data cache bit BIC r0, r0, #0x1 << 12 // Disable instruction cache bit DSB MCR p15, 0, r0, c1, c0, 0 // Write System Control Register ISB // Ensures following instructions are not executed from cache MRC p15, 0, r1, c1, c0, 1 // Read Auxiliary Control Register ORR r1, r1, #(0x5 << 3) //Enable ECC for Cache MCR p15, 0, r1, c1, c0, 1 // Write Auxiliary Control Register MCR p15, 0, r0, c15, c5, 0 // Invalidate entire data cache MCR p15, 0, r0, c7, c5, 0 // Invalidate entire instruction cache MRC p15, 0, r0, c1, c0, 0 // Read System Control Register ORR r0, r0, #0x1 << 2 // Enable data cache bit ORR r0, r0, #0x1 << 12 // Enable instruction cache bit DSB MCR p15, 0, r0, c1, c0, 0 // Write System Control Register ISB
2.启用 R5F PMCR 寄存器的导出功能、将缓存事件路由到 ESM/ Pulsar 寄存器。
asm("MOV R5, #0x0");
asm("MRC P15,#0, R5, C9, C12,#0");
asm("ORR R5, R5, #0x2"); // Reset event counter
asm("MCR P15,#0, R5, C9, C12,#0");
asm("MRC P15,#0, R5, C9, C12,#0");
asm("ORR R5, R5, #0x11");
asm("MCR P15,#0, R5, C9, C12,#0");
asm("MOV r4, #0x60");
asm("MCR p15,#0,r4,c9,c13,#1");
3. 使用 SDL_ESM_init () API 初始化 ESM 模块并启用与 R5F 存储器对应的 ECC 事件:(随附的屏幕截图适用于 AM62x。 其他器件也会映射类似的事件)

4.在测试每个 RAM ID 之前、对整个 DCache/ICache 执行失效和回写
DCache:
CacheP_wbInvAll(CacheP_TYPE_L1D)
ICache:
CacheP_wbInvAll(CacheP_TYPE_L1P)
5.通过从高速缓存中执行32KB 的读操作来用虚值填充高速缓存。
DCache:
#define ARRAY_SIZE 32*1024 // Size of the array in bytes (32KB)
uint8_t a[ARRAY_SIZE];
uint8_t b[ARRAY_SIZE];
for(uint32_t iii=0;iii<ARRAY_SIZE;iii++)
{
a[iii]=(iii%256)+1;
}
ICache
您可以执行8192个虚拟指令的读取以完全填充 ICache。
void Fill_ICache()
{
asm("MOV R0, #0x0");
asm("MOV R0, #0x0");
.
.
.(8192 times)
.
asm("MOV R0, #0x0");
}
6. 使用 ECC Aggr. (下表中列出了 ECC 聚合设置)
a.对于 single-bit 错误注入:
uint32_t *ptr2=(uint32_t *)0x3f00d008; //Set RAM ID
*ptr2=0xD; // RAM ID 13 - DData0 RAM ID
uint32_t *ptr3=(uint32_t *)0x3f00d014; // ECC Ctrl Reg
*ptr3=0x28;
uint32_t *ptr5=(uint32_t *)0x3f00d008; // ECC vector Reg
*ptr5=0x148000;
while(((*ptr5>>24)&0x1)!=1) // Polling the Read done bit to ensure ECC aggr. gets properly updated
{
;
}
asm("NOP");
b.对于双位错误注入:
uint32_t *ptr2=(uint32_t *)0x3f00d008; //Set RAM ID
*ptr2=0xD; // RAM ID 13 - DData0 RAM ID
uint32_t *ptr4=(uint32_t *)0x3f00d01C; //ECC Error Control2 reg
*ptr4=0x30002;
uint32_t *ptr3=(uint32_t *)0x3f00d014; // ECC Ctrl Reg
*ptr3=0x28;
uint32_t *ptr5=(uint32_t *)0x3f00d008; // ECC vector Reg
*ptr5=0x148000;
while(((*ptr5>>24)&0x1)!=1) // Polling the Read done bit to ensure ECC aggr. gets properly updated
{
;
}
asm("NOP");
使用上述示例代码作为参考、可以对不同的 RAM ID 进行以下设置:
|
DCache RAM
|
秒
|
记录
|
|---|---|---|
| DTAG |
ECC 错误 Ctlr1寄存器(0x18) 0xFD ECC Ctlr 寄存器(0x14) 0x48 (FORCE_sec + ERROR_ONCE) |
ECC 错误 Ctlr2寄存器(0x1C) 0x30002 ECC Ctlr 寄存器(0x14) 0x30 (FORCE_DED + FORCE_n_ROW) |
| DDIrty |
ECC Ctlr 寄存器(0x14) 0x28 (FORCE_sec + FORCE_n_ROW) |
ECC 错误 Ctlr2寄存器(0x1C) 0x30002 ECC Ctlr 寄存器(0x14) 0x30 (FORCE_DED + FORCE_n_ROW) |
| DDATA |
ECC Ctlr 寄存器(0x14) 0x28 (FORCE_sec + FORCE_n_ROW) |
ECC 错误 Ctlr2寄存器(0x1C) 0x30002 ECC Ctlr 寄存器(0x14) 0x30 (FORCE_DED + FORCE_n_ROW) |
| ITAG |
ECC 错误 Ctlr1寄存器(0x18) 0xFD ECC Ctlr 寄存器(0x14) 0x48 (FORCE_sec + ERROR_ONCE) |
不适用 |
|---|---|---|
| iDATA |
ECC Ctlr 寄存器(0x14) 0x28 (FORCE_sec + FORCE_n_ROW) |
不适用 |
7.循环遍历整个 DCache 以触发 Data 和 Dtag RAM ID 错误。 对于 ddirty RAM、通过从高速缓存内存读取不同的32KB 来清除整个 DCache。 同样、 循环通过整个 ICache 来触发 iDATA 和 Itag RAM ID 的错误
DCache:
for(uint32_t i=0;i<ARRAY_SIZE;i++)
{
b[i]=a[i]; // Same arrays as defined in Step 5
}
ICache:
Fill_ICache() //Same function as defined in Step 5
注:
必须在 ISR (针对 single-bit 错误)内部额外禁用错误注入或通过将 ECC Ctlr 寄存器(0x14)设置为0来中止处理程序(针对 double-bit 错误)、以防止进一步的错误注入。
// Add the below code inside the ISR/Abort Handler whenever an ECC error is detected
// if error == R5F Cache ECC Error {
uint32_t *ptr3=(uint32_t *)0x3f00d014; // ECC Ctrl Reg
*ptr3=0x0;
uint32_t *ptr5=(uint32_t *)0x3f00d008; // ECC vector Reg
*ptr5=0x148000;
while(((*ptr5>>24)&0x1)!=1) // Polling the Read done bit to ensure ECC aggr. gets properly updated
{
;
}
//}
2.在执行双位错误注入时、我们可以获得对应于 DData 和 Dtag RAM ID 的同步中止和对应于 DDirty RAM 的异步中止。 如果触发异步中止检查并清除 CPSR 寄存器的 A 位存在延迟、则应在检测到错误后立即触发中止。