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

📄 vaxexception.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 3 页
字号:
/*	@(#)vaxexception.s	4.1		7/2/90		*/#include "../machine/emul/vaxemul.h"#include "../machine/psl.h"#include "../machine/emul/vaxregdef.h"#include "../machine/mtpr.h"/************************************************************************ *									* *			Copyright (c) 1984,85,88 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									*/************************************************************************ * *			Modification History * *	Fred Canter, 15-Feb-88 *	Added VAX420, VAX3600, and VAX6200 to MVAX for calling *	vax$modify_exception routine. * *	Stephen Reilly, 25-Mar-85 * 003- Fixed the exception handler so that if an access violation occurs *	during the emulation of a floation point instruction it will point *	to the emulated instruction and not into the emulation code that *	caused the exception. * *	Stephen Reilly, 22-Jul-84 * 002- Added #ifdef for the new floating point option * *	Stephen Reilly, 11-Jul-84 * 001- Changes were made so that in the event of a stack overflow the *	exception handling will die gracefully. * *	Stephen Reilly, 20-Mar-84 * 000- This code is the modification of the VMS emulation code that  *	was written by Dave Cutler. This routine includes sysunwind.mar, *	exception.mar and exeadjstk.mar. The reason was so that all of the *      handling for the emulation code could be found in one module. *      These routines have been modified to run on Ultrix * ***********************************************************************/ # # d. n. cutler 6-jul-76 # # modified by: # #	v03-005 ly00b2		larry yetto		10-feb-1984 09:56 #		fix truncation error # #	v03-005	ljk0260		lawrence j. kenah	5-feb-1984 #		allow exception dispatching to take a detour through an #		instruction emulator so that the exception parameters can #		be modified to describe an exception at the site of the #		emulated instruction rather than inside the emulator. #		correct errors that appeared in comments. # #	v03-004	acg0393		andrew c. goldstein,	20-jan-1984  1:38 #		fix fp validation in condition handler search# also #		call exe$unwind directly to avoid p1 vectors # #	v03-003	wmc0001		wayne cardoza		28-oct-1983 #		change mode to user or supervisor handlers should not get  #		control in privileged modes. # #	v03-002	acg0348		andrew c. goldstein,	4-aug-1983  17:01 #		fix unwinding to frame of exception # #	v03-001	acg0310		andrew c. goldstein,	31-jan-1983  13:44 #		fix probing of stack after expansion # #	v02-016	msh0001		maryann hinden		09-feb-1982 #		fix probe problem. # #	v02-015	acg0261		andrew c. goldstein,	4-feb-1982  13:50 #		fix skipping over vectored handler invocations #		in nested exceptions. # #	v02-014	acg0260		andrew c. goldstein,	1-feb-1982  16:25 #		make failure to create stack space non-fatal for user #		and super modes # #	v02-013	acg0242		andrew c. goldstein,	30-dec-1981  19:12 #		catch exceptions at ast call site # #	v02-012	acg0224		andrew c. goldstein,	23-nov-1981  14:31 #		fix access mode used to report ast faults # #	v02-011	acg0222		andrew c. goldstein,	17-nov-1981  16:52 #		fix context bug in compatibility mode check # #	v02-010 dwt0003		david w. thiel		11-nov-1981 #		allow t-bit traps during call to a condition handler. #		fix search's condition handler. #		define global entry (exe$sigtoret) for a condition handler #		that turns an exception into a return with status. # #	v02-009	kdm0064		kathleen d. morse	25-aug-1981 #		change label of exception to exe$exception, for the use of #		the multi-processing code. # #	v02-008	ljk0036		lawrence j. kenah	23-jun-1981 #		convert fatal exception for executive mode into a #		nonfatal bugcheck. # #	v02-007	kta0022		kerbey t. altmann	10-jun-1981 #		add some code for inhibited system services. change #		stack range check to use new top limit array. # #	v02-006	kdm0037		kathleen d. morse	12-feb-1981 #		change non-kernel mode references to sch$gl_curpcb #		to use ctl$gl_pcb instead. # #	v02-005	acg0183		andrew c. goldstein,	29-dec-1980  20:01 #		fix condition handler search bugs, add entry point for #		lib$signal, add support for lib$stop, add checks to catch #		call failures to handlers. # # # hardware exception handling # #**************************************************************************** # # fair warning!! the exception reflection and condition handling code in # this module crawls with assumptions about the format of the stack and # argument lists, as documented in various comments throughout. since # the stack pointer moves frequently, no attempt has been made to use # symbolic offsets for stack relative references. changes to the stack # format should be made only after thorough inspection and understanding # of the code (not to mention appendix c of the architecture handbook). # note also that lib$signal must track the stack formats used here. # #**************************************************************************** #  # # local symbols # # call frame offset definitions # #define handler 0					#condition handler address#define savpsw 4					#saved psw from call#define savmsk 6					#register save mask#define savap 8					#saved ap register image#define savfp 12					#saved fp register image#define savpc 16					#saved pc register image#define savrg 20					#other saved register images  # # local data # #define final_idx 0					#indices to fetch message addresses#define attconsto_idx 1#define badhandler_idx 2#define badast_idx 3 # #+ # exe$acviolat - access violate fault # # this routine is automatically vectored to when an access violation is # detected. the state of the stack on entry is: # #	00(sp) = access violation reason mask. #	04(sp) = access violation virtual address. #	08(sp) = exception pc. #	12(sp) = exception psl. # # access violation reason mask format is: # #	bit 0 = type of access violation. #		0 = pte access code did not permit intented access. #		1 = p0lr, p1lr, or s0lr length violation. #	bit 1 = pte reference. #		0 = specified virtual address not accessible. #		1 = associated page table entry not accessible. #	bit 2 = intended access type. #		0 = read. #		1 = modify. # # the exception name followed by the number of exception arguments are # pushed on the stack. final processing is accomplished in common code. #- 	.align	2	.globl	exe$acviolat exe$acviolat:				#access violation faults/* *	The following code emulates what is done with a SEGFLT in the *	module trap.c.  The reason for this is that if a length violation *	has occured we attempt to extend the stack. If we fail then continue *	where the code will had an actual stack overflow.  The only problem with *	this is the address the user sees causing the violation is not the *	emulated instruction, instead it is the instruction in the emulation *	code. */	blbc	(sp),acviolat		#001 is this a lenght violation?	cmpzv	$psl$v_curmod,$psl$s_curmod,12(sp),$psl$c_user # check for user  	bneq	acviolat		#001 no, really an access violation	pushr	$0x03f			#001 save r0-r1 because C uses these					# as temp registers and never saves 					# them	mfpr	$USP,-(sp)		#001 get user stack	calls	$1,_grow 		#001 see if we can grow	blbs	r0,1f			#001 br if we did grow	pushl	(4+(6*4))(sp)		#001 get address that caused the					# violation	calls	$1,_grow		#001 try to grow	blbc	r0,2f			#001 br if we fail1: 	popr	$0x3f			#001 restore r0-r1 	addl2	$8,sp			#clean exception parameters from stack 	rei				#and return to retry instruction2:	popr	$0x03f			#restore registers r0-r1 acviolat:				#	movzwl	$ss$_accvio,-(sp)	#set exception nameex5arg:	pushl	$5			#set number of signal arguments	jmp	exe$exception		#finish in common code #+ # exe$reflect - reflect exception from mode other than kernel # # this routine is jumped to reflect an exception from a mode other than kernel. # the signal arguments are assumed to be set up properly on the stack. # note that the previous mode field of the psl contains the access mode # of the exception. #- 	.globl	exe$reflectexe$reflect:				#reflect exception	pushl	$1			#save code indicating signal #	pushr	$^m<r0,r1>		#save registers r0 and r1	 pushr	$0x03 # 003 We do not have primary and secondary exception vectors so because #     of this we set to -1 the frame depth.	mnegl	$1,-(sp)		#set initial frame depth	pushl	fp			#set initial handler establisher frame	pushl	$4			#set number of mechanism arguments  # # at this point the stack has the following format: # #	00(sp) = number of mechanism arguments (always 4). #	04(sp) = fp of handler establisher frame (tentative). #	08(sp) = frame depth (always -1). #	12(sp) = saved r0. #	16(sp) = saved r1. #	20(sp) = flags longword #	24(sp) = number of signal arguments. #	28(sp) = exception name (integer value). #	32(sp) = first exception parameter (if any). #	36(sp) = second exception parameter (if any). #	      . #	      . #	      . #	28+n*4(sp) = n'th exception parameter (if any). #	28+n*4+4(sp) = exception pc. #	28+n*4+8(sp) = exception psl. # 	movpsl	r0			#read current psl	extzv	$psl$v_curmod,$psl$s_curmod,r0,r1 #current mode kernel?	beql	3f			#if eql yes	cmpzv	$psl$v_prvmod,$psl$s_prvmod,r0,r1 #is current eql previous?	beql	4f			#if eql yes  # # adjust previous mode stack pointer using system service #  #	pushr	$^m<r2,r3,r4>		#save registers r2, r3, and r4	 pushr	$0x01c	addl3	$7,36(sp),r3		#calculate number of longwords to move	pushab	normal			#assume information can be copied	clrl	-(sp)			#set to use current stack pointer value	pushab	(sp)			#push address to store updated stack value	ashl	$2,r3,-(sp)		#calculate stack adjustment value	mnegl	(sp),(sp)		#set negative adjustment value	extzv	$psl$v_prvmod,$psl$s_prvmod,r0,-(sp) #push access mode of stack	pushl	$3			#push number of arguments	callg	(sp),*$sys$adjstk	#adjust previous mode stack pointer	blbs	r0,2f			#if lbs successful completion	addl2	$((6*4)+(3*4)),sp	#001 strip of the stuff associated					#001 with the sys$adjstk call	movab	28(sp),sp		#001 set sp to the exception name	jmp	start_handling		#001 handle the exception	/* *1:	movab	w^badstack,20(sp)	#set bad stack return *	movl	4(sp),r2		#retrieve previous access mode *	movl	*$ctl$al_stack[r2],16(sp) #set to use specifed stack pointer value *	callg	(sp),sys$adjstk		#reload previous mode stack pointer *	blbs	r0,20$			#if lbs successful completion *	subl3	$4,*$ctl$al_stack[r2],-(sp) #calculate top address of stack range *	addl3	12(sp),(sp),-(sp)	#calculate bottom address of stack range *	bsbw	crestack		#re-create virtual space under stack *	addl	$8,sp			#remove virtual address descriptor *	brb	10$			#and try again */2:	addl2	$16,sp			#remove argument list from stack #	popr	$^m<r1>			#get new previous mode stack pointer value	 popr	$0x02	brw	copyargs		#3:	jmp	reflect			#4:	brw	normal			# # # # all exceptions converge to this point with: # #	00(sp) = number of signal arguments. #	04(sp) = exception name (integer value). #	08(sp) = first exception parameter (if any). #	12(sp) = second exception parameter (if any). #	      . #	      . #	      . #	04+n*4(sp) = n'th exception parameter (if any). #	04+n*4+4(sp) = exception pc. #	04+n*4+8(sp) = exception psl. # # note that the previous mode field of the psl contains the access mode # of the exception. # 		.globl	exe$exceptionexe$exception:				#this label must be global for mp code	pushl	$1			#set code indicating signal #	pushr	$^m<r0,r1>		#save registers r0 and r1	 pushr	$0x03	mnegl	$3,-(sp)		#set initial frame depth	pushl	fp			#set initial handler establisher frame	pushl	$4			#set number of mechanism arguments  # # at this point the stack has the following format: # #	00(sp) = number of mechanism arguments (always 4). #	04(sp) = fp of handler establisher frame (tentative). #	08(sp) = frame depth (always -3). #	12(sp) = saved r0. #	16(sp) = saved r1. #	20(sp) = flags longword #	24(sp) = number of signal arguments. #	28(sp) = exception name (integer value). #	32(sp) = first exception parameter (if any). #	36(sp) = second exception parameter (if any). #	      . #	      . #	      . #	28+n*4(sp) = n'th exception parameter (if any). #	28+n*4+4(sp) = exception pc. #	28+n*4+8(sp) = exception psl. # reflect:				#reflect exception to proper access mode/*	addl3	$6,24(sp),r0		#calculate longword offset to saved psl *	assume	psl$v_cm eq 31 *	tstl	(sp)[r0]		#previously in compatibility mode? *	bgeq 	10$			#branch if not *	moval	*$ctl$al_cmcntx,r1	#get address of compatibility context area *	movq	12(sp),(r1)+		#save r0 and r1 *	movq	r2,(r1)+		#save r2 and r3 *	movq	r4,(r1)+		#save r4 and r5 *	movl	r6,(r1)+		#save r6 *	movzbl	$8,(r1)+		#set cm exception type *	movl	-4(sp)[r0],(r1)+	#save pc *	movl	(sp)[r0],(r1)		#save psl */1:	movpsl	r1			#read current psl/* *	mfpr	$pr$_ipl,r0		#read current ipl *	cmpl	$ipl$_astdel,r0		#invalid priority level? *	blss	20$			#if lss yes *	bbc	$psl$v_is,r1,30$	#if clr, then not on interrupt stack *20$:	bug_check invexceptn,fatal	#invalid exception *30$:	ifnord	$4,*$ctl$al_stack,20$	#is there a control region? */					# (not swapper,nullproc)	extzv	$psl$v_prvmod,$psl$s_prvmod,r1,r0 #extract previous mode field	bneq	8f			#if eql previous mode was kernel	jmp	normal			#8:	jmp	9f			#goto paged code9: #	pushr	$^m<r2,r3,r4>		#save registers r2, r3, r4	 pushr	$0x01c	pushab	normal			#assume information can be copied	movl	r0,r2			#save previous mode	addl3	$7,40(sp),r3		#calculate number of longwords to move	mfpr	r2,r1			#read previous mode stack pointer 8:	bsbw	check_stack		#check stack range	bneq	4f			#continue if stack ok	cmpl	$psl$c_user,r2		#is it user mode stack fault? 	bneq	5f			#no, then bad stack # 	pushr	$^m<r1,r2,r3,r4,r5>	#save registers	 pushr	$0x03e # 	movl	r0,r2			#get lowest stack address from check_st *ack	pushl	r0			#001 push address to grow	calls	$1,_grow		#001 try to grow # 	bsbw	exe$expandstk		#and call to expand stack # 	popr	$^m<r1,r2,r3,r4,r5>	#restore registers	 popr	$0x3e 	blbc	r0,5f			#br if any error to declare bad stack 	brb	8b			#check the stack again 					#note- check_stack prevents us from loping5:	movab	44(sp),sp		#001 pop everthing except the exception					# stuff	jmp	start_handling		#001 go to general handler4:/*	cmpl	r1,*$ctl$al_stack[r2]	#top address of stack in range? *	bgtru	50$			#if gtru no */	cmpl	$psl$c_user,r2		#previous mode user?	beql	7f			#if eql yes/*	cmpl	r0,*$ctl$al_stacklim[r2]#bottom address of stack in range? *	bgequ	70$			#if gequ yes *50$:	movab	w^badstack,(sp)		#set bad stack return *	movl	*$ctl$al_stack[r2],r1	#get starting address of previous mode stack *	bsbw	check_stack		#check stack range *	bneq	70$			#if neq successful range check *	pushal	-(r1)			#push top address of stack range *	movab	-1024+4(r1),-(sp)	#push bottom address of stack range *	bsbb	crestack		#re-create stack space *	addl	$8,sp			#remove virtual address limits from stack *	movl	*$ctl$al_stack[r2],r1	#get starting address of previous mode stack */7:	ashl	$2,r3,r0		#calculate number of bytes to move	subl2	r0,r1			#calculate new top of stack address	mtpr	r1,r2			#set new previous mode stack pointer	brw	copyargs		#

⌨️ 快捷键说明

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