gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / sim / erc32 / interf.c
CommitLineData
296730a5
MF
1/* This file is part of SIS (SPARC instruction simulator)
2
b811d2c2 3 Copyright (C) 1995-2020 Free Software Foundation, Inc.
296730a5 4 Contributed by Jiri Gaisler, European Space Agency
17d88f73
JB
5
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.
10
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.
15
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/>. */
c906108c 18
5272643f 19#include "config.h"
c906108c
SS
20#include <signal.h>
21#include <string.h>
22#include <stdio.h>
23#include <stdlib.h>
c906108c
SS
24#include <sys/fcntl.h>
25#include "sis.h"
2b3cc94f 26#include "libiberty.h"
c906108c
SS
27#include "bfd.h"
28#include <dis-asm.h>
29#include "sim-config.h"
30
3c25f8c7 31#include "gdb/remote-sim.h"
aba6488e 32#include "gdb/signals.h"
c906108c 33
c906108c
SS
34#define PSR_CWP 0x7
35
c906108c
SS
36extern struct disassemble_info dinfo;
37extern struct pstate sregs;
38extern struct estate ebase;
39
c906108c
SS
40extern int ctrl_c;
41extern int nfp;
42extern int ift;
43extern int rom8;
44extern int wrp;
45extern int uben;
46extern int sis_verbose;
47extern char *sis_version;
48extern struct estate ebase;
49extern struct evcell evbuf[];
50extern struct irqcell irqarr[];
51extern int irqpend, ext_irl;
52extern int sparclite;
53extern int dumbio;
54extern int sparclite_board;
55extern int termsave;
56extern char uart_dev1[], uart_dev2[];
57
58int sis_gdb_break = 1;
59
60host_callback *sim_callback;
61
62int
63run_sim(sregs, icount, dis)
64 struct pstate *sregs;
94110024 65 uint64 icount;
c906108c
SS
66 int dis;
67{
68 int mexc, irq;
69
70 if (sis_verbose)
71 (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
72 sregs->pc);
73 init_stdio();
96d67095 74 sregs->starttime = get_time();
c906108c 75 irq = 0;
20a0ffe3
JG
76 if ((sregs->pc != 0) && (ebase.simtime == 0))
77 boot_init();
c906108c
SS
78 while (!sregs->err_mode & (icount > 0)) {
79
80 sregs->fhold = 0;
81 sregs->hold = 0;
82 sregs->icnt = 1;
83
84 if (sregs->psr & 0x080)
85 sregs->asi = 8;
86 else
87 sregs->asi = 9;
88
89#if 0 /* DELETE ME! for debugging purposes only */
90 if (sis_verbose > 1)
91 if (sregs->pc == 0 || sregs->npc == 0)
92 printf ("bogus pc or npc\n");
93#endif
102b920e
JG
94 mexc = memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
95#if 0 /* DELETE ME! for debugging purposes only */
c906108c
SS
96 if (sis_verbose > 2)
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],
101 sregs->wim,
102 sregs->psr & 7,
103 sregs->inst);
104#endif
105 if (sregs->annul) {
106 sregs->annul = 0;
107 sregs->icnt = 1;
108 sregs->pc = sregs->npc;
109 sregs->npc = sregs->npc + 4;
110 } else {
111 if (ext_irl) irq = check_interrupts(sregs);
112 if (!irq) {
113 if (mexc) {
114 sregs->trap = I_ACC_EXC;
115 } else {
116 if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
117 if (sis_verbose)
118 (*sim_callback->printf_filtered) (sim_callback,
119 "SW BP hit at %x\n", sregs->pc);
120 sim_halt();
121 restore_stdio();
122 clearerr(stdin);
5831e29b 123 return BPT_HIT;
c906108c
SS
124 } else
125 dispatch_instruction(sregs);
126 }
127 icount--;
128 }
129 if (sregs->trap) {
130 irq = 0;
131 sregs->err_mode = execute_trap(sregs);
132 }
133 }
134 advance_time(sregs);
135 if (ctrl_c) {
136 icount = 0;
137 }
138 }
139 sim_halt();
96d67095 140 sregs->tottime += get_time() - sregs->starttime;
c906108c
SS
141 restore_stdio();
142 clearerr(stdin);
143 if (sregs->err_mode)
144 error_mode(sregs->pc);
145 if (sregs->err_mode)
5831e29b 146 return ERROR;
c906108c
SS
147 if (sregs->bphit) {
148 if (sis_verbose)
149 (*sim_callback->printf_filtered) (sim_callback,
150 "HW BP hit at %x\n", sregs->pc);
5831e29b 151 return BPT_HIT;
c906108c
SS
152 }
153 if (ctrl_c) {
154 ctrl_c = 0;
5831e29b 155 return CTRL_C;
c906108c 156 }
5831e29b 157 return TIME_OUT;
c906108c
SS
158}
159
c906108c
SS
160SIM_DESC
161sim_open (kind, callback, abfd, argv)
162 SIM_OPEN_KIND kind;
163 struct host_callback_struct *callback;
6b4a8935 164 struct bfd *abfd;
2e3d4f4d 165 char * const *argv;
c906108c
SS
166{
167
168 int argc = 0;
169 int stat = 1;
170 int freq = 0;
171
172 sim_callback = callback;
173
34fed699 174 argc = countargv (argv);
c906108c
SS
175 while (stat < argc) {
176 if (argv[stat][0] == '-') {
177 if (strcmp(argv[stat], "-v") == 0) {
178 sis_verbose++;
179 } else
180 if (strcmp(argv[stat], "-nfp") == 0) {
181 nfp = 1;
182 } else
183 if (strcmp(argv[stat], "-ift") == 0) {
184 ift = 1;
185 } else
186 if (strcmp(argv[stat], "-sparclite") == 0) {
187 sparclite = 1;
188 } else
189 if (strcmp(argv[stat], "-sparclite-board") == 0) {
190 sparclite_board = 1;
191 } else
192 if (strcmp(argv[stat], "-dumbio") == 0) {
193 dumbio = 1;
194 } else
195 if (strcmp(argv[stat], "-wrp") == 0) {
196 wrp = 1;
197 } else
198 if (strcmp(argv[stat], "-rom8") == 0) {
199 rom8 = 1;
200 } else
201 if (strcmp(argv[stat], "-uben") == 0) {
202 uben = 1;
203 } else
204 if (strcmp(argv[stat], "-uart1") == 0) {
205 if ((stat + 1) < argc)
206 strcpy(uart_dev1, argv[++stat]);
207 } else
208 if (strcmp(argv[stat], "-uart2") == 0) {
209 if ((stat + 1) < argc)
210 strcpy(uart_dev2, argv[++stat]);
211 } else
212 if (strcmp(argv[stat], "-nogdb") == 0) {
213 sis_gdb_break = 0;
214 } else
215 if (strcmp(argv[stat], "-freq") == 0) {
216 if ((stat + 1) < argc) {
94110024 217 freq = strtol(argv[++stat], (char **)NULL, 0);
c906108c 218 }
ce6f492f
MF
219 } else
220 if (strncmp(argv[stat], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
221 /* Ignore until we start to support this. */
c906108c
SS
222 } else {
223 (*sim_callback->printf_filtered) (sim_callback,
224 "unknown option %s\n",
225 argv[stat]);
226 }
227 } else
228 bfd_load(argv[stat]);
229 stat++;
230 }
231
232 if (sis_verbose) {
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");
235 if (nfp)
236 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
237 if (sparclite)
238 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
239 if (dumbio)
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");
243 if (freq)
244 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
245 }
246
247 sregs.freq = freq ? freq : 15;
248 termsave = fcntl(0, F_GETFL, 0);
249 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
d3e9b40a
JG
250#ifdef HOST_LITTLE_ENDIAN
251 dinfo.endian = BFD_ENDIAN_LITTLE;
252#else
c906108c 253 dinfo.endian = BFD_ENDIAN_BIG;
d3e9b40a 254#endif
c906108c
SS
255 reset_all();
256 ebase.simtime = 0;
257 init_sim();
258 init_bpt(&sregs);
259 reset_stat(&sregs);
260
261 /* Fudge our descriptor for now. */
262 return (SIM_DESC) 1;
263}
264
265void
266sim_close(sd, quitting)
267 SIM_DESC sd;
268 int quitting;
269{
270
271 exit_sim();
272 fcntl(0, F_SETFL, termsave);
273
274};
275
276SIM_RC
277sim_load(sd, prog, abfd, from_tty)
278 SIM_DESC sd;
b2b255bd 279 const char *prog;
c906108c
SS
280 bfd *abfd;
281 int from_tty;
282{
283 bfd_load (prog);
284 return SIM_RC_OK;
285}
286
287SIM_RC
288sim_create_inferior(sd, abfd, argv, env)
289 SIM_DESC sd;
6b4a8935 290 struct bfd *abfd;
2e3d4f4d
MF
291 char * const *argv;
292 char * const *env;
c906108c
SS
293{
294 bfd_vma start_address = 0;
295 if (abfd != NULL)
296 start_address = bfd_get_start_address (abfd);
297
298 ebase.simtime = 0;
299 reset_all();
300 reset_stat(&sregs);
301 sregs.pc = start_address & ~3;
302 sregs.npc = sregs.pc + 4;
303 return SIM_RC_OK;
304}
305
306int
307sim_store_register(sd, regno, value, length)
308 SIM_DESC sd;
309 int regno;
310 unsigned char *value;
311 int length;
312{
c906108c 313 int regval;
d3e9b40a
JG
314
315 regval = (value[0] << 24) | (value[1] << 16)
c906108c 316 | (value[2] << 8) | value[3];
c906108c 317 set_regi(&sregs, regno, regval);
dae477fe 318 return length;
c906108c
SS
319}
320
321
322int
323sim_fetch_register(sd, regno, buf, length)
324 SIM_DESC sd;
325 int regno;
326 unsigned char *buf;
327 int length;
328{
329 get_regi(&sregs, regno, buf);
330 return -1;
331}
332
333int
d3e9b40a 334sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
c906108c 335{
d3e9b40a
JG
336 int i, len;
337
338 for (i = 0; i < length; i++) {
339 sis_memory_write ((mem + i) ^ EBT, &buf[i], 1);
340 }
341 return length;
c906108c
SS
342}
343
344int
d3e9b40a 345sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
c906108c 346{
d3e9b40a
JG
347 int i, len;
348
349 for (i = 0; i < length; i++) {
350 sis_memory_read ((mem + i) ^ EBT, &buf[i], 1);
351 }
352 return length;
c906108c
SS
353}
354
355void
356sim_info(sd, verbose)
357 SIM_DESC sd;
358 int verbose;
359{
360 show_stat(&sregs);
361}
362
363int simstat = OK;
364
365void
366sim_stop_reason(sd, reason, sigrc)
367 SIM_DESC sd;
368 enum sim_stop * reason;
369 int *sigrc;
370{
371
372 switch (simstat) {
373 case CTRL_C:
374 *reason = sim_stopped;
a493e3e2 375 *sigrc = GDB_SIGNAL_INT;
c906108c
SS
376 break;
377 case OK:
378 case TIME_OUT:
379 case BPT_HIT:
380 *reason = sim_stopped;
a493e3e2 381 *sigrc = GDB_SIGNAL_TRAP;
c906108c
SS
382 break;
383 case ERROR:
384 *sigrc = 0;
385 *reason = sim_exited;
386 }
387 ctrl_c = 0;
388 simstat = OK;
389}
390
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
399 handlers.
400*/
401
402static void
403flush_windows ()
404{
405 int invwin;
406 int cwp;
407 int win;
408 int ws;
409
410 /* Keep current window handy */
411
412 cwp = sregs.psr & PSR_CWP;
413
414 /* Calculate the invalid window from the wim. */
415
416 for (invwin = 0; invwin <= PSR_CWP; invwin++)
417 if ((sregs.wim >> invwin) & 1)
418 break;
419
420 /* Start saving with the window after the invalid window. */
421
422 invwin = (invwin - 1) & PSR_CWP;
423
424 for (win = invwin; ; win = (win - 1) & PSR_CWP)
425 {
426 uint32 sp;
427 int i;
428
429 sp = sregs.r[(win * 16 + 14) & 0x7f];
430#if 1
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);
434 }
435#endif
436
437 for (i = 0; i < 16; i++)
438 memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
439 &ws);
440
441 if (win == cwp)
442 break;
443 }
444}
445
446void
447sim_resume(SIM_DESC sd, int step, int siggnal)
448{
94110024 449 simstat = run_sim(&sregs, UINT64_MAX, 0);
c906108c
SS
450
451 if (sis_gdb_break) flush_windows ();
452}
453
c906108c
SS
454void
455sim_do_command(sd, cmd)
456 SIM_DESC sd;
60d847df 457 const char *cmd;
c906108c
SS
458{
459 exec_cmd(&sregs, cmd);
460}
461
248d2a8f 462char **
3cb2ab1a 463sim_complete_command (SIM_DESC sd, const char *text, const char *word)
248d2a8f
JB
464{
465 return NULL;
466}
467
c906108c
SS
468#if 0 /* FIXME: These shouldn't exist. */
469
470int
471sim_insert_breakpoint(int addr)
472{
473 if (sregs.bptnum < BPT_MAX) {
474 sregs.bpts[sregs.bptnum] = addr & ~0x3;
475 sregs.bptnum++;
476 if (sis_verbose)
477 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
478 return 0;
479 } else
480 return 1;
481}
482
483int
484sim_remove_breakpoint(int addr)
485{
486 int i = 0;
487
488 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
489 i++;
490 if (addr == sregs.bpts[i]) {
491 for (; i < sregs.bptnum - 1; i++)
492 sregs.bpts[i] = sregs.bpts[i + 1];
493 sregs.bptnum -= 1;
494 if (sis_verbose)
495 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
496 return 0;
497 }
498 return 1;
499}
500
501#endif
This page took 1.014651 seconds and 4 git commands to generate.