0% found this document useful (0 votes)
5 views

Exception_handlingand algorithms

The document provides an overview of exception and interrupt handling with ARM processors, detailing the processes involved when exceptions occur, including the copying of registers and setting of program counters. It explains various types of ARM exceptions, their priorities, and the structure of the vector table used for handling these exceptions. Additionally, it discusses the use of interrupt controllers to manage multiple interrupt sources and the enhancements in ARM v6 cores for improved exception handling.

Uploaded by

fentexprep
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Exception_handlingand algorithms

The document provides an overview of exception and interrupt handling with ARM processors, detailing the processes involved when exceptions occur, including the copying of registers and setting of program counters. It explains various types of ARM exceptions, their priorities, and the structure of the vector table used for handling these exceptions. Additionally, it discusses the use of interrupt controllers to manage multiple interrupt sources and the enhancements in ARM v6 cores for improved exception handling.

Uploaded by

fentexprep
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 67

Valpont.

com, a Technology Content Platform

Exception and Interrupt


Handling with ARM Processors

063v11 1
Valpont.com, a Technology Content Platform

Interrupt Timeline and Simple ISR

063v11 2
Valpont.com, a Technology Content Platform

Exception Handling
 When an exception occurs, the ARM:
 Copies CPSR into SPSR_<mode>
 Sets appropriate CPSR bits
 If core currently in Thumb state then
ARM state is entered
 Mode field bits
 Interrupt disable bits (if appropriate)
 Stores the return address in LR_<mode>
 Sets PC to vector address
 Different for v6 with vectored interrupts -
see later
 To return, exception handler needs to:
 Restore CPSR from SPSR_<mode>
 Restore PC from LR_<mode>

 This can only be done in ARM state

063v11 3
Valpont.com, a Technology Content Platform

ARM Exceptions

• Reset - executed on power on


• Undef - when an invalid instruction reaches
the execute stage of the pipeline
• SWI - when a software interrupt instruction is
0x1C FIQ executed
0x18 IRQ
• Prefetch - when an instruction is fetched
0x14 (Reserved) from memory that is invalid for some reason,
0x10 Data Abort if it reaches the execute stage then this
0x0C Prefetch Abort exception is taken
0x08 Software Interrupt • Data - if a load/store instruction tries to
0x04 Undefined Instruction access an invalid memory location, then this
0x00 Reset exception is taken
Vector Table • IRQ - normal interrupt
Vector table may be placed at • FIQ - fast interrupt
0xFFFF0000 on ARM720T,
ARM9 family and later devices

063v11 4
Valpont.com, a Technology Content Platform

Exception Handling
Exception handling on the ARM is controlled through the use
of an area of memory called the vector table. This lives
(normally) at the bottom of the memory map from 0x0 to 0x1c.
To support WinCE applications, most of the cached cores
allow the vector table to be moved from 0x0 to 0xFFFF0000.
All current cores except 7TDMI, 740T and 7TDMI-S support
this - including SA-1100/1110 and XScale. Selection is either
by asserting HIVECS input on reset or by software control via
CP15.

Within this table one word is allocated to each of the various


exception types.

This word will contain some form of branch instruction. It will


not contain an address.

063v11 5
Valpont.com, a Technology Content Platform

Exception Handling
When one of these exceptions is taken, the ARM goes through a set of actions
(as shown on the slide) in order to invoke the appropriate exception handler.

To return, the core must:


• Restore CPSR from SPSR_<mode> : This will automatically restore the
original mode, state (ARM/Thumb), interrupt settings and condition codes
• Restore PC using “return address” stored in LR_<mode> : This will continue
execution of the application from the place where the exception occurred.

Return has to be done from ARM state. There is no Thumb instruction to copy
SPSR back into CPSR
v6 vectored interrupts will take the IRQ handler address directly from the VIC via
the IRQADDR input to the core and start executing from that address - see later
slides
Also (as we mention later) the 1156 can take exceptions written in Thumb-2 code
in Thumb state, by setting the TE bit of cp15 register 1. This is set on reset by
the TEINIT signal to the core.

063v11 6
Valpont.com, a Technology Content Platform

Exception Return Instructions


To return from an exception  For SWI and Undefined
 Use a data processing instruction Instruction handlers
 The actual instruction used depends MOVS pc,lr
on the exception being handled

 For FIQ, IRQ and Prefetch Abort


 With the S bit set
handlers
 With the PC as the destination
SUBS pc,lr,#4
register

 In privileged modes this not only  For Data Abort handlers


updates the PC but also copies SUBS pc,lr,#8
the SPSR into the CPSR
 LDM with ^ qualifier can also be used
if LR adjusted before being stacked
LDMFD sp!,{pc}^
See end of presentation for background
information on these instructions
 v6 cores also have RFE - more later
063v11 7
Valpont.com, a Technology Content Platform

Exception Return Instructions


When returning from an exception, can do both of the required actions using a
single data processing instruction with the S flag set, and the PC as destination
register

In privileged modes this not only updates the PC but also copies the SPSR
into the CPSR
However the actual instruction depends on which exception is being handled.

Also possible to use a Load Multiple instruction (using the ^ qualifier) to return if in
a privileged mode with the PC as the destination.

There are some slides at the end of this module that show how the return
instructions are calculated. However these are really for reference and should not
normally be run through during class (though there is a hyperlink to them on this
slide if needed).

063v11 8
Valpont.com, a Technology Content Platform

Exception Priorities
 Several exceptions can occur at the same time

 Exceptions are assigned priorities and are serviced in a fixed order:

Highest priority Reset


Data Abort
FIQ
IRQ
Prefetch Abort
SWI
Lowest priority Undefined instruction

 IRQs are disabled on entry to all exceptions


 Will only be taken by the core if they are re-enabled
(e.g. nested interrupt handler)
 FIQs are disabled on entry to FIQs and Reset

063v11 9
Valpont.com, a Technology Content Platform

Exception Priorities
Because the Data Abort exception has a higher priority that the FIQ exception, the Data Abort
is actually registered before the FIQ is handled. The Data Abort handler is entered, but control
is then passed immediately to the FIQ handler. When the FIQ has been handled, control
returns to the Data Abort Handler. This means that the data transfer error does not escape
detection as it would if the FIQ were handled first.

For prefetch abort, instn is marked as invalid on fetch, but exception not taken until instn
reaches execution stage of the pipeline

Generally, exceptions are taken immediately after the current instruction has completed. This
is not always true, e.g. SWI exception is taken as part of the instruction.

