⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 func.c

📁 leon2的指令模拟器。leon是应用于航天领域的一款高可靠性的sparc v7指令集的处理器。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * func.c, misc simulator functions. This file is part of SIS. *  * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler, * European Space Agency *  * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. *  * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for * more details. *  * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 675 * Mass Ave, Cambridge, MA 02139, USA. *  */#include <signal.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include "sis.h"#include "end.h"#include <dis-asm.h>#include "sim-config.h"#define	VAL(x)	strtoul(x,(char **)NULL,0)extern int	current_target_byte_order;struct disassemble_info dinfo;struct pstate   sregs;extern struct estate ebase;int             ctrl_c = 0;int             sis_verbose = 0;char           *sis_version = "2.7.5";int             nfp = 0;int             ift = 0;int             wrp = 0;int             rom8 = 0;int             uben = 0;int		termsave;int             sparclite = 0;		/* emulating SPARClite instructions? */int             sparclite_board = 0;	/* emulating SPARClite board RAM? */char            uart_dev1[128] = "";char            uart_dev2[128] = "";extern	int	ext_irl;uint32		last_load_addr = 0;#ifdef ERRINJuint32		errcnt = 0;uint32		errper = 0;uint32		errtt = 0;uint32		errftt = 0;uint32		errmec = 0;#endif/* Forward declarations */static int	batch PARAMS ((struct pstate *sregs, char *fname));static void	set_rega PARAMS ((struct pstate *sregs, char *reg, uint32 rval));static void	disp_reg PARAMS ((struct pstate *sregs, char *reg));static uint32	limcalc PARAMS ((float32 freq));static void	int_handler PARAMS ((int32 sig));static void	init_event PARAMS ((void));static int	disp_fpu PARAMS ((struct pstate  *sregs));static void	disp_regs PARAMS ((struct pstate  *sregs, int cwp));static void	disp_ctrl PARAMS ((struct pstate *sregs));static void	disp_mem PARAMS ((uint32 addr, uint32 len));static int batch(sregs, fname)    struct pstate  *sregs;    char           *fname;{    FILE           *fp;    char            lbuf[1024];    if ((fp = fopen(fname, "r")) == NULL) {	fprintf(stderr, "couldn't open batch file %s\n", fname);	return (0);    }    while (!feof(fp)) {	lbuf[0] = 0;	fgets(lbuf, 1023, fp);	if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n'))	    lbuf[strlen(lbuf) - 1] = 0;	printf("sis> %s\n", lbuf);	exec_cmd(sregs, lbuf);    }    fclose(fp);    return (1);}voidset_regi(sregs, reg, rval)    struct pstate  *sregs;    int32           reg;    uint32          rval;{    uint32          cwp;    cwp = ((sregs->psr & 0x7) << 4);    if ((reg > 0) && (reg < 8)) {	sregs->g[reg] = rval;    } else if ((reg >= 8) && (reg < 32)) {	sregs->r[(cwp + reg) & 0x7f] = rval;    } else if ((reg >= 32) && (reg < 64)) {	sregs->fsi[reg - 32] = rval;    } else {	switch (reg) {	case 64:	    sregs->y = rval;	    break;	case 65:	    sregs->psr = rval;	    break;	case 66:	    sregs->wim = rval;	    break;	case 67:	    sregs->tbr = rval;	    break;	case 68:	    sregs->pc = rval;	    break;	case 69:	    sregs->npc = rval;	    break;	case 70:	    sregs->fsr = rval;	    set_fsr(rval);	    break;    default:break;	}    }}voidget_regi(struct pstate * sregs, int32 reg, char *buf){    uint32          cwp;    uint32          rval = 0;    cwp = ((sregs->psr & 0x7) << 4);    if ((reg >= 0) && (reg < 8)) {	rval = sregs->g[reg];    } else if ((reg >= 8) && (reg < 32)) {	rval = sregs->r[(cwp + reg) & 0x7f];    } else if ((reg >= 32) && (reg < 64)) {	rval = sregs->fsi[reg - 32];    } else {	switch (reg) {	case 64:	    rval = sregs->y;	    break;	case 65:	    rval = sregs->psr;	    break;	case 66:	    rval = sregs->wim;	    break;	case 67:	    rval = sregs->tbr;	    break;	case 68:	    rval = sregs->pc;	    break;	case 69:	    rval = sregs->npc;	    break;	case 70:	    rval = sregs->fsr;	    break;    default:break;	}    }    if (current_target_byte_order == BIG_ENDIAN) {	buf[0] = (rval >> 24) & 0x0ff;	buf[1] = (rval >> 16) & 0x0ff;	buf[2] = (rval >> 8) & 0x0ff;	buf[3] = rval & 0x0ff;    }    else {	buf[3] = (rval >> 24) & 0x0ff;	buf[2] = (rval >> 16) & 0x0ff;	buf[1] = (rval >> 8) & 0x0ff;	buf[0] = rval & 0x0ff;    }}static voidset_rega(sregs, reg, rval)    struct pstate  *sregs;    char           *reg;    uint32          rval;{    uint32          cwp;    int32           err = 0;    cwp = ((sregs->psr & 0x7) << 4);    if (strcmp(reg, "psr") == 0)	sregs->psr = (rval = (rval & 0x00f03fff));    else if (strcmp(reg, "tbr") == 0)	sregs->tbr = (rval = (rval & 0xfffffff0));    else if (strcmp(reg, "wim") == 0)	sregs->wim = (rval = (rval & 0x0ff));    else if (strcmp(reg, "y") == 0)	sregs->y = rval;    else if (strcmp(reg, "pc") == 0)	sregs->pc = rval;    else if (strcmp(reg, "npc") == 0)	sregs->npc = rval;    else if (strcmp(reg, "fsr") == 0) {	sregs->fsr = rval;	set_fsr(rval);    } else if (strcmp(reg, "g0") == 0)	err = 2;    else if (strcmp(reg, "g1") == 0)	sregs->g[1] = rval;    else if (strcmp(reg, "g2") == 0)	sregs->g[2] = rval;    else if (strcmp(reg, "g3") == 0)	sregs->g[3] = rval;    else if (strcmp(reg, "g4") == 0)	sregs->g[4] = rval;    else if (strcmp(reg, "g5") == 0)	sregs->g[5] = rval;    else if (strcmp(reg, "g6") == 0)	sregs->g[6] = rval;    else if (strcmp(reg, "g7") == 0)	sregs->g[7] = rval;    else if (strcmp(reg, "o0") == 0)	sregs->r[(cwp + 8) & 0x7f] = rval;    else if (strcmp(reg, "o1") == 0)	sregs->r[(cwp + 9) & 0x7f] = rval;    else if (strcmp(reg, "o2") == 0)	sregs->r[(cwp + 10) & 0x7f] = rval;    else if (strcmp(reg, "o3") == 0)	sregs->r[(cwp + 11) & 0x7f] = rval;    else if (strcmp(reg, "o4") == 0)	sregs->r[(cwp + 12) & 0x7f] = rval;    else if (strcmp(reg, "o5") == 0)	sregs->r[(cwp + 13) & 0x7f] = rval;    else if (strcmp(reg, "o6") == 0)	sregs->r[(cwp + 14) & 0x7f] = rval;    else if (strcmp(reg, "o7") == 0)	sregs->r[(cwp + 15) & 0x7f] = rval;    else if (strcmp(reg, "l0") == 0)	sregs->r[(cwp + 16) & 0x7f] = rval;    else if (strcmp(reg, "l1") == 0)	sregs->r[(cwp + 17) & 0x7f] = rval;    else if (strcmp(reg, "l2") == 0)	sregs->r[(cwp + 18) & 0x7f] = rval;    else if (strcmp(reg, "l3") == 0)	sregs->r[(cwp + 19) & 0x7f] = rval;    else if (strcmp(reg, "l4") == 0)	sregs->r[(cwp + 20) & 0x7f] = rval;    else if (strcmp(reg, "l5") == 0)	sregs->r[(cwp + 21) & 0x7f] = rval;    else if (strcmp(reg, "l6") == 0)	sregs->r[(cwp + 22) & 0x7f] = rval;    else if (strcmp(reg, "l7") == 0)	sregs->r[(cwp + 23) & 0x7f] = rval;    else if (strcmp(reg, "i0") == 0)	sregs->r[(cwp + 24) & 0x7f] = rval;    else if (strcmp(reg, "i1") == 0)	sregs->r[(cwp + 25) & 0x7f] = rval;    else if (strcmp(reg, "i2") == 0)	sregs->r[(cwp + 26) & 0x7f] = rval;    else if (strcmp(reg, "i3") == 0)	sregs->r[(cwp + 27) & 0x7f] = rval;    else if (strcmp(reg, "i4") == 0)	sregs->r[(cwp + 28) & 0x7f] = rval;    else if (strcmp(reg, "i5") == 0)	sregs->r[(cwp + 29) & 0x7f] = rval;    else if (strcmp(reg, "i6") == 0)	sregs->r[(cwp + 30) & 0x7f] = rval;    else if (strcmp(reg, "i7") == 0)	sregs->r[(cwp + 31) & 0x7f] = rval;    else	err = 1;    switch (err) {    case 0:	printf("%s = %d (0x%08x)\n", reg, rval, rval);	break;    case 1:	printf("no such regiser: %s\n", reg);	break;    case 2:	printf("cannot set g0\n");	break;    default:	break;    }}static voiddisp_reg(sregs, reg)    struct pstate  *sregs;    char           *reg;{    if (strncmp(reg, "w",1) == 0)	disp_regs(sregs, VAL(&reg[1]));}#ifdef ERRINJvoiderrinj(){    int	err;    switch (err = (random() % 12)) {	case 0: errtt = 0x61; break;	case 1: errtt = 0x62; break;	case 2: errtt = 0x63; break;	case 3: errtt = 0x64; break;	case 4: errtt = 0x65; break;	case 5: 	case 6: 	case 7: errftt = err; 		break;	case 8: errmec = 1; break;	case 9: errmec = 2; break;	case 10: errmec = 5; break;	case 11: errmec = 6; break;    }    errcnt++;    if (errper) event(errinj, 0, (random()%errper));}voiderrinjstart(){    if (errper) event(errinj, 0, (random()%errper));}#endifstatic uint32limcalc (freq)    float32		freq;{    uint32          unit, lim;    double	    flim;    char           *cmd1, *cmd2;    unit = 1;    lim = -1;    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {        lim = VAL(cmd1);        if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {            if (strcmp(cmd2,"us")==0) unit = 1;      	    if (strcmp(cmd2,"ms")==0) unit = 1000;            if (strcmp(cmd2,"s")==0)  unit = 1000000;        }        flim = (double) lim * (double) unit * (double) freq + 	   (double) ebase.simtime;        if ((flim > ebase.simtime) && (flim < 4294967296.0)) {            lim = (uint32) flim;        } else  {            printf("error in expression\n");            lim = -1;        }    }    return (lim);}    intexec_cmd(sregs, cmd)    char           *cmd;    struct pstate  *sregs;{    char           *cmd1, *cmd2;    int32           stat;    uint32          len, i, clen, j;    static uint32   daddr = 0;    char           *cmdsave;    stat = OK;    cmdsave = strdup(cmd);    if ((cmd1 = strtok(cmd, " \t")) != NULL) {	clen = strlen(cmd1);	if (strncmp(cmd1, "bp", clen) == 0) {	    for (i = 0; i < sregs->bptnum; i++) {		printf("  %d : 0x%08x\n", i + 1, sregs->bpts[i]);	    }	} else if (strncmp(cmd1, "+bp", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;		printf("added breakpoint %d at 0x%08x\n",		       sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);		sregs->bptnum += 1;	    }	} else if (strncmp(cmd1, "-bp", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		i = VAL(cmd1) - 1;		if ((i >= 0) && (i < sregs->bptnum)) {		    printf("deleted breakpoint %d at 0x%08x\n", i + 1,			   sregs->bpts[i]);		    for (; i < sregs->bptnum - 1; i++) {			sregs->bpts[i] = sregs->bpts[i + 1];		    }		    sregs->bptnum -= 1;		}	    }	} else if (strncmp(cmd1, "batch", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {		printf("no file specified\n");	    } else {		batch(sregs, cmd1);	    }	} else if (strncmp(cmd1, "cont", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {		stat = run_sim(sregs, -1, 0);	    } else {		stat = run_sim(sregs, VAL(cmd1), 0);	    }	    daddr = sregs->pc;	    sim_halt();	} else if (strncmp(cmd1, "debug", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		sis_verbose = VAL(cmd1);	    }	    printf("Debug level = %d\n",sis_verbose);	} else if (strncmp(cmd1, "dis", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		daddr = VAL(cmd1);	    }	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {		len = VAL(cmd2);	    } else		len = 16;	    printf("\n");	    dis_mem(daddr, len, &dinfo);	    printf("\n");	    daddr += len * 4;	} else if (strncmp(cmd1, "echo", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		printf("%s\n", (&cmdsave[clen+1]));	    }#ifdef ERRINJ	} else if (strncmp(cmd1, "error", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		errper = VAL(cmd1);	        if (errper) {		    event(errinj, 0, (len = (random()%errper)));		    printf("Error injection started with period %d\n",len);	        } 	     } else printf("Injected errors: %d\n",errcnt);#endif	} else if (strncmp(cmd1, "float", clen) == 0) {	    stat = disp_fpu(sregs);	} else if (strncmp(cmd1, "go", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {		len = last_load_addr;	    } else {		len = VAL(cmd1);	    }	    sregs->pc = len & ~3;	    sregs->npc = sregs->pc + 4;	    printf("resuming at 0x%08x\n",sregs->pc);	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {		stat = run_sim(sregs, VAL(cmd2), 0);	    } else {		stat = run_sim(sregs, -1, 0);	    }	    daddr = sregs->pc;	    sim_halt();	} else if (strncmp(cmd1, "help", clen) == 0) {	    gen_help();	} else if (strncmp(cmd1, "history", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		sregs->histlen = VAL(cmd1);		if (sregs->histbuf != NULL)		    free(sregs->histbuf);		sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));		printf("trace history length = %d\n\r", sregs->histlen);		sregs->histind = 0;	    } else {		j = sregs->histind;		for (i = 0; i < sregs->histlen; i++) {		    if (j >= sregs->histlen)			j = 0;		    printf(" %8d ", sregs->histbuf[j].time);		    dis_mem(sregs->histbuf[j].addr, 1, &dinfo);		    j++;		}	    }	} else if (strncmp(cmd1, "load", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		last_load_addr = bfd_load(cmd1);		while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)		    last_load_addr = bfd_load(cmd1);	    } else {		printf("load: no file specified\n");	    }	} else if (strncmp(cmd1, "mem", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)		daddr = VAL(cmd1);	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL)		len = VAL(cmd2);	    else		len = 64;	    disp_mem(daddr, len);	    daddr += len;	} else if (strncmp(cmd1, "perf", clen) == 0) {	    cmd1 = strtok(NULL, " \t\n\r");	    if ((cmd1 != NULL) &&		(strncmp(cmd1, "reset", strlen(cmd1)) == 0)) {		reset_stat(sregs);	    } else		show_stat(sregs);	} else if (strncmp(cmd1, "quit", clen) == 0) {	    exit(0);	} else if (strncmp(cmd1, "reg", clen) == 0) {	    cmd1 = strtok(NULL, " \t\n\r");	    cmd2 = strtok(NULL, " \t\n\r");	    if (cmd2 != NULL)		set_rega(sregs, cmd1, VAL(cmd2));	    else if (cmd1 != NULL)		disp_reg(sregs, cmd1);	    else {		disp_regs(sregs,sregs->psr);		disp_ctrl(sregs);	    }	} else if (strncmp(cmd1, "reset", clen) == 0) {	    ebase.simtime = 0;	    reset_all();	    reset_stat(sregs);	} else if (strncmp(cmd1, "run", clen) == 0) {	    ebase.simtime = 0;	    reset_all();	    reset_stat(sregs);	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {		stat = run_sim(sregs, -1, 0);	    } else {		stat = run_sim(sregs, VAL(cmd1), 0);	    }	    daddr = sregs->pc;	    sim_halt();	} else if (strncmp(cmd1, "shell", clen) == 0) {	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {		system(&cmdsave[clen]);	    }	} else if (strncmp(cmd1, "step", clen) == 0) {	    stat = run_sim(sregs, 1, 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -