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>
32 #include "sim-config.h"
34 #include "remote-sim.h"
42 #define VAL(x) strtol(x,(char **)NULL,0)
44 extern char **buildargv(char *input
);
46 extern struct disassemble_info dinfo
;
47 extern struct pstate sregs
;
48 extern struct estate ebase
;
50 extern int current_target_byte_order
;
57 extern int sis_verbose
;
58 extern char *sis_version
;
59 extern struct estate ebase
;
60 extern struct evcell evbuf
[];
61 extern struct irqcell irqarr
[];
62 extern int irqpend
, ext_irl
;
64 extern int sparclite_board
;
66 extern char uart_dev1
[], uart_dev2
[];
68 int sis_gdb_break
= 1;
70 host_callback
*sim_callback
;
73 run_sim(sregs
, icount
, dis
)
81 (*sim_callback
->printf_filtered
) (sim_callback
, "resuming at %x\n",
84 sregs
->starttime
= time(NULL
);
85 while (!sregs
->err_mode
& (icount
> 0)) {
91 check_interrupts(sregs
);
93 sregs
->err_mode
= execute_trap(sregs
);
95 if (sregs
->psr
& 0x080)
100 #if 0 /* DELETE ME! for debugging purposes only */
101 printf("pc = %08x, npc = %08x\n", sregs
->pc
, sregs
->npc
);
102 if (sregs
->pc
== 0 || sregs
->npc
== 0)
103 printf ("bogus pc or npc\n");
105 mexc
= memory_read(sregs
->asi
, sregs
->pc
, &sregs
->inst
,
110 sregs
->pc
= sregs
->npc
;
111 sregs
->npc
= sregs
->npc
+ 4;
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
);
130 sregs
->err_mode
= execute_trap(sregs
);
139 sregs
->tottime
+= time(NULL
) - sregs
->starttime
;
143 error_mode(sregs
->pc
);
148 (*sim_callback
->printf_filtered
) (sim_callback
,
149 "HW BP hit at %x\n", sregs
->pc
);
160 sim_set_callbacks (ptr
)
173 sim_open (kind
, callback
, abfd
, argv
)
175 struct host_callback_struct
*callback
;
184 sim_callback
= callback
;
188 while (stat
< argc
) {
189 if (argv
[stat
][0] == '-') {
190 if (strcmp(argv
[stat
], "-v") == 0) {
193 if (strcmp(argv
[stat
], "-nfp") == 0) {
196 if (strcmp(argv
[stat
], "-ift") == 0) {
199 if (strcmp(argv
[stat
], "-sparclite") == 0) {
202 if (strcmp(argv
[stat
], "-sparclite-board") == 0) {
205 if (strcmp(argv
[stat
], "-wrp") == 0) {
208 if (strcmp(argv
[stat
], "-rom8") == 0) {
211 if (strcmp(argv
[stat
], "-uben") == 0) {
214 if (strcmp(argv
[stat
], "-uart1") == 0) {
215 if ((stat
+ 1) < argc
)
216 strcpy(uart_dev1
, argv
[++stat
]);
218 if (strcmp(argv
[stat
], "-uart2") == 0) {
219 if ((stat
+ 1) < argc
)
220 strcpy(uart_dev2
, argv
[++stat
]);
222 if (strcmp(argv
[stat
], "-nogdb") == 0) {
225 if (strcmp(argv
[stat
], "-freq") == 0) {
226 if ((stat
+ 1) < argc
) {
227 freq
= VAL(argv
[++stat
]);
230 (*sim_callback
->printf_filtered
) (sim_callback
,
231 "unknown option %s\n",
235 bfd_load(argv
[stat
]);
240 (*sim_callback
->printf_filtered
) (sim_callback
, "\n SIS - SPARC instruction simulator %s\n", sis_version
);
241 (*sim_callback
->printf_filtered
) (sim_callback
, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
243 (*sim_callback
->printf_filtered
) (sim_callback
, "no FPU\n");
245 (*sim_callback
->printf_filtered
) (sim_callback
, "simulating Sparclite\n");
246 if (sis_gdb_break
== 0)
247 (*sim_callback
->printf_filtered
) (sim_callback
, "disabling GDB trap handling for breakpoints\n");
249 (*sim_callback
->printf_filtered
) (sim_callback
, " ERC32 freq %d Mhz\n", freq
);
252 sregs
.freq
= freq
? freq
: 15;
253 termsave
= fcntl(0, F_GETFL
, 0);
254 INIT_DISASSEMBLE_INFO(dinfo
, stdout
,(fprintf_ftype
)fprintf
);
255 dinfo
.endian
= BFD_ENDIAN_BIG
;
262 /* Fudge our descriptor for now. */
267 sim_close(sd
, quitting
)
273 fcntl(0, F_SETFL
, termsave
);
278 sim_load(sd
, prog
, abfd
, from_tty
)
289 sim_create_inferior(sd
, abfd
, argv
, env
)
295 bfd_vma start_address
= 0;
297 start_address
= bfd_get_start_address (abfd
);
302 sregs
.pc
= start_address
& ~3;
303 sregs
.npc
= sregs
.pc
+ 4;
308 sim_store_register(sd
, regno
, value
, length
)
311 unsigned char *value
;
314 /* FIXME: Review the computation of regval. */
315 int regval
= (value
[0] << 24) | (value
[1] << 16) | (value
[2] << 8) | value
[3];
316 set_regi(&sregs
, regno
, regval
);
322 sim_fetch_register(sd
, regno
, buf
, length
)
328 get_regi(&sregs
, regno
, buf
);
333 sim_write(sd
, mem
, buf
, length
)
339 return (sis_memory_write(mem
, buf
, length
));
343 sim_read(sd
, mem
, buf
, length
)
349 return (sis_memory_read(mem
, buf
, length
));
353 sim_info(sd
, verbose
)
363 sim_stop_reason(sd
, reason
, sigrc
)
365 enum sim_stop
* reason
;
371 *reason
= sim_stopped
;
377 *reason
= sim_stopped
;
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 for (i
= 0; i
< 16; i
++)
432 memory_write (11, sp
+ 4 * i
, &sregs
.r
[(win
* 16 + 16 + i
) & 0x7f], 2,
441 sim_resume(SIM_DESC sd
, int step
, int siggnal
)
443 simstat
= run_sim(&sregs
, -1, 0);
445 if (sis_gdb_break
) flush_windows ();
452 /* FIXME: unfinished */
453 sim_resume (sd
, 0, 0);
458 sim_do_command(sd
, cmd
)
462 exec_cmd(&sregs
, cmd
);
465 #if 0 /* FIXME: These shouldn't exist. */
468 sim_insert_breakpoint(int addr
)
470 if (sregs
.bptnum
< BPT_MAX
) {
471 sregs
.bpts
[sregs
.bptnum
] = addr
& ~0x3;
474 (*sim_callback
->printf_filtered
) (sim_callback
, "inserted HW BP at %x\n", addr
);
481 sim_remove_breakpoint(int addr
)
485 while ((i
< sregs
.bptnum
) && (sregs
.bpts
[i
] != addr
))
487 if (addr
== sregs
.bpts
[i
]) {
488 for (; i
< sregs
.bptnum
- 1; i
++)
489 sregs
.bpts
[i
] = sregs
.bpts
[i
+ 1];
492 (*sim_callback
->printf_filtered
) (sim_callback
, "removed HW BP at %x\n", addr
);