IRQs are disabled for all exceptions and will not be taken during another handler unless they
are re-enabled. Imprecise data aborts on v6 are disabled on entry to Aborts, FIQs, IRQs and
Reset.

FIQs can be non-maskable on the 1156, Cortex-R4 and Cortex-A8 cores. This means that
FIQ and reset will still set the F bit in the CPSR/SPSR, but all you can do in software is clear it
(i.e. re-enable FIQs) - you cannot disable them by setting the F bit. On the 1156, this is set by
the FIQISNMI pin at reset. On the Cortex cores, it’s set by the CFGNMFI pin. It *cannot* be
changed by software, but can be read from cp15 register 1.

063v11 10
Valpont.com, a Technology Content Platform

Vector Table Instructions


0xFFFFFFFF

Undef handler outside 32MBytes


Undef Handler
0x30008000 branch instruction range

SWI Handler
SWI Exception handler placed on
0x30000000 appropriate address boundary
> 32 Mbytes 0x2000000

IRQ Handler
IRQ handler within 32MBytes Branch
instruction range
0x1000
< 4 Kbytes Literal pool containing address of
0x30008000
0xFFC Undef Handler

FIQ Handler
0x1C FIQ vector FIQ handler follows vector table
0x18 B IRQ_Handler
IRQ vector
0x14 Reserved
0x10 Data abort vector
0xC Prefetch abort vector
0x8
MOV PC,
SWI#0x30000000
vector
0x4
Undef
LDR PC, vector
[PC, #+0xFF0]
0x0
Reset vector

063v11 11
Valpont.com, a Technology Content Platform

Vector Table Instructions


Branch Instruction
Direct branch always to handler address label
The handler must be within 32MB of the branch instruction, which may not be possible
with some memory organizations
Move PC instruction
Directly load the PC with a handler address label located on applicable address boundary
Address must be able to be stored in 8-bits, rotated right an even number of places
Load PC instruction
The PC is forced directly to the handler’s address by
Storing the address in a suitable memory location (within 4KB of the vector address).
Loading the vector with an instruction which loads the PC with the contents of the
chosen memory location.
For the Load PC example; LDR PC, [PC+offset]
offset address =(address location - vector address - pipeline effect)
= 0xFFC - 0x4 - 0x8
= 0xFF0
Note that the Load PC cannot be written using MOV because the address location of the Undef
handler cannot be generated using 8-bits rotated right an even number of places.
For the Move PC example the value 0x03 is rotated right four bits which is stored as two lots of
2 bits and is hence encoded as 0xA30F203
063v11 12
Valpont.com, a Technology Content Platform

Example Vector Table


 One typical approach is to use a literal pool for all of the addresses, so that
they can be modified later if necessary

AREA vectors, CODE, READONLY


You can include the FIQ
ENTRY
handler at the end of the
vector table (assuming it’s <
Vector_Table 4kB) but move the other
LDR pc, reset_addr handlers around to any
LDR pc, undef_addr location in the memory map. If
LDR pc, swi_addr you use LDR pc, … from a
LDR pc, prefetch_addr
literal pool, you won’t
suddenly find that it breaks
LDR pc, abort_addr your vector table instructions if
NOP ; Reserved the handlers change location.
LDR pc, irq_addr
FIQ_Handler
; FIQ handler code, < 4kB in size

reset_addr DCD Reset_Handler


undef_addr DCD Undef_Handler
swi_addr DCD Swi_Handler
...

063v11 13
Valpont.com, a Technology Content Platform

Register Usage in Exception Handlers


 The mode change associated with an exception occurring means that as a
minimum, the particular exception handler called will have access to
 Its own stack pointer (SP_<mode>)
 Its own link register (LR_<mode>)
 Its own saved program status register (SPSR_<mode>)
 In the case of a FIQ handler, 5 other general purpose registers (r8_FIQ to r12_FIQ)
 Other registers will be shared with the previous mode
 SP_<mode> must maintain 8-byte alignment at external interfaces - see later

 The exception handler must ensure that other (corrupted) registers are
restored to their original state upon exit

 This can be done by storing the contents of any working registers on the
stack and restoring them before returning

063v11 14
Valpont.com, a Technology Content Platform

Handling exceptions in v6 cores


 v6 cores provide several enhancements

 SRS and RFE instructions to save and restore r14 and the SPSR
 Must adjust the link register before saving it
 CPS simplifies changing state and/or modifying the I and F bits in the CPSR

 Architectural support for vectored interrupts with a VIC

 Low-latency interrupt mode:


 Disables hit-under-miss support
 Can abandon LDM/STM instructions to memory marked as normal
(restarted after exception handler returns)
 Note: other multi-word loads and stores (e.g. peripheral registers) must still
complete before interrupts - try to keep them as short as possible

 ARM1156T2-S can enter exceptions in Thumb state (using Thumb-2 code)

063v11 15
Valpont.com, a Technology Content Platform

Handling exceptions in v6 cores


SRS stores the SPSR and r14 - so you don’t have to save them in separate steps
(see the example code in the appendix). CPS allows mode changes and
enabling/disabling interrupts in one instruction rather than a read-modify-write 3
instruction sequence (again, compare the v5TE and v6 examples in the
appendix)

VIC use is covered later

Low-latency interrupt mode - see the TRM for your core for full details, however
what it typically does is disable hit-under-miss and allows LDM/STM to normal
(cacheable, bufferable) memory to be abandoned and repeated later on.

Normal memory is described elsewhere (e.g. Initializing Cached Cores module)

The 1156 can take exceptions in Thumb state (written in Thumb-2 code for PSR
access) if the TE bit is set in the cp15 control register 1. This also applies to the
Cortex-A/R cores. The TE bit is set at reset by the TEINIT pin.

063v11 16
Valpont.com, a Technology Content Platform

Interrupt Handling
 The ARM has two levels of external interrupt - FIQ and IRQ
 However most ARM based systems have more than 2 interrupt sources!
 Therefore need an interrupt controller (typically memory mapped) to control how
interrupts are passed onto the ARM
 In many systems some interrupts will be higher priority than others - these will
need to preempt any lower priority interrupts that may be being handled at that
point in time
Note: An interrupt handler should always contain code which clears the source
of an interrupt

1) ARM reads controller


nIRQ
Multiple Memory register to find out interrupt
Peripheral Mapped source which clears IRQ/FIQ
nFIQ ARM
interrupt Interrupt
sources Controller
2) ARM writes to peripheral to
clear actual interrupt source

