Merge branch 'master' of /media/usbdisk-11/IER/reference/romboot
[romboot.git] / asm_isr.S
blobae82ed98c081987a35d17b74390624c6c18d003f
1 #include <AT91RM9200_inc.h>\r
2 \r
3 #define ARM_MODE_USER           0x10\r
4 #define ARM_MODE_FIQ            0x11\r
5 #define ARM_MODE_IRQ            0x12\r
6 #define ARM_MODE_SVC            0x13\r
7 #define ARM_MODE_ABORT          0x17\r
8 #define ARM_MODE_UNDEF          0x1B\r
9 #define ARM_MODE_SYS            0x1F\r
11 #define I_BIT                   0x80\r
12 #define F_BIT                   0x40\r
13 #define T_BIT                   0x20\r
16 /* -----------------------------------------------------------------------------\r
17    AT91F_ASM_SPI_Handler\r
18    ---------------------\r
19       Handler called by the AIC\r
20         \r
21       Save context\r
22         Call C handler\r
23     Restore context\r
24    ----------------------------------------------------------------------------- */\r
25                 \r
26 .global AT91F_ST_ASM_Handler  \r
28 AT91F_ST_ASM_Handler:\r
29 /*  Adjust and save LR_irq in IRQ stack */\r
30         sub         r14, r14, #4\r
31         stmfd       sp!, {r14}\r
33 /*  Write in the IVR to support Protect Mode\r
34   No effect in Normal Mode\r
35   De-assert the NIRQ and clear the source in Protect Mode */\r
36         ldr         r14, =AT91C_BASE_AIC\r
37         str         r14, [r14, #AIC_IVR]\r
39 /*  Save SPSR and r0 in IRQ stack */\r
40         mrs         r14, SPSR\r
41         stmfd       sp!, {r0, r14}\r
43 /*  Enable Interrupt and Switch in SYS Mode */\r
44         mrs         r0, CPSR\r
45         bic         r0, r0, #I_BIT\r
46         orr         r0, r0, #ARM_MODE_SYS\r
47         msr         CPSR_c, r0\r
48  \r
49 /* Save scratch/used registers and LR in User Stack */\r
50         stmfd       sp!, { r1-r3, r12, r14}\r
52         ldr     r1, =AT91F_ST_Handler\r
53         mov     r14, pc\r
54         bx      r1\r
56 /*  Restore scratch/used registers and LR from User Stack */\r
57         ldmia       sp!, { r1-r3, r12, r14}\r
59 /*  Disable Interrupt and switch back in IRQ mode */\r
60         mrs         r0, CPSR\r
61         bic         r0, r0, #ARM_MODE_SYS\r
62         orr         r0, r0, #I_BIT | ARM_MODE_IRQ\r
63         msr         CPSR_c, r0\r
65 /*  Mark the End of Interrupt on the AIC */\r
66         ldr         r0, =AT91C_BASE_AIC\r
67         str         r0, [r0, #AIC_EOICR]\r
69 /*  Restore SPSR_irq and r0 from IRQ stack */\r
70         ldmia       sp!, {r0, r14}\r
71         msr         SPSR_cxsf, r14\r
73 /*  Restore adjusted  LR_irq from IRQ stack directly in the PC */\r
74         ldmia       sp!, {pc}^\r