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