063v11 17
Valpont.com, a Technology Content Platform

Interrupt Handling
The ARM only directly supports two interrupts, IRQ and FIQ but most systems will
have more sources than two. Thus almost all ARM based systems will need to
have some form of interrupt controller in the hardware system. At a very simple
level such a controller could simply be a mux of the interrupt sources (in which
case, it helps if they are active low, level sensitive as the ARM interrupt inputs are).
When the ARM receives an interrupt it would then need to poll each of the sources
in turn until it found the active source.

However most systems will have a more sophisticated controller than this. In a
typical system the controller will normally provide a set of memory mapped
registers which the ARM can read to work out which source caused the interrupt.
The controller will normally also provide some mechanism for prioritizing interrupt
sources, so that even when the ARM is dealing with a low priority interrupt, the
controller can still flag to the ARM when a more important interrupt occurs (and not
just FIQ). Such a controller will also normally be designed to also allow the ARM to
be interrupted by edge sensitive, active high interrupt sources.

Note also that there are some significant differences on the ARM11 MPcore, as the
interrupt controller is integrated into the core (it has to be, to direct interrupts
between the four cores).

063v11 18
Valpont.com, a Technology Content Platform

FIQ vs IRQ
 FIQ and IRQ provide very basic level of prioritization

 FIQs have a higher priority than IRQs in two ways:


 Serviced first when multiple interrupts arise
 Servicing an FIQ disables IRQs (and further FIQs)
 IRQs will not be serviced until after FIQ handler exits

 FIQs are designed to service interrupts as quickly as possible.


 FIQ vector is last in vector table
 Allows handler to be run sequentially from that address
 FIQ mode has 5 extra banked registers (r8_FIQ to r12_FIQ)
 Interrupt handlers must always preserve non-banked registers
 Can have multiple FIQ sources, but avoid nested FIQs for best system performance
 FIQs are disabled on entry to exception; re-enable to allow further FIQs to be taken

 Avoid other exceptions occurring inside an FIQ handler

063v11 19
Valpont.com, a Technology Content Platform

FIQ vs IRQ
FIQs are meant to be for the most important interrupt source or sources in the
system. If you do have more than 1 very critical interrupt source that you want
dealt with as an FIQ it is normally best not to nest the handling of these
sources. Typically the overhead of nesting FIQs adds too much latency to the
FIQ handler (e.g extra banked registers that must be saved). In most cases it
will be more efficient to just finish dealing with the one you are handling now,
return from it and then reenter immediately to deal with the second source.

Servicing an FIQ disables IRQs, so IRQs will not be serviced until after FIQ
handler exits. IRQs may be re-enabled inside FIQ handler, if required.

063v11 20
Valpont.com, a Technology Content Platform

Simple Interrupt Handlers in C (1)


 Can write simple interrupt handlers in C by specifying the keyword “__irq” in
the function definition

 This causes
 All corrupted registers used within the function to be preserved
 If applicable, any other registers that may be corrupted by a further function call to
be preserved
 The function to be exited with the correct return instruction
(sets the pc to lr-4 and restores the cpsr from the spsr)

 __irq can only be used with ARM-state code


 However subroutines called by the __irq function may be compiled as
Thumb-state code

 Make sure that you set up SP_irq and add a vector table entry!

063v11 21
Valpont.com, a Technology Content Platform

Simple Interrupt Handlers in C (1)


It is possible to write simple interrupt handlers in C using the __irq compiler directive.

This causes
all corrupted registers used within the function to be preserved
if applicable, any other registers that may be corrupted by a further function call to be preserved
the function to be exited with the correct return instruction
(sets the pc to lr-4 and restores the cpsr from the spsr)

__irq can only be used with ARM-state code.


However subroutines called by the __irq function may be compiled with armcc --thumb.

Make sure that you set up sp_irq and add a vector table entry!

The floating point registers are not preserved.


The registers preserved are not just those normally preserved under the APCS.

__irq can also be used to write FIQ handlers in C, but this is NOT recommended (C compiler cannot take
advantage of banked-in r8-r12).

For the Cortex-M3 rev0, (with --cpu Cortex-M3-rev0) the compiler will insert a “dynamic stack veneer” to
account for 8-byte stack alignment and adjust the stack as necessary when you use __irq.

063v11 22
Valpont.com, a Technology Content Platform

Simple Interrupt Handlers in C (2)


__irq void IRQHandler (void)
{
volatile unsigned int *source = (unsigned int *)0x80000000;
if (*source == 1) // which interrupt was it
int_handler_1(); // process the interrupt
// insert checks for other interrupt sources here
*(source+1) = 0; // clear the interrupt
}

Output without __irq Output with __irq

STMFD sp!,{r4,lr} STMFD sp!{r0-r5,r12,lr}


