|
|
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" */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.