Add `sim_complete_command' definition to erc32 sim
[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"
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
SS
236 }
237 } else {
238 (*sim_callback->printf_filtered) (sim_callback,
239 "unknown option %s\n",
240 argv[stat]);
241 }
242 } else
243 bfd_load(argv[stat]);
244 stat++;
245 }
246
247 if (sis_verbose) {
248 (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
249 (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
250 if (nfp)
251 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
252 if (sparclite)
253 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
254 if (dumbio)
255 (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
256 if (sis_gdb_break == 0)
257 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
258 if (freq)
259 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
260 }
261
262 sregs.freq = freq ? freq : 15;
263 termsave = fcntl(0, F_GETFL, 0);
264 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
265 dinfo.endian = BFD_ENDIAN_BIG;
266 reset_all();
267 ebase.simtime = 0;
268 init_sim();
269 init_bpt(&sregs);
270 reset_stat(&sregs);
271
272 /* Fudge our descriptor for now. */
273 return (SIM_DESC) 1;
274}
275
276void
277sim_close(sd, quitting)
278 SIM_DESC sd;
279 int quitting;
280{
281
282 exit_sim();
283 fcntl(0, F_SETFL, termsave);
284
285};
286
287SIM_RC
288sim_load(sd, prog, abfd, from_tty)
289 SIM_DESC sd;
290 char *prog;
291 bfd *abfd;
292 int from_tty;
293{
294 bfd_load (prog);
295 return SIM_RC_OK;
296}
297
298SIM_RC
299sim_create_inferior(sd, abfd, argv, env)
300 SIM_DESC sd;
6b4a8935 301 struct bfd *abfd;
c906108c
SS
302 char **argv;
303 char **env;
304{
305 bfd_vma start_address = 0;
306 if (abfd != NULL)
307 start_address = bfd_get_start_address (abfd);
308
309 ebase.simtime = 0;
310 reset_all();
311 reset_stat(&sregs);
312 sregs.pc = start_address & ~3;
313 sregs.npc = sregs.pc + 4;
314 return SIM_RC_OK;
315}
316
317int
318sim_store_register(sd, regno, value, length)
319 SIM_DESC sd;
320 int regno;
321 unsigned char *value;
322 int length;
323{
324 /* FIXME: Review the computation of regval. */
325 int regval;
326 if (current_target_byte_order == BIG_ENDIAN)
327 regval = (value[0] << 24) | (value[1] << 16)
328 | (value[2] << 8) | value[3];
329 else
330 regval = (value[3] << 24) | (value[2] << 16)
331 | (value[1] << 8) | value[0];
332 set_regi(&sregs, regno, regval);
dae477fe 333 return length;
c906108c
SS
334}
335
336
337int
338sim_fetch_register(sd, regno, buf, length)
339 SIM_DESC sd;
340 int regno;
341 unsigned char *buf;
342 int length;
343{
344 get_regi(&sregs, regno, buf);
345 return -1;
346}
347
348int
349sim_write(sd, mem, buf, length)
350 SIM_DESC sd;
351 SIM_ADDR mem;
5558e7e6 352 const unsigned char *buf;
c906108c
SS
353 int length;
354{
355 return (sis_memory_write(mem, buf, length));
356}
357
358int
359sim_read(sd, mem, buf, length)
360 SIM_DESC sd;
361 SIM_ADDR mem;
362 unsigned char *buf;
363 int length;
364{
365 return (sis_memory_read(mem, buf, length));
366}
367
368void
369sim_info(sd, verbose)
370 SIM_DESC sd;
371 int verbose;
372{
373 show_stat(&sregs);
374}
375
376int simstat = OK;
377
378void
379sim_stop_reason(sd, reason, sigrc)
380 SIM_DESC sd;
381 enum sim_stop * reason;
382 int *sigrc;
383{
384
385 switch (simstat) {
386 case CTRL_C:
387 *reason = sim_stopped;
aba6488e 388 *sigrc = TARGET_SIGNAL_INT;
c906108c
SS
389 break;
390 case OK:
391 case TIME_OUT:
392 case BPT_HIT:
393 *reason = sim_stopped;
aba6488e 394 *sigrc = TARGET_SIGNAL_TRAP;
c906108c
SS
395 break;
396 case ERROR:
397 *sigrc = 0;
398 *reason = sim_exited;
399 }
400 ctrl_c = 0;
401 simstat = OK;
402}
403
404/* Flush all register windows out to the stack. Starting after the invalid
405 window, flush all windows up to, and including the current window. This
406 allows GDB to do backtraces and look at local variables for frames that
407 are still in the register windows. Note that strictly speaking, this
408 behavior is *wrong* for several reasons. First, it doesn't use the window
409 overflow handlers. It therefore assumes standard frame layouts and window
410 handling policies. Second, it changes system state behind the back of the
411 target program. I expect this to mainly pose problems when debugging trap
412 handlers.
413*/
414
415static void
416flush_windows ()
417{
418 int invwin;
419 int cwp;
420 int win;
421 int ws;
422
423 /* Keep current window handy */
424
425 cwp = sregs.psr & PSR_CWP;
426
427 /* Calculate the invalid window from the wim. */
428
429 for (invwin = 0; invwin <= PSR_CWP; invwin++)
430 if ((sregs.wim >> invwin) & 1)
431 break;
432
433 /* Start saving with the window after the invalid window. */
434
435 invwin = (invwin - 1) & PSR_CWP;
436
437 for (win = invwin; ; win = (win - 1) & PSR_CWP)
438 {
439 uint32 sp;
440 int i;
441
442 sp = sregs.r[(win * 16 + 14) & 0x7f];
443#if 1
444 if (sis_verbose > 2) {
445 uint32 fp = sregs.r[(win * 16 + 30) & 0x7f];
446 printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
447 }
448#endif
449
450 for (i = 0; i < 16; i++)
451 memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
452 &ws);
453
454 if (win == cwp)
455 break;
456 }
457}
458
459void
460sim_resume(SIM_DESC sd, int step, int siggnal)
461{
94110024 462 simstat = run_sim(&sregs, UINT64_MAX, 0);
c906108c
SS
463
464 if (sis_gdb_break) flush_windows ();
465}
466
467int
468sim_trace (sd)
469 SIM_DESC sd;
470{
471 /* FIXME: unfinished */
472 sim_resume (sd, 0, 0);
473 return 1;
474}
475
476void
477sim_do_command(sd, cmd)
478 SIM_DESC sd;
479 char *cmd;
480{
481 exec_cmd(&sregs, cmd);
482}
483
248d2a8f
JB
484char **
485sim_complete_command (SIM_DESC sd, char *text, char *word)
486{
487 return NULL;
488}
489
c906108c
SS
490#if 0 /* FIXME: These shouldn't exist. */
491
492int
493sim_insert_breakpoint(int addr)
494{
495 if (sregs.bptnum < BPT_MAX) {
496 sregs.bpts[sregs.bptnum] = addr & ~0x3;
497 sregs.bptnum++;
498 if (sis_verbose)
499 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
500 return 0;
501 } else
502 return 1;
503}
504
505int
506sim_remove_breakpoint(int addr)
507{
508 int i = 0;
509
510 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
511 i++;
512 if (addr == sregs.bpts[i]) {
513 for (; i < sregs.bptnum - 1; i++)
514 sregs.bpts[i] = sregs.bpts[i + 1];
515 sregs.bptnum -= 1;
516 if (sis_verbose)
517 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
518 return 0;
519 }
520 return 1;
521}
522
523#endif
This page took 0.48715 seconds and 4 git commands to generate.