MOV r4,#0x80000000 MOV r4,#0x80000000
LDR r0,[r4,#0] LDR r0,[r4,#0]
CMP r0,#1 CMP r0,#1
BLEQ int_handler_1 BLEQ int_handler_1
MOV r0,#0 MOV r0,#0
STR r0,[r4,#4] STR r0,[r4,#4]
LDMFD sp!,{r4,pc} LDMFD sp!,{r0-r5,r12,lr}
SUBS pc,lr,#4

063v11 23
Valpont.com, a Technology Content Platform

Simple Interrupt Handlers in C (2)


It is possible to write simple interrupt handlers in C using the __irq compiler
directive.

The floating point registers are not preserved.


The registers preserved are not just those normally preserved under the APCS.

__irq can also be used to write FIQ handlers in C, but this is NOT recommended
(C compiler cannot take advantage of banked-in r8-r12).

Example routine reads an integer from location 0x80000000 to identify the source
of the interrupt.
If the source equals 1 then call int_handler_1 subroutine
Although only shown as a comment here, the code would normally need to check
for all the other possible sources too.
The interrupt is then cleared by writing 1 to 0x80000004.
Note that the compiled code uses r4 because it will not be corrupted by the
subroutine. If it had used a lower register e.g. r1 then it would need to re-load this
register from memory after the subroutine call.
063v11 24
Valpont.com, a Technology Content Platform

Issues with re-enabling interrupts


 Interrupts may be nested, if the programmer take special steps to prevent
system state being lost if another interrupt preempts the current one:
 Store LR_irq
 Store SPSR_irq
 Particular care must be taken with BL within interrupt handlers when
interrupts are re-enabled:
 The BL return address (in LR_irq) may get corrupted if second interrupt occurs.
The subroutine will return incorrectly - infinite loop!
 Solution is to change mode before the BL to prevent LR_irq being corrupted
 Typically use System mode (so BL uses LR_usr)
 At the end of a handler, it must
 Switch back to IRQ mode
 Disable interrupts (to avoid SPSR_irq being corrupted after you unstack it into a
temporary register)
 __irq cannot be used to write a re-entrant IRQ handler
 Must use a top-level assembler veneer instead - see following slides for example

063v11 25
Valpont.com, a Technology Content Platform

Issues with re-enabling interrupts


Corruption of LR is a general problem on ARM when exceptions happen when
you are in the appropriate exception mode already. System mode was added to
assist in solving this problem. Key point about system mode is that it is not
entered by an exception.

System mode is only available for Arch4 cores (and later).

For Architecture 3 cores it is possible to use SVC mode.

If you don’t use a BL then there is no need to change mode.

Other key point is that interrupts must be disabled as the SPSR is being restored,
otherwise the temporary register used to hold the SPSR after popping of the stack
might be corrupted by another interrupt.

063v11 26
Valpont.com, a Technology Content Platform

Stack issues

 The ABI for the ARM Architecture requires 8-byte stack alignment at all
external boundaries
 Need to ensure we maintain this for calling external functions

 However, when changing to system mode in an interrupt, we may be at a


point where the user stack did not need to be 8-byte aligned
 Your interrupt handler should check the stack alignment from system mode
 Correct the stack alignment if necessary, and flag that you need to “undo” this
change before returning
 Do this before re-enabling interrupts

063v11 27
Valpont.com, a Technology Content Platform

Stack issues
The ABI / AAPCS requires 8-byte alignment of the stack at *external* interfaces. So
in interrupt handlers, this means we need to beware of 4 points:

1) Whenever we call an AAPCS function (i.e. C code), we must ensure we’ve


preserved the stack alignment (and saved other AAPCS-corruptible registers, of
course)
2) When we change mode, we switch stacks - so alignment issues between the two
are independent and need to be checked separately
3) When we change to system mode in our interrupt handler, we are effectively
forcing an external boundary wherever we happened to be in our user code. This
could be in the middle of a function (the most common example of this situation
being a leaf function), and at that point there is no requirement on the user code
for SP_usr to be 8-byte aligned. So we must test this, adjust if necessary, and
undo the change on the return portion of the handler.
4) Because interrupts will use the user stack, user code must never use stack
memory below SP. E.g. if your assembly code wants to store some local data on
the stack, you must adjust SP when you do this, otherwise the memory may be
corrupted. (This is an ARM ABI requirement, but because it’s the same for all
ARM cores it’s sensible whichever ABI you actually use)

063v11 28
Valpont.com, a Technology Content Platform

ARM Nested Irq and Irq Re-entrant

063v11 29
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v4 / v5TE)

}
IRQ_Handler
SUB lr, lr, #4
Push LR_irq,
STR lr, [sp, #-4]! SPSR_irq, APCS-
Read interrupt source,
MRS r14, SPSR corruptible registers
clearing interrupt in STMFD sp!, {r0-r4,r12, r14}
and r4 onto the stack
controller
{ BL identify_and_clear_source

{
Switch to system MRS r2, CPSR
mode, keep ORR r2, r2, #0x1f
IRQ disabled MSR CPSR_c, r2 Check SP_usr for 8-byte

Enable IRQ
AND
SUB
STMFD
r1, sp, #4
sp, sp, r1
sp!, {r1, lr} } alignment and save
LR_usr plus a word to
indicate the stack
adjustment used (0 or 4)
and call C
handler, passing { BIC
MSR
BL
r2, r2, #0x80
CPSR_c,r2
C_irq_handler
the source in r0
...

063v11 30
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v4 / v5TE)


There are several things to look out for here:

First, we store LR_irq. I’ve used a single-word store here as it may typically save a
cycle compared to a one-word STM (which we used in the previous version of this
code).

We then push the user registers (r0-r3, r12) early so that we can write
identify_and_clear_source in C using the AAPCS if necessary. We also need to
push r4 here so that SP_irq is 8-byte aligned; you don’t need to save r4 if your
identify-and-clear code is assembly and you are aware you will not need 8-byte
stack alignment (many people may want to inline this code in their handler). We
also push SPSR_irq, held in r14.
A simple example of clearing an interrupt at your controller is below. This method
masks off the interrupt at the VIC which corresponds to the highest active bit in the
status register and leaves that bit in r0. You would then need to clear the interrupt at
the peripheral and unmask it at the interrupt controller from your main handler. NB:
this is only really for reference as an example if the audience ask - it will depend
entirely on the interrupt controller in use and the design of the interrupt handlers

063v11 31
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v4 / v5TE)


LDR r1, =vic_base ; e.g. 0x10140000 on
Versatile
MOV r0, #0x80000000
LDR r2, [r1, #vic_status_offset] ; e.g. 0x0 for Versatile
(PL192)
CLZ r2, r2
MOV r0, r0, ROR r2
STR r0, [r1, #vic_mask_clear_offset] ; e.g. 0x14 for
Versatile / PL192
BX lr

After this, we switch to system mode but keep IRQs disabled - as we need to check the stack
alignment. Remember that the AAPCS requires eight-byte stack alignment, but only at
external boundaries. So it’s entirely possible that we’ll have interrupted some code in the
middle of a function, where SP_usr was not eight-byte aligned. We need to check for this,
correct the stack pointer if necessary. We also push an extra word on the stack to indicate the
adjustment made to SP_usr to restore it later. Note also that we must now push LR_usr as
we have changed mode - fortunately, this also maintains our 8-byte stack alignment. Then we
just re-enable interrupts (staying in system mode) and call the main body of the IRQ handler in
C.

063v11 32
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v4 / v5TE)


...
BL C_irq_handler

Disable IRQ
{ MRS
ORR
MSR
r2, CPSR
r2, r2, #0x80
CPSR_c,r2

}
Restore LR_usr and
LDMFD sp!, {r1,lr}
ADD sp, sp, r1
undo the adjustment
made to SP_usr

{
Switch back BIC r2, r2, #0x1f
to IRQ ORR r2, r2, #0x92
mode MSR CPSR_c,r2

LDMFD
MSR
LDMFD
SPSR_csxf, r14
sp!, {pc}^ }
sp!, {r0-r4, r12, r14}

Restore APCS registers,


LR and SPSR and return
from exception using
modified LR

063v11 33
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v4 / v5TE)

On the way back, we do the reverse operations from the previous slide:

-Disable IRQs, stay in system mode

-Restore the LR_usr and “un-adjust” the stack (i.e. if it was misaligned on entry,
we need to misalign it on the way out)

-Switch back to IRQ mode

-Restore everything else, including LR_irq and the SPSR and return

063v11 34
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v6)


}
IRQ_Handler Use SRS to save
SUB lr, lr, #4
SRSFD #0x1f!
LR_irq and SPSR_irq
in one step on to the
Use CPS to switch
to System mode
{ CPS #0x1f System mode stack
STMFD sp!, {r0-r3,r12} }
AND r1, sp, #4
SUB sp, sp, r1
STMFD sp!, {r1, lr}
Store remaining AAPCS
BL identify_and_clear_source registers on to the

