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