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

unix.superglobalmegacorp.com

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