Mercurial > nand-ecoscentric
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 |
