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