Home | History | Annotate | Line # | Download | only in erc32
      1   1.1.1.4  christos /* This file is part of SIS (SPARC instruction simulator)
      2   1.1.1.4  christos 
      3  1.1.1.11  christos    Copyright (C) 1995-2025 Free Software Foundation, Inc.
      4   1.1.1.4  christos    Contributed by Jiri Gaisler, European Space Agency
      5   1.1.1.4  christos 
      6   1.1.1.4  christos    This program is free software; you can redistribute it and/or modify
      7   1.1.1.4  christos    it under the terms of the GNU General Public License as published by
      8   1.1.1.4  christos    the Free Software Foundation; either version 3 of the License, or
      9   1.1.1.4  christos    (at your option) any later version.
     10   1.1.1.4  christos 
     11   1.1.1.4  christos    This program is distributed in the hope that it will be useful,
     12   1.1.1.4  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1.1.4  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1.1.4  christos    GNU General Public License for more details.
     15   1.1.1.4  christos 
     16   1.1.1.4  christos    You should have received a copy of the GNU General Public License
     17   1.1.1.4  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18       1.1  christos 
     19   1.1.1.9  christos /* This must come before any other includes.  */
     20   1.1.1.9  christos #include "defs.h"
     21   1.1.1.9  christos 
     22       1.1  christos #include <signal.h>
     23       1.1  christos #include <string.h>
     24       1.1  christos #include <stdlib.h>
     25       1.1  christos #include <stdio.h>
     26       1.1  christos #include <sys/fcntl.h>
     27       1.1  christos #include "sis.h"
     28       1.1  christos #include <dis-asm.h>
     29       1.1  christos #include "sim-config.h"
     30   1.1.1.4  christos #include <inttypes.h>
     31       1.1  christos 
     32       1.1  christos #define	VAL(x)	strtol(x,(char **)NULL,0)
     33       1.1  christos 
     34       1.1  christos /* Structures and functions from readline library */
     35       1.1  christos 
     36   1.1.1.4  christos #include "readline/readline.h"
     37   1.1.1.4  christos #include "readline/history.h"
     38       1.1  christos 
     39       1.1  christos /* Command history buffer length - MUST be binary */
     40       1.1  christos #define HIST_LEN	64
     41       1.1  christos 
     42       1.1  christos extern struct disassemble_info dinfo;
     43       1.1  christos extern struct pstate sregs;
     44       1.1  christos extern struct estate ebase;
     45       1.1  christos 
     46       1.1  christos extern int      ctrl_c;
     47       1.1  christos extern int      nfp;
     48       1.1  christos extern int      ift;
     49       1.1  christos extern int      wrp;
     50       1.1  christos extern int      rom8;
     51       1.1  christos extern int      uben;
     52       1.1  christos extern int      sis_verbose;
     53       1.1  christos extern char    *sis_version;
     54       1.1  christos extern struct estate ebase;
     55       1.1  christos extern struct evcell evbuf[];
     56       1.1  christos extern struct irqcell irqarr[];
     57       1.1  christos extern int      irqpend, ext_irl;
     58       1.1  christos extern int      termsave;
     59       1.1  christos extern int      sparclite;
     60       1.1  christos extern int      dumbio;
     61       1.1  christos extern char     uart_dev1[];
     62       1.1  christos extern char     uart_dev2[];
     63   1.1.1.9  christos extern uint32_t   last_load_addr;
     64       1.1  christos 
     65       1.1  christos #ifdef ERA
     66       1.1  christos extern int era;
     67       1.1  christos #endif
     68       1.1  christos 
     69       1.1  christos int
     70   1.1.1.9  christos run_sim(struct pstate *sregs, uint64_t icount, int dis)
     71       1.1  christos {
     72   1.1.1.4  christos     int             irq, mexc, deb;
     73       1.1  christos 
     74   1.1.1.4  christos     sregs->starttime = get_time();
     75       1.1  christos     init_stdio();
     76       1.1  christos     if (sregs->err_mode) icount = 0;
     77       1.1  christos     deb = dis || sregs->histlen || sregs->bptnum;
     78       1.1  christos     irq = 0;
     79       1.1  christos     while (icount > 0) {
     80       1.1  christos 
     81   1.1.1.4  christos 	mexc = memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
     82       1.1  christos 	sregs->icnt = 1;
     83       1.1  christos 	if (sregs->annul) {
     84       1.1  christos 	    sregs->annul = 0;
     85       1.1  christos 	    sregs->pc = sregs->npc;
     86       1.1  christos 	    sregs->npc = sregs->npc + 4;
     87       1.1  christos 	} else {
     88       1.1  christos 	    sregs->fhold = 0;
     89       1.1  christos 	    if (ext_irl) irq = check_interrupts(sregs);
     90       1.1  christos 	    if (!irq) {
     91       1.1  christos 		if (mexc) {
     92       1.1  christos 		    sregs->trap = I_ACC_EXC;
     93       1.1  christos 		} else {
     94       1.1  christos 		    if (deb) {
     95       1.1  christos 	    		if ((sregs->bphit = check_bpt(sregs)) != 0) {
     96       1.1  christos             		    restore_stdio();
     97   1.1.1.4  christos 	    		    return BPT_HIT;
     98       1.1  christos 	    		}
     99       1.1  christos 		        if (sregs->histlen) {
    100       1.1  christos 			    sregs->histbuf[sregs->histind].addr = sregs->pc;
    101       1.1  christos 			    sregs->histbuf[sregs->histind].time = ebase.simtime;
    102       1.1  christos 			    sregs->histind++;
    103       1.1  christos 			    if (sregs->histind >= sregs->histlen)
    104       1.1  christos 			        sregs->histind = 0;
    105       1.1  christos 		        }
    106       1.1  christos 		        if (dis) {
    107   1.1.1.4  christos 			    printf(" %8" PRIu64 " ", ebase.simtime);
    108       1.1  christos 			    dis_mem(sregs->pc, 1, &dinfo);
    109       1.1  christos 		        }
    110       1.1  christos 		    }
    111       1.1  christos 		    dispatch_instruction(sregs);
    112       1.1  christos 		    icount--;
    113       1.1  christos 		}
    114       1.1  christos 	    }
    115       1.1  christos 	    if (sregs->trap) {
    116       1.1  christos 		irq = 0;
    117       1.1  christos 		sregs->err_mode = execute_trap(sregs);
    118       1.1  christos         	if (sregs->err_mode) {
    119       1.1  christos 	            error_mode(sregs->pc);
    120       1.1  christos 	            icount = 0;
    121       1.1  christos 	        }
    122       1.1  christos 	    }
    123       1.1  christos 	}
    124       1.1  christos 	advance_time(sregs);
    125       1.1  christos 	if (ctrl_c || (sregs->tlimit <= ebase.simtime)) {
    126       1.1  christos 	    icount = 0;
    127       1.1  christos 	    if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1;
    128       1.1  christos 	}
    129       1.1  christos     }
    130   1.1.1.4  christos     sregs->tottime += get_time() - sregs->starttime;
    131       1.1  christos     restore_stdio();
    132       1.1  christos     if (sregs->err_mode)
    133   1.1.1.4  christos 	return ERROR;
    134       1.1  christos     if (ctrl_c) {
    135       1.1  christos 	ctrl_c = 0;
    136   1.1.1.4  christos 	return CTRL_C;
    137       1.1  christos     }
    138   1.1.1.4  christos     return TIME_OUT;
    139       1.1  christos }
    140       1.1  christos 
    141   1.1.1.9  christos static int ATTRIBUTE_PRINTF (3, 4)
    142   1.1.1.9  christos fprintf_styled (void *stream, enum disassembler_style style,
    143   1.1.1.9  christos 		const char *fmt, ...)
    144   1.1.1.9  christos {
    145   1.1.1.9  christos   int ret;
    146   1.1.1.9  christos   FILE *out = (FILE *) stream;
    147   1.1.1.9  christos   va_list args;
    148   1.1.1.9  christos 
    149   1.1.1.9  christos   va_start (args, fmt);
    150   1.1.1.9  christos   ret = vfprintf (out, fmt, args);
    151   1.1.1.9  christos   va_end (args);
    152   1.1.1.9  christos 
    153   1.1.1.9  christos   return ret;
    154   1.1.1.9  christos }
    155   1.1.1.9  christos 
    156       1.1  christos int
    157   1.1.1.9  christos main(int argc, char **argv)
    158       1.1  christos {
    159       1.1  christos 
    160       1.1  christos     int             cont = 1;
    161       1.1  christos     int             stat = 1;
    162       1.1  christos     int             freq = 14;
    163       1.1  christos     int             copt = 0;
    164       1.1  christos 
    165       1.1  christos     char           *cfile, *bacmd;
    166       1.1  christos     char           *cmdq[HIST_LEN];
    167       1.1  christos     int             cmdi = 0;
    168       1.1  christos     int             i;
    169   1.1.1.4  christos     int             lfile = 0;
    170       1.1  christos 
    171       1.1  christos     cfile = 0;
    172       1.1  christos     for (i = 0; i < 64; i++)
    173       1.1  christos 	cmdq[i] = 0;
    174       1.1  christos     printf("\n SIS - SPARC instruction simulator %s,  copyright Jiri Gaisler 1995\n", sis_version);
    175       1.1  christos     printf(" Bug-reports to jgais (at) wd.estec.esa.nl\n\n");
    176       1.1  christos     while (stat < argc) {
    177       1.1  christos 	if (argv[stat][0] == '-') {
    178       1.1  christos 	    if (strcmp(argv[stat], "-v") == 0) {
    179   1.1.1.4  christos 		sis_verbose += 1;
    180       1.1  christos 	    } else if (strcmp(argv[stat], "-c") == 0) {
    181       1.1  christos 		if ((stat + 1) < argc) {
    182       1.1  christos 		    copt = 1;
    183       1.1  christos 		    cfile = argv[++stat];
    184       1.1  christos 		}
    185       1.1  christos 	    } else if (strcmp(argv[stat], "-nfp") == 0)
    186       1.1  christos 		nfp = 1;
    187       1.1  christos 	    else if (strcmp(argv[stat], "-ift") == 0)
    188       1.1  christos 		ift = 1;
    189       1.1  christos 	    else if (strcmp(argv[stat], "-wrp") == 0)
    190       1.1  christos 		wrp = 1;
    191       1.1  christos 	    else if (strcmp(argv[stat], "-rom8") == 0)
    192       1.1  christos 		rom8 = 1;
    193       1.1  christos 	    else if (strcmp(argv[stat], "-uben") == 0)
    194       1.1  christos 		uben = 1;
    195       1.1  christos 	    else if (strcmp(argv[stat], "-uart1") == 0) {
    196       1.1  christos 		if ((stat + 1) < argc)
    197       1.1  christos 		    strcpy(uart_dev1, argv[++stat]);
    198       1.1  christos 	    } else if (strcmp(argv[stat], "-uart2") == 0) {
    199       1.1  christos 		if ((stat + 1) < argc)
    200       1.1  christos 		    strcpy(uart_dev2, argv[++stat]);
    201       1.1  christos 	    } else if (strcmp(argv[stat], "-freq") == 0) {
    202       1.1  christos 		if ((stat + 1) < argc)
    203       1.1  christos 		    freq = VAL(argv[++stat]);
    204       1.1  christos 	    } else if (strcmp(argv[stat], "-sparclite") == 0) {
    205       1.1  christos 		sparclite = 1;
    206       1.1  christos #ifdef ERA
    207       1.1  christos 	    } else if (strcmp(argv[stat], "-era") == 0) {
    208       1.1  christos 		era = 1;
    209       1.1  christos #endif
    210       1.1  christos             } else if (strcmp(argv[stat], "-dumbio") == 0) {
    211       1.1  christos 		dumbio = 1;
    212       1.1  christos 	    } else {
    213       1.1  christos 		printf("unknown option %s\n", argv[stat]);
    214       1.1  christos 		usage();
    215       1.1  christos 		exit(1);
    216       1.1  christos 	    }
    217       1.1  christos 	} else {
    218   1.1.1.4  christos 	    lfile = stat;
    219       1.1  christos 	}
    220       1.1  christos 	stat++;
    221       1.1  christos     }
    222       1.1  christos     if (nfp)
    223       1.1  christos 	printf("FPU disabled\n");
    224       1.1  christos #ifdef ERA
    225       1.1  christos     if (era)
    226       1.1  christos 	printf("ERA ECC emulation enabled\n");
    227       1.1  christos #endif
    228       1.1  christos     sregs.freq = freq;
    229       1.1  christos 
    230   1.1.1.9  christos     INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf,
    231   1.1.1.9  christos 			  (fprintf_styled_ftype) fprintf_styled);
    232   1.1.1.4  christos #ifdef HOST_LITTLE_ENDIAN
    233   1.1.1.4  christos     dinfo.endian = BFD_ENDIAN_LITTLE;
    234   1.1.1.4  christos #else
    235       1.1  christos     dinfo.endian = BFD_ENDIAN_BIG;
    236   1.1.1.4  christos #endif
    237       1.1  christos 
    238   1.1.1.9  christos #ifdef F_GETFL
    239       1.1  christos     termsave = fcntl(0, F_GETFL, 0);
    240   1.1.1.9  christos #endif
    241       1.1  christos     using_history();
    242       1.1  christos     init_signals();
    243       1.1  christos     ebase.simtime = 0;
    244       1.1  christos     reset_all();
    245       1.1  christos     init_bpt(&sregs);
    246       1.1  christos     init_sim();
    247   1.1.1.4  christos     if (lfile)
    248   1.1.1.4  christos         last_load_addr = bfd_load(argv[lfile]);
    249       1.1  christos #ifdef STAT
    250       1.1  christos     reset_stat(&sregs);
    251       1.1  christos #endif
    252       1.1  christos 
    253       1.1  christos     if (copt) {
    254       1.1  christos 	bacmd = (char *) malloc(256);
    255       1.1  christos 	strcpy(bacmd, "batch ");
    256       1.1  christos 	strcat(bacmd, cfile);
    257       1.1  christos 	exec_cmd(&sregs, bacmd);
    258       1.1  christos     }
    259       1.1  christos     while (cont) {
    260       1.1  christos 
    261       1.1  christos 	if (cmdq[cmdi] != 0) {
    262       1.1  christos #if 0
    263       1.1  christos 	    remove_history(cmdq[cmdi]);
    264       1.1  christos #else
    265       1.1  christos 	    remove_history(cmdi);
    266       1.1  christos #endif
    267       1.1  christos 	    free(cmdq[cmdi]);
    268       1.1  christos 	    cmdq[cmdi] = 0;
    269       1.1  christos 	}
    270       1.1  christos 	cmdq[cmdi] = readline("sis> ");
    271       1.1  christos 	if (cmdq[cmdi] && *cmdq[cmdi])
    272       1.1  christos 	    add_history(cmdq[cmdi]);
    273       1.1  christos 	if (cmdq[cmdi])
    274       1.1  christos 	    stat = exec_cmd(&sregs, cmdq[cmdi]);
    275       1.1  christos 	else {
    276       1.1  christos 	    puts("\n");
    277       1.1  christos 	    exit(0);
    278       1.1  christos 	}
    279       1.1  christos 	switch (stat) {
    280       1.1  christos 	case OK:
    281       1.1  christos 	    break;
    282       1.1  christos 	case CTRL_C:
    283       1.1  christos 	    printf("\b\bInterrupt!\n");
    284  1.1.1.10  christos 	    ATTRIBUTE_FALLTHROUGH;
    285       1.1  christos 	case TIME_OUT:
    286   1.1.1.4  christos 	    printf(" Stopped at time %" PRIu64 " (%.3f ms)\n", ebase.simtime,
    287       1.1  christos 	      ((double) ebase.simtime / (double) sregs.freq) / 1000.0);
    288       1.1  christos 	    break;
    289       1.1  christos 	case BPT_HIT:
    290       1.1  christos 	    printf("breakpoint at 0x%08x reached\n", sregs.pc);
    291       1.1  christos 	    sregs.bphit = 1;
    292       1.1  christos 	    break;
    293       1.1  christos 	case ERROR:
    294       1.1  christos 	    printf("IU in error mode (%d)\n", sregs.trap);
    295       1.1  christos 	    stat = 0;
    296   1.1.1.4  christos 	    printf(" %8" PRIu64 " ", ebase.simtime);
    297       1.1  christos 	    dis_mem(sregs.pc, 1, &dinfo);
    298       1.1  christos 	    break;
    299       1.1  christos 	default:
    300       1.1  christos 	    break;
    301       1.1  christos 	}
    302       1.1  christos 	ctrl_c = 0;
    303       1.1  christos 	stat = OK;
    304       1.1  christos 
    305       1.1  christos 	cmdi = (cmdi + 1) & (HIST_LEN - 1);
    306       1.1  christos 
    307       1.1  christos     }
    308       1.1  christos     return 0;
    309       1.1  christos }
    310       1.1  christos 
    311