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