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


/******************************************************************************
*
*	SPECIAL FAULT HANDLERS FOR THE FPP DEMAND PAGE TEST
*
*  This file contains the special handlers for Translation (page) Fault,
*  Priveleged Instruction Fault events, and the FPP Emulation (FPM) Traps. 
*  The handlers for the other events are located in "evthandlers.s". There 
*  handlers for these events in "evthandlers.s" too but they aren't used in 
*  this *  macro test.
*  These routines are included in the systems initialyzer (init.x) at 
*  assembly time. While it doesn't appear in the makefile, terrible things 
*  will happen if this file is removed.
*
*   7-Jun-85  -added code to trap on a specific page fault occurrence.
*  13-Jun-85  -added code to spot corrupted return addresses
*  18-Jul-85  -added the FPM trap handler
******************************************************************************/


/******************************************************************************
*		ADDRESS TRANSLATION EXCEPTION HANDLER
*
*  This code is executed on an address translation (page) fault.
*  It will bump the translation fault count, validate the page that caused
*  the fault, change the code cache key, and restart the failing instruction.
*  If the faulting instruction is not a 'load accumulator' type then the
*  current accumulator will be checked to see if it was corrupted by the
*  event.
*
*  On entry, the stack is:
*  	( SP+12 ) PSL value at the time of the fault
*  	( SP+8  ) PC of the faulting instruction
*  	( SP+4  ) Virtual Address of the fault (operand or instruction)
*  	( SP    ) Fault Type  ( unused here )
*
*  NOTE: The PC and the PSL aren't removed from the stack. This keeps them 
*        where the REI can use them to return to the test code.
*****************************************************************************/
	.align	2
	.globl	_Trans
_Trans:
	mtpr	$0x1f,$IPL		/* disable the clock, etc.          */
	movl	r0,_trans_r0		/* save register 0                  */
	movl	(sp)+,r0		/* Ignore the fault type            */
	movl	(sp)+,_f_vaddr		/* Get VA that caused fault         */
	incl	_no_page_faults		/* bump translation fault count     */
	tstl	_pipe_test		/* If we aren't running one of the  */
	bneq	1f			/*    pipelined tests then compare  */
	cmpl	(sp),_code_addr		/*       the fault's address to the */
	beql	1f			/*          instruction's address   */
	movl	r0,_pop_val_1		/* MAJOR ERROR!! -CORRUPTED STACK!! */
	movl	_f_vaddr,_pop_val_2	/*   save the stack data for the    */
	movl	(sp),_pop_val_3		/*      error report                */
	movl	(sp)+,_pop_val_3	/*  ( type, VA, PC, & PSL saved )   */
	callf	$4,_bad_trans_stack	/* handle it (and don't come back)  */
1:	nop
	shar	$PGSHIFT,_f_vaddr,r0	/* R0 = PTE at fault                */
	orl2	$0x80000000,_Sysmap[r0] /* Turn Valid bit on in page table  */
	mtpr	_f_vaddr,$TBIS
/*****************************************************************************
*	How many page faults have occurred? (a fun place to sync an analyzer)
*****************************************************************************/
	movl	_no_page_faults,r0
	cmpl	$1,r0
	bneq	1f
	brb	2f			/* This is the 1st page fault       */
1:	cmpl	$2,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 2nd page fault       */
1:	cmpl	$3,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 3rd page fault       */
1:	cmpl	$4,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 4th page fault       */
1:	cmpl	$5,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 5th page fault       */
1:	cmpl	$6,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 6th page fault       */
1:	cmpl	$7,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 7th page fault       */
1:	cmpl	$8,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the 8th page fault       */
1:	cmpl	$9,r0
	bneq	1f
	nop
	nop
	brb	2f			/* This is the  9th page fault      */
	nop				/* This is the 10th page fault      */
	nop
2:
/*****************************************************************************
*	Should we compare the current accumulator to the initial one?
*****************************************************************************/
	tstl	_pipe_test		/* don't check the accumulator      */
	bneq	1f			/*   ... during pipelined subtests  */
	tstl	_load_type_inst		/* don't check the accumulator      */
	bneq	1f			/*   ... for load type instructions */
	tstl	_force_loop		/* don't check the accumulator      */
	bneq	1f			/*   ... during error loops         */
	tstl	_trans_acc_error	/* don't check the accumulator      */
	bneq	1f			/*   ... if it is already bad       */
	callf	$4,_chk_trans_acc	/* verify the current accumulator   */
1:
/*****************************************************************************
*  	Bump the code cache key if we're running with code cache misses
*****************************************************************************/
	tstl	_i_cache_hit		/* are we running with cache hits?  */
	bneq	2f			/*    yes -don't bump the cache key */
	incl	_Codek			/*     no -bump code cache key      */
	cmpl	_Codek,$255		/* Last key yet ?                   */
	jlss	1f
	movl	$1,_Codek		/* Reset Code key to 1              */
	mtpr	$1,$PACC		/* Purge all code cache             */
