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