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