1:
	mtpr	_Codek,$CCK		/* Set new key                      */
2:
	nop
	movl	_trans_r0,r0		/* restore register 0               */
	rei				/* return to the instruction        */
 
	.align 	2
_trans_r0:				/* save register 0 here             */
	.long	0





/*****************************************************************************
*	     PRIVILEGE INSTRUCTION EXEPTION HANDLER
* The privileged instruction event is used by the RUN_CODE routine to switch
* from User Mode back to Kernal Mode.
*
*  On entry, the stack is:
*	  PSL value at the time of the fault
*	  PC of the faulting instruction
*		
*****************************************************************************/
	.align	2
	.globl	_Prvis
_Prvis:
	mtpr	$0x1f,$IPL		/* Set IPL to HIGH                  */
	movl	(sp)+,_act_pc		/* Get the PC that caused the fault */
	movl	(sp)+,_f_ptr		/* Get the PSL from the stack       */
	cmpl	_act_pc,$_run_code_mtpr	/* was it from RUN_CODE?            */
	bneq	1f
	pushl	_run_code_psl		/* push "run_code"'s PSL            */
	pushl	$_run_code_mtpr		/* push the return address          */
	rei				/* return to "run_code"             */
1:
	pushl	_f_ptr			/* push the PSL back on the stack   */
	pushl	_act_pc			/* push the PC back on the stack    */
	pushl	$0x2c			/* push the Priv. Instr. Fault code */
	callf	$8,_XTrap		/* report an invalid fault          */




/******************************************************************************
*		FPP EMULATION TRAP HANDLER
*
*  This code is executed after an FPP Emulation trap. These traps are to allow
*  the software to emulate complex FPP instructions when there is no FPP in
*  the system.
*  If the trap was expected, this code will save the stack values and go to 
*  the address in "event_return". If the trap wasn't expected then the
*  general event handler ("fpp_event") will be called.
*
*  On entry, the stack is:
*  	( SP+16 ) PSL value at the time of the fault
*  	( SP+12 ) PC of the NEXT instruction
*  	( SP+8  ) OP-CODE of the instruction to be emulated
*  	( SP+4  ) Least significant longword of the operand (if any)
*  	( SP    )  Most significant longword of the operand (if any)
*
*  NOTE: If the trap was not expected then nothing will be popped from the
*        stack. If is was expected then everything will be popped.
* 
*  NOTE2: This code is responsible for saving the PSL, registers, and the
*	 accumulator - it bypasses the parts in "run_code" that save them.
*****************************************************************************/
	.align	2
	.globl	_FPM_handler
_FPM_handler:
	movpsl	_psl_val		/* save the psl        */
	mtpr	$0x1f,$IPL		/* disable the clock, etc.   */
	movl	_psl_val,_post_event_psl   /* make a copy for DMP4 */
	storer 	$0x1fff,_store_regs  	/* store regs 0 - 12   */
	moval	(r13),_post_event_fp	/* save the frame pointer */
	moval	(r14),_post_event_sp	/* save the stack pointer */
	movl	$1,_fpm_trap_occurred	/* set Trap Occurred flag */
	tstl	_emulated_inst		/* Was the trap expected? */
	bneq	1f			/*   Yes, jump            */
	pushl	$FPM_CODE		/*   No, -unexpected event */
	callf	$8,_XTrap
	halt
1:					/* The trap was expected */
	cmpl	_acc_st_size,$DBL	/* check the accumulator's size */
	beql	1f
	stf	_dbl_st_acc		/* store the sgl accumulator */
	brb	2f
1:	std	_dbl_st_acc		/* store the dbl accumulator */
2:
	movl	(sp)+,_fpm_ms_op	/* pop the MS operand  */
	movl	(sp)+,_fpm_ls_op	/* pop the LS operand  */
	movl	(sp)+,_fpm_op_code	/* pop the op-code     */
	movl	(sp)+,_fpm_pc		/* pop the next PC     */
	movl	(sp)+,_fpm_psl		/* pop the stack's PSL */
	bitl	$PSL_DBL,_psl_val  	/* check for DBL Acc.  */
	beql	1f 
	std	_post_evt_acc		/* save the DBL Acc.   */
	brb	2f
1:	stf	_post_evt_acc		/* save the SGL Acc.   */
	clrl	_post_evt_acc+4
2:
	pushl	_run_code_psl		/* push this Kernal mode PSL       */
	pushl	_event_return		/* push the return address         */
	rei				/* return to "run_code"            */


unix.superglobalmegacorp.com

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