File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / event / roprnd_evt.s
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:30:53 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

#
#	reserved operand event test
#
#	includes mtpr,mfpr,&rei
#
#	R7 = which instruction is testing
#	     1 - MTPR
#	     2 - MFPR
#	     3 - REI
#	R3 = PC that force fault
#	R0 = error code	
#	     1 : expected reserved operand fault didnot happen
#	     2 : error in PC pushed on stack
#		  R1 = actual, R2 = expected
#	     3 : error in PSL pushed on stack
#		  R1 = actual, R2 = expected
#	     4 : Too many parameters pushed on the stack
#	     5 : REI did not catch bad PC/PSL on the stack
#

	.set	N_EXIST_PR,255

	.globl	_roprnd_evt
_roprnd_evt:
	.word	0x1fff
	mtpr	$31,$IPL		/* disable interrupts */
	movab	(sp),_savvec0		/* Save current SP (ISP)	*/
	mtpr	_savvec0,$ISP		/* Set ISP = current SP 	*/
	mfpr	$KSP,_savvec9		/* Save kernal stack pointer */
	mfpr	$USP,_savveca		/* Save user stack pointer */
	movl	_scb+ROVEC,_savvec2	/* Save vector of Resr. oprd fault */
	movab	ropflt1,_scb+ROVEC	/* Set new vector 		*/
	movl	$-1,-(sp)		/* Push marker on stack		*/


	movl	_scb+PINSTVEC,_savvec3
	movpsl	r1			/* If PSL_MODE != Kernel then	*/
	bitl	$0x01000000,r1		/* change to Kernel mode by 	*/
	beql	1f			/* executing a privilege inst.  */
	movab	tempvec,_scb+PINSTVEC	/* as HALT			*/
	halt

	.align	2
tempvec:
	addl2	$8,sp			/* Get rid of trash on the stack */
	movl	_savvec3,_scb+PINSTVEC	/* Restore original vector	*/
#
#	We are running in Kernel mode; Interrupt stack
#	MTPR to non existent privileged register			*/
#
1:		
	movl	$0,r11		/* Set flag to be checked in event handler */
	movab 	mfprt,r6	/* R6 = return address after exception	*/
	movab	mtprt,r5	/* R5 = expected PC on stack after fault */
	movl	r5,r3
	movl	$1,r7		/* R7 = 1; testing MTPR */
	movpsl	r4		/* R4 = expected PSL			*/
mtprt:
	mtpr	$0,$N_EXIST_PR  /* Should cause reserved operand fault !! */
	movl	$1,r0		/* R0 = error code; expected reserved	*/
	jmp	*badrtn		/* operand fault did not happen 	*/

	.align	2		/* Event handler for reserved oprd. fault */
ropflt1:
	movl	(sp)+,r1	/* R1 = actual PC from stack		*/
	movl	r5,r2		/* R5 = expected PC			*/
	cmpl	r1,r2
	beql	1f
	movl	$2,r0		/* R0 = error code; PC saved on stack 	*/
	jmp	*badrtn		/* not equal to expexted PC		*/
				/* R1 = actual; R2 = expected		*/

1:	movl	(sp)+,r1	/* R1 = actual PSL from stack		*/
	movl	r4,r2		/* R2 = expected PSL			*/
	cmpl	r2,r1		/* Are they the same ?			*/
	beql	1f
	movl	$3,r0		/* Error in PSL !! 			*/
	jmp	*badrtn
1:
	cmpl	$1,r11		/* Is fault caused by REI or MTPR ?	*/
	bneq	1f		/* Skip this part if come here from MTPR */
	movl	(sp)+,r10	/* REI fault : get rid of PC,PSL on the */
	movl	(sp)+,r10	/* stack then check for marker 		*/

1:
	cmpl	$-1,(sp)	/* Is SP pointing at the marker on SP ?	*/
	beql	1f
	movl	$4,r0		/* If not then error : pushed too many  */
	jmp	*badrtn		/* parameters on SP after fault ..	*/

1:	movpsl	r1		/* Get ready to return from fault	*/
	movl	r1,-(sp)	/* Push current PSL on stack		*/
	movl	r6,-(sp)	/* R6 = addr to return to		*/
	rei
	halt			/* Should never come here !!!!		*/
#
#
#	MFPR from non existent privileged register
#
mfprt:
	movl	$2,r7		/* R7 = 2; testing MFPR */
	movab 	reit,r6		/* Set R6 = return adddress after fault */
	movab	mfprt0,r5	/* R5 = expected PC on stack 		*/
	movl	r5,r3
	movpsl	r4		/* R4 = expected PSL			*/
mfprt0:
	mfpr	$N_EXIST_PR,r10	/* Should cause resr. oprd. fault ..	*/
	movl	$1,r0		/* Error; expected fault did not happen */
	jmp	*badrtn
#
#	REI with illegal PSL on the stack : PSL_IS on and PSL_MODE is User
#
reit:
	movl	$3,r7		/* R7 = 3; testing REI */
	movab	reit1,r6	/* R6 = return address after exception	*/
	movab	reita,r5	/* R5 = expected PC on SP 		*/
	movl	r5,r3
	movl	$0x05000000,r1	/* Push PSL on stack; PSL_IS on and	*/
	movl	r1,-(sp)	/* and PSL_MODE = User			*/
	movab	reierr,-(sp)	/* PC if REI doesn't catch bad PSL	*/
	movl	$1,r11		/* Set flag to be checked in event handler */
