|
|
Power 6/32 Unix version 1.2b
#include "data.h"
#include "definitions"
long exp_psl, exp_pc, act_pc, exp_result, act_result, exp_sp, act_sp;
long dummy, *opr_adr, *fault_vadr, saved_vec1, saved_vec2, saved_pte, temp_glb;
long d6pc;
extern long exp_fvadr, act_fvadr;
char *msg1, *msg2, *bptr;
extern long iob1, iob2, iob3, u0p2pt, pcb0, savvec4, savvec5, savvec6, savvec7;
extern long ret_adr, saved_sp, saved_fp, *p_ptr;
/* Demand paging with longword relative deferred indexed
Boundery of virtual Page _iob0 and _iob1 are used in this test. Opcodes of
the "clrl *loc[r6]" instruction (loc is 1 page away from PC) is moved
to last byte in page _iob0 and operand specifiers are moved to 1st bytes
in page _iob1. PTE of Page _iob1 is then set to invalid.
*/
dmp4()
{
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:");
dpt4();
asm("mtpr $0,$MME");
asm("mtpr $0,$P0LR");
}
dpt4()
{ char *byte_ptr;
long ix, byte_no;
savvec4 = (long)&pcb0;
asm("mtpr _savvec4,$PCBB"); /* Set PCBB */
asm("movab act_opr,_savvec4"); /* Make test loc user R/W */
savvec4 = (savvec4 >> PGSHIFT) & 0xfffff;
fixpv_pte(P0BR,savvec4,&saved_pte,(PTE_V|PTE_UW));
for(byte_no=1;byte_no<I4;byte_no++)
{
/* Move code to boundery of test page */
exp_pc = ((TEST_PG-1)<<PGSHIFT)|(NBPG-byte_no);
byte_ptr = (char *)exp_pc;
for(ix=0;ix<I4;ix++) *byte_ptr++ = CLRL4[ix];
bptr = byte_ptr - 1; /* Point to last byte : displacement */
*byte_ptr++ = KCALL[0]; /* move KCALL instruction */
*byte_ptr = KCALL[1];
/* Compute address of operand */
opr_adr = (long *) (exp_pc + I4); /* PC after fetching instruction */
opr_adr = (long *)((long)opr_adr+NBPG-4); /* PC after add in displ. */
/* Make data longword align */
switch ( ((long)opr_adr) & 0x3)
{
case 1 : { opr_adr = (long *)( (long)opr_adr + 3);
*bptr = 0xff; /* Modify displacement */
break; }
case 2 : { opr_adr = (long *)( (long)opr_adr + 2);
*bptr = 0xfe; /* Modify displacement */
break; }
case 3 : { opr_adr = (long *)( (long)opr_adr + 1);
*bptr = 0xfd; /* Modify displacement */
break; }
}
savvec6 = (long)opr_adr; /* Make base addr user READ/WRITE */
savvec6 = (savvec6 >> PGSHIFT) & 0xfffff;
fixpv_pte(P0BR,savvec6,&saved_pte,(PTE_V|PTE_UW));
fixpv_pte(P0BR,(savvec6+1),&saved_pte,(PTE_V|PTE_UW));
asm("movab bopr_t4,_savvec4");
asm("movl _savvec4,*_opr_adr"); /* Set base addr of operand */
asm("movl $0xffffffff,act_opr"); /* Set dummy value in operand */
fixpv_pte(P0BR,(TEST_PG-1),&saved_pte,(PTE_V|PTE_UW));
/* Invalidate PTE of test page */
exp_fvadr = (TEST_PG<<PGSHIFT) & 0xfffffc00;
fixpv_pte(P0BR,TEST_PG,&saved_pte,PTE_UW);
/* Set new exception handlers */
asm("movab trans_f4,_savvec4");
set_handler(TRANS_VEC,&saved_vec1,savvec4);
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_result = 0;
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 *loc[r6] */
asm("movl $1,r6"); /* Set index value in r6 */
asm("mtpr $1,$PACC"); /* Purge all code cache */
asm("movab d6rei,_d6pc");
asm("d6rei:");
asm("rei");
asm("halt");
asm(".align 2");
asm("rtn_t40:"); /* Return from error */
asm("movl _saved_fp,fp"); /* restore FP */
break;
asm("rtn_t41:");
asm("movl _saved_fp,fp"); /* restore FP */
asm("movl act_opr,_act_result"); /* Get actual result */
if (act_result != exp_result)
{
msg1 = "** Incorrect result after instruction is restarted.\n";
d2err(msg1,act_result,exp_result,exp_pc,d6pc,exp_fvadr);
}
set_handler(CHMK_VEC,&dummy,saved_vec2); /* Restore KCALL vector */
}
}
new_hdr4()
{
asm(".align 2"); /* Longword align */
asm("trans_f4:");
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"); /* PC that caused fault */
asm("movab (sp),fp"); /* set new frame pointer */
if ( act_pc != exp_pc )
{ /* Error in PC */
msg1="** PC pushed on the stack is not correct.\n";
d2err(msg1,act_pc,exp_pc,exp_pc,d6pc,exp_fvadr);
asm("svpctx"); /* Back to ISP */
asm("jmp rtn_t40"); /* return */
}
if ( (act_fvadr & 0xfffffc00) != (exp_fvadr & 0xfffffc00) )
{ /* Error in PC */
msg1="** Fault virtual address pushed on the stack is not correct\n";
d2err(msg1,(act_fvadr&0xfffffc00),(exp_fvadr&0xfffffc00),exp_pc,d6pc,exp_fvadr);
asm("svpctx"); /* Back to ISP */
asm("jmp rtn_t40"); /* return */
}
else
{
/* Set V bit and restart instruction at PC */
fixpv_pte(P0BR,TEST_PG,&saved_pte,(PTE_V|PTE_UW));
asm("movab kcall4,_savvec4"); /* New handler for KCALL */
set_handler(CHMK_VEC,&saved_vec2,savvec4);
/* restore original vector of TRANSLATION fault */
set_handler(TRANS_VEC,&temp_glb,saved_vec1);
asm("movab d61rei,_d6pc");
asm("d61rei:");
asm("rei");
asm("halt");
}
asm(".align 2");
asm("kcall4:");
asm("mtpr $0x1f,$IPL");
asm("svpctx"); /* Back to ISP */
asm("jmp rtn_t41");
}
t_area4()
{
asm(".align 2");
asm("bopr_t4:");
asm(".long 0");
asm("act_opr:");
asm(".long 0"); /* Actual operand */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.