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