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 "gdb/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
;
65 extern int sparclite_board
;
67 extern char uart_dev1
[], uart_dev2
[];
69 int sis_gdb_break
= 1;
71 host_callback
*sim_callback
;
74 run_sim(sregs
, icount
, dis
)
82 (*sim_callback
->printf_filtered
) (sim_callback
, "resuming at %x\n",
85 sregs
->starttime
= time(NULL
);
87 while (!sregs
->err_mode
& (icount
> 0)) {
93 if (sregs
->psr
& 0x080)
98 #if 0 /* DELETE ME! for debugging purposes only */
100 if (sregs
->pc
== 0 || sregs
->npc
== 0)
101 printf ("bogus pc or npc\n");
103 mexc
= memory_read(sregs
->asi
, sregs
->pc
, &sregs
->inst
,
105 #if 1 /* DELETE ME! for debugging purposes only */
107 printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
108 sregs
->pc
, sregs
->npc
,
109 sregs
->r
[(((sregs
->psr
& 7) << 4) + 14) & 0x7f],
110 sregs
->r
[(((sregs
->psr
& 7) << 4) + 30) & 0x7f],
118 sregs
->pc
= sregs
->npc
;
119 sregs
->npc
= sregs
->npc
+ 4;
121 if (ext_irl
) irq
= check_interrupts(sregs
);
124 sregs
->trap
= I_ACC_EXC
;
126 if ((sis_gdb_break
) && (sregs
->inst
== 0x91d02001)) {
128 (*sim_callback
->printf_filtered
) (sim_callback
,
129 "SW BP hit at %x\n", sregs
->pc
);
135 dispatch_instruction(sregs
);
141 sregs
->err_mode
= execute_trap(sregs
);
150 sregs
->tottime
+= time(NULL
) - sregs
->starttime
;
154 error_mode(sregs
->pc
);
159 (*sim_callback
->printf_filtered
) (sim_callback
,
160 "HW BP hit at %x\n", sregs
->pc
);
171 sim_set_callbacks (ptr
)
184 sim_open (kind
, callback
, abfd
, argv
)
186 struct host_callback_struct
*callback
;
195 sim_callback
= callback
;
199 while (stat
< argc
) {
200 if (argv
[stat
][0] == '-') {
201 if (strcmp(argv
[stat
], "-v") == 0) {
204 if (strcmp(argv
[stat
], "-nfp") == 0) {
207 if (strcmp(argv
[stat
], "-ift") == 0) {
210 if (strcmp(argv
[stat
], "-sparclite") == 0) {
213 if (strcmp(argv
[stat
], "-sparclite-board") == 0) {
216 if (strcmp(argv
[stat
], "-dumbio") == 0) {
219 if (strcmp(argv
[stat
], "-wrp") == 0) {
222 if (strcmp(argv
[stat
], "-rom8") == 0) {
225 if (strcmp(argv
[stat
], "-uben") == 0) {
228 if (strcmp(argv
[stat
], "-uart1") == 0) {
229 if ((stat
+ 1) < argc
)
230 strcpy(uart_dev1
, argv
[++stat
]);
232 if (strcmp(argv
[stat
], "-uart2") == 0) {
233 if ((stat
+ 1) < argc
)
234 strcpy(uart_dev2
, argv
[++stat
]);
236 if (strcmp(argv
[stat
], "-nogdb") == 0) {
239 if (strcmp(argv
[stat
], "-freq") == 0) {
240 if ((stat
+ 1) < argc
) {
241 freq
= VAL(argv
[++stat
]);
244 (*sim_callback
->printf_filtered
) (sim_callback
,
245 "unknown option %s\n",
249 bfd_load(argv
[stat
]);
254 (*sim_callback
->printf_filtered
) (sim_callback
, "\n SIS - SPARC instruction simulator %s\n", sis_version
);
255 (*sim_callback
->printf_filtered
) (sim_callback
, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
257 (*sim_callback
->printf_filtered
) (sim_callback
, "no FPU\n");
259 (*sim_callback
->printf_filtered
) (sim_callback
, "simulating Sparclite\n");
261 (*sim_callback
->printf_filtered
) (sim_callback
, "dumb IO (no input, dumb output)\n");
262 if (sis_gdb_break
== 0)
263 (*sim_callback
->printf_filtered
) (sim_callback
, "disabling GDB trap handling for breakpoints\n");
265 (*sim_callback
->printf_filtered
) (sim_callback
, " ERC32 freq %d Mhz\n", freq
);
268 sregs
.freq
= freq
? freq
: 15;
269 termsave
= fcntl(0, F_GETFL
, 0);
270 INIT_DISASSEMBLE_INFO(dinfo
, stdout
,(fprintf_ftype
)fprintf
);
271 dinfo
.endian
= BFD_ENDIAN_BIG
;
278 /* Fudge our descriptor for now. */
283 sim_close(sd
, quitting
)
289 fcntl(0, F_SETFL
, termsave
);
294 sim_load(sd
, prog
, abfd
, from_tty
)
305 sim_create_inferior(sd
, abfd
, argv
, env
)
311 bfd_vma start_address
= 0;
313 start_address
= bfd_get_start_address (abfd
);
318 sregs
.pc
= start_address
& ~3;
319 sregs
.npc
= sregs
.pc
+ 4;
324 sim_store_register(sd
, regno
, value
, length
)
327 unsigned char *value
;
330 /* FIXME: Review the computation of regval. */
332 if (current_target_byte_order
== BIG_ENDIAN
)
333 regval
= (value
[0] << 24) | (value
[1] << 16)
334 | (value
[2] << 8) | value
[3];
336 regval
= (value
[3] << 24) | (value
[2] << 16)
337 | (value
[1] << 8) | value
[0];
338 set_regi(&sregs
, regno
, regval
);
344 sim_fetch_register(sd
, regno
, buf
, length
)
350 get_regi(&sregs
, regno
, buf
);
355 sim_write(sd
, mem
, buf
, length
)
361 return (sis_memory_write(mem
, buf
, length
));
365 sim_read(sd
, mem
, buf
, length
)
371 return (sis_memory_read(mem
, buf
, length
));
375 sim_info(sd
, verbose
)
385 sim_stop_reason(sd
, reason
, sigrc
)
387 enum sim_stop
* reason
;
393 *reason
= sim_stopped
;
399 *reason
= sim_stopped
;
407 *reason
= sim_exited
;
413 /* Flush all register windows out to the stack. Starting after the invalid
414 window, flush all windows up to, and including the current window. This
415 allows GDB to do backtraces and look at local variables for frames that
416 are still in the register windows. Note that strictly speaking, this
417 behavior is *wrong* for several reasons. First, it doesn't use the window
418 overflow handlers. It therefore assumes standard frame layouts and window
419 handling policies. Second, it changes system state behind the back of the
420 target program. I expect this to mainly pose problems when debugging trap
432 /* Keep current window handy */
434 cwp
= sregs
.psr
& PSR_CWP
;
436 /* Calculate the invalid window from the wim. */
438 for (invwin
= 0; invwin
<= PSR_CWP
; invwin
++)
439 if ((sregs
.wim
>> invwin
) & 1)
442 /* Start saving with the window after the invalid window. */
444 invwin
= (invwin
- 1) & PSR_CWP
;
446 for (win
= invwin
; ; win
= (win
- 1) & PSR_CWP
)
451 sp
= sregs
.r
[(win
* 16 + 14) & 0x7f];
453 if (sis_verbose
> 2) {
454 uint32 fp
= sregs
.r
[(win
* 16 + 30) & 0x7f];
455 printf("flush_window: win %d, sp %x, fp %x\n", win
, sp
, fp
);
459 for (i
= 0; i
< 16; i
++)
460 memory_write (11, sp
+ 4 * i
, &sregs
.r
[(win
* 16 + 16 + i
) & 0x7f], 2,
469 sim_resume(SIM_DESC sd
, int step
, int siggnal
)
471 simstat
= run_sim(&sregs
, -1, 0);
473 if (sis_gdb_break
) flush_windows ();
480 /* FIXME: unfinished */
481 sim_resume (sd
, 0, 0);
486 sim_do_command(sd
, cmd
)
490 exec_cmd(&sregs
, cmd
);
493 #if 0 /* FIXME: These shouldn't exist. */
496 sim_insert_breakpoint(int addr
)
498 if (sregs
.bptnum
< BPT_MAX
) {
499 sregs
.bpts
[sregs
.bptnum
] = addr
& ~0x3;
502 (*sim_callback
->printf_filtered
) (sim_callback
, "inserted HW BP at %x\n", addr
);
509 sim_remove_breakpoint(int addr
)
513 while ((i
< sregs
.bptnum
) && (sregs
.bpts
[i
] != addr
))
515 if (addr
== sregs
.bpts
[i
]) {
516 for (; i
< sregs
.bptnum
- 1; i
++)
517 sregs
.bpts
[i
] = sregs
.bpts
[i
+ 1];
520 (*sim_callback
->printf_filtered
) (sim_callback
, "removed HW BP at %x\n", addr
);