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