rsp_other.c 9.84 KB
#include <sys/types.h>
#ifdef __sgi__
#include <sys/sbd.h>
#endif
#include <sys/stat.h>
#include <sys/mman.h>
#ifdef __sgi__
#include <sys/sema.h>
#endif
#include <netinet/in.h>

#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <getopt.h>

#include <rcp.h>
#include <rsp.h>

#define DMEM_SIZE 4096
#define IMEM_SIZE 4096

#define IBIST_REG_MSK 0x0000007f
/*
 * From $ROOT/usr/include/ide, which is installed from $ROOT/PR/diags/include
 */
#include "diag.h"
#include "dbg_comm.h"

#define RSP_OTHER_TEST_BASE	1

static int rsptest(TEST_REF *test_ref);
static int NumFailures = 0;

static int rsp_Init();
static int rsp_Do(TEST_REF *test_ref);
static int imem_marching_1(void);
static int dmem_marching_1(void);
static int mem_marching_1(unsigned int start_addr, unsigned int end_addr);
static int imem_pattern(void);
static int dmem_pattern(void);
static int mem_pattern(unsigned int start_addr, unsigned int end_addr);
static int imem_bist(void);
static int pc_r_w(void);

/*
 * Create an array of tests, each of which corresponds to a separate menu
 * item callable from the master ide menu.
 */
static TEST_REF TestRefs[] = {
  {"Sequential IMem Marching 1 Test", RSP_OTHER_TEST_BASE+0, imem_marching_1},
  {"Sequential DMem Marching 1 Test", RSP_OTHER_TEST_BASE+1, dmem_marching_1},
  {"IMem Pattern Test", RSP_OTHER_TEST_BASE+2, imem_pattern},
  {"DMem Pattern Test", RSP_OTHER_TEST_BASE+3, dmem_pattern},
  {"IMem BIST", RSP_OTHER_TEST_BASE+4, imem_bist},
  {"PC Read Write", RSP_OTHER_TEST_BASE+5, pc_r_w},
    {"",0,0}
};

/*
 * diagnostic entry point:
 *
 * Each separately invokable ide diagnostic command corresponds to an
 * independent ".c" module; the entry point herein must match
 * the test name as specified in the rspcmd.awk script.  These command
 * names correspond to the names you see from the ide menu.  For this
 * module, there will be an ide command "rsp_other".
 */

int rsp_other(void)
{
    int c;

    while ((c = getopt(pGlobalComm->argc, pGlobalComm->argv, "hdet:")) != EOF) {
	switch(c) {
	    case 'h':
	        dgListSubTests(TestRefs);
		return;
	    case 'd':
		printmask = 0xff;
		errlog(INFO, "Test will be run in debug mode.");
		break;
	    case 'e':
		exitmask = 0x0;
		errlog(INFO, "Test will not terminate on errors.");
		break;
	    case 't':
		pGlobalComm->entryNum = -atoi(optarg);
		errlog(INFO, "Running test %d only.", pGlobalComm->entryNum);
		break;
	    default:
		printf("weird option character %c = 0x%x\n", c, c);
		break;
        }
    }

    /*
     * IDE will call our one-time initialization function rsp_Init(),
     * then invoke rsp_Do() for as many tests as we've put into the
     * global test array "TestRefs", declared at the top of this module.
     */
    diaginit(TestRefs, rsp_Init, rsp_Do);

    if (NumFailures) {
        errlog(ERR_SEVERE, "... test %s FAILED, %d failures.",
            ideTestName, NumFailures);
    } else {
	errlog(INFO_END, "... test %s PASSED", ideTestName);
    }
}

static int rsp_Init()
{
    errlog(INFO, "Starting test %s ... ", ideTestName);
    NumFailures = 0;
    dgInitComm();
    return(0);
}

