File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / demand / dmp0.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b

#include "data.h"
#include "definitions"

/* 		Demand paging with auto_decrement mode
   Boundery of virtual Page _iob0 and _iob1 are used in this test. USP is set to
   1st byte of page _iob1, PTE of Page _iob0 is then set to invalid.  Program do
   a REI to user code which will execute the "clrl -(sp)" instruction . At
   this point translation not valid fault should occur and the exception
   handler will set page _iob0 to valid and do a REI to restart the instruction.
*/

long exp_psl, exp_pc, act_pc, exp_result, act_result, exp_sp, act_sp;
long d1rei, *fault_vadr, saved_vec1, saved_vec2, saved_pte, temp_glb;
char *msg1, *msg2;

extern long iob1, iob2, iob3, u0p2pt, pcb0, savvec4, savvec5, savvec6, savvec7;
extern long ret_adr, saved_sp, saved_fp, *p_ptr;

dmp0()
{
	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:");
	dpt1();
	asm("mtpr $0,$MME");
	asm("mtpr $0,$P0LR");
}


dpt1()
{
	long ix;

	savvec4 = (long)&pcb0;
	asm("mtpr _savvec4,$PCBB");		/* Set PCBB */
	asm("movab fault_pc1,_savvec4");
	savvec4 = (savvec4 >> PGSHIFT) & 0xfffff;
	fixpv_pte(P0BR,savvec4,&saved_pte,(PTE_V|PTE_UW));
	fixpv_pte(P0BR,(savvec4+1),&saved_pte,(PTE_V|PTE_UW));

	asm("movab fault_pc1,_exp_pc");
	exp_sp = TEST_PG << PGSHIFT;
	fault_vadr = (long *) (exp_sp-4);
	*fault_vadr = 0xfffffff;	/* set some value in test location */
	exp_result = 0;

	/* Set page _iob1 to valid	*/
	fixpv_pte(P0BR,TEST_PG,&saved_pte,(PTE_V|PTE_UW));
	/* Set page _iob0 to invalid	*/
	fixpv_pte(P0BR,(TEST_PG-1),&saved_pte,PTE_UW);

	/* Set new exception handlers  */
	asm("movab trans_f1,_savvec4");
	set_handler(TRANS_VEC,&saved_vec1,savvec4);

	asm("movab (sp),_savvec4");
	savvec4 -= 16;				/* KSP is 4 words below ISP */
	asm("mtpr _savvec4,$KSP");

	exp_psl = PSL_USR;			/* User mode          */
	asm("mtpr _exp_sp,$USP");	   	/* Set USP to valid page */
	asm("movl fp,_saved_fp");		/* save FP to return  */
	asm("pushl _exp_psl");
	asm("pushl _exp_pc");			/* Push PSL,PC for REI */
	asm("mtpr $1,$PACC");			/* Purge all code cache */
	asm("movab d2pc,_d1rei");
asm("d2pc:");
	asm("rei");
	asm("halt");

asm(".align 2");
asm("rtn_t10:");
	asm("movl _saved_fp,fp");		/* restore FP */
	if (1) return;			/* Avoid warning from compiler */
asm(".align 2");
asm("rtn_t11:");
	asm("movl _saved_fp,fp");		/* restore FP */
	act_result = *fault_vadr;
	if (act_result != exp_result)
		{
		msg1 = "** incorrect result after instruction is restarted.\n";
		d3err(msg1,act_result,exp_result,exp_pc,d1rei);
		}
	set_handler(CHMK_VEC,&temp_glb,saved_vec2);  /* Restore KCALL vector */
}

TEST_AREA()
{
asm("fault_pc1:");
	asm("clrl -(sp)");	/* should cause translation not valid fault */
	asm("kcall $0");	/* return */
}

new_hdr1()
{
asm(".align	2");			/* Longword align */
asm("trans_f1:");

	asm("mtpr $0x1f,$IPL");
	asm("movl (sp)+,r12");		/* Ignore 1st parameter */
	asm("movl (sp)+,r12");		/* Ignore 2nd parameter */
	asm("movl (sp),_act_pc");	/* PC that caused fault */
	asm("movab (sp),fp");		/* set new frame pointer */
	asm("mfpr $USP,_act_sp");
	if ( act_pc != exp_pc )
		{	/* Error in PC */
		msg1="\nPC pushed on the stack is not correct.";
		d3err(msg1,act_pc,exp_pc,exp_pc,d1rei);
		asm("svpctx");			/* Back to ISP */
		asm("jmp  rtn_t10");		/* return   */
		}
	   else
		{
		if ( exp_sp != act_sp )
			{
			msg1 = "\nSP is not backed up correctly.";
			d3err(msg1,act_sp,exp_sp,exp_pc,d1rei);
			asm("svpctx");			/* Back to ISP */
			asm("jmp  rtn_t10");		/* return   */
			}
		    else
			{
			/* Set V bit and restart instruction at PC */
			fixpv_pte(P0BR,(TEST_PG-1),&saved_pte,(PTE_V|PTE_UW));
	   		/* New handler for KCALL */
			asm("movab kcall1,_savvec4");
			set_handler(CHMK_VEC,&saved_vec2,savvec4);
			/* restore original vector of TRANSLATION fault  */
			set_handler(TRANS_VEC,&temp_glb,saved_vec1);
			asm("movab d21pc,_d1rei");
asm("d21pc:");
			asm("rei");
			asm("halt");
			}
		}

asm(".align 2");
asm("kcall1:");
	asm("mtpr $0x1f,$IPL");
	asm("svpctx");			/* Back to ISP */
	asm("jmp rtn_t11");	
}

d3err(msg1,act,exp,pc,reipc)
char *msg1;
long act, exp, pc, reipc;
{
	writes(msg1);
	writes("\n** Actual   : "); writeh(act); 
	writes("\n** Expect   : "); writeh(exp);
	writes("\n** PC                   : "); writeh(pc);
	writes("\n** PC (REI instruction) : "); writeh(reipc);
	writec('\n');
	asm("halt");
}

unix.superglobalmegacorp.com

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