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