User guide

; Add instructions to clear the interrupt here
; then re-enable interrupts.
MSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
; enabled. USR mode registers
; are now current.
STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee
; saved registers
BL C_irq_handler ; branch to C IRQ handler.
LDMFD sp!, {r0-r3, lr} ; restore registers
MSR CPSR_c, #0x92 ; switch to IRQ mode and disable
; IRQs. FIQ is still enabled.
LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ
MSR SPSR_cf, r14
LDMFD sp!, {pc}^ ; return from IRQ.
END
5.5.3 Example interrupt handlers in assembly language
Interrupt handlers are often written in assembly language to ensure that they execute quickly. The following sections
give some examples:
Single-channel DMA transfer
Dual-channel DMA transfer
Interrupt prioritization
Context switch.
Single-channel DMA transfer
Example 5-15 shows an interrupt handler that performs interrupt driven I/O to memory transfers (soft DMA). The
code is an FIQ handler. It uses the banked FIQ registers to maintain state between interrupts. This code is best
situated at location 0x1C.
In the example code:
r8
Points to the base address of the I/O device that data is read from.
IOData
Is the offset from the base address to the 32-bit data register that is read. Reading this register
clears the interrupt.
r9
Points to the memory location to where that data is being transferred.
r10
Points to the last address to transfer to.
The entire sequence for handling a normal transfer is four instructions. Code situated after the conditional return is
used to signal that the transfer is complete.
Example 5-15
LDR r11, [r8, #IOData] ; Load port data from the IO
; device.
STR r11, [r9], #4 ; Store it to memory: update
; the pointer.
CMP r9, r10 ; Reached the end ?
SUBLSS pc, lr, #4 ; No, so return.
; Insert transfer complete
; code here.
Byte transfers can be made by replacing the load instructions with load byte instructions. Transfers from memory to
an I/O device are made by swapping the addressing modes between the load instruction and the store instruction.
Dual-channel DMA transfer
Example 5-16 is similar to Example 5-15, except that there are two channels being handled. The code is an FIQ
handler. It uses the banked FIQ registers to maintain state between interrupts. It is best situated at location 0x1c.
In the example code:
r8
Points to the base address of the I/O device from which data is read.
IOStat
Is the offset from the base address to a register indicating which of two ports caused the
interrupt.
IOPort1Active
Is a bit mask indicating if the first port caused the interrupt (otherwise it is assumed that
the second port caused the interrupt).
Handling Processor Exceptions
Copyright ?1999 2001 ARM Limited 5-16