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