ARM I/O, Exceptions, Interrupts

Tulika Mitra T lik Mit National University of Singapore
tulika@comp.nus.edu.sg

Programming I/O – 1 Pr r i
Embedded systems usually include some non-digital components Digital interface to CPU: status & data registers
CPU data reg me echanism m status reg

10/3/2007

CS5272 © 2007 Tulika Mitra

1

10/3/2007

CS5272 © 2007 Tulika Mitra

2

Programming I/O - 2 Pr r i
Memory-mapped Devices are mapped CPU to specific memory locations just like RAM Uses load/store instructions just like accesses to memory CPU I/O mapped Special bus line and instructions
10/3/2007

I/O R i t r B i Register Basics
Address Data Read Write

Memory
Address Data Memory I/O Read R d Write

I/O Device

I/O Registers are NOT like normal memory Device events can change their values (e.g., status reg) Reading a register can change its value (e.g., error co d o ese ) condition reset) read-only (e.g., receive registers) , write-only (e.g., transmit registers) Multiple registers mapped to same address
Clear from context

I/O Port Memory M I/O Device
3

The bits in a control register often each specify something different and important -- and have significant side effects Cache must be disabled for memory-mapped addresses When polling I/O registers, should tell compiler that value can change on its own
10/3/2007

CS5272 © 2007 Tulika Mitra

volatile int *ptr;

CS5272 © 2007 Tulika Mitra

4

ARM memory-mapped I/O r pp d
Define location for device DEV1 EQU 0x1000 Read/write code ADR r1,DEV1 ; set up device address r1 DEV1 LDR r0,[r1] ; read DEV1 MOV r0 #8 r0,#8 ; set up value to write t p l t rit STR r0,[r1] ; write value to device
10/3/2007 CS5272 © 2007 Tulika Mitra 5

Memory-mapped I/O E M r pp d I/O: Example pl
A device containing eight 8-bit registers at addresses 0x00001000 – 0x00001007 The decoder activates chip enable for this address range Address bits A0—A2 are used for register select dd ess b s 0 a e o eg s e se ec Example: storing the lowest byte of processor register r3 in device register R2 LDR r1 =0x1002 r1, 0x1002 STR r3, [r1]

10/3/2007

CS5272 © 2007 Tulika Mitra

6

Memory-mapped I/O i C M r pp d in
int peek(char *location) p ( ) { return *location; } void poke(char *location,char value) { *location = value; } #define DEV1 0x1000 dev_status = peek((char *)DEV1); poke((char *)DEV1, 8);
10/3/2007 CS5272 © 2007 Tulika Mitra 7

