📄 vectors.s
字号:
/* * vectors.s: micromonitor exception-handling * * Basic interrupt handling code. These are the ISRs used * by the monitor. They basically save processor state and call * the respective C handler. The C handler will figure out the * interrupt cause and will either call the application handler, * if one is declared, or perform the default handling which is to * enter the monitor (via a SWI trap). * * by Nick Patavalis (npat@inaccessnetworks.com) * * $Id: vectors.s,v 1.4 2001/05/25 03:32:18 npat Exp $ *//********************************************************************/ /* Generate ARM (not thumb) instruction set */ .arm/********************************************************************/ .equ REGTBL_PC, (15 * 4) .equ REGTBL_CPSR, (16 * 4) .extern handle_irq .extern handle_software_interrupt .extern handle_undefined_instruction .extern handle_abort_prefetch .extern handle_abort_data .global undefined_instruction .global abort_prefetch .global abort_data .global not_used .global fast_interrupt_request .global interrupt_request .global software_interrupt .global resume /********************************************************************/ .text/**********************************************************************/undefined_instruction: /* * Save full user-mode processor-state */ str r14, [sp, #-4]! /* push link-addr from r14 to stack */ stmfd sp!, {r0-r14}^ /* push all usr regs to stack */ /* * Put the exception address in r0 */ sub r0, r14, #4 /* * Call the C function to figure out what happened */ bl handle_undefined_instruction /* * Restore user-mode processor state and return */ ldmfd sp!, {r0-r14}^ /* pop all usr regs from stack */ ldr r14, [sp], #4 /* pop link addr from stack to r14 */ movs pc, r14 /* return */ abort_prefetch: /* * Save full user-mode processor-state */ str r14, [sp, #-4]! /* push link-addr from r14 to stack */ stmfd sp!, {r0-r14}^ /* push all usr regs to stack */ /* * Put the exception address in r0 */ sub r0, r14, #4 /* * Call the C function to figure out what happened */ bl handle_abort_prefetch /* * Restore user-mode processor state and return */ ldmfd sp!, {r0-r14}^ /* pop all usr regs from stack */ ldr r14, [sp], #4 /* pop link addr from stack to r14 */ subs pc, r14, #4 /* return */abort_data: /* * Save full user-mode processor-state */ str r14, [sp, #-4]! /* push link-addr from r14 to stack */ stmfd sp!, {r0-r14}^ /* push all usr regs to stack */ /* * Put the exception address in r0 */ sub r0, r14, #8 /* * Call the C function to figure out what happened */ bl handle_abort_data /* * Restore user-mode processor state and return */ ldmfd sp!, {r0-r14}^ /* pop all usr regs from stack */ ldr r14, [sp], #4 /* pop link addr from stack to r14 */ subs pc, r14, #8 /* return */not_used: b not_used/**********************************************************************/ /* * IRQs and FIQs are handled in exactly the same manner. * This is maybe not the most eficient thing to do (as it * practically equates FIQs with IRQs) but it is much simpler, * and it will have to do for our purposes. */ fast_interrupt_request:interrupt_request: /* * Save full user-mode processor-state */ str r14, [sp, #-4]! /* push link-addr from r14 to stack */ stmfd sp!, {r0-r14}^ /* push all usr regs to stack */ /* * Put the exception address in r0 */ sub r0, r14, #8 /* * Call the C function to figure out what happened */ bl handle_irq /* * Restore user-mode processor state and return */ ldmfd sp!, {r0-r14}^ /* pop all usr regs from stack */ ldr r14, [sp], #4 /* pop link addr from stack to r14 */ subs pc, r14, #4 /* return *//**********************************************************************/ software_interrupt: /* * Save full user-mode processor-state */ str r14, [sp, #-4]! /* Save link-addr from r14 to stack */ ldr r14, =regtbl /* load r14 with addr of regtbl */ stmia r14!, {r0-r14}^ /* store usr regs to regtbl */ mov r0, r14 /* move regtbl[pc] addr to r0 */ ldr r14, [sp], #4 /* load link-addr from stack to r14 */ str r14, [r0], #4 /* save link-addr to regtbl[pc] */ mrs r1, spsr /* move SPSR value to r1 */ str r1, [r0], #4 /* save SPSR value to regtbl[cpsr] */ /* * Put the trap-number in r0 */ ldr r0, [r14, #-4] bic r0, r0, #0xff000000 /* * Now go on to C to figure out what happened */ bl handle_software_interrupt /* if the C function returns, then gracefully 'return' from the SWI handler by falling-through and doing a resume */ resume: ldr r14, =regtbl /* move regtbl addr to r14 */ ldr r0, [r14, #REGTBL_PC] /* load link-addr to r0 */ str r0, [r13, #-4]! /* push link-addr to stack */ ldr r0, [r14, #REGTBL_CPSR] /* load cpsr to r0 */ msr spsr, r0 /* set spsr from r0 */ ldmia r14, {r0-r14}^ /* restore usr regs from regtbl */ ldr r14, [r13], #4 /* load link-addr to r14 from stack */ movs pc, r14 /* return *//**********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -