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(®[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