mi_random.c 8.18 KB

/*************************************************************************
 *
 *  File: mi_random.c
 *
 *  $Header: /root/leakn64/depot/rf/sw/bbplayer/iosim/src/mi_test/mi_random.c,v 1.5 2002/12/08 02:07:08 blythe Exp $
 *
 */
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

#include "iomap.h"
#include "iotest.h"
#include "sim.h"
#include "simipc.h"
#include "trace.h"
#include "bcp_util.h"
#include "mi_test.h"
#include "nvram_test.h"

#define PASS 0
#define FAIL -1

/***********************************************************************
 * Extern definitions
 */
extern	TstCmd	TstCmdTbl[];
extern	void	IoTestAll(void);


/***********************************************************************
 * Macro definitions
 */
#define	TEST_CMD_FILE	"all.tst"
#define	OPTARG		"v:r:d:l:h:qt:"


/***********************************************************************
 * Global definitions
 */
int		IpcFd = -1;
unsigned long	Dflags;
char		*CmdFile = TEST_CMD_FILE;
FILE		*LogFp, *CmdFp;
int		ConfigRdramV = 0;
int             NumberStallCycles = 0;


/***********************************************************************
 * Local static definitions
 */
static void		usage(void);

#define BROM_SIZE 16384
#define VIRAGE2_SIZE (64*4)

