File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / memman / vbit_limit.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
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");
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.