AnsweredAssumed Answered

LS2085ARDB data cache corruption

Question asked by yan yan on Feb 14, 2016
Latest reply on Mar 1, 2016 by Yuri Muhin

we encountered data corruption issues after D-cache disable/enable cycle on LS2085ARDB board, the code sequence is:

1. disable the global Data/Unify cache by clearing SCTLR.C bit;

2. do cache clean by way/set as recommended by ARM user manual;

3. modify data when cache disabled;

4. re-enable Data/Unify cache by setting SCTRL.C bit;

5. the modified data in step 3 is not visible any more.

 

This issue is observed in both AARCH64 and AARCH32 modes. We created a small testcase as shown below; this testcase is loaded by u-boot. a brief explanation of the test code:

1. the testcase is loaded to address 0x80100000, and from the u-boot shell, 'go 0x80100000' to enter the testcase.

2. the testcase just replicates the above described sequence, first, it writes constant #1 to address 0x80000000, then disable and clean the cache, and write constant #2 to 0x80000000, after that, enable the cache again, and try reading from 0x80000000; if the read value is #2, then the modification is visible and test passed ('A' is printed on console), otherwise 'B' is printed. Please note the testcase inherits the MMU & page attributes settings from the LS2085ARDB u-boot, which is cacheable writeback for address at 0x80000000.

 

=======================================

Test code:

 

retry:

        LDR     x0, =0x80000000

        MOV     x1, #1

        STR     x1, [x0]

 

        /********************************************clean all ****************/

        DMB     SY                                                                                                                                                               

        MRS     X0, CLIDR_EL1                                                                               

        AND     W3, W0, #CLIDR_LOC                                                                          

        LSR     W3, W3, #(CLIDR_LOC_SHIFT - 1)   /* get 2x LoC */                                           

        CBZ     W3, 5f                                                       /* done */                                                 

        MOV     W10, #0                          /* W10 = 2x LoC */                                         

        MOV     W8, #1                           /* W8 = constant 0b1 */

1:                                                                                                          

        ADD     W2, W10, W10, LSR #1             /* W2 = 3x LoC */                                          

        LSR     W1, W0, W2                                                                                  

        AND     W1, W1, #CLIDR_CTYPE_MASK        /* get cache type */                                       

        CMP     W1, #CLIDR_CTYPE_D                                                                          

        B.LT    4f                               /* skip if no or i-cache */                                

        MRS       X14, DAIF

        MSR       DAIFSet, #3

        MSR     CSSELR_EL1, X10                  /* select this cache */                                    

        ISB                                      /* Synchronize change of CSSELR */                         

        MRS     X1, CCSIDR_EL1                   /* read CCSIDR */                                          

                MSR       DAIF, X14

        AND     W2, W1, #CCSIDR_LINESIZE_MASK    /* W2 = log2(linelen)-4 */                                 

        ADD     W2, W2, #4                       /* W2 = log2(linelen) */                                   

        UBFX    W4, W1, #3, #10                  /* W4 = max way number/associativity */                    

        CLZ     W5, W4                           /* W5 = 32-log2(ways), bit position of way in DC operand */

        LSL          W9, W4, W5                                /* W9 = max way number, aligned to position in DC operand */

        LSL          W12, W8, W5                              /* W12 = amount to decrement way number per iteration */   

2:                                                                                                          

        UBFX     W7, W1, #13, #15                      /* W7 = max set number, right aligned */                   

        LSL          W7, W7, W2                                /* W7 = max set number, aligned to position in DC operand */

        LSL          W13, W8, W2                              /* W13 = amount to decrement set number per iteration */   

3:                                                                                                          

        ORR       W11, W10, W9                            /* W11 = combine way number and cache number */            

        ORR       W11, W11, W7                            /* and set number for DC operand */                        

        DC          CISW, X11                                     /* Do data cache operation by set and way */               

        SUBS     W7, W7, W13                              /* Decrement set number */                                 

        B.GE      3b                                                                                          

        SUBS     X9, X9, X12                                   /* Decrement way number */                                 

        B.GE      2b                                                                                          

4:                                                                                                          

        ADD       W10, W10, #2                             /* Increment 2 x cache level */                            

        CMP      W3, W10                                                                                     

        DSB        SY

        B.GT      1b                                                                                          

5:                                                                                                          

        MOV     X10, #0                          // swith back to cache level 0                             

        MSR     CSSELR_EL1, X10                  // select current cache level in csselr                    

        DSB     SY                                                                                          

        ISB

 

        /********************************************clean done **************/

 

        MRS       X0, SCTLR_EL3

        BIC         X0, X0, SCTLR_C   /* disable D-Cache */

        MSR       SCTLR_EL3, X0

        ISB          SY           /* Guarantees visibility to instruction fetch */

 

 

      

        LDR        x0, =0x80000000

        MOV     x1, #2

        STR         x1, [x0]

 

        MRS       X0, SCTLR_EL3

        ORR       X0, X0, #SCTLR_C  /* enable d-cache*/

        MSR       SCTLR_EL3, X0

        ISB          SY           /* Guarantees visibility to instruction fetch */

 

 

        LDR        x0, =0x80000000

        LDR        x1, [x0]

        CMP      x1, #2

        BNE        error

ok:

        LDR        x2, =0x21c0600

        MOV     x3, #65

        STRB      w3, [x2]

        B             retry

error:   

        CMP      x1, #1

        BNE        2f

 

        LDR        x2, =0x21c0600

        MOV     x3, #66

        STRB      w3, [x2]

        B             .

 

2:           

        LDR        x2, =0x21c0600

        MOV     x3, #67

        STRB      w3, [x2]

        B             .

 

/* end */

Outcomes