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/>