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

📄 arch.inc

📁 开放源码实时操作系统源码.
💻 INC
📖 第 1 页 / 共 2 页
字号:
	movups	%xmm7,i386reg_simd_xmm7(%esp)
#endif
	movl	$1,i386reg_fpstate_valid(%esp)	# indicate it is valid
	.endm

	.macro	hal_fpu_pop_ctx
	btl	$0,i386reg_fpstate_valid(%esp)	# check ls bit of valid flag
	jc	1f				# if set, restore state
	finit					# otherwise init FPU
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
	# FIXME. Anything needed here?
#endif
	jmp	2f				# and skip restore
1:
	frstor  i386reg_fpstate(%esp)		# 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(%esp),%xmm0
	movups	i386reg_simd_xmm1(%esp),%xmm1
	movups	i386reg_simd_xmm2(%esp),%xmm2
	movups	i386reg_simd_xmm3(%esp),%xmm3
	movups	i386reg_simd_xmm4(%esp),%xmm4
	movups	i386reg_simd_xmm5(%esp),%xmm5
	movups	i386reg_simd_xmm6(%esp),%xmm6
	movups	i386reg_simd_xmm7(%esp),%xmm7
	ldmxcsr	i386reg_simd_mxcsr(%esp)
#endif
2:
	addl	$i386reg_fpstate_size,%esp	# pop space used
	.endm

	# ------------------------------------------------------------
	# Interrupt and exception handling

	# In this configuration, the interrupt and exception code behaves in
	# exactly the same way as the context switch code.

	.macro	hal_fpu_push_int
	hal_fpu_push_ctx
	.endm

	.macro	hal_fpu_push_int_annex
	.endm

	.macro	hal_fpu_pop_int_annex
	.endm

	.macro	hal_fpu_pop_int
	hal_fpu_pop_ctx
	.endm

	.macro	hal_fpu_push_exc
	hal_fpu_push_ctx
	.endm

	.macro	hal_fpu_push_exc_annex
	.endm

	.macro	hal_fpu_pop_exc_annex
	.endm

	.macro	hal_fpu_pop_exc
	hal_fpu_pop_ctx
	.endm

#else // CYGHWR_HAL_I386_FPU_SWITCH_LAZY

	# Lazy CPU state switching. We defer CPU state switching until the new
	# thread actually uses the FPU. This state switch is handled by
	# __fpu_switch_vsr in vectors.S.

	.extern cyg_hal_fpustate_owner
	.extern cyg_hal_fpustate_current

	# ------------------------------------------------------------
	# Context switch handling

	# On context switch we simply stack a pointer to this
	# threads FPU context save area.

	.macro	hal_fpu_push_ctx
	hal_smp_cpu %ebx			# Get CPU id
	movl	$cyg_hal_fpustate_current,%ecx	# current state table
	pushl	0(%ecx,%ebx,4)			# push table[cpu] entry
	.endm

	# We do nothing here but set the CR0:TS bit to force
	# an exception when the FPU is next used and pop the
	# FPU save area pointer into the static variable.

	.macro	hal_fpu_pop_ctx
	movl	%cr0, %ecx			# get CR0
	orl	$0x8, %ecx			# set TS bit
	movl	%ecx, %cr0			# restore CR0
	hal_smp_cpu %ebx			# get CPU id
	movl	$cyg_hal_fpustate_current,%ecx	# current state table
	popl	0(%ecx,%ebx,4)			# pop table[cpu] entry
	.endm

	# ------------------------------------------------------------
	# Interrupt handling

	# On entry to an interrupt we save the current threads FPU context
	# pointer and set the CR0:TS bit to trap any FP operations in the
	# interrupt.

	.macro	hal_fpu_push_int
	hal_smp_cpu %ebx			# get CPU id
	movl	$cyg_hal_fpustate_current,%ecx	# current state table
	pushl	0(%ecx,%ebx,4)			# push table[cpu] entry
	# ensure that CR0:TS bit is set
	movl	%cr0, %ecx			# get CR0
	orl	$0x8, %ecx			# set TS bit
	movl	%ecx, %cr0			# restore CR0
	.endm

	# The following is called after we transfer to the interrupt
	# stack. We make space here for the FPU state of the interrupt
	# handler to be saved in case we get nested interrupts that use FP.

	.macro	hal_fpu_push_int_annex
	subl	$i386reg_fpucontext_size,%esp
	movl	$0,i386reg_fpucontext_valid(%esp)
	hal_smp_cpu %ebx			# get CPU id
	movl	$cyg_hal_fpustate_current,%ecx	# current state table
	movl	%esp,0(%ecx,%ebx,4)		# save in table[cpu] entry
	.endm

	# This is invoked just before any transfer back to the thread stack.
	# We check whether we are the FPU state owner, and if so, abdicate.
	# There is no need to save the state, the next thread will load its
	# own state over the top of it.

	.macro	hal_fpu_pop_int_annex
	hal_smp_cpu %ebx			# get CPU id
	movl	$cyg_hal_fpustate_owner,%ecx	# current state table
	cmpl	0(%ecx,%ebx,4),%esp		# are we FPU owner?
	jne	1f				# if not, then just continue
	movl	$0,0(%ecx,%ebx,4)		# no one owns FPU now
	# ensure that CR0:TS bit is set to force a reload of
	# the previous FPU state
	movl	%cr0, %ecx			# get CR0
	orl	$0x8, %ecx			# set TS bit
	movl	%ecx, %cr0			# restore CR0
