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