Subject: Re: ARM exception handlers -- question
To: Jason R Thorpe <thorpej@wasabisystems.com>
From: Ben Harris <bjh21@netbsd.org>
List: port-arm
Date: 11/09/2001 13:30:08
On Thu, 8 Nov 2001, Jason R Thorpe wrote:
> This should have worked, of course. However, in attempting to determine
> why it *didn't* work, I've become very confused as to just exactly what
> the low-level exception handlers are doing.
>
> In particular, the PUSHFRAMEINSVC is a little confusing. The comment
> above it states that it should not be used if the CPU is already in SVC
> mode -- but the CPU *IS* in SVC mode when I take my Data Abort.
The comment means that it shouldn't be called from an exception handler
that's entered in SVC32 mode (which I think is just SWI). Data aborts are
handled in ABT32 mode, so using PUSHFRAMEINSVC is fine.
> The PUSHFRAMEINSVC macro specifically stores USR_sp and USR_lr on
> the stack:
>
> stmia r0, {r13-r14}^; /* Push the user mode registers */ \
>
> Obviously, I want to be storing SVC_sp and SVC_lr (which should be no
> problem in a fixed fault handler, since this op is done after switing
> from ABT mode to SVC mode).
A few lines earlier:
str r0, [sp, #-4]!; /* Push return address */ \
str lr, [sp, #-4]!; /* Push SVC lr */ \
str r2, [sp, #-4]!; /* Push SVC sp */ \
These get restored by the final LDMIA in PULLFRAMEFROMSVCANDEXIT.
> Now, my real question is -- how on EARTH does copyin()/copyout() work?
> Those routines are going to be called while already in SVC mode, and it's
> possible to take a Data Abort in those routines (to fault in the user
> page). How does the pcb_onfault handling actually work here? I'm obviously
> missing something subtle (bear with me -- I'm basically taking a crash
> course in ARM, here :-)
As above, PUSHFRAMEINSVC puts both the SVC and USR registers in the
trapframe, and PULLFRAMEFROMSVCANDEXIT pops them. data_abort_handler
twiddles tf_pc as necessary to return to the right place.
> I'll note that the way Linux handles this problem is pretty clever --
> it uses a table, indexed by the SPSR mode bits, to select which stack
> frame pushing method is used.
That saves having to push SVC registers when taking a fault from USR mode
and vice versa, at the expense of more complex code. It might be
worthwhile, and I do something like that when handling IRQs on arm26.
> BTW, I have to say that the arm26 exception handlers are a lot cleaner,
> easier to read...
That's because I have to be able to understand them, and I'm easily
confused.
> I'd like for us to have a common set of handlers based
> on the arm26 versions, eventually.
Yeah, that'd be nice.
--
Ben Harris <bjh21@netbsd.org>
Portmaster, NetBSD/arm26 <URL:http://www.netbsd.org/Ports/arm26/>