📄 arch.inc
字号:
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 restore1: 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)#endif2: 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 CR01: 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 pointer1: .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 1b2: inb $K_STATUS, %al testb $K_OBUF_FUL, %al jz 3f inb $K_RDWR, %al jmp 2b3: movb $KC_CMD_WOUT, %al outb %al, $K_CMD1: inb $K_STATUS, %al testb $K_IBUF_FUL, %al jnz 1b movb $KB_A20, %al outb %al, $K_RDWR1: 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 + -