File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / demand / dmp5.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 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 */

}


unix.superglobalmegacorp.com

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