int main(int argc, char **argv)
{

    int c, i, n;
    int rom[BROM_SIZE/4];
    int v2[VIRAGE2_SIZE/4];
    char line[1024];
    int do_quit = 0;
    char	*file;
    FILE	*fp = NULL;
    FILE *v_fp = NULL;
    char* test = "dram";
    int memaddr, memsize, seed;
    unsigned data_o[32], addr;
    V_INT data_i[32];
    static unsigned char sizes[] = { 4, 8, 16, 32, 1, 2, 3 };
#define NO_BYTE		4
#define YES_BYTE	(sizeof sizes)

    extern char *optarg;
    extern int optind, opterr, optopt;

    optind = 1;
    Dflags = 0;
    LogFp  = stderr;

    while ((c = getopt(argc, argv, OPTARG)) != EOF) {
        switch (c) {
        case 'd': {	/* Debug flag */
            Dflags = strtoul(optarg, NULL, 16);
            printf("Debug flag=0x%08lx\n", Dflags);
            break;
        }
        case 'l': {	/* Log file */
            file = optarg;
            printf("Log file = %s\n", file);
            if ((fp = fopen(file, "w+")) == NULL) {
                printf("Unable to open log: %s\n",
                       file);
            }
            else
                LogFp = fp;
            break;
        }
        case 'h': {	/* Help */
            usage();
            exit(0);
        }
        case 'q': {
            do_quit = 1;
            break;
        }
        case 'r': {	/* Rom file */
            file = optarg;
            printf("ROM file = %s\n", file);
            if ((fp = fopen(file, "r")) == NULL) {
                printf("Unable to open ROM: %s\n", file);
                fp = NULL;
            }
            break;
        }

        case 'v': {	/* Virage 2 file */
            file = optarg;
            printf("Virage2 file = %s\n", file);
            if ((v_fp = fopen(file, "r")) == NULL) {
                printf("Unable to open ROM: %s\n", file);
                v_fp = NULL;
            }
            break;
        }
	case 't':
	    test = optarg;
	    break;
        default:
            break;
        }
    }  /* while */

    /*
     * Read ROM file if it exists
     */
    if (fp) {
        i = 0;
        while (i<BROM_SIZE/4) {
            fgets(line, 1024, fp);
            // Skip comment lines
            if (line[0] == '/') {
                continue;
            }
            if (sscanf(line, "%x", rom+i) > 0) {
                i++;
            }
        }

    }

    if (v_fp) {
        i = 0;
        while (i<VIRAGE2_SIZE/4) {
            fgets(line, 1024, v_fp);
            // Skip comment lines
            if (line[0] == '/') {
                continue;
            }
            if (sscanf(line, "%x", v2+i) > 0) {
                i++;
            }
        }

    }

    ExceptionHandlerInit();
    IpcInit(NULL);
    FindServer();

    do_keep_alive_socket(1);

    /* 
     * MI random tests 
     */
    memaddr = strtoul(getenv("IOSIM_ADDR"), 0, 0);
    memsize = strtoul(getenv("IOSIM_MEM_SIZE"), 0, 0);
    seed = strtoul(getenv("IOSIM_SEED"), 0, 0);
    srand(seed);
    fprintf(LogFp, "mi_random test %s seed %d addr 0x%x size 0x%x\n", test, seed, memaddr, memsize);
    //IO_READ(BOOT_RAM_LO_START);
    //IO_WRITE(VIRAGE2_CTRL_REG, 0);	/* take out of reset */
    if (strcmp(test, "dram") == 0) {
	addr = memaddr + rand() % memsize;
	n = sizes[rand() % YES_BYTE];
    } else if (strcmp(test, "bram") == 0) {
	n = sizes[rand() % YES_BYTE];
	addr = BOOT_RAM_HI_START + rand()%(BOOT_RAM_HI_END-BOOT_RAM_HI_START-n);
    } else if (strcmp(test, "isram") == 0) {
	n = sizes[rand() % YES_BYTE];
	addr = INTERNAL_RAM_START + rand()%(INTERNAL_RAM_END-INTERNAL_RAM_START-n);
    } else if (strcmp(test, "v0sram") == 0) {
	n = sizes[rand() % NO_BYTE];
	addr = VIRAGE0_RAM_START + rand()%(VIRAGE0_RAM_END-VIRAGE0_RAM_START-n);
    } else if (strcmp(test, "v1sram") == 0) {
	n = sizes[rand() % NO_BYTE];
	addr = VIRAGE1_RAM_START + rand()%(VIRAGE1_RAM_END-VIRAGE1_RAM_START-n);
    } else if (strcmp(test, "v2sram") == 0) {
	n = sizes[rand() % NO_BYTE];
	addr = VIRAGE2_RAM_START + rand()%(VIRAGE2_RAM_END-VIRAGE2_RAM_START-n);
    }  else {
	fprintf(LogFp, "MI invalid test %s (failed)\n", test);
	goto done;
    }
    if (n >= 4 || n == 2) addr &= ~(n-1);
    else if (n == 3) addr &= ~2;
    for(i = 0; i < (n+3)>>2; i++)
	data_o[i] = rand();

    /* will never see a 32-byte block write, so split */
    if (n == 32) {
	block_write(addr, 16, data_o);
	block_write(addr+16, 16, data_o+4);
    } else if (n > 4) {
	block_write(addr, n, data_o);
    } else if (n == 4) {
	IO_WRITE(addr, data_o[0]);
    } else if (n == 3) {
	V_INT d;
	d.data_part = data_o[0] >> (8*(addr&1));
	v_io_swrite(addr, SIZE_3BYTE, 0, &d);
    } else if (n == 2) {
	V_INT d;
	d.data_part = data_o[0] >> (8*(addr&2));
	V_IO_SWRITE_HWORD(addr, 0, &d);
    } else if (n == 1) {
	V_INT d;
	d.data_part = data_o[0] >> (8*(addr&3));
	V_IO_SWRITE_BYTE(addr, 0, &d);
    }

    for(i = 0; i < (n+3)>>2; i++) {
	data_o[i] = ntohl(data_o[i]);
//fprintf(LogFp, "data_o[%d] 0x%x\n", i, data_o[i]);
    }
    /* determine what to read */
    if (rand() & 1) { /* block read */
	int m = (2 << (rand() % 3))<<2;
	unsigned int naddr = addr&~(m-1);
	int off = addr - naddr;
	unsigned int d[32];
	unsigned char* p = (unsigned char*)data_o, *q = (unsigned char*)d;

	V_IO_BREAD(naddr, m, 0, data_i);
	/* reformat to byte addressable array */
	for(i = 0 ; i < (m >> 2); i++) {
	    d[i] = ntohl(data_i[i].data_part);
//fprintf(LogFp, "data[%d] 0x%x\n", i, d[i]);
	}
//fprintf(LogFp, "off %d n %d m %d\n", off, n, m);

	/* compare original n bytes up to min(n,m) bytes */
	for(i = 0; i < (n < m ? n : m); i++) {
	    if (p[i] != q[off+i])
		fprintf(LogFp, "MI block write/read @ 0x%x[%d of %d] expected 0x%x got 0x%x - failed\n", addr, i, n, p[i], q[i+off]);
	}
    } else {	/* single read */
	V_INT d;
	int m = 1 + (rand() % 4);
	unsigned naddr = addr & ~(m-1);
	int off = addr - naddr;
	unsigned char* p = (unsigned char*)data_o, *q = (unsigned char*)&d.data_part;
	if (m == 4) {
	    V_IO_SREAD_WORD(naddr, 0, &d);
	} else if (m == 3) {
	    v_io_sread(naddr, SIZE_3BYTE, 0, &d);
	} else if (m == 2) {
	    V_IO_SREAD_HWORD(naddr, 0, &d);
	} else if (m == 1) {
	    V_IO_SREAD_BYTE(naddr, 0, &d);
	}
	d.data_part <<= 8*(naddr&3);
	d.data_part = ntohl(d.data_part);

	//fprintf(LogFp, "read m %d n %d off %d naddr 0x%x 0x%x\n", m, n, off, naddr, d.data_part);
	/* compare original n bytes up to min(n,m) bytes */
	for(i = 0; i < (n < m ? n : m); i++) {
	    if (p[i] != q[off+i])
		fprintf(LogFp, "MI block write/read @ 0x%x[%d of %d] expected 0x%x got 0x%x - failed\n", addr, i, n, p[i], q[i+off]);
	}
    }

done:
    do_keep_alive_socket(0);

    /* exit simulator */
    if (do_quit) {
	printf("Quit\n");
	IoCmd(REQ_QUIT, 0);
    }

    if (fp)
        fclose(fp);

    if (IpcFd != -1)
        IpcClose(IpcFd);

    //fprintf(LogFp, "mi_random test done\n");
    exit(0);

}

static void
usage(void)
{
	printf("Usage: mi_random \n");
	printf("       -l <log_file>\n");
	printf("       -d <debug_flags in hex>\n");
	printf("       -t <test=dram|bram|isram|v0sram|v1sram|v2sram>\n");
}