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

📄 mpx88.s

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 S
📖 第 1 页 / 共 2 页
字号:
	mov	es,dx
	mov	ss,dx		! interrupt handlers may not make system calls
	mov	sp,#k_stktop	! so stack is not already switched
				! end of inline save
				! now set up parameters for C routine sys_call
	push	bx		! pointer to user message
	push	ax		! src/dest
	push	cx		! SEND/RECEIVE/BOTH
	sti			! allow SWITCHER to be interrupted
	call	_sys_call	! sys_call(function, src_dest, m_ptr)
				! caller is now explicitly in proc_ptr
	mov	AXREG(si),ax	! sys_call MUST PRESERVE si
	cli

! Fall into code to restart proc/task running.


!*===========================================================================*
!*				restart					     *
!*===========================================================================*
_restart:

! Flush any held-up interrupts.
! This reenables interrupts, so the current interrupt handler may reenter.
! This does not matter, because the current handler is about to exit and no
! other handlers can reenter since flushing is only done when k_reenter == 0.

! In protected mode a jump to p_restart is patched over the following
! code during initialization.

	cmp	_held_head,#0	! do fast test to usually avoid function call
	jz	over_call_unhold
	call	_unhold		! this is rare so overhead is acceptable
over_call_unhold:

	mov	si,_proc_ptr
	decb	_k_reenter
	mov	ax,AXREG(si)	! start restoring registers from proc table
				! could make AXREG == 0 to use lodw here
	mov	bx,BXREG(si)
	mov	cx,CXREG(si)
	mov	dx,DXREG(si)
	mov	di,DIREG(si)
	mov	bp,BPREG(si)
	mov	es,ESREG(si)
	mov	ss,SSREG(si)
	mov	sp,SPREG(si)
	push	PSWREG(si)	! fake interrupt stack frame
	push	CSREG(si)
	push	PCREG(si)
				! could put si:ds together to use
				! lds si,SIREG(si)
	push	DSREG(si)
	mov	si,SIREG(si)
	pop	ds
	iret

restart1:
	decb	_k_reenter
	pop	ax
	pop	bx
	pop	cx
	pop	dx
	pop	di
	pop	bp
	pop	es
	pop	si
	pop	ds
	add	sp,#2		! skip return adr
	iret


!*===========================================================================*
!*				int00-07				     *
!*===========================================================================*
! These are entry points for exceptions (processor generated interrupts, 
! usually caused by error conditions such as an attempt to divide by zero)

_int00:				! interrupt through vector 0
	push	ax
	movb	al,#0
	jmp	exception

_int01:				! interrupt through vector 1, etc
	push	ax
	movb	al,#1
	jmp	exception

_int02:
	push	ax
	movb	al,#2
	jmp	exception

_int03:
	push	ax
	movb	al,#3
	jmp	exception

_int04:
	push	ax
	movb	al,#4
	jmp	exception

_int05:
	push	ax
	movb	al,#5
	jmp	exception

_int06:
	push	ax
	movb	al,#6
	jmp	exception

_int07:
	push	ax
	movb	al,#7
	!jmp	exception

exception:
  cseg	movb	ex_number,al	! it is cumbersome to get this into dseg
	pop	ax
	call	save
  cseg	push	ex_number	! high byte is constant 0
	call	_exception	! do whatever is necessary (sti only if safe)
	add	sp,#2
	cli
	ret


!*===========================================================================*
!*				level0_call				     *
!*===========================================================================*
_level0_call:
	call	save
	jmp	@_level0_func


!*===========================================================================*
!*				idle_task				     *
!*===========================================================================*
_idle_task:			! executed when there is no work
	jmp	_idle_task	! a "hlt" before this fails in protected mode


!*===========================================================================*
!*				data					     *
!*===========================================================================*
! NB some variables are stored in code segment.

ex_number:			! exception number
	.space	2


!*===========================================================================*
!*			variants for 286 protected mode			     *
!*===========================================================================*

! Most routines are different in 286 protected mode.
! The only essential difference is that an interrupt in protected mode
! (usually) switches the stack, so there is less to do in software.

! These functions are reached along jumps patched in by klib_init_prot():

	.define		p_restart	! replaces _restart
	.define		p_save		! replaces save

! These exception and software-interrupt handlers are enabled by the new
! interrupt vector table set up in protect.c:

	.define		_divide_error		! _int00
	.define		_single_step_exception	! _int01
	.define		_nmi			! _int02
	.define		_breakpoint_exception	! _int03
	.define		_overflow		! _int04
	.define		_bounds_check		! _int05
	.define		_inval_opcode		! _int06
	.define		_copr_not_available	! _int07
	.define		_double_fault		! (286 trap)
	.define		_copr_seg_overrun	! (etc)
	.define		_inval_tss
	.define		_segment_not_present
	.define		_stack_exception
	.define		_general_protection
	.define		_p_s_call		! _s_call
	.define		_level0_call

! The hardware interrupt handlers need not be altered apart from putting
! them in the new table (save() handles the differences).
! Some of the intxx handlers (those for exceptions which do not push an
! error code) need not have been replaced, but the names here are better.

#include "protect.h"

/* Selected 286 tss offsets. */
#define TSS2_S_SP0	2

! imported variables

	.extern		_tss
	.extern		_level0_func

!*===========================================================================*
!*				p_save					     *
!*===========================================================================*
! Save for 286 protected mode.
! This is much simpler than for 8086 mode, because the stack already points
! into process table, or has already been switched to the kernel stack.

