Commit | Line | Data |
---|---|---|
296730a5 MF |
1 | /* This file is part of SIS (SPARC instruction simulator) |
2 | ||
b811d2c2 | 3 | Copyright (C) 1995-2020 Free Software Foundation, Inc. |
296730a5 | 4 | Contributed by Jiri Gaisler, European Space Agency |
17d88f73 JB |
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/>. */ | |
c906108c SS |
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> | |
c906108c SS |
26 | #include <sys/fcntl.h> |
27 | #include "sis.h" | |
28 | #include <dis-asm.h> | |
29 | #include "sim-config.h" | |
638fcdad | 30 | #include <inttypes.h> |
c906108c | 31 | |
c906108c SS |
32 | #define VAL(x) strtol(x,(char **)NULL,0) |
33 | ||
34 | /* Structures and functions from readline library */ | |
35 | ||
5634e839 JG |
36 | #include "readline/readline.h" |
37 | #include "readline/history.h" | |
c906108c SS |
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; | |
94110024 | 72 | uint64 icount; |
c906108c SS |
73 | int dis; |
74 | { | |
102b920e | 75 | int irq, mexc, deb; |
c906108c | 76 | |
96d67095 | 77 | sregs->starttime = get_time(); |
c906108c SS |
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 | ||
102b920e | 84 | mexc = memory_iread (sregs->pc, &sregs->inst, &sregs->hold); |
c906108c SS |
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(); | |
5831e29b | 100 | return BPT_HIT; |
c906108c SS |
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) { | |
638fcdad | 110 | printf(" %8" PRIu64 " ", ebase.simtime); |
c906108c SS |
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 | } | |
96d67095 | 133 | sregs->tottime += get_time() - sregs->starttime; |
c906108c SS |
134 | restore_stdio(); |
135 | if (sregs->err_mode) | |
5831e29b | 136 | return ERROR; |
c906108c SS |
137 | if (ctrl_c) { |
138 | ctrl_c = 0; | |
5831e29b | 139 | return CTRL_C; |
c906108c | 140 | } |
5831e29b | 141 | return TIME_OUT; |
c906108c SS |
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; | |
e26473a1 | 159 | int lfile = 0; |
c906108c SS |
160 | |
161 | cfile = 0; | |
162 | for (i = 0; i < 64; i++) | |
163 | cmdq[i] = 0; | |
14e1f957 | 164 | printf("\n SIS - SPARC instruction simulator %s, copyright Jiri Gaisler 1995\n", sis_version); |
c906108c SS |
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) { | |
0a13382c | 169 | sis_verbose += 1; |
c906108c SS |
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 { | |
e26473a1 | 208 | lfile = stat; |
c906108c SS |
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); | |
d3e9b40a JG |
221 | #ifdef HOST_LITTLE_ENDIAN |
222 | dinfo.endian = BFD_ENDIAN_LITTLE; | |
223 | #else | |
c906108c | 224 | dinfo.endian = BFD_ENDIAN_BIG; |
d3e9b40a | 225 | #endif |
c906108c SS |
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(); | |
e26473a1 JG |
234 | if (lfile) |
235 | last_load_addr = bfd_load(argv[lfile]); | |
c906108c SS |
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: | |
638fcdad | 272 | printf(" Stopped at time %" PRIu64 " (%.3f ms)\n", ebase.simtime, |
c906108c SS |
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; | |
638fcdad | 282 | printf(" %8" PRIu64 " ", ebase.simtime); |
c906108c SS |
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 |