Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Nov 2012 11:23:32 -0700
From:      Ian Lepore <freebsd@damnhippie.dyndns.org>
To:        Warner Losh <imp@bsdimp.com>
Cc:        freebsd-arm@freebsd.org
Subject:   Re: exynos4412 hangs on enabling MMU
Message-ID:  <1352658212.1217.14.camel@revolution.hippie.lan>
In-Reply-To: <7FA4A9AA-F217-4425-9A21-E0967237540C@bsdimp.com>
References:  <20121030123231.GA91006@jail.io> <1351607803.1120.27.camel@revolution.hippie.lan> <7FA4A9AA-F217-4425-9A21-E0967237540C@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-TGlwGHekoNL4VYMYypNE
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

On Tue, 2012-10-30 at 10:08 -0600, Warner Losh wrote:
> On Oct 30, 2012, at 8:36 AM, Ian Lepore wrote:
> 
> > On Tue, 2012-10-30 at 16:32 +0400, Ruslan Bukin wrote:
> >> hello!
> >> 
> >> exynos hangs on mcr cmd in this context:
> >> 
> >> /* Enable MMU */
> >> [..]
> >> orr     r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE)
> >> mcr     p15, 0, r0, c1, c0, 0
> >> [..]
> >> 
> >> without CPU_CONTROL_MMU_ENABLE flag, mcr command works,
> >> but board hangs again on line:
> >> str r3, [r1], #0x0004 /* get zero init data */
> >> 
> >> any suggestions?
> >> 
> >> -Ruslan
> > 
> > I don't have a direct answer to your question, but there is something
> > related that I've always wondered about locore.S...  It starts by
> > assuming the bootloader turned on the data cache, so it disables it,
> > then it sets up TTB and TLB and other MMU-related stuff, then it turns
> > back on the cache.  
> > 
> > Shouldn't it have flushed the cache in there somewhere before turning it
> > back on?  
> > 
> > The part I don't know is whether the cache flush happens implicitly as a
> > side effect of some of the other cp15 commands for setting up the MMU.
> > 
> > Also, I have no idea whether this is related or not, but on armv4
> > platforms on -current, the kernel init locks up somewhere in initarm()
> > about 20% of the time.  It locks up at different points, sometimes it
> > only makes it few lines into initarm(), sometimes it gets almost to the
> > end before locking up.  The variability makes me think it's somehow
> > related to caching or the MMU or something like that.  It's a problem
> > that never happens on freebsd 8, but I haven't had time yet to start
> > bisecting the changes to see where it quit working.
> 
> I'd be interested in tracking that down...  I've been booting lots of armv5 boards lately and haven't seen this hang with current.
> 
> Warner

So my mission this morning was to track this down, and I started by
diff'ing the current locore.S against the one from freebsd 8.2 that I
know for sure never hangs.  The significant difference jumped out at me
right away, and it's the code Ruslan referenced in his original post.

It appears there was a paste-o or mis-merge when the armv6 support came
in; it turns on the data cache too early.  Usually this is harmless (at
least for me), but sometimes there'll be something in the cache that
causes a hang, either immediately (as happens to Ruslan) or later when
some innocuous instruction sequence (such as returning from a function
call) stumbles across stale cache data and wanders into the weeds.

The attached patch fixes the problem, turning on the MMU but not
enabling data cache until later in the kernel init (it happens during
cpu_setup()).  There is a similar sequence to enable the MMU and data
cache at the bottom of locore.S.  I think it's the code that enables
processors other than the primary/boot.  Maybe it's okay to enable the
cache in that context, or maybe it's another paste-o.  I didn't change
it because I can't test that code.

For testing, I inserted a call to kern_reboot() in start_init() so that
I could get several different units here (atmel rm92 and sam9) all
rebooting constantly to see if they'd hang.  With the original locore.S
they always hang within 6-8 reboot cycles.  With the patched code
they've been rebooting continuously for several hours without a single
hang.

-- Ian


--=-TGlwGHekoNL4VYMYypNE
Content-Disposition: inline; filename="locore.S.diff"
Content-Type: text/x-patch; name="locore.S.diff"; charset="us-ascii"
Content-Transfer-Encoding: 7bit

diff -r 14a88c479800 sys/arm/arm/locore.S
--- a/sys/arm/arm/locore.S	Sat Nov 03 14:44:21 2012 -0600
+++ b/sys/arm/arm/locore.S	Sun Nov 11 10:42:13 2012 -0700
@@ -181,7 +181,7 @@ 3:
 #if defined(CPU_ARM11) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B)
 	orr	r0, r0, #CPU_CONTROL_V6_EXTPAGE
 #endif
-	orr	r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE)
+	orr	r0, r0, #(CPU_CONTROL_MMU_ENABLE)
 	mcr	p15, 0, r0, c1, c0, 0
 	nop
 	nop

--=-TGlwGHekoNL4VYMYypNE--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1352658212.1217.14.camel>