📄 vectors.s
字号:
mov r0,sp // r0 survives mode switch mrs r2,cpsr // Save current psr for return orr r1,r1,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE bic r1,r1,#CPSR_THUMB_ENABLE msr cpsr,r1 stmfd r0!,{r8-r12,sp,lr} msr cpsr,r2 // back to svc mode mov sp,r0 // update stack pointer 2: // now save pre-exception r0-r7 on current stack ldmfd r3,{r0-r5} stmfd sp!,{r0-r7} // sp needs fixing if exception occured in SVC mode. ldr r1,[sp,#armreg_cpsr] and r1,r1,#CPSR_MODE_BITS cmp r1,#CPSR_SUPERVISOR_MODE ldreq r1,[sp,#armreg_svcsp] streq r1,[sp,#armreg_sp] mov v6,sp // Save pointer to register frame// mov r0,sp// bl _show_frame_in#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK // Switch to interrupt stack ldr r2,.irq_level // current number of nested interrupts ldr r0,[r2] add r1,r0,#1 str r1,[r2] // if was zero, switch stacks cmp r0,#0 moveq r1,sp // save old stack pointer ldreq sp,.__interrupt_stack stmeqfd sp!,{r1}10:#endif // The entire CPU state is now stashed on the stack, // increment the scheduler lock and handle the interrupt#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT .extern cyg_scheduler_sched_lock ldr r3,.cyg_scheduler_sched_lock ldr r4,[r3] add r4,r4,#1 str r4,[r3]#endif THUMB_MODE(r3,10) mov r0,v6 bl hal_IRQ_handler // determine interrupt source mov v1,r0 // returned vector ##if defined(CYGPKG_KERNEL_INSTRUMENT) && \ defined(CYGDBG_KERNEL_INSTRUMENT_INTR) ldr r0,=RAISE_INTR // arg0 = type = INTR,RAISE mov r1,v1 // arg1 = vector mov r2,#0 // arg2 = 0 bl cyg_instrument // call instrument function#endif ARM_MODE(r0,10) mov r0,v1 // vector ##if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) // If we are supporting Ctrl-C interrupts from GDB, we must squirrel // away a pointer to the save interrupt state here so that we can // plant a breakpoint at some later time. .extern hal_saved_interrupt_state ldr r2,=hal_saved_interrupt_state str v6,[r2]#endif cmp r0,#CYGNUM_HAL_INTERRUPT_NONE // spurious interrupt bne 10f#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS // Acknowledge the interrupt THUMB_CALL(r1,12,hal_interrupt_acknowledge)#else mov r0,v6 // register frame THUMB_CALL(r1,12,hal_spurious_IRQ)#endif // CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS b spurious_IRQ 10: ldr r1,.hal_interrupt_data ldr r1,[r1,v1,lsl #2] // handler data ldr r2,.hal_interrupt_handlers ldr v3,[r2,v1,lsl #2] // handler (indexed by vector #) mov r2,v6 // register frame (this is necessary // for the ISR too, for ^C detection)#ifdef __thumb__ ldr lr,=10f bx v3 // invoke handler (thumb mode) .pool .code 16 .thumb_funcIRQ_10T:10: ldr r2,=15f bx r2 // switch back to ARM mode .pool .code 3215:IRQ_15A:#else mov lr,pc // invoke handler (call indirect mov pc,v3 // thru v3)#endifspurious_IRQ: #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK // If we are returning from the last nested interrupt, move back // to the thread stack. interrupt_end() must be called on the // thread stack since it potentially causes a context switch. ldr r2,.irq_level ldr r3,[r2] subs r1,r3,#1 str r1,[r2] ldreq sp,[sp] // This should be the saved stack pointer#endif#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT // The return value from the handler (in r0) will indicate whether a // DSR is to be posted. Pass this together with a pointer to the // interrupt object we have just used to the interrupt tidy up routine. // don't run this for spurious interrupts! cmp v1,#CYGNUM_HAL_INTERRUPT_NONE beq 17f ldr r1,.hal_interrupt_objects ldr r1,[r1,v1,lsl #2] mov r2,v6 // register frame THUMB_MODE(r3,10) bl interrupt_end // post any bottom layer handler // threads and call scheduler ARM_MODE(r1,10)17:#endif// mov r0,sp// bl show_frame_out // return from IRQ is same as return from exception b return_from_exception#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK// Execute pending DSRs the interrupt stack// Note: this can only be called from code running on a thread stackFUNC_START_ARM(hal_interrupt_stack_call_pending_DSRs, r1) stmfd sp!,{r4,r5,lr} // Disable interrupts mrs r4,cpsr // disable IRQ's orr r2,r4,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE bic r5,r4,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE msr cpsr,r2 // Switch to interrupt stack mov r3,sp // save old stack pointer ldr sp,.__interrupt_stack stmfd sp!,{r3} // stored at top of interrupt stack ldr r2,.irq_level // current number of nested interrupts ldr r3,[r2] add r3,r3,#1 // bump nesting level str r3,[r2] msr cpsr,r5 // enable interrupts THUMB_MODE(r1,20) bl cyg_interrupt_call_pending_DSRs ARM_MODE(r1,22) // Disable interrupts mrs r1,cpsr // disable IRQ's orr r2,r1,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE msr cpsr,r2 // Move back to the thread stack. ldr r2,.irq_level ldr r3,[r2] sub r3,r3,#1 // decrement nesting level str r3,[r2] ldr sp,[sp] // This should be the saved stack pointer msr cpsr,r4 // restore interrupts to original state#ifdef __thumb__ ldmfd sp!,{r4,r5,lr} // return bx lr#else ldmfd sp!,{r4,r5,pc} // return#endif // __thumb__#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK // Thumb-only support functions#ifdef __thumb__FUNC_START_ARM(hal_disable_interrupts, r1) mrs r0,cpsr // current state orr r1,r0,#0xC0 // mask both FIQ and IRQ msr cpsr,r1 bx lr // exit, _old_ in r0 FUNC_START_ARM(hal_enable_interrupts, r1) mrs r0,cpsr // current state bic r1,r0,#0xC0 // mask both FIQ and IRQ msr cpsr,r1 bx lr // exit FUNC_START_ARM(hal_restore_interrupts, r1) mrs r1,cpsr // current state bic r1,r1,#0xC0 // mask out FIQ/IRQ bits and r0,r0,#0xC0 // keep only FIQ/IRQ orr r1,r1,r0 // mask both FIQ and IRQ msr cpsr,r1 bx lr // exit FUNC_START_ARM(hal_query_interrupts, r1) mrs r0,cpsr // current state bx lr // exit, state in r0#endif // __thumb__// Dummy/support functions .global __gccmain .global _psr .global _sp#ifdef __thumb__ .code 16 .thumb_func__gccmain: bx lr .code 16 .thumb_func_psr: ARM_MODE(r1,10) mrs r0,cpsr bx lr .code 16 .thumb_func_sp: mov r0,sp bx lr#else__gccmain: mov pc,lr _psr: mrs r0,cpsr mov pc,lr_sp: mov r0,sp mov pc,lr#endif //// Pointers to various objects.//#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBSPTR(__GDB_stack_base)PTR(__GDB_stack)#endifPTR(__startup_stack)PTR(__exception_stack)PTR(__undef_exception_stack)PTR(__bss_start)PTR(__bss_end)PTR(_end)PTR(__rom_data_start)PTR(__ram_data_start)PTR(__ram_data_end)PTR(hal_interrupt_handlers)PTR(hal_interrupt_data)PTR(hal_interrupt_objects)PTR(__exception_handlers)PTR(init_flag)#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORTPTR(cyg_scheduler_sched_lock)#endif#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACKPTR(irq_level)PTR(__interrupt_stack)#endif#ifdef CYGHWR_HAL_ARM_DUMP_EXCEPTIONSPTR(__dump_procs)#endif//// Identification - useful to find out when a system was configured_eCos_id: .asciz "eCos : " __DATE__// -------------------------------------------------------------------------// Interrupt vector tables.// These tables contain the isr, data and object pointers used to deliver// interrupts to user code.// Despite appearances, their sizes are not #defines, but .equ symbols// generated by magic without proper dependencies in arm.inc// Recompiling will not DTRT without manual intervention. .datainit_flag: .balign 4 .long 0 .extern hal_default_isr .globl hal_interrupt_handlershal_interrupt_handlers: .rept CYGNUM_HAL_ISR_COUNT .long hal_default_isr .endr .globl hal_interrupt_datahal_interrupt_data: .rept CYGNUM_HAL_ISR_COUNT .long 0 .endr .globl hal_interrupt_objectshal_interrupt_objects: .rept CYGNUM_HAL_ISR_COUNT .long 0 .endr// -------------------------------------------------------------------------// Temporary interrupt stack .section ".bss"// Small stacks, only used for saving information between CPU modes__exception_stack_base: .rept 32 .long 0 .endr__exception_stack: .rept 32 .long 0 .endr__undef_exception_stack:// Runtime stack used during all interrupt processing#ifndef CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE#define CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE 4096#endif#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK .balign 16 .global cyg_interrupt_stack_basecyg_interrupt_stack_base:__interrupt_stack_base: .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE .byte 0 .endr .balign 16 .global cyg_interrupt_stackcyg_interrupt_stack:__interrupt_stack:irq_level: .long 0#endif#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS .balign 16__GDB_stack_base: .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE // rather than 1k .byte 0 .endr__GDB_stack:#endif .balign 16__startup_stack_base:#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK .rept 512#else .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE#endif .byte 0 .endr .balign 16__startup_stack:#ifdef PLATFORM_EXTRAS#include PLATFORM_EXTRAS#endif // --------------------------------------------------------------------------// end of vectors.S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -