1 /* This file is part of SIS (SPARC instruction simulator)
3 Copyright (C) 1995-2019 Free Software Foundation, Inc.
4 Contributed by Jiri Gaisler, European Space Agency
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include <sys/fcntl.h>
26 #include "libiberty.h"
29 #include "sim-config.h"
31 #include "gdb/remote-sim.h"
32 #include "gdb/signals.h"
36 extern struct disassemble_info dinfo
;
37 extern struct pstate sregs
;
38 extern struct estate ebase
;
46 extern int sis_verbose
;
47 extern char *sis_version
;
48 extern struct estate ebase
;
49 extern struct evcell evbuf
[];
50 extern struct irqcell irqarr
[];
51 extern int irqpend
, ext_irl
;
54 extern int sparclite_board
;
56 extern char uart_dev1
[], uart_dev2
[];
58 int sis_gdb_break
= 1;
60 host_callback
*sim_callback
;
63 run_sim(sregs
, icount
, dis
)
71 (*sim_callback
->printf_filtered
) (sim_callback
, "resuming at %x\n",
74 sregs
->starttime
= get_time();
76 if ((sregs
->pc
!= 0) && (ebase
.simtime
== 0))
78 while (!sregs
->err_mode
& (icount
> 0)) {
84 if (sregs
->psr
& 0x080)
89 #if 0 /* DELETE ME! for debugging purposes only */
91 if (sregs
->pc
== 0 || sregs
->npc
== 0)
92 printf ("bogus pc or npc\n");
94 mexc
= memory_iread (sregs
->pc
, &sregs
->inst
, &sregs
->hold
);
95 #if 0 /* DELETE ME! for debugging purposes only */
97 printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
98 sregs
->pc
, sregs
->npc
,
99 sregs
->r
[(((sregs
->psr
& 7) << 4) + 14) & 0x7f],
100 sregs
->r
[(((sregs
->psr
& 7) << 4) + 30) & 0x7f],
108 sregs
->pc
= sregs
->npc
;
109 sregs
->npc
= sregs
->npc
+ 4;
111 if (ext_irl
) irq
= check_interrupts(sregs
);
114 sregs
->trap
= I_ACC_EXC
;
116 if ((sis_gdb_break
) && (sregs
->inst
== 0x91d02001)) {
118 (*sim_callback
->printf_filtered
) (sim_callback
,
119 "SW BP hit at %x\n", sregs
->pc
);
125 dispatch_instruction(sregs
);
131 sregs
->err_mode
= execute_trap(sregs
);
140 sregs
->tottime
+= get_time() - sregs
->starttime
;
144 error_mode(sregs
->pc
);
149 (*sim_callback
->printf_filtered
) (sim_callback
,
150 "HW BP hit at %x\n", sregs
->pc
);
161 sim_open (kind
, callback
, abfd
, argv
)
163 struct host_callback_struct
*callback
;
172 sim_callback
= callback
;
174 argc
= countargv (argv
);
175 while (stat
< argc
) {
176 if (argv
[stat
][0] == '-') {
177 if (strcmp(argv
[stat
], "-v") == 0) {
180 if (strcmp(argv
[stat
], "-nfp") == 0) {
183 if (strcmp(argv
[stat
], "-ift") == 0) {
186 if (strcmp(argv
[stat
], "-sparclite") == 0) {
189 if (strcmp(argv
[stat
], "-sparclite-board") == 0) {
192 if (strcmp(argv
[stat
], "-dumbio") == 0) {
195 if (strcmp(argv
[stat
], "-wrp") == 0) {
198 if (strcmp(argv
[stat
], "-rom8") == 0) {
201 if (strcmp(argv
[stat
], "-uben") == 0) {
204 if (strcmp(argv
[stat
], "-uart1") == 0) {
205 if ((stat
+ 1) < argc
)
206 strcpy(uart_dev1
, argv
[++stat
]);
208 if (strcmp(argv
[stat
], "-uart2") == 0) {
209 if ((stat
+ 1) < argc
)
210 strcpy(uart_dev2
, argv
[++stat
]);
212 if (strcmp(argv
[stat
], "-nogdb") == 0) {
215 if (strcmp(argv
[stat
], "-freq") == 0) {
216 if ((stat
+ 1) < argc
) {
217 freq
= strtol(argv
[++stat
], (char **)NULL
, 0);
220 if (strncmp(argv
[stat
], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
221 /* Ignore until we start to support this. */
223 (*sim_callback
->printf_filtered
) (sim_callback
,
224 "unknown option %s\n",
228 bfd_load(argv
[stat
]);
233 (*sim_callback
->printf_filtered
) (sim_callback
, "\n SIS - SPARC instruction simulator %s\n", sis_version
);
234 (*sim_callback
->printf_filtered
) (sim_callback
, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
236 (*sim_callback
->printf_filtered
) (sim_callback
, "no FPU\n");
238 (*sim_callback
->printf_filtered
) (sim_callback
, "simulating Sparclite\n");
240 (*sim_callback
->printf_filtered
) (sim_callback
, "dumb IO (no input, dumb output)\n");
241 if (sis_gdb_break
== 0)
242 (*sim_callback
->printf_filtered
) (sim_callback
, "disabling GDB trap handling for breakpoints\n");
244 (*sim_callback
->printf_filtered
) (sim_callback
, " ERC32 freq %d Mhz\n", freq
);
247 sregs
.freq
= freq
? freq
: 15;
248 termsave
= fcntl(0, F_GETFL
, 0);
249 INIT_DISASSEMBLE_INFO(dinfo
, stdout
,(fprintf_ftype
)fprintf
);
250 #ifdef HOST_LITTLE_ENDIAN
251 dinfo
.endian
= BFD_ENDIAN_LITTLE
;
253 dinfo
.endian
= BFD_ENDIAN_BIG
;
261 /* Fudge our descriptor for now. */
266 sim_close(sd
, quitting
)
272 fcntl(0, F_SETFL
, termsave
);
277 sim_load(sd
, prog
, abfd
, from_tty
)
288 sim_create_inferior(sd
, abfd
, argv
, env
)
294 bfd_vma start_address
= 0;
296 start_address
= bfd_get_start_address (abfd
);
301 sregs
.pc
= start_address
& ~3;
302 sregs
.npc
= sregs
.pc
+ 4;
307 sim_store_register(sd
, regno
, value
, length
)
310 unsigned char *value
;
315 regval
= (value
[0] << 24) | (value
[1] << 16)
316 | (value
[2] << 8) | value
[3];
317 set_regi(&sregs
, regno
, regval
);
323 sim_fetch_register(sd
, regno
, buf
, length
)
329 get_regi(&sregs
, regno
, buf
);
334 sim_write (SIM_DESC sd
, SIM_ADDR mem
, const unsigned char *buf
, int length
)
338 for (i
= 0; i
< length
; i
++) {
339 sis_memory_write ((mem
+ i
) ^ EBT
, &buf
[i
], 1);
345 sim_read (SIM_DESC sd
, SIM_ADDR mem
, unsigned char *buf
, int length
)
349 for (i
= 0; i
< length
; i
++) {
350 sis_memory_read ((mem
+ i
) ^ EBT
, &buf
[i
], 1);
356 sim_info(sd
, verbose
)
366 sim_stop_reason(sd
, reason
, sigrc
)
368 enum sim_stop
* reason
;
374 *reason
= sim_stopped
;
375 *sigrc
= GDB_SIGNAL_INT
;
380 *reason
= sim_stopped
;
381 *sigrc
= GDB_SIGNAL_TRAP
;
385 *reason
= sim_exited
;
391 /* Flush all register windows out to the stack. Starting after the invalid
392 window, flush all windows up to, and including the current window. This
393 allows GDB to do backtraces and look at local variables for frames that
394 are still in the register windows. Note that strictly speaking, this
395 behavior is *wrong* for several reasons. First, it doesn't use the window
396 overflow handlers. It therefore assumes standard frame layouts and window
397 handling policies. Second, it changes system state behind the back of the
398 target program. I expect this to mainly pose problems when debugging trap
410 /* Keep current window handy */
412 cwp
= sregs
.psr
& PSR_CWP
;
414 /* Calculate the invalid window from the wim. */
416 for (invwin
= 0; invwin
<= PSR_CWP
; invwin
++)
417 if ((sregs
.wim
>> invwin
) & 1)
420 /* Start saving with the window after the invalid window. */
422 invwin
= (invwin
- 1) & PSR_CWP
;
424 for (win
= invwin
; ; win
= (win
- 1) & PSR_CWP
)
429 sp
= sregs
.r
[(win
* 16 + 14) & 0x7f];
431 if (sis_verbose
> 2) {
432 uint32 fp
= sregs
.r
[(win
* 16 + 30) & 0x7f];
433 printf("flush_window: win %d, sp %x, fp %x\n", win
, sp
, fp
);
437 for (i
= 0; i
< 16; i
++)
438 memory_write (11, sp
+ 4 * i
, &sregs
.r
[(win
* 16 + 16 + i
) & 0x7f], 2,
447 sim_resume(SIM_DESC sd
, int step
, int siggnal
)
449 simstat
= run_sim(&sregs
, UINT64_MAX
, 0);
451 if (sis_gdb_break
) flush_windows ();
455 sim_do_command(sd
, cmd
)
459 exec_cmd(&sregs
, cmd
);
463 sim_complete_command (SIM_DESC sd
, const char *text
, const char *word
)
468 #if 0 /* FIXME: These shouldn't exist. */
471 sim_insert_breakpoint(int addr
)
473 if (sregs
.bptnum
< BPT_MAX
) {
474 sregs
.bpts
[sregs
.bptnum
] = addr
& ~0x3;
477 (*sim_callback
->printf_filtered
) (sim_callback
, "inserted HW BP at %x\n", addr
);
484 sim_remove_breakpoint(int addr
)
488 while ((i
< sregs
.bptnum
) && (sregs
.bpts
[i
] != addr
))
490 if (addr
== sregs
.bpts
[i
]) {
491 for (; i
< sregs
.bptnum
- 1; i
++)
492 sregs
.bpts
[i
] = sregs
.bpts
[i
+ 1];
495 (*sim_callback
->printf_filtered
) (sim_callback
, "removed HW BP at %x\n", addr
);