AnsweredAssumed Answered

L1 data cache parity error test T2080

Question asked by Perrin NTAFAM on Nov 13, 2018

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

Outcomes