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

#
#
#	*arithmetic exception evnt test
#	*divide by zero & integer overflow
#	*divl2,divl3,ediv
#	*are tested.
#
#	R3 = PC that failed
#	R0 = error code
#	     1 - Expected fault did not happen
#		 R1 = current PSL
#	     2 - PSL_V bit is not set
#		 R1 = current PSL
#	     3 - Unexpected arithmetic fault
#		 R1 = error code,  R2 = actual PC on the stack
#	     4 - Wrong error code on the stack
#		 R1 = actual,  R2 = expected
#	     5 - Error in PC pushed on the stack
#		 R1 = actual,  R2 = expected
#	     6 - Error in PSL pushed on the stack
#		 R1 = actual,  R2 = expected
#	     7 - Too many parameters pushed on the stack
#	     8 - PSL_V on the stack is not reset
#		 R1 = PSL on the stack

	.globl	_arith_evt
_arith_evt:
	.word	0x1fff
	mtpr	$31,$IPL		/* Set IPL to HIGH		*/
	movab	(sp),_savvec0		/* Save current SP		*/
	mtpr	_savvec0,$ISP		/* Set ISP = current SP		*/
	movl	_scb+ARITHVEC,_savvec2	/* Save arith. fault vector	*/
	movab	arthflt,_scb+ARITHVEC	/* Set new vector		*/
	movl	$-1,-(sp)		/* Push marker on stack		*/
	movab	_pcb0,r1
	mtpr	r1,$PCBB		/* Set PCBB			*/
	movab	(sp),_pcb0		/* Set KSP in PCB0		*/
	movab	(sp),_pcb0+4		/* Set USP in PCB0		*/

	movpsl	r1			/* If not KERNEL mode, then  	*/
	bitl	$0x01000000,r1		/* force KERNEL mode		*/
	beql	1f
	movl	_scb+PINSTVEC,_savvec3
	movab	forckmd,_scb+PINSTVEC
	halt				/* HALT in USER mode to force	*/
					/* KERNEL mode 			*/
	.align	2
forckmd:
	addl2	$8,sp			/*get rid of trash on the stack	*/
	movl	_savvec3,_scb+PINSTVEC	/*restore vector		*/
#
#	We are now running in KERNEL mode; IPL = 0x1f
#	try to force PSW_V bit set without causing fault
#	by dividing MAX. negative no by -1
1:
	bicpsw	$0x3f			/* Disable overflow event (PSW)	*/
	movab	epc2,r3			/* R5 = expected PC		*/
	movl	$-1,r4			/* R4 = -1; Donot expect fault	*/
	movl	$0x80000000,r8
	clrl	r9
epc2:
	divl2	$-1,r8		/* Should not get overflow exception	*/
	movpsl	r1
	bitl	$2,r1			/* Check if PSW_V bit is on	*/
	bneq	1f
	movl	$2,r0			/* Error : PSW_V not set	*/
	jmp	*badrtn
#
#	We are now running in KERNEL mode; IPL = 0x1f
#	forcing arithmetic fault by dividing by 0
#
1:
	movl	$0x300,r0		/* R0 = error code		*/
	bicpsw	$0x3f			/* Reset PSW 			*/
	bispsw	$0x20			/* Enable Overflow fault (in PSW) */
	movab	epc3,r5			/* R5 = expected PC		*/
	movl	r5,r3			/* R3 = PC that failed 		*/
	movab	pc4,r6			/* R6 = return addr from evt handler */
	movl	$2,r4			/* R4 = expected error code on SP */
	movl	$0x80000000,r8		/* divide by zero exception	*/
	clrl	r9
	movpsl	r7			/* R7 = expected PSL		*/

epc3:	divl2	$0,r8			/* Should cause fault ..	*/
	movpsl	r1
	movl	$1,r0			/* Error : No fault happen	*/
	jmp	*badrtn
#
#	forcing arithmetic fault (int. overflow) by dividing 
#	MAX negative no. by -1
#
pc4:
	movab	epc4,r5			/* R5 = expected PC; next inst.	*/
	movab	epc40,r3		/* R3 = PC that failed 		*/
	movab	pc5,r6			/* R6 = return addr from evt handler */
	movl	$1,r4			/* R4 = expected code on stack	*/
	movl	$0x80000000,r8
	clrl	r9
epc40:
	divl2	$-1,r8		/* Should  get overflow exception	*/
epc4:
	movpsl	r1			/* R7 = expected PSL		*/
	movl	$1,r0			/* Error : No fault happen	*/
	jmp	*badrtn
#
#	forcing arithmetic fault (int. overflow) by dividing 
#	MAX negative no. by 0 (using DIVL3)
#
pc5:
	movl	$0x500,r0		/* R0 = error code		*/
	movab	epc5,r5			/* R5 = expected PC		*/
	movl	r5,r3
	movab	pc6,r6			/* R6 = return addr from evt handler */
	movl	$2,r4			/* R4 = expected error code on stack */
	movl	$0x80000000,r8
	clrl	r9
	movpsl	r7			/* R7 = expected PSL		*/
