1 /* This file is part of SIS (SPARC instruction simulator) 2 3 Copyright (C) 1995-2017 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 42 extern struct disassemble_info dinfo; 43 extern struct pstate sregs; 44 extern struct estate ebase; 45 46 extern int ctrl_c; 47 extern int nfp; 48 extern int ift; 49 extern int wrp; 50 extern int rom8; 51 extern int uben; 52 extern int sis_verbose; 53 extern char *sis_version; 54 extern struct estate ebase; 55 extern struct evcell evbuf[]; 56 extern struct irqcell irqarr[]; 57 extern int irqpend, ext_irl; 58 extern int termsave; 59 extern int sparclite; 60 extern int dumbio; 61 extern char uart_dev1[]; 62 extern char uart_dev2[]; 63 extern uint32 last_load_addr; 64 65 #ifdef ERA 66 extern int era; 67 #endif 68 69 int 70 run_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 144 int 145 main(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