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