这篇是中断向量的存储、注释比较清晰、就不再细讲
1 /*
2 *************************************************************************
3 *
4 * Interrupt handling
5 *
6 *************************************************************************
7 */
8 @
9 @ IRQ stack frame.
10 @
11 #define S_FRAME_SIZE 72
12
13 #define S_OLD_R0 68
14 #define S_PSR 64
15 #define S_PC 60
16 #define S_LR 56
17 #define S_SP 52
18
19 #define S_IP 48
20 #define S_FP 44
21 #define S_R10 40
22 #define S_R9 36
23 #define S_R8 32
24 #define S_R7 28
25 #define S_R6 24
26 #define S_R5 20
27 #define S_R4 16
28 #define S_R3 12
29 #define S_R2 8
30 #define S_R1 4
31 #define S_R0 0
32
33 #define MODE_SVC 0x13
34 #define I_BIT 0x80
35
36 /*
37 * use bad_save_user_regs for abort/prefetch/undef/swi ...
38 */
39
40 .macro bad_save_user_regs
41 /* carve out a frame on current user stack */
42 sub sp, sp, #S_FRAME_SIZE
43 /* Save user registers (now in svc mode) r0-r12 */
44 stmia sp, {r0 - r12}
45
46 ldr r2, _armboot_start
47 sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
48 /* set base 2 words into abort stack */
49 sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
50 /* get values for 'aborted' pc and cpsr (into parm regs) */
51 ldmia r2, {r2 - r3}
52 /* grab pointer to old stack */
53 add r0, sp, #S_FRAME_SIZE
54
55 add r5, sp, #S_SP
56 mov r1, lr
57 /* save sp_SVC, lr_SVC, pc, cpsr */
58 stmia r5, {r0 - r3}
59 /* save current stack into r0 (param register) */
60 mov r0, sp
61 .endm
62
63 .macro get_bad_stack
64 /* setup our mode stack (enter in banked mode) */
65 ldr r13, _armboot_start
66 /* move past malloc pool */
67 sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
68 /* move to reserved a couple spots for abort stack */
69 sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
70
71 /* save caller lr in position 0 of saved stack */
72 str lr, [r13]
73 /* get the spsr */
74 mrs lr, spsr
75 /* save spsr in position 1 of saved stack */
76 str lr, [r13, #4]
77
78 /* prepare SVC-Mode */
79 mov r13, #MODE_SVC
80 @ msr spsr_c, r13
81 /* switch modes, make sure moves will execute */
82 msr spsr, r13
83 /* capture return pc */
84 mov lr, pc
85 /* jump to next instruction & switch modes. */
86 movs pc, lr
87 .endm
88
89 .macro get_bad_stack_swi
90 /* space on current stack for scratch reg. */
91 sub r13, r13, #4
92 /* save R0's value. */
93 str r0, [r13]
94 /* get data regions start */
95 ldr r0, _armboot_start
96 /* move past malloc pool */
97 sub r0, r0, #(CONFIG_SYS_MALLOC_LEN)
98 /* move past gbl and a couple spots for abort stack */
99 sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
100 /* save caller lr in position 0 of saved stack */
101 str lr, [r0]
102 /* get the spsr */
103 mrs r0, spsr
104 /* save spsr in position 1 of saved stack */
105 str lr, [r0, #4]
106 /* restore r0 */
107 ldr r0, [r13]
108 /* pop stack entry */
109 add r13, r13, #4
110 .endm
111
112 /*
113 * exception handlers
114 */
115 .align 5
116 undefined_instruction:
117 get_bad_stack
118 bad_save_user_regs
119 bl do_undefined_instruction
120
121 .align 5
122 software_interrupt:
123 get_bad_stack_swi
124 bad_save_user_regs
125 bl do_software_interrupt
126
127 .align 5
128 prefetch_abort:
129 get_bad_stack
130 bad_save_user_regs
131 bl do_prefetch_abort
132
133 .align 5
134 data_abort:
135 get_bad_stack
136 bad_save_user_regs
137 bl do_data_abort
138
139 .align 5
140 not_used:
141 get_bad_stack
142 bad_save_user_regs
143 bl do_not_used
144
145 .align 5
146 irq:
147 get_bad_stack
148 bad_save_user_regs
149 bl do_irq
150
151 .align 5
152 fiq:
153 get_bad_stack
154 bad_save_user_regs
155 bl do_fiq
156 #endif /* CONFIG_NAND_SPL */