iotestrdp.c 8.35 KB

/*************************************************************************
 *
 *  File: iotestrdp.c
 *
 *  This file contains the routines to test RDP.
 *
 *  $Header: /root/leakn64/depot/rf/sw/bbplayer/iosim/src/iotestrdp.c,v 1.10 2002/12/07 23:18:19 whs Exp $
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include "trace.h"
#include "iomap.h"
#include "iotest.h"
#include "verify.h"
#include "simipc.h"
#include "bcp_util.h"

extern int IoCmd(int, int);

/***********************************************************************
 * Test Routines
 * 
 */
int
RDPList(int a1, int a2, int a3, int a4)
{
    VerifyInfo	*verifp;
    int StartAddr;
    int Count;
    unsigned int inst1, inst2;	
    long long st, ed;
   
#ifdef __sgi__ 
    verifp = (VerifyInfo *)(PHYS_TO_K1(VERIFY_INFO_PHYSADDR));
    StartAddr = verifp->rdpListAddr;
    /*
     * The rdpListSize is 64 bit written back by the SP. The count resides in
     * the lower 32 bit. Since iosim only traps 32 bit mbus reads, we must
     * read the lower 32 bit.
     */
    Count = *(((unsigned int *)&verifp->rdpListSize)+1);
#else
    {
         int offset;
         VerifyInfo tmp;

         offset = ((void *) &tmp.rdpListAddr) - ((void *) &tmp);
		 if (a1) StartAddr = IO_READ(offset);
         else StartAddr = IO_READ(VERIFY_INFO_PHYSADDR + offset);
   
         offset = ((void *) &tmp.rdpListSize) - ((void *) &tmp);
		 if (a1) Count = IO_READ(offset + 4);
         else Count = IO_READ(VERIFY_INFO_PHYSADDR + offset + 4);
    }
#endif
   
#ifdef __DUMP_VERIFY_INFO__ 
    {
             /* DUMP info for Test 107 */
             printf("\n **** Dump Verify info (RDPList) * * * * * \n");
             printf("0x00-0x10 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                    IO_READ(VERIFY_INFO_PHYSADDR),
                    IO_READ(VERIFY_INFO_PHYSADDR+4),
                    IO_READ(VERIFY_INFO_PHYSADDR+8),
                    IO_READ(VERIFY_INFO_PHYSADDR+0xc));

             printf("0x10-0x20 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                    IO_READ(VERIFY_INFO_PHYSADDR+0x10),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x14),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x18),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x1c));

             printf("0x20-0x30 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                    IO_READ(VERIFY_INFO_PHYSADDR+0x20),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x24),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x28),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x2c));

             printf("0x30-0x40 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                    IO_READ(VERIFY_INFO_PHYSADDR+0x30),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x34),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x38),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x3c));

             printf("0x40-0x50 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                    IO_READ(VERIFY_INFO_PHYSADDR+0x40),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x44),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x48),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x4c));

             printf("0x50-0x60 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                    IO_READ(VERIFY_INFO_PHYSADDR+0x50),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x54),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x58),
                    IO_READ(VERIFY_INFO_PHYSADDR+0x5c));

    }
#endif
 
    _TRACE(DLOG, printf("RDP list execute start(56) 0x%x, end 0x%x\n",
			    StartAddr, StartAddr + Count));
   
    /* XXX Should we add a check for Flush at end? */
	do {
    	inst1 = BD_IO_READ((StartAddr + Count - 8) & 0xFFFFFF);
		inst2 = BD_IO_READ((StartAddr + Count - 4) & 0xFFFFFF);
	 	Count -= 8;
	} while ((inst1 == 0xe9000000) && (inst2 == 0));
	Count += 16;   /* Only keep the last fullsync */  
 
    SIM_TIME(&st);
    /* Write start & end addresses */
    MemWrite(DPC_START_REG,  StartAddr, 0, 0);
    MemWrite(DPC_END_REG, StartAddr + Count, 0, 0);  
    
    /* status read */
    MemRead(DPC_STATUS_REG, 0, 0, 0);
    
    /* wait until DMA counter is at end */
    /* MemReadUntil(DPC_CURRENT_REG, 0x00ffffff, StartAddr + Count, 0); */
    while (MemReadCompMaskNoError(DPC_CURRENT_REG, StartAddr + Count, 0x00ffffff, 0))
      {
	IoCmd(REQ_STALL, NumberStallCycles);
      }
    
    /* wait for full sync */
    /* MemPollStatus(DPC_STATUS_REG, DPC_STATUS_PIPE_BUSY, 1, 0); */
    while (MemReadCompMaskNoError(DPC_STATUS_REG, 0, DPC_STATUS_PIPE_BUSY, 0))
      {
	IoCmd(REQ_STALL, NumberStallCycles);
      }
    
	SIM_TIME(&ed);
    {
        FILE *f = fopen("/tmp/bb_perf", "ab");
        if(f) fprintf(f, "  Takes CPU %d ns\n", (int)(ed-st));
        if (f) fclose(f);
    }
    return 1;

}  /* RDPList */


/*
 *  Loop RDP display list until memory compares
 */
int
RDPListLoop(int addr, int data, int max_loops, int failExpected)
{
    VerifyInfo	*verifp;
    int StartAddr;
    int Count;
    int nloops = 0;
   
#ifdef __sgi__ 
    verifp = (VerifyInfo *)(PHYS_TO_K1(VERIFY_INFO_PHYSADDR));
    StartAddr = verifp->rdpListAddr;
    /*
     * The rdpListSize is 64 bit written back by the SP. The count resides in
     * the lower 32 bit. Since iosim only traps 32 bit mbus reads, we must
     * read the lower 32 bit.
     */
    Count = *(((unsigned int *)&verifp->rdpListSize)+1);
#else
    {
       int offset;
       VerifyInfo tmp;

       offset = ((void *) &tmp.rdpListAddr) - ((void *) &tmp);
       StartAddr = IO_READ(VERIFY_INFO_PHYSADDR + offset);

       offset = ((void *) &tmp.rdpListSize) - ((void *) &tmp);
       Count = IO_READ(VERIFY_INFO_PHYSADDR + offset + 4);
    }
#endif
    
    _TRACE(DLOG, printf("RDP list execute start 120 0x%x, end 0x%x\n",
			    StartAddr, StartAddr + Count));
    
    /* XXX Should we add a check for Flush at end? */
  
    do {
  
      /* Write start & end addresses */
      MemWrite(DPC_START_REG,  StartAddr, 0, 0);
      MemWrite(DPC_END_REG, StartAddr + Count, 0, 0);
    
      /* status read */
      MemRead(DPC_STATUS_REG, 0, 0, 0);
    
      /* wait until DMA counter is at end */
      MemReadUntil(DPC_CURRENT_REG, 0x00ffffff, StartAddr + Count, 0);
    
      /* wait for full sync */
      MemPollStatus(DPC_STATUS_REG, DPC_STATUS_PIPE_BUSY, 1, 0);

      /* repeat display list until memory matches given value */
      _TRACE(DLOG, printf("RDP list executed, loop %d\n", nloops++));

      if(nloops > max_loops)
      {
	_TRACE(DLOG, printf("RDP list executed %d loops, exceeded max loops, test passed\n", nloops));
	return 1;
      }
    } while ( MemReadCompare(addr, data, 0, failExpected));
    
     _TRACE(DLOG, printf("RDP list loop failed at %d loops\n", nloops));
    _TRACE(DERROR, LOG_ERROR(max_loops, nloops));
    return -1;

}  /* RDPListLoop */

/*
 *  Check DP counter values before stalling
 */
int
RDPListCounter(int a1, int a2, int a3, int a4)
{
    VerifyInfo	*verifp;
    int StartAddr;
    int Count;
    
    verifp = (VerifyInfo *)(PHYS_TO_K1(VERIFY_INFO_PHYSADDR));
    StartAddr = verifp->rdpListAddr;
    /*
     * The rdpListSize is 64 bit written back by the SP. The count resides in
     * the lower 32 bit. Since iosim only traps 32 bit mbus reads, we must
     * read the lower 32 bit.
     */
    Count = *(((unsigned int *)&verifp->rdpListSize)+1);
    
    _TRACE(DLOG, printf("RDP list counter execute start 0x%x, end 0x%x\n",
			    StartAddr, StartAddr + Count));
    
    /* XXX Should we add a check for Flush at end? */
    
    /* Write start & end addresses */
    MemWrite(DPC_START_REG,  StartAddr, 0, 0);
    MemWrite(DPC_END_REG, StartAddr + Count, 0, 0);

    /* clear out counters */
    MemWrite(DPC_STATUS_REG, 
	     DPC_CLR_TMEM_CTR |
	     DPC_CLR_PIPE_CTR |      
	     DPC_CLR_CMD_CTR  |      
	     DPC_CLR_CLOCK_CTR, 
	     0, 0);
    
    /* status read */
    MemRead(DPC_STATUS_REG, 0, 0, 0);
    
    /* wait until DMA counter is at end */
    while (MemReadCompMaskNoError(DPC_CURRENT_REG, StartAddr + Count, 0x00ffffff, 0))
      {
	MemRead(DPC_CLOCK_REG, 0, 0, 0);
	MemRead(DPC_BUFBUSY_REG, 0, 0, 0);
	MemRead(DPC_PIPEBUSY_REG, 0, 0, 0);
	MemRead(DPC_TMEM_REG, 0, 0, 0);
	IoCmd(REQ_STALL, NumberStallCycles);
      }
    
    /* wait for full sync */
    while (MemReadCompMaskNoError(DPC_STATUS_REG, 0, DPC_STATUS_PIPE_BUSY, 0))
      {
	MemRead(DPC_CLOCK_REG, 0, 0, 0);
	MemRead(DPC_BUFBUSY_REG, 0, 0, 0);
	MemRead(DPC_PIPEBUSY_REG, 0, 0, 0);
	MemRead(DPC_TMEM_REG, 0, 0, 0);
	IoCmd(REQ_STALL, NumberStallCycles);
      }
    
    return 1;

}  /* RDPList */