I would like to test the single-bit parity check detection on L1 data cache of the T2080 SoC containing e6500 core. For this purpose I set some bits in the L1CSR0 as recommended in the EREF and e6500 reference manuals in order to enable parity check and parity fault injection. According to the manuals, once a DCP_ERROR is raised in the MCSR, a machine check routine is executed and the address of the function to be executed once the interrupt is raised is should be specified in IVPR+IVOR1 registers. I follow instructions of reference manuals and could not make it works. In fact, the processor is stuck within the machine check routine and loops on the machine check routine despite the rfmci instruction (which is not executed because of new coming exception while being in the machine check handler). Please could someone have : 1. Some hint on why the processor is stuck and loops on the machine check error routine ? 2. An example of assembly code which detects single-bit parity error, process the error and returns back to the main function?
Here is a example of the assembly code I wrote :
L1_Parity_Test:
/*Setting the interrupt vector*/
LOAD_REG_32(r5, parity_error_check_vector)
mtspr CPU_PPC_E500_IVPR, r5
xor r4, r4, r4
LOAD_REG_32(r4, parity_error_check_vector)
mtspr CPU_PPC_E500_IVOR1, r4
/*Enabling Machine Check MSR[ME] ans MSR[RI]*/
xor r4, r4, r4
li r4, 0x1
li r5, 0xC
slw r6, r4, r5
xor r4, r4, r4
li r4, 0x2
or r6, r6, r4
sync
isync
mtmsr r6
isync
/*Enabling Parity detection and data cache error injection type*/
LOAD_REG_32(r5, CPU_PPC_E500_L1CSR0_CE | CPU_PPC_E500_L1CSR0_CPE | CPU_PPC_E500_L1CSR0_CEI)
mfspr r4, CPU_PPC_E500_L1CSR0
or r4, r4, r5
sync
isync
mtspr CPU_PPC_E500_L1CSR0, r4
isync
/*1:*/
/* wait while running */
/*sync
mfspr r4, CPU_PPC_E500_MCSR
andis. 0, r4, 0x2000*/ /* MCSR_DCPERR */
/*bne 1b*/
blr /*End of l1 cache parity test */
.align 4
parity_error_check_vector:
wrtee 0
/*Disabling parity fault injection*/
LOAD_REG_32(r5, CPU_PPC_E500_L1CSR0_CE | CPU_PPC_E500_L1CSR0_CPE)
sync
isync
mtspr CPU_PPC_E500_L1CSR0,r5
isync
/* invalidate d-cache */
xor r4, r4, r4
sync
/*Disabling L1 data cache */
isync
mtspr CPU_PPC_E500_L1CSR0, r4
isync
/* Compliant with A004778: LFC is done in the same mtspr that FI */
LOAD_REG_32(r5, CPU_PPC_E500_L1CSR0_CFI | CPU_PPC_E500_L1CSR0_CLFC)
sync
isync
mtspr CPU_PPC_E500_L1CSR0,r5
isync
loop:
mfspr r4, CPU_PPC_E500_L1CSR0
and. r4, r4, r5
bne loop
/*Store MCSRRO in r0 and MCSRR1 in r1*/
xor r0, r0, r0
mfspr r0, CPU_PPC_E500_MCSRR0
xor r1, r1, r1
mfspr r1, CPU_PPC_E500_MCSRR1
xor r2, r2, r2
mfspr r2, CPU_PPC_E500_MCAR
/*Writing contents that were read from the MCSR back to the MCSR in order to clear only status bits that were previously read*/
mfspr r4, CPU_PPC_E500_MCSR
sync
isync
mtspr CPU_PPC_E500_MCSR, r4
isync
/*Disabling Machine Check MSR[ME]*/
xor r4, r4, r4
sync
isync
mtmsr r4
isync
/*Re-enabling L1 data cache*/
LOAD_REG_32(r5, CPU_PPC_E500_L1CSR0_CE | CPU_PPC_E500_L1CSR0_CPE)
mfspr r4, CPU_PPC_E500_L1CSR0
or r4,r4,r5
mtspr CPU_PPC_E500_L1CSR0,r4
/*Updating the address of the next instruction to be executed before the interrupt occurs*/
sync
isync
mtspr CPU_PPC_E500_MCSRR0, r0
isync
/*Returning from machine check interrupt*/
rfmci