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 */