]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/erc32/interf.c
GDB copyright headers update after running GDB's copyright.py script.
[thirdparty/binutils-gdb.git] / sim / erc32 / interf.c
CommitLineData
296730a5
MF
1/* This file is part of SIS (SPARC instruction simulator)
2
618f726f 3 Copyright (C) 1995-2016 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;
c906108c
SS
165 char **argv;
166{
167
168 int argc = 0;
169 int stat = 1;
170 int freq = 0;
171
172 sim_callback = callback;
173
174 while (argv[argc])
175 argc++;
176 while (stat < argc) {
177 if (argv[stat][0] == '-') {
178 if (strcmp(argv[stat], "-v") == 0) {
179 sis_verbose++;
180 } else
181 if (strcmp(argv[stat], "-nfp") == 0) {
182 nfp = 1;
183 } else
184 if (strcmp(argv[stat], "-ift") == 0) {
185 ift = 1;
186 } else
187 if (strcmp(argv[stat], "-sparclite") == 0) {
188 sparclite = 1;
189 } else
190 if (strcmp(argv[stat], "-sparclite-board") == 0) {
191 sparclite_board = 1;
192 } else
193 if (strcmp(argv[stat], "-dumbio") == 0) {
194 dumbio = 1;
195 } else
196 if (strcmp(argv[stat], "-wrp") == 0) {
197 wrp = 1;
198 } else
199 if (strcmp(argv[stat], "-rom8") == 0) {
200 rom8 = 1;
201 } else
202 if (strcmp(argv[stat], "-uben") == 0) {
203 uben = 1;
204 } else
205 if (strcmp(argv[stat], "-uart1") == 0) {
206 if ((stat + 1) < argc)
207 strcpy(uart_dev1, argv[++stat]);
208 } else
209 if (strcmp(argv[stat], "-uart2") == 0) {
210 if ((stat + 1) < argc)
211 strcpy(uart_dev2, argv[++stat]);
212 } else
213 if (strcmp(argv[stat], "-nogdb") == 0) {
214 sis_gdb_break = 0;
215 } else
216 if (strcmp(argv[stat], "-freq") == 0) {
217 if ((stat + 1) < argc) {
94110024 218 freq = strtol(argv[++stat], (char **)NULL, 0);
c906108c 219 }
ce6f492f
MF
220 } else
221 if (strncmp(argv[stat], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
222 /* Ignore until we start to support this. */
c906108c
SS
223 } else {
224 (*sim_callback->printf_filtered) (sim_callback,
225 "unknown option %s\n",
226 argv[stat]);
227 }
228 } else
229 bfd_load(argv[stat]);
230 stat++;
231 }
232
233 if (sis_verbose) {
234 (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
235 (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
236 if (nfp)
237 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
238 if (sparclite)
239 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
240 if (dumbio)
241 (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
242 if (sis_gdb_break == 0)
243 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
244 if (freq)
245 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
246 }
247
248 sregs.freq = freq ? freq : 15;
249 termsave = fcntl(0, F_GETFL, 0);
250 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
d3e9b40a
JG
251#ifdef HOST_LITTLE_ENDIAN
252 dinfo.endian = BFD_ENDIAN_LITTLE;
253#else
c906108c 254 dinfo.endian = BFD_ENDIAN_BIG;
d3e9b40a 255#endif
c906108c
SS
256 reset_all();
257 ebase.simtime = 0;
258 init_sim();
259 init_bpt(&sregs);
260 reset_stat(&sregs);
261
262 /* Fudge our descriptor for now. */
263 return (SIM_DESC) 1;
264}
265
266void
267sim_close(sd, quitting)
268 SIM_DESC sd;
269 int quitting;
270{
271
272 exit_sim();
273 fcntl(0, F_SETFL, termsave);
274
275};
276
277SIM_RC
278sim_load(sd, prog, abfd, from_tty)
279 SIM_DESC sd;
b2b255bd 280 const char *prog;
c906108c
SS
281 bfd *abfd;
282 int from_tty;
283{
284 bfd_load (prog);
285 return SIM_RC_OK;
286}
287
288SIM_RC
289sim_create_inferior(sd, abfd, argv, env)
290 SIM_DESC sd;
6b4a8935 291 struct bfd *abfd;
c906108c
SS
292 char **argv;
293 char **env;
294{
295 bfd_vma start_address = 0;
296 if (abfd != NULL)
297 start_address = bfd_get_start_address (abfd);
298
299 ebase.simtime = 0;
300 reset_all();
301 reset_stat(&sregs);
302 sregs.pc = start_address & ~3;
303 sregs.npc = sregs.pc + 4;
304 return SIM_RC_OK;
305}
306
307int
308sim_store_register(sd, regno, value, length)
309 SIM_DESC sd;
310 int regno;
311 unsigned char *value;
312 int length;
313{
c906108c 314 int regval;
d3e9b40a
JG
315
316 regval = (value[0] << 24) | (value[1] << 16)
c906108c 317 | (value[2] << 8) | value[3];
c906108c 318 set_regi(&sregs, regno, regval);
dae477fe 319 return length;
c906108c
SS
320}
321
322
323int
324sim_fetch_register(sd, regno, buf, length)
325 SIM_DESC sd;
326 int regno;
327 unsigned char *buf;
328 int length;
329{
330 get_regi(&sregs, regno, buf);
331 return -1;
332}
333
334int
d3e9b40a 335sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
c906108c 336{
d3e9b40a
JG
337 int i, len;
338
339 for (i = 0; i < length; i++) {
340 sis_memory_write ((mem + i) ^ EBT, &buf[i], 1);
341 }
342 return length;
c906108c
SS
343}
344
345int
d3e9b40a 346sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
c906108c 347{
d3e9b40a
JG
348 int i, len;
349
350 for (i = 0; i < length; i++) {
351 sis_memory_read ((mem + i) ^ EBT, &buf[i], 1);
352 }
353 return length;
c906108c
SS
354}
355
356void
357sim_info(sd, verbose)
358 SIM_DESC sd;
359 int verbose;
360{
361 show_stat(&sregs);
362}
363
364int simstat = OK;
365
366void
367sim_stop_reason(sd, reason, sigrc)
368 SIM_DESC sd;
369 enum sim_stop * reason;
370 int *sigrc;
371{
372
373 switch (simstat) {
374 case CTRL_C:
375 *reason = sim_stopped;
a493e3e2 376 *sigrc = GDB_SIGNAL_INT;
c906108c
SS
377 break;
378 case OK:
379 case TIME_OUT:
380 case BPT_HIT:
381 *reason = sim_stopped;
a493e3e2 382 *sigrc = GDB_SIGNAL_TRAP;
c906108c
SS
383 break;
384 case ERROR:
385 *sigrc = 0;
386 *reason = sim_exited;
387 }
388 ctrl_c = 0;
389 simstat = OK;
390}
391
392/* Flush all register windows out to the stack. Starting after the invalid
393 window, flush all windows up to, and including the current window. This
394 allows GDB to do backtraces and look at local variables for frames that
395 are still in the register windows. Note that strictly speaking, this
396 behavior is *wrong* for several reasons. First, it doesn't use the window
397 overflow handlers. It therefore assumes standard frame layouts and window
398 handling policies. Second, it changes system state behind the back of the
399 target program. I expect this to mainly pose problems when debugging trap
400 handlers.
401*/
402
403static void
404flush_windows ()
405{
406 int invwin;
407 int cwp;
408 int win;
409 int ws;
410
411 /* Keep current window handy */
412
413 cwp = sregs.psr & PSR_CWP;
414
415 /* Calculate the invalid window from the wim. */
416
417 for (invwin = 0; invwin <= PSR_CWP; invwin++)
418 if ((sregs.wim >> invwin) & 1)
419 break;
420
421 /* Start saving with the window after the invalid window. */
422
423 invwin = (invwin - 1) & PSR_CWP;
424
425 for (win = invwin; ; win = (win - 1) & PSR_CWP)
426 {
427 uint32 sp;
428 int i;
429
430 sp = sregs.r[(win * 16 + 14) & 0x7f];
431#if 1
432 if (sis_verbose > 2) {
433 uint32 fp = sregs.r[(win * 16 + 30) & 0x7f];
434 printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
435 }
436#endif
437
438 for (i = 0; i < 16; i++)
439 memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
440 &ws);
441
442 if (win == cwp)
443 break;
444 }
445}
446
447void
448sim_resume(SIM_DESC sd, int step, int siggnal)
449{
94110024 450 simstat = run_sim(&sregs, UINT64_MAX, 0);
c906108c
SS
451
452 if (sis_gdb_break) flush_windows ();
453}
454
c906108c
SS
455void
456sim_do_command(sd, cmd)
457 SIM_DESC sd;
60d847df 458 const char *cmd;
c906108c
SS
459{
460 exec_cmd(&sregs, cmd);
461}
462
248d2a8f 463char **
3cb2ab1a 464sim_complete_command (SIM_DESC sd, const char *text, const char *word)
248d2a8f
JB
465{
466 return NULL;
467}
468
c906108c
SS
469#if 0 /* FIXME: These shouldn't exist. */
470
471int
472sim_insert_breakpoint(int addr)
473{
474 if (sregs.bptnum < BPT_MAX) {
475 sregs.bpts[sregs.bptnum] = addr & ~0x3;
476 sregs.bptnum++;
477 if (sis_verbose)
478 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
479 return 0;
480 } else
481 return 1;
482}
483
484int
485sim_remove_breakpoint(int addr)
486{
487 int i = 0;
488
489 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
490 i++;
491 if (addr == sregs.bpts[i]) {
492 for (; i < sregs.bptnum - 1; i++)
493 sregs.bpts[i] = sregs.bpts[i + 1];
494 sregs.bptnum -= 1;
495 if (sis_verbose)
496 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
497 return 0;
498 }
499 return 1;
500}
501
502#endif