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

# ************************************************************************
# *
# *		"RUN THE TEST CODE" ROUTINE
# *
# *  The general template of the test code will be:
# *
# *      <op-code> [<addr-mode>] [<op.#1>] [<addr-mode>] [<op.#2>]
# *
# *  any unused bytes will be padded with NOPs. After the NOPs there will
# *  be a jump back to this routine. The jump will only be taken if there
# *  is no event generated by the test instruction.
# *
# *  The event handler will verify the event type and return to this code 
# *  through the "event_return" pointer.
# *  After the event, this routine will decide if the event should have
# *  been masked or not. If it wasn't masked then this code will call the
# *  routine to check the event results (reg's, PSL, etc.). The checking
# *  routine is called from here because after the event, this was the  
# *  last routine with the right frame pointer.
# *
# *  30-May-85  added: ACC = 0 for pipelined test #2
# *  10-Jul-85  pulled instruction cache hit parts
# ************************************************************************
	.set	NOP_JMP,0x1010719f	/* jump to an absolute address */
	.text
	.align 1
	.globl _run_code
_run_code:
	.word	0
	moval	(r13),_rc_code_fp		/* save the frame pointer    */
	moval	(r14),_rc_code_sp		/* save the stack pointer    */
	movab	_loop_n_leave,return		/* exit for unexpected event */
	callf	$4,_fill_code_buff		/* stuff the code buffer     */
	moval	_evt_return,_event_return	/* set up event return addr  */

#########################################################################
# Invalidate the instruction cache (error loop starts here)
#########################################################################
_shift_loop:
	incl	_Codek			/* 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       */
	nop
1:
	mtpr	_Codek,$CCK		/* Set new key                */
 
#########################################################################
# If the addressing mode is POP or deferred POP, push the data needed
#########################################################################
	cmpl	$0x8e,_addr_code	/* POP SP addressing?        */
	beql	1f
	cmpl	$0x9e,_addr_code	/* POP SP deferred addr.?    */
	bneq	2f
1:
	cmpl	$1,_no_ops		/* push 1 or 2 operands?     */
	beql	1f
	pushl	_sgl_value_10		/* push the 2nd data operand */
1:
	pushl	_sgl_value_9		/* push the data to be popped */
 
2:
#########################################################################
# LOAD THE ACCUMULATOR AND THE REGISTERS  
# If this is pipelined test #2, load a zero into the accumulator
#########################################################################
	moval	(sp),_pre_event_sp	/* save the stack pointer      */
	cmpl	$2,_pipe_test
	bneq	1f
	clrl	r0			/* load the accumulator with   */
	clrl	r1			/*    zero for pipe test #2    */
	brb	2f
1:	movl	_dbl_ld_acc,r0		/* if not pipe test #2, load   */
	movl	_dbl_ld_acc+4,r1	/*    the ACC with the data    */
2:
	cmpl	_acc_ld_size,$DBL	/* load DBL or SGL ACC?        */
	beql	1f
	ldf	r0			/* load the sgl accumulator    */
	brb	2f
1:	ldd	r0			/* load the dbl accumulator    */
2:
	loadr	$0x3fff,_load_regs	/* load regs 0 - 13 (FP)       */
 
 
#########################################################################
# ENABLE OR DISABLE THE EVENT, SET THE EVENT TYPE & EXECUTE THE TEST CODE
#########################################################################
	bispsw	$ENABLE_EVENTS		/* enable ovfl & undfl events  */
	bicpsw	_disable_mask		/* disable events as needed    */
	movl	_test_event,_exp_event	/* set the event expected flag */
	movpsl  _init_psl		/* save PSL for error checking */
	jmp	*_code_addr		/* execute the test code       */
	halt


##########################################################################
# The only way here (knock on wood) is if we executed the test instruction
# without getting any events. If an event was expected, it is an error to 
# come here.
# - Save the PSL and check if the event was disabled.
##########################################################################
	.globl _rc_code_return
