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