Enable/disable
{ CPSIE
BL
i
C_irq_handler
System mode stack

IRQ with CPS


{ CPSID i

LDMFD sp!, {r1,lr}


ADD sp, sp, r1

Restore registers
and return using { LDMFD
RFEFD
sp!, {r0-r3, r12}
sp!

RFE from the


System mode stack
Note: This is for non-vectored interrupts

063v11 35
Valpont.com, a Technology Content Platform

C Nested Interrupt Example (v6)


This is the v6 version of the code on the previous two slides.

The process is very similar, but notice that this is now much shorter (15 instructions
compared to 25 for v5TE; one less register pushed and popped).

The key points are:


-We still adjust the link register before pushing it, but now we use the v6 SRS
instruction, so we don’t need to push the SPSR and LR_irq independently
-In addition, the SRS instruction allows you to store the registers on a different
mode’s stack - in this case, the System mode stack using SP_usr.
This means that we do not need to return to IRQ mode to exit our handler
-Also notice that as we now perform all of our register storing in System mode, we
can store an odd number of registers before the stack adjustment - we save one
register push and pop over v5
-We use CPS for the mode change and enabling/disabling interrupt bits
-The return uses RFE from the System mode stack

063v11 36
Valpont.com, a Technology Content Platform

Vectored interrupt controllers


 v6 provides architectural support for vectored interrupt controllers (VICs)
 Implementation-defined on previous architectures
 Enabled by setting the VE bit in CP15 register 1
nIRQ

Interrupt
VIC
sources

IRQADDR ARM1136JF-S

Core branches to Top-level handler Handler for


Application code vector table checks source specific source
Control passes
directly to device
handler
Handler clears
source

063v11 37
Valpont.com, a Technology Content Platform

Vectored interrupt controllers


This slide intends to show the story of what happens with normal interrupt handling versus vectored interrupt
handling, looking at both the hardware and software and tying the two together.
(Each numbered step below corresponds to a new step in the animation)
1) Show the core and VIC, briefly explain that we’re showing interrupt lines going into the VIC from several
peripherals with connections to the v6 core
2) A peripheral signals an interrupt to the VIC
3) This is passed on to the core by taking the nIRQ signal low
4) In software, our application code is interrupted
5) Control passes first to the vector table, then a top-level handler which determines the interrupt source
6) This in turn calls the handler for our specific device…
7) …which will clears the interrupt source
8) (Source cleared in animation)
9) (Handler sequence disappears) - Now what happens when we use vectored interrupts?
10) On the ARM core, we have an extra set of inputs, IRQADDR, which are connected directly to the VIC to
take the address of a device’s interrupt handler
11) We receive another interrupt
12) This time, in addition to signalling an interrupt on nIRQ, the VIC also passes a programmed handler
address corresponding to that interrupt to IRQADDR
(This address must be set up when initializing the VIC)
13) Control passes directly to the handler
14) The handler clears the source and returns directly itself

063v11 38
Valpont.com, a Technology Content Platform

Vectored interrupt controllers


There are in effect three ways of using an interrupt controller:
1) Entirely non-vectored; i.e. you must check the interrupt status register(s) at the controller
to identify the source
2) Vectored without core support - the interrupt controller sets up vectors, but this can’t be
passed directly to the core (see below)
3) Fully vectored including IRQADDR input to the core, as pictured

On v5TE (e.g. ARM926EJ-S without a dedicated IRQADDR port) you could still set up
vectored interrupts (using e.g. PL190) such that your top-level handler read the address of
the device handler from the VIC, which also acknowledged the interrupt in the VIC’s
prioritization hardware. This eliminated the need for the top-level handler to do
identification and prioritization itself. Even better, if you use your MMU to map the VIC’s
registers to the top of the address range (e.g. 0xFFFF0000) you can use an LDR pc, [pc, #-
offset] in the vector table where the negative offset will wrap around - so this is effectively
the same as the v6 version, plus one branch in the vector table. You could also use this
scheme on a v6 core without an IRQADDR input.

NB: None of this applies to the ARM11 MPcore, as the interrupt controller is integrated into
the core.

063v11 39
Valpont.com, a Technology Content Platform

Vectored interrupt controllers


 FIQ is not usually vectored
 Usually a single interrupt source, with handler running directly from address 0x1C

 Handler should return as a normal interrupt handler


 use RFEFD sp! or SUBS pc, lr, #4

 Prioritization and nesting can be done in hardware by the VIC


 No need for top-level IRQ handler
 Avoids branch via vector table, code to identify the source and software prioritization
 However, still need to store SPSR_irq and LR_irq, change to system mode,
check stack alignment and re-enable interrupts as before
 Usually a limit on the number of vectored interrupts supported by the VIC
(e.g. ARM PL192 supports 32 vectored interrupts)

 Beware of clearing interrupt source immediately before re-enabling interrupts


 Store to a peripheral must go out through the core’s level two memory system
 May need to wait for the update to be seen by the VIC and the core, or use a DSB
063v11 40
Valpont.com, a Technology Content Platform

Vectored interrupt controllers


FIQ isn’t vectored (there’s no point, it’s typically a single source anyway)

The handler is now doing everything that the top-level handler does; i.e. you must
store SPSR_irq and LR_irq, change to system mode, check stacks, etc.

You must also return yourself using SUBS pc, lr, #4 as a top-level handler would

VICs usually provide for hardware prioritization of interrupts (but have a maximum
number of vectored interrupts they support). Reduces the IRQ handler overhead
in addition to the branching via the vector table.

