From the TRM of the Cortex A9 we can read in section 7.4.3 Cortex-A9 behavior for Normal Memory Cacheable memory regions:
SCTLR.C=1 The Cortex-A9 Data Cache is enabled. Some Cacheable accesses are still treatedas Non-Cacheable:• all pages marked as Write-Through are treated as Non-Cacheable• if ACTLR.SMP=0, all pages marked as Shared are treated as Non-Cacheable.
SCTLR.C=1 The Cortex-A9 Data Cache is enabled. Some Cacheable accesses are still treated
as Non-Cacheable:
• all pages marked as Write-Through are treated as Non-Cacheable
• if ACTLR.SMP=0, all pages marked as Shared are treated as Non-Cacheable.
I am only running on a single core, and I want to enable L1 and L2 caches without enabling the SCU (I have issues with that at the moment).
I tried to set ACTLR.SMP to 1 with the SCU disabled without any success so far (I get memory corruption), so how should I set my MMU to get L1 and L2 caches on ?
I think I need to map my pages with the S bit set to 0, is that correct ?
Ok, so at least I understood this part correctly.
At the moment, here is what I do:
- At boot (only core0 is running), I make sure SCTLR.{M,C,I,Z} are set to 0
- I set a stack to call C code & clear the bss
- I invalidate the SCU (writing 0xffff to the inval register), I set the SCU diag register bit 0 (SCU_BASE + 0x30 as per the errata) to 1 and then I enable the SCU
- I set the ACTLR.{SMP,FW} bits
- I invalidate the whole TLB, L1 I cache, BP cache & L1 D cache
- I configure the PL310 by invalidating it completely and enabling it
- I set the undocumented diag register for imx.6 erratas (bits 4, 6, 11 & 21)
- I set TTBR0,1,TTBCR and then I set the SCTLR.{M, C, I, Z} bits
Up to this point, I have quite a lot of crashes. I added a dsb before the DCISW in my L1 D cache invalidation routine (as per errata 764369) and I have a lot less crashes, I manage to boot quite often, but some crashes are still here.
I'm investigating my L1 Dcache invalidation routine to see if I do everything correctly, that might be the problem
Thank you for the explanations !
I'm not sure it really matters, on Cortex-A9 at least, since the caches are disabled but is there any reason you don't invalidate the CPU caches ASAP instead of leaving it to after you enable coherency management? On more modern cores, cache hits can still happen even if the caches are off, although most of those modern cores will be automatically invalidating their caches on 'cold' reset.
For the boot-time invalidation you shouldn't be using any IS-suffix cache maintenance. Apart from that I'm not sure what could be going on, it's a little hard to guess at the complexity of the issue if all we have is information that "it crashes and I see memory corruption". You mention next that you replaced your TLBIALLIS by ASID with TLBIALLIS - there are few reasons to invalidate the entire TLB or evict entire applications worth of translations at most points in kernel code - application exit is one, although you can usually rely on the entries being naturally evicted. Another is ASID re-use. Is it possible that you're not following the sequence defined for break-before-make or properly synchronizing your TTBR/CONTEXTIDR swap, depending on which version you're using (there are Cortex-A9 errata on it with the exact sequences..)?
Ta,
Matt