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

📄 vectors.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 2 页
字号:
##=============================================================================
##
##      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_start
cyg_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_startup
1:	
	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, 0xFF
gdtEnd:
#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_end
cyg_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, 0xFF
slave_gdt:
	.word	gdtEnd - gdtStart
#	.word	39
	.long	gdtStart

	.align	4, 0xFF
slave_idt:
	.extern idtStart
	.word	0x07FF		# space for 256 entries
	.long	idtStart
	
	.code32

3:

	# 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 switch
1:
	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 flag
2:
	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_return

9:	
	# 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 + -