2005-03-07 Jerome Guitton <guitton@gnat.com>
[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
37 #define PSR_CWP 0x7
38
39 #define VAL(x) strtol(x,(char **)NULL,0)
40
41 extern struct disassemble_info dinfo;
42 extern struct pstate sregs;
43 extern struct estate ebase;
44
45 extern int current_target_byte_order;
46 extern int ctrl_c;
47 extern int nfp;
48 extern int ift;
49 extern int rom8;
50 extern int wrp;
51 extern int uben;
52 extern int sis_verbose;
53 extern char *sis_version;
54 extern struct estate ebase;
55 extern struct evcell evbuf[];
56 extern struct irqcell irqarr[];
57 extern int irqpend, ext_irl;
58 extern int sparclite;
59 extern int dumbio;
60 extern int sparclite_board;
61 extern int termsave;
62 extern char uart_dev1[], uart_dev2[];
63
64 int sis_gdb_break = 1;
65
66 host_callback *sim_callback;
67
68 int
69 run_sim(sregs, icount, dis)
70 struct pstate *sregs;
71 unsigned int icount;
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
165 void
166 sim_set_callbacks (ptr)
167 host_callback *ptr;
168 {
169 sim_callback = ptr;
170 }
171
172 void
173 sim_size (memsize)
174 int memsize;
175 {
176 }
177
178 SIM_DESC
179 sim_open (kind, callback, abfd, argv)
180 SIM_OPEN_KIND kind;
181 struct host_callback_struct *callback;
182 struct bfd *abfd;
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) {
236 freq = VAL(argv[++stat]);
237 }
238 } else {
239 (*sim_callback->printf_filtered) (sim_callback,
240 "unknown option %s\n",
241 argv[stat]);
242 }
243 } else
244 bfd_load(argv[stat]);
245 stat++;
246 }
247
248 if (sis_verbose) {
249 (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
250 (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
251 if (nfp)
252 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
253 if (sparclite)
254 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
255 if (dumbio)
256 (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
257 if (sis_gdb_break == 0)
258 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
259 if (freq)
260 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
261 }
262
263 sregs.freq = freq ? freq : 15;
264 termsave = fcntl(0, F_GETFL, 0);
265 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
266 dinfo.endian = BFD_ENDIAN_BIG;
267 reset_all();
268 ebase.simtime = 0;
269 init_sim();
270 init_bpt(&sregs);
271 reset_stat(&sregs);
272
273 /* Fudge our descriptor for now. */
274 return (SIM_DESC) 1;
275 }
276
277 void
278 sim_close(sd, quitting)
279 SIM_DESC sd;
280 int quitting;
281 {
282
283 exit_sim();
284 fcntl(0, F_SETFL, termsave);
285
286 };
287
288 SIM_RC
289 sim_load(sd, prog, abfd, from_tty)
290 SIM_DESC sd;
291 char *prog;
292 bfd *abfd;
293 int from_tty;
294 {
295 bfd_load (prog);
296 return SIM_RC_OK;
297 }
298
299 SIM_RC
300 sim_create_inferior(sd, abfd, argv, env)
301 SIM_DESC sd;
302 struct bfd *abfd;
303 char **argv;
304 char **env;
305 {
306 bfd_vma start_address = 0;
307 if (abfd != NULL)
308 start_address = bfd_get_start_address (abfd);
309
310 ebase.simtime = 0;
311 reset_all();
312 reset_stat(&sregs);
313 sregs.pc = start_address & ~3;
314 sregs.npc = sregs.pc + 4;
315 return SIM_RC_OK;
316 }
317
318 int
319 sim_store_register(sd, regno, value, length)
320 SIM_DESC sd;
321 int regno;
322 unsigned char *value;
323 int length;
324 {
325 /* FIXME: Review the computation of regval. */
326 int regval;
327 if (current_target_byte_order == BIG_ENDIAN)
328 regval = (value[0] << 24) | (value[1] << 16)
329 | (value[2] << 8) | value[3];
330 else
331 regval = (value[3] << 24) | (value[2] << 16)
332 | (value[1] << 8) | value[0];
333 set_regi(&sregs, regno, regval);
334 return -1;
335 }
336
337
338 int
339 sim_fetch_register(sd, regno, buf, length)
340 SIM_DESC sd;
341 int regno;
342 unsigned char *buf;
343 int length;
344 {
345 get_regi(&sregs, regno, buf);
346 return -1;
347 }
348
349 int
350 sim_write(sd, mem, buf, length)
351 SIM_DESC sd;
352 SIM_ADDR mem;
353 unsigned char *buf;
354 int length;
355 {
356 return (sis_memory_write(mem, buf, length));
357 }
358
359 int
360 sim_read(sd, mem, buf, length)
361 SIM_DESC sd;
362 SIM_ADDR mem;
363 unsigned char *buf;
364 int length;
365 {
366 return (sis_memory_read(mem, buf, length));
367 }
368
369 void
370 sim_info(sd, verbose)
371 SIM_DESC sd;
372 int verbose;
373 {
374 show_stat(&sregs);
375 }
376
377 int simstat = OK;
378
379 void
380 sim_stop_reason(sd, reason, sigrc)
381 SIM_DESC sd;
382 enum sim_stop * reason;
383 int *sigrc;
384 {
385
386 switch (simstat) {
387 case CTRL_C:
388 *reason = sim_stopped;
389 *sigrc = SIGINT;
390 break;
391 case OK:
392 case TIME_OUT:
393 case BPT_HIT:
394 *reason = sim_stopped;
395 #ifdef _WIN32
396 #define SIGTRAP 5
397 #endif
398 *sigrc = SIGTRAP;
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
419 static void
420 flush_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
463 void
464 sim_resume(SIM_DESC sd, int step, int siggnal)
465 {
466 simstat = run_sim(&sregs, -1, 0);
467
468 if (sis_gdb_break) flush_windows ();
469 }
470
471 int
472 sim_trace (sd)
473 SIM_DESC sd;
474 {
475 /* FIXME: unfinished */
476 sim_resume (sd, 0, 0);
477 return 1;
478 }
479
480 void
481 sim_do_command(sd, cmd)
482 SIM_DESC sd;
483 char *cmd;
484 {
485 exec_cmd(&sregs, cmd);
486 }
487
488 #if 0 /* FIXME: These shouldn't exist. */
489
490 int
491 sim_insert_breakpoint(int addr)
492 {
493 if (sregs.bptnum < BPT_MAX) {
494 sregs.bpts[sregs.bptnum] = addr & ~0x3;
495 sregs.bptnum++;
496 if (sis_verbose)
497 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
498 return 0;
499 } else
500 return 1;
501 }
502
503 int
504 sim_remove_breakpoint(int addr)
505 {
506 int i = 0;
507
508 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
509 i++;
510 if (addr == sregs.bpts[i]) {
511 for (; i < sregs.bptnum - 1; i++)
512 sregs.bpts[i] = sregs.bpts[i + 1];
513 sregs.bptnum -= 1;
514 if (sis_verbose)
515 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
516 return 0;
517 }
518 return 1;
519 }
520
521 #endif
This page took 0.039894 seconds and 5 git commands to generate.