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