|
|
Power 6/32 Unix version 1.2b
#include "definitions"
/* testing virtual read/write in physical mode
1st unused PTE in SPT is mapped to physical page iob3 (25)
1st PTE in P0PT is mapped to physical page iob0 (22)
1st PTE in P1PT is mapped to physical page iob1 (23)
1st PTE in P2PT is mapped to physical page iob2 (24)
*/
extern long u0p0pt, u0p1pt, u0p2pt, ss1;
extern long unused, iob0, iob1, iob2, iob3, Sysmap;
extern long savvec4, savvec5, savvec6;
char *msg1, *msg2;
long Phys_adr, Fail_pc;
vtest()
{
if (ss1)
writes("** Subtest1 : diagnostic virtual read/write\n");
Fail_pc = 0;
fix_maps(); /* set up SBR,P0PT,P1PT,P2PT */
/* Try to read/write to memory in virtual
mode by using the diagostic intruction
*/
test1_sgl(); /* read/write at single location */
test1_pg(); /* read/write on whole page */
asm("mfpr $SBR,_savvec4"); /* Set up maps to go virtual */
savvec4 |= 0xc0000000;
asm("mtpr _savvec4,$P0BR"); /* Double map P0 in System space */
asm("mfpr $SLR,_savvec4");
asm("mtpr _savvec4,$P0LR");
asm("mtpr $0,$TBIA"); /* Purge all translation buffer */
asm("mtpr $1,$MME"); /* Enable MME */
asm("jmp *$0f"); /* Go !! */
asm("0:");
/* Now program is running running virtual
in P0 space, Kernel privilege
*/
vt1_pg(); /* read/write on whole page */
asm("mtpr $0,$MME"); /* Back to physical */
asm("mtpr $0,$P0LR"); /* invalidate P0BR */
}
/* Test using diagnostic instruction to do virtual read from 1st location
and virtual write to last location in test pages of System, P0, P1, P2
space. Program is running in PHYSICAL mode.
*/
test1_sgl()
{
t1s_sys(); /* test SPT */
t1s_usr(); /* test P0PT, P1PT, P2PT */
}
/* Test using diagnostic instruction to do virtual read/write a page
in System, P0, P1, P2 space. Program is running in PHYSICAL mode.
*/
test1_pg()
{ long loc, *lptr, vaddr;
asm("mtpr $0,$TBIA"); /* Invalidate translation buffers */
asm("mtpr $0,$PADC"); /* Purge data cache */
/* 1st unused virtual page (Set by init.x) in system space
is mapped to physical page of _iob3.
*/
lptr = &unused; /* 1st unused virtual page no. */
loc = ((*lptr)<<PGSHIFT)|SADDR;
t1p_diag(&iob3,loc); /* test in system space */
vaddr = 0|P0ADDR;
t1p_diag(&iob0, vaddr); /* test P0 space */
vaddr = 0|P1ADDR;
t1p_diag(&iob1, vaddr); /* test P1 space */
loc = LAST_VPGNO << PGSHIFT;
vaddr = loc | P2ADDR;
t1p_diag(&iob2, vaddr); /* test P2 space */
}
/* This routine runs in virtual mode and try to read/write to a
page in System, P0, P1, P2 space.
System : 1st unused virtual page is mapped to the physical
page of _iob3.
P0 : Has the same map as system. 1st virtual page is
mapped to physical page of _iob0.
P1 : 1st virtual page is mapped the physical page of
_iob1.
P2 : Last virtual page is mapped the physical page of
_iob2.
*/
vt1_pg()
{
vt1_page(SBR,&iob3); /* test in system space */
vt1_page(P0BR,&iob0); /* test in P0 space */
vt1_page(P1BR,&iob1); /* test in P1 space */
vt1_page(P2BR,&iob2); /* test in P2 space */
}
/* This routine runs in virtual mode and read/write to a page.
Input : page = physical address of 1st longword of the page
that mapped to the test (virtual) page.
space= Space the virtual page is in.
READ test : This routine first disable MME to initialize the test
page with value from 0 to 1023 in physical mode and then turn on
MME to read back virtually and check against the value 0 - 1023.
WRITE test : The same page used in Read test is cleared in physical
mode. The test then turn on MME and write to the test page with
value 0 -1023 and disable MME, read back the contents of the page
in physical mode and compare to 0-1023.
*/
vt1_page(space, page)
long space, page;
{ long *lptr, pte, page_no, v_adr, old_pte, vaddr, access;
int ix;
/* initialize test page with value 0-1023 */
page_no = arithsr(((unsigned)(page & 0x3fffffff)));
asm("mtpr $0,$MME"); /* Disable MME */
write_pg(0,page_no,0,1);
asm("mtpr $1,$MME"); /* Enable MME */
asm("mtpr $0,$PADC"); /* Purge all data cache */
v_adr = 0;
if (space==SBR) {
lptr = &unused;
v_adr = ((*lptr)<<PGSHIFT) & 0x3ffffc00;
vaddr = v_adr | SADDR;
}
if (space==P0BR) {
/* Map 1st PTE in P0BR <or SBR> to iob0 */
pte = arithsr(((unsigned)&iob0)) & 0xfffff;
fixpfn_pte(SBR,0,&old_pte,pte);
access = PTE_V | PTE_UW;
fixpv_pte(SBR,0,&old_pte, access);
vaddr = v_adr | P0ADDR;
}
if (space==P1BR) vaddr = v_adr | P1ADDR;
if (space==P2BR) {
v_adr = LAST_VPGNO << PGSHIFT;
vaddr = v_adr | P2ADDR;
}
vt1_read(vaddr,page); /* This routine read virtual and compare */
asm("mtpr $0,$MME"); /* Disable MME */
write_pg(0,page_no,0,0); /* Clear test page */
asm("mtpr $1,$MME"); /* Enable MME */
if (space==SBR) vt1_write(v_adr|SADDR, &iob3);
if (space==P0BR) {
vt1_write(v_adr|P0ADDR, &iob0);
fixpfn_pte(SBR,0,&old_pte,0);
fixpv_pte(SBR,0,&old_pte, PTE_V | PTE_KW);
}
if (space==P1BR) vt1_write(v_adr|P1ADDR, &iob1);
if (space==P2BR) vt1_write(v_adr|P2ADDR, &iob2);
page_no = page_no;
asm("mtpr $0,$MME"); /* Disable MME */
write_pg(0,page_no,0,0); /* Clear test page */
asm("mtpr $1,$MME"); /* Enable MME */
}
/* This routine runs virtual in user space ,kernel mode. It reads
the contents of the test virtual page and compare to values
0-1023.
Input : v_adr = 1st virtual address of test page
physadr = 1st physical address of test page
*/
vt1_read(v_adr,physadr)
long v_adr, physadr;
{ long *lptr, ix, act_data;
register long *r12, r11;
msg1 = "\n** fail when read whole page virtually ..\n";
msg2 = "";
asm("movab _Fpcr,_Fail_pc");
Phys_adr = physadr;
lptr = (long *)v_adr; /* 1st virtual address */
asm("mtpr $1,$PADC"); /* Purge all data cache */
for (ix=0; ix<NBPG; ix += 4) {
Phys_adr += ix; /* Phys. address of loc. to be read */
r12 = lptr++;
asm("_Fpcr:");
r11 = *r12;
act_data = r11;
if (act_data != ix) error1(msg1,msg2,ix,act_data,lptr-1);
}
}
/* This routine runs virtual in user space ,kernel mode. It writes
the contents of the test virtual page with values 0 - 1023,
then disable map,running physical, reads contents of the test
page back and compares to value 0-1023.
Input : p_adr = physical address of 1st longword of the
test page.
v_adr = virtual address of 1st longword of the
test page.
*/
vt1_write(v_adr, p_adr)
long v_adr, *p_adr;
{ long act_data, *lptr;
register long *r12, ix;
msg1 = "** fail when write whole page ..\n";
msg2 = "";
asm("movab Fpcw,_Fail_pc");
lptr = (long *)v_adr;
for (ix=0; ix<NBPG; ix += 4) {
r12 = lptr++;
asm("Fpcw:");
*r12 = ix; /* write in virtual */
}
asm("mtpr $0,$PADC"); /* Purge all data cache */
asm("mtpr $0,$MME"); /* Disable MME */
lptr = (long *)v_adr;
for (ix=0; ix<NBPG; ix += 4)
{
Phys_adr = (long)p_adr;
act_data = *p_adr++; /* Read in physical mode */
if (act_data != ix) error1(msg1,msg2,ix,act_data,lptr);
lptr++;
}
asm("mtpr $1,$MME"); /* Enable MME */
}
t1s_sys()
{ long *lptr, loc, val, exp_data, act_data;
register long r12;
msg1 = " MTPR $VREAD,$DCR failed\n";
msg2 = " Test on single location\n";
asm("movab _Pcr,_Fail_pc");
/* 1st unused virtual page in system space is mapped to
the physical page of _iob3. Initialize 1st longword
in _iob3 with pattern 0xaaaaaaaa
*/
exp_data = 0xaaaaaaaa;
lptr = (long *)(((long)(&iob3)) & 0xfffffc00);
*lptr = exp_data;
Phys_adr = (long)lptr;
/* Test address : 1st longword in unused virtual page */
loc = (unused << PGSHIFT & 0x3ffffc00) | SADDR;
act_data = vread(loc);
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
/* write last location in iob3 using diagnostic instruction */
msg1 = " MTPR $VWRITE,$DCR failed\n";
asm("movab _Pcw,_Fail_pc");
exp_data = 0xbbbbbbbb;
Phys_adr += 0x3fc;
loc += 0x3fc;
vwrite(loc,exp_data);
lptr += 255; /* address of last longword */
act_data = *lptr;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
}
/* This routine running in PHYSICAL mode and try to use the diagnostic
instruction to do virtual read/write to a page.
Input : v_adr = Virtual address of the 1st longword in the
test page.
test_pg = Physical address of the 1st longword in the
page that is mapped to the test page
READ test : Each location in the test page is initialized with its
unique physical address and then read back virtually using the
diagnostic instruction to check against the physical addresses.
WRITE test : The same page used in Read test is cleared in physical
mode and then using the diagnostic instruction to write virtually
to each location with its unique address. Each location in this page
is then read back in physical mode and check against its the physical
address.
*/
t1p_diag(test_pg, v_adr)
long test_pg, v_adr;
{ long page_no, *lptr, loc, val, exp_data, act_data;
int ix;
/* TEST VIRTUAL READ USING DIAGNOSTIC INSTRUCTION */
msg1 = "\n MTPR $VREAD,$DCR failed \n";
msg2 = " Test with whole page\n";
asm("movab _Pcr,_Fail_pc");
/* initialize each location in test page with its address */
page_no = arithsr(((unsigned)((long)test_pg & 0x3fffffff)));
write_pg(0,page_no,test_pg,1);
loc = v_adr;
for(exp_data=test_pg; exp_data<test_pg+NBPG; exp_data+=4)
{ act_data = vread(loc);
Phys_adr = exp_data;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
else loc += 4;
}
/* TEST VIRTUAL WRITE USING DIAGNOSTIC INSTRUCTION */
msg1 = "\n MTPR $VWRITE,$DCR failed \n";
asm("movab _Pcw,_Fail_pc");
write_pg(0,page_no,0,0); /* clear test page */
loc = v_adr;
/* write to each location its physical address */
for(exp_data=test_pg; exp_data<test_pg+NBPG; exp_data+=4)
{
vwrite(loc,exp_data); /* virtual write in system mode */
loc += 4; }
loc = v_adr; /* virtual location */
lptr = (long *)test_pg; /* mapped to this physical loc */
for(exp_data=test_pg; exp_data<test_pg+NBPG; exp_data+=4)
{
Phys_adr = (long)lptr;
act_data = *lptr++;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
loc += 4;
}
}
/* Routine using the diagnostic instruction to read/write single
locations in P0, P1, P2 space.
*/
t1s_usr()
{ long *lptr, exp_data, loc, val, act_data;
long phys0, phys1, phys2;
/* Virtual Page 0 of P0 is mapped to _iob0, initialize
1st longword in _iob0 with pattern 0xaaaaaaaa */
exp_data = 0xaaaaaaaa;
lptr = (long *)(((long)(&iob0)) & 0xfffffc00);
*lptr = exp_data;
phys0 = (long)lptr; /* Physical addr of test location */
/* Virtual Page 0 of P1 is mapped to _iob1, initialize
1st longword in _iob1 with pattern 0xbbbbbbbb */
exp_data = 0xbbbbbbbb;
lptr = (long *)(((long)(&iob1)) & 0xfffffc00);
*lptr = exp_data;
phys1 = (long)lptr; /* Physical addr of test location */
/* Last Virtual Page of P2 is mapped to _iob2, initialize
1st longword in _iob2 with pattern 0xcccccccc */
exp_data = 0xcccccccc;
lptr = (long *)(((long)(&iob2)) & 0xfffffc00);
*lptr = exp_data;
phys2 = (long)lptr; /* Physical addr of test location */
/* now use diagnostic inst. to read them in virtual mode */
msg1 = "\n MTPR $VREAD,$DCR failed \n";
msg2 = " Test on single location\n";
asm("movab _Pcr,_Fail_pc");
Phys_adr = phys0; /* Physical addr of test location */
loc = 0|P0ADDR;
act_data = 0;
act_data = vread(loc); /* read in P0 space */
exp_data = 0xaaaaaaaa;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
Phys_adr = phys1; /* Physical addr of test location */
loc = 0|P1ADDR;
act_data = 0;
act_data = vread(loc); /* read in P1 space */
exp_data = 0xbbbbbbbb;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
Phys_adr = phys2; /* Physical addr of test location */
loc = (LAST_VPGNO << PGSHIFT) | P2ADDR;
act_data = 0;
act_data = vread(loc); /* read in P2 space */
exp_data = 0xcccccccc;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
/* Virtual Page 0 of P0 is mapped to _iob0, try to use
the diagnostic instruction to write to last longword
in _iob0 with pattern 0x11111111.
*/
asm("movab _Pcw,_Fail_pc");
msg1 = " MTPR $VWRITE,$DCR failed\n";
exp_data = 0x11111111; /* Write last location in P0 */
lptr = (long *)((((long)(&iob0)) & 0xfffffc00) + 0x3fc);
Phys_adr = (long)lptr; /* Physical addr of test location */
loc = (0 | P0ADDR) + 0x3fc; /* equivalent virtual address */
vwrite(loc,exp_data);
act_data = *lptr;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
/* Virtual Page 0 of P1 is mapped to _iob1, try to use
the diagnostic instruction to write to last longword
in _iob1 with pattern 0x22222222.
*/
exp_data = 0x22222222; /* Write last location in P1 */
lptr = (long *)((((long)(&iob1)) & 0xfffffc00) + 0x3fc);
Phys_adr = (long)lptr; /* Physical addr of test location */
loc = (0 | P1ADDR) + 0x3fc; /* equivalent virtual address */
vwrite(loc,exp_data);
act_data = *lptr;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
/* Virtual Page 0 of P2 is mapped to _iob2, try to use
the diagnostic instruction to write to last longword
in _iob2 with pattern 0x33333333.
*/
exp_data = 0x33333333; /* Write last location in P2 */
lptr = (long *)((((long)(&iob2)) & 0xfffffc00) + 0x3fc);
Phys_adr = (long)lptr; /* Physical addr of test location */
loc = ( (LAST_VPGNO << PGSHIFT) | P2ADDR) + 0x3fc;
vwrite(loc,exp_data);
act_data = *lptr;
if (exp_data != act_data)
error1(msg1,msg2,exp_data,act_data,loc);
}
/* This routine fix SBR, P0PT, P1PT, P2PT as follow :
SBR : map 1st unused virtual page in System map to
the physica page of _iob3.
P0PT: map virtual page 0 of P0 space to the physical
page of _iob0
P1PT: map virtual page 0 of P1 space to the physical
page of _iob1
P2PT: map last virtual page of P2 space to the physical
page of _iob2
*/
fix_maps()
{
long *temp, pte, pfn, lx;
long *lptr, pte_no, old_pte0, old_pte1, access;
/* Fix up System Page Table */
lptr = &unused;
pte_no = *lptr;
pte = arithsr(((unsigned)&iob3)) & 0xfffff;
fixpfn_pte(SBR,pte_no,&old_pte0,pte);
access = PTE_V | PTE_KW;
fixpv_pte(SBR,pte_no,&old_pte1, access);
/* Set up P0PT */
lx = arithsr(((unsigned)(&iob0) & 0x3ffffc00)) ;
pfn = lx & 0xfffff;
pte = pfn | (PTE_V | PTE_UW);
temp = &u0p0pt;
*temp = pte; /* 1st page in P0 mapped to IOB0 */
savvec4 = ((long)temp) | SADDR; /* system virtual address */
asm("mtpr _savvec4,$P0BR");
asm("mtpr $1,$P0LR");
/* Set up P1PT */
lx = arithsr(((unsigned)(&iob1) & 0x3ffffc00)) ;
pfn = lx & 0xfffff;
pte = pfn | (PTE_V | PTE_UW);
temp = &u0p1pt;
*temp = pte; /* 1st page in P1 mapped to IOB1 */
savvec4 = ((long)temp) | SADDR;
asm("mtpr _savvec4,$P1BR");
asm("mtpr $1,$P1LR");
/* Set up P2PT */
lx = arithsr(((unsigned)(&iob2) & 0x3ffffc00)) ;
pfn = lx & 0xfffff;
pte = pfn | (PTE_V | PTE_UW);
temp = &u0p2pt;
*temp = pte; /* 1st PTE in P2 mapped to IOB2 */
savvec4 = ((long)temp) | SADDR;
savvec4 -= (LAST_VPGNO << 2); /* This is how P2BR works !! */
asm("mtpr _savvec4 ,$P2BR");
asm("mtpr $0xffffe,$P2LR"); /* use only 1 entry */
asm("mtpr $0,$TBIA"); /* invalidate all cache */
}
extern long dummy;
arithsr(num)
long num;
{
asm("shar $10,4(fp),_dummy");
return(dummy);
}
error1(mss1,mss2,exp,act,loc)
char *mss1, *mss2;
long exp, act, loc;
{ register long r12;
writes(mss1); writes(mss2);
writes("** PC : "); writeh(Fail_pc); writec('\n');
writes("** VA of test loc. : "); writeh(loc); writec('\n');
writes("** PA of test loc. : "); writeh(Phys_adr); writec('\n');
writes("** Expected data : "); writeh(exp); writec('\n');
writes("** Actual data : "); writeh(act); writec('\n');
prt_base(loc); /* Print base registers */
asm("halt");
}
/* THESE FOLLOWING ROUTINES USE THE DIANOSTIC CONTROL REGISTER
TO DO VIRTUAL READ/WRITE WHILE RUNNING IN PHYSICAL MODE
*/
int vread(loc) /* virtual read in user mode */
long loc;
{
savvec5 = loc;
asm("movl _savvec5,r0"); /* R0 : virtual address to read */
asm("_Pcr:");
asm("mtpr $4,$DCR"); /* 4 : Read opcode */
asm("movl r1,_savvec5"); /* R1 : read data */
return(savvec5);
}
vwrite(loc,val) /* virtual write in user mode */
long loc, val;
{
savvec5 = loc;
savvec6 = val;
asm("movl _savvec5,r0"); /* R0 : virtual address to write */
asm("movl _savvec6,r1"); /* R1 : data to write */
asm("_Pcw:");
asm("mtpr $8,$DCR"); /* 8 : Write opcode */
}
prt_base(va)
long va;
{ register long r12;
asm("mfpr $MME,r12");
writes("** MME : "); writeh(r12); writec('\n');
asm("mfpr $SBR,r12");
writes("** SBR : "); writeh(r12); writec('\n');
asm("mfpr $SLR,r12");
writes("** SLR : "); writeh(r12); writec('\n');
if ((va&0xc0000000)==0) {
asm("mfpr $P0BR,r12");
writes("** P0BR : "); writeh(r12); writec('\n');
asm("mfpr $P0LR,r12");
writes("** P0LR : "); writeh(r12); writec('\n');
}
if ((va&0xc0000000)==0x40000000) {
asm("mfpr $P1BR,r12");
writes("** P1BR : "); writeh(r12); writec('\n');
asm("mfpr $P1LR,r12");
writes("** P1LR : "); writeh(r12); writec('\n');
}
if ((va&0xc0000000)==0x80000000) {
asm("mfpr $P2BR,r12");
writes("** P2BR : "); writeh(r12); writec('\n');
asm("mfpr $P2LR,r12");
writes("** P2LR : "); writeh(r12); writec('\n');
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.