static int rsp_Do(TEST_REF *test_ref)
{
    int rc;

    errlog(INFO,
        "%s: starting subtest %s (%d) ...",
        ideTestName, test_ref->name, test_ref->num);

    /*
     * Invoke the actual test from the "TEST_REF" array statically declared
     * as a global within this test module.
     */
    if (rc = test_ref->fnc(test_ref)) NumFailures++;

    if (rc == 0) errlog(INFO, "--- subtest %s PASSED", test_ref->name);
    else {
      errlog(ERR_SEVERE, "--- subtest %s FAILED", test_ref->name);
    }
    
    return(NumFailures);
}

/*
 * Simple sequential write/read of IMem/DMem with marching 1.
 *** Not to be run if monitor is in IMem/DMem. ***
 */

int
imem_marching_1(void)
{
  int error_count = 0;

  error_count = mem_marching_1(RSP_IMEM_BASE, RSP_IMEM_BASE + IMEM_SIZE - 4);
  return error_count;
}

int
dmem_marching_1(void)
{
  int error_count = 0;

  error_count = mem_marching_1(RSP_DMEM_BASE, RSP_DMEM_BASE + DMEM_SIZE - 4);
  return error_count;
}

int
mem_marching_1(start_addr, end_addr)
  unsigned int start_addr, end_addr;
{
  int error_count = 0;
  int i;
  unsigned int read_data;
  unsigned int write_data;
  int msb;
  
  write_data = 1;
  errlog(DEBUG, "Fill Mem from %08x to %08x with marching 1",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    errlog(DEBUG, "Writing data 0x%08x to Mem[0x%08x]", write_data, i);
    dgWriteWord(i, write_data);
    msb = (write_data == 0x80000000);
    write_data = (write_data << 1) | msb;
  }

  write_data = 1;
  errlog(DEBUG, "Test Mem from %08x to %08x for marching 1",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    dgReadWord(i, &read_data);
    errlog(DEBUG, "Read data 0x%08x from Mem[0x%08x]", read_data, i);
    if (write_data != read_data) {
      errlog(ERR_SEVERE,
             "data miscompare - ad = %08x, wr = %08x, rd = %08x",
             i, write_data, read_data);
      error_count++;
    }
    msb = (write_data == 0x80000000);
    write_data = (write_data << 1) | msb;
  }
  return error_count;
}


int imem_bist(void)
{
   int errcount = 0;
   unsigned read_data;

   /* clear bist status */
   errcount += dgWriteWord(SP_IBIST_REG, SP_IBIST_CLEAR);
   errcount += dgRdTestWordMsk(SP_IBIST_REG, 0x00000000, IBIST_REG_MSK);

   /* bist_check 1 */
   errcount += dgWriteWord(SP_IBIST_REG, SP_IBIST_CHECK);
   while (!(errcount += dgReadWord(SP_IBIST_REG, &read_data)))
   {
     if (read_data & SP_IBIST_DONE) break;
   }
   errcount += dgRdTestWordMsk(SP_IBIST_REG, (SP_IBIST_FAILED | SP_IBIST_DONE | SP_IBIST_CHECK), 
			       IBIST_REG_MSK);

   /* clear bist, bist_check 0 */
   errcount += dgWriteWord(SP_IBIST_REG, SP_IBIST_CLEAR);
   while (!(errcount += dgReadWord(SP_IBIST_REG, &read_data)))
   {
     if (read_data & SP_IBIST_DONE) break;
   }
   errcount += dgRdTestWordMsk(SP_IBIST_REG, (SP_IBIST_FAILED | SP_IBIST_DONE), IBIST_REG_MSK);

   /* clear bist status */
   errcount += dgWriteWord(SP_IBIST_REG, SP_IBIST_CLEAR);
   errcount += dgRdTestWordMsk(SP_IBIST_REG, 0x00000000, IBIST_REG_MSK);

   /* bist_go */
   errcount += dgWriteWord(SP_IBIST_REG, SP_IBIST_GO);
   while (!(errcount += dgReadWord(SP_IBIST_REG, &read_data)))
   {
     if (read_data & SP_IBIST_DONE) break;
   }
   errcount += dgRdTestWordMsk(SP_IBIST_REG, (SP_IBIST_DONE | SP_IBIST_GO), IBIST_REG_MSK);

   /* clear bist status */
   errcount += dgWriteWord(SP_IBIST_REG, SP_IBIST_CLEAR);
   errcount += dgRdTestWordMsk(SP_IBIST_REG, 0x00000000, IBIST_REG_MSK);

   if (errcount)
      errlog(ERR_SEVERE, "IMem BIST errcount = %d", errcount);

   return(errcount);
}