Also, beware of clearing an interrupt source immediately before re-enabling


interrupts; this needs to go to a peripheral via the core’s L2 memory system so
you may need to wait some cycles before the update is actually seen by the
peripheral, the VIC and the core. Alternatively, you may use a DSB (Data
Synchronization Barrier, pre-v6 this is a Drain Write Buffer / Data Write Barrier
operation), using cp15 register 7.

063v11 41
Valpont.com, a Technology Content Platform

Prefetch and Data Aborts

 A prefetch abort indicates a failed instruction fetch


 Tagged as aborting when the fetch occurs;
abort only taken if instruction reaches the execute stage of the pipeline

 A data abort indicates a failed data access


 Load/store between the core and memory system

 Internal aborts are those from the core itself - the MMU/MPU
 MMU faults may indicate you need to take corrective action and
re-execute the appropriate instruction

 External aborts are those from the memory system


 May indicate a hardware fault
 Could be an attempted access to non-existent memory

063v11 42
Valpont.com, a Technology Content Platform

Abort Handlers
 What you do when an abort happens depends on the system
 In a simple system without any memory management, this usually indicates a
serious error (e.g. hardware fault, code bug)
 With memory management, you may need to identify the cause of the abort and
take corrective action. For example:
 Allocate more memory for a process
 Load a new page of code or data which the process was trying to access
 Terminate the process if it did not have permission to access the aborting address
 ARM7TDMI family devices have a different abort model - see appendix

 For a prefetch abort, the offending instruction is at LR_abt - 4


 For a data abort, the offending instruction is usually at LR_abt - 8
 However, use MMU to find the faulting address
 Instruction may not be at lr - 8 if it is an imprecise abort

063v11 43
Valpont.com, a Technology Content Platform

Abort Handlers
For the 1156 and Cortex-R4, the MPU also has fault status and address registers
for checking this, although you obviously can’t do memory remapping. However,
may be useful for identifying the location of the fault.

Aborts from cached memory loads may not be seen by the core:

Pre-v6 cores, they won’t be seen by the core so don’t cache memory that may
abort (if you have h/w failure, there’s not much you can do anyway…)

For v6 cores, the following description is based on the 1136 TRM and a brief chat
to Rich A about the behaviour. If in doubt, point customers to their core TRM
and/or support-cores 
- I$ linefills that experience an abort will not mark the line as valid. Any
subsequent instruction execution from that line will cause a prefetch abort
- D$ linefills that abort will not mark the line as valid. If the abort is on
the critical word the abort is passed to the core; others will *not* cause a direct
abort (but of course, if they are subsequently accessed and abort again as the
critical word of the fetch, the abort _will_ be seen)

063v11 44
Valpont.com, a Technology Content Platform

Identifying the abort source


 In v4 and v5TE, there are two registers:
FSR (Fault Status Register) and FAR (Fault Address Register)
 CP15 register 5 (FSR), register 6 (FAR)
 v6 has separate status registers - IFSR and DFSR for instructions and data
 Both use CP15 register 5, but specify opcode2 = 0 (DFSR) or 1 (IFSR)
in MRC instruction
 Look at the source in the FSR
 External aborts probably fatal (at least to the running process in a multitasking OS)
 For internal faults, check if we need to map in more memory or if the process is
performing an illegal access (e.g. domain fault, accessing privileged memory)
 Address of the fault can be found in FAR or (LR_abt - 4)
 For data aborts, may need to take care of imprecise aborts

V6 also has a WFAR (Watchpoint Fault Address Register) for monitor-mode debug.
Core implementations may also provide an IFAR (instruction fault address register) - but this
is not in e.g. the ARM1136.
With TrustZone, an external abort may also be because you are accessing a secure
peripheral from the non-secure world.

063v11 45
Valpont.com, a Technology Content Platform

Imprecise aborts
 Architecture v6 can recognise “imprecise data aborts”
 A store to memory held in the write buffer may actually happen and abort
several cycles after the original instruction
 Could potentially nest under a precise abort

 Only external aborts may be imprecise


 …But not all are (e.g. loads to PC, loads or stores to/from strongly-ordered memory)
 See the TRM for your core for a description of which external aborts are precise
 Internal (MMU) faults are all precise

 To handle imprecise aborts, must save abort state prior to clearing


the CPSR A bit
 Similar to nested interrupt code
 As the abort will be external this is usually a fatal error and in a multitasking OS we
should try to kill the process causing the abort
 We cannot usually identify the offending instruction - the abort may be
unrecoverable

063v11 46
Valpont.com, a Technology Content Platform

SWI Invocation
 In assembler, a SWI is called with an appropriate SWI number: SWI 0x24
 Note: SWI has now been renamed to SVC (RVDS 2.2 and later)
 Beware that calling a SWI when in Supervisor mode will corrupt LR_svc
 Solution: push LR_svc onto stack before calling the SWI
 Parameters are passed in:
 The SWI number e.g. for semihosting, use 0x123456 (ARM) or 0xAB (Thumb)
 Core registers
 In C, map a call to a function onto a SWI using the keyword “__swi”
 Pass up to 4 parameters in r0-r3
 Note: no stack parameters because of the change to supervisor mode
For example... compiles to:
__swi(0x24) void my_swi (char *s); foo
STMFD sp!,{r4,lr}
void foo (void) LDR r0, =text
{ SWI 0x24
my_swi(“Hello world\n”); LDMFD sp!,{r4,pc}
} ...
text DCB “Hello world\n”,0

063v11 47
Valpont.com, a Technology Content Platform

SWI Invocation
Note that the compiler won’t let you use more than four arguments for __swi functions. In theory you could get the user SP, but
that’s awkward and there are simpler ways of designing the handler interface.
SWIs can also be called from inline assembler. See docs for details.

SWI numbers can also be passed using the keyword __swi_indirect


This passes an operation code to the SWI handler in r12:
int __swi_indirect(swi_num)
swi_name(int real_num,
int arg1, ... argn);
where:
swi_num = the SWI number used in the SWI instruction.
real_num = the value passed in r12 to the SWI handler. You can use this feature to implement indirect SWIs. The SWI handler
can use r12 to determine the function to perform.
For example:
int __swi_indirect(0) ioctl(int swino, int fn, void *argp);
This SWI can be called as follows:
ioctl(IOCTL+4, RESET, NULL);
It compiles to a SWI 0 with IOCTL+4 in r12.
To use the indirect SWI mechanism, your system SWI handlers must make use of the r12 value to select the required
operation.
(ADS1.2 Compilers and Libraries Guide - section 3.1.2 - Function qualifiers)

