⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vectors.s

📁 eCos操作系统源码
💻 S
📖 第 1 页 / 共 2 页
字号:
		pusha			# save registers	hal_fpu_push_int	# save FPU state#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \    defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)	# Save the context just to be able to set a breakpoint	# when we have a CTRL-C	.extern hal_saved_interrupt_state	movl %esp,hal_saved_interrupt_state#endif#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \    !defined(CYGPKG_HAL_SMP_SUPPORT)	# Increment scheduler lock	.extern cyg_scheduler_sched_lock	incl	cyg_scheduler_sched_lock#endif	movl	%esp,%ebp			# EBP = copy of ESP	        # adjust ESP by 16 for the state stored before the pusha        add     $16,i386reg_esp(%esp)			hal_to_intstack			hal_fpu_push_int_annex			# save extra FPU state	#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING	# If we are allowing nested interrupts, restore the flags pushed	# by the hardware when this interrupt was taken.		movl	i386reg_eflags(%ebp), %eax	btrl	$8,%eax			# Clear TF bit	pushl	%eax	popfl#endif#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)	# Call cyg_instrument to record that this interrupt is being raised.	movl	i386reg_vector(%ebp), %ecx # vector number from saved state	movl	%ecx,%edi		# EDI = copy of vector	subl	$0x20,%edi		# EDI = interrupt table offset				pushl	%edi			# arg3 = interrupt number	pushl	%ecx			# arg2 = vector number	pushl	$0x0301			# arg1 = type = INTR.RAISE	call	cyg_instrument		# call instrument function	add	$12,%esp		# skip arguments#endif		# Call hal_interrupt_handlers[vector](vector, cyg_hal_interrupt_data[vector])		movl	i386reg_vector(%ebp), %ecx # vector number from saved state	movl	%ecx,%edi		# EDI = copy of vector	subl	$0x20,%edi		# EDI = interrupt table offset	movl	$hal_interrupt_handlers, %ebx	movl	(%ebx, %edi, 4), %edx	# EDX = interrupt routine	movl	$hal_interrupt_data, %ebx	movl	(%ebx, %edi, 4), %eax	# EAX = interrupt data	pushl	%eax			# arg2 = data	pushl	%ecx			# arg1 = vector	call	*%edx			# EAX = return value, needed for interrupt_end()	addl	$8,%esp			# pop args	# At this point:	# EAX = ISR return code (returned by call)	# EDI = ISR table offset (saved across call)	# EBP = State pointer (saved across call)	hal_fpu_pop_int_annex		# Pop any saved interrupt state			# 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.		hal_from_intstack				#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT	# Call interrupt_end(r, cyg_hal_interrupt_objects[vector], regs)	# - r is the return value from the ISR	# - regs points to saved CPU context	movl	$hal_interrupt_objects, %ebx	movl	(%ebx, %edi, 4), %edx	# EDX = interrupt object ptr	pushl	%ebp			# arg3 = ptr to saved registers	pushl	%edx			# arg2 = object	pushl	%eax			# arg1 = ISR return code	call	interrupt_end		# Call it	addl	$12, %esp		# pop args	#endif	# Now pull saved state from stack and return to 	# what thread was originally doing.		hal_fpu_pop_int			# restore FPU state	popa				# restore all our registers.	addl	$4, %esp		# skip the vector number.	iret				# and return to the thread.#==============================================================================## Execute pending DSRs on the interrupt stack with interrupts enabled.## Note: this can only be called from code running on a thread stack so we ## can always just jump to the interrupt stack without looking.#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK	.extern cyg_interrupt_call_pending_DSRs	.global hal_interrupt_stack_call_pending_DSRs	hal_interrupt_stack_call_pending_DSRs:		pushl	%ebp			# save EBP	pushfl				# save flags	movl	%esp,%ebp		# EBP = saved SP	hal_load_istack	%edx		# load new SP into EDX	movl	%edx,%esp		# move it to ESP		sti				# Enable interrupts	# Call back to kernel to run DSRs	call	cyg_interrupt_call_pending_DSRs	# On return EBP will still contain the old ESP since	# it is a callee saved register.		movl	%ebp,%esp		# restore saved SP	# Now merge the original IF bit into the current	# EFLAGS. 		popl	%eax			# EAX = saved flags	pushfl				# 0(%esp) = current flags	btrl	$9,0(%esp)		# clear IF bit in current flags	andl	$0x00000200,%eax	# isolate saved IF bit	orl	%eax,0(%esp)		# OR it in to the saved flags	popfl				# restore flags		popl	%ebp			# restore EBP	ret				# and return	#endif				#==============================================================================# FPU lazy state switch VSR# This is invoked via hardware exception 7 (FPU unavailable) as a result of# setting the TS bit in CR0 whenever we context switch. If we discover here# that a different context from the current owner of the FPU has attempted# a floating point operation, we save the old context and load the new before # allowing it to proceed.	#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY		#ifndef CYGPKG_HAL_SMP_CPU_MAX#define CYGPKG_HAL_SMP_CPU_MAX 1#endif					.data	.global cyg_hal_fpustate_ownercyg_hal_fpustate_owner:	.rept	CYGPKG_HAL_SMP_CPU_MAX	.long	0				# pointer to FPU owning context	.endr	.global cyg_hal_fpustate_current	cyg_hal_fpustate_current:		.rept	CYGPKG_HAL_SMP_CPU_MAX	.long	0				# pointer to current threads FPU context	.endr				.text	__fpu_switch_vsr:	## We enter here with the CPU state still in the registers and:	##  0(%esp)	vector number pushed by trampoline	##  4(%esp)	PC pushed by hardware	##  8(%esp)	CS pushed by hardware	## 12(%esp)	EFLAGS pushed by hardware		clts					# clear CR0:TS bit	pusha					# save all regs	hal_smp_cpu %ecx			# ECX = CPU id	movl	$cyg_hal_fpustate_owner,%eax	# EAX = FPU context owner table	leal	0(%eax,%ecx,4),%esi		# ESI = address of owner pointer	movl	$cyg_hal_fpustate_current,%ebx	# EBX = current threads context table	leal	0(%ebx,%ecx,4),%edi		# EDI = address of context pointer	movl	0(%esi),%eax			# EAX = Current FPU context owner	movl	0(%edi),%ebx			# EBX = Current threads FPU context	cmpl	%ebx,%eax			# current == owner ?	je	9f				# yes, nothing else to do	cmpl	$0,%eax				# is FPU even in use?	je	1f				# if not, skip save	fnsave	i386reg_fpucontext_state(%eax)	# save FPU state#ifdef CYGHWR_HAL_I386_PENTIUM_SSE	# Save SIMD state.	# FIXME. This is awfully inefficient. Need to use FXSAVE to	# save FPU and SIMD at same time. FXSAVE requires a 16 byte	# alignment and does not have an implicit finit as does FSAVE.	stmxcsr	i386reg_simd_mxcsr(%eax)	movups	%xmm0,i386reg_simd_xmm0(%eax)	movups	%xmm1,i386reg_simd_xmm1(%eax)	movups	%xmm2,i386reg_simd_xmm2(%eax)	movups	%xmm3,i386reg_simd_xmm3(%eax)	movups	%xmm4,i386reg_simd_xmm4(%eax)	movups	%xmm5,i386reg_simd_xmm5(%eax)	movups	%xmm6,i386reg_simd_xmm6(%eax)	movups	%xmm7,i386reg_simd_xmm7(%eax)#endif	movl	$1,i386reg_fpucontext_valid(%eax) # mark valid1:	movl	%ebx,0(%esi)            	# Set new owner	btl	$0,i386reg_fpucontext_valid(%ebx) # Valid state?	jc	2f				# If yes, go to restore it	finit					# Otherwise init FPU#ifdef CYGHWR_HAL_I386_PENTIUM_SSE	# FIXME. Anything needed here?#endif	jmp	9f				# skip restore2:	frstor	i386reg_fpucontext_state(%ebx)	# restore FPU state#ifdef CYGHWR_HAL_I386_PENTIUM_SSE	# Restore SIMD state.	# FIXME. This is awfully inefficient. Need to use FXRSTOR to	# restore FPU and SIMD at same time. FXRSTOR requires a 16 byte	# alignment.	movups	i386reg_simd_xmm0(%ebx),%xmm0	movups	i386reg_simd_xmm1(%ebx),%xmm1	movups	i386reg_simd_xmm2(%ebx),%xmm2	movups	i386reg_simd_xmm3(%ebx),%xmm3	movups	i386reg_simd_xmm4(%ebx),%xmm4	movups	i386reg_simd_xmm5(%ebx),%xmm5	movups	i386reg_simd_xmm6(%ebx),%xmm6	movups	i386reg_simd_xmm7(%ebx),%xmm7	ldmxcsr	i386reg_simd_mxcsr(%ebx)#endif9:	popa					# restore all our registers.	addl	$4, %esp			# skip the vector number.	iret					# and return to the thread.		#endif#if 0			#==============================================================================# Assembler swap routines			# x = CPU_swap_u16(x)	.align	4	.global CPU_swap_u16CPU_swap_u16:	xorl	%eax, %eax	movb	4(%esp), %ah	movb	5(%esp), %al	ret# x = CPU_swap_u32(x)	.align	4	.global CPU_swap_u32CPU_swap_u32:	xorl	%eax, %eax	movb	4(%esp), %ah	movb	5(%esp), %al	sall	$16, %eax	movb	6(%esp), %ah	movb	7(%esp), %al	ret#endif		#==============================================================================# Exception trampolines# IDT exception gates point to short code sequences that push the vector# number on to the stack and then indirect via the VSR table to a handler.# 	# Just for yuks we keep a count of the number of times each	# vector is called.	.bss	.globl hal_vsr_statshal_vsr_stats:		.rept 64	// Default VSR table is 64 entries long	.long 0	.endr	# When an exception which supplies an error code is generated,	# we move the code here. hal_trap_error_code:	.long 0	.text		# macro to create exception handler (no error code)	.macro  hal_pc_exception_noerr idxhal_pc_exception_\idx:	movl	$0,hal_trap_error_code	pushl	$\idx	incl	(hal_vsr_stats+\idx*4)	jmp	*(hal_vsr_table+\idx*4)	.endm	# macro to create exception handler (with error code)	.macro  hal_pc_exception_err idxhal_pc_exception_\idx:	popl	hal_trap_error_code	pushl	$\idx	incl	(hal_vsr_stats+\idx*4)	jmp	*(hal_vsr_table+\idx*4)	.endm	# Now generate all the default exception VSR trampolines.		hal_pc_exception_noerr  0	hal_pc_exception_noerr  1	hal_pc_exception_noerr  2	hal_pc_exception_noerr  3		hal_pc_exception_noerr  4	hal_pc_exception_noerr  5		hal_pc_exception_noerr  6	hal_pc_exception_noerr  7		hal_pc_exception_err    8	hal_pc_exception_noerr  9		hal_pc_exception_err   10	hal_pc_exception_err   11		hal_pc_exception_err   12	hal_pc_exception_err   13		hal_pc_exception_err   14	hal_pc_exception_noerr 15		hal_pc_exception_noerr 16	hal_pc_exception_err   17		hal_pc_exception_noerr 18	hal_pc_exception_noerr 19		hal_pc_exception_noerr 20	hal_pc_exception_noerr 21		hal_pc_exception_noerr 22	hal_pc_exception_noerr 23		hal_pc_exception_noerr 24	hal_pc_exception_noerr 25		hal_pc_exception_noerr 26	hal_pc_exception_noerr 27		hal_pc_exception_noerr 28	hal_pc_exception_noerr 29		hal_pc_exception_noerr 30	hal_pc_exception_noerr 31	#==============================================================================# IRQ handler trampolines	# macro to create exception handler (no error code)	.macro  hal_pc_irq_handler idxhal_pc_irq_\idx:	pushl	$\idx	incl	(hal_vsr_stats+\idx*4)	jmp	*(hal_vsr_table+\idx*4)	.endm	hal_pc_irq_handler 32	hal_pc_irq_handler 33	hal_pc_irq_handler 34	hal_pc_irq_handler 35	hal_pc_irq_handler 36	hal_pc_irq_handler 37	hal_pc_irq_handler 38	hal_pc_irq_handler 39	hal_pc_irq_handler 40	hal_pc_irq_handler 41	hal_pc_irq_handler 42	hal_pc_irq_handler 43	hal_pc_irq_handler 44	hal_pc_irq_handler 45	hal_pc_irq_handler 46	hal_pc_irq_handler 47#ifdef CYGPKG_HAL_SMP_SUPPORT	# Extra interrupt vectors for IOAPIc routed PCI and	# other interrupt sources	hal_pc_irq_handler 48	hal_pc_irq_handler 49	hal_pc_irq_handler 50	hal_pc_irq_handler 51	hal_pc_irq_handler 52	hal_pc_irq_handler 53	hal_pc_irq_handler 54	hal_pc_irq_handler 55	hal_pc_irq_handler 56	hal_pc_irq_handler 57	hal_pc_irq_handler 58	hal_pc_irq_handler 59	hal_pc_irq_handler 60	hal_pc_irq_handler 61	hal_pc_irq_handler 62	hal_pc_irq_handler 63	# Inter-CPU interrupts start at 64	hal_pc_irq_handler 64	hal_pc_irq_handler 65	hal_pc_irq_handler 66	hal_pc_irq_handler 67#endif			# default vsr entries: pop the vector code from the stack and return.default_vsr_iret:	add $4,%esp	iret	# GNUPro apps use "int $0x80" for syscalls.        # There is no vsr table entry for this.	.global __syscall_tramp__syscall_tramp:	pushl $0x80	jmp __default_exception_vsr#==============================================================================# Initial and interrupt stack#ifndef CYG_HAL_I386_INTERRUPT_STACK_DEFINED	.bss#ifndef CYGPKG_HAL_SMP_SUPPORT		.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:                .long   0,0,0,0,0,0,0,0#else // CYGPKG_HAL_SMP_SUPPORT		__interrupt_stack_vector:	.rept CYGPKG_HAL_SMP_CPU_MAX	.long 0	.endr			.balign 16	.global cyg_interrupt_stack_basecyg_interrupt_stack_base:__interrupt_stack_base:__interrupt_stack_first:	.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE	.byte 0	.endr	.global cyg_interrupt_stackcyg_interrupt_stack:__interrupt_stack:	.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE*(CYGPKG_HAL_SMP_CPU_MAX-1)	.byte 0	.endr	#endif // CYGPKG_HAL_SMP_SUPPORT	#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS	.global __stub_stack_base__stub_stack_base:	.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE	.byte 0	.endr	.balign 16	.global __stub_stack__stub_stack:                .long   0,0,0,0,0,0,0,0#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS	#endif // CYG_HAL_I386_INTERRUPT_STACK_DEFINED		#------------------------------------------------------------------------------# end of vectors.S

⌨️ 快捷键说明

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