Subject: cpu_reset hang disabling MMU
To: None <port-arm@netbsd.org>
From: Todd Allan <todd_allan@picovex.com>
List: port-arm
Date: 08/16/2006 17:54:10
arch/arm/arm32/locore.S: cpu_reset turns off MMU and caches with this
code fragment:
mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
mcr 15, 0, r0, c1, c0, 0
The mcr immediately hangs on my board when the r0 value disables the
instruction cache (modifying r0 to preserve the instruction cache can
allow execution to proceed for at least a short time).
Since PC will now point to the kernel virtual address of the mcr
instruction + 4 and the MMU has been disabled, and since the kernel
virtual address of this memory page is not equal to its physical
address, it's not surprising it crashes. The ARM ARM B3-5 claims it is
"strongly recommended that code which enables or disables the MMU has
identical virtual and physical addresses". The above code works fine on
this board when I create a virtual == physical mapping for the cpu_reset
code and execute it from that virtual address.
I've only a hacked a workaround for now (a pmap_map_chunk for a 1MB
section -- after intruding into pmap.c internals to get the current L1
PTE KVA -- assuming cpu_reset doesn't straddle a 1M boundary). I wanted
to ask whether anyone has any suggestions or comments on what I've
perceived as a problem. I searched the archives for previous discussion
but found only a question from two years ago:
http://article.gmane.org/gmane.os.netbsd.ports.arm/997/match=cpu+reset .
I can cook up a better fix if there's agreement this should be done.
Any comments appreciated, thanks,
Todd