BKPT can also be used for semihosting on e.g. Cortex-M3.

063v11 48
Valpont.com, a Technology Content Platform

Software Interrupts
User program
(C/ASM)

Vector table

SWI handler
(ARM assembly)
SWI handler
(ARM or Thumb
SWI 0x01 C code)

(Optional)

 User program invokes SWI


 SWI handler contain assembly
part and optional C part

063v11 49
Valpont.com, a Technology Content Platform

Software Interrupts
This slide shows the sequence of actions involved in handling a SWI.

1) The SWI is invoked in the user program (either C or ASM). Parameters may have
been placed in registers before the SWI. The SWI number is embedded in the SWI
instruction itself.

2) The SWI vector is taken. This includes switch to SVC mode.

3) The vector points to a handler which is written in ASM. This is where the SWI
number is extracted from the SWI instruction (by back-tracing through LR).
Optionally, parameters may be placed on the stack prior to calling a C handler. If a C
handler is not used, the parameters may be used directly from the registers.

4) Optionally, a C handler may be used to carry out the bulk of the SWI processing.
In order to be able to pass the SWI number plus four other parameters to this routine
(more than we can usually pass in registers), the SWI number is passed in a register
together with a pointer to the other parameters which are placed on the stack prior to
the call.
The C handler is a normal C function.
063v11 50
Valpont.com, a Technology Content Platform

Software Interrupts
As ARM state is automatically entered on taking an exception, and an ARM
instruction is needed to return from an exception, the obvious way to code your
exception handlers is completely in ARM code. This is particularly the case when
performance is critical and the exception handling code can be located in fast 32-bit
wide memory - for instance with interrupt handlers.

However in other circumstances, it may be better if the main part of an exception


handler is written in Thumb code, with an ARM code stub which is used for entry and
exit from the handler. This will both provide better code density and also performance
if running from narrow memory.

This does apply generally to other exceptions, but SWIs are the most common one
that you may want to use Thumb code in (e.g. for a large handler for OS calls)

063v11 51
Valpont.com, a Technology Content Platform

Accessing the SWI number & arguments


 The core provides no mechanism for passing the SWI number directly to
the handler
 SWI handler must extract the comment field from the SWI instruction itself
 To do this, the SWI handler must determine which state (ARM/Thumb)
the SWI was called from
 Check the T bit in the SPSR
 The SWI instruction is at LR-4 for ARM state, LR-2 for Thumb state
ARM format:
31 28 27 24 23 0

Cond 1 1 1 1 SWI number

Thumb format:
15 8 7 0

1 1 0 1 1 1 1 1 SWI number

 To pass the parameters to C, they are typically pushed on the stack


 Pass a pointer to those parameters to the C subroutine implementing the main
body of the handler

063v11 52
Valpont.com, a Technology Content Platform

Example SWI Handler


