comparison packages/hal/cortexm/arch/current/src/vectors.S @ 3234:abf5be1b8582

Whitespace cleanup
author vae
date Mon, 23 Apr 2012 19:03:36 +0000
parents 05d279424483
children 614e724c4b7a
comparison
equal deleted inserted replaced
3233:e07f3346a350 3234:abf5be1b8582
46 // that save and restore state for both exceptions and 46 // that save and restore state for both exceptions and
47 // interrupts. 47 // interrupts.
48 // 48 //
49 //####DESCRIPTIONEND#### 49 //####DESCRIPTIONEND####
50 // 50 //
51 //========================================================================*/ 51 //========================================================================
52 */
52 53
53 #include <pkgconf/hal.h> 54 #include <pkgconf/hal.h>
54 #include <pkgconf/hal_cortexm.h> 55 #include <pkgconf/hal_cortexm.h>
55 #ifdef CYGPKG_KERNEL 56 #ifdef CYGPKG_KERNEL
56 #include <pkgconf/kernel.h> 57 #include <pkgconf/kernel.h>
76 77
77 .long hal_startup_stack // 0 Reset stack 78 .long hal_startup_stack // 0 Reset stack
78 .long hal_reset_vsr // 1 Reset entry 79 .long hal_reset_vsr // 1 Reset entry
79 80
80 //========================================================================== 81 //==========================================================================
81 82
82 .text 83 .text
83 .thumb 84 .thumb
84 85
85 //========================================================================== 86 //==========================================================================
86 // Fake entry point. 87 // Fake entry point.
87 // 88 //
88 // The ELF file entry point points here. When loading an executable 89 // The ELF file entry point points here. When loading an executable
89 // via RedBoot/Stubs or via JTAG the PC will be set to this address. 90 // via RedBoot/Stubs or via JTAG the PC will be set to this address.
90 // The code here sets up the SP and branches to the reset VSR in 91 // The code here sets up the SP and branches to the reset VSR in
91 // emulation of the hardware reset behaviour. 92 // emulation of the hardware reset behaviour.
92 93
93 .align 2 94 .align 2
94 .global reset_vector 95 .global reset_vector
95 .thumb 96 .thumb
96 .thumb_func 97 .thumb_func
97 .type reset_vector, %function 98 .type reset_vector, %function
100 ldr sp,=hal_startup_stack 101 ldr sp,=hal_startup_stack
101 b hal_reset_vsr 102 b hal_reset_vsr
102 103
103 .pool 104 .pool
104 105
105 #if !defined(CYG_HAL_STARTUP_RAM) 106 #if !defined(CYG_HAL_STARTUP_RAM)
106 //========================================================================== 107 //==========================================================================
107 // State switch VSR 108 // State switch VSR
108 // 109 //
109 // This is called from the init code to switch execution from the main 110 // This is called from the init code to switch execution from the main
110 // stack to the process stack. We also take the opportunity to do some 111 // stack to the process stack. We also take the opportunity to do some
113 // 114 //
114 // The adjustment to MSP by 1/2 interrupt stack size allows code to 115 // The adjustment to MSP by 1/2 interrupt stack size allows code to
115 // throw exceptions without corrupting the execution stack. This is 116 // throw exceptions without corrupting the execution stack. This is
116 // only necessary for non-kernel configurations (e.g. RedBoot, Stubs) 117 // only necessary for non-kernel configurations (e.g. RedBoot, Stubs)
117 // since kernel configurations will switch to a thread stack before 118 // since kernel configurations will switch to a thread stack before
118 // they should throw an exception. 119 // they should throw an exception.
119 120
120 .global hal_switch_state_vsr 121 .global hal_switch_state_vsr
121 .thumb 122 .thumb
122 .thumb_func 123 .thumb_func
123 .type hal_switch_state_vsr, %function 124 .type hal_switch_state_vsr, %function
124 hal_switch_state_vsr: 125 hal_switch_state_vsr:
125 126
126 mov r0,#CYGNUM_HAL_CORTEXM_PRIORITY_MAX 127 mov r0,#CYGNUM_HAL_CORTEXM_PRIORITY_MAX
127 msr basepri,r0 128 msr basepri,r0
128 129
129 mov r0,#2 // Set CONTROL register to 2 130 mov r0,#2 // Set CONTROL register to 2
130 msr control,r0 131 msr control,r0
131 isb // Insert a barrier 132 isb // Insert a barrier
132 133
133 mov r0,sp 134 mov r0,sp
134 msr psp,r0 // Copy SP to PSP 135 msr psp,r0 // Copy SP to PSP
135 136
136 #if !defined(CYGPKG_KERNEL) 137 #if !defined(CYGPKG_KERNEL)
137 sub sp,#(CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE/2) 138 sub sp,#(CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE/2)
138 #endif 139 #endif
139 140
140 orr lr,#0xD // Adjust return link 141 orr lr,#0xD // Adjust return link
141 bx lr // Return to init code on PSP now 142 bx lr // Return to init code on PSP now
142 143
143 #endif 144 #endif
144 145
145 //========================================================================== 146 //==========================================================================
146 // Default exception VSR 147 // Default exception VSR
147 // 148 //
148 // This is attached to all exception vectors. It saves the entire 149 // This is attached to all exception vectors. It saves the entire
149 // machine state and calls into the eCos exception handling code. 150 // machine state and calls into the eCos exception handling code.
151 // NOTE: At present this implementation does not permit an exception 152 // NOTE: At present this implementation does not permit an exception
152 // handler to suspend the faulting thread and enter the scheduler to 153 // handler to suspend the faulting thread and enter the scheduler to
153 // switch elsewhere. However, I know of no code that does anything 154 // switch elsewhere. However, I know of no code that does anything
154 // like this. If there is then this may need treating in the same way 155 // like this. If there is then this may need treating in the same way
155 // as the interrupt end code. 156 // as the interrupt end code.
156 157
157 .global hal_default_exception_vsr 158 .global hal_default_exception_vsr
158 .thumb 159 .thumb
159 .thumb_func 160 .thumb_func
160 .type hal_default_exception_vsr, %function 161 .type hal_default_exception_vsr, %function
161 hal_default_exception_vsr: 162 hal_default_exception_vsr:
162 163
163 mrs r0,psp // Get process stack 164 mrs r0,psp // Get process stack
164 sub r1,r0,#(4*12) // Make space for saved state 165 sub r1,r0,#(4*12) // Make space for saved state
165 msr psp,r1 // Ensure PSP is up to date 166 msr psp,r1 // Ensure PSP is up to date
166 167
167 mov r1,#1 // R1 = exception state type 168 mov r1,#1 // R1 = exception state type
168 mrs r2,ipsr // R2 = vector number 169 mrs r2,ipsr // R2 = vector number
169 mrs r3,basepri // R3 = basepri 170 mrs r3,basepri // R3 = basepri
170 stmfd r0!,{r1-r11,lr} // Push type, vector, basepri, r4-11 171 stmfd r0!,{r1-r11,lr} // Push type, vector, basepri, r4-11
171 172
172 mov r4,r0 // R4 = saved state pointer 173 mov r4,r0 // R4 = saved state pointer
173 174
174 bl hal_deliver_exception 175 bl hal_deliver_exception
175 176
176 mov r0,r4 // R0 = state saved across call 177 mov r0,r4 // R0 = state saved across call
177 ldmfd r0!,{r1-r11,lr} // Pop type, vec, basepri, registers and LR 178 ldmfd r0!,{r1-r11,lr} // Pop type, vec, basepri, registers and LR
178 msr psp,r0 // Restore PSP 179 msr psp,r0 // Restore PSP
179 msr basepri,r3 // Restore basepri 180 msr basepri,r3 // Restore basepri
180 181
181 bx lr // Return 182 bx lr // Return
182 183
183 .pool 184 .pool
184 185
185 //========================================================================== 186 //==========================================================================
186 // Default interrupt VSR 187 // Default interrupt VSR
187 // 188 //
188 // This is a trampoline that translates from the hardware defined entry point 189 // This is a trampoline that translates from the hardware defined entry point
189 // to the ISR defined by eCos. The CPU will switch automatically to the main 190 // to the ISR defined by eCos. The CPU will switch automatically to the main
190 // (interrupt) stack with the process state saved on the process stack. Apart 191 // (interrupt) stack with the process state saved on the process stack. Apart
191 // from saving a pointer to the interrupt state for Ctrl-C support, and fetching 192 // from saving a pointer to the interrupt state for Ctrl-C support, and fetching
192 // the vector number, most of the work is actually done in hal_deliver_interrupt(). 193 // the vector number, most of the work is actually done in hal_deliver_interrupt().
193 194
194 195
195 .global hal_default_interrupt_vsr 196 .global hal_default_interrupt_vsr
196 .thumb 197 .thumb
198 .type hal_default_interrupt_vsr, %function 199 .type hal_default_interrupt_vsr, %function
199 hal_default_interrupt_vsr: 200 hal_default_interrupt_vsr:
200 201
201 push {lr} // Save return link 202 push {lr} // Save return link
202 sub sp,#4 // Realign SP to 8 bytes 203 sub sp,#4 // Realign SP to 8 bytes
203 204
204 #if CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED > 0 205 #if CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED > 0
205 // If we are supporting Ctrl-C interrupts from GDB, we must squirrel 206 // If we are supporting Ctrl-C interrupts from GDB, we must squirrel
206 // away a pointer to the saved interrupt state here so that we can 207 // away a pointer to the saved interrupt state here so that we can
207 // plant a breakpoint at some later time. 208 // plant a breakpoint at some later time.
208 209
209 .extern hal_saved_interrupt_state 210 .extern hal_saved_interrupt_state
210 mrs r1,psp // Get PSP 211 mrs r1,psp // Get PSP
211 mov r0,#3 // Interrupt state type 212 mov r0,#3 // Interrupt state type
212 stmfd r1!,{r0} // Push interrupt type 213 stmfd r1!,{r0} // Push interrupt type
213 ldr r12,=hal_saved_interrupt_state 214 ldr r12,=hal_saved_interrupt_state
214 str r1,[r12] 215 str r1,[r12]
215 #endif 216 #endif
216 217
217 mrs r0,ipsr // R0 = arg0 = vector number 218 mrs r0,ipsr // R0 = arg0 = vector number
218 sub r0,#15 // Adjust to interrupt range 219 sub r0,#15 // Adjust to interrupt range
219 220
220 bl hal_deliver_interrupt 221 bl hal_deliver_interrupt
221 222
222 add sp,#4 // pop alignment padding 223 add sp,#4 // pop alignment padding
223 pop {pc} // Pop LR and return 224 pop {pc} // Pop LR and return
224 225
225 .pool 226 .pool
226 227
227 //========================================================================== 228 //==========================================================================
228 // Pendable SVC VSR 229 // Pendable SVC VSR
229 // 230 //
231 // and finalizes interrupt processing by calling interrupt_end(). We want 232 // and finalizes interrupt processing by calling interrupt_end(). We want
232 // to run interrupt_end() on the PSP of the current thread. So we push 233 // to run interrupt_end() on the PSP of the current thread. So we push
233 // a fake exception frame onto the PSP which will take us to hal_interrupt_end(), 234 // a fake exception frame onto the PSP which will take us to hal_interrupt_end(),
234 // which will make the call. The return link loaded by that frame takes us 235 // which will make the call. The return link loaded by that frame takes us
235 // back to hal_interrupt_end_done which will unwind the real exception 236 // back to hal_interrupt_end_done which will unwind the real exception
236 // frame that is still on the PSP. 237 // frame that is still on the PSP.
237 238
238 239
239 .global hal_pendable_svc_vsr 240 .global hal_pendable_svc_vsr
240 .thumb 241 .thumb
241 .thumb_func 242 .thumb_func
242 .type hal_pendable_svc_vsr, %function 243 .type hal_pendable_svc_vsr, %function
243 hal_pendable_svc_vsr: 244 hal_pendable_svc_vsr:
244 245
245 mrs r12,psp // R12 = thread's PSP 246 mrs r12,psp // R12 = thread's PSP
246 sub r0,r12,#0x20 // Make space for frame 247 sub r0,r12,#0x20 // Make space for frame
247 msr psp,r0 // Put it back 248 msr psp,r0 // Put it back
248 249
249 ldr r3,=0x01000000 // R3 = PSR = thumb bit set 250 ldr r3,=0x01000000 // R3 = PSR = thumb bit set
250 ldr r2,=hal_interrupt_end // R2 = PC = interrupt end entry point 251 ldr r2,=hal_interrupt_end // R2 = PC = interrupt end entry point
251 ldr r1,=hal_interrupt_end_done // R1 = LR = restore code 252 ldr r1,=hal_interrupt_end_done // R1 = LR = restore code
252 stmfd r12!,{r0-r3} // Save fake R12, LR, PC, PSR 253 stmfd r12!,{r0-r3} // Save fake R12, LR, PC, PSR
253 stmfd r12!,{r0-r3} // Save fake R0-R3 254 stmfd r12!,{r0-r3} // Save fake R0-R3
254 255
255 bx lr // Return to hal_interrupt_end 256 bx lr // Return to hal_interrupt_end
256 257
257 .pool 258 .pool
258 259
259 //========================================================================== 260 //==========================================================================
260 // Interrupt end done 261 // Interrupt end done
261 // 262 //
262 // After calling interrupt end a thread returns here to unstack the 263 // After calling interrupt end a thread returns here to unstack the
263 // exception frame used to enter hal_pendable_svc_vsr. We can only 264 // exception frame used to enter hal_pendable_svc_vsr. We can only
264 // successfully unstack a frame by doing a proper exception return 265 // successfully unstack a frame by doing a proper exception return
265 // from handler mode, so we use a SWI which will discard its own 266 // from handler mode, so we use a SWI which will discard its own
266 // frame and restore the saved one. 267 // frame and restore the saved one.
267 268
268 269
269 .global hal_interrupt_end_done 270 .global hal_interrupt_end_done
270 .thumb 271 .thumb
271 .thumb_func 272 .thumb_func
272 .type hal_interrupt_end_done, %function 273 .type hal_interrupt_end_done, %function
273 hal_interrupt_end_done: 274 hal_interrupt_end_done:
274 275
275 ldr r3,=hal_interrupt_end_vsr 276 ldr r3,=hal_interrupt_end_vsr
276 swi 0 277 swi 0
277 278
278 //========================================================================== 279 //==========================================================================
279 // Interrupt end VSR 280 // Interrupt end VSR
280 // 281 //
281 // This is the SVC VSR invoked by hal_interrupt_end_done to restore the 282 // This is the SVC VSR invoked by hal_interrupt_end_done to restore the
282 // original exception frame from a pendable SVC entry. It does this 283 // original exception frame from a pendable SVC entry. It does this
283 // by discarding its own frame and using the one below it on the 284 // by discarding its own frame and using the one below it on the
284 // stack to return. 285 // stack to return.
285 286
286 .global hal_interrupt_end_vsr 287 .global hal_interrupt_end_vsr
287 .thumb 288 .thumb
288 .thumb_func 289 .thumb_func
289 .type hal_interrupt_end_vsr, %function 290 .type hal_interrupt_end_vsr, %function
290 hal_interrupt_end_vsr: 291 hal_interrupt_end_vsr:
291 292
292 mrs r12,psp // R12 = thread's PSP 293 mrs r12,psp // R12 = thread's PSP
293 add r12,#32 // Skip our saved state 294 add r12,#32 // Skip our saved state
294 msr psp,r12 // Restore thread's PSP 295 msr psp,r12 // Restore thread's PSP
295 296
296 bx lr // And return 297 bx lr // And return
305 306
306 .global hal_call_dsrs_vsr 307 .global hal_call_dsrs_vsr
307 .thumb 308 .thumb
308 .thumb_func 309 .thumb_func
309 .type hal_call_dsrs_vsr, %function 310 .type hal_call_dsrs_vsr, %function
310 311
311 hal_call_dsrs_vsr: 312 hal_call_dsrs_vsr:
312 313
313 .extern cyg_interrupt_call_pending_DSRs 314 .extern cyg_interrupt_call_pending_DSRs
314 b cyg_interrupt_call_pending_DSRs 315 b cyg_interrupt_call_pending_DSRs
315 316
318 // 319 //
319 // The SVC VSR is used as a general-purpose mechanism for running code 320 // The SVC VSR is used as a general-purpose mechanism for running code
320 // in handler mode. R3 contains the address of a piece of code to run, 321 // in handler mode. R3 contains the address of a piece of code to run,
321 // R0-R2 contain any arguments. Once entered the code is responsible for 322 // R0-R2 contain any arguments. Once entered the code is responsible for
322 // handling the system state and returning to thread mode. 323 // handling the system state and returning to thread mode.
323 // 324 //
324 // Note that R0-R3 must be explicitly restored from their stacked 325 // Note that R0-R3 must be explicitly restored from their stacked
325 // copies since a late arriving interrupt can preempt the SVC entry 326 // copies since a late arriving interrupt can preempt the SVC entry
326 // and corrupt these registers before we get here. 327 // and corrupt these registers before we get here.
327 328
328 .global hal_default_svc_vsr 329 .global hal_default_svc_vsr
334 mrs r12,psp 335 mrs r12,psp
335 ldmfd r12,{r0-r3} 336 ldmfd r12,{r0-r3}
336 bx r3 // Jump to routine in R3 337 bx r3 // Jump to routine in R3
337 338
338 .pool 339 .pool
339 340
340 //========================================================================== 341 //==========================================================================
341 // end of vectors.S 342 // end of vectors.S