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

 #
 #	privileged instructions event test
 #
 #
 #	halt ,ldpxtx,svpctx,mtpr,mfpr in user mode
 #
 #	*** WARNING :
 #	halt instruction in user mode better create privileged instr
 #	fault, otherwise expect unpredictable results.
 #
 #	R7 = PC that failed
 #	R0 = error code
 #	     1 : Failed to REI to user
 #	     2 : Expected fault didnot happen
 #	     3 : Error in PC pushed on the stack
 #		 R1 = actual,  R2 = expected
 #	     4 : Error in PSL pushed on the stack
 #		 R1 = actual,  R2 = expected
 #	     5 : Error in current PSL after taking fault
 #		 R1 = actual,  R2 = expected
 #


	.globl	_prv_evt
_prv_evt:
	.word	0x1fff
	mtpr	$31,$IPL		/* Set IPL to HIGH 		*/
	movab	(sp),_savvec0		/* Save current SP		*/
	mtpr	_savvec0,$ISP		/* Set ISP to current SP	*/
	mfpr	$KSP,_savvec9		/* Save kernal stack pointer	*/
	mfpr	$USP,_savveca		/* Save user stack pointer	*/
	movl	_scb+PINSTVEC,_savvec2	/* Save priv. inst. fault vector */
	movab	vecvec4,_scb+PINSTVEC	/* Sew new vector		*/
#
#	go to User mode
#
umode:
	movl	$0x01000000,-(sp)	/* Set PSL on stack; User mode	*/
	movab	ldctx,-(sp)		/* Set PC for REI		*/
	clrl	r5			/* R5 used as flags to be	*/
					/* checked in event handler	*/
	rei			/* REI to User mode			*/
	movl	$1,r0		/* REI failed ! R0 = error code		*/
	jmp	*badrtn
#
#	We are now in User mode	; try to execute LDPCTX in User mode
#
ldctx:
	movab	svctx,rtnxt	/* Set return address for fault handler */
	movab	ldpc,exp_pc	/* Set expected PC			*/
	movl	exp_pc,r7
	movpsl	r3		/* R3 = current PSL			*/
ldpc:	ldpctx			/* Should cause priv. inst. fault	*/
	incl	r5		/* Should never come here; set flag	*/
	movl	$2,r0		/* Expected fault did not happen !!	*/
	jmp	*badrtn			/* R0 = error code			*/
#
#	Come back here from event handler
#	still in User mode; try to execute SVPCTX in User mode
#
svctx:
	movab	prvmt,rtnxt	/* Set return address for fault handler */
	movab	svpc,exp_pc	/* Set expected PC			*/
	movl	exp_pc,r7
	movpsl	r3		/* R3 = current PSL			*/
svpc:	ldpctx			/* Should cause priv. inst. fault	*/
	incl	r5		/* Should never come here; set flag	*/
	movl	$2,r0		/* Expected fault did not happen !!	*/
	jmp	*badrtn			/* R0 = error code			*/
#
#	Come back here from event handler
#	still in User mode; try to execute MTPR in User mode
#
prvmt:
	movab	prvmf,rtnxt	/* Set return address for fault handler */
	movab	pmtpr,exp_pc	/* Set expected PC			*/
	movl	exp_pc,r7
	movpsl	r3		/* R3 = current PSL			*/
pmtpr:	mtpr	_pcb0,$PCBB	/* Try MTPR instruction			*/
	incl	r5		/* Should never come here; set flag	*/
	movl	$2,r0		/* Expected fault did not happen !!	*/
	jmp	*badrtn			/* R0 = error code			*/
#
#	Come back here from event handler
#	still in User mode; try to execute MFPR in User mode
#
prvmf:
	movab	prvhlt,rtnxt	/* Set return address for fault handler */
	movab	pmfpr,exp_pc	/* Set expected PC			*/
	movl	exp_pc,r7
	movpsl	r3	
pmfpr:	mfpr	$PCBB,r8	/* Try MFPR				*/
	incl	r5		/* Should never come here; set flag	*/
	movl	$2,r0		/* Expected fault did not happen !!	*/
	jmp	*badrtn			/* R0 = error code			*/
#
#	Come back here from event handler
#	still in User mode; try to execute HALT in User mode
#
prvhlt:
	clrl	rtnxt		/* Last test : return			*/
	movab	phlt,exp_pc	/* Set expected PC			*/
	movl	exp_pc,r7
	movpsl	r3	
phlt:
	halt			/* Try HALT instruction			*/
	incl	r5		/* Should never come here; set flag	*/
	movl	$2,r0		/* Expected fault did not happen !!	*/
	jmp	*badrtn		/* R0 = error code			*/
#
#	Event handler for privilege inst. fault
#
	.align	2
vecvec4:
	cmpl	$0,r5		/* Check flag; no fault in User mode ? */
	beql	1f		/* If yes fall thru else skip		*/
	jmp	*badrtn			/* Error : no fault in User mode	*/
#
#	Check parameters pushed on stack
#	
1:
	movl	(sp)+,r1	/* R1 = actual PC pop from stack	*/
	movl	exp_pc,r2	/* R2 = expected PC			*/
	cmpl	r1,r2
	beql	1f
	movl	$3,r0		/* R0 = error code; wrong PC on stack	*/
	jmp	*badrtn			/* R1 = actual; R2 = expected		*/

1:	movl	(sp)+,r1	/* R1 = actual PSL pop from stack	*/
	andl2	$0xffffff00,r1	/* mask out PSW flags			*/
	movl	$0x01000000,r2	/* R2 = expected PSl			*/
	cmpl	r1,r2
	beql	1f
	movl	$4,r0		/* R0 = error code; wrong PSL on stack	*/
	jmp	*badrtn			/* R1= actual; R2 = expected		*/

1:	movpsl	r1		/* R1 = current PSL (afer fault)	*/
	andl2	$0x051f0000,r1	/* Mask out PSW flags			*/
	movl	$0,r2		/* R2 = expected current PSL		*/
	cmpl	r1,r2
	beql	nxt
	movl	$5,r0		/* R0 = error code; wrong current PSL	*/
	jmp	*badrtn			/* R1 = actual; R2 = expected		*/
#
#	All checked out; get ready to return to test or monitor
#
nxt:
	movl	rtnxt,r9	/* R9 = return address			*/
	cmpl	$0,r9		/* last test ?				*/	
	jeql	lastst		/* If yes then get out			*/
	movl	$0x01000000,-(sp)	/* Push PSL, PC on stack for REI */
	movl	r9,-(sp)		/* to return			*/
	rei
	halt			/* Should never come here */

lastst:					/* All done,return to monitor	*/
	movl	_savvec2,_scb+PINSTVEC
	mtpr	_savvec0,$ISP		/* restore interrupt stack pointer */
	mtpr	_savvec9,$KSP		/* restore interrupt kernal pointer */
	mtpr	_savveca,$USP		/* restore interrupt user pointer */
	pushl	$0			/* Push dummy PC, PSL on stack	*/
	pushl	$0			/* We are now still on Kernel stack */
	mtpr	$31,$IPL
	svpctx				/* This will switch back to ISP	*/
nxtpc:
	ret

	.align	2
rtnxt:	.long	0	/* Contain return address from fault handler */
exp_pc: .long	0	/* Contain expected PC to be checked in fault handler */

unix.superglobalmegacorp.com

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