📄 vectors.s
字号:
##=============================================================================#### vectors.S#### x86 exception vectors####=============================================================================#####ECOSGPLCOPYRIGHTBEGIN###### -------------------------------------------## This file is part of eCos, the Embedded Configurable Operating System.## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.#### eCos is free software; you can redistribute it and/or modify it under## the terms of the GNU General Public License as published by the Free## Software Foundation; either version 2 or (at your option) any later version.#### eCos is distributed in the hope that it will be useful, but WITHOUT ANY## WARRANTY; without even the implied warranty of MERCHANTABILITY or## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License## for more details.#### You should have received a copy of the GNU General Public License along## with eCos; if not, write to the Free Software Foundation, Inc.,## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.#### As a special exception, if other files instantiate templates or use macros## or inline functions from this file, or you compile this file and link it## with other works to produce a work based on this file, this file does not## by itself cause the resulting work to be covered by the GNU General Public## License. However the source code for this file must still be made available## in accordance with section (3) of the GNU General Public License.#### This exception does not invalidate any other reasons why a work based on## this file might be covered by the GNU General Public License.#### Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.## at http://sources.redhat.com/ecos/ecos-license/## -------------------------------------------#####ECOSGPLCOPYRIGHTEND######=============================================================================#######DESCRIPTIONBEGIN######## Author(s): jskov## Contributors:jskov## Date: 1999-01-07## Purpose: x86 exception vectors## Description: This file defines the code placed into the exception## vectors. It also contains the first level default VSRs## that save and restore state for both exceptions and## interrupts.########DESCRIPTIONEND########=============================================================================#include <pkgconf/system.h>#include <pkgconf/hal.h>#include CYGBLD_HAL_PLATFORM_H#ifdef CYGPKG_KERNEL#include <pkgconf/kernel.h>#endif /* CYGPKG_KERNEL */#include <cyg/hal/arch.inc>#==============================================================================// .file "vectors.S"#==============================================================================# Real startup code. We jump here from the various reset vectors to set up the# world. .text .globl _start_start: hal_cpu_init hal_smp_init hal_diag_init hal_mmu_init hal_memc_init hal_intc_init hal_cache_init hal_timer_init # Loading the stack pointer seems appropriate now. # In SMP systems, this may not be the interrupt stack we # actually need to use for this CPU. We fix that up later. movl $__interrupt_stack, %esp#if defined(CYG_HAL_STARTUP_FLOPPY) \ || defined(CYG_HAL_STARTUP_ROM) \ || defined(CYG_HAL_STARTUP_GRUB) # If we are here first, initialize the IDT. RAM startup # configurations can assume that Redboot has already set # the IDT up. hal_idt_init#endif hal_mon_init # Init FPU # Do this after the monitor init so that we can plant our # own FPU unavailable VSR. hal_fpu_init # WARNING: may adjust stack pointer # Zero the BSS. If the BSS is not a whole number of words # long we will write up to 3 extra bytes at the end. # (This should not be a problem usually). movl $__bss_end,%ecx # ECX = end of BSS movl $__bss_start,%edi # EDI = base of BSS subl %edi,%ecx # ECX = size of BSS addl $3,%ecx # ECX += sizeof(long)-1 shrl $2,%ecx # ECX >>= 2 = number of words to fill xorl %eax,%eax # EAX = 0 = fill value rep stosl # Fill it in#ifdef CYG_HAL_STARTUP_ROM # In a ROM booted system, we also need to copy the data section # out to the RAM. movl $__rom_data_start,%esi # ESI = base of ROM data area movl $__ram_data_start,%edi # EDI = base of RAM data area movl $__ram_data_end,%ecx # ECX = end of data subl %edi,%ecx # ECX = size of data in bytes shrl $2,%ecx # ECX >>= 2 = number of words to copy rep movsl # Copy it over#endif .extern hal_variant_init call hal_variant_init .extern hal_platform_init call hal_platform_init#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS // This is here so we can debug the constructors. .extern initialize_stub call initialize_stub#endif .extern cyg_hal_invoke_constructors call cyg_hal_invoke_constructors#ifdef CYGPKG_HAL_SMP_SUPPORT # Now move SP to actual interrupt stack we will use for this # processor. hal_init_istack %esp#ifndef CYG_HAL_STARTUP_RAM # Only start other CPUs when we are the original boot executable. # RAM executables are loaded via RedBoot, so only FLOPPY, GRUB # and ROM startups count here. .extern cyg_hal_smp_cpu_start_all call cyg_hal_smp_cpu_start_all#endif #endif#ifdef CYGDBG_HAL_DEBUG_GDB_INITIAL_BREAK .extern breakpoint call breakpoint#endif .extern cyg_start call cyg_start # Hmm. Not expecting to return from cyg_start.1: hlt jmp 1b##-----------------------------------------------------------------------------## SMP entry point#if defined(CYGPKG_HAL_SMP_SUPPORT) .extern cyg_hal_smp_startup .global cyg_hal_smp_startcyg_hal_smp_start: # Finalize CPU init? # Interrupts? # hal_cpu_init# hal_intc_init hal_init_istack %esp # Init flags register pushl $0 popfl hal_fpu_cpu_init call cyg_hal_smp_startup1: jmp 1b #ifdef CYG_HAL_STARTUP_RAM .align 4, 0xFF gdtStart: /* Selector 0x00 == invalid. */ .word 0x0000 .word 0x0000 .byte 0x00 .byte 0x00 .byte 0x00 .byte 0x00 /* Selector 0x08 == code. */ .word 0xFFFF .word 0x0000 .byte 0x00 .byte 0x9B .byte 0xCF .byte 0x00 /* Selector 0x10 == data. */ .word 0xFFFF .word 0x0000 .byte 0x00 .byte 0x93 .byte 0xCF .byte 0x00 /* Selector 0x18 == shorter code: faults any code * access 0xF0000000-0xFFFFFFFF. */ .word 0xFFFF .word 0x0000 .byte 0x00 .byte 0x9B .byte 0xC7 .byte 0x00 /* Selector 0x20 == data; faults any access 0xF0000000-0xFFFFFFFF. */ .word 0xFFFF .word 0x0000 .byte 0x00 .byte 0x93 .byte 0xC7 .byte 0x00 .align 4, 0xFFgdtEnd:#endif // CYG_HAL_STARTUP_RAM ##-----------------------------------------------------------------------------## Slave processor startup code## This code is copied into low RAM, at 0x2000 and is the destination of the## startup interrupt that is sent to get the slaves running. .data .code16 .global cyg_hal_slave_trampoline .global cyg_hal_slave_trampoline_endcyg_hal_slave_trampoline:slave_base = . cld /* always count up. */ cli /* disable interrupts */ # Load up selector registers # Set DS == CS movw %cs,%ax movw %ax,%ds # load GDTR lgdt slave_gdt - slave_base lidt slave_idt - slave_base /* Switch to protected mode. */ movl %cr0,%eax orb $1, %al movl %eax,%cr0 ljmp $8, $3f-slave_base+0x2000 hlt .align 4, 0xFFslave_gdt: .word gdtEnd - gdtStart# .word 39 .long gdtStart .align 4, 0xFFslave_idt: .extern idtStart .word 0x07FF # space for 256 entries .long idtStart .code323: # Load up selector registers movw $0x10, %ax movw %ax, %ds movw %ax, %ss movw %ax, %es movw %ax, %fs movw %ax, %gs # Go to real HAL entry point movl $cyg_hal_smp_start,%eax jmp *%eax cyg_hal_slave_trampoline_end: .text#endif // defined(CYGPKG_HAL_SMP_SUPPORT) #==============================================================================# Default exception VSR .align 4, 0xCC .globl __default_exception_vsr__default_exception_vsr: ## We enter here with the CPU state still in the registers and: ## 12(%esp) EFLAGS pushed by hardware ## 8(%esp) CS pushed by hardware ## 4(%esp) PC pushed by hardware ## 0(%esp) vector number pushed by trampoline pusha # save all registers#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS mov %esp,%ebp # save SP cmpl $__stub_stack_base,%esp # compare SP with stub stack base jb 1f # if sp < istack base, switch cmpl $__stub_stack,%esp # compare SP with stub stack top jbe 2f # if sp < stack top, dont switch1: movl $__stub_stack,%esp # move to stub stack ## We switched stacks with previous ESP in EBP ## 44(%ebp) EFLAGS pushed by hardware ## 40(%ebp) CS pushed by hardware ## 36(%ebp) PC pushed by hardware ## 32(%ebp) vector number pushed by trampoline ## 28(%ebp) EAX ## 24(%ebp) ECX ## 20(%ebp) EDX ## 16(%ebp) EBX ## 12(%ebp) (ESP - 16) ## 8(%ebp) EBP ## 4(%ebp) ESI ## 0(%ebp) EDI pushl 44(%ebp) # copy EFLAGS from original stack pushl 40(%ebp) # copy CS pushl 36(%ebp) # copy PC pushl 32(%ebp) # copy vector number pusha movl 8(%ebp),%eax # copy EBP movl %eax,8(%esp) movl 12(%ebp),%eax # copy ESP movl %eax,12(%esp)2:#endif hal_fpu_push_exc # save FPU state mov %esp,%edi # save state pointer in EDI # adjust ESP by 16 for the state stored before the pusha add $16,i386reg_esp(%edi) #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) && defined(CYGPKG_HAL_SMP_SUPPORT) .extern cyg_hal_smp_cpu_sync .extern cyg_hal_smp_cpu_sync_flag .extern cyg_hal_smp_vsr_sync_flag # An SMP ROM monitor needs to suspend all other CPUs when # taking an exception.1: lock btsl $0,cyg_hal_smp_vsr_sync_flag # test serialization bit jnc 9f # if it was zero we are first here # Some other CPU is already handling an exception. We need to spin until # released. hal_smp_cpu %eax # get CPU index movl $cyg_hal_smp_cpu_sync,%ebx movl $cyg_hal_smp_cpu_sync_flag,%ecx lock incl 0(%ecx,%eax,4) # inc cpu sync flag2: cmpl $0,0(%ebx,%eax,4) # test sync location je 2b # loop while value is zero lock decl 0(%ecx,%eax,4) # dec cpu sync flag # Jump to return from this VSR. If the exception was genuine, # we will re-execute the cause and come back here. If it was # just a duplicate, or a halt NMI, we will continue as if # nothing had happened. jmp __default_exception_vsr_return9: # Stop all other CPUs .extern cyg_hal_smp_halt_other_cpus call cyg_hal_smp_halt_other_cpus#endif hal_fpu_push_exc_annex # Call exception handler .extern cyg_hal_exception_handler pushl %edi # arg1 = saved state call cyg_hal_exception_handler addl $4,%esp # pop arg hal_fpu_pop_exc_annex #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) && defined(CYGPKG_HAL_SMP_SUPPORT) .extern cyg_hal_smp_release_other_cpus call cyg_hal_smp_release_other_cpus lock btrl $0,cyg_hal_smp_vsr_sync_flag # clear serialization bit __default_exception_vsr_return:#endif hal_fpu_pop_exc # restore FPU state ## At this point, the stack contains: ## 44(%esp) EFLAGS pushed by hardware ## 40(%esp) CS pushed by hardware ## 36(%esp) PC pushed by hardware ## 32(%esp) vector number pushed by trampoline ## 28(%esp) EAX ## 24(%esp) ECX ## 20(%esp) EDX ## 16(%esp) EBX ## 12(%esp) ESP ## 8(%esp) EBP ## 4(%esp) ESI ## 0(%esp) EDI #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS movl 12(%esp),%ebp # pre-exception ESP sub $48,%ebp # adjust for current stack frame cmpl %esp,%ebp je 1f ## need to switch stacks xchg %esp,%ebp add $48,%esp pushl 44(%ebp) # EFLAGS pushl 40(%ebp) # CS pushl 36(%ebp) # PC mov %ebp,%esp popa movl -20(%esp),%esp # popa does not restore %esp sub $12,%esp # adjust for EFLAGS, CS, and PC iret 1:#endif popa # restore all our registers. addl $4, %esp # skip the vector number # Note: we do not need to re-adjust ESP # back by 16 as popa does not pop ESP. iret # and return to the program. #==============================================================================# Default interrupt VSR## .extern __interrupt_stack .align 4, 0xCC .globl __default_interrupt_vsr__default_interrupt_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -