|
|
Power 6/32 Unix version 1.2b
#include "data.h"
#include "definitions"
extern long savvec4, iob1, iob2, pcb0;
/* Demand paging with longword displacement deferred indexed.
Intruction used for this test is CLRL *12(R5)[r6]. This test force
a translation fault at AG level (2nd). To compute the effective
address of operand, content of R5 is added by 12 bytes (displacement)
to give an indirect address which is then fetched and indexed by R6
to give the operand address. This test force a fault by setting the
PTE of the indirect address to invalid and then the fault handler
will valid this PTE (turn V_bit on) and restart the instruction.
*/
long dummy, exp_pc, act_pc, exp_psl, exp_val, act_val;
long d8pc, tst_pte, saved_vec1, saved_vec2, saved_pte1, saved_pte2, saved_pte3;
extern long exp_fvadr, act_fvadr;
char *msg1, *msg2;
dmp6()
{
asm("mfpr $SBR,_savvec4");
savvec4 |= (savvec4 | SADDR); /* Make it system address */
asm("mtpr _savvec4,$P0BR"); /* Double map P0PT to SPT */
asm("mfpr $SLR,_savvec4");
asm("mtpr _savvec4,$P0LR");
asm("mtpr $6,$DCK");
asm("mtpr $0,$TBIA");
asm("mtpr $0,$PADC");
asm("mtpr $1,$MME"); /* Enable MME */
asm("jmp *$0f"); /* Go virtual */
asm("0:");
tst_dmp6();
asm("mtpr $0,$MME"); /* Disable MME */
asm("mtpr $0,$P0LR");
}
tst_dmp6()
{ char *byte_ptr, *msg1, *msg2;
long ix, hdr_adr, pc_err, byte_no;
savvec4 = (long)&pcb0;
asm("mtpr _savvec4,$PCBB"); /* Initialize PCBB */
/* Move code to boundery of page */
exp_pc = ((TEST_PG-1)<<PGSHIFT)|(NBPG-1);
byte_ptr = (char *)exp_pc;
for(ix=0;ix<I3;ix++) *byte_ptr++ = CLRL3[ix];
*byte_ptr++ = KCALL[0]; /* move KCALL instruction */
*byte_ptr = KCALL[1];
/* Make code area user accessible */
fixpv_pte(P0BR,(TEST_PG-1),&saved_pte1,(PTE_V|PTE_UW));
fixpv_pte(P0BR,TEST_PG,&saved_pte2,(PTE_V|PTE_UW));
/* Make operand user accessible */
asm("movab operd,_dummy");
dummy = (dummy >> PGSHIFT) & 0xfffff; /* Page no */
fixpv_pte(P0BR,dummy,&saved_pte3,(PTE_V|PTE_UW));
/* Invalidate PTE of indirect address */
asm("movab indr_adr,_tst_pte");
exp_fvadr = tst_pte; /* Expected VA at fault */
tst_pte = (tst_pte >> PGSHIFT) & 0xfffff; /* Page no */
fixpv_pte(P0BR,tst_pte,&saved_pte3,PTE_UW); /* Set PTE_V off */
/* Set new exception handlers */
asm("movab prot_f3,_savvec4");
set_handler(TRANS_VEC,&saved_vec1,savvec4);
/* Set up to execute REI */
asm("movab (sp),_savvec4");
savvec4 -= 16; /* KSP is 4 words below ISP */
asm("mtpr _savvec4,$KSP");
asm("movl fp,_saved_fp"); /* save FP to return */
exp_psl = PSL_USR; /* PSL : user mode */
asm("pushl _exp_psl"); /* Push PSL on stack */
asm("pushl _exp_pc"); /* Push PC on stack */
/* Set up for CLRL *12(r5)[r6] */
asm("movab r5_here,r5");
asm("movl $1,r6"); /* Set index value in r6 */
asm("movl $0xfffffff,operd");
exp_val = 0;
/* Use REI to switch to user mode */
asm("mtpr $1,$PACC"); /* Purge all code cache */
asm("movab d8rei,_d8pc");
asm("d8rei:");
asm("rei");
asm("halt");
asm(".align 2");
asm("rtn_t30:"); /* Return here if error */
asm("movl _saved_fp,fp"); /* restore FP */
return(0); /* Stop test */
asm("rtn_t31:");
asm("movl _saved_fp,fp"); /* restore FP */
asm("movl operd,_act_val");
set_handler(CHMK_VEC,&dummy,saved_vec2); /* restore handler */
if (exp_val != act_val) /* Demand paging fail !! */
{
msg1="** Incorrect result after instruction is restarted.\n";
d2err(msg1,act_val,exp_val,exp_pc,d8pc,exp_fvadr);
}
}
prot_hdl6()
{
asm(".align 2");
asm("prot_f3:");
asm("mtpr $0x1f,$IPL");
asm("movl (sp)+,r12"); /* Ignore 1st parameter */
asm("movl (sp)+,_act_fvadr"); /* Actual VA at fault */
asm("movl (sp),_act_pc"); /* Actual PC that caused fault */
asm("movab (sp),fp"); /* Set FP */
/* Check fault parameters */
if (act_pc != exp_pc) /* Check PC pushed on SP */
{
msg1="** PC pushed on the stack is not correct.\n";
d2err(msg1,act_pc,exp_pc,exp_pc,d8pc,exp_fvadr);
asm("svpctx"); /* Switch to ISP */
asm("jmp rtn_t30"); /* Error return */
}
if (act_fvadr != exp_fvadr) /* Check fault VA pushed on SP */
{
msg1="** Fault virtual address pushed on the stack is not correct.\n";
d2err(msg1,act_fvadr,exp_fvadr,exp_pc,d8pc,exp_fvadr);
asm("svpctx"); /* Switch to ISP */
asm("jmp rtn_t30"); /* Error return */
}
/* Restore original Translation fault vector */
set_handler(TRANS_VEC,&dummy,saved_vec1);
asm("movab kcall3,_savvec4"); /* New handler for KCALL */
set_handler(CHMK_VEC,&saved_vec2,savvec4);
/* Validate PTE of indirect addr and restart instruction */
fixpv_pte(P0BR,tst_pte,&dummy,(PTE_V|PTE_UW));
asm("movab d81rei,_d8pc");
asm("d81rei:");
asm("rei");
asm(".align 2");
asm("kcall3:"); /* KCALL handler */
asm("mtpr $0x1f,$IPL");
asm("svpctx"); /* Switch to ISP */
asm("jmp rtn_t31"); /* Return */
}
t6_space()
{
/* Operand of CLRL *12(r5)[r6] */
asm(".space 1024"); /* Make sure this area is in next page */
asm(".align 2");
asm("r5_here:");
asm(".space 12"); /* 12 bytes for displacement */
asm("indr_adr:");
asm(".long base_op");
asm(".space 1024"); /* Make sure nothing else is in this page */
asm(".data"); /* This is in DATA area */
asm(".align 2");
asm("base_op:");
asm(".long 0xffff"); /* four bytes for index by r6 */
asm(".globl operd");
asm("operd:");
asm(".long 0xffffffff");
/* this loc will be clear when inst. is restarted */
asm(".text");
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.