1:
	addl	$i386reg_fpucontext_size,%esp	# pop FPU save area
	.endm

	# Final return from interrupt handling. Just pull the current
	# FPU context off the stack.
	.macro	hal_fpu_pop_int
	hal_smp_cpu %ebx			# get CPU id
	movl	$cyg_hal_fpustate_current,%ecx	# current state table
	popl	0(%ecx,%ebx,4)			# pop table[cpu] entry
	.endm

	# ------------------------------------------------------------
	# Exception handling

	# Whenever we take an exception, we save the current FPU state away
	# into its save area. This way, if we are going to end up in GDB, the
	# whole machine state is saved in memory.

	.macro	hal_fpu_push_exc
	hal_smp_cpu %ebx			# get CPU id
	movl	$cyg_hal_fpustate_current,%ecx	# current state table
	pushl	0(%ecx,%ebx,4)			# push table[cpu] entry
	movl	$cyg_hal_fpustate_owner,%ecx	# current owner table
	movl	0(%ecx,%ebx,4),%eax		# EAX = FPU state owner
	cmpl	$0,%eax				# test it
	je	1f				# skip if zero
	fnsave	i386reg_fpucontext_state(%eax)	# save 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) # set valid
	movl	$0,0(%ecx,%ebx,4)		# zero owner pointer
1:
	.endm

	# The rest of the exception macros behave exactly like the
	# interrupt ones.

	.macro	hal_fpu_push_exc_annex
	hal_fpu_push_int_annex
	.endm

	.macro	hal_fpu_pop_exc_annex
	hal_fpu_pop_int_annex	
	.endm

	.macro	hal_fpu_pop_exc
	hal_fpu_pop_int
	.endm

#endif // CYGHWR_HAL_I386_FPU_SWITCH_LAZY

#else /* !CYGHWR_HAL_I386_FPU */

	# Non-FP macros.

	.macro	hal_fpu_init
	.endm

	.macro	hal_fpu_cpu_init
	.endm

	.macro	hal_fpu_push_ctx
	.endm

	.macro	hal_fpu_pop_ctx
	.endm

	.macro	hal_fpu_push_int
	.endm

	.macro	hal_fpu_push_int_annex
	.endm

	.macro	hal_fpu_pop_int_annex
	.endm

	.macro	hal_fpu_pop_int
	.endm

	.macro	hal_fpu_push_exc
	.endm

	.macro	hal_fpu_push_exc_annex
	.endm

	.macro	hal_fpu_pop_exc_annex
	.endm

	.macro	hal_fpu_pop_exc
	.endm

#endif

#endif	

#------------------------------------------------------------------------------
# MMU macros.

#ifndef CYGPKG_HAL_I386_MMU_DEFINED

#define CYGPKG_HAL_I386_MMU_DEFINED

	.macro 	hal_mmu_init
	.endm

#endif	

#------------------------------------------------------------------------------
# A20 gate enable

#define K_RDWR			0x60
#define	K_STATUS		0x64
#define	K_CMD			0x64
#define K_OBUF_FUL		0x01
#define K_IBUF_FUL		0x02
#define KC_CMD_WIN		0xD0
#define	KC_CMD_WOUT		0xD1
#define KB_A20			0xDF

	.macro	hal_a20_enable
	// Enable A20 so that addresses at 1MB don't wrap around back to 0.
1:	inb 	$K_STATUS, %al
	testb 	$K_IBUF_FUL, %al
	jnz 	1b

2:	inb 	$K_STATUS, %al
	testb 	$K_OBUF_FUL, %al
	jz 	3f
	inb 	$K_RDWR, %al
	jmp 	2b

3:	movb 	$KC_CMD_WOUT, %al
	outb 	%al, $K_CMD
1:	inb 	$K_STATUS, %al
	testb 	$K_IBUF_FUL, %al
	jnz 	1b

	movb 	$KB_A20, %al
	outb 	%al, $K_RDWR
1:	inb 	$K_STATUS, %al
	testb 	$K_IBUF_FUL, %al
	jnz 	1b
	.endm

#------------------------------------------------------------------------------
# MEMC macros.
# This version simply enables the A20 gate.
	
#ifndef CYGPKG_HAL_I386_MEMC_DEFINED

	.macro	hal_memc_init
	hal_a20_enable
	.endm

#endif	
	
#------------------------------------------------------------------------------
# Cache macros.
	
#ifndef CYGPKG_HAL_I386_CACHE_DEFINED

	.macro	hal_cache_init
	.endm

#endif	

#------------------------------------------------------------------------------
# Diagnostics macros.
	
#ifndef CYGPKG_HAL_I386_DIAG_DEFINED

	.macro	hal_diag_init
	.endm

	.macro	hal_diag_excpt_start
	.endm

	.macro	hal_diag_intr_start
	.endm

	.macro	hal_diag_restore
	.endm
#endif	

#------------------------------------------------------------------------------
# Timer initialization.
	
#ifndef CYGPKG_HAL_I386_TIMER_DEFINED

	.macro	hal_timer_init
	.endm

#endif	

#------------------------------------------------------------------------------
# Monitor initialization.
	
#ifndef CYGPKG_HAL_I386_MON_DEFINED

	.macro	hal_mon_init
	.endm

#endif	

#------------------------------------------------------------------------------
#endif // ifndef CYGONCE_HAL_ARCH_INC
# end of arch.inc

⌨️ 快捷键说明

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