Home | History | Annotate | Line # | Download | only in erc32
func.c revision 1.9
      1  1.5  christos /* This file is part of SIS (SPARC instruction simulator)
      2  1.5  christos 
      3  1.9  christos    Copyright (C) 1995-2020 Free Software Foundation, Inc.
      4  1.5  christos    Contributed by Jiri Gaisler, European Space Agency
      5  1.5  christos 
      6  1.5  christos    This program is free software; you can redistribute it and/or modify
      7  1.5  christos    it under the terms of the GNU General Public License as published by
      8  1.5  christos    the Free Software Foundation; either version 3 of the License, or
      9  1.5  christos    (at your option) any later version.
     10  1.5  christos 
     11  1.5  christos    This program is distributed in the hope that it will be useful,
     12  1.5  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  1.5  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  1.5  christos    GNU General Public License for more details.
     15  1.5  christos 
     16  1.5  christos    You should have received a copy of the GNU General Public License
     17  1.5  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18  1.1  christos 
     19  1.1  christos #include "config.h"
     20  1.1  christos #include <signal.h>
     21  1.1  christos #include <string.h>
     22  1.1  christos #include <stdio.h>
     23  1.1  christos #include <stdlib.h>
     24  1.1  christos #include <ctype.h>
     25  1.1  christos #include "sis.h"
     26  1.1  christos #include <dis-asm.h>
     27  1.1  christos #include "sim-config.h"
     28  1.5  christos #include <inttypes.h>
     29  1.1  christos 
     30  1.1  christos #define	VAL(x)	strtoul(x,(char **)NULL,0)
     31  1.1  christos 
     32  1.1  christos struct disassemble_info dinfo;
     33  1.1  christos struct pstate   sregs;
     34  1.1  christos extern struct estate ebase;
     35  1.1  christos int             ctrl_c = 0;
     36  1.1  christos int             sis_verbose = 0;
     37  1.1  christos char           *sis_version = "2.7.5";
     38  1.1  christos int             nfp = 0;
     39  1.1  christos int             ift = 0;
     40  1.1  christos int             wrp = 0;
     41  1.1  christos int             rom8 = 0;
     42  1.1  christos int             uben = 0;
     43  1.1  christos int		termsave;
     44  1.1  christos int             sparclite = 0;		/* emulating SPARClite instructions? */
     45  1.1  christos int             sparclite_board = 0;	/* emulating SPARClite board RAM? */
     46  1.1  christos char            uart_dev1[128] = "";
     47  1.1  christos char            uart_dev2[128] = "";
     48  1.1  christos extern	int	ext_irl;
     49  1.1  christos uint32		last_load_addr = 0;
     50  1.1  christos 
     51  1.1  christos #ifdef ERRINJ
     52  1.1  christos uint32		errcnt = 0;
     53  1.1  christos uint32		errper = 0;
     54  1.1  christos uint32		errtt = 0;
     55  1.1  christos uint32		errftt = 0;
     56  1.1  christos uint32		errmec = 0;
     57  1.1  christos #endif
     58  1.1  christos 
     59  1.1  christos /* Forward declarations */
     60  1.1  christos 
     61  1.1  christos static int	batch (struct pstate *sregs, char *fname);
     62  1.1  christos static void	set_rega (struct pstate *sregs, char *reg, uint32 rval);
     63  1.1  christos static void	disp_reg (struct pstate *sregs, char *reg);
     64  1.1  christos static uint32	limcalc (float32 freq);
     65  1.1  christos static void	int_handler (int32 sig);
     66  1.1  christos static void	init_event (void);
     67  1.1  christos static int	disp_fpu (struct pstate  *sregs);
     68  1.1  christos static void	disp_regs (struct pstate  *sregs, int cwp);
     69  1.1  christos static void	disp_ctrl (struct pstate *sregs);
     70  1.1  christos static void	disp_mem (uint32 addr, uint32 len);
     71  1.1  christos 
     72  1.1  christos static int
     73  1.1  christos batch(sregs, fname)
     74  1.1  christos     struct pstate  *sregs;
     75  1.1  christos     char           *fname;
     76  1.1  christos {
     77  1.1  christos     FILE           *fp;
     78  1.5  christos     char           *lbuf = NULL;
     79  1.5  christos     size_t         len = 0;
     80  1.5  christos     size_t         slen;
     81  1.1  christos 
     82  1.1  christos     if ((fp = fopen(fname, "r")) == NULL) {
     83  1.1  christos 	fprintf(stderr, "couldn't open batch file %s\n", fname);
     84  1.5  christos 	return 0;
     85  1.1  christos     }
     86  1.5  christos     while (getline(&lbuf, &len, fp) > -1) {
     87  1.5  christos 	slen = strlen(lbuf);
     88  1.5  christos 	if (slen && (lbuf[slen - 1] == '\n')) {
     89  1.5  christos 	    lbuf[slen - 1] = 0;
     90  1.5  christos 	    printf("sis> %s\n", lbuf);
     91  1.5  christos 	    exec_cmd(sregs, lbuf);
     92  1.5  christos 	}
     93  1.1  christos     }
     94  1.5  christos     free(lbuf);
     95  1.1  christos     fclose(fp);
     96  1.5  christos     return 1;
     97  1.1  christos }
     98  1.1  christos 
     99  1.1  christos void
    100  1.1  christos set_regi(sregs, reg, rval)
    101  1.1  christos     struct pstate  *sregs;
    102  1.1  christos     int32           reg;
    103  1.1  christos     uint32          rval;
    104  1.1  christos {
    105  1.1  christos     uint32          cwp;
    106  1.1  christos 
    107  1.1  christos     cwp = ((sregs->psr & 0x7) << 4);
    108  1.1  christos     if ((reg > 0) && (reg < 8)) {
    109  1.1  christos 	sregs->g[reg] = rval;
    110  1.1  christos     } else if ((reg >= 8) && (reg < 32)) {
    111  1.1  christos 	sregs->r[(cwp + reg) & 0x7f] = rval;
    112  1.1  christos     } else if ((reg >= 32) && (reg < 64)) {
    113  1.1  christos 	sregs->fsi[reg - 32] = rval;
    114  1.1  christos     } else {
    115  1.1  christos 	switch (reg) {
    116  1.1  christos 	case 64:
    117  1.1  christos 	    sregs->y = rval;
    118  1.1  christos 	    break;
    119  1.1  christos 	case 65:
    120  1.1  christos 	    sregs->psr = rval;
    121  1.1  christos 	    break;
    122  1.1  christos 	case 66:
    123  1.1  christos 	    sregs->wim = rval;
    124  1.1  christos 	    break;
    125  1.1  christos 	case 67:
    126  1.1  christos 	    sregs->tbr = rval;
    127  1.1  christos 	    break;
    128  1.1  christos 	case 68:
    129  1.1  christos 	    sregs->pc = rval;
    130  1.1  christos 	    break;
    131  1.1  christos 	case 69:
    132  1.1  christos 	    sregs->npc = rval;
    133  1.1  christos 	    break;
    134  1.1  christos 	case 70:
    135  1.1  christos 	    sregs->fsr = rval;
    136  1.1  christos 	    set_fsr(rval);
    137  1.1  christos 	    break;
    138  1.1  christos     default:break;
    139  1.1  christos 	}
    140  1.1  christos     }
    141  1.1  christos }
    142  1.1  christos 
    143  1.1  christos void
    144  1.1  christos get_regi(struct pstate * sregs, int32 reg, char *buf)
    145  1.1  christos {
    146  1.1  christos     uint32          cwp;
    147  1.1  christos     uint32          rval = 0;
    148  1.1  christos 
    149  1.1  christos     cwp = ((sregs->psr & 0x7) << 4);
    150  1.1  christos     if ((reg >= 0) && (reg < 8)) {
    151  1.1  christos 	rval = sregs->g[reg];
    152  1.1  christos     } else if ((reg >= 8) && (reg < 32)) {
    153  1.1  christos 	rval = sregs->r[(cwp + reg) & 0x7f];
    154  1.1  christos     } else if ((reg >= 32) && (reg < 64)) {
    155  1.1  christos 	rval = sregs->fsi[reg - 32];
    156  1.1  christos     } else {
    157  1.1  christos 	switch (reg) {
    158  1.1  christos 	case 64:
    159  1.1  christos 	    rval = sregs->y;
    160  1.1  christos 	    break;
    161  1.1  christos 	case 65:
    162  1.1  christos 	    rval = sregs->psr;
    163  1.1  christos 	    break;
    164  1.1  christos 	case 66:
    165  1.1  christos 	    rval = sregs->wim;
    166  1.1  christos 	    break;
    167  1.1  christos 	case 67:
    168  1.1  christos 	    rval = sregs->tbr;
    169  1.1  christos 	    break;
    170  1.1  christos 	case 68:
    171  1.1  christos 	    rval = sregs->pc;
    172  1.1  christos 	    break;
    173  1.1  christos 	case 69:
    174  1.1  christos 	    rval = sregs->npc;
    175  1.1  christos 	    break;
    176  1.1  christos 	case 70:
    177  1.1  christos 	    rval = sregs->fsr;
    178  1.1  christos 	    break;
    179  1.1  christos     default:break;
    180  1.1  christos 	}
    181  1.1  christos     }
    182  1.5  christos     buf[0] = (rval >> 24) & 0x0ff;
    183  1.5  christos     buf[1] = (rval >> 16) & 0x0ff;
    184  1.5  christos     buf[2] = (rval >> 8) & 0x0ff;
    185  1.5  christos     buf[3] = rval & 0x0ff;
    186  1.1  christos }
    187  1.1  christos 
    188  1.1  christos 
    189  1.1  christos static void
    190  1.1  christos set_rega(sregs, reg, rval)
    191  1.1  christos     struct pstate  *sregs;
    192  1.1  christos     char           *reg;
    193  1.1  christos     uint32          rval;
    194  1.1  christos {
    195  1.1  christos     uint32          cwp;
    196  1.1  christos     int32           err = 0;
    197  1.1  christos 
    198  1.1  christos     cwp = ((sregs->psr & 0x7) << 4);
    199  1.1  christos     if (strcmp(reg, "psr") == 0)
    200  1.1  christos 	sregs->psr = (rval = (rval & 0x00f03fff));
    201  1.1  christos     else if (strcmp(reg, "tbr") == 0)
    202  1.1  christos 	sregs->tbr = (rval = (rval & 0xfffffff0));
    203  1.1  christos     else if (strcmp(reg, "wim") == 0)
    204  1.1  christos 	sregs->wim = (rval = (rval & 0x0ff));
    205  1.1  christos     else if (strcmp(reg, "y") == 0)
    206  1.1  christos 	sregs->y = rval;
    207  1.1  christos     else if (strcmp(reg, "pc") == 0)
    208  1.1  christos 	sregs->pc = rval;
    209  1.1  christos     else if (strcmp(reg, "npc") == 0)
    210  1.1  christos 	sregs->npc = rval;
    211  1.1  christos     else if (strcmp(reg, "fsr") == 0) {
    212  1.1  christos 	sregs->fsr = rval;
    213  1.1  christos 	set_fsr(rval);
    214  1.1  christos     } else if (strcmp(reg, "g0") == 0)
    215  1.1  christos 	err = 2;
    216  1.1  christos     else if (strcmp(reg, "g1") == 0)
    217  1.1  christos 	sregs->g[1] = rval;
    218  1.1  christos     else if (strcmp(reg, "g2") == 0)
    219  1.1  christos 	sregs->g[2] = rval;
    220  1.1  christos     else if (strcmp(reg, "g3") == 0)
    221  1.1  christos 	sregs->g[3] = rval;
    222  1.1  christos     else if (strcmp(reg, "g4") == 0)
    223  1.1  christos 	sregs->g[4] = rval;
    224  1.1  christos     else if (strcmp(reg, "g5") == 0)
    225  1.1  christos 	sregs->g[5] = rval;
    226  1.1  christos     else if (strcmp(reg, "g6") == 0)
    227  1.1  christos 	sregs->g[6] = rval;
    228  1.1  christos     else if (strcmp(reg, "g7") == 0)
    229  1.1  christos 	sregs->g[7] = rval;
    230  1.1  christos     else if (strcmp(reg, "o0") == 0)
    231  1.1  christos 	sregs->r[(cwp + 8) & 0x7f] = rval;
    232  1.1  christos     else if (strcmp(reg, "o1") == 0)
    233  1.1  christos 	sregs->r[(cwp + 9) & 0x7f] = rval;
    234  1.1  christos     else if (strcmp(reg, "o2") == 0)
    235  1.1  christos 	sregs->r[(cwp + 10) & 0x7f] = rval;
    236  1.1  christos     else if (strcmp(reg, "o3") == 0)
    237  1.1  christos 	sregs->r[(cwp + 11) & 0x7f] = rval;
    238  1.1  christos     else if (strcmp(reg, "o4") == 0)
    239  1.1  christos 	sregs->r[(cwp + 12) & 0x7f] = rval;
    240  1.1  christos     else if (strcmp(reg, "o5") == 0)
    241  1.1  christos 	sregs->r[(cwp + 13) & 0x7f] = rval;
    242  1.1  christos     else if (strcmp(reg, "o6") == 0)
    243  1.1  christos 	sregs->r[(cwp + 14) & 0x7f] = rval;
    244  1.1  christos     else if (strcmp(reg, "o7") == 0)
    245  1.1  christos 	sregs->r[(cwp + 15) & 0x7f] = rval;
    246  1.1  christos     else if (strcmp(reg, "l0") == 0)
    247  1.1  christos 	sregs->r[(cwp + 16) & 0x7f] = rval;
    248  1.1  christos     else if (strcmp(reg, "l1") == 0)
    249  1.1  christos 	sregs->r[(cwp + 17) & 0x7f] = rval;
    250  1.1  christos     else if (strcmp(reg, "l2") == 0)
    251  1.1  christos 	sregs->r[(cwp + 18) & 0x7f] = rval;
    252  1.1  christos     else if (strcmp(reg, "l3") == 0)
    253  1.1  christos 	sregs->r[(cwp + 19) & 0x7f] = rval;
    254  1.1  christos     else if (strcmp(reg, "l4") == 0)
    255  1.1  christos 	sregs->r[(cwp + 20) & 0x7f] = rval;
    256  1.1  christos     else if (strcmp(reg, "l5") == 0)
    257  1.1  christos 	sregs->r[(cwp + 21) & 0x7f] = rval;
    258  1.1  christos     else if (strcmp(reg, "l6") == 0)
    259  1.1  christos 	sregs->r[(cwp + 22) & 0x7f] = rval;
    260  1.1  christos     else if (strcmp(reg, "l7") == 0)
    261  1.1  christos 	sregs->r[(cwp + 23) & 0x7f] = rval;
    262  1.1  christos     else if (strcmp(reg, "i0") == 0)
    263  1.1  christos 	sregs->r[(cwp + 24) & 0x7f] = rval;
    264  1.1  christos     else if (strcmp(reg, "i1") == 0)
    265  1.1  christos 	sregs->r[(cwp + 25) & 0x7f] = rval;
    266  1.1  christos     else if (strcmp(reg, "i2") == 0)
    267  1.1  christos 	sregs->r[(cwp + 26) & 0x7f] = rval;
    268  1.1  christos     else if (strcmp(reg, "i3") == 0)
    269  1.1  christos 	sregs->r[(cwp + 27) & 0x7f] = rval;
    270  1.1  christos     else if (strcmp(reg, "i4") == 0)
    271  1.1  christos 	sregs->r[(cwp + 28) & 0x7f] = rval;
    272  1.1  christos     else if (strcmp(reg, "i5") == 0)
    273  1.1  christos 	sregs->r[(cwp + 29) & 0x7f] = rval;
    274  1.1  christos     else if (strcmp(reg, "i6") == 0)
    275  1.1  christos 	sregs->r[(cwp + 30) & 0x7f] = rval;
    276  1.1  christos     else if (strcmp(reg, "i7") == 0)
    277  1.1  christos 	sregs->r[(cwp + 31) & 0x7f] = rval;
    278  1.1  christos     else
    279  1.1  christos 	err = 1;
    280  1.1  christos     switch (err) {
    281  1.1  christos     case 0:
    282  1.1  christos 	printf("%s = %d (0x%08x)\n", reg, rval, rval);
    283  1.1  christos 	break;
    284  1.1  christos     case 1:
    285  1.1  christos 	printf("no such regiser: %s\n", reg);
    286  1.1  christos 	break;
    287  1.1  christos     case 2:
    288  1.1  christos 	printf("cannot set g0\n");
    289  1.1  christos 	break;
    290  1.1  christos     default:
    291  1.1  christos 	break;
    292  1.1  christos     }
    293  1.1  christos 
    294  1.1  christos }
    295  1.1  christos 
    296  1.1  christos static void
    297  1.1  christos disp_reg(sregs, reg)
    298  1.1  christos     struct pstate  *sregs;
    299  1.1  christos     char           *reg;
    300  1.1  christos {
    301  1.1  christos     if (strncmp(reg, "w",1) == 0)
    302  1.1  christos 	disp_regs(sregs, VAL(&reg[1]));
    303  1.1  christos }
    304  1.1  christos 
    305  1.1  christos #ifdef ERRINJ
    306  1.1  christos 
    307  1.1  christos void
    308  1.1  christos errinj()
    309  1.1  christos {
    310  1.1  christos     int	err;
    311  1.1  christos 
    312  1.1  christos     switch (err = (random() % 12)) {
    313  1.1  christos 	case 0: errtt = 0x61; break;
    314  1.1  christos 	case 1: errtt = 0x62; break;
    315  1.1  christos 	case 2: errtt = 0x63; break;
    316  1.1  christos 	case 3: errtt = 0x64; break;
    317  1.1  christos 	case 4: errtt = 0x65; break;
    318  1.1  christos 	case 5:
    319  1.1  christos 	case 6:
    320  1.1  christos 	case 7: errftt = err;
    321  1.1  christos 		break;
    322  1.1  christos 	case 8: errmec = 1; break;
    323  1.1  christos 	case 9: errmec = 2; break;
    324  1.1  christos 	case 10: errmec = 5; break;
    325  1.1  christos 	case 11: errmec = 6; break;
    326  1.1  christos     }
    327  1.1  christos     errcnt++;
    328  1.1  christos     if (errper) event(errinj, 0, (random()%errper));
    329  1.1  christos }
    330  1.1  christos 
    331  1.1  christos void
    332  1.1  christos errinjstart()
    333  1.1  christos {
    334  1.1  christos     if (errper) event(errinj, 0, (random()%errper));
    335  1.1  christos }
    336  1.1  christos 
    337  1.1  christos #endif
    338  1.1  christos 
    339  1.1  christos static uint32
    340  1.1  christos limcalc (freq)
    341  1.1  christos     float32		freq;
    342  1.1  christos {
    343  1.1  christos     uint32          unit, lim;
    344  1.1  christos     double	    flim;
    345  1.1  christos     char           *cmd1, *cmd2;
    346  1.1  christos 
    347  1.1  christos     unit = 1;
    348  1.1  christos     lim = -1;
    349  1.1  christos     if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    350  1.1  christos         lim = VAL(cmd1);
    351  1.1  christos         if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
    352  1.1  christos             if (strcmp(cmd2,"us")==0) unit = 1;
    353  1.1  christos       	    if (strcmp(cmd2,"ms")==0) unit = 1000;
    354  1.1  christos             if (strcmp(cmd2,"s")==0)  unit = 1000000;
    355  1.1  christos         }
    356  1.1  christos         flim = (double) lim * (double) unit * (double) freq +
    357  1.1  christos 	   (double) ebase.simtime;
    358  1.1  christos         if ((flim > ebase.simtime) && (flim < 4294967296.0)) {
    359  1.1  christos             lim = (uint32) flim;
    360  1.1  christos         } else  {
    361  1.1  christos             printf("error in expression\n");
    362  1.1  christos             lim = -1;
    363  1.1  christos         }
    364  1.1  christos     }
    365  1.5  christos     return lim;
    366  1.1  christos }
    367  1.5  christos 
    368  1.1  christos int
    369  1.5  christos exec_cmd(struct pstate *sregs, const char *cmd)
    370  1.1  christos {
    371  1.1  christos     char           *cmd1, *cmd2;
    372  1.1  christos     int32           stat;
    373  1.1  christos     uint32          len, i, clen, j;
    374  1.1  christos     static uint32   daddr = 0;
    375  1.5  christos     char           *cmdsave, *cmdsave2 = NULL;
    376  1.1  christos 
    377  1.1  christos     stat = OK;
    378  1.1  christos     cmdsave = strdup(cmd);
    379  1.5  christos     cmdsave2 = strdup (cmd);
    380  1.5  christos     if ((cmd1 = strtok (cmdsave2, " \t")) != NULL) {
    381  1.1  christos 	clen = strlen(cmd1);
    382  1.1  christos 	if (strncmp(cmd1, "bp", clen) == 0) {
    383  1.1  christos 	    for (i = 0; i < sregs->bptnum; i++) {
    384  1.1  christos 		printf("  %d : 0x%08x\n", i + 1, sregs->bpts[i]);
    385  1.1  christos 	    }
    386  1.1  christos 	} else if (strncmp(cmd1, "+bp", clen) == 0) {
    387  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    388  1.1  christos 		sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;
    389  1.1  christos 		printf("added breakpoint %d at 0x%08x\n",
    390  1.1  christos 		       sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);
    391  1.1  christos 		sregs->bptnum += 1;
    392  1.1  christos 	    }
    393  1.1  christos 	} else if (strncmp(cmd1, "-bp", clen) == 0) {
    394  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    395  1.1  christos 		i = VAL(cmd1) - 1;
    396  1.1  christos 		if ((i >= 0) && (i < sregs->bptnum)) {
    397  1.1  christos 		    printf("deleted breakpoint %d at 0x%08x\n", i + 1,
    398  1.1  christos 			   sregs->bpts[i]);
    399  1.1  christos 		    for (; i < sregs->bptnum - 1; i++) {
    400  1.1  christos 			sregs->bpts[i] = sregs->bpts[i + 1];
    401  1.1  christos 		    }
    402  1.1  christos 		    sregs->bptnum -= 1;
    403  1.1  christos 		}
    404  1.1  christos 	    }
    405  1.1  christos 	} else if (strncmp(cmd1, "batch", clen) == 0) {
    406  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    407  1.1  christos 		printf("no file specified\n");
    408  1.1  christos 	    } else {
    409  1.1  christos 		batch(sregs, cmd1);
    410  1.1  christos 	    }
    411  1.1  christos 	} else if (strncmp(cmd1, "cont", clen) == 0) {
    412  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    413  1.1  christos 		stat = run_sim(sregs, UINT64_MAX, 0);
    414  1.1  christos 	    } else {
    415  1.1  christos 		stat = run_sim(sregs, VAL(cmd1), 0);
    416  1.1  christos 	    }
    417  1.1  christos 	    daddr = sregs->pc;
    418  1.1  christos 	    sim_halt();
    419  1.1  christos 	} else if (strncmp(cmd1, "debug", clen) == 0) {
    420  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    421  1.1  christos 		sis_verbose = VAL(cmd1);
    422  1.1  christos 	    }
    423  1.1  christos 	    printf("Debug level = %d\n",sis_verbose);
    424  1.1  christos 	} else if (strncmp(cmd1, "dis", clen) == 0) {
    425  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    426  1.1  christos 		daddr = VAL(cmd1);
    427  1.1  christos 	    }
    428  1.1  christos 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
    429  1.1  christos 		len = VAL(cmd2);
    430  1.1  christos 	    } else
    431  1.1  christos 		len = 16;
    432  1.1  christos 	    printf("\n");
    433  1.1  christos 	    dis_mem(daddr, len, &dinfo);
    434  1.1  christos 	    printf("\n");
    435  1.1  christos 	    daddr += len * 4;
    436  1.1  christos 	} else if (strncmp(cmd1, "echo", clen) == 0) {
    437  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    438  1.1  christos 		printf("%s\n", (&cmdsave[clen+1]));
    439  1.1  christos 	    }
    440  1.1  christos #ifdef ERRINJ
    441  1.1  christos 	} else if (strncmp(cmd1, "error", clen) == 0) {
    442  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    443  1.1  christos 		errper = VAL(cmd1);
    444  1.1  christos 	        if (errper) {
    445  1.1  christos 		    event(errinj, 0, (len = (random()%errper)));
    446  1.1  christos 		    printf("Error injection started with period %d\n",len);
    447  1.1  christos 	        }
    448  1.1  christos 	     } else printf("Injected errors: %d\n",errcnt);
    449  1.1  christos #endif
    450  1.1  christos 	} else if (strncmp(cmd1, "float", clen) == 0) {
    451  1.1  christos 	    stat = disp_fpu(sregs);
    452  1.1  christos 	} else if (strncmp(cmd1, "go", clen) == 0) {
    453  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    454  1.1  christos 		len = last_load_addr;
    455  1.1  christos 	    } else {
    456  1.1  christos 		len = VAL(cmd1);
    457  1.1  christos 	    }
    458  1.1  christos 	    sregs->pc = len & ~3;
    459  1.1  christos 	    sregs->npc = sregs->pc + 4;
    460  1.5  christos 	    if ((sregs->pc != 0) && (ebase.simtime == 0))
    461  1.5  christos 	        boot_init();
    462  1.1  christos 	    printf("resuming at 0x%08x\n",sregs->pc);
    463  1.1  christos 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
    464  1.1  christos 		stat = run_sim(sregs, VAL(cmd2), 0);
    465  1.1  christos 	    } else {
    466  1.1  christos 		stat = run_sim(sregs, UINT64_MAX, 0);
    467  1.1  christos 	    }
    468  1.1  christos 	    daddr = sregs->pc;
    469  1.1  christos 	    sim_halt();
    470  1.1  christos 	} else if (strncmp(cmd1, "help", clen) == 0) {
    471  1.1  christos 	    gen_help();
    472  1.1  christos 	} else if (strncmp(cmd1, "history", clen) == 0) {
    473  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    474  1.1  christos 		sregs->histlen = VAL(cmd1);
    475  1.1  christos 		if (sregs->histbuf != NULL)
    476  1.1  christos 		    free(sregs->histbuf);
    477  1.1  christos 		sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));
    478  1.1  christos 		printf("trace history length = %d\n\r", sregs->histlen);
    479  1.1  christos 		sregs->histind = 0;
    480  1.1  christos 
    481  1.1  christos 	    } else {
    482  1.1  christos 		j = sregs->histind;
    483  1.1  christos 		for (i = 0; i < sregs->histlen; i++) {
    484  1.1  christos 		    if (j >= sregs->histlen)
    485  1.1  christos 			j = 0;
    486  1.1  christos 		    printf(" %8d ", sregs->histbuf[j].time);
    487  1.1  christos 		    dis_mem(sregs->histbuf[j].addr, 1, &dinfo);
    488  1.1  christos 		    j++;
    489  1.1  christos 		}
    490  1.1  christos 	    }
    491  1.1  christos 
    492  1.1  christos 	} else if (strncmp(cmd1, "load", clen) == 0) {
    493  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    494  1.1  christos 		last_load_addr = bfd_load(cmd1);
    495  1.1  christos 		while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
    496  1.1  christos 		    last_load_addr = bfd_load(cmd1);
    497  1.1  christos 	    } else {
    498  1.1  christos 		printf("load: no file specified\n");
    499  1.1  christos 	    }
    500  1.1  christos 	} else if (strncmp(cmd1, "mem", clen) == 0) {
    501  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
    502  1.1  christos 		daddr = VAL(cmd1);
    503  1.1  christos 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL)
    504  1.1  christos 		len = VAL(cmd2);
    505  1.1  christos 	    else
    506  1.1  christos 		len = 64;
    507  1.1  christos 	    disp_mem(daddr, len);
    508  1.1  christos 	    daddr += len;
    509  1.1  christos 	} else if (strncmp(cmd1, "perf", clen) == 0) {
    510  1.1  christos 	    cmd1 = strtok(NULL, " \t\n\r");
    511  1.1  christos 	    if ((cmd1 != NULL) &&
    512  1.1  christos 		(strncmp(cmd1, "reset", strlen(cmd1)) == 0)) {
    513  1.1  christos 		reset_stat(sregs);
    514  1.1  christos 	    } else
    515  1.1  christos 		show_stat(sregs);
    516  1.1  christos 	} else if (strncmp(cmd1, "quit", clen) == 0) {
    517  1.1  christos 	    exit(0);
    518  1.1  christos 	} else if (strncmp(cmd1, "reg", clen) == 0) {
    519  1.1  christos 	    cmd1 = strtok(NULL, " \t\n\r");
    520  1.1  christos 	    cmd2 = strtok(NULL, " \t\n\r");
    521  1.1  christos 	    if (cmd2 != NULL)
    522  1.1  christos 		set_rega(sregs, cmd1, VAL(cmd2));
    523  1.1  christos 	    else if (cmd1 != NULL)
    524  1.1  christos 		disp_reg(sregs, cmd1);
    525  1.1  christos 	    else {
    526  1.1  christos 		disp_regs(sregs,sregs->psr);
    527  1.1  christos 		disp_ctrl(sregs);
    528  1.1  christos 	    }
    529  1.1  christos 	} else if (strncmp(cmd1, "reset", clen) == 0) {
    530  1.1  christos 	    ebase.simtime = 0;
    531  1.1  christos 	    reset_all();
    532  1.1  christos 	    reset_stat(sregs);
    533  1.1  christos 	} else if (strncmp(cmd1, "run", clen) == 0) {
    534  1.1  christos 	    ebase.simtime = 0;
    535  1.1  christos 	    reset_all();
    536  1.1  christos 	    reset_stat(sregs);
    537  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    538  1.1  christos 		stat = run_sim(sregs, UINT64_MAX, 0);
    539  1.1  christos 	    } else {
    540  1.1  christos 		stat = run_sim(sregs, VAL(cmd1), 0);
    541  1.1  christos 	    }
    542  1.1  christos 	    daddr = sregs->pc;
    543  1.1  christos 	    sim_halt();
    544  1.1  christos 	} else if (strncmp(cmd1, "shell", clen) == 0) {
    545  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    546  1.5  christos 		if (system(&cmdsave[clen])) {
    547  1.5  christos 		    /* Silence unused return value warning.  */
    548  1.5  christos 		}
    549  1.1  christos 	    }
    550  1.1  christos 	} else if (strncmp(cmd1, "step", clen) == 0) {
    551  1.1  christos 	    stat = run_sim(sregs, 1, 1);
    552  1.1  christos 	    daddr = sregs->pc;
    553  1.1  christos 	    sim_halt();
    554  1.1  christos 	} else if (strncmp(cmd1, "tcont", clen) == 0) {
    555  1.1  christos 	    sregs->tlimit = limcalc(sregs->freq);
    556  1.1  christos 	    stat = run_sim(sregs, UINT64_MAX, 0);
    557  1.1  christos 	    daddr = sregs->pc;
    558  1.1  christos 	    sim_halt();
    559  1.1  christos 	} else if (strncmp(cmd1, "tgo", clen) == 0) {
    560  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    561  1.1  christos 		len = last_load_addr;
    562  1.1  christos 	    } else {
    563  1.1  christos 		len = VAL(cmd1);
    564  1.1  christos 	        sregs->tlimit = limcalc(sregs->freq);
    565  1.1  christos 	    }
    566  1.1  christos 	    sregs->pc = len & ~3;
    567  1.1  christos 	    sregs->npc = sregs->pc + 4;
    568  1.1  christos 	    printf("resuming at 0x%08x\n",sregs->pc);
    569  1.1  christos 	    stat = run_sim(sregs, UINT64_MAX, 0);
    570  1.1  christos 	    daddr = sregs->pc;
    571  1.1  christos 	    sim_halt();
    572  1.1  christos 	} else if (strncmp(cmd1, "tlimit", clen) == 0) {
    573  1.1  christos 	   sregs->tlimit = limcalc(sregs->freq);
    574  1.1  christos 	   if (sregs->tlimit != (uint32) -1)
    575  1.1  christos               printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit,
    576  1.1  christos 		sregs->tlimit / sregs->freq / 1000);
    577  1.1  christos 	} else if (strncmp(cmd1, "tra", clen) == 0) {
    578  1.1  christos 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    579  1.1  christos 		stat = run_sim(sregs, UINT64_MAX, 1);
    580  1.1  christos 	    } else {
    581  1.1  christos 		stat = run_sim(sregs, VAL(cmd1), 1);
    582  1.1  christos 	    }
    583  1.1  christos 	    printf("\n");
    584  1.1  christos 	    daddr = sregs->pc;
    585  1.1  christos 	    sim_halt();
    586  1.1  christos 	} else if (strncmp(cmd1, "trun", clen) == 0) {
    587  1.1  christos 	    ebase.simtime = 0;
    588  1.1  christos 	    reset_all();
    589  1.1  christos 	    reset_stat(sregs);
    590  1.1  christos 	    sregs->tlimit = limcalc(sregs->freq);
    591  1.1  christos 	    stat = run_sim(sregs, UINT64_MAX, 0);
    592  1.1  christos 	    daddr = sregs->pc;
    593  1.1  christos 	    sim_halt();
    594  1.1  christos 	} else
    595  1.1  christos 	    printf("syntax error\n");
    596  1.1  christos     }
    597  1.5  christos     if (cmdsave2 != NULL)
    598  1.5  christos 	free(cmdsave2);
    599  1.1  christos     if (cmdsave != NULL)
    600  1.1  christos 	free(cmdsave);
    601  1.5  christos     return stat;
    602  1.1  christos }
    603  1.1  christos 
    604  1.1  christos 
    605  1.1  christos void
    606  1.1  christos reset_stat(sregs)
    607  1.1  christos     struct pstate  *sregs;
    608  1.1  christos {
    609  1.5  christos     sregs->tottime = 0.0;
    610  1.1  christos     sregs->pwdtime = 0;
    611  1.1  christos     sregs->ninst = 0;
    612  1.1  christos     sregs->fholdt = 0;
    613  1.1  christos     sregs->holdt = 0;
    614  1.1  christos     sregs->icntt = 0;
    615  1.1  christos     sregs->finst = 0;
    616  1.1  christos     sregs->nstore = 0;
    617  1.1  christos     sregs->nload = 0;
    618  1.1  christos     sregs->nbranch = 0;
    619  1.1  christos     sregs->simstart = ebase.simtime;
    620  1.1  christos 
    621  1.1  christos }
    622  1.1  christos 
    623  1.1  christos void
    624  1.1  christos show_stat(sregs)
    625  1.1  christos     struct pstate  *sregs;
    626  1.1  christos {
    627  1.1  christos     uint32          iinst;
    628  1.5  christos     uint32          stime;
    629  1.1  christos 
    630  1.5  christos     if (sregs->tottime == 0.0)
    631  1.5  christos         sregs->tottime += 1E-6;
    632  1.1  christos     stime = ebase.simtime - sregs->simstart;	/* Total simulated time */
    633  1.1  christos #ifdef STAT
    634  1.1  christos 
    635  1.1  christos     iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore -
    636  1.1  christos 	sregs->nbranch;
    637  1.1  christos #endif
    638  1.1  christos 
    639  1.5  christos     printf("\n Cycles       : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
    640  1.5  christos     printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
    641  1.1  christos 
    642  1.1  christos #ifdef STAT
    643  1.1  christos     printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
    644  1.1  christos     printf("   load       : %9.2f %%\n",
    645  1.1  christos 	   100.0 * (float) sregs->nload / (float) sregs->ninst);
    646  1.1  christos     printf("   store      : %9.2f %%\n",
    647  1.1  christos 	   100.0 * (float) sregs->nstore / (float) sregs->ninst);
    648  1.1  christos     printf("   branch     : %9.2f %%\n",
    649  1.1  christos 	   100.0 * (float) sregs->nbranch / (float) sregs->ninst);
    650  1.1  christos     printf("   float      : %9.2f %%\n",
    651  1.1  christos 	   100.0 * (float) sregs->finst / (float) sregs->ninst);
    652  1.1  christos     printf(" Integer CPI  : %9.2f\n",
    653  1.1  christos 	   ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
    654  1.1  christos 	   /
    655  1.1  christos 	   (float) (sregs->ninst - sregs->finst));
    656  1.1  christos     printf(" Float CPI    : %9.2f\n",
    657  1.1  christos 	   ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
    658  1.1  christos #endif
    659  1.1  christos     printf(" Overall CPI  : %9.2f\n",
    660  1.1  christos 	   (float) (stime - sregs->pwdtime) / (float) sregs->ninst);
    661  1.1  christos     printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
    662  1.1  christos 	   sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime),
    663  1.1  christos 	   sregs->freq * (float) (sregs->ninst - sregs->finst) /
    664  1.1  christos 	   (float) (stime - sregs->pwdtime),
    665  1.1  christos      sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
    666  1.5  christos     printf(" Simulated ERC32 time        : %.2f s\n",
    667  1.5  christos         (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
    668  1.5  christos     printf(" Processor utilisation       : %.2f %%\n",
    669  1.5  christos         100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
    670  1.5  christos     printf(" Real-time performance       : %.2f %%\n",
    671  1.5  christos         100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
    672  1.5  christos     printf(" Simulator performance       : %.2f MIPS\n",
    673  1.5  christos         (double)(sregs->ninst) / sregs->tottime / 1E6);
    674  1.5  christos     printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);
    675  1.1  christos }
    676  1.1  christos 
    677  1.1  christos 
    678  1.1  christos 
    679  1.1  christos void
    680  1.1  christos init_bpt(sregs)
    681  1.1  christos     struct pstate  *sregs;
    682  1.1  christos {
    683  1.1  christos     sregs->bptnum = 0;
    684  1.1  christos     sregs->histlen = 0;
    685  1.1  christos     sregs->histind = 0;
    686  1.1  christos     sregs->histbuf = NULL;
    687  1.1  christos     sregs->tlimit = -1;
    688  1.1  christos }
    689  1.1  christos 
    690  1.1  christos static void
    691  1.1  christos int_handler(sig)
    692  1.1  christos     int32           sig;
    693  1.1  christos {
    694  1.1  christos     if (sig != 2)
    695  1.1  christos 	printf("\n\n Signal handler error  (%d)\n\n", sig);
    696  1.1  christos     ctrl_c = 1;
    697  1.1  christos }
    698  1.1  christos 
    699  1.1  christos void
    700  1.1  christos init_signals()
    701  1.1  christos {
    702  1.1  christos     typedef void    (*PFI) ();
    703  1.1  christos     static PFI      int_tab[2];
    704  1.1  christos 
    705  1.1  christos     int_tab[0] = signal(SIGTERM, int_handler);
    706  1.1  christos     int_tab[1] = signal(SIGINT, int_handler);
    707  1.1  christos }
    708  1.1  christos 
    709  1.1  christos 
    710  1.1  christos extern struct disassemble_info dinfo;
    711  1.1  christos 
    712  1.1  christos struct estate   ebase;
    713  1.1  christos struct evcell   evbuf[EVENT_MAX];
    714  1.1  christos struct irqcell  irqarr[16];
    715  1.1  christos 
    716  1.1  christos static int
    717  1.1  christos disp_fpu(sregs)
    718  1.1  christos     struct pstate  *sregs;
    719  1.1  christos {
    720  1.1  christos 
    721  1.1  christos     int         i;
    722  1.1  christos     float	t;
    723  1.1  christos 
    724  1.1  christos     printf("\n fsr: %08X\n\n", sregs->fsr);
    725  1.1  christos 
    726  1.5  christos #ifdef HOST_LITTLE_ENDIAN
    727  1.1  christos     for (i = 0; i < 32; i++)
    728  1.1  christos       sregs->fdp[i ^ 1] = sregs->fs[i];
    729  1.1  christos #endif
    730  1.1  christos 
    731  1.1  christos     for (i = 0; i < 32; i++) {
    732  1.1  christos 	t = sregs->fs[i];
    733  1.1  christos 	printf(" f%02d  %08x  %14e  ", i, sregs->fsi[i], sregs->fs[i]);
    734  1.1  christos 	if (!(i & 1))
    735  1.1  christos 	    printf("%14e\n", sregs->fd[i >> 1]);
    736  1.1  christos 	else
    737  1.1  christos 	    printf("\n");
    738  1.1  christos     }
    739  1.1  christos     printf("\n");
    740  1.5  christos     return OK;
    741  1.1  christos }
    742  1.1  christos 
    743  1.1  christos static void
    744  1.1  christos disp_regs(sregs,cwp)
    745  1.1  christos     struct pstate  *sregs;
    746  1.1  christos     int cwp;
    747  1.1  christos {
    748  1.1  christos 
    749  1.1  christos     int           i;
    750  1.1  christos 
    751  1.1  christos     cwp = ((cwp & 0x7) << 4);
    752  1.1  christos     printf("\n\t  INS       LOCALS      OUTS     GLOBALS\n");
    753  1.1  christos     for (i = 0; i < 8; i++) {
    754  1.1  christos 	printf("   %d:  %08X   %08X   %08X   %08X\n", i,
    755  1.1  christos 	       sregs->r[(cwp + i + 24) & 0x7f],
    756  1.1  christos 	    sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f],
    757  1.1  christos 	       sregs->g[i]);
    758  1.1  christos     }
    759  1.1  christos }
    760  1.1  christos 
    761  1.5  christos static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info)
    762  1.5  christos {
    763  1.5  christos     unsigned char           i[4];
    764  1.5  christos 
    765  1.5  christos     sis_memory_read(addr, i, 4);
    766  1.5  christos     dinfo.buffer_vma = addr;
    767  1.5  christos     dinfo.buffer_length = 4;
    768  1.5  christos     dinfo.buffer = i;
    769  1.5  christos     print_insn_sparc(addr, info);
    770  1.5  christos }
    771  1.5  christos 
    772  1.1  christos static void
    773  1.1  christos disp_ctrl(sregs)
    774  1.1  christos     struct pstate  *sregs;
    775  1.1  christos {
    776  1.1  christos 
    777  1.5  christos     uint32           i;
    778  1.1  christos 
    779  1.1  christos     printf("\n psr: %08X   wim: %08X   tbr: %08X   y: %08X\n",
    780  1.1  christos 	   sregs->psr, sregs->wim, sregs->tbr, sregs->y);
    781  1.5  christos     sis_memory_read (sregs->pc, (char *) &i, 4);
    782  1.5  christos     printf ("\n  pc: %08X = %08X    ", sregs->pc, i);
    783  1.5  christos     print_insn_sparc_sis(sregs->pc, &dinfo);
    784  1.5  christos     sis_memory_read (sregs->npc, (char *) &i, 4);
    785  1.5  christos     printf ("\n npc: %08X = %08X    ", sregs->npc, i);
    786  1.5  christos     print_insn_sparc_sis(sregs->npc, &dinfo);
    787  1.1  christos     if (sregs->err_mode)
    788  1.1  christos 	printf("\n IU in error mode");
    789  1.1  christos     printf("\n\n");
    790  1.1  christos }
    791  1.1  christos 
    792  1.1  christos static void
    793  1.1  christos disp_mem(addr, len)
    794  1.1  christos     uint32          addr;
    795  1.1  christos     uint32          len;
    796  1.1  christos {
    797  1.1  christos 
    798  1.1  christos     uint32          i;
    799  1.5  christos     union {
    800  1.5  christos 	    unsigned char u8[4];
    801  1.5  christos 	    uint32 u32;
    802  1.5  christos     } data;
    803  1.1  christos     uint32          mem[4], j;
    804  1.1  christos     char           *p;
    805  1.1  christos 
    806  1.1  christos     for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
    807  1.1  christos 	printf("\n %8X  ", i);
    808  1.1  christos 	for (j = 0; j < 4; j++) {
    809  1.5  christos 	    sis_memory_read ((i + (j * 4)), data.u8, 4);
    810  1.5  christos 	    printf ("%08x  ", data.u32);
    811  1.5  christos 	    mem[j] = data.u32;
    812  1.1  christos 	}
    813  1.1  christos 	printf("  ");
    814  1.1  christos 	p = (char *) mem;
    815  1.1  christos 	for (j = 0; j < 16; j++) {
    816  1.5  christos 	    if (isprint (p[j ^ EBT]))
    817  1.5  christos 		putchar (p[j ^ EBT]);
    818  1.1  christos 	    else
    819  1.1  christos 		putchar('.');
    820  1.1  christos 	}
    821  1.1  christos     }
    822  1.1  christos     printf("\n\n");
    823  1.1  christos }
    824  1.1  christos 
    825  1.1  christos void
    826  1.1  christos dis_mem(addr, len, info)
    827  1.1  christos     uint32          addr;
    828  1.1  christos     uint32          len;
    829  1.1  christos     struct disassemble_info *info;
    830  1.1  christos {
    831  1.1  christos     uint32          i;
    832  1.5  christos     union {
    833  1.5  christos 	    unsigned char u8[4];
    834  1.5  christos 	    uint32 u32;
    835  1.5  christos     } data;
    836  1.1  christos 
    837  1.1  christos     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
    838  1.5  christos 	sis_memory_read (i, data.u8, 4);
    839  1.5  christos 	printf (" %08x  %08x  ", i, data.u32);
    840  1.5  christos 	print_insn_sparc_sis(i, info);
    841  1.1  christos         if (i >= 0xfffffffc) break;
    842  1.1  christos 	printf("\n");
    843  1.1  christos     }
    844  1.1  christos }
    845  1.1  christos 
    846  1.1  christos /* Add event to event queue */
    847  1.1  christos 
    848  1.1  christos void
    849  1.1  christos event(cfunc, arg, delta)
    850  1.1  christos     void            (*cfunc) ();
    851  1.1  christos     int32           arg;
    852  1.1  christos     uint64          delta;
    853  1.1  christos {
    854  1.1  christos     struct evcell  *ev1, *evins;
    855  1.1  christos 
    856  1.1  christos     if (ebase.freeq == NULL) {
    857  1.1  christos 	printf("Error, too many events in event queue\n");
    858  1.1  christos 	return;
    859  1.1  christos     }
    860  1.1  christos     ev1 = &ebase.eq;
    861  1.1  christos     delta += ebase.simtime;
    862  1.1  christos     while ((ev1->nxt != NULL) && (ev1->nxt->time <= delta)) {
    863  1.1  christos 	ev1 = ev1->nxt;
    864  1.1  christos     }
    865  1.1  christos     if (ev1->nxt == NULL) {
    866  1.1  christos 	ev1->nxt = ebase.freeq;
    867  1.1  christos 	ebase.freeq = ebase.freeq->nxt;
    868  1.1  christos 	ev1->nxt->nxt = NULL;
    869  1.1  christos     } else {
    870  1.1  christos 	evins = ebase.freeq;
    871  1.1  christos 	ebase.freeq = ebase.freeq->nxt;
    872  1.1  christos 	evins->nxt = ev1->nxt;
    873  1.1  christos 	ev1->nxt = evins;
    874  1.1  christos     }
    875  1.1  christos     ev1->nxt->time = delta;
    876  1.1  christos     ev1->nxt->cfunc = cfunc;
    877  1.1  christos     ev1->nxt->arg = arg;
    878  1.1  christos }
    879  1.1  christos 
    880  1.1  christos #if 0	/* apparently not used */
    881  1.1  christos void
    882  1.1  christos stop_event()
    883  1.1  christos {
    884  1.1  christos }
    885  1.1  christos #endif
    886  1.1  christos 
    887  1.1  christos void
    888  1.1  christos init_event()
    889  1.1  christos {
    890  1.1  christos     int32           i;
    891  1.1  christos 
    892  1.1  christos     ebase.eq.nxt = NULL;
    893  1.1  christos     ebase.freeq = evbuf;
    894  1.1  christos     for (i = 0; i < EVENT_MAX; i++) {
    895  1.1  christos 	evbuf[i].nxt = &evbuf[i + 1];
    896  1.1  christos     }
    897  1.1  christos     evbuf[EVENT_MAX - 1].nxt = NULL;
    898  1.1  christos }
    899  1.1  christos 
    900  1.1  christos void
    901  1.1  christos set_int(level, callback, arg)
    902  1.1  christos     int32           level;
    903  1.1  christos     void            (*callback) ();
    904  1.1  christos     int32           arg;
    905  1.1  christos {
    906  1.1  christos     irqarr[level & 0x0f].callback = callback;
    907  1.1  christos     irqarr[level & 0x0f].arg = arg;
    908  1.1  christos }
    909  1.1  christos 
    910  1.1  christos /* Advance simulator time */
    911  1.1  christos 
    912  1.1  christos void
    913  1.1  christos advance_time(sregs)
    914  1.1  christos     struct pstate  *sregs;
    915  1.1  christos {
    916  1.1  christos 
    917  1.1  christos     struct evcell  *evrem;
    918  1.1  christos     void            (*cfunc) ();
    919  1.1  christos     uint32          arg;
    920  1.1  christos     uint64          endtime;
    921  1.1  christos 
    922  1.1  christos #ifdef STAT
    923  1.1  christos     sregs->fholdt += sregs->fhold;
    924  1.1  christos     sregs->holdt += sregs->hold;
    925  1.1  christos     sregs->icntt += sregs->icnt;
    926  1.1  christos #endif
    927  1.1  christos 
    928  1.1  christos     endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold;
    929  1.1  christos 
    930  1.1  christos     while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) {
    931  1.1  christos 	ebase.simtime = ebase.eq.nxt->time;
    932  1.1  christos 	cfunc = ebase.eq.nxt->cfunc;
    933  1.1  christos 	arg = ebase.eq.nxt->arg;
    934  1.1  christos 	evrem = ebase.eq.nxt;
    935  1.1  christos 	ebase.eq.nxt = ebase.eq.nxt->nxt;
    936  1.1  christos 	evrem->nxt = ebase.freeq;
    937  1.1  christos 	ebase.freeq = evrem;
    938  1.1  christos 	cfunc(arg);
    939  1.1  christos     }
    940  1.1  christos     ebase.simtime = endtime;
    941  1.1  christos 
    942  1.1  christos }
    943  1.1  christos 
    944  1.1  christos uint32
    945  1.1  christos now()
    946  1.1  christos {
    947  1.5  christos     return ebase.simtime;
    948  1.1  christos }
    949  1.1  christos 
    950  1.1  christos 
    951  1.1  christos /* Advance time until an external interrupt is seen */
    952  1.1  christos 
    953  1.1  christos int
    954  1.1  christos wait_for_irq()
    955  1.1  christos {
    956  1.1  christos     struct evcell  *evrem;
    957  1.1  christos     void            (*cfunc) ();
    958  1.1  christos     int32           arg;
    959  1.1  christos     uint64          endtime;
    960  1.1  christos 
    961  1.1  christos     if (ebase.eq.nxt == NULL)
    962  1.1  christos 	printf("Warning: event queue empty - power-down mode not entered\n");
    963  1.1  christos     endtime = ebase.simtime;
    964  1.1  christos     while (!ext_irl && (ebase.eq.nxt != NULL)) {
    965  1.1  christos 	ebase.simtime = ebase.eq.nxt->time;
    966  1.1  christos 	cfunc = ebase.eq.nxt->cfunc;
    967  1.1  christos 	arg = ebase.eq.nxt->arg;
    968  1.1  christos 	evrem = ebase.eq.nxt;
    969  1.1  christos 	ebase.eq.nxt = ebase.eq.nxt->nxt;
    970  1.1  christos 	evrem->nxt = ebase.freeq;
    971  1.1  christos 	ebase.freeq = evrem;
    972  1.1  christos 	cfunc(arg);
    973  1.1  christos 	if (ctrl_c) {
    974  1.1  christos 	    printf("\bwarning: power-down mode interrupted\n");
    975  1.1  christos 	    break;
    976  1.1  christos 	}
    977  1.1  christos     }
    978  1.1  christos     sregs.pwdtime += ebase.simtime - endtime;
    979  1.5  christos     return ebase.simtime - endtime;
    980  1.1  christos }
    981  1.1  christos 
    982  1.1  christos int
    983  1.1  christos check_bpt(sregs)
    984  1.1  christos     struct pstate  *sregs;
    985  1.1  christos {
    986  1.1  christos     int32           i;
    987  1.1  christos 
    988  1.1  christos     if ((sregs->bphit) || (sregs->annul))
    989  1.5  christos 	return 0;
    990  1.1  christos     for (i = 0; i < (int32) sregs->bptnum; i++) {
    991  1.1  christos 	if (sregs->pc == sregs->bpts[i])
    992  1.5  christos 	    return BPT_HIT;
    993  1.1  christos     }
    994  1.5  christos     return 0;
    995  1.1  christos }
    996  1.1  christos 
    997  1.1  christos void
    998  1.1  christos reset_all()
    999  1.1  christos {
   1000  1.1  christos     init_event();		/* Clear event queue */
   1001  1.1  christos     init_regs(&sregs);
   1002  1.1  christos     reset();
   1003  1.1  christos #ifdef ERRINJ
   1004  1.1  christos     errinjstart();
   1005  1.1  christos #endif
   1006  1.1  christos }
   1007  1.1  christos 
   1008  1.1  christos void
   1009  1.1  christos sys_reset()
   1010  1.1  christos {
   1011  1.1  christos     reset_all();
   1012  1.1  christos     sregs.trap = 256;		/* Force fake reset trap */
   1013  1.1  christos }
   1014  1.1  christos 
   1015  1.1  christos void
   1016  1.1  christos sys_halt()
   1017  1.1  christos {
   1018  1.1  christos     sregs.trap = 257;           /* Force fake halt trap */
   1019  1.1  christos }
   1020  1.1  christos 
   1021  1.1  christos #include "ansidecl.h"
   1022  1.1  christos 
   1023  1.1  christos #include <stdarg.h>
   1024  1.1  christos 
   1025  1.1  christos #include "libiberty.h"
   1026  1.1  christos #include "bfd.h"
   1027  1.1  christos 
   1028  1.1  christos #define min(A, B) (((A) < (B)) ? (A) : (B))
   1029  1.1  christos #define LOAD_ADDRESS 0
   1030  1.1  christos 
   1031  1.1  christos int
   1032  1.5  christos bfd_load (const char *fname)
   1033  1.1  christos {
   1034  1.1  christos     asection       *section;
   1035  1.1  christos     bfd            *pbfd;
   1036  1.1  christos     const bfd_arch_info_type *arch;
   1037  1.5  christos     int            i;
   1038  1.1  christos 
   1039  1.1  christos     pbfd = bfd_openr(fname, 0);
   1040  1.1  christos 
   1041  1.1  christos     if (pbfd == NULL) {
   1042  1.1  christos 	printf("open of %s failed\n", fname);
   1043  1.5  christos 	return -1;
   1044  1.1  christos     }
   1045  1.1  christos     if (!bfd_check_format(pbfd, bfd_object)) {
   1046  1.1  christos 	printf("file %s  doesn't seem to be an object file\n", fname);
   1047  1.5  christos 	return -1;
   1048  1.1  christos     }
   1049  1.1  christos 
   1050  1.1  christos     arch = bfd_get_arch_info (pbfd);
   1051  1.1  christos     if (sis_verbose)
   1052  1.1  christos 	printf("loading %s:", fname);
   1053  1.1  christos     for (section = pbfd->sections; section; section = section->next) {
   1054  1.9  christos 	if (bfd_section_flags (section) & SEC_ALLOC) {
   1055  1.1  christos 	    bfd_vma         section_address;
   1056  1.1  christos 	    unsigned long   section_size;
   1057  1.1  christos 	    const char     *section_name;
   1058  1.1  christos 
   1059  1.9  christos 	    section_name = bfd_section_name (section);
   1060  1.1  christos 
   1061  1.9  christos 	    section_address = bfd_section_vma (section);
   1062  1.1  christos 	    /*
   1063  1.1  christos 	     * Adjust sections from a.out files, since they don't carry their
   1064  1.1  christos 	     * addresses with.
   1065  1.1  christos 	     */
   1066  1.1  christos 	    if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) {
   1067  1.1  christos 		if (strcmp (section_name, ".text") == 0)
   1068  1.1  christos 		    section_address = bfd_get_start_address (pbfd);
   1069  1.1  christos 		else if (strcmp (section_name, ".data") == 0) {
   1070  1.1  christos 		    /* Read the first 8 bytes of the data section.
   1071  1.1  christos 		       There should be the string 'DaTa' followed by
   1072  1.1  christos 		       a word containing the actual section address. */
   1073  1.1  christos 		    struct data_marker
   1074  1.1  christos 		    {
   1075  1.1  christos 			char signature[4];	/* 'DaTa' */
   1076  1.1  christos 			unsigned char sdata[4];	/* &sdata */
   1077  1.1  christos 		    } marker;
   1078  1.1  christos 		    bfd_get_section_contents (pbfd, section, &marker, 0,
   1079  1.1  christos 					      sizeof (marker));
   1080  1.1  christos 		    if (strncmp (marker.signature, "DaTa", 4) == 0)
   1081  1.1  christos 		      {
   1082  1.5  christos 			section_address = bfd_getb32 (marker.sdata);
   1083  1.1  christos 		      }
   1084  1.1  christos 		}
   1085  1.1  christos 	    }
   1086  1.1  christos 
   1087  1.9  christos 	    section_size = bfd_section_size (section);
   1088  1.1  christos 
   1089  1.1  christos 	    if (sis_verbose)
   1090  1.1  christos 		printf("\nsection %s at 0x%08lx (0x%lx bytes)",
   1091  1.1  christos 		       section_name, section_address, section_size);
   1092  1.1  christos 
   1093  1.1  christos 	    /* Text, data or lit */
   1094  1.9  christos 	    if (bfd_section_flags (section) & SEC_LOAD) {
   1095  1.1  christos 		file_ptr        fptr;
   1096  1.1  christos 
   1097  1.1  christos 		fptr = 0;
   1098  1.1  christos 
   1099  1.1  christos 		while (section_size > 0) {
   1100  1.1  christos 		    char            buffer[1024];
   1101  1.1  christos 		    int             count;
   1102  1.1  christos 
   1103  1.1  christos 		    count = min(section_size, 1024);
   1104  1.1  christos 
   1105  1.1  christos 		    bfd_get_section_contents(pbfd, section, buffer, fptr, count);
   1106  1.1  christos 
   1107  1.5  christos 		    for (i = 0; i < count; i++)
   1108  1.5  christos 			sis_memory_write ((section_address + i) ^ EBT, &buffer[i], 1);
   1109  1.1  christos 
   1110  1.1  christos 		    section_address += count;
   1111  1.1  christos 		    fptr += count;
   1112  1.1  christos 		    section_size -= count;
   1113  1.1  christos 		}
   1114  1.1  christos 	    } else		/* BSS */
   1115  1.1  christos 		if (sis_verbose)
   1116  1.1  christos 		    printf("(not loaded)");
   1117  1.1  christos 	}
   1118  1.1  christos     }
   1119  1.1  christos     if (sis_verbose)
   1120  1.1  christos 	printf("\n");
   1121  1.1  christos 
   1122  1.5  christos     return bfd_get_start_address (pbfd);
   1123  1.5  christos }
   1124  1.5  christos 
   1125  1.5  christos double get_time (void)
   1126  1.5  christos {
   1127  1.5  christos     double usec;
   1128  1.5  christos 
   1129  1.5  christos     struct timeval tm;
   1130  1.5  christos 
   1131  1.5  christos     gettimeofday (&tm, NULL);
   1132  1.5  christos     usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec);
   1133  1.5  christos     return usec / 1E6;
   1134  1.1  christos }
   1135