* interf.c (sim_open): Ignore -E arg.
[deliverable/binutils-gdb.git] / sim / erc32 / interf.c
1 /*
2 * This file is part of SIS.
3 *
4 * SIS, SPARC instruction simulator V1.6 Copyright (C) 1995 Jiri Gaisler,
5 * European 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 <signal.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <sys/fcntl.h>
27 #include "sis.h"
28 #include "bfd.h"
29 #include <dis-asm.h>
30
31 #include "remote-sim.h"
32
33 #ifndef fprintf
34 extern fprintf();
35 #endif
36
37 #define VAL(x) strtol(x,(char *)NULL,0)
38
39 extern char **buildargv(char *input);
40
41 extern struct disassemble_info dinfo;
42 extern struct pstate sregs;
43 extern struct estate ebase;
44
45 extern int ctrl_c;
46 extern int nfp;
47 extern int ift;
48 extern int rom8;
49 extern int wrp;
50 extern int sis_verbose;
51 extern char *sis_version;
52 extern struct estate ebase;
53 extern struct evcell evbuf[];
54 extern struct irqcell irqarr[];
55 extern int irqpend, ext_irl;
56 extern int sparclite;
57 extern int termsave;
58 extern char uart_dev1[], uart_dev2[];
59
60 int sis_gdb_break = 1;
61
62 host_callback *sim_callback;
63
64 run_sim(sregs, go, icount, dis)
65 struct pstate *sregs;
66 int go;
67 unsigned int icount;
68 int dis;
69 {
70 int mexc, ws;
71
72 if (sis_verbose)
73 (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
74 sregs->pc);
75 init_stdio();
76 sregs->starttime = time(NULL);
77 while ((!sregs->err_mode & (go || (icount > 0))) &&
78 ((sregs->bptnum == 0) || !(sregs->bphit = check_bpt(sregs)))) {
79
80 sregs->fhold = 0;
81 sregs->hold = 0;
82 sregs->icnt = 0;
83
84 check_interrupts(sregs);
85 if (sregs->trap) {
86 sregs->err_mode = execute_trap(sregs);
87 } else {
88 if (sregs->psr & 0x080)
89 sregs->asi = 8;
90 else
91 sregs->asi = 9;
92
93 mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, &sregs->hold);
94 if (sregs->annul) {
95 sregs->annul = 0;
96 sregs->icnt = 1;
97 sregs->pc = sregs->npc;
98 sregs->npc = sregs->npc + 4;
99 } else {
100 if (mexc) {
101 sregs->trap = I_ACC_EXC;
102 } else {
103 if (sregs->histlen) {
104 sregs->histbuf[sregs->histind].addr = sregs->pc;
105 sregs->histbuf[sregs->histind].time = ebase.simtime;
106 sregs->histind++;
107 if (sregs->histind >= sregs->histlen)
108 sregs->histind = 0;
109 }
110 if (dis) {
111 printf(" %8d ", ebase.simtime);
112 dis_mem(sregs->pc, 1, &dinfo);
113 }
114 if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
115 if (sis_verbose)
116 (*sim_callback->printf_filtered) (sim_callback,
117 "SW BP hit at %x\n", sregs->pc);
118 sim_stop();
119 restore_stdio();
120 clearerr(stdin);
121 return (BPT_HIT);
122 } else
123 dispatch_instruction(sregs);
124 }
125 icount--;
126 }
127 if (sregs->trap) {
128 sregs->err_mode = execute_trap(sregs);
129 }
130 }
131 advance_time(sregs);
132 if (ctrl_c) {
133 go = icount = 0;
134 }
135 }
136 sim_stop();
137 sregs->tottime += time(NULL) - sregs->starttime;
138 restore_stdio();
139 clearerr(stdin);
140 if (sregs->err_mode)
141 error_mode(sregs->pc);
142 if (sregs->err_mode)
143 return (ERROR);
144 if (sregs->bphit) {
145 if (sis_verbose)
146 (*sim_callback->printf_filtered) (sim_callback,
147 "HW BP hit at %x\n", sregs->pc);
148 return (BPT_HIT);
149 }
150 if (ctrl_c) {
151 ctrl_c = 0;
152 return (CTRL_C);
153 }
154 return (TIME_OUT);
155 }
156
157 void
158 sim_set_callbacks (sd, ptr)
159 SIM_DESC sd;
160 host_callback *ptr;
161 {
162 sim_callback = ptr;
163 }
164
165 void
166 sim_size (memsize)
167 int memsize;
168 {
169 }
170
171 SIM_DESC
172 sim_open(kind, argv)
173 SIM_OPEN_KIND kind;
174 char **argv;
175 {
176
177 int argc = 0;
178 int cont = 1;
179 int stat = 1;
180 int grdl = 0;
181 int freq = 15;
182
183 (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
184 (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
185 while (argv[argc])
186 argc++;
187 while (stat < argc) {
188 if (argv[stat][0] == '-') {
189 if (strcmp(argv[stat], "-E") == 0)
190 ++stat; /* ignore endian spec */
191 if (strcmp(argv[stat], "-v") == 0) {
192 sis_verbose = 1;
193 } else
194 if (strcmp(argv[stat], "-nfp") == 0) {
195 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
196 nfp = 1;
197 } else
198 if (strcmp(argv[stat], "-ift") == 0) {
199 ift = 1;
200 } else
201 if (strcmp(argv[stat], "-sparclite") == 0) {
202 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
203 sparclite = 1;
204 } else
205 if (strcmp(argv[stat], "-wrp") == 0) {
206 wrp = 1;
207 } else
208 if (strcmp(argv[stat], "-rom8") == 0) {
209 rom8 = 1;
210 } else
211 if (strcmp(argv[stat], "-uart1") == 0) {
212 if ((stat + 1) < argc)
213 strcpy(uart_dev1, argv[++stat]);
214 } else
215 if (strcmp(argv[stat], "-uart2") == 0) {
216 if ((stat + 1) < argc)
217 strcpy(uart_dev2, argv[++stat]);
218 } else
219 if (strcmp(argv[stat], "-nogdb") == 0) {
220 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
221 sis_gdb_break = 0;
222 } else
223 if (strcmp(argv[stat], "-freq") == 0)
224 if ((stat + 1) < argc) {
225 freq = VAL(argv[++stat]);
226 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
227 }
228 } else
229 bfd_load(argv[stat]);
230 stat++;
231 }
232 sregs.freq = freq;
233 termsave = fcntl(0, F_GETFL, 0);
234 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
235 dinfo.endian = BFD_ENDIAN_BIG;
236 init_signals();
237 reset_all();
238 ebase.simtime = 0;
239 init_sim();
240 init_bpt(&sregs);
241 reset_stat(&sregs);
242
243 /* Fudge our descriptor for now. */
244 return (SIM_DESC) 1;
245 }
246
247 void
248 sim_close(sd, quitting)
249 SIM_DESC sd;
250 int quitting;
251 {
252
253 exit_sim();
254 fcntl(0, F_SETFL, termsave);
255
256 };
257
258 /* For communication from sim_load to sim_create_inferior. */
259 static bfd_vma start_address;
260
261 SIM_RC
262 sim_load(sd, prog, abfd, from_tty)
263 SIM_DESC sd;
264 char *prog;
265 bfd *abfd;
266 int from_tty;
267 {
268 start_address = bfd_load (prog);
269 return (0);
270 }
271
272 SIM_RC
273 sim_create_inferior(sd, argv, env)
274 SIM_DESC sd;
275 char **argv;
276 char **env;
277 {
278 ebase.simtime = 0;
279 reset_all();
280 reset_stat(&sregs);
281 sregs.pc = start_address & ~3;
282 sregs.npc = sregs.pc + 4;
283 return SIM_RC_OK;
284 }
285
286 void
287 sim_store_register(sd, regno, value)
288 SIM_DESC sd;
289 int regno;
290 unsigned char *value;
291 {
292 /* FIXME: Review the computation of regval. */
293 int regval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
294 set_regi(&sregs, regno, regval);
295 }
296
297
298 void
299 sim_fetch_register(sd, regno, buf)
300 SIM_DESC sd;
301 int regno;
302 unsigned char *buf;
303 {
304 get_regi(&sregs, regno, buf);
305 }
306
307 int
308 sim_write(sd, mem, buf, length)
309 SIM_DESC sd;
310 SIM_ADDR mem;
311 unsigned char *buf;
312 int length;
313 {
314 return (sis_memory_write(mem, buf, length));
315 }
316
317 int
318 sim_read(sd, mem, buf, length)
319 SIM_DESC sd;
320 SIM_ADDR mem;
321 unsigned char *buf;
322 int length;
323 {
324 return (sis_memory_read(mem, buf, length));
325 }
326
327 void
328 sim_info(sd, verbose)
329 SIM_DESC sd;
330 int verbose;
331 {
332 show_stat(&sregs);
333 }
334
335 int simstat = OK;
336
337 void
338 sim_stop_reason(sd, reason, sigrc)
339 SIM_DESC sd;
340 enum sim_stop * reason;
341 int *sigrc;
342 {
343
344 switch (simstat) {
345 case CTRL_C:
346 *reason = sim_stopped;
347 *sigrc = SIGINT;
348 break;
349 case OK:
350 case TIME_OUT:
351 case BPT_HIT:
352 *reason = sim_stopped;
353 #ifdef _WIN32
354 #define SIGTRAP 5
355 #endif
356 *sigrc = SIGTRAP;
357 break;
358 case ERROR:
359 *sigrc = 0;
360 *reason = sim_exited;
361 }
362 ctrl_c = 0;
363 simstat = OK;
364 }
365
366 /* Flush all register windows out to the stack. Starting after the invalid
367 window, flush all windows up to, and including the current window. This
368 allows GDB to do backtraces and look at local variables for frames that
369 are still in the register windows. Note that strictly speaking, this
370 behavior is *wrong* for several reasons. First, it doesn't use the window
371 overflow handlers. It therefore assumes standard frame layouts and window
372 handling policies. Second, it changes system state behind the back of the
373 target program. I expect this to mainly pose problems when debugging trap
374 handlers.
375 */
376
377 #define PSR_CWP 0x7
378
379 static void
380 flush_windows ()
381 {
382 int invwin;
383 int cwp;
384 int win;
385 int ws;
386
387 /* Keep current window handy */
388
389 cwp = sregs.psr & PSR_CWP;
390
391 /* Calculate the invalid window from the wim. */
392
393 for (invwin = 0; invwin <= PSR_CWP; invwin++)
394 if ((sregs.wim >> invwin) & 1)
395 break;
396
397 /* Start saving with the window after the invalid window. */
398
399 invwin = (invwin - 1) & PSR_CWP;
400
401 for (win = invwin; ; win = (win - 1) & PSR_CWP)
402 {
403 uint32 sp;
404 int i;
405
406 sp = sregs.r[(win * 16 + 14) & 0x7f];
407
408 for (i = 0; i < 16; i++)
409 memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
410 &ws);
411
412 if (win == cwp)
413 break;
414 }
415 }
416
417 void
418 sim_resume(SIM_DESC sd, int step, int siggnal)
419 {
420 simstat = run_sim(&sregs, 1, 0, 0);
421
422 if (sis_gdb_break) flush_windows ();
423 }
424
425 int
426 sim_trace (sd)
427 SIM_DESC sd;
428 {
429 /* FIXME: unfinished */
430 sim_resume (sd, 0, 0);
431 return 1;
432 }
433
434 void
435 sim_kill(SIM_DESC sd)
436 {
437 }
438
439 void
440 sim_do_command(sd, cmd)
441 SIM_DESC sd;
442 char *cmd;
443 {
444 exec_cmd(&sregs, cmd);
445 }
446
447 #if 0 /* FIXME: These shouldn't exist. */
448
449 int
450 sim_insert_breakpoint(int addr)
451 {
452 if (sregs.bptnum < BPT_MAX) {
453 sregs.bpts[sregs.bptnum] = addr & ~0x3;
454 sregs.bptnum++;
455 if (sis_verbose)
456 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
457 return 0;
458 } else
459 return 1;
460 }
461
462 int
463 sim_remove_breakpoint(int addr)
464 {
465 int i = 0;
466
467 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
468 i++;
469 if (addr == sregs.bpts[i]) {
470 for (; i < sregs.bptnum - 1; i++)
471 sregs.bpts[i] = sregs.bpts[i + 1];
472 sregs.bptnum -= 1;
473 if (sis_verbose)
474 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
475 return 0;
476 }
477 return 1;
478 }
479
480 #endif
This page took 0.040944 seconds and 5 git commands to generate.