2 * This file is part of SIS.
4 * SIS, SPARC instruction simulator V1.6 Copyright (C) 1995 Jiri Gaisler,
5 * European Space Agency
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)
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
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.
28 #include <sys/fcntl.h>
30 #include "libiberty.h"
33 #include "sim-config.h"
35 #include "gdb/remote-sim.h"
36 #include "gdb/signals.h"
40 #define VAL(x) strtol(x,(char **)NULL,0)
42 extern struct disassemble_info dinfo
;
43 extern struct pstate sregs
;
44 extern struct estate ebase
;
46 extern int current_target_byte_order
;
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
;
61 extern int sparclite_board
;
63 extern char uart_dev1
[], uart_dev2
[];
65 int sis_gdb_break
= 1;
67 host_callback
*sim_callback
;
70 run_sim(sregs
, icount
, dis
)
78 (*sim_callback
->printf_filtered
) (sim_callback
, "resuming at %x\n",
81 sregs
->starttime
= time(NULL
);
83 while (!sregs
->err_mode
& (icount
> 0)) {
89 if (sregs
->psr
& 0x080)
94 #if 0 /* DELETE ME! for debugging purposes only */
96 if (sregs
->pc
== 0 || sregs
->npc
== 0)
97 printf ("bogus pc or npc\n");
99 mexc
= memory_read(sregs
->asi
, sregs
->pc
, &sregs
->inst
,
101 #if 1 /* DELETE ME! for debugging purposes only */
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],
114 sregs
->pc
= sregs
->npc
;
115 sregs
->npc
= sregs
->npc
+ 4;
117 if (ext_irl
) irq
= check_interrupts(sregs
);
120 sregs
->trap
= I_ACC_EXC
;
122 if ((sis_gdb_break
) && (sregs
->inst
== 0x91d02001)) {
124 (*sim_callback
->printf_filtered
) (sim_callback
,
125 "SW BP hit at %x\n", sregs
->pc
);
131 dispatch_instruction(sregs
);
137 sregs
->err_mode
= execute_trap(sregs
);
146 sregs
->tottime
+= time(NULL
) - sregs
->starttime
;
150 error_mode(sregs
->pc
);
155 (*sim_callback
->printf_filtered
) (sim_callback
,
156 "HW BP hit at %x\n", sregs
->pc
);
167 sim_set_callbacks (ptr
)
180 sim_open (kind
, callback
, abfd
, argv
)
182 struct host_callback_struct
*callback
;
191 sim_callback
= callback
;
195 while (stat
< argc
) {
196 if (argv
[stat
][0] == '-') {
197 if (strcmp(argv
[stat
], "-v") == 0) {
200 if (strcmp(argv
[stat
], "-nfp") == 0) {
203 if (strcmp(argv
[stat
], "-ift") == 0) {
206 if (strcmp(argv
[stat
], "-sparclite") == 0) {
209 if (strcmp(argv
[stat
], "-sparclite-board") == 0) {
212 if (strcmp(argv
[stat
], "-dumbio") == 0) {
215 if (strcmp(argv
[stat
], "-wrp") == 0) {
218 if (strcmp(argv
[stat
], "-rom8") == 0) {
221 if (strcmp(argv
[stat
], "-uben") == 0) {
224 if (strcmp(argv
[stat
], "-uart1") == 0) {
225 if ((stat
+ 1) < argc
)
226 strcpy(uart_dev1
, argv
[++stat
]);
228 if (strcmp(argv
[stat
], "-uart2") == 0) {
229 if ((stat
+ 1) < argc
)
230 strcpy(uart_dev2
, argv
[++stat
]);
232 if (strcmp(argv
[stat
], "-nogdb") == 0) {
235 if (strcmp(argv
[stat
], "-freq") == 0) {
236 if ((stat
+ 1) < argc
) {
237 freq
= VAL(argv
[++stat
]);
240 (*sim_callback
->printf_filtered
) (sim_callback
,
241 "unknown option %s\n",
245 bfd_load(argv
[stat
]);
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");
253 (*sim_callback
->printf_filtered
) (sim_callback
, "no FPU\n");
255 (*sim_callback
->printf_filtered
) (sim_callback
, "simulating Sparclite\n");
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");
261 (*sim_callback
->printf_filtered
) (sim_callback
, " ERC32 freq %d Mhz\n", freq
);
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
;
274 /* Fudge our descriptor for now. */
279 sim_close(sd
, quitting
)
285 fcntl(0, F_SETFL
, termsave
);
290 sim_load(sd
, prog
, abfd
, from_tty
)
301 sim_create_inferior(sd
, abfd
, argv
, env
)
307 bfd_vma start_address
= 0;
309 start_address
= bfd_get_start_address (abfd
);
314 sregs
.pc
= start_address
& ~3;
315 sregs
.npc
= sregs
.pc
+ 4;
320 sim_store_register(sd
, regno
, value
, length
)
323 unsigned char *value
;
326 /* FIXME: Review the computation of regval. */
328 if (current_target_byte_order
== BIG_ENDIAN
)
329 regval
= (value
[0] << 24) | (value
[1] << 16)
330 | (value
[2] << 8) | value
[3];
332 regval
= (value
[3] << 24) | (value
[2] << 16)
333 | (value
[1] << 8) | value
[0];
334 set_regi(&sregs
, regno
, regval
);
340 sim_fetch_register(sd
, regno
, buf
, length
)
346 get_regi(&sregs
, regno
, buf
);
351 sim_write(sd
, mem
, buf
, length
)
357 return (sis_memory_write(mem
, buf
, length
));
361 sim_read(sd
, mem
, buf
, length
)
367 return (sis_memory_read(mem
, buf
, length
));
371 sim_info(sd
, verbose
)
381 sim_stop_reason(sd
, reason
, sigrc
)
383 enum sim_stop
* reason
;
389 *reason
= sim_stopped
;
390 *sigrc
= TARGET_SIGNAL_INT
;
395 *reason
= sim_stopped
;
396 *sigrc
= TARGET_SIGNAL_TRAP
;
400 *reason
= sim_exited
;
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
425 /* Keep current window handy */
427 cwp
= sregs
.psr
& PSR_CWP
;
429 /* Calculate the invalid window from the wim. */
431 for (invwin
= 0; invwin
<= PSR_CWP
; invwin
++)
432 if ((sregs
.wim
>> invwin
) & 1)
435 /* Start saving with the window after the invalid window. */
437 invwin
= (invwin
- 1) & PSR_CWP
;
439 for (win
= invwin
; ; win
= (win
- 1) & PSR_CWP
)
444 sp
= sregs
.r
[(win
* 16 + 14) & 0x7f];
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
);
452 for (i
= 0; i
< 16; i
++)
453 memory_write (11, sp
+ 4 * i
, &sregs
.r
[(win
* 16 + 16 + i
) & 0x7f], 2,
462 sim_resume(SIM_DESC sd
, int step
, int siggnal
)
464 simstat
= run_sim(&sregs
, -1, 0);
466 if (sis_gdb_break
) flush_windows ();
473 /* FIXME: unfinished */
474 sim_resume (sd
, 0, 0);
479 sim_do_command(sd
, cmd
)
483 exec_cmd(&sregs
, cmd
);
486 #if 0 /* FIXME: These shouldn't exist. */
489 sim_insert_breakpoint(int addr
)
491 if (sregs
.bptnum
< BPT_MAX
) {
492 sregs
.bpts
[sregs
.bptnum
] = addr
& ~0x3;
495 (*sim_callback
->printf_filtered
) (sim_callback
, "inserted HW BP at %x\n", addr
);
502 sim_remove_breakpoint(int addr
)
506 while ((i
< sregs
.bptnum
) && (sregs
.bpts
[i
] != addr
))
508 if (addr
== sregs
.bpts
[i
]) {
509 for (; i
< sregs
.bptnum
- 1; i
++)
510 sregs
.bpts
[i
] = sregs
.bpts
[i
+ 1];
513 (*sim_callback
->printf_filtered
) (sim_callback
, "removed HW BP at %x\n", addr
);