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