|
|
Power 6/32 Unix version 1.2b
#include "definitions"
extern long iob0, iob1, iob2, iob3, ss1;
extern long unused, u0p1pt, u0p2pt, scb, savvec4, savvec5, savvec6, savvec7;
extern long *p_ptr, ret_adr, exp_par0, exp_par1, exp_par2, exp_par3;
extern long savvec3 ,act_par0, act_par1, act_par2, act_par3;
extern long Failpc, test_va, Tpsl;
vl_test()
{ long *temp;
if (ss1) writes("** Subtest3 : Limit and translation fault\n");
temp = (long *)0;
asm("mfpr $SBR,_savvec4");
savvec4 |= 0xc0000000;
asm("mtpr _savvec4,$P0BR"); /* Double map P0 into System space */
asm("mfpr $SLR,_savvec4");
asm("mtpr _savvec4,$P0LR");
/* Set up P1PT */
temp = &u0p1pt;
*temp = IOB2; /* 1st PTE in P1 map to IOB2 */
savvec4 = ((long)temp) | SADDR;
asm("mtpr _savvec4,$P1BR");
asm("mtpr $1,$P1LR");
/* Set up P2PT */
temp = &u0p2pt;
*temp = IOB3; /* 1st PTE in P2 map to IOB3 */
savvec4 = ((long)temp) | SADDR;
savvec4 -= (LAST_VPGNO << 2);
asm("mtpr _savvec4, $P2BR");
asm("mtpr $0xffffe, $P2LR"); /* Use only 1 entry */
asm("mtpr $0,$TBIA");
asm("mtpr $0,$PADC");
asm("mtpr $1,$MME");
asm("jmp *$0f"); /* Go virtual */
asm("0:");
limit_chk(); /* Limit test */
vbit_chk(); /* valid bit test */
asm("mtpr $0,$MME"); /* back to physical */
asm("mtpr $0,$P0LR"); /* Invalidate P0 space */
}
limit_chk()
/* this test will validate that TAHOE will detect any off limit
access to SPT, P0PT, P1PT, P2PT.
*/
{
long sys_vadr, fault_vadr, pte_ref, fault_type;
length_chk(SLR, SADDR); /* Test on SPT */
length_chk(P0LR, P0ADDR); /* Test on P0PT */
length_chk(P1LR, P1ADDR); /* Test on P1PT */
length_chk(P2LR, P2ADDR); /* Test on P2PT */
/* Check limit fault on SPT when access P1 space */
asm("mfpr $P1LR,_savvec7"); /* save P1LR */
asm("mtpr $0x1ffff,$P1LR"); /* set P1LR to very large value */
asm("mfpr $SLR,_savvec4");
sys_vadr = ((savvec4+1) << PGSHIFT) | SADDR;
asm("mfpr $P1BR,_savvec4");
fault_vadr = (((unsigned)(sys_vadr-savvec4) >> 2) << PGSHIFT) | P1ADDR;
pte_ref = TRUE;
fault_type = LENGTH;
lmt_fault(fault_vadr, pte_ref, fault_type);
/* restore original SLR, P1LR */
asm("mtpr _savvec7,$P1LR");
}
length_chk(table, space)
long table, space;
{ long fault_vadr, pte_ref, fault_type;
savvec6 = table;
asm("mfpr _savvec6,_savvec4"); /* Get length of table */
if (table==P2LR) savvec4--;
else savvec4++;
fault_vadr = (savvec4<<PGSHIFT)|space;
fault_type = LENGTH;
pte_ref = FALSE;
lmt_fault(fault_vadr, pte_ref, fault_type);
}
vbit_chk()
/* This test force translation not valid fault on SPT, P0PT,
P1PT, P2PT.
*/
{
long fault_vadr, t_pgno, *pt_base, fault_type, pte_ref;
long saved_p1lr;
valid_chk(SBR, TEST_PTESYS, SADDR); /* Test on SPT */
valid_chk(P0BR, TEST_PTEP0, P0ADDR); /* Test on P0PT */
valid_chk(P1BR, TEST_PTEP1, P1ADDR); /* Test on P1PT */
valid_chk(P2BR, TEST_PTEP2, P2ADDR); /* Test on P2PT */
/* Check translation not valid fault on SPT when access P1 space */
asm("mfpr $P1LR,_savvec5");
saved_p1lr = savvec5; /* save P1LR */
asm("mtpr $768,$P1LR"); /* Set P1LR to have 768 PTEs which */
/* is 3 page long. */
/* Virtual addr used to force the fault will need PTE #512 in P1PT */
fault_vadr = (long)((512<<PGSHIFT)|P1ADDR);
/* invalidate PTE in SPT which map 3rd page of P1PT */
asm("mfpr $SBR,_savvec5");
pt_base = (long *)savvec5;
t_pgno = (U0_P1PT) + 2;
pt_base += t_pgno; /* address of PTE in SPT that */
/* mapped the 3rd page of P1PT */
*pt_base = *pt_base & 0x7fffffff; /* Turn off valid bit */
fault_type = VALID;
pte_ref = TRUE;
lmt_fault(fault_vadr, pte_ref, fault_type);
/* restore original SLR, P1LR */
*pt_base = *pt_base | 0x80000000; /* Turn on valid bit */
savvec5 = saved_p1lr;
asm("mtpr _savvec5,$P1LR");
}
valid_chk(table, test_pte, space)
long table, test_pte, space;
{ long *pt_base, saved_pte, fault_vadr, pte_ref, fault_type;
savvec6 = table;
asm("mfpr _savvec6,_savvec5");
pt_base = (long *)savvec5;
pt_base += test_pte; /* address of test PTE */
fault_vadr = (test_pte<<PGSHIFT)|space;
saved_pte = *pt_base; /* save original PTE */
/* Turn off valid bit and set access to User,Kernel R/W */
*pt_base = (*pt_base & 0x7ffffff) | PTE_UW;
fault_type = VALID;
pte_ref = FALSE;
lmt_fault(fault_vadr, pte_ref, fault_type);
*pt_base = saved_pte; /* Restore original PTE */
}
/* Force limit and valid fault */
lmt_fault(fault_vadr, pte_ref, fault_type)
long fault_vadr, pte_ref, fault_type;
{
long saved_vec, *scb_base, lx, *lptr, access;
scb_base = &scb;
if (fault_type == LENGTH)
{
scb_base += PROT_VEC;
/* Make new PTE : If this logic "mkpte" is taken out */
/* and this test passed that imply TAHOE will generate */
/* limit fault before access prot. and translation not */
/* valid fault. */
if (pte_ref==FALSE) mkpte(fault_vadr);
}
else scb_base += TRANS_VEC;
saved_vec = *scb_base; /* save old protection fault vector */
asm("movab handler1,_savvec4");
exp_par1 = fault_vadr; /* Set up expect fault parameters */
test_va = exp_par1;
asm("movpsl _exp_par3"); /* PSL at time of fault */
exp_par3 &= 0xffffffc0; /* Mask out PSW flags */
Tpsl = exp_par3;
asm("movab okret,_ret_adr");
for (access = READ; access <= WRITE; access++)
{
/* length ,R/W violation */
if (fault_type == LENGTH)
exp_par0 = 1 | (access<<2) | (pte_ref<<1);
else
exp_par0 = (access<<2) | (pte_ref<<1);
*scb_base = savvec4; /* Set new handler */
asm("movl _exp_par1,r0");
if (access==WRITE)
{
asm("movab pc_fault1,_exp_par2"); /* PC at fault */
Failpc = exp_par2;
asm("pc_fault1:");
asm("movl $0,(r0)"); /* Try with write access */
}
else
{
asm("movab pc_fault2,_exp_par2"); /* PC at fault */
Failpc = exp_par2;
asm("pc_fault2:");
asm("movl (r0),r12"); /* Try with read access */
}
/* Error if program comes to this point */
if (fault_type == LENGTH)
writes("** Expected limit fault didnot happen\n");
else
writes("** Expected translation fault didnot happen\n");
ac_error1();
*scb_base = saved_vec; /* Restore ILL_ACCESS vector */
asm("halt");
asm("okret:");
*scb_base = saved_vec; /* Restore ILL_ACCESS vector */
if (fault_type == LENGTH)
chk_fpars("** Page Table Limit exception\n");
else
chk_fpars("** Translation not valid exception\n");
}
}
mkpte(flt_vadr)
long flt_vadr;
{ long space, oldpte, pteno, regno;
space = (flt_vadr >> 30) & 0x3;
pteno = (flt_vadr >> PGSHIFT) & 0xfffff;
if (space==3) regno = SBR; /* System */
if (space==2) { regno = P2BR; /* P2 */
pteno = LAST_VPGNO - 2; }
if (space==1) regno = P1BR; /* P1 */
if (space==0) regno = P0BR; /* P0 */
/* All access, V_BIT on */
fixpv_pte(regno,pteno,&oldpte,PTE_KW | PTE_V);
}
prot_handler()
{
asm(".align 2");
asm("handler1:");
asm("movab _act_par0,_p_ptr"); /* Set pointer to fault parameters */
asm("movl (sp)+,_act_par0");
asm("movl (sp)+,_act_par1");
asm("movl (sp)+,_act_par2");
asm("movl (sp)+,_act_par3");
asm("jmp *_ret_adr");
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.