This commit was generated by cvs2svn to track changes on a CVS vendor
[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 sim_halt();
119 restore_stdio();
120 clearerr(stdin);
121 return (BPT_HIT);
122 } else
123 dispatch_instruction(sregs);
124 }
125 icount--;
126 }
127 if (sregs->trap) {
128 sregs->err_mode = execute_trap(sregs);
129 }
130 }
131 advance_time(sregs);
132 if (ctrl_c) {
133 go = icount = 0;
134 }
135 }
136 sim_halt();
137 sregs->tottime += time(NULL) - sregs->starttime;
138 restore_stdio();
139 clearerr(stdin);
140 if (sregs->err_mode)
141 error_mode(sregs->pc);
142 if (sregs->err_mode)
143 return (ERROR);
144 if (sregs->bphit) {
145 if (sis_verbose)
146 (*sim_callback->printf_filtered) (sim_callback,
147 "HW BP hit at %x\n", sregs->pc);
148 return (BPT_HIT);
149 }
150 if (ctrl_c) {
151 ctrl_c = 0;
152 return (CTRL_C);
153 }
154 return (TIME_OUT);
155 }
156
157 void
158 sim_set_callbacks (ptr)
159 host_callback *ptr;
160 {
161 sim_callback = ptr;
162 }
163
164 void
165 sim_size (memsize)
166 int memsize;
167 {
168 }
169
170 SIM_DESC
171 sim_open (kind, callback, abfd, argv)
172 SIM_OPEN_KIND kind;
173 struct host_callback_struct *callback;
174 struct _bfd *abfd;
175 char **argv;
176 {
177
178 int argc = 0;
179 int cont = 1;
180 int stat = 1;
181 int grdl = 0;
182 int freq = 15;
183
184 sim_callback = callback;
185
186 (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
187 (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
188 while (argv[argc])
189 argc++;
190 while (stat < argc) {
191 if (argv[stat][0] == '-') {
192 if (strcmp(argv[stat], "-v") == 0) {
193 sis_verbose = 1;
194 } else
195 if (strcmp(argv[stat], "-nfp") == 0) {
196 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
197 nfp = 1;
198 } else
199 if (strcmp(argv[stat], "-ift") == 0) {
200 ift = 1;
201 } else
202 if (strcmp(argv[stat], "-sparclite") == 0) {
203 (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
204 sparclite = 1;
205 } else
206 if (strcmp(argv[stat], "-wrp") == 0) {
207 wrp = 1;
208 } else
209 if (strcmp(argv[stat], "-rom8") == 0) {
210 rom8 = 1;
211 } else
212 if (strcmp(argv[stat], "-uart1") == 0) {
213 if ((stat + 1) < argc)
214 strcpy(uart_dev1, argv[++stat]);
215 } else
216 if (strcmp(argv[stat], "-uart2") == 0) {
217 if ((stat + 1) < argc)
218 strcpy(uart_dev2, argv[++stat]);
219 } else
220 if (strcmp(argv[stat], "-nogdb") == 0) {
221 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
222 sis_gdb_break = 0;
223 } else
224 if (strcmp(argv[stat], "-freq") == 0)
225 if ((stat + 1) < argc) {
226 freq = VAL(argv[++stat]);
227 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
228 }
229 } else
230 bfd_load(argv[stat]);
231 stat++;
232 }
233 sregs.freq = freq;
234 termsave = fcntl(0, F_GETFL, 0);
235 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
236 dinfo.endian = BFD_ENDIAN_BIG;
237 init_signals();
238 reset_all();
239 ebase.simtime = 0;
240 init_sim();
241 init_bpt(&sregs);
242 reset_stat(&sregs);
243
244 /* Fudge our descriptor for now. */
245 return (SIM_DESC) 1;
246 }
247
248 void
249 sim_close(sd, quitting)
250 SIM_DESC sd;
251 int quitting;
252 {
253
254 exit_sim();
255 fcntl(0, F_SETFL, termsave);
256
257 };
258
259 /* For communication from sim_load to sim_create_inferior. */
260 static bfd_vma start_address;
261
262 SIM_RC
263 sim_load(sd, prog, abfd, from_tty)
264 SIM_DESC sd;
265 char *prog;
266 bfd *abfd;
267 int from_tty;
268 {
269 start_address = bfd_load (prog);
270 return (0);
271 }
272
273 SIM_RC
274 sim_create_inferior(sd, argv, env)
275 SIM_DESC sd;
276 char **argv;
277 char **env;
278 {
279 ebase.simtime = 0;
280 reset_all();
281 reset_stat(&sregs);
282 sregs.pc = start_address & ~3;
283 sregs.npc = sregs.pc + 4;
284 return SIM_RC_OK;
285 }
286
287 void
288 sim_store_register(sd, regno, value)
289 SIM_DESC sd;
290 int regno;
291 unsigned char *value;
292 {
293 /* FIXME: Review the computation of regval. */
294 int regval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
295 set_regi(&sregs, regno, regval);
296 }
297
298
299 void
300 sim_fetch_register(sd, regno, buf)
301 SIM_DESC sd;
302 int regno;
303 unsigned char *buf;
304 {
305 get_regi(&sregs, regno, buf);
306 }
307
308 int
309 sim_write(sd, mem, buf, length)
310 SIM_DESC sd;
311 SIM_ADDR mem;
312 unsigned char *buf;
313 int length;
314 {
315 return (sis_memory_write(mem, buf, length));
316 }
317
318 int
319 sim_read(sd, mem, buf, length)
320 SIM_DESC sd;
321 SIM_ADDR mem;
322 unsigned char *buf;
323 int length;
324 {
325 return (sis_memory_read(mem, buf, length));
326 }
327
328 void
329 sim_info(sd, verbose)
330 SIM_DESC sd;
331 int verbose;
332 {
333 show_stat(&sregs);
334 }
335
336 int simstat = OK;
337
338 void
339 sim_stop_reason(sd, reason, sigrc)
340 SIM_DESC sd;
341 enum sim_stop * reason;
342 int *sigrc;
343 {
344
345 switch (simstat) {
346 case CTRL_C:
347 *reason = sim_stopped;
348 *sigrc = SIGINT;
349 break;
350 case OK:
351 case TIME_OUT:
352 case BPT_HIT:
353 *reason = sim_stopped;
354 #ifdef _WIN32
355 #define SIGTRAP 5
356 #endif
357 *sigrc = SIGTRAP;
358 break;
359 case ERROR:
360 *sigrc = 0;
361 *reason = sim_exited;
362 }
363 ctrl_c = 0;
364 simstat = OK;
365 }
366
367 /* Flush all register windows out to the stack. Starting after the invalid
368 window, flush all windows up to, and including the current window. This
369 allows GDB to do backtraces and look at local variables for frames that
370 are still in the register windows. Note that strictly speaking, this
371 behavior is *wrong* for several reasons. First, it doesn't use the window
372 overflow handlers. It therefore assumes standard frame layouts and window
373 handling policies. Second, it changes system state behind the back of the
374 target program. I expect this to mainly pose problems when debugging trap
375 handlers.
376 */
377
378 #define PSR_CWP 0x7
379
380 static void
381 flush_windows ()
382 {
383 int invwin;
384 int cwp;
385 int win;
386 int ws;
387
388 /* Keep current window handy */
389
390 cwp = sregs.psr & PSR_CWP;
391
392 /* Calculate the invalid window from the wim. */
393
394 for (invwin = 0; invwin <= PSR_CWP; invwin++)
395 if ((sregs.wim >> invwin) & 1)
396 break;
397
398 /* Start saving with the window after the invalid window. */
399
400 invwin = (invwin - 1) & PSR_CWP;
401
402 for (win = invwin; ; win = (win - 1) & PSR_CWP)
403 {
404 uint32 sp;
405 int i;
406
407 sp = sregs.r[(win * 16 + 14) & 0x7f];
408
409 for (i = 0; i < 16; i++)
410 memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
411 &ws);
412
413 if (win == cwp)
414 break;
415 }
416 }
417
418 void
419 sim_resume(SIM_DESC sd, int step, int siggnal)
420 {
421 simstat = run_sim(&sregs, 1, 0, 0);
422
423 if (sis_gdb_break) flush_windows ();
424 }
425
426 int
427 sim_trace (sd)
428 SIM_DESC sd;
429 {
430 /* FIXME: unfinished */
431 sim_resume (sd, 0, 0);
432 return 1;
433 }
434
435 void
436 sim_do_command(sd, cmd)
437 SIM_DESC sd;
438 char *cmd;
439 {
440 exec_cmd(&sregs, cmd);
441 }
442
443 #if 0 /* FIXME: These shouldn't exist. */
444
445 int
446 sim_insert_breakpoint(int addr)
447 {
448 if (sregs.bptnum < BPT_MAX) {
449 sregs.bpts[sregs.bptnum] = addr & ~0x3;
450 sregs.bptnum++;
451 if (sis_verbose)
452 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
453 return 0;
454 } else
455 return 1;
456 }
457
458 int
459 sim_remove_breakpoint(int addr)
460 {
461 int i = 0;
462
463 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
464 i++;
465 if (addr == sregs.bpts[i]) {
466 for (; i < sregs.bptnum - 1; i++)
467 sregs.bpts[i] = sregs.bpts[i + 1];
468 sregs.bptnum -= 1;
469 if (sis_verbose)
470 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
471 return 0;
472 }
473 return 1;
474 }
475
476 #endif
This page took 0.041175 seconds and 5 git commands to generate.