reita:	rei			/* should cause reserved opr. fault	*/
	movl	$1,r0		/* Error; expected fault did not happen */
	jmp	*badrtn		/* Should never come here ..		*/
#
#	REI with illegal PSL on the stack : PSL_IS on and PSL_IPL = 0
#
reit1:
	movab	reit2,r6	/* R6 = return address after exception	*/
	movab	reit1a,r5	/* R5 = expected PC on stack		*/
	movl	r5,r3
	movl	$0x04000000,r1	/* Set PSL, PC on stack for REI		*/
	movl	r1,-(sp)
	movab	reierr,-(sp)	/* PC if REI doesn't catch bad PSL	*/
reit1a:	rei			/* Should cause fault			*/
	movl	$1,r0		/* Error; expected fault did not happen */
	jmp	*badrtn		/* Should never come here ..		*/
#
#	REI with illegal PSL on the stack : PSL_IS off,PSL_IPL > 0
#	and PSL_MODE = User
#
reit2:
	movab	reit3,r6	/* R6 = return address after exception	*/
	movab	reit2a,r5	/* R5 = expected PC on stack 		*/
	movl	r5,r3
	movl	$0x010f0000,r1	/* Set PSL, PC on stack for REI		*/
	movl	r1,-(sp)
	movab	reierr,-(sp)	/* PC if REI doesn't catch bad PSl	*/
reit2a:	rei			/* Should cause fault 			*/
	movl	$1,r0		/* Error; expected fault did not happen */
	jmp	*badrtn		/* Should never come here ..		*/

reit3:
	movpsl	r1
	bitl	$0x04000000,r1
	beql	1f		/* If IS is ON, turn it off by 		*/
	andl2	$0xfbffffff,r1	/* using REI				*/
	movl	r1,-(sp)
	movab	1f,-(sp)
	rei
	jmp	*badrtn

#
#	REI with illegal PSL on the stack : PSL_IS is off ; Try to switch
#	to Interrupt stack by REI
#
1:				/* Current PSL_IS is OFF		*/
	movl	$-1,-(sp)	/* push marker on stack (kernal stack)	*/
	movab	reit4,r6	/* R6 = return address after exception	*/
	movab	reit3a,r5	/* R5 = expected PC on stack 		*/
	movl	r5,r3
	movl	$0x04000000,r1	/* Set PSL, PC on stack for REI		*/
	movl	r1,-(sp)
	movab	reierr,-(sp)	/* PC if REI doesn't catch bad PSL	*/
	movpsl	r4
reit3a:	rei			/* Should cause fault       		*/
	movl	$1,r0		/* Error; expected fault did not happen */
	jmp	*badrtn		/* Should never come here ..		*/
#
#	REI with illegal PSL on the stack : Current PSL_IPL is smaller
#	than PSL_IPL on stack 
#
reit4:
	movab	reit5,r6	/* R6 = return address after exception	*/
	movab	reit4a,r5	/* R5 = expected PC on stack		*/
	movl	r5,r3
	mtpr	$0x10,$IPL	/* Set current PSL_IPL = 0x10		*/
	movpsl	r4
	movl	$0x00180001,r1	/* Set PSL_IPL (on stack) to 0x18	*/
	movl	r1,-(sp)
	movab	reierr,-(sp)	/* PC if REI doesn't catch bad PSL	*/
reit4a:	rei			/* Should cause fault       		*/
	movl	$1,r0		/* Error; expected fault did not happen */
	jmp	*badrtn		/* Should never come here ..		*/
#
#
reit5:
	movl	$0x01000000,-(sp)	/* Set up PSL, PC to use REI to */
	movab	usrmd,-(sp)		/* switch to User mode		*/
	rei
	jmp	*badrtn
#
#	REI with illegal PSL on the stack : Try to switch from USER to
#	KERNEL mode by REI 
#
usrmd:				/* We now running in User mode		*/
	movab	reit6,r6	/* R6 = return address after exception	*/
	movab	reit5a,r5	/* R5 = expected PC on stack   		*/
	movl	r5,r3
	movl	$0x00000000,r1	/* Set up PSL, PC for REI 		*/
	movl	r1,-(sp)
	movab	reierr,-(sp)	/* PC if REI doesn't catch bad PSL	*/
	clrl	r11		/* Clear flag				*/
	movpsl	r4
reit5a:	rei			/* Should cause fault       		*/
	movl	$1,r0
	jmp	*badrtn		/* Should never come here ..		*/
#
#
#
reit6:
	movl	_savvec3,_scb+PINSTVEC	/* Restore vectors		*/
	movl	_savvec2,_scb+ROVEC
	pushl	$0			/* Push dummy PSL,PC on stack	*/
	pushl	$0
	mtpr	$31,$IPL		/* Reset IPL to HIGH		*/
	svpctx				/* Switch to ISP		*/
btisp:
	movl	_savvec0,sp		/* Restore SP 			*/
	mtpr	_savvec0,$ISP		/* Restore ISP 			*/
	mtpr	_savvec9,$KSP		/* Restore KSP 			*/
	mtpr	_savveca,$USP		/* Restore USP 			*/
	ret
#
#
#
reierr:
	movl	$5,r0
	jmp	*badrtn		/* REI error - REI did not catch illegal PSL*/
				/* on the stack !*/

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.