Subject: ARM exception handlers -- question
To: None <>
From: Jason R Thorpe <>
List: port-arm
Date: 11/08/2001 18:08:32
I'm in the process of porting to an XScale-based eval board.  I've run
into a little snag while writing the PCI support, and I need to get
some input/advice from the list.

Background: To read PCI configuration space, I poke an address register
with the IDSEL, etc. and then read the data from a data register.  If
the device does not exist, then the CPU gets a Data Abort when the data
register is read.

Obviously, I need to be able to handle this, as it is perfectly normal
to encounter non-existent PCI devices when scanning the bus.

It seemed pretty obvious how to deal with this -- implement a badaddr()
routine which sets data_abort_expected=1 and performs the load (returning
the value to the caller), and in the data abort handler, set
data_abort_received=1, adjust PC so that the faulting insn is skipped
when the handler returns, and return.

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 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).

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 :-)

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.  If people agree that Data Abort handling while
in SVC mode is indeed broken, I'll take a look at fixing our trap handlers
in a similar way.

BTW, I have to say that the arm26 exception handlers are a lot cleaner,
easier to read... I'd like for us to have a common set of handlers based
on the arm26 versions, eventually.

        -- Jason R. Thorpe <>