|
|
Power 6/32 Unix version 1.21
#include "fpp_defs.h"
#define TBL_SIZE 1024 /* size of the prom table */
/*****************************************************************************
*
* MTPR - TEST THE "READ TABLE DATA" MTPR INSTRUCTION
*
* This test checks the ability to use an MTPR to the Diagnostic Control
* Register (DCR) to read an entry in the FPP tables.
*
* The instruction is:
* MTPR $2048,$DCR
* R0 = the table address to check
*
* The MTPR instruction will put the table data into R1.
*
*****************************************************************************/
mtpr_tst()
{
asm(".globl _mtpr_t");
asm("_mtpr_t:"); /* entry address */
if( (cycle == 1) && (prt_hdrs) ) /* print headers on 1st cycle */
writes(" MTPR");
mtpr_1(); /* read w/ sgl accumulator */
mtpr_2(); /* read w/ dbl accumulator */
mtpr_3(); /* read during "sinf" */
asm("jmp *return"); /* return to the test monitor */
}
/************************************************************************
*
* SUBTEST 1 - Read the tables with a single precision accumulator
*
************************************************************************/
mtpr_1()
{
force_loop = FALSE;
subtest = 1;
index = 0;
for( sgl_value_1 = 0; sgl_value_1 < TBL_SIZE; sgl_value_1++ ) {
sgl_ld_acc = ldf_1_data[index].ld; /* get a sgl value */
sgl_expected = ldf_1_data[index].exp; /* & expected acc. */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_mtpr_1_lp1:");
asm("ldf _sgl_ld_acc"); /* load the accumulator */
asm("movl _sgl_value_1,r0"); /* move table address to r0 */
asm("clrl r1"); /* clear R1 */
asm("mtpr $0x800,$27"); /* read the table entry */
asm("stf _sgl_st_acc"); /* save the accumulator */
asm("movl r1,_sgl_value_2"); /* save the value read */
if( force_loop )
asm("brb _mtpr_1_lp1");; /* loop on the error */
/*
* end error loop
*/
if( sgl_st_acc != sgl_expected ) { /* verify the accumulator */
errcnt++; /* bump the error count */
if( prt_error )
print_mtpr_error(
" (SGL Accumulator) -THE ACC WAS MODIFIED");
if( halt_flg )
mtpr_er_halt( 2 );
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mtpr_1_lp1"); /* and loop */
}
} /* end of compare error */
if( ++index > max_ldf_1_index )
index = 0; /* reset the Acc's index */
}
} /* end of subtest 1 */
/************************************************************************
*
* SUBTEST 2 - Read the tables with a double precision accumulator
*
************************************************************************/
mtpr_2()
{
force_loop = FALSE;
subtest = 2;
index = 0;
for( sgl_value_1 = 0; sgl_value_1 < TBL_SIZE; sgl_value_1++ ) {
dbl_ld_acc = ldd_1_data[index].ld; /* get a dbl value */
dbl_expected = ldd_1_data[index].exp; /* & expected acc. */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_mtpr_2_lp1:");
asm("ldd _dbl_ld_acc"); /* load the accumulator */
asm("movl _sgl_value_1,r0"); /* move table address to r0 */
asm("clrl r1"); /* clear R1 */
asm("mtpr $0x800,$27"); /* read the table entry */
asm("std _dbl_st_acc"); /* save the accumulator */
asm("movl r1,_sgl_value_2"); /* save the value read */
if( force_loop )
asm("brb _mtpr_2_lp1");; /* loop on the error */
/*
* end error loop
*/
if( (dbl_st_acc.m != dbl_expected.m) || /* verify the acc. */
(dbl_st_acc.l != dbl_expected.l) ) {
errcnt++; /* bump the error count */
if( prt_error )
print_mtpr_error(
" (DBL Accumulator) -THE ACC WAS MODIFIED");
if( halt_flg )
mtpr_er_halt( 2 );
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mtpr_2_lp1"); /* and loop */
}
} /* end of compare error */
if( ++index > max_ldf_1_index )
index = 0; /* reset the Acc's index */
}
} /* end of subtest 2 */
/************************************************************************
*
* SUBTEST 3 - Read table data during a SINF function
*
* Read every 10th table entry while doing SINF's.
* Read the entry once, read it again during a SINF, verify that the SINF
* result is correct and that the same table data was read.
************************************************************************/
mtpr_3()
{
int max_index;
force_loop = FALSE;
subtest = 3;
max_index = TBL_SIZE / 10;
if( max_index > max_sinf_1_index ) /* don't go over the SIN data */
max_index = max_sinf_1_index; /* set the max index value */
for( index = 0; index < max_sinf_1_index; index++ ) {
sgl_value_1 = index * 10; /* get table entry to read */
sgl_ld_acc = sinf_1_data[index].ld; /* get a sgl value */
sgl_expected = sinf_1_data[index].exp; /* & expected acc. */
asm("movl _sgl_value_1,r0"); /* move table address to r0 */
asm("clrl r1"); /* clear R1 */
asm("mtpr $0x800,$27"); /* read the table entry */
asm("movl r1,_sgl_value_3"); /* save the value read */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_mtpr_3_lp1:");
asm("ldf _sgl_ld_acc"); /* load the accumulator */
asm("movl _sgl_value_1,r0"); /* move table address to r0 */
asm("clrl r1"); /* clear R1 */
asm("sinf"); /* start the SIN function */
asm("mtpr $0x800,$27"); /* read the table entry */
asm("stf _sgl_st_acc"); /* save the accumulator */
asm("movl r1,_sgl_value_2"); /* save the value read */
if( force_loop )
asm("brb _mtpr_3_lp1");; /* loop on the error */
/*
* end error loop
*/
if( sgl_value_2 != sgl_value_3 ) { /* verify the data read */
errcnt++; /* bump the error count */
if( prt_error )
print_mtpr_error( bad_tbl_entry_msg );
if( halt_flg )
mtpr_er_halt( 1 );
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mtpr_3_lp1"); /* and loop */
}
} /* end of table data compare error */
if( sgl_st_acc != sgl_expected ) { /* verify the accumulator */
errcnt++; /* bump the error count */
if( prt_error )
print_mtpr_error(" -BAD FINAL ACC");
if( halt_flg )
mtpr_er_halt( 3 );
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mtpr_3_lp1"); /* and loop */
}
} /* end of SINF compare error */
if( ++index > max_sinf_1_index )
index = 0; /* reset the Acc's index */
}
} /* end of subtest 3 */
/******************************************************************************
*
* Print an error message of the form:
*
* cycle: xx MTPR test xx, subtest xx <your message here>
* table index = xxxxxxxx, table entry read = xxxxxxxx (2nd read)
* expected entry = xxxxxxxx (1st read)
* or
* cycle: xx MTPR test xx, subtest xx <your message here>
* table index = xxxxxxxx, table entry = xxxxxxxx
* initial Acc = xxxxxxxx xxxxxxxx, final Acc = xxxxxxxx xxxxxxxx
* expected Acc = xxxxxxxx xxxxxxxx
******************************************************************************/
print_mtpr_error( msg )
char *msg;
{
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" MTPR test ");
writed( test_no );
writes( msg );
writes("\ntable index = ");
write32h( sgl_value_1 );
if( msg == bad_tbl_entry_msg ) { /* bad data read? */
writes(", table entry = ");
write32h( sgl_value_2 );
writes(" (2nd read)\n");
writes(" entry expected = ");
write32h( sgl_value_3 );
writes(" (1st read)\n");
} else { /* bad accumulator error */
writes(", table entry = ");
write32h( sgl_value_2 );
writes("\ninitial Acc = ");
if( subtest == 2 ) { /* DBL precision? */
write32h( dbl_ld_acc.m );
writec(' ');
write32h( dbl_ld_acc.l );
writes(", final Acc = ");
write32h( dbl_st_acc.m );
writec(' ');
write32h( dbl_st_acc.l );
writes("\n expected Acc = ");
write32h( dbl_expected.m );
writec(' ');
write32h( dbl_expected.l );
} else { /* SGL precision */
write32h( sgl_ld_acc );
writes(", final Acc = ");
write32h( sgl_st_acc );
writes("\n expected Acc = ");
write32h( sgl_expected );
}
writec('\n');
}
}
/******************************************************************************
*
* halt with the failure information in registers
*
******************************************************************************/
mtpr_er_halt( code )
int code; /* error code to halt with */
{
sgl_dummy1 = code; /* get the halt code */
if( subtest != 2 ) { /* check for DBL accumulator */
dbl_ld_acc.m = sgl_ld_acc; /* get the init Acc */
dbl_ld_acc.l = 0;
dbl_st_acc.m = sgl_st_acc; /* get the final Acc */
dbl_st_acc.l = 0;
dbl_expected.m = sgl_expected; /* get the expected Acc */
dbl_expected.l = 0;
}
asm("movl _test_no,r0"); /* r0 = test number */
asm("movl _subtest,r1"); /* r1 = subtest # */
asm("movl _sgl_dummy1,r2"); /* r2 = error code */
asm("movl _cycle,r3"); /* r3 = cycle count */
if( code == 2 ) { /* corrupted Acc */
asm("movl _dbl_ld_acc,r4"); /* r4 = MS initial Acc */
asm("movl _dbl_ld_acc+4,r5"); /* r5 = LS initial Acc */
asm("movl _dbl_st_acc,r6"); /* r6 = MS final Acc */
asm("movl _dbl_st_acc+4,r7"); /* r7 = LS final Acc */
asm("movl _dbl_expected,r8"); /* r8 = MS expected */
asm("movl _dbl_expected+4,r9"); /* r9 = LS expected */
asm("movl _sgl_value_1,r10"); /* r10 = table addr. */
asm("movl _sgl_value_2,r11");; /* r11 = entry read */
} else { /* wrong data read or wrong final Acc */
asm("movl _sgl_value_1,r4"); /* r4 = table addr. */
asm("movl _sgl_value_2,r5"); /* r5 = entry read */
asm("movl _sgl_value_3,r6"); /* r6 = expected entry */
asm("movl _sgl_ld_acc,r7"); /* r7 = initial Acc */
asm("movl _sgl_st_acc,r8"); /* r8 = final Acc */
asm("movl _sgl_expected,r9");; /* r9 = sgl expected */
};
asm("halt");; /* HALT ... */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.