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