Add `sim_complete_command' definition to erc32 sim
[deliverable/binutils-gdb.git] / sim / erc32 / interf.c
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"
30 #include "libiberty.h"
31 #include "bfd.h"
32 #include <dis-asm.h>
33 #include "sim-config.h"
34
35 #include "gdb/remote-sim.h"
36 #include "gdb/signals.h"
37
38 #define PSR_CWP 0x7
39
40 extern struct disassemble_info dinfo;
41 extern struct pstate sregs;
42 extern struct estate ebase;
43
44 extern int current_target_byte_order;
45 extern int ctrl_c;
46 extern int nfp;
47 extern int ift;
48 extern int rom8;
49 extern int wrp;
50 extern int uben;
51 extern int sis_verbose;
52 extern char *sis_version;
53 extern struct estate ebase;
54 extern struct evcell evbuf[];
55 extern struct irqcell irqarr[];
56 extern int irqpend, ext_irl;
57 extern int sparclite;
58 extern int dumbio;
59 extern int sparclite_board;
60 extern int termsave;
61 extern char uart_dev1[], uart_dev2[];
62
63 int sis_gdb_break = 1;
64
65 host_callback *sim_callback;
66
67 int
68 run_sim(sregs, icount, dis)
69 struct pstate *sregs;
70 uint64 icount;
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
164 void
165 sim_set_callbacks (ptr)
166 host_callback *ptr;
167 {
168 sim_callback = ptr;
169 }
170
171 void
172 sim_size (memsize)
173 int memsize;
174 {
175 }
176
177 SIM_DESC
178 sim_open (kind, callback, abfd, argv)
179 SIM_OPEN_KIND kind;
180 struct host_callback_struct *callback;
181 struct bfd *abfd;
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) {
235 freq = strtol(argv[++stat], (char **)NULL, 0);
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
276 void
277 sim_close(sd, quitting)
278 SIM_DESC sd;
279 int quitting;
280 {
281
282 exit_sim();
283 fcntl(0, F_SETFL, termsave);
284
285 };
286
287 SIM_RC
288 sim_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
298 SIM_RC
299 sim_create_inferior(sd, abfd, argv, env)
300 SIM_DESC sd;
301 struct bfd *abfd;
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
317 int
318 sim_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);
333 return length;
334 }
335
336
337 int
338 sim_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
348 int
349 sim_write(sd, mem, buf, length)
350 SIM_DESC sd;
351 SIM_ADDR mem;
352 const unsigned char *buf;
353 int length;
354 {
355 return (sis_memory_write(mem, buf, length));
356 }
357
358 int
359 sim_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
368 void
369 sim_info(sd, verbose)
370 SIM_DESC sd;
371 int verbose;
372 {
373 show_stat(&sregs);
374 }
375
376 int simstat = OK;
377
378 void
379 sim_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;
388 *sigrc = TARGET_SIGNAL_INT;
389 break;
390 case OK:
391 case TIME_OUT:
392 case BPT_HIT:
393 *reason = sim_stopped;
394 *sigrc = TARGET_SIGNAL_TRAP;
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
415 static void
416 flush_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
459 void
460 sim_resume(SIM_DESC sd, int step, int siggnal)
461 {
462 simstat = run_sim(&sregs, UINT64_MAX, 0);
463
464 if (sis_gdb_break) flush_windows ();
465 }
466
467 int
468 sim_trace (sd)
469 SIM_DESC sd;
470 {
471 /* FIXME: unfinished */
472 sim_resume (sd, 0, 0);
473 return 1;
474 }
475
476 void
477 sim_do_command(sd, cmd)
478 SIM_DESC sd;
479 char *cmd;
480 {
481 exec_cmd(&sregs, cmd);
482 }
483
484 char **
485 sim_complete_command (SIM_DESC sd, char *text, char *word)
486 {
487 return NULL;
488 }
489
490 #if 0 /* FIXME: These shouldn't exist. */
491
492 int
493 sim_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
505 int
506 sim_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.048957 seconds and 5 git commands to generate.