|
|
Power 6/32 Unix version 1.2b
#include "data.h"
#include "definitions"
/* Demand paging with 4 operands instruction
EMUL *12(r3)[r4], r5, *12(r6)[r7], *12(r10)[R9]
*/
long exp_psl, exp_result0, exp_result1, saved_vec1, saved_vec2, saved_pte;
long saved_pte2, *opa4, exp_pc, act_pc, act_result0, act_result1, temp_glb;
long d7pc, dummy, act_fvadr;
char *msg1, *msg2;
extern long iob1,iob2,iob3, u0p2pt, pcb0, savvec4, ret_adr, saved_sp, saved_fp;
extern long exp_fvadr, act_fvadr;
dmp5()
{
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:");
dt5();
asm("mtpr $0,$MME");
asm("mtpr $0,$P0LR");
}
dt5()
{ char *byte_ptr;
long ix, byte_no, dummy;
savvec4 = (long)&pcb0;
asm("mtpr _savvec4,$PCBB");
fixpv_pte(P0BR,(TEST_PG-1),&saved_pte,(PTE_V|PTE_UW));
asm("movab prod,_opa4"); /* address of operand 4 */
asm("movab opadr1,_savvec4");
savvec4 = (savvec4 >> PGSHIFT) & 0xfffff; /* Make test area */
fixpv_pte(P0BR,savvec4,&dummy,(PTE_V|PTE_UW)); /* User read/write */
fixpv_pte(P0BR,(savvec4+1),&dummy,(PTE_V|PTE_UW));
for(byte_no=1;byte_no<I5;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<I5;ix++) *byte_ptr++ = EMUL[ix];
*byte_ptr++ = KCALL[0]; /* move KCALL instruction */
*byte_ptr = KCALL[1];
exp_fvadr = (TEST_PG<<PGSHIFT) & 0xfffffc00;
fixpv_pte(P0BR,TEST_PG,&saved_pte,PTE_UW); /* Set V bit off */
asm("movab prot_f5,_savvec4"); /* Set new exception handlers */
set_handler(TRANS_VEC,&saved_vec1,savvec4);
asm("movl fp,_saved_fp"); /* save FP to return */
asm("movab (sp),_savvec4");
savvec4 -= 160; /* KSP is 40 words below ISP */
asm("mtpr _savvec4,$KSP");
exp_psl = PSL_USR; /* PSL : user mode */
asm("pushl _exp_psl"); /* Push PSL on stack */
asm("pushl _exp_pc"); /* Push PC on stack */
opa4[0] = opa4[1] = 0xffffffff; /* result = dummy value */
exp_result0 = 0;
exp_result1 = 6; /* prod = (2*2) + 2 */
asm("movl $1,r4"); /* Set index value */
asm("movl $2,r5"); /* R5 = multiplicand */
asm("movl $1,r7");
asm("movl $1,r9");
asm("movab opadr1,r3"); /* Set base address of operand1 */
asm("movab opadr3,r6"); /* Set base address of operand3 */
asm("movab opadr4,r10"); /* Set base address of operand4 */
asm("mtpr $1,$PACC"); /* Purge all code cache */
asm("movab d7rei,_d7pc");
asm("d7rei:");
asm("rei"); /* Context switch to user */
asm("halt");
asm(".align 2");
asm("rtn_t50:");
asm("movl _saved_fp,fp"); /* restore FP */
break; /* return from error ; stop test */
asm("rtn_t51:");
asm("movl _saved_fp,fp"); /* restore FP */
act_result0 = opa4[0];
act_result1 = opa4[1];
set_handler(CHMK_VEC,&temp_glb,saved_vec2); /* restore CMHK vector */
if ( (act_result0!=exp_result0)||(act_result1!=exp_result1) )
{
msg1 = "** Incorrect result after instruction is restarted.\n";
d2err(msg1,act_result1,exp_result1,exp_pc,d7pc,exp_fvadr);
}
}
}
prot_hdl5()
{
asm(".align 2");
asm("prot_f5:");
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 */
if (act_pc != exp_pc)
{
msg1="** PC pushed on the stack is not correct.\n";
d2err(msg1,act_pc,exp_pc,exp_pc,d7pc,exp_fvadr);
asm("svpctx"); /* Switch to ISP */
asm("jmp rtn_t50");
}
act_fvadr &= 0xfffffc00;
if (act_fvadr != exp_fvadr)
{
msg1="** Fault virtual address pushed on the stack is not correct.\n";
d2err(msg1,act_fvadr,exp_fvadr,exp_pc,d7pc,exp_fvadr);
asm("svpctx"); /* Switch to ISP */
asm("jmp rtn_t50");
}
else
{
asm("movab kcall5,_savvec4"); /* New handler for KCALL */
set_handler(CHMK_VEC,&saved_vec2,savvec4);
/* Restore TRANSLATION fault vector */
set_handler(TRANS_VEC,&dummy,saved_vec1);
/* Validate test page and restart instruction */
fixpv_pte(P0BR,TEST_PG,&saved_pte2,(PTE_V|PTE_UW));
asm("movab d71rei,_d7pc");
asm("d71rei:");
asm("rei");
}
asm(".align 2");
asm("kcall5:");
asm("mtpr $0x1f,$IPL");
asm("svpctx"); /* Switch to ISP */
asm("jmp rtn_t51");
}
TEST_AREA5()
{
asm(".align 2");
asm("opadr1:"); /* r3 point to here */
asm(".space 12"); /* 12 bytes for displacement */
asm(".long op1"); /* r3 point to here after add in displacement */
asm("op1:");
asm(".long 0"); /* indexed by r4 */
asm("mulr:");
asm(".long 2"); /* Multiplier = 2 */
asm("opadr3:"); /* r6 point to here */
asm(".space 12"); /* 12 bytes for displacement */
asm(".long op3"); /* r6 point to here after add in displacement */
asm("op3:");
asm(".long 0"); /* indexed by r7 */
asm("addop:");
asm(".long 2"); /* addend operand = 2 */
asm("opadr4:"); /* r10 point to here */
asm(".space 12"); /* 12 bytes for displacement */
asm(".long op4"); /* r8 point to here after add in displacement */
asm("op4:");
asm(".long 0"); /* indexed by r9 : quadword */
asm(".long 0");
asm("prod:");
asm(".space 16"); /* Quadword for result of EMUL */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.