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