T_bit EQU 0x20
Stack registers, and
set pointer to SWI_Handler
parameters
{ STMFD sp!, {r0-r4,r12,lr}
MOV r1, sp
Get spsr and
MRS
STR
r0, spsr
r0, [sp, #-4]! } store onto
stack
Extract comment field

{
TST r0, #T_bit
(24 bits if called from ARM, LDRNEH r0, [lr,#-2]
8 bits if called from Thumb) BICNE r0, r0, #0xff00
LDREQ r0, [lr,#-4]
BICEQ r0, r0, #0xff000000

; r0 now contains SWI number


; r1 now contains pointer to parameters on stack
Call 2nd level
BL C_SWI_Handler
SWI handler C

}
code LDR r1, [sp], #4
Restore
MSR spsr_csxf, r1
registers
LDMFD sp!, {r0-r4,r12,pc}^
and return

063v11 53
Valpont.com, a Technology Content Platform

Example SWI Handler


This routine supports the passing back of parameters as well. If the C handler
modifies the parameters on the stack, these modified values will be passed back
to the invocation in r0-r3.

Example C handler:
int C_SWI_Handler(int swinum, int * params)
{
switch(swinum)
{
case 0:
return writechar(params[0], params[1]);
break;
case 1:
return readchar(params[0]);
break;
}
return -1;
}

063v11 54
Valpont.com, a Technology Content Platform

Reset

 The operations carried out by a Reset handler depend upon the system in
question
 For example it may:
 Set up exception vectors
 Initialize the memory system (e.g. MMU/PU)
 Initialize all required processor mode stacks and registers
 Initialize variables required by C
 Initialize any critical I/O devices
 Enable interrupts
 Change processor mode and/or state
 Call the main application

Unlike the other exception handlers, there should be no need to ‘return’ from
the Reset handler as it should call your main application.

063v11 55
Valpont.com, a Technology Content Platform

Undefined Instruction
 An Undefined Instruction exception can occur if:
 The ARM tries to execute a real undefined instruction
 The ARM encounters a coprocessor instruction for which the appropriate
coprocessor hardware does not exist in the system.
 The ARM encounters a coprocessor instruction for which the appropriate
coprocessor hardware exists, but has not been enabled
 The ARM encounters a coprocessor instruction for which the appropriate
coprocessor does exist but rejects the instruction because the ARM is not in a
privileged mode.
 For example access to cp15 - the system control coprocessor
 Other privileged instructions

 Courses of action:
 Implement “soft” coprocessor emulation in the handler (such as VFP support code)
 Take action based on rogue task attempting forbidden privileged operation
 Report error and quit

063v11 56
Valpont.com, a Technology Content Platform

Undefined Instruction
Coprocessors may need to be enabled via cp15 register 1, opcode2 = 4

In the case of the non-existent coprocessor, it is possible to write an undefined


instruction handler which emulates that coprocessor in software.
An emulator can examine the instruction to see if it is one it can emulate.
If bits 27-24 = 1110 or 110x then the instruction is a coprocessor instruction.
Can then extract bits 8-11 which define which coprocessor should deal with
this instruction.
If this emulator is the correct one, then process the instruction and return to
the application.
This is the way that floating point used to be done on the ARM before the
introduction of the floating point library. Floating point would either be implemented
in hardware, FPA - Floating Point Accelerator, as used by ARM7500FE, or in
software using a Floating Point Emulator.
In reality the FPA actually used a combination of hardware coprocessor for the
common cases and software emulation for the rare cases. VFP10 (for use with
ARM1020T) also uses this combined hardware/software approach for
implementing floating point as coprocessor instructions.

063v11 57
Valpont.com, a Technology Content Platform

The “Return Address”


 The way the return address is set comes from the ARM7 pipeline
 Newer cores have the same effective behaviour for backwards-compatibility

 In ARM state:
 Upon exception occurring the core sets LR_mode = PC - 4
 Handler may need to adjust LR_mode (depending on the exception which occurred)
to return to the correct address

 In Thumb state:
 The address stored in LR_mode is amended automatically by the processor
depending upon the exception that has occurred
 This ensures the ARM return instruction from the handler will return to the correct
address (and to the correct state), regardless of the state that was current when the
exception occurred

063v11 58
Valpont.com, a Technology Content Platform

Returning from SWI and Undef


 Exception handler called, in effect, by instruction itself. Thus PC has not
been updated at the point that LR is calculated

ARM Thumb
SWI pc-8 pc-4 Exception taken here
xxx  pc-4 pc-2 lr = next instruction
yyy pc pc

 Return instruction is
MOVS pc,lr

 Note :  symbol denotes instruction to execute after return from exception

063v11 59
Valpont.com, a Technology Content Platform

Returning from SWI and Undef

The SWI and Undefined Instruction exceptions are generated by the instruction
itself, so the program counter is not updated when the exception is taken. The
processor stores (pc - 4) in lr_ mode. This makes lr_mode point to the next
instruction to be executed. Restoring the program counter from the lr with:
MOVS pc, lr
returns control from the handler.

The handler entry and exit code to stack the return address and pop it on return is:
STMFD sp!,{reglist,lr}
;...
LDMFD sp!,{reglist,pc}^

063v11 60
Valpont.com, a Technology Content Platform

Returning from FIQs and IRQs


 Exception handler called after instruction has finished executing. Thus PC
has been updated at the point LR is calculated

ARM Thumb
www pc - 12 pc - 6 Interrupt occurred during execution
xxx  pc - 8 pc - 4
yyy pc - 4 pc - 2 ARM lr = next instruction
zzz pc pc Thumb lr = two instructions ahead

 Return instruction is
SUBS pc,lr,#4

 Note :  symbol denotes instruction to execute after return from exception

063v11 61
Valpont.com, a Technology Content Platform

Returning from FIQs and IRQs


After executing each instruction, the processor checks to see whether the interrupt
pins are LOW and whether the interrupt disable bits in the CPSR are clear. As a
result, IRQ or FIQ exceptions are generated only after the program counter has
been updated. The processor stores (pc - 4) in lr_mode. This makes lr_mode point
one instruction beyond the end of the instruction in which the exception occurred.
When the handler has finished, execution must continue from the instruction prior
to the one pointed to by lr_mode. The address to continue from is one word (four
bytes) less than that in lr_mode, so the return instruction is:

SUBS pc, lr, #4


The handler entry and exit code to stack the return address and pop it on return is:
SUB lr,lr,#4
STMFD sp!,{reglist,lr}
;...
LDMFD sp!,{reglist,pc}^

063v11 62
Valpont.com, a Technology Content Platform

Returning from Prefetch Aborts


 Exception taken when instruction reaches execute stage of pipeline. Thus
PC has not been updated at the point LR is calculated
 Need to attempt re-execution of the instruction which caused the abort

ARM Thumb
www  pc – 8 pc - 4 Prefetch Abort occurred here
xxx pc – 4 pc - 2 ARM lr = next instruction
yyy pc pc Thumb lr = two instructions ahead

 Return instruction is
SUBS pc,lr,#4

 Note :  symbol denotes instruction to execute after return from exception

063v11 63
Valpont.com, a Technology Content Platform

Returning from Prefetch Aborts


If the processor attempts to fetch an instruction from an illegal address, the
instruction is flagged as invalid. Instructions already in the pipeline continue to
execute until the invalid instruction is reached, at which point a Prefetch Abort is
generated.
The exception handler loads the unmapped instruction into physical memory and
uses the MMU, if there is one, to map the virtual memory location into the physical
one. The handler must then return to retry the instruction that caused the exception.
The instruction should now load and execute.
Because the program counter is not updated at the time the prefetch abort is
issued, lr_ABT points to the instruction following the one that caused the exception.
The handler must return to lr_ABT - 4 with:
SUBS pc,lr, #4
The handler entry and exit code to stack the return address and pop it on return is:
SUB lr,lr,#4
STMFD sp!,{reglist,lr}
;...
LDMFD sp!,{reglist,pc}^

063v11 64
Valpont.com, a Technology Content Platform

Returning from Data Aborts


 Exception taken (and LR calculated) after PC has been updated
 Need to attempt re-execution of instruction which caused the abort

ARM Thumb
www  pc - 12 pc - 6 Data abort occurred here
xxx pc - 8 pc - 4
yyy pc - 4 pc - 2 ARM lr = two instructions ahead
zzz pc pc
aaa pc + 4 pc + 2 Thumb lr = four instructions ahead

 Return instruction is
SUBS pc,lr,#8

 Note :  symbol denotes instruction to execute after return from


exception

063v11 65
Valpont.com, a Technology Content Platform

Returning from Data Aborts


When a load or store instruction tries to access memory, the program counter has
been updated. The stored value of (pc - 4) in lr_ABT points to the second
instruction beyond the address where the exception occurred. When the MMU, if
present, has mapped the appropriate address into physical memory, the handler
should return to the original, aborted instruction so that a second attempt can be
made to execute it. The return address is therefore two words (eight bytes) less
than that in lr_ABT, making the return instruction:

SUBS pc, lr, #8


The handler entry and exit code to stack the return address and pop it on return is:
SUB lr,lr,#8
STMFD sp!,{reglist,lr}
;...
LDMFD sp!,{reglist,pc}^

063v11 66
Valpont.com, a Technology Content Platform

The Abort Model


 Many ARM memory access instructions cause the base register to be
updated e.g.

LDR r0,[r1,#8]!

causes r1 to be updated

 If the memory access results in a data abort, the effect on the base register is
dependent on the particular ARM core in use
 “Base Restored Abort Model”
 Supported by StrongARM, ARM9 and ARM10, ARM11 and later families
 Base register is restored automatically by the ARM core
 “Base Updated Abort Model”
 Supported by ARM7TDMI family
 Base register may have to be restored by the handler before instruction can be
re-executed
 Example code for both models is included in RVDS examples directory

063v11 67

You might also like