/*
 * Simple sequential write/read of IMem/DMem with "aaa..." and "555" pattern.
 *** Not to be run if monitor is in IMem/DMem. ***
 */

int
imem_pattern(void)
{
  int error_count = 0;

  error_count = mem_pattern(RSP_IMEM_BASE, RSP_IMEM_BASE + IMEM_SIZE - 4);
  return error_count;
}

int
dmem_pattern(void)
{
  int error_count = 0;

  error_count = mem_pattern(RSP_DMEM_BASE, RSP_DMEM_BASE + DMEM_SIZE - 4);
  return error_count;
}

int
mem_pattern(start_addr, end_addr)
  unsigned int start_addr, end_addr;
{
  int error_count = 0;
  int i;
  unsigned int read_data;
  unsigned int write_data;
  int msb;
  
  write_data = 0xaaaaaaaa;
  errlog(DEBUG, "Fill Mem from %08x to %08x with 0xaaa...",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    errlog(DEBUG, "Writing data 0x%08x to Mem[0x%08x]", write_data, i);
    dgWriteWord(i, write_data);
  }

  errlog(DEBUG, "Test Mem from %08x to %08x for 0xaaa...",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    dgReadWord(i, &read_data);
    errlog(DEBUG, "Read data 0x%08x from Mem[0x%08x]", read_data, i);
    if (write_data != read_data) {
      errlog(ERR_SEVERE, 
             "data miscompare - ad = %08x, wr = %08x, rd = %08x",
             i, write_data, read_data);
      error_count++;
    }
  }

  write_data = 0x55555555;
  errlog(DEBUG, "Fill Mem from %08x to %08x with 0x555...",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    errlog(DEBUG, "Writing data 0x%08x to Mem[0x%08x]", write_data, i);
    dgWriteWord(i, write_data);
  }

  errlog(DEBUG, "Test Mem from %08x to %08x for 0x555...",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    dgReadWord(i, &read_data);
    errlog(DEBUG, "Read data 0x%08x from Mem[0x%08x]", read_data, i);
    if (write_data != read_data) {
      errlog(ERR_SEVERE, 
             "data miscompare - ad = %08x, wr = %08x, rd = %08x",
             i, write_data, read_data);
      error_count++;
    }
  }
  
  write_data = 0xaaaaaaaa;
  errlog(DEBUG, "Fill Mem from %08x to %08x with 0xaaa...",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    errlog(DEBUG, "Writing data 0x%08x to Mem[0x%08x]", write_data, i);
    dgWriteWord(i, write_data);
  }

  errlog(DEBUG, "Test Mem from %08x to %08x for 0xaaa...",
         start_addr, end_addr);
  for (i = start_addr; i < end_addr; i += 4) {
    dgReadWord(i, &read_data);
    errlog(DEBUG, "Read data 0x%08x from Mem[0x%08x]", read_data, i);
    if (write_data != read_data) {
      errlog(ERR_SEVERE, 
             "data miscompare - ad = %08x, wr = %08x, rd = %08x",
             i, write_data, read_data);
      error_count++;
    }
  }

  return error_count;
}


int
pc_r_w()
{
  int error_count = 0;
  int i;
  unsigned int read_data;
  unsigned int write_data;
  
  write_data = 0x4;
  for (i = 2; i < 12; i ++) {
    dgWriteWord(SP_PC_REG, write_data);
    dgReadWord(SP_PC_REG, &read_data);
    errlog(DEBUG, "Read data 0x%08x from PC", read_data);
    if (write_data != read_data) {
      errlog(ERR_SEVERE, 
             "PC data miscompare - wr = %08x, rd = %08x",
             write_data, read_data);
      error_count++;
    }
    write_data = write_data << 1;
  }
  return error_count;
}