_rc_code_return:
	movpsl	_psl_val		/* save the final PSL      */
	clrl	_exp_event		/* no more events expected */
	bitl 	$PSL_DBL,_psl_val  	/* check for DBL Acc.       */
	bneq	1f
	stf	_dbl_st_acc		/* save the accumulator    */
	clrl	_dbl_st_acc+4
	brb	2f
1:	std	_dbl_st_acc		/* save the accumulator    */
2:
	tstl	_evt_disabled		/* Was the event disabled? */
	bneq	1f
	jmp	_rc_no_event		/*  No -event not disabled */
1:


##########################################################################
# The event was disabled so we're OK so far. Check the PSL flags
##########################################################################
	callf	$4,_bad_final_psl	/* check the final PSL     */
	tstl	r0			/* was the PSL OK?         */
	bneq	1f			/*   -NO. handle the error */
	jmp	_loop_n_leave		/*   -YES. exit (or loop)  */
1:
	tstl	_prt_error		/* print an error message? */
	beql	1f
	pushl	_bad_psl_msg		/* "bad final PSL" message */
	callf	$8,_prt_evt_er_msg	/* print the error message */
	pushl	$_rc_f_psl_msg		/* "final PSL = "          */
	callf	$8,_writes
	pushl	_psl_val
	callf	$8,_write32h
	pushl	$_rc_e_psl_msg		/* "expected PSL = "       */
	callf	$8,_writes
	pushl	_exp_psl
	callf	$8,_write32h
	pushl	$_rc_newline		/* print a line feed       */
	callf	$8,_writec
1:
	tstl	_halt_flg		/* halt on error?          */
	beql	1f
	pushl	$BAD_PSL_HLT
	callf	$8,_event_halt		/* set up regs and halt    */
1:
	tstl	_loop_on_err		/* loop on the error?      */
	beql	1f
	movl	$1,_force_loop		/* set the Force Loop flag */
1:
	jmp	_loop_n_leave		/* exit or loop            */


##########################################################################
# BUMMER!!   WE SHOULD HAVE GOTTEN AN EVENT  
##########################################################################
_rc_no_event:
	storer	$0x3fff,_store_regs	/* store regs 0 - 13         */
	movl	_rc_code_fp,fp		/* re-load the frame pointer */
	movl	_rc_code_sp,sp		/* re-load the stack pointer */
	tstl	_force_loop		/* Is "force_loop" set?      */
	beql	1f
	jmp	_shift_loop		/* Yes - loop on the error   */
1:
	incl	_errcnt;		/* bump the error count      */
	tstl	_prt_error		/* print an error message?   */
	beql	1f
	pushl	_no_evt_msg		/* "did not get event" msg   */
	callf	$8,_prt_evt_er_msg	/* print the error message   */
1:
	tstl	_halt_flg		/* halt on error?            */
	beql	1f
	pushl	$NO_EVT_HLT
	callf	$8,_event_halt	 	/* halt with code of 1       */
1:
	tstl	_loop_on_err		/* loop on the error?        */
	beql	1f
	movl	$1,_force_loop		/* set the force_loop flag   */
1:
	jmp	_loop_n_leave		/* loop on the error or exit */
	halt				/* we should never get here  */


##########################################################################
# The only way here (knock on wood) is if we got the correct event while
# executing the instruction. 
##########################################################################
	.globl _evt_return
_evt_return:
	clrl	_exp_event		/* no more events expected     */
	movl	_post_evt_acc,_dbl_st_acc	/* save the accumulator */
	movl	_post_evt_acc+4,_dbl_st_acc+4
	movl	_rc_code_fp,fp		/* re-load the frame pointer  */
	movl	_rc_code_sp,sp		/* re-load the stack pointer  */
	tstl	_force_loop		/* Is "force_loop" set?       */
	beql	1f
	jmp	_shift_loop		/* then loop on the error     */

1:
##########################################################################
# NOW CHECK TO SEE IF THE EVENT WAS DISABLED WHEN IT OCCURRED
##########################################################################
	tstl	_evt_disabled		/* Was the interrupt disabled? */
	bneq	1f
	callf	$4,_chk_event		/*  No -verify the stack, etc. */
	jmp	_loop_n_leave		/* Exit ( or loop if error )   */

