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