epc5:	divl3	$0,r8,r9		/* Should cause fault ..	*/
	movpsl	r1
	movl	$1,r0			/* Error : No fault happen	*/
	jmp	*badrtn
#
#	forcing arithmetic fault (int. overflow) by dividing 
#	MAX negative no. by -1 (using DIVL3)
#
pc6:
	movl	$0x600,r0		/* R0 = error code		*/
	bicpsw  $0x3f			/* Clear PSW			*/
	bispsw	$0x20			/* Enable overflow exception	*/
	movab	epc6,r5			/* R5 = expected PC		*/
	movab	epc60,r3
	movab	pc11,r6			/* R7 = return addr from evt handler */
	movl	$1,r4			/* R4 = expected error code on stack */
	movl	$0x80000000,r8
	clrl	r9
	movpsl	r7			/* R7 = expected PSL		*/
epc60:
	divl3	$-1,r8,r9		/* Should  get overflow exception */
epc6:
	movpsl	r1
	movl	$1,r0			/* Error : No fault happen	*/
	jmp	*badrtn
#
#	forcing arithmetic fault (int. overflow) by dividing 
#	MAX negative no. by 0 (using EDIV)
#
pc11:
	movl	$0xb00,r0		/* R0 = error code		*/
	movab	epc11,r5		/* R5 = expected PC		*/
	movl	r5,r3
	movab	pc12,r6			/* R6 = return addr from evt handler*/
	movl	$2,r4			/* R4 = expected code on stack	*/
	movl	$0x80000000,r8
	clrl	r10
	clrl	r9
	movpsl	r7			/* R7 = expected PSL		*/
epc11:	ediv	$0,r8,r9,r10		/* Should cause fault ..	*/
	movpsl	r1
	movl	$1,r0			/* Error : No fault happen	*/
	jmp	*badrtn
#
#	forcing arithmetic fault (int. overflow) by dividing 
#	MAX negative no. by -1 (using EDIV)
#
pc12:
	movl	$0xc00,r0		/* R0 = error code		*/
	bispsw	$0x20			/* Enable overflow exception	*/
	movab	epc12,r5		/* R5 = expected PC		*/
	movab	epc120,r3
	movab	eee,r6			/* R6 = return addr from evt handler*/
	movl	$1,r4			/* R4 = expected code on stack	*/
	movl	$0x80000000,r8
	clrl	r9
	clrl	r10
	movpsl	r7			/* R7 = expected PSL		*/
epc120:
	ediv	$-1,r8,r9,r10		/* Should  get overflow exception */
epc12:
	movpsl	r1
	movl	$1,r0			/* Error : No fault happen	*/
	jmp	*badrtn
#
#	**********************************
#	Event handler for arithmetic fault
#	**********************************	
	.align	2
arthflt:
	cmpl	$-1,r4		/* Is fault expected ?			*/
	bneq	1f		/* if YES then skip to 1f		*/
	movl	$3,r0		/* Error : exception not expected	*/
	movl	(sp)+,r1	/* R1 = fault type */
	movl	(sp),r2		/* R2 = PC on the stack */
	jmp	*badrtn
1:	
	movl	(sp)+,r1	/* Get actual error code from stack	*/
	movl	r4,r2		/* R2 = expected error code		*/
	cmpl	r1,r2
	beql	1f
	movl	$4,r0		/* Error : wrong error code on stack	*/
	jmp	*badrtn
1:
	movl	(sp)+,r1	/* R1 = actual PC pop from stack	*/
	movl	r5,r2		/* R5 = expected PC			*/
	cmpl	r1,r2
	beql	1f
	movl	$5,r0		/* Error : wrong PC on stack		*/
	jmp	*badrtn		/* R1 = actual; R2 = expected		*/
#
1:
	movl	(sp)+,r1	/* R1 = actual PSL pop from stack	*/
	andl2	$0xfffffff0,r1	/* Mask out PSW flags			*/
	andl3	$0xfffffff0,r7,r2	/* R2 = actual PSL		*/
	cmpl	r2,r1
	beql	1f
	movl	$6,r0		/* Error : wrong PSL on stack		*/
	jmp	*badrtn
#
1:
	cmpl	$-1,(sp)	/* SP should point at the marker 	*/
	beql	1f
	movl	$7,r0		/* Error : too many lgwords pushed on SP */
	jmp	*badrtn
#
1:
	bitl	$2,r1		/* Check if PSL_V on stack is reset	*/
	beql	1f
	movl	$8,r0		/* Error : PSL_V on SP is not OFF	*/
	jmp	*badrtn
#
1:
	movl	r1,-(sp)	/* Set up PSL, PC to return from fault  */
	movl	r6,-(sp)
	rei
	halt			/* Should never come here		*/
#
#	***************************
#	All done; return to monitor
#
eee:
	mtpr	$31,$IPL
	movl	_savvec0,sp		/* Restore stack, vector	*/
	movl	_savvec2,_scb+ARITHVEC
	ret


unix.superglobalmegacorp.com

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