1:
##########################################################################
# BUMMER!! WE SHOULDN'T HAVE GOTTEN AN EVENT  
##########################################################################
	movl	_rc_code_fp,fp		/* re-load the frame pointer  */
	movl	_rc_code_sp,sp		/* re-load the stack pointer  */
	tstl	_force_loop		/* Is "force_loop" set?       */
	beql	1f
	jmp	_shift_loop		/* then loop on the error     */
1:
	incl	_errcnt;		/* bump the error count      */
	tstl	_prt_error		/* print an error message?   */
	beql	1f
	pushl	_disbl_evt_msg		/* "event while disabled" msg */
	callf	$8,_prt_evt_er_msg	/* print the error message */
1:
	tstl	_halt_flg		/* halt on error?            */
	beql	1f
	pushl	$EVT_MSK_HLT
	callf	$8,_event_halt	 	/* halt with code of 2       */
1:
	tstl	_loop_on_err		/* loop on the error?        */
	beql	1f
	movl	$1,_force_loop		/* set the force_loop flag   */

1:
#########################################################################
# 	THIS IS THE EXIT FROM THIS ROUTINE
# LOOP IF THE FORCE LOOP FLAG IS SET, OTHERWISE EXIT
#########################################################################
_loop_n_leave:
	movl	_rc_code_fp,fp		/* re-load the frame pointer */
	movl	_rc_code_sp,sp		/* re-load the stack pointer */
	tstl	_force_loop		/* Is "force_loop" set?      */
	beql	1f
	jmp	_shift_loop		/* then loop on the error    */
1:
	ret				/* return */






# *************************************************************************
# *
# *			FILL IN THE CODE BUFFER ROUTINE
# *
# *  Set up the instruction code sequence. After the instruction code, 
# *  put a jump back to "execute_code" and fill the rest of the code buffer 
# *  with NOPs.
# *
# *************************************************************************
	.text
	.align	1
	.globl	_fill_code_buff
_fill_code_buff:
	.word	0
	movl	$START_OF_CODE,r0
	movl	r0,_code_addr		/* save the starting address */
	clrl	r1
1:	movb	_inst_buf(r1),(r0)	/* move the code to the code buf */
	incl	r0
	aoblss	$16,r1,1b
########################################################################
# After the instruction code, put a jump back to "_rc_code_return"
########################################################################
	movl	$NOP_JMP,_sgl_dummy1	/* "<nop><nop><jmp><abs addr>" */
	clrl	r1
1:	movb	_sgl_dummy1(r1),(r0)	/* move the code to the code buf */
	incl	r0
	aoblss	$4,r1,1b
  
	moval	_rc_code_return,_sgl_dummy1 /* jmp to 'ex_code_return' */
	clrl	r1
1:	movb	_sgl_dummy1(r1),(r0)	/* move the code to the code buf */
	incl	r0
	aoblss	$4,r1,1b
 
########################################################################
# Fill the rest of the buffer with NOPs and return
########################################################################
	movl	$0x10,r1		/* 0x10 = NOP op-code         */
1:	movb	r1,(r0)			/* put NOPs in the code space */
	aobleq	$END_OF_CODE,r1,1b
	ret				/* return */



########################################################################
# 	Variables
########################################################################
	.align 2
	.globl	_rc_code_sp
_rc_code_sp:				/* save stack pointer value here */
	.long	0
	.globl	_rc_code_fp
_rc_code_fp:				/* save frame pointer value here */
	.long	0

	.globl	return			/* emergency indirect return addr */
return:
	.long	_loop_n_leave		/* return to loop or leave */

########################################################################
#	ERROR MESSAGES
########################################################################
_rc_f_psl_msg:
	.ascii	"final PSL = \0"
_rc_e_psl_msg:
	.ascii	",   expected PSL = \0"
_rc_newline:
	.ascii	" \n\0"

unix.superglobalmegacorp.com

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