1

turning off/on mmu is not a good way to switch TTB_BASE in ARM as far as I know .So what is the better way ? Is the main steps like this ? (ARM 920T ARMV4T)

1 . sync dcache --> external memory
2 . clean_icache () && invalidate_dcache () ; // this is my question ,if the current instruction alreay in icache ,then I clean & invalidate them ,how can ARM core knows what is the next step ? May ARM core fetch instructions from external memory again ?
3. invalidate whole tlb
4. change the ttb base register

Is there another better way ? Any help appreciated ! ^_^

true_casey
  • 79
  • 1
  • 11
  • ARM memory management has evolved quite a bit through the progression of the architecture. Please provide information about what processor or architecture version you are targeting. – unixsmurf May 08 '13 at 09:35
  • ARM920T arm core ARMV4T arch . – true_casey May 08 '13 at 11:24

1 Answers1

2

Switching the TTB_BASE is much the same as turning on the MMU. Before the operation, there is one memory space and after there is another. You need your currently executing code to remain valid during the operation. Choices are,

  1. Map current code to same location in both.
  2. Rely on a cache to transition.

The 1st is basically with phys == virt when enabling the MMU. When updating the TTB_BASE a complete copy of the old version is the most basic. If interrupts are locked, you may only need to map pages needed by the switching code. This maybe a two phase operation where the current code page is eventually re-located to some other memory address. First alias the page, branch to the alias location and remove the original page. At every step, it is safe to flush the TLB and caches. You may not need to do this, depending on the context of the change. However, after the first flush, sub-sequent flushes are not expensive for each of d-cache, i-cache and TLB.

The 2nd method is rather flakey. On the StrongARM, this was known as the dance of death, when enabling the MMU. Basically, the instructions where timed so that prefetching and NOP padding would sequence the instructions so that a branch was performed from the phys address to the virt address right at the time of transition. For updating the TTB_BASE, you can assume that the current code page is in the TLB and if the code is aligned properly it starts an I-CACHE line. There are about six instructions that maybe performed after the TTB_BASE update before any memory will be fetched by the CPU. It is a full page, if you don't flush the TLB.

I can only see the 2nd method being used in the case of a hypervisor that wants to switch an entire memory map frequently; generally hypervisors will only change part of the memory map on a context switch. The 2nd method is slightly faster, but the down sides should be obvious.

artless noise
  • 21,212
  • 6
  • 68
  • 105