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