p_save:
	cld			! set direction flag to a known value
	pusha			! save "general" registers
	push	ds		! save ds
	push	es		! save es
	mov	dx,ss		! ss is kernel data segment
	mov	ds,dx		! load rest of kernel segments
	mov	es,dx
	mov	bp,sp		! prepare to return
	incb	_k_reenter	! from -1 if not reentering
	jnz	set_p1_restart	! stack is already kernel stack
	mov	sp,#k_stktop
	push	#p_restart	! build return address for interrupt handler
	jmp	@RETADR-P_STACKBASE(bp)

set_p1_restart:
	push	#p1_restart
	jmp	@RETADR-P_STACKBASE(bp)


!*===========================================================================*
!*				p_s_call				     *
!*===========================================================================*
_p_s_call:
	cld			! set direction flag to a known value
	sub	sp,#6*2		! skip RETADR, ax, cx, dx, bx, st
	push	bp		! stack already points into process table
	push	si
	push	di
	push	ds
	push	es
	mov	dx,ss
	mov	ds,dx
	mov	es,dx
	incb	_k_reenter
	mov	si,sp		! assumes P_STACKBASE == 0
	mov	sp,#k_stktop
				! end of inline save
	sti			! allow SWITCHER to be interrupted
				! now set up parameters for C routine sys_call
	push	bx		! pointer to user message
	push	ax		! src/dest
	push	cx		! SEND/RECEIVE/BOTH
	call	_sys_call	! sys_call(function, src_dest, m_ptr)
				! caller is now explicitly in proc_ptr
	mov	AXREG(si),ax	! sys_call MUST PRESERVE si
	cli

! Fall into code to restart proc/task running.

p_restart:

! Flush any held-up interrupts.
! This reenables interrupts, so the current interrupt handler may reenter.
! This does not matter, because the current handler is about to exit and no
! other handlers can reenter since flushing is only done when k_reenter == 0.

	cmp	_held_head,#0	! do fast test to usually avoid function call
	jz	p_over_call_unhold
	call	_unhold		! this is rare so overhead is acceptable
p_over_call_unhold:
	mov	si,_proc_ptr
	lldt	P_LDT_SEL(si)		! enable segment descriptors for task
	lea	ax,P_STACKTOP(si)	! arrange for next interrupt
	mov	_tss+TSS2_S_SP0,ax	! to save state in process table
	mov	sp,si		! assumes P_STACKBASE == 0
p1_restart:
	decb	_k_reenter
	pop	es
	pop	ds
	popa
	add	sp,#2		! skip return adr
	iret			! continue process


!*===========================================================================*
!*				exception handlers			     *
!*===========================================================================*
_divide_error:
	push	#DIVIDE_VECTOR
	jmp	p_exception

_single_step_exception:
	push	#DEBUG_VECTOR
	jmp	p_exception

_nmi:
	push	#NMI_VECTOR
	jmp	p_exception

_breakpoint_exception:
	push	#BREAKPOINT_VECTOR
	jmp	p_exception

_overflow:
	push	#OVERFLOW_VECTOR
	jmp	p_exception

_bounds_check:
	push	#BOUNDS_VECTOR
	jmp	p_exception

_inval_opcode:
	push	#INVAL_OP_VECTOR
	jmp	p_exception

_copr_not_available:
	push	#COPROC_NOT_VECTOR
	jmp	p_exception

_double_fault:
	push	#DOUBLE_FAULT_VECTOR
	jmp	errexception

_copr_seg_overrun:
	push	#COPROC_SEG_VECTOR
	jmp	p_exception

_inval_tss:
	push	#INVAL_TSS_VECTOR
	jmp	errexception

_segment_not_present:
	push	#SEG_NOT_VECTOR
	jmp	errexception

_stack_exception:
	push	#STACK_FAULT_VECTOR
	jmp	errexception

_general_protection:
	push	#PROTECTION_VECTOR
	jmp	errexception


!*===========================================================================*
!*				p_exception				     *
!*===========================================================================*
! This is called for all exceptions which do not push an error code.

p_exception:
  sseg	pop	ds_ex_number
	call	p_save
	jmp	p1_exception


!*===========================================================================*
!*				errexception				     *
!*===========================================================================*
! This is called for all exceptions which push an error code.

errexception:
  sseg	pop	ds_ex_number
  sseg	pop	trap_errno
	call	p_save
p1_exception:			! Common for all exceptions.
	push	ds_ex_number
	call	_exception
	add	sp,#2
	cli
	ret


!*===========================================================================*
!*				data					     *
!*===========================================================================*
! These declarations assure that storage will be allocated at the very 
! beginning of the kernel data section, so the boot monitor can be easily 
! told how to patch these locations. Note that the magic number is put
! here by the compiler, but will be read by, and then overwritten by,
! the boot monitor. When the kernel starts the sizes array will be
! found here, as if it had been initialized by the compiler.

	.data
begdata:
_sizes:				! sizes of kernel, mm, fs filled in by boot
	.data2	0x526F		! this must be the first data entry (magic #)
	.space	16*2*2-2	! monitor uses previous 2 words and this space
				! extra space allows for additional servers
	.bss
begbss:
k_stack:
	.space	K_STACK_BYTES	! kernel stack
k_stktop:			! top of kernel stack
ds_ex_number:
	.space	2
trap_errno:
	.space	2

⌨️ 快捷键说明

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