xref: /netbsd/external/gpl3/gdb/dist/sim/erc32/func.c (revision 1424dfb3)
1ed6a76a9Schristos /* This file is part of SIS (SPARC instruction simulator)
2ed6a76a9Schristos 
3*1424dfb3Schristos    Copyright (C) 1995-2020 Free Software Foundation, Inc.
4ed6a76a9Schristos    Contributed by Jiri Gaisler, European Space Agency
5ed6a76a9Schristos 
6ed6a76a9Schristos    This program is free software; you can redistribute it and/or modify
7ed6a76a9Schristos    it under the terms of the GNU General Public License as published by
8ed6a76a9Schristos    the Free Software Foundation; either version 3 of the License, or
9ed6a76a9Schristos    (at your option) any later version.
10ed6a76a9Schristos 
11ed6a76a9Schristos    This program is distributed in the hope that it will be useful,
12ed6a76a9Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13ed6a76a9Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14ed6a76a9Schristos    GNU General Public License for more details.
15ed6a76a9Schristos 
16ed6a76a9Schristos    You should have received a copy of the GNU General Public License
17ed6a76a9Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1866e63ce3Schristos 
1948596154Schristos #include "config.h"
2066e63ce3Schristos #include <signal.h>
2166e63ce3Schristos #include <string.h>
2266e63ce3Schristos #include <stdio.h>
2366e63ce3Schristos #include <stdlib.h>
2466e63ce3Schristos #include <ctype.h>
2566e63ce3Schristos #include "sis.h"
2666e63ce3Schristos #include <dis-asm.h>
2766e63ce3Schristos #include "sim-config.h"
28ed6a76a9Schristos #include <inttypes.h>
2966e63ce3Schristos 
3066e63ce3Schristos #define	VAL(x)	strtoul(x,(char **)NULL,0)
3166e63ce3Schristos 
3266e63ce3Schristos struct disassemble_info dinfo;
3366e63ce3Schristos struct pstate   sregs;
3466e63ce3Schristos extern struct estate ebase;
3566e63ce3Schristos int             ctrl_c = 0;
3666e63ce3Schristos int             sis_verbose = 0;
3766e63ce3Schristos char           *sis_version = "2.7.5";
3866e63ce3Schristos int             nfp = 0;
3966e63ce3Schristos int             ift = 0;
4066e63ce3Schristos int             wrp = 0;
4166e63ce3Schristos int             rom8 = 0;
4266e63ce3Schristos int             uben = 0;
4366e63ce3Schristos int		termsave;
4466e63ce3Schristos int             sparclite = 0;		/* emulating SPARClite instructions? */
4566e63ce3Schristos int             sparclite_board = 0;	/* emulating SPARClite board RAM? */
4666e63ce3Schristos char            uart_dev1[128] = "";
4766e63ce3Schristos char            uart_dev2[128] = "";
4866e63ce3Schristos extern	int	ext_irl;
4966e63ce3Schristos uint32		last_load_addr = 0;
5066e63ce3Schristos 
5166e63ce3Schristos #ifdef ERRINJ
5266e63ce3Schristos uint32		errcnt = 0;
5366e63ce3Schristos uint32		errper = 0;
5466e63ce3Schristos uint32		errtt = 0;
5566e63ce3Schristos uint32		errftt = 0;
5666e63ce3Schristos uint32		errmec = 0;
5766e63ce3Schristos #endif
5866e63ce3Schristos 
5966e63ce3Schristos /* Forward declarations */
6066e63ce3Schristos 
617af5a897Schristos static int	batch (struct pstate *sregs, char *fname);
627af5a897Schristos static void	set_rega (struct pstate *sregs, char *reg, uint32 rval);
637af5a897Schristos static void	disp_reg (struct pstate *sregs, char *reg);
647af5a897Schristos static uint32	limcalc (float32 freq);
657af5a897Schristos static void	int_handler (int32 sig);
667af5a897Schristos static void	init_event (void);
677af5a897Schristos static int	disp_fpu (struct pstate  *sregs);
687af5a897Schristos static void	disp_regs (struct pstate  *sregs, int cwp);
697af5a897Schristos static void	disp_ctrl (struct pstate *sregs);
707af5a897Schristos static void	disp_mem (uint32 addr, uint32 len);
7166e63ce3Schristos 
7266e63ce3Schristos static int
batch(sregs,fname)7366e63ce3Schristos batch(sregs, fname)
7466e63ce3Schristos     struct pstate  *sregs;
7566e63ce3Schristos     char           *fname;
7666e63ce3Schristos {
7766e63ce3Schristos     FILE           *fp;
78ed6a76a9Schristos     char           *lbuf = NULL;
79ed6a76a9Schristos     size_t         len = 0;
80ed6a76a9Schristos     size_t         slen;
8166e63ce3Schristos 
8266e63ce3Schristos     if ((fp = fopen(fname, "r")) == NULL) {
8366e63ce3Schristos 	fprintf(stderr, "couldn't open batch file %s\n", fname);
84ed6a76a9Schristos 	return 0;
8566e63ce3Schristos     }
86ed6a76a9Schristos     while (getline(&lbuf, &len, fp) > -1) {
87ed6a76a9Schristos 	slen = strlen(lbuf);
88ed6a76a9Schristos 	if (slen && (lbuf[slen - 1] == '\n')) {
89ed6a76a9Schristos 	    lbuf[slen - 1] = 0;
9066e63ce3Schristos 	    printf("sis> %s\n", lbuf);
9166e63ce3Schristos 	    exec_cmd(sregs, lbuf);
9266e63ce3Schristos 	}
93ed6a76a9Schristos     }
94ed6a76a9Schristos     free(lbuf);
9566e63ce3Schristos     fclose(fp);
96ed6a76a9Schristos     return 1;
9766e63ce3Schristos }
9866e63ce3Schristos 
9966e63ce3Schristos void
set_regi(sregs,reg,rval)10066e63ce3Schristos set_regi(sregs, reg, rval)
10166e63ce3Schristos     struct pstate  *sregs;
10266e63ce3Schristos     int32           reg;
10366e63ce3Schristos     uint32          rval;
10466e63ce3Schristos {
10566e63ce3Schristos     uint32          cwp;
10666e63ce3Schristos 
10766e63ce3Schristos     cwp = ((sregs->psr & 0x7) << 4);
10866e63ce3Schristos     if ((reg > 0) && (reg < 8)) {
10966e63ce3Schristos 	sregs->g[reg] = rval;
11066e63ce3Schristos     } else if ((reg >= 8) && (reg < 32)) {
11166e63ce3Schristos 	sregs->r[(cwp + reg) & 0x7f] = rval;
11266e63ce3Schristos     } else if ((reg >= 32) && (reg < 64)) {
11366e63ce3Schristos 	sregs->fsi[reg - 32] = rval;
11466e63ce3Schristos     } else {
11566e63ce3Schristos 	switch (reg) {
11666e63ce3Schristos 	case 64:
11766e63ce3Schristos 	    sregs->y = rval;
11866e63ce3Schristos 	    break;
11966e63ce3Schristos 	case 65:
12066e63ce3Schristos 	    sregs->psr = rval;
12166e63ce3Schristos 	    break;
12266e63ce3Schristos 	case 66:
12366e63ce3Schristos 	    sregs->wim = rval;
12466e63ce3Schristos 	    break;
12566e63ce3Schristos 	case 67:
12666e63ce3Schristos 	    sregs->tbr = rval;
12766e63ce3Schristos 	    break;
12866e63ce3Schristos 	case 68:
12966e63ce3Schristos 	    sregs->pc = rval;
13066e63ce3Schristos 	    break;
13166e63ce3Schristos 	case 69:
13266e63ce3Schristos 	    sregs->npc = rval;
13366e63ce3Schristos 	    break;
13466e63ce3Schristos 	case 70:
13566e63ce3Schristos 	    sregs->fsr = rval;
13666e63ce3Schristos 	    set_fsr(rval);
13766e63ce3Schristos 	    break;
13866e63ce3Schristos     default:break;
13966e63ce3Schristos 	}
14066e63ce3Schristos     }
14166e63ce3Schristos }
14266e63ce3Schristos 
14366e63ce3Schristos void
get_regi(struct pstate * sregs,int32 reg,char * buf)14466e63ce3Schristos get_regi(struct pstate * sregs, int32 reg, char *buf)
14566e63ce3Schristos {
14666e63ce3Schristos     uint32          cwp;
14766e63ce3Schristos     uint32          rval = 0;
14866e63ce3Schristos 
14966e63ce3Schristos     cwp = ((sregs->psr & 0x7) << 4);
15066e63ce3Schristos     if ((reg >= 0) && (reg < 8)) {
15166e63ce3Schristos 	rval = sregs->g[reg];
15266e63ce3Schristos     } else if ((reg >= 8) && (reg < 32)) {
15366e63ce3Schristos 	rval = sregs->r[(cwp + reg) & 0x7f];
15466e63ce3Schristos     } else if ((reg >= 32) && (reg < 64)) {
15566e63ce3Schristos 	rval = sregs->fsi[reg - 32];
15666e63ce3Schristos     } else {
15766e63ce3Schristos 	switch (reg) {
15866e63ce3Schristos 	case 64:
15966e63ce3Schristos 	    rval = sregs->y;
16066e63ce3Schristos 	    break;
16166e63ce3Schristos 	case 65:
16266e63ce3Schristos 	    rval = sregs->psr;
16366e63ce3Schristos 	    break;
16466e63ce3Schristos 	case 66:
16566e63ce3Schristos 	    rval = sregs->wim;
16666e63ce3Schristos 	    break;
16766e63ce3Schristos 	case 67:
16866e63ce3Schristos 	    rval = sregs->tbr;
16966e63ce3Schristos 	    break;
17066e63ce3Schristos 	case 68:
17166e63ce3Schristos 	    rval = sregs->pc;
17266e63ce3Schristos 	    break;
17366e63ce3Schristos 	case 69:
17466e63ce3Schristos 	    rval = sregs->npc;
17566e63ce3Schristos 	    break;
17666e63ce3Schristos 	case 70:
17766e63ce3Schristos 	    rval = sregs->fsr;
17866e63ce3Schristos 	    break;
17966e63ce3Schristos     default:break;
18066e63ce3Schristos 	}
18166e63ce3Schristos     }
18266e63ce3Schristos     buf[0] = (rval >> 24) & 0x0ff;
18366e63ce3Schristos     buf[1] = (rval >> 16) & 0x0ff;
18466e63ce3Schristos     buf[2] = (rval >> 8) & 0x0ff;
18566e63ce3Schristos     buf[3] = rval & 0x0ff;
18666e63ce3Schristos }
18766e63ce3Schristos 
18866e63ce3Schristos 
18966e63ce3Schristos static void
set_rega(sregs,reg,rval)19066e63ce3Schristos set_rega(sregs, reg, rval)
19166e63ce3Schristos     struct pstate  *sregs;
19266e63ce3Schristos     char           *reg;
19366e63ce3Schristos     uint32          rval;
19466e63ce3Schristos {
19566e63ce3Schristos     uint32          cwp;
19666e63ce3Schristos     int32           err = 0;
19766e63ce3Schristos 
19866e63ce3Schristos     cwp = ((sregs->psr & 0x7) << 4);
19966e63ce3Schristos     if (strcmp(reg, "psr") == 0)
20066e63ce3Schristos 	sregs->psr = (rval = (rval & 0x00f03fff));
20166e63ce3Schristos     else if (strcmp(reg, "tbr") == 0)
20266e63ce3Schristos 	sregs->tbr = (rval = (rval & 0xfffffff0));
20366e63ce3Schristos     else if (strcmp(reg, "wim") == 0)
20466e63ce3Schristos 	sregs->wim = (rval = (rval & 0x0ff));
20566e63ce3Schristos     else if (strcmp(reg, "y") == 0)
20666e63ce3Schristos 	sregs->y = rval;
20766e63ce3Schristos     else if (strcmp(reg, "pc") == 0)
20866e63ce3Schristos 	sregs->pc = rval;
20966e63ce3Schristos     else if (strcmp(reg, "npc") == 0)
21066e63ce3Schristos 	sregs->npc = rval;
21166e63ce3Schristos     else if (strcmp(reg, "fsr") == 0) {
21266e63ce3Schristos 	sregs->fsr = rval;
21366e63ce3Schristos 	set_fsr(rval);
21466e63ce3Schristos     } else if (strcmp(reg, "g0") == 0)
21566e63ce3Schristos 	err = 2;
21666e63ce3Schristos     else if (strcmp(reg, "g1") == 0)
21766e63ce3Schristos 	sregs->g[1] = rval;
21866e63ce3Schristos     else if (strcmp(reg, "g2") == 0)
21966e63ce3Schristos 	sregs->g[2] = rval;
22066e63ce3Schristos     else if (strcmp(reg, "g3") == 0)
22166e63ce3Schristos 	sregs->g[3] = rval;
22266e63ce3Schristos     else if (strcmp(reg, "g4") == 0)
22366e63ce3Schristos 	sregs->g[4] = rval;
22466e63ce3Schristos     else if (strcmp(reg, "g5") == 0)
22566e63ce3Schristos 	sregs->g[5] = rval;
22666e63ce3Schristos     else if (strcmp(reg, "g6") == 0)
22766e63ce3Schristos 	sregs->g[6] = rval;
22866e63ce3Schristos     else if (strcmp(reg, "g7") == 0)
22966e63ce3Schristos 	sregs->g[7] = rval;
23066e63ce3Schristos     else if (strcmp(reg, "o0") == 0)
23166e63ce3Schristos 	sregs->r[(cwp + 8) & 0x7f] = rval;
23266e63ce3Schristos     else if (strcmp(reg, "o1") == 0)
23366e63ce3Schristos 	sregs->r[(cwp + 9) & 0x7f] = rval;
23466e63ce3Schristos     else if (strcmp(reg, "o2") == 0)
23566e63ce3Schristos 	sregs->r[(cwp + 10) & 0x7f] = rval;
23666e63ce3Schristos     else if (strcmp(reg, "o3") == 0)
23766e63ce3Schristos 	sregs->r[(cwp + 11) & 0x7f] = rval;
23866e63ce3Schristos     else if (strcmp(reg, "o4") == 0)
23966e63ce3Schristos 	sregs->r[(cwp + 12) & 0x7f] = rval;
24066e63ce3Schristos     else if (strcmp(reg, "o5") == 0)
24166e63ce3Schristos 	sregs->r[(cwp + 13) & 0x7f] = rval;
24266e63ce3Schristos     else if (strcmp(reg, "o6") == 0)
24366e63ce3Schristos 	sregs->r[(cwp + 14) & 0x7f] = rval;
24466e63ce3Schristos     else if (strcmp(reg, "o7") == 0)
24566e63ce3Schristos 	sregs->r[(cwp + 15) & 0x7f] = rval;
24666e63ce3Schristos     else if (strcmp(reg, "l0") == 0)
24766e63ce3Schristos 	sregs->r[(cwp + 16) & 0x7f] = rval;
24866e63ce3Schristos     else if (strcmp(reg, "l1") == 0)
24966e63ce3Schristos 	sregs->r[(cwp + 17) & 0x7f] = rval;
25066e63ce3Schristos     else if (strcmp(reg, "l2") == 0)
25166e63ce3Schristos 	sregs->r[(cwp + 18) & 0x7f] = rval;
25266e63ce3Schristos     else if (strcmp(reg, "l3") == 0)
25366e63ce3Schristos 	sregs->r[(cwp + 19) & 0x7f] = rval;
25466e63ce3Schristos     else if (strcmp(reg, "l4") == 0)
25566e63ce3Schristos 	sregs->r[(cwp + 20) & 0x7f] = rval;
25666e63ce3Schristos     else if (strcmp(reg, "l5") == 0)
25766e63ce3Schristos 	sregs->r[(cwp + 21) & 0x7f] = rval;
25866e63ce3Schristos     else if (strcmp(reg, "l6") == 0)
25966e63ce3Schristos 	sregs->r[(cwp + 22) & 0x7f] = rval;
26066e63ce3Schristos     else if (strcmp(reg, "l7") == 0)
26166e63ce3Schristos 	sregs->r[(cwp + 23) & 0x7f] = rval;
26266e63ce3Schristos     else if (strcmp(reg, "i0") == 0)
26366e63ce3Schristos 	sregs->r[(cwp + 24) & 0x7f] = rval;
26466e63ce3Schristos     else if (strcmp(reg, "i1") == 0)
26566e63ce3Schristos 	sregs->r[(cwp + 25) & 0x7f] = rval;
26666e63ce3Schristos     else if (strcmp(reg, "i2") == 0)
26766e63ce3Schristos 	sregs->r[(cwp + 26) & 0x7f] = rval;
26866e63ce3Schristos     else if (strcmp(reg, "i3") == 0)
26966e63ce3Schristos 	sregs->r[(cwp + 27) & 0x7f] = rval;
27066e63ce3Schristos     else if (strcmp(reg, "i4") == 0)
27166e63ce3Schristos 	sregs->r[(cwp + 28) & 0x7f] = rval;
27266e63ce3Schristos     else if (strcmp(reg, "i5") == 0)
27366e63ce3Schristos 	sregs->r[(cwp + 29) & 0x7f] = rval;
27466e63ce3Schristos     else if (strcmp(reg, "i6") == 0)
27566e63ce3Schristos 	sregs->r[(cwp + 30) & 0x7f] = rval;
27666e63ce3Schristos     else if (strcmp(reg, "i7") == 0)
27766e63ce3Schristos 	sregs->r[(cwp + 31) & 0x7f] = rval;
27866e63ce3Schristos     else
27966e63ce3Schristos 	err = 1;
28066e63ce3Schristos     switch (err) {
28166e63ce3Schristos     case 0:
28266e63ce3Schristos 	printf("%s = %d (0x%08x)\n", reg, rval, rval);
28366e63ce3Schristos 	break;
28466e63ce3Schristos     case 1:
28566e63ce3Schristos 	printf("no such regiser: %s\n", reg);
28666e63ce3Schristos 	break;
28766e63ce3Schristos     case 2:
28866e63ce3Schristos 	printf("cannot set g0\n");
28966e63ce3Schristos 	break;
29066e63ce3Schristos     default:
29166e63ce3Schristos 	break;
29266e63ce3Schristos     }
29366e63ce3Schristos 
29466e63ce3Schristos }
29566e63ce3Schristos 
29666e63ce3Schristos static void
disp_reg(sregs,reg)29766e63ce3Schristos disp_reg(sregs, reg)
29866e63ce3Schristos     struct pstate  *sregs;
29966e63ce3Schristos     char           *reg;
30066e63ce3Schristos {
30166e63ce3Schristos     if (strncmp(reg, "w",1) == 0)
30266e63ce3Schristos 	disp_regs(sregs, VAL(&reg[1]));
30366e63ce3Schristos }
30466e63ce3Schristos 
30566e63ce3Schristos #ifdef ERRINJ
30666e63ce3Schristos 
30766e63ce3Schristos void
errinj()30866e63ce3Schristos errinj()
30966e63ce3Schristos {
31066e63ce3Schristos     int	err;
31166e63ce3Schristos 
31266e63ce3Schristos     switch (err = (random() % 12)) {
31366e63ce3Schristos 	case 0: errtt = 0x61; break;
31466e63ce3Schristos 	case 1: errtt = 0x62; break;
31566e63ce3Schristos 	case 2: errtt = 0x63; break;
31666e63ce3Schristos 	case 3: errtt = 0x64; break;
31766e63ce3Schristos 	case 4: errtt = 0x65; break;
31866e63ce3Schristos 	case 5:
31966e63ce3Schristos 	case 6:
32066e63ce3Schristos 	case 7: errftt = err;
32166e63ce3Schristos 		break;
32266e63ce3Schristos 	case 8: errmec = 1; break;
32366e63ce3Schristos 	case 9: errmec = 2; break;
32466e63ce3Schristos 	case 10: errmec = 5; break;
32566e63ce3Schristos 	case 11: errmec = 6; break;
32666e63ce3Schristos     }
32766e63ce3Schristos     errcnt++;
32866e63ce3Schristos     if (errper) event(errinj, 0, (random()%errper));
32966e63ce3Schristos }
33066e63ce3Schristos 
33166e63ce3Schristos void
errinjstart()33266e63ce3Schristos errinjstart()
33366e63ce3Schristos {
33466e63ce3Schristos     if (errper) event(errinj, 0, (random()%errper));
33566e63ce3Schristos }
33666e63ce3Schristos 
33766e63ce3Schristos #endif
33866e63ce3Schristos 
33966e63ce3Schristos static uint32
limcalc(freq)34066e63ce3Schristos limcalc (freq)
34166e63ce3Schristos     float32		freq;
34266e63ce3Schristos {
34366e63ce3Schristos     uint32          unit, lim;
34466e63ce3Schristos     double	    flim;
34566e63ce3Schristos     char           *cmd1, *cmd2;
34666e63ce3Schristos 
34766e63ce3Schristos     unit = 1;
34866e63ce3Schristos     lim = -1;
34966e63ce3Schristos     if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
35066e63ce3Schristos         lim = VAL(cmd1);
35166e63ce3Schristos         if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
35266e63ce3Schristos             if (strcmp(cmd2,"us")==0) unit = 1;
35366e63ce3Schristos       	    if (strcmp(cmd2,"ms")==0) unit = 1000;
35466e63ce3Schristos             if (strcmp(cmd2,"s")==0)  unit = 1000000;
35566e63ce3Schristos         }
35666e63ce3Schristos         flim = (double) lim * (double) unit * (double) freq +
35766e63ce3Schristos 	   (double) ebase.simtime;
35866e63ce3Schristos         if ((flim > ebase.simtime) && (flim < 4294967296.0)) {
35966e63ce3Schristos             lim = (uint32) flim;
36066e63ce3Schristos         } else  {
36166e63ce3Schristos             printf("error in expression\n");
36266e63ce3Schristos             lim = -1;
36366e63ce3Schristos         }
36466e63ce3Schristos     }
365ed6a76a9Schristos     return lim;
36666e63ce3Schristos }
36766e63ce3Schristos 
36866e63ce3Schristos int
exec_cmd(struct pstate * sregs,const char * cmd)369ed6a76a9Schristos exec_cmd(struct pstate *sregs, const char *cmd)
37066e63ce3Schristos {
37166e63ce3Schristos     char           *cmd1, *cmd2;
37266e63ce3Schristos     int32           stat;
37366e63ce3Schristos     uint32          len, i, clen, j;
37466e63ce3Schristos     static uint32   daddr = 0;
375ed6a76a9Schristos     char           *cmdsave, *cmdsave2 = NULL;
37666e63ce3Schristos 
37766e63ce3Schristos     stat = OK;
37866e63ce3Schristos     cmdsave = strdup(cmd);
379ed6a76a9Schristos     cmdsave2 = strdup (cmd);
380ed6a76a9Schristos     if ((cmd1 = strtok (cmdsave2, " \t")) != NULL) {
38166e63ce3Schristos 	clen = strlen(cmd1);
38266e63ce3Schristos 	if (strncmp(cmd1, "bp", clen) == 0) {
38366e63ce3Schristos 	    for (i = 0; i < sregs->bptnum; i++) {
38466e63ce3Schristos 		printf("  %d : 0x%08x\n", i + 1, sregs->bpts[i]);
38566e63ce3Schristos 	    }
38666e63ce3Schristos 	} else if (strncmp(cmd1, "+bp", clen) == 0) {
38766e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
38866e63ce3Schristos 		sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;
38966e63ce3Schristos 		printf("added breakpoint %d at 0x%08x\n",
39066e63ce3Schristos 		       sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);
39166e63ce3Schristos 		sregs->bptnum += 1;
39266e63ce3Schristos 	    }
39366e63ce3Schristos 	} else if (strncmp(cmd1, "-bp", clen) == 0) {
39466e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
39566e63ce3Schristos 		i = VAL(cmd1) - 1;
39666e63ce3Schristos 		if ((i >= 0) && (i < sregs->bptnum)) {
39766e63ce3Schristos 		    printf("deleted breakpoint %d at 0x%08x\n", i + 1,
39866e63ce3Schristos 			   sregs->bpts[i]);
39966e63ce3Schristos 		    for (; i < sregs->bptnum - 1; i++) {
40066e63ce3Schristos 			sregs->bpts[i] = sregs->bpts[i + 1];
40166e63ce3Schristos 		    }
40266e63ce3Schristos 		    sregs->bptnum -= 1;
40366e63ce3Schristos 		}
40466e63ce3Schristos 	    }
40566e63ce3Schristos 	} else if (strncmp(cmd1, "batch", clen) == 0) {
40666e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
40766e63ce3Schristos 		printf("no file specified\n");
40866e63ce3Schristos 	    } else {
40966e63ce3Schristos 		batch(sregs, cmd1);
41066e63ce3Schristos 	    }
41166e63ce3Schristos 	} else if (strncmp(cmd1, "cont", clen) == 0) {
41266e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
41366e63ce3Schristos 		stat = run_sim(sregs, UINT64_MAX, 0);
41466e63ce3Schristos 	    } else {
41566e63ce3Schristos 		stat = run_sim(sregs, VAL(cmd1), 0);
41666e63ce3Schristos 	    }
41766e63ce3Schristos 	    daddr = sregs->pc;
41866e63ce3Schristos 	    sim_halt();
41966e63ce3Schristos 	} else if (strncmp(cmd1, "debug", clen) == 0) {
42066e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
42166e63ce3Schristos 		sis_verbose = VAL(cmd1);
42266e63ce3Schristos 	    }
42366e63ce3Schristos 	    printf("Debug level = %d\n",sis_verbose);
42466e63ce3Schristos 	} else if (strncmp(cmd1, "dis", clen) == 0) {
42566e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
42666e63ce3Schristos 		daddr = VAL(cmd1);
42766e63ce3Schristos 	    }
42866e63ce3Schristos 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
42966e63ce3Schristos 		len = VAL(cmd2);
43066e63ce3Schristos 	    } else
43166e63ce3Schristos 		len = 16;
43266e63ce3Schristos 	    printf("\n");
43366e63ce3Schristos 	    dis_mem(daddr, len, &dinfo);
43466e63ce3Schristos 	    printf("\n");
43566e63ce3Schristos 	    daddr += len * 4;
43666e63ce3Schristos 	} else if (strncmp(cmd1, "echo", clen) == 0) {
43766e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
43866e63ce3Schristos 		printf("%s\n", (&cmdsave[clen+1]));
43966e63ce3Schristos 	    }
44066e63ce3Schristos #ifdef ERRINJ
44166e63ce3Schristos 	} else if (strncmp(cmd1, "error", clen) == 0) {
44266e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
44366e63ce3Schristos 		errper = VAL(cmd1);
44466e63ce3Schristos 	        if (errper) {
44566e63ce3Schristos 		    event(errinj, 0, (len = (random()%errper)));
44666e63ce3Schristos 		    printf("Error injection started with period %d\n",len);
44766e63ce3Schristos 	        }
44866e63ce3Schristos 	     } else printf("Injected errors: %d\n",errcnt);
44966e63ce3Schristos #endif
45066e63ce3Schristos 	} else if (strncmp(cmd1, "float", clen) == 0) {
45166e63ce3Schristos 	    stat = disp_fpu(sregs);
45266e63ce3Schristos 	} else if (strncmp(cmd1, "go", clen) == 0) {
45366e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
45466e63ce3Schristos 		len = last_load_addr;
45566e63ce3Schristos 	    } else {
45666e63ce3Schristos 		len = VAL(cmd1);
45766e63ce3Schristos 	    }
45866e63ce3Schristos 	    sregs->pc = len & ~3;
45966e63ce3Schristos 	    sregs->npc = sregs->pc + 4;
460ed6a76a9Schristos 	    if ((sregs->pc != 0) && (ebase.simtime == 0))
461ed6a76a9Schristos 	        boot_init();
46266e63ce3Schristos 	    printf("resuming at 0x%08x\n",sregs->pc);
46366e63ce3Schristos 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
46466e63ce3Schristos 		stat = run_sim(sregs, VAL(cmd2), 0);
46566e63ce3Schristos 	    } else {
46666e63ce3Schristos 		stat = run_sim(sregs, UINT64_MAX, 0);
46766e63ce3Schristos 	    }
46866e63ce3Schristos 	    daddr = sregs->pc;
46966e63ce3Schristos 	    sim_halt();
47066e63ce3Schristos 	} else if (strncmp(cmd1, "help", clen) == 0) {
47166e63ce3Schristos 	    gen_help();
47266e63ce3Schristos 	} else if (strncmp(cmd1, "history", clen) == 0) {
47366e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
47466e63ce3Schristos 		sregs->histlen = VAL(cmd1);
47566e63ce3Schristos 		if (sregs->histbuf != NULL)
47666e63ce3Schristos 		    free(sregs->histbuf);
47766e63ce3Schristos 		sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));
47866e63ce3Schristos 		printf("trace history length = %d\n\r", sregs->histlen);
47966e63ce3Schristos 		sregs->histind = 0;
48066e63ce3Schristos 
48166e63ce3Schristos 	    } else {
48266e63ce3Schristos 		j = sregs->histind;
48366e63ce3Schristos 		for (i = 0; i < sregs->histlen; i++) {
48466e63ce3Schristos 		    if (j >= sregs->histlen)
48566e63ce3Schristos 			j = 0;
48666e63ce3Schristos 		    printf(" %8d ", sregs->histbuf[j].time);
48766e63ce3Schristos 		    dis_mem(sregs->histbuf[j].addr, 1, &dinfo);
48866e63ce3Schristos 		    j++;
48966e63ce3Schristos 		}
49066e63ce3Schristos 	    }
49166e63ce3Schristos 
49266e63ce3Schristos 	} else if (strncmp(cmd1, "load", clen) == 0) {
49366e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
49466e63ce3Schristos 		last_load_addr = bfd_load(cmd1);
49566e63ce3Schristos 		while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
49666e63ce3Schristos 		    last_load_addr = bfd_load(cmd1);
49766e63ce3Schristos 	    } else {
49866e63ce3Schristos 		printf("load: no file specified\n");
49966e63ce3Schristos 	    }
50066e63ce3Schristos 	} else if (strncmp(cmd1, "mem", clen) == 0) {
50166e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
50266e63ce3Schristos 		daddr = VAL(cmd1);
50366e63ce3Schristos 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL)
50466e63ce3Schristos 		len = VAL(cmd2);
50566e63ce3Schristos 	    else
50666e63ce3Schristos 		len = 64;
50766e63ce3Schristos 	    disp_mem(daddr, len);
50866e63ce3Schristos 	    daddr += len;
50966e63ce3Schristos 	} else if (strncmp(cmd1, "perf", clen) == 0) {
51066e63ce3Schristos 	    cmd1 = strtok(NULL, " \t\n\r");
51166e63ce3Schristos 	    if ((cmd1 != NULL) &&
51266e63ce3Schristos 		(strncmp(cmd1, "reset", strlen(cmd1)) == 0)) {
51366e63ce3Schristos 		reset_stat(sregs);
51466e63ce3Schristos 	    } else
51566e63ce3Schristos 		show_stat(sregs);
51666e63ce3Schristos 	} else if (strncmp(cmd1, "quit", clen) == 0) {
51766e63ce3Schristos 	    exit(0);
51866e63ce3Schristos 	} else if (strncmp(cmd1, "reg", clen) == 0) {
51966e63ce3Schristos 	    cmd1 = strtok(NULL, " \t\n\r");
52066e63ce3Schristos 	    cmd2 = strtok(NULL, " \t\n\r");
52166e63ce3Schristos 	    if (cmd2 != NULL)
52266e63ce3Schristos 		set_rega(sregs, cmd1, VAL(cmd2));
52366e63ce3Schristos 	    else if (cmd1 != NULL)
52466e63ce3Schristos 		disp_reg(sregs, cmd1);
52566e63ce3Schristos 	    else {
52666e63ce3Schristos 		disp_regs(sregs,sregs->psr);
52766e63ce3Schristos 		disp_ctrl(sregs);
52866e63ce3Schristos 	    }
52966e63ce3Schristos 	} else if (strncmp(cmd1, "reset", clen) == 0) {
53066e63ce3Schristos 	    ebase.simtime = 0;
53166e63ce3Schristos 	    reset_all();
53266e63ce3Schristos 	    reset_stat(sregs);
53366e63ce3Schristos 	} else if (strncmp(cmd1, "run", clen) == 0) {
53466e63ce3Schristos 	    ebase.simtime = 0;
53566e63ce3Schristos 	    reset_all();
53666e63ce3Schristos 	    reset_stat(sregs);
53766e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
53866e63ce3Schristos 		stat = run_sim(sregs, UINT64_MAX, 0);
53966e63ce3Schristos 	    } else {
54066e63ce3Schristos 		stat = run_sim(sregs, VAL(cmd1), 0);
54166e63ce3Schristos 	    }
54266e63ce3Schristos 	    daddr = sregs->pc;
54366e63ce3Schristos 	    sim_halt();
54466e63ce3Schristos 	} else if (strncmp(cmd1, "shell", clen) == 0) {
54566e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
546ed6a76a9Schristos 		if (system(&cmdsave[clen])) {
547ed6a76a9Schristos 		    /* Silence unused return value warning.  */
548ed6a76a9Schristos 		}
54966e63ce3Schristos 	    }
55066e63ce3Schristos 	} else if (strncmp(cmd1, "step", clen) == 0) {
55166e63ce3Schristos 	    stat = run_sim(sregs, 1, 1);
55266e63ce3Schristos 	    daddr = sregs->pc;
55366e63ce3Schristos 	    sim_halt();
55466e63ce3Schristos 	} else if (strncmp(cmd1, "tcont", clen) == 0) {
55566e63ce3Schristos 	    sregs->tlimit = limcalc(sregs->freq);
55666e63ce3Schristos 	    stat = run_sim(sregs, UINT64_MAX, 0);
55766e63ce3Schristos 	    daddr = sregs->pc;
55866e63ce3Schristos 	    sim_halt();
55966e63ce3Schristos 	} else if (strncmp(cmd1, "tgo", clen) == 0) {
56066e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
56166e63ce3Schristos 		len = last_load_addr;
56266e63ce3Schristos 	    } else {
56366e63ce3Schristos 		len = VAL(cmd1);
56466e63ce3Schristos 	        sregs->tlimit = limcalc(sregs->freq);
56566e63ce3Schristos 	    }
56666e63ce3Schristos 	    sregs->pc = len & ~3;
56766e63ce3Schristos 	    sregs->npc = sregs->pc + 4;
56866e63ce3Schristos 	    printf("resuming at 0x%08x\n",sregs->pc);
56966e63ce3Schristos 	    stat = run_sim(sregs, UINT64_MAX, 0);
57066e63ce3Schristos 	    daddr = sregs->pc;
57166e63ce3Schristos 	    sim_halt();
57266e63ce3Schristos 	} else if (strncmp(cmd1, "tlimit", clen) == 0) {
57366e63ce3Schristos 	   sregs->tlimit = limcalc(sregs->freq);
57466e63ce3Schristos 	   if (sregs->tlimit != (uint32) -1)
57566e63ce3Schristos               printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit,
57666e63ce3Schristos 		sregs->tlimit / sregs->freq / 1000);
57766e63ce3Schristos 	} else if (strncmp(cmd1, "tra", clen) == 0) {
57866e63ce3Schristos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
57966e63ce3Schristos 		stat = run_sim(sregs, UINT64_MAX, 1);
58066e63ce3Schristos 	    } else {
58166e63ce3Schristos 		stat = run_sim(sregs, VAL(cmd1), 1);
58266e63ce3Schristos 	    }
58366e63ce3Schristos 	    printf("\n");
58466e63ce3Schristos 	    daddr = sregs->pc;
58566e63ce3Schristos 	    sim_halt();
58666e63ce3Schristos 	} else if (strncmp(cmd1, "trun", clen) == 0) {
58766e63ce3Schristos 	    ebase.simtime = 0;
58866e63ce3Schristos 	    reset_all();
58966e63ce3Schristos 	    reset_stat(sregs);
59066e63ce3Schristos 	    sregs->tlimit = limcalc(sregs->freq);
59166e63ce3Schristos 	    stat = run_sim(sregs, UINT64_MAX, 0);
59266e63ce3Schristos 	    daddr = sregs->pc;
59366e63ce3Schristos 	    sim_halt();
59466e63ce3Schristos 	} else
59566e63ce3Schristos 	    printf("syntax error\n");
59666e63ce3Schristos     }
597ed6a76a9Schristos     if (cmdsave2 != NULL)
598ed6a76a9Schristos 	free(cmdsave2);
59966e63ce3Schristos     if (cmdsave != NULL)
60066e63ce3Schristos 	free(cmdsave);
601ed6a76a9Schristos     return stat;
60266e63ce3Schristos }
60366e63ce3Schristos 
60466e63ce3Schristos 
60566e63ce3Schristos void
reset_stat(sregs)60666e63ce3Schristos reset_stat(sregs)
60766e63ce3Schristos     struct pstate  *sregs;
60866e63ce3Schristos {
609ed6a76a9Schristos     sregs->tottime = 0.0;
61066e63ce3Schristos     sregs->pwdtime = 0;
61166e63ce3Schristos     sregs->ninst = 0;
61266e63ce3Schristos     sregs->fholdt = 0;
61366e63ce3Schristos     sregs->holdt = 0;
61466e63ce3Schristos     sregs->icntt = 0;
61566e63ce3Schristos     sregs->finst = 0;
61666e63ce3Schristos     sregs->nstore = 0;
61766e63ce3Schristos     sregs->nload = 0;
61866e63ce3Schristos     sregs->nbranch = 0;
61966e63ce3Schristos     sregs->simstart = ebase.simtime;
62066e63ce3Schristos 
62166e63ce3Schristos }
62266e63ce3Schristos 
62366e63ce3Schristos void
show_stat(sregs)62466e63ce3Schristos show_stat(sregs)
62566e63ce3Schristos     struct pstate  *sregs;
62666e63ce3Schristos {
62766e63ce3Schristos     uint32          iinst;
628ed6a76a9Schristos     uint32          stime;
62966e63ce3Schristos 
630ed6a76a9Schristos     if (sregs->tottime == 0.0)
631ed6a76a9Schristos         sregs->tottime += 1E-6;
63266e63ce3Schristos     stime = ebase.simtime - sregs->simstart;	/* Total simulated time */
63366e63ce3Schristos #ifdef STAT
63466e63ce3Schristos 
63566e63ce3Schristos     iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore -
63666e63ce3Schristos 	sregs->nbranch;
63766e63ce3Schristos #endif
63866e63ce3Schristos 
639ed6a76a9Schristos     printf("\n Cycles       : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
640ed6a76a9Schristos     printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
64166e63ce3Schristos 
64266e63ce3Schristos #ifdef STAT
64366e63ce3Schristos     printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
64466e63ce3Schristos     printf("   load       : %9.2f %%\n",
64566e63ce3Schristos 	   100.0 * (float) sregs->nload / (float) sregs->ninst);
64666e63ce3Schristos     printf("   store      : %9.2f %%\n",
64766e63ce3Schristos 	   100.0 * (float) sregs->nstore / (float) sregs->ninst);
64866e63ce3Schristos     printf("   branch     : %9.2f %%\n",
64966e63ce3Schristos 	   100.0 * (float) sregs->nbranch / (float) sregs->ninst);
65066e63ce3Schristos     printf("   float      : %9.2f %%\n",
65166e63ce3Schristos 	   100.0 * (float) sregs->finst / (float) sregs->ninst);
65266e63ce3Schristos     printf(" Integer CPI  : %9.2f\n",
65366e63ce3Schristos 	   ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
65466e63ce3Schristos 	   /
65566e63ce3Schristos 	   (float) (sregs->ninst - sregs->finst));
65666e63ce3Schristos     printf(" Float CPI    : %9.2f\n",
65766e63ce3Schristos 	   ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
65866e63ce3Schristos #endif
65966e63ce3Schristos     printf(" Overall CPI  : %9.2f\n",
66066e63ce3Schristos 	   (float) (stime - sregs->pwdtime) / (float) sregs->ninst);
66166e63ce3Schristos     printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
66266e63ce3Schristos 	   sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime),
66366e63ce3Schristos 	   sregs->freq * (float) (sregs->ninst - sregs->finst) /
66466e63ce3Schristos 	   (float) (stime - sregs->pwdtime),
66566e63ce3Schristos      sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
666ed6a76a9Schristos     printf(" Simulated ERC32 time        : %.2f s\n",
667ed6a76a9Schristos         (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
668ed6a76a9Schristos     printf(" Processor utilisation       : %.2f %%\n",
669ed6a76a9Schristos         100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
670ed6a76a9Schristos     printf(" Real-time performance       : %.2f %%\n",
671ed6a76a9Schristos         100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
672ed6a76a9Schristos     printf(" Simulator performance       : %.2f MIPS\n",
673ed6a76a9Schristos         (double)(sregs->ninst) / sregs->tottime / 1E6);
674ed6a76a9Schristos     printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);
67566e63ce3Schristos }
67666e63ce3Schristos 
67766e63ce3Schristos 
67866e63ce3Schristos 
67966e63ce3Schristos void
init_bpt(sregs)68066e63ce3Schristos init_bpt(sregs)
68166e63ce3Schristos     struct pstate  *sregs;
68266e63ce3Schristos {
68366e63ce3Schristos     sregs->bptnum = 0;
68466e63ce3Schristos     sregs->histlen = 0;
68566e63ce3Schristos     sregs->histind = 0;
68666e63ce3Schristos     sregs->histbuf = NULL;
68766e63ce3Schristos     sregs->tlimit = -1;
68866e63ce3Schristos }
68966e63ce3Schristos 
69066e63ce3Schristos static void
int_handler(sig)69166e63ce3Schristos int_handler(sig)
69266e63ce3Schristos     int32           sig;
69366e63ce3Schristos {
69466e63ce3Schristos     if (sig != 2)
69566e63ce3Schristos 	printf("\n\n Signal handler error  (%d)\n\n", sig);
69666e63ce3Schristos     ctrl_c = 1;
69766e63ce3Schristos }
69866e63ce3Schristos 
69966e63ce3Schristos void
init_signals()70066e63ce3Schristos init_signals()
70166e63ce3Schristos {
70266e63ce3Schristos     typedef void    (*PFI) ();
70366e63ce3Schristos     static PFI      int_tab[2];
70466e63ce3Schristos 
70566e63ce3Schristos     int_tab[0] = signal(SIGTERM, int_handler);
70666e63ce3Schristos     int_tab[1] = signal(SIGINT, int_handler);
70766e63ce3Schristos }
70866e63ce3Schristos 
70966e63ce3Schristos 
71066e63ce3Schristos extern struct disassemble_info dinfo;
71166e63ce3Schristos 
71266e63ce3Schristos struct estate   ebase;
71366e63ce3Schristos struct evcell   evbuf[EVENT_MAX];
71466e63ce3Schristos struct irqcell  irqarr[16];
71566e63ce3Schristos 
71666e63ce3Schristos static int
disp_fpu(sregs)71766e63ce3Schristos disp_fpu(sregs)
71866e63ce3Schristos     struct pstate  *sregs;
71966e63ce3Schristos {
72066e63ce3Schristos 
72166e63ce3Schristos     int         i;
72266e63ce3Schristos     float	t;
72366e63ce3Schristos 
72466e63ce3Schristos     printf("\n fsr: %08X\n\n", sregs->fsr);
72566e63ce3Schristos 
726ed6a76a9Schristos #ifdef HOST_LITTLE_ENDIAN
72766e63ce3Schristos     for (i = 0; i < 32; i++)
72866e63ce3Schristos       sregs->fdp[i ^ 1] = sregs->fs[i];
72966e63ce3Schristos #endif
73066e63ce3Schristos 
73166e63ce3Schristos     for (i = 0; i < 32; i++) {
73266e63ce3Schristos 	t = sregs->fs[i];
73366e63ce3Schristos 	printf(" f%02d  %08x  %14e  ", i, sregs->fsi[i], sregs->fs[i]);
73466e63ce3Schristos 	if (!(i & 1))
73566e63ce3Schristos 	    printf("%14e\n", sregs->fd[i >> 1]);
73666e63ce3Schristos 	else
73766e63ce3Schristos 	    printf("\n");
73866e63ce3Schristos     }
73966e63ce3Schristos     printf("\n");
740ed6a76a9Schristos     return OK;
74166e63ce3Schristos }
74266e63ce3Schristos 
74366e63ce3Schristos static void
disp_regs(sregs,cwp)74466e63ce3Schristos disp_regs(sregs,cwp)
74566e63ce3Schristos     struct pstate  *sregs;
74666e63ce3Schristos     int cwp;
74766e63ce3Schristos {
74866e63ce3Schristos 
74966e63ce3Schristos     int           i;
75066e63ce3Schristos 
75166e63ce3Schristos     cwp = ((cwp & 0x7) << 4);
75266e63ce3Schristos     printf("\n\t  INS       LOCALS      OUTS     GLOBALS\n");
75366e63ce3Schristos     for (i = 0; i < 8; i++) {
75466e63ce3Schristos 	printf("   %d:  %08X   %08X   %08X   %08X\n", i,
75566e63ce3Schristos 	       sregs->r[(cwp + i + 24) & 0x7f],
75666e63ce3Schristos 	    sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f],
75766e63ce3Schristos 	       sregs->g[i]);
75866e63ce3Schristos     }
75966e63ce3Schristos }
76066e63ce3Schristos 
print_insn_sparc_sis(uint32 addr,struct disassemble_info * info)761ed6a76a9Schristos static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info)
762ed6a76a9Schristos {
763ed6a76a9Schristos     unsigned char           i[4];
764ed6a76a9Schristos 
765ed6a76a9Schristos     sis_memory_read(addr, i, 4);
766ed6a76a9Schristos     dinfo.buffer_vma = addr;
767ed6a76a9Schristos     dinfo.buffer_length = 4;
768ed6a76a9Schristos     dinfo.buffer = i;
769ed6a76a9Schristos     print_insn_sparc(addr, info);
770ed6a76a9Schristos }
771ed6a76a9Schristos 
77266e63ce3Schristos static void
disp_ctrl(sregs)77366e63ce3Schristos disp_ctrl(sregs)
77466e63ce3Schristos     struct pstate  *sregs;
77566e63ce3Schristos {
77666e63ce3Schristos 
777ed6a76a9Schristos     uint32           i;
77866e63ce3Schristos 
77966e63ce3Schristos     printf("\n psr: %08X   wim: %08X   tbr: %08X   y: %08X\n",
78066e63ce3Schristos 	   sregs->psr, sregs->wim, sregs->tbr, sregs->y);
781ed6a76a9Schristos     sis_memory_read (sregs->pc, (char *) &i, 4);
782ed6a76a9Schristos     printf ("\n  pc: %08X = %08X    ", sregs->pc, i);
783ed6a76a9Schristos     print_insn_sparc_sis(sregs->pc, &dinfo);
784ed6a76a9Schristos     sis_memory_read (sregs->npc, (char *) &i, 4);
785ed6a76a9Schristos     printf ("\n npc: %08X = %08X    ", sregs->npc, i);
786ed6a76a9Schristos     print_insn_sparc_sis(sregs->npc, &dinfo);
78766e63ce3Schristos     if (sregs->err_mode)
78866e63ce3Schristos 	printf("\n IU in error mode");
78966e63ce3Schristos     printf("\n\n");
79066e63ce3Schristos }
79166e63ce3Schristos 
79266e63ce3Schristos static void
disp_mem(addr,len)79366e63ce3Schristos disp_mem(addr, len)
79466e63ce3Schristos     uint32          addr;
79566e63ce3Schristos     uint32          len;
79666e63ce3Schristos {
79766e63ce3Schristos 
79866e63ce3Schristos     uint32          i;
799ed6a76a9Schristos     union {
800ed6a76a9Schristos 	    unsigned char u8[4];
801ed6a76a9Schristos 	    uint32 u32;
802ed6a76a9Schristos     } data;
80366e63ce3Schristos     uint32          mem[4], j;
80466e63ce3Schristos     char           *p;
80566e63ce3Schristos 
80666e63ce3Schristos     for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
80766e63ce3Schristos 	printf("\n %8X  ", i);
80866e63ce3Schristos 	for (j = 0; j < 4; j++) {
809ed6a76a9Schristos 	    sis_memory_read ((i + (j * 4)), data.u8, 4);
810ed6a76a9Schristos 	    printf ("%08x  ", data.u32);
811ed6a76a9Schristos 	    mem[j] = data.u32;
81266e63ce3Schristos 	}
81366e63ce3Schristos 	printf("  ");
81466e63ce3Schristos 	p = (char *) mem;
81566e63ce3Schristos 	for (j = 0; j < 16; j++) {
816ed6a76a9Schristos 	    if (isprint (p[j ^ EBT]))
817ed6a76a9Schristos 		putchar (p[j ^ EBT]);
81866e63ce3Schristos 	    else
81966e63ce3Schristos 		putchar('.');
82066e63ce3Schristos 	}
82166e63ce3Schristos     }
82266e63ce3Schristos     printf("\n\n");
82366e63ce3Schristos }
82466e63ce3Schristos 
82566e63ce3Schristos void
dis_mem(addr,len,info)82666e63ce3Schristos dis_mem(addr, len, info)
82766e63ce3Schristos     uint32          addr;
82866e63ce3Schristos     uint32          len;
82966e63ce3Schristos     struct disassemble_info *info;
83066e63ce3Schristos {
83166e63ce3Schristos     uint32          i;
832ed6a76a9Schristos     union {
833ed6a76a9Schristos 	    unsigned char u8[4];
834ed6a76a9Schristos 	    uint32 u32;
835ed6a76a9Schristos     } data;
83666e63ce3Schristos 
83766e63ce3Schristos     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
838ed6a76a9Schristos 	sis_memory_read (i, data.u8, 4);
839ed6a76a9Schristos 	printf (" %08x  %08x  ", i, data.u32);
840ed6a76a9Schristos 	print_insn_sparc_sis(i, info);
84166e63ce3Schristos         if (i >= 0xfffffffc) break;
84266e63ce3Schristos 	printf("\n");
84366e63ce3Schristos     }
84466e63ce3Schristos }
84566e63ce3Schristos 
84666e63ce3Schristos /* Add event to event queue */
84766e63ce3Schristos 
84866e63ce3Schristos void
84966e63ce3Schristos event(cfunc, arg, delta)
85066e63ce3Schristos     void            (*cfunc) ();
85166e63ce3Schristos     int32           arg;
85266e63ce3Schristos     uint64          delta;
85366e63ce3Schristos {
85466e63ce3Schristos     struct evcell  *ev1, *evins;
85566e63ce3Schristos 
85666e63ce3Schristos     if (ebase.freeq == NULL) {
85766e63ce3Schristos 	printf("Error, too many events in event queue\n");
85866e63ce3Schristos 	return;
85966e63ce3Schristos     }
86066e63ce3Schristos     ev1 = &ebase.eq;
86166e63ce3Schristos     delta += ebase.simtime;
86266e63ce3Schristos     while ((ev1->nxt != NULL) && (ev1->nxt->time <= delta)) {
86366e63ce3Schristos 	ev1 = ev1->nxt;
86466e63ce3Schristos     }
86566e63ce3Schristos     if (ev1->nxt == NULL) {
86666e63ce3Schristos 	ev1->nxt = ebase.freeq;
86766e63ce3Schristos 	ebase.freeq = ebase.freeq->nxt;
86866e63ce3Schristos 	ev1->nxt->nxt = NULL;
86966e63ce3Schristos     } else {
87066e63ce3Schristos 	evins = ebase.freeq;
87166e63ce3Schristos 	ebase.freeq = ebase.freeq->nxt;
87266e63ce3Schristos 	evins->nxt = ev1->nxt;
87366e63ce3Schristos 	ev1->nxt = evins;
87466e63ce3Schristos     }
87566e63ce3Schristos     ev1->nxt->time = delta;
87666e63ce3Schristos     ev1->nxt->cfunc = cfunc;
87766e63ce3Schristos     ev1->nxt->arg = arg;
87866e63ce3Schristos }
87966e63ce3Schristos 
88066e63ce3Schristos #if 0	/* apparently not used */
88166e63ce3Schristos void
88266e63ce3Schristos stop_event()
88366e63ce3Schristos {
88466e63ce3Schristos }
88566e63ce3Schristos #endif
88666e63ce3Schristos 
88766e63ce3Schristos void
init_event()88866e63ce3Schristos init_event()
88966e63ce3Schristos {
89066e63ce3Schristos     int32           i;
89166e63ce3Schristos 
89266e63ce3Schristos     ebase.eq.nxt = NULL;
89366e63ce3Schristos     ebase.freeq = evbuf;
89466e63ce3Schristos     for (i = 0; i < EVENT_MAX; i++) {
89566e63ce3Schristos 	evbuf[i].nxt = &evbuf[i + 1];
89666e63ce3Schristos     }
89766e63ce3Schristos     evbuf[EVENT_MAX - 1].nxt = NULL;
89866e63ce3Schristos }
89966e63ce3Schristos 
90066e63ce3Schristos void
set_int(level,callback,arg)90166e63ce3Schristos set_int(level, callback, arg)
90266e63ce3Schristos     int32           level;
90366e63ce3Schristos     void            (*callback) ();
90466e63ce3Schristos     int32           arg;
90566e63ce3Schristos {
90666e63ce3Schristos     irqarr[level & 0x0f].callback = callback;
90766e63ce3Schristos     irqarr[level & 0x0f].arg = arg;
90866e63ce3Schristos }
90966e63ce3Schristos 
91066e63ce3Schristos /* Advance simulator time */
91166e63ce3Schristos 
91266e63ce3Schristos void
advance_time(sregs)91366e63ce3Schristos advance_time(sregs)
91466e63ce3Schristos     struct pstate  *sregs;
91566e63ce3Schristos {
91666e63ce3Schristos 
91766e63ce3Schristos     struct evcell  *evrem;
91866e63ce3Schristos     void            (*cfunc) ();
91966e63ce3Schristos     uint32          arg;
92066e63ce3Schristos     uint64          endtime;
92166e63ce3Schristos 
92266e63ce3Schristos #ifdef STAT
92366e63ce3Schristos     sregs->fholdt += sregs->fhold;
92466e63ce3Schristos     sregs->holdt += sregs->hold;
92566e63ce3Schristos     sregs->icntt += sregs->icnt;
92666e63ce3Schristos #endif
92766e63ce3Schristos 
92866e63ce3Schristos     endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold;
92966e63ce3Schristos 
93066e63ce3Schristos     while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) {
93166e63ce3Schristos 	ebase.simtime = ebase.eq.nxt->time;
93266e63ce3Schristos 	cfunc = ebase.eq.nxt->cfunc;
93366e63ce3Schristos 	arg = ebase.eq.nxt->arg;
93466e63ce3Schristos 	evrem = ebase.eq.nxt;
93566e63ce3Schristos 	ebase.eq.nxt = ebase.eq.nxt->nxt;
93666e63ce3Schristos 	evrem->nxt = ebase.freeq;
93766e63ce3Schristos 	ebase.freeq = evrem;
93866e63ce3Schristos 	cfunc(arg);
93966e63ce3Schristos     }
94066e63ce3Schristos     ebase.simtime = endtime;
94166e63ce3Schristos 
94266e63ce3Schristos }
94366e63ce3Schristos 
94466e63ce3Schristos uint32
now()94566e63ce3Schristos now()
94666e63ce3Schristos {
947ed6a76a9Schristos     return ebase.simtime;
94866e63ce3Schristos }
94966e63ce3Schristos 
95066e63ce3Schristos 
95166e63ce3Schristos /* Advance time until an external interrupt is seen */
95266e63ce3Schristos 
95366e63ce3Schristos int
wait_for_irq()95466e63ce3Schristos wait_for_irq()
95566e63ce3Schristos {
95666e63ce3Schristos     struct evcell  *evrem;
95766e63ce3Schristos     void            (*cfunc) ();
95866e63ce3Schristos     int32           arg;
95966e63ce3Schristos     uint64          endtime;
96066e63ce3Schristos 
96166e63ce3Schristos     if (ebase.eq.nxt == NULL)
96266e63ce3Schristos 	printf("Warning: event queue empty - power-down mode not entered\n");
96366e63ce3Schristos     endtime = ebase.simtime;
96466e63ce3Schristos     while (!ext_irl && (ebase.eq.nxt != NULL)) {
96566e63ce3Schristos 	ebase.simtime = ebase.eq.nxt->time;
96666e63ce3Schristos 	cfunc = ebase.eq.nxt->cfunc;
96766e63ce3Schristos 	arg = ebase.eq.nxt->arg;
96866e63ce3Schristos 	evrem = ebase.eq.nxt;
96966e63ce3Schristos 	ebase.eq.nxt = ebase.eq.nxt->nxt;
97066e63ce3Schristos 	evrem->nxt = ebase.freeq;
97166e63ce3Schristos 	ebase.freeq = evrem;
97266e63ce3Schristos 	cfunc(arg);
97366e63ce3Schristos 	if (ctrl_c) {
97466e63ce3Schristos 	    printf("\bwarning: power-down mode interrupted\n");
97566e63ce3Schristos 	    break;
97666e63ce3Schristos 	}
97766e63ce3Schristos     }
97866e63ce3Schristos     sregs.pwdtime += ebase.simtime - endtime;
979ed6a76a9Schristos     return ebase.simtime - endtime;
98066e63ce3Schristos }
98166e63ce3Schristos 
98266e63ce3Schristos int
check_bpt(sregs)98366e63ce3Schristos check_bpt(sregs)
98466e63ce3Schristos     struct pstate  *sregs;
98566e63ce3Schristos {
98666e63ce3Schristos     int32           i;
98766e63ce3Schristos 
98866e63ce3Schristos     if ((sregs->bphit) || (sregs->annul))
989ed6a76a9Schristos 	return 0;
99066e63ce3Schristos     for (i = 0; i < (int32) sregs->bptnum; i++) {
99166e63ce3Schristos 	if (sregs->pc == sregs->bpts[i])
992ed6a76a9Schristos 	    return BPT_HIT;
99366e63ce3Schristos     }
994ed6a76a9Schristos     return 0;
99566e63ce3Schristos }
99666e63ce3Schristos 
99766e63ce3Schristos void
reset_all()99866e63ce3Schristos reset_all()
99966e63ce3Schristos {
100066e63ce3Schristos     init_event();		/* Clear event queue */
100166e63ce3Schristos     init_regs(&sregs);
100266e63ce3Schristos     reset();
100366e63ce3Schristos #ifdef ERRINJ
100466e63ce3Schristos     errinjstart();
100566e63ce3Schristos #endif
100666e63ce3Schristos }
100766e63ce3Schristos 
100866e63ce3Schristos void
sys_reset()100966e63ce3Schristos sys_reset()
101066e63ce3Schristos {
101166e63ce3Schristos     reset_all();
101266e63ce3Schristos     sregs.trap = 256;		/* Force fake reset trap */
101366e63ce3Schristos }
101466e63ce3Schristos 
101566e63ce3Schristos void
sys_halt()101666e63ce3Schristos sys_halt()
101766e63ce3Schristos {
101866e63ce3Schristos     sregs.trap = 257;           /* Force fake halt trap */
101966e63ce3Schristos }
102066e63ce3Schristos 
102166e63ce3Schristos #include "ansidecl.h"
102266e63ce3Schristos 
102366e63ce3Schristos #include <stdarg.h>
102466e63ce3Schristos 
102566e63ce3Schristos #include "libiberty.h"
102666e63ce3Schristos #include "bfd.h"
102766e63ce3Schristos 
102866e63ce3Schristos #define min(A, B) (((A) < (B)) ? (A) : (B))
102966e63ce3Schristos #define LOAD_ADDRESS 0
103066e63ce3Schristos 
103166e63ce3Schristos int
bfd_load(const char * fname)1032ed6a76a9Schristos bfd_load (const char *fname)
103366e63ce3Schristos {
103466e63ce3Schristos     asection       *section;
103566e63ce3Schristos     bfd            *pbfd;
103666e63ce3Schristos     const bfd_arch_info_type *arch;
1037ed6a76a9Schristos     int            i;
103866e63ce3Schristos 
103966e63ce3Schristos     pbfd = bfd_openr(fname, 0);
104066e63ce3Schristos 
104166e63ce3Schristos     if (pbfd == NULL) {
104266e63ce3Schristos 	printf("open of %s failed\n", fname);
1043ed6a76a9Schristos 	return -1;
104466e63ce3Schristos     }
104566e63ce3Schristos     if (!bfd_check_format(pbfd, bfd_object)) {
104666e63ce3Schristos 	printf("file %s  doesn't seem to be an object file\n", fname);
1047ed6a76a9Schristos 	return -1;
104866e63ce3Schristos     }
104966e63ce3Schristos 
105066e63ce3Schristos     arch = bfd_get_arch_info (pbfd);
105166e63ce3Schristos     if (sis_verbose)
105266e63ce3Schristos 	printf("loading %s:", fname);
105366e63ce3Schristos     for (section = pbfd->sections; section; section = section->next) {
1054*1424dfb3Schristos 	if (bfd_section_flags (section) & SEC_ALLOC) {
105566e63ce3Schristos 	    bfd_vma         section_address;
105666e63ce3Schristos 	    unsigned long   section_size;
105766e63ce3Schristos 	    const char     *section_name;
105866e63ce3Schristos 
1059*1424dfb3Schristos 	    section_name = bfd_section_name (section);
106066e63ce3Schristos 
1061*1424dfb3Schristos 	    section_address = bfd_section_vma (section);
106266e63ce3Schristos 	    /*
106366e63ce3Schristos 	     * Adjust sections from a.out files, since they don't carry their
106466e63ce3Schristos 	     * addresses with.
106566e63ce3Schristos 	     */
106666e63ce3Schristos 	    if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) {
106766e63ce3Schristos 		if (strcmp (section_name, ".text") == 0)
106866e63ce3Schristos 		    section_address = bfd_get_start_address (pbfd);
106966e63ce3Schristos 		else if (strcmp (section_name, ".data") == 0) {
107066e63ce3Schristos 		    /* Read the first 8 bytes of the data section.
107166e63ce3Schristos 		       There should be the string 'DaTa' followed by
107266e63ce3Schristos 		       a word containing the actual section address. */
107366e63ce3Schristos 		    struct data_marker
107466e63ce3Schristos 		    {
107566e63ce3Schristos 			char signature[4];	/* 'DaTa' */
107666e63ce3Schristos 			unsigned char sdata[4];	/* &sdata */
107766e63ce3Schristos 		    } marker;
107866e63ce3Schristos 		    bfd_get_section_contents (pbfd, section, &marker, 0,
107966e63ce3Schristos 					      sizeof (marker));
108066e63ce3Schristos 		    if (strncmp (marker.signature, "DaTa", 4) == 0)
108166e63ce3Schristos 		      {
108266e63ce3Schristos 			section_address = bfd_getb32 (marker.sdata);
108366e63ce3Schristos 		      }
108466e63ce3Schristos 		}
108566e63ce3Schristos 	    }
108666e63ce3Schristos 
1087*1424dfb3Schristos 	    section_size = bfd_section_size (section);
108866e63ce3Schristos 
108966e63ce3Schristos 	    if (sis_verbose)
109066e63ce3Schristos 		printf("\nsection %s at 0x%08lx (0x%lx bytes)",
109166e63ce3Schristos 		       section_name, section_address, section_size);
109266e63ce3Schristos 
109366e63ce3Schristos 	    /* Text, data or lit */
1094*1424dfb3Schristos 	    if (bfd_section_flags (section) & SEC_LOAD) {
109566e63ce3Schristos 		file_ptr        fptr;
109666e63ce3Schristos 
109766e63ce3Schristos 		fptr = 0;
109866e63ce3Schristos 
109966e63ce3Schristos 		while (section_size > 0) {
110066e63ce3Schristos 		    char            buffer[1024];
110166e63ce3Schristos 		    int             count;
110266e63ce3Schristos 
110366e63ce3Schristos 		    count = min(section_size, 1024);
110466e63ce3Schristos 
110566e63ce3Schristos 		    bfd_get_section_contents(pbfd, section, buffer, fptr, count);
110666e63ce3Schristos 
1107ed6a76a9Schristos 		    for (i = 0; i < count; i++)
1108ed6a76a9Schristos 			sis_memory_write ((section_address + i) ^ EBT, &buffer[i], 1);
110966e63ce3Schristos 
111066e63ce3Schristos 		    section_address += count;
111166e63ce3Schristos 		    fptr += count;
111266e63ce3Schristos 		    section_size -= count;
111366e63ce3Schristos 		}
111466e63ce3Schristos 	    } else		/* BSS */
111566e63ce3Schristos 		if (sis_verbose)
111666e63ce3Schristos 		    printf("(not loaded)");
111766e63ce3Schristos 	}
111866e63ce3Schristos     }
111966e63ce3Schristos     if (sis_verbose)
112066e63ce3Schristos 	printf("\n");
112166e63ce3Schristos 
1122ed6a76a9Schristos     return bfd_get_start_address (pbfd);
1123ed6a76a9Schristos }
1124ed6a76a9Schristos 
get_time(void)1125ed6a76a9Schristos double get_time (void)
1126ed6a76a9Schristos {
1127ed6a76a9Schristos     double usec;
1128ed6a76a9Schristos 
1129ed6a76a9Schristos     struct timeval tm;
1130ed6a76a9Schristos 
1131ed6a76a9Schristos     gettimeofday (&tm, NULL);
1132ed6a76a9Schristos     usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec);
1133ed6a76a9Schristos     return usec / 1E6;
113466e63ce3Schristos }
1135