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.
29 #include <sys/fcntl.h>
31 #include "libiberty.h"
34 #include "sim-config.h"
36 #include "gdb/remote-sim.h"
37 #include "gdb/signals.h"
41 extern struct disassemble_info dinfo
;
42 extern struct pstate sregs
;
43 extern struct estate ebase
;
45 extern int current_target_byte_order
;
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
;
60 extern int sparclite_board
;
62 extern char uart_dev1
[], uart_dev2
[];
64 int sis_gdb_break
= 1;
66 host_callback
*sim_callback
;
69 run_sim(sregs
, icount
, dis
)
77 (*sim_callback
->printf_filtered
) (sim_callback
, "resuming at %x\n",
80 sregs
->starttime
= time(NULL
);
82 while (!sregs
->err_mode
& (icount
> 0)) {
88 if (sregs
->psr
& 0x080)
93 #if 0 /* DELETE ME! for debugging purposes only */
95 if (sregs
->pc
== 0 || sregs
->npc
== 0)
96 printf ("bogus pc or npc\n");
98 mexc
= memory_read(sregs
->asi
, sregs
->pc
, &sregs
->inst
,
100 #if 1 /* DELETE ME! for debugging purposes only */
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],
113 sregs
->pc
= sregs
->npc
;
114 sregs
->npc
= sregs
->npc
+ 4;
116 if (ext_irl
) irq
= check_interrupts(sregs
);
119 sregs
->trap
= I_ACC_EXC
;
121 if ((sis_gdb_break
) && (sregs
->inst
== 0x91d02001)) {
123 (*sim_callback
->printf_filtered
) (sim_callback
,
124 "SW BP hit at %x\n", sregs
->pc
);
130 dispatch_instruction(sregs
);
136 sregs
->err_mode
= execute_trap(sregs
);
145 sregs
->tottime
+= time(NULL
) - sregs
->starttime
;
149 error_mode(sregs
->pc
);
154 (*sim_callback
->printf_filtered
) (sim_callback
,
155 "HW BP hit at %x\n", sregs
->pc
);
166 sim_set_callbacks (ptr
)
179 sim_open (kind
, callback
, abfd
, argv
)
181 struct host_callback_struct
*callback
;
190 sim_callback
= callback
;
194 while (stat
< argc
) {
195 if (argv
[stat
][0] == '-') {
196 if (strcmp(argv
[stat
], "-v") == 0) {
199 if (strcmp(argv
[stat
], "-nfp") == 0) {
202 if (strcmp(argv
[stat
], "-ift") == 0) {
205 if (strcmp(argv
[stat
], "-sparclite") == 0) {
208 if (strcmp(argv
[stat
], "-sparclite-board") == 0) {
211 if (strcmp(argv
[stat
], "-dumbio") == 0) {
214 if (strcmp(argv
[stat
], "-wrp") == 0) {
217 if (strcmp(argv
[stat
], "-rom8") == 0) {
220 if (strcmp(argv
[stat
], "-uben") == 0) {
223 if (strcmp(argv
[stat
], "-uart1") == 0) {
224 if ((stat
+ 1) < argc
)
225 strcpy(uart_dev1
, argv
[++stat
]);
227 if (strcmp(argv
[stat
], "-uart2") == 0) {
228 if ((stat
+ 1) < argc
)
229 strcpy(uart_dev2
, argv
[++stat
]);
231 if (strcmp(argv
[stat
], "-nogdb") == 0) {
234 if (strcmp(argv
[stat
], "-freq") == 0) {
235 if ((stat
+ 1) < argc
) {
236 freq
= strtol(argv
[++stat
], (char **)NULL
, 0);
239 if (strncmp(argv
[stat
], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
240 /* Ignore until we start to support this. */
242 (*sim_callback
->printf_filtered
) (sim_callback
,
243 "unknown option %s\n",
247 bfd_load(argv
[stat
]);
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");
255 (*sim_callback
->printf_filtered
) (sim_callback
, "no FPU\n");
257 (*sim_callback
->printf_filtered
) (sim_callback
, "simulating Sparclite\n");
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");
263 (*sim_callback
->printf_filtered
) (sim_callback
, " ERC32 freq %d Mhz\n", freq
);
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
;
276 /* Fudge our descriptor for now. */
281 sim_close(sd
, quitting
)
287 fcntl(0, F_SETFL
, termsave
);
292 sim_load(sd
, prog
, abfd
, from_tty
)
303 sim_create_inferior(sd
, abfd
, argv
, env
)
309 bfd_vma start_address
= 0;
311 start_address
= bfd_get_start_address (abfd
);
316 sregs
.pc
= start_address
& ~3;
317 sregs
.npc
= sregs
.pc
+ 4;
322 sim_store_register(sd
, regno
, value
, length
)
325 unsigned char *value
;
328 /* FIXME: Review the computation of regval. */
330 if (current_target_byte_order
== BIG_ENDIAN
)
331 regval
= (value
[0] << 24) | (value
[1] << 16)
332 | (value
[2] << 8) | value
[3];
334 regval
= (value
[3] << 24) | (value
[2] << 16)
335 | (value
[1] << 8) | value
[0];
336 set_regi(&sregs
, regno
, regval
);
342 sim_fetch_register(sd
, regno
, buf
, length
)
348 get_regi(&sregs
, regno
, buf
);
353 sim_write(sd
, mem
, buf
, length
)
356 const unsigned char *buf
;
359 return (sis_memory_write(mem
, buf
, length
));
363 sim_read(sd
, mem
, buf
, length
)
369 return (sis_memory_read(mem
, buf
, length
));
373 sim_info(sd
, verbose
)
383 sim_stop_reason(sd
, reason
, sigrc
)
385 enum sim_stop
* reason
;
391 *reason
= sim_stopped
;
392 *sigrc
= GDB_SIGNAL_INT
;
397 *reason
= sim_stopped
;
398 *sigrc
= GDB_SIGNAL_TRAP
;
402 *reason
= sim_exited
;
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
427 /* Keep current window handy */
429 cwp
= sregs
.psr
& PSR_CWP
;
431 /* Calculate the invalid window from the wim. */
433 for (invwin
= 0; invwin
<= PSR_CWP
; invwin
++)
434 if ((sregs
.wim
>> invwin
) & 1)
437 /* Start saving with the window after the invalid window. */
439 invwin
= (invwin
- 1) & PSR_CWP
;
441 for (win
= invwin
; ; win
= (win
- 1) & PSR_CWP
)
446 sp
= sregs
.r
[(win
* 16 + 14) & 0x7f];
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
);
454 for (i
= 0; i
< 16; i
++)
455 memory_write (11, sp
+ 4 * i
, &sregs
.r
[(win
* 16 + 16 + i
) & 0x7f], 2,
464 sim_resume(SIM_DESC sd
, int step
, int siggnal
)
466 simstat
= run_sim(&sregs
, UINT64_MAX
, 0);
468 if (sis_gdb_break
) flush_windows ();
475 /* FIXME: unfinished */
476 sim_resume (sd
, 0, 0);
481 sim_do_command(sd
, cmd
)
485 exec_cmd(&sregs
, cmd
);
489 sim_complete_command (SIM_DESC sd
, char *text
, char *word
)
494 #if 0 /* FIXME: These shouldn't exist. */
497 sim_insert_breakpoint(int addr
)
499 if (sregs
.bptnum
< BPT_MAX
) {
500 sregs
.bpts
[sregs
.bptnum
] = addr
& ~0x3;
503 (*sim_callback
->printf_filtered
) (sim_callback
, "inserted HW BP at %x\n", addr
);
510 sim_remove_breakpoint(int addr
)
514 while ((i
< sregs
.bptnum
) && (sregs
.bpts
[i
] != addr
))
516 if (addr
== sregs
.bpts
[i
]) {
517 for (; i
< sregs
.bptnum
- 1; i
++)
518 sregs
.bpts
[i
] = sregs
.bpts
[i
+ 1];
521 (*sim_callback
->printf_filtered
) (sim_callback
, "removed HW BP at %x\n", addr
);