Volatile ri bl V l til variable
volatile int *p status; p_status; p_status = (int *) 0x4001; while (( p_status & 0x01) == 0); ((*p status Compiler allocates (*p_status) to register
Infinite loop as (*p status) will not be updated ( p_status)

Volatile keyword ensures that compiler will not allocate it in register and will not allow it to be put in data cache
10/3/2007 CS5272 © 2007 Tulika Mitra 8

Example: S ri l I/O - 1 E pl Serial
Processor has parallel buses for data -- need to convert serial data to parallel (and vice versa) UART - Universal asynchronous receiver and transmitter
Chip Reg Select R/W Control

Example: Serial I/O - 2
High-level High level I/O call
printf(“the number is %d\n”, someNumber);

Low-level details
is a library call which formats the output (e.g., converts %d formats) and then makes system call to output the formatted string
printf() Formatted string is nothing more than an array of characters Low-level routines then output the string one character at a time using UART
10/3/2007 CS5272 © 2007 Tulika Mitra 10

Tx Clock

IRQ D0-D7
Data Bus Buffers

Tx Data Reg Status R St t Reg Control Reg Rx Data Reg
CS5272 © 2007 Tulika Mitra

Tx Shift Reg

Tx Data CTS RTS Rx Data
9

Rx Shift Reg

Rx Clock
10/3/2007

Conceptual Vi of D i Dri r C pt l View f Device Driver
string while (*string != '\0') printChar(*string++);
Problem • while loop can execute a lot faster than the UART can transmit

Check Ch k UART f r space for p
string g
while (*string != '\0'){ if (UART is empty()) printChar(*string++); }
Chip Reg Select R/W Control

Chip Reg Select R/W Control

Tx Clock

Tx Clock 2 Tx Data Reg 1 Status Reg Tx Shift Reg Tx Data CTS RTS Rx Data
12

IRQ D0-D7

Tx Data Reg Status R St t Reg Data Bus Control Reg Rx Data Reg
CS5272 © 2007 Tulika Mitra

Tx Shift Reg

Tx Data CTS RTS Rx Data
11

IRQ D0-D7

Data Bus

Control Reg Rx Data Reg
CS5272 © 2007 Tulika Mitra

Rx Shift Reg

Rx Shift Reg

Rx Clock
10/3/2007 10/3/2007

Rx Clock

Busy-wait I/O B it
Continuously test if device is ready current_char = mystring; while ( current_char != ‘\0’) { (*current char ! \0 ) poke(OUT_CHAR,*current_char); /* busy wait for the transmission to complete */ while (peek(OUT_STATUS) != 0); current_char++; rr t h r++ } Better B tt option: Interrupt ti I t t
10/3/2007 CS5272 © 2007 Tulika Mitra 13

Interrupt I t rr pt
When device is ready, it sends an interrupt On O an interrupt, CPU jumps to interrupt handler i t t j t i t t h dl Read/write of the device is done inside interrupt handler
user program
IRQ Interrupt handler Q p

time

Task IRQ

user program

Interrupt
10/3/2007 CS5272 © 2007 Tulika Mitra 14

Normal Program Flow vs. Exceptions/Interrupts E pti /I t rr pt
Normally, Normally programs execute sequentially (with a few branches to make life interesting) Normally, Normally programs execute in user mode Exceptions and interrupts break the sequential flow of a program, jumping to architecturally-defined memory locations

Exception Interrupt E pti vs. I t rr pt
Exception refers to an internal CPU event
floating point overflow MMU fault (e.g., page fault) ( g,p g ) trap (SWI)

Interrupt refers to an external I/O event
I/O device request reset

ARM manual usually does not make distinction between exception & interrupt
10/3/2007 CS5272 © 2007 Tulika Mitra 15 10/3/2007 CS5272 © 2007 Tulika Mitra 16

ARM E pti Exceptions

Processor M d Pr r Modes
User: Normal program execution
unable to access protected system resources or change mode

Exception modes: Additional registers to avoid corrupting user mode
FIQ: fast interrupt for high-speed data transfer IRQ: general-purpose interrupt handling Supervisor (SVC) protected mode for OS S i (SVC): t t d d f

System: Supervisor mode but access to only user mode registers
10/3/2007 CS5272 © 2007 Tulika Mitra 17 10/3/2007 CS5272 © 2007 Tulika Mitra 18

Processor mode r i t r - 1 Pr r d registers

Processor mode r i t r - 2 Pr r d registers
Exception handlers have access to a certain p subset of the banked registers
its own r13 or sp register (sp_mode) its own r14 or lr register (lr_mode) (lr mode) its own saved program status registers (spsr_mode)

In case of FIQ, each exception handler has access to 5 more general-purpose registers (r8_FIQ to r12_FIQ) Other registers must be restored to their original contents upon exit from handler
Save and restore from stack
10/3/2007 CS5272 © 2007 Tulika Mitra 19 10/3/2007 CS5272 © 2007 Tulika Mitra 20

Vector table V t r t bl
Controls exception handling 32 bytes at the bottom of memory map One word for each exception type
Not enough space to g p include full handler code Contains a branch or load pc instruction to continue execution with th ti ith the interrupt handler

Processor actions on exception Pr r ti pti
Addr 0x0 0x8 0x18 0x1C Type yp Mode Priority y 1 6 4 3
21

Reset SVC SWI IRQ FIQ SVC IRQ FIQ

Copy CPSR into SPSR mode SPSR_mode Change CPSR to reflect
Appropriate mode Map banked registers according to the mode Disable interrupts
IRQs on any exception FIQs when a FIQ occurs and on reset

Sets lr_mode to return address lr mode Sets pc to the vector address for the exception
10/3/2007 CS5272 © 2007 Tulika Mitra 22

10/3/2007

CS5272 © 2007 Tulika Mitra

Returning from exception R t r i fr pti
If entry code used stack to store registers that must be preserved while it handles the exception, use LDM instruction to restore those registers Restore CPSR from SPSR_mode Restore program counter using return address stored in lr_mode

More M r concretely … r t l
Reset
No need to return

SWI
MOVS pc, lr

IRQ, FIQ Q, Q
SUBS pc, lr, #4 Processor checks for interrupt after executing each instruction

10/3/2007

CS5272 © 2007 Tulika Mitra

23

10/3/2007

CS5272 © 2007 Tulika Mitra

24

Interrupt Handlers I t rr pt H dl r
When an interrupt occurs, the hardware will jump to an occurs “interrupt handler”
time

Nested/Re-entrant Interrupts N t d/R tr t I t rr pt
Interrupts can occur within interrupt handlers
user program
IRQ Interrupt handler FIQ Interrupt handler

time

Task IRQ FIQ

user program
IRQ Interrupt handler

user program p g

Task IRQ FIQ

user program

Interrupt Interrupt
10/3/2007 CS5272 © 2007 Tulika Mitra 25 10/3/2007

Second CS5272 Interrupt© 2007 Tulika Mitra

• On interrupt, the processor will set the corresponding interrupt bit in the CPSR p g p to disable subsequent interrupts of the same type from occurring. • However, interrupts of a higher priority can still occur. till
26

Timing f Interrupts Ti i of I t rr pt
Before an interrupt handler can do anything, it must save away the current program's registers (if it touches those registers) That's why the FIQ has lots of extra registers - to minimize time CPU context saving overhead

Installing interrupt handler 1 I t lli i t rr pt h dl r -1
unsigned Install_Handler (unsigned location, unsigned *vector) { unsigned vec, oldvec; vec = ( (unsigned location) – (unsigned) vector – 0x8) | 0xE59FF000; oldvec = *vector; vector; *vector = vec; return (oldvec); } unsigned *irqvec = (unsigned *)0x18; static unsigned pIRQ_Handler = (unsigned)IRQ_handler; Install_Handler (&pIRQHandler, irqvec);

Task IRQ FIQ

user program

cpu context saved

user program

“servicing” interrupt cpu context restored

Interrupt latency

10/3/2007

Interrupt

CS5272 © 2007 Tulika Mitra

27

10/3/2007

CS5272 © 2007 Tulika Mitra

28

Interrupt response

Installing interrupt h dl r I t lli i t rr pt handler - 2
Take the address of the exception handler Subtract the address of the vector Subtract 0x8 as PC points to current address + 0x8 Logically OR this with 0xE59FF000 (opcode for LDR PC, [pc, #offset]) to produce the value to be placed in the vector

Simple interrupt handler in Si pl i t rr pt h dl r i C
__irq void IRQHandler (void) { volatile unsigned int *base = (unsigned int *) 0x80000000; if (*base == 1) // which interrupt was it ? C_int_handler(); // process the interrupt *(base+1) = 0; //clear the interrupt } __irq keyword preserves all ATPCS corruptible registers, preserves all other registers used by the function, and exits by setting PC to (lr-4) and restoring CPSR If handler calls a subroutine, __irq also preserves and restores the link register from stack 0x80000000 is the memory-mapped interrupt controller base address
10/3/2007 CS5272 © 2007 Tulika Mitra 30

10/3/2007

CS5272 © 2007 Tulika Mitra

29

Reentrant i t rr pt h dl r R tr t interrupt handler - 1
Interrupt handler re-enables interrupts p p Interrupt handler calls a subroutine (with BL instr) and return address is copied into lr_IRQ Another interrupt occurs and the return address of the subroutine (in lr_IRQ) is corrupted
__irq keyword does not help irq

Reentrant i t rr pt h dl r R tr t interrupt handler - 2
IRQ SUB lr lr #4 lr, lr, ; return address STMFD sp!, {lr} ; push adjusted lr_IRQ MRS r14, SPSR ; copy spsr_IRQ to r14 STMFD sp!, {r12, r14} ; save work registers and spsr_IRQ ; clear interrupts ; re-enable interrupts MSR CPSR_c, #0x1F ; switch to SYS mode, USR mode registers are now current ; CPSR_c are just the control bits STMFD sp! {r0-r3,lr} ; save lr_USR and non callee saved registers sp!, {r0 r3 lr} lr USR non-callee BL C_irq_handler LDMFD sp!, {r0-r3,lr} MSR CPSR_c, #0x92 ; switch to IRQ mode and disable IRQs LDMFD sp! {r12 r14} sp!, {r12, MSR SPSR_cf, r14 ; SPSR_cf are control and conditional bits LDMFD sp!, {pc}^ ; return from IRQ, ^ specifies CPSR is restored from SPSR END

Use system mode that uses user-mode register Write top level interrupt handler in assembly

10/3/2007

CS5272 © 2007 Tulika Mitra

31

10/3/2007

CS5272 © 2007 Tulika Mitra

32

Reentrant i t rr pt h dl r 3 R tr t interrupt handler -3
Save return address on IRQ stack Save work registers and spsr_IRQ Clear the source of the interrupt Switch to system mode Re-enable interrupts Save user mode link register and non callee-saved register Call C interrupt handler function (user-mode lr register) p ( g ) When the C interrupt handler returns, restore user mode register and disable interrupts Switch to IRQ node disabling interrupts Restore work registers and spsr_IRQ Return from IRQ

MSR and MRS instructions d i tr ti
MRS and MSR are used to read and write the Current Program Status Register (CPSR) and Saved Program Status Registers (SPSRs) of the ARM core. These are commonly used to change processor mode and to enable/disable interrupts, d dt bl /di bl i t t when the core is in a privileged mode (i.e. not User mode)

10/3/2007

CS5272 © 2007 Tulika Mitra

33

10/3/2007

CS5272 © 2007 Tulika Mitra

34

Putting ll t th r I t rr pt P tti it all together: Interrupt I/O
Replaces the following busy-wait I/O busy wait current_char = mystring; while ( current_char != ‘\0’) { (*current char ! \0 ) poke(OUT_CHAR,*current_char); /* busy wait for the transmission to complete */ while (peek(OUT_STATUS) != 0); current_char++; rr t h r++ }
10/3/2007 CS5272 © 2007 Tulika Mitra 35

Putting ll t th r I t rr pt P tti it all together: Interrupt I/O
Foreground program
current_char = mystring; h i while (*current_char != ‘\0’) { add_char_to_buffer(*current_char); current_char++; } poke (OUT_DATA, remove_char_from_buffer()); /* put character in device */ poke(OUT_STATUS, 1); /* initiate transmission */

Interrupt handler (called when transmission is complete) I t t h dl ( ll d h t i i i l t )
void output_handler(){ if (!empty_buffer()){ poke(OUT_DATA, remove_char_from_buffer()); /* put character in device */ poke(OUT_STATUS, 1); /* initiate transmission */ } }

10/3/2007

CS5272 © 2007 Tulika Mitra

36

Software I t rr pt S ft r Interrupts (SWI)
SWIs (often called software traps) allow a user program to “call” the OS -- that is, SWIs are how system calls are implemented. When SWIs execute, the processor changes modes (from User to Supervisor mode on the ARM) and disables interrupts

How Do We Determine the SWI number? b r?
All SWIs go to 0x08
Vector Table USER Program
ADD SWI SUB r0,r0,r1 0x10 r2,r2,r0 starting at 0x00 in memory 0x00 to R_Handler (Reset 0x04 to U_Handler (Undef instr.) 0x08 to S_Handler (SWI) 0x0c to P_Handler (Prefetch abort) 0 0 0x10 to D Handler (Data abort) D_Handler 0x14 ... (Reserved) 0x18 to I_Handler (IRQ) 0x1c to F_Handler (FIQ)

SWI Handler (S_Handler) SWI Handler must serve as clearing house f different h for diffe e t SWIs

MOVS

pc, lr

10/3/2007

CS5272 © 2007 Tulika Mitra

37

10/3/2007

CS5272 © 2007 Tulika Mitra

38

SWI Instr ction Format Instruction
Example: SWI 0x18

SWI Handler Uses “Comment” Field Comment
cond
1 1 1 1

24-bit “comment” field (ignored by processor)

Vector Table starting at 0x00 in memory 31 28 27 24 23 24-bit “comment” field (ignored by processor) 0 USER Program
ADD SWI SUB r0,r0,r1 0x10 r2,r2,r0 0x00 0x04 0x08 0x0c 0x10 0x14 0x18 0x1c to to to to to R Handler R_Handler U_Handler S_Handler P_Handler D_Handler ... to I_Handler to F_Handler (Reset (S_Handler) (Undef instr.) (SWI) LDR r0,[lr,#-4] (Prefetch abort) BIC r0,r0,#0xff000000 (Data abort) (Reserved) (IRQ) R0 holds SWI number (FIQ) MOVS pc, l lr

SWI Handler

cond 1 1 1 1

SWI number

10/3/2007

CS5272 © 2007 Tulika Mitra

39

10/3/2007

CS5272 © 2007 Tulika Mitra

40

Use SWI # to Jump to “Service Routine Service Routine”
cond
1 1 1 1

P ob e w t T e C e t Ha d e Problem with The Current Handler
What was in R0? User program may have been using this register. Therefore, cannot just use it - must first save it Vector Table (spring board) USER Program
ADD SWI SUB r0,r0,r1 0x10 r2,r2,r0 starting at 0x00 in memory i 0 00 i SWI Handler 0x00 to R_Handler (Reset (S_Handler) 0x04 to U_Handler (Undef instr.) 0x08 to S_Handler (SWI) LDR r0,[lr,#-4] 0x0c to P Handler (Prefetch abort) BIC r0 r0 #0xff000000 P_Handler r0,r0,#0xff000000 0x10 to D_Handler (Data abort) switch (r0){ 0x14 ... (Reserved) case 0x00: service_SWI1(); 0x18 to I_Handler (IRQ) case 0x01: service_SWI2(); case 0x02: service_SWI3(); 0x1c to F_Handler (FIQ)
… }

24-bit “comment” field (ignored by processor)

Vector Table USER Program
ADD SWI SUB r0,r0,r1 0x10 r2,r2,r0 starting at 0x00 in memory SWI Handler 0x00 to R_Handler (Reset (S_Handler) 0x04 to U_Handler (Undef instr.) 0x08 to S_Handler (SWI) LDR r0,[lr,#-4] 0x0c to P_Handler (Prefetch abort) BIC r0,r0,#0xff000000 0x10 to D_Handler (Data abort) switch (r0){ 0x14 ... (Reserved) case 0x00: service_SWI1(); 0x18 to I Handler (IRQ) I_Handler case 0 01 service_SWI2(); 0x01: i SWI2() case 0x02: service_SWI3(); 0x1c to F_Handler (FIQ)
… }

MOVS

pc, lr

MOVS

pc, lr

10/3/2007

CS5272 © 2007 Tulika Mitra

41

10/3/2007

CS5272 © 2007 Tulika Mitra

42

Full F ll SWI Handler
S_Handler SUB STMFD MRS STR MOV LDR BIC BL LDR MSR LDMFD ADD MOVS
10/3/2007

C_SWI_Handler C SWI H dl r
Previous sp_svc

sp,sp, # #4 sp!, {r0­r12, lr} r2, spsr[_csxf] r2, [sp, #14*4] r1, sp r0, [lr, #­4] r0,r0,#0xff000000 C_SWI_handler r2, [sp, #14*4] spsr_csxf, r2 sp!, {r0­r12, lr} sp, sp, #4 pc, lr

; leave room on stack for SPSR ; store user's gp registers ; get SPSR into gp registers ; store SPSR above gp registers ; pointer to parameters on stack ; extract the SWI number ; get SWI # by bit-masking ; go to handler (see next slide) ; restore SPSR (NOT “sp!”) ; unstack user's registers ; remove space used to store SPSR ; return from handler
CS5272 © 2007 Tulika Mitra 43

void C_SWI_handler(unsigned number, ( g , unsigned *regs) regs[12] { switch (number){ case 0: /* SWI number 0 code */ break; case 1: /* SWI number 1 code */ break; ... case XXX: /* SWI number XXX code */ break; default: sp_svc } /* end switch */ } /* end C_SWI_handler() */ ()
10/3/2007 CS5272 © 2007 Tulika Mitra

spsr_svc lr_svc r12 r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 2 r1 r0

44

C_SWI_Handler Contd. C SWI H dl – C td
Previous sp_svc

Calling SWIs from C Code
spsr_svc lr_svc r12 r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 2 r1 r0

void C_SWI_handler(unsigned number, g , unsigned *regs) regs[12] { switch (number){ case 0: /* SWI number 0 code */ value_in_reg 0 = reg[0]; g_ g reg[0] = updated_value_0; break; …… } /* end switch */ sp_svc } /* end C_SWI_handler() */

Assembly code produced by compiler User-Level C Source Code char __swi(4) SWI_ReadC(void); void readline (char *buffer) { char ch; do { *buffer++ = ch= SWI_ReadC();} while (ch != 13); *buffer = 0; } /* end readline() */
readline STMDF MOV readagain SWI STRB CMP BNE MOV STRB LDMIA sp!,{lr} lr, a1 0x4 a1,[lr],#1 a1,0xd readagain a1,#0 a1, [lr, #0] sp!, {pc}

10/3/2007

CS5272 © 2007 Tulika Mitra

45

10/3/2007

CS5272 © 2007 Tulika Mitra

46

Summary S r
Memory mapped Memory-mapped I/O Interrupt and Exceptions Interrupt driven Interrupt-driven I/O Software Interrupt (SWI)

10/3/2007

CS5272 © 2007 Tulika Mitra

47

Sign up to vote on this title
UsefulNot useful