vectors.s

来自「ecos为实时嵌入式操作系统」· S 代码 · 共 761 行 · 第 1/2 页

S
761
字号
#endif	sub	sp,sp,#ARMREG_SIZE	// make space for frame	stmea	sp,{r0-r10,fp}		// save immediately visible registers	ldmfd	ip,{r0-r4}		// saved registers	str	r0,[sp,#armreg_cpsr]	// CPSR at time of interrupt	str	r1,[sp,#armreg_r0]	// saved R0	str	r2,[sp,#armreg_fp]	// saved FP	str	r3,[sp,#armreg_ip]	// saved IP	str	r4,[sp,#armreg_pc]	// PC at time of interrupt	str	lr,[sp,#armreg_lr]	// LR at time of interrupt	add	r0,ip,#ARMREG_SIZE	str	fp,[sp,#armreg_sp]	// SP at time of interrupt#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS	mov	r0,sp	bl	abort_data#endif	mov	v1,#CYGNUM_HAL_EXCEPTION_DATA_ACCESS	b	call_exception_handlerFIQ:	ldr	sp,.__startup_stack	// get good stack	sub	lr,lr,#4		// PC at time of interrupt	stmfd	sp!,{r0,ip,lr}			mrs	r0,spsr	stmfd	sp!,{r0}	mov	ip,sp			// save SP which will vanish with                                        //    mode switch	mrs	r0,cpsr			// switch to Supervisor Mode	bic	r0,r0,#CPSR_MODE_BITS	orr	r0,r0,#CPSR_SUPERVISOR_MODE	msr	cpsr,r0			// sp,lr are now old values	mov	ip,sp	ldr	sp,.__startup_stack	// get good stack	sub	sp,sp,#ARMREG_SIZE+16	// make space for frame	stmea	sp,{r0-r10,fp}		// save immediately visible registers	ldmfd	ip,{r0-r3}		// saved registers	str	r0,[sp,#armreg_cpsr]	// CPSR at time of interrupt	str	r1,[sp,#armreg_r0]	// saved R0	str	r2,[sp,#armreg_ip]	// saved IP	str	r3,[sp,#armreg_pc]	// PC at time of interrupt	str	lr,[sp,#armreg_lr]	// LR at time of interrupt	add	r0,ip,#ARMREG_SIZE	str	r0,[sp,#armreg_sp]	// SP at time of interrupt#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS	mov	r0,sp	bl	FIQ#endif	mov	v1,#CYGNUM_HAL_EXCEPTION_FIQ	b	call_exception_handler//// Dispatch an exception handler.call_exception_handler:	str	v1,[sp,#armreg_vector]	mov	r0,sp	bl	exception_handler#ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS	mov	r0,sp	bl	exception_handler_returned#endif// Restore [interrupted] context	mov	ip,sp			// get stack pointer	ldr	lr,[ip,#armreg_lr]	ldr	sp,[sp,#armreg_sp]	mrs	r0,cpsr			// move back to IRQ mode	bic	r0,r0,#CPSR_MODE_BITS	orr	r0,r0,#CPSR_IRQ_MODE	msr	cpsr,r0	mov	sp,ip	ldr	lr,[sp,#armreg_pc]	ldr	r0,[sp,#armreg_cpsr]	ldr	ip,[sp,#armreg_ip]	msr	spsr,r0	ldmfd	sp,{r0-r10,fp}	movs	pc,lr			// restore PC from LR, CPSR from SPSR// Handle device interrupts// This is slightly more complicated than the other exception handlers because// it needs to interface with the kernel (if present).IRQ:	// Note: I use this exception stack while saving the context because	// the current SP does not seem to be always valid in this CPU mode.	ldr	sp,.__exception_stack	// get good stack	sub	lr,lr,#4		// PC at time of interrupt	stmfd	sp!,{r0,fp,ip,lr}			mrs	r0,spsr	stmfd	sp!,{r0}	mov	ip,sp			// save SP which will vanish with                                        //   mode switch	mrs	r0,cpsr			// switch to Supervisor Mode	bic	r0,r0,#CPSR_MODE_BITS	orr	r0,r0,#CPSR_SUPERVISOR_MODE	msr	cpsr,r0			// sp,lr are now old values	mov	fp,sp			// save old SP	sub	sp,sp,#ARMREG_SIZE	// make space for frame	stmea	sp,{r0-r10,fp}		// save immediately visible registers	ldmfd	ip,{r0-r4}		// saved registers	str	r0,[sp,#armreg_cpsr]	// CPSR at time of interrupt	str	r1,[sp,#armreg_r0]	// saved R0	str	r2,[sp,#armreg_fp]	// saved FP	str	r3,[sp,#armreg_ip]	// saved IP	str	r4,[sp,#armreg_pc]	// PC at time of interrupt	str	lr,[sp,#armreg_lr]	// LR at time of interrupt	str	fp,[sp,#armreg_sp]	// SP at time of interrupt	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	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	mov	r0,v1			// vector #	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	mov	lr,pc			// invoke handler (call indirect	mov	pc,v3                   // thru v3)#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.	ldr	r1,.hal_interrupt_objects	ldr	r1,[r1,v1,lsl #2]	bl	interrupt_end   // post any bottom layer handler                                // threads and call scheduler#endif//	mov	r0,sp//	bl	show_frame_out	mov	ip,sp			// get stack pointer	ldr	lr,[ip,#armreg_lr]	ldr	sp,[sp,#armreg_sp]	mrs	r0,cpsr			// move back to IRQ mode	bic	r0,r0,#CPSR_MODE_BITS	orr	r0,r0,#CPSR_IRQ_MODE	msr	cpsr,r0	mov	sp,ip	ldr	lr,[sp,#armreg_pc]	ldr	r0,[sp,#armreg_cpsr]	ldr	ip,[sp,#armreg_ip]	msr	spsr,r0	ldmfd	sp,{r0-r10,fp}	movs	pc,lr			// restore PC from LR, CPSR from SPSR#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 stack	.global	hal_interrupt_stack_call_pending_DSRshal_interrupt_stack_call_pending_DSRs:        stmfd	sp!,{r4,r5,lr}	// Disable interrupts	mrs	r4,cpsr			// disable IRQ's	orr	r2,r4,#CPSR_IRQ_DISABLE	bic	r5,r4,#CPSR_IRQ_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	bl	cyg_interrupt_call_pending_DSRs	// Disable interrupts	mrs	r1,cpsr			// disable IRQ's	orr	r2,r1,#CPSR_IRQ_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	ldmfd	sp!,{r4,r5,pc}		// return#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK// Dummy functions	.global	__gccmain__gccmain:	mov	pc,lr		.global	_psr_psr:	mrs	r0,cpsr	mov	pc,lr	.global	_sp_sp:	mov	r0,sp	mov	pc,lr//// 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// -------------------------------------------------------------------------// Interrupt vector tables.// These tables contain the isr, data and object pointers used to deliver// interrupts to user code.		.datainit_flag:	.long	0	.extern hal_default_isr	.globl	hal_vsr_tablehal_vsr_table:	.rept	CYGNUM_HAL_VSR_COUNT	.long	0		// hal_default_isr	.endr	.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__interrupt_stack_base:        .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE        .byte 0        .endr	.balign 16__interrupt_stack:irq_level:	.long	0#endif#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS	.balign 16__GDB_stack_base:        .rept 0x400        .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:// --------------------------------------------------------------------------//  end of vectors.S

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?