* config/tc-mips.c (mips16_extended_frag): Correct base address
[deliverable/binutils-gdb.git] / sim / erc32 / interf.c
CommitLineData
f4d2ff34
RS
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>
a665caa6 26#include <sys/fcntl.h>
f4d2ff34
RS
27#include "sis.h"
28#include "bfd.h"
29#include <dis-asm.h>
30
a665caa6
RS
31#include "remote-sim.h"
32
f4d2ff34
RS
33#ifndef fprintf
34extern fprintf();
35#endif
36
37#define VAL(x) strtol(x,(char *)NULL,0)
38
39extern char **buildargv(char *input);
40
41extern struct disassemble_info dinfo;
42extern struct pstate sregs;
43extern struct estate ebase;
44
45extern int ctrl_c;
46extern int nfp;
a665caa6
RS
47extern int ift;
48extern int rom8;
49extern int wrp;
f4d2ff34
RS
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;
a665caa6
RS
56extern int sparclite;
57extern int termsave;
58extern char uart_dev1[], uart_dev2[];
f4d2ff34
RS
59
60int sis_gdb_break = 1;
61
a665caa6 62host_callback *sim_callback;
f4d2ff34
RS
63
64run_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)
a665caa6
RS
73 (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
74 sregs->pc);
75 init_stdio();
76 sregs->starttime = time(NULL);
f4d2ff34
RS
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;
f4d2ff34
RS
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)
a665caa6
RS
116 (*sim_callback->printf_filtered) (sim_callback,
117 "SW BP hit at %x\n", sregs->pc);
f4d2ff34
RS
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 }
a665caa6 133 sim_stop();
f4d2ff34 134 sregs->tottime += time(NULL) - sregs->starttime;
a665caa6
RS
135 restore_stdio();
136 clearerr(stdin);
f4d2ff34
RS
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)
a665caa6
RS
143 (*sim_callback->printf_filtered) (sim_callback,
144 "HW BP hit at %x\n", sregs->pc);
f4d2ff34
RS
145 return (BPT_HIT);
146 }
147 if (ctrl_c) {
148 ctrl_c = 0;
149 return (CTRL_C);
150 }
151 return (TIME_OUT);
152}
153
a665caa6
RS
154void
155sim_set_callbacks (ptr)
156 host_callback *ptr;
157{
158 sim_callback = ptr;
159}
f4d2ff34
RS
160
161void
a665caa6
RS
162sim_size (memsize)
163 int memsize;
164{
165}
166
167void
168sim_open(args)
169 char *args;
f4d2ff34
RS
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
a665caa6
RS
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");
f4d2ff34
RS
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;
a665caa6 189 } else
f4d2ff34 190 if (strcmp(argv[stat], "-nfp") == 0) {
a665caa6 191 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
f4d2ff34 192 nfp = 1;
a665caa6
RS
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
f4d2ff34 215 if (strcmp(argv[stat], "-nogdb") == 0) {
a665caa6 216 (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
f4d2ff34 217 sis_gdb_break = 0;
a665caa6 218 } else
f4d2ff34
RS
219 if (strcmp(argv[stat], "-freq") == 0)
220 if ((stat + 1) < argc) {
221 freq = VAL(argv[++stat]);
a665caa6 222 (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
f4d2ff34
RS
223 }
224 } else
225 bfd_load(argv[stat]);
226 stat++;
227 }
228 freeargv(argv);
229 sregs.freq = freq;
a665caa6
RS
230 termsave = fcntl(0, F_GETFL, 0);
231 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
f4d2ff34
RS
232 init_signals();
233 reset_all();
234 ebase.simtime = 0;
235 init_sim();
236 init_bpt(&sregs);
237 reset_stat(&sregs);
238}
239
240void
241sim_close(int quitting)
242{
243
244 exit_sim();
a665caa6 245 fcntl(0, F_SETFL, termsave);
f4d2ff34
RS
246
247};
248
b7b31114
SG
249/* Return non-zero if the caller should handle the load. Zero if
250 we have loaded the image. */
a665caa6
RS
251
252int sim_load PARAMS ((char *prog, int from_tty));
253
f4d2ff34 254int
a665caa6
RS
255sim_load(prog, from_tty)
256 char *prog;
257 int from_tty;
f4d2ff34 258{
b7b31114 259 bfd_load(prog);
f4d2ff34
RS
260 return (0);
261}
262
a665caa6
RS
263void sim_create_inferior PARAMS ((SIM_ADDR start_address, char **argv, char **env));
264
f4d2ff34 265void
a665caa6
RS
266sim_create_inferior(start_address, argv, env)
267 SIM_ADDR start_address;
268 char **argv;
269 char **env;
f4d2ff34
RS
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
279void
280sim_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
290void
291sim_fetch_register(regno, buf)
292 int regno;
293 unsigned char *buf;
294{
295 get_regi(&sregs, regno, buf);
296}
297
298int
299sim_write(mem, buf, length)
a665caa6 300 SIM_ADDR mem;
f4d2ff34
RS
301 unsigned char *buf;
302 int length;
303{
304 return (sis_memory_write(mem, buf, length));
305}
306
a665caa6
RS
307int sim_read PARAMS ((SIM_ADDR mem, unsigned char *buf, int length));
308
f4d2ff34 309int
a665caa6
RS
310sim_read(mem, buf, length)
311 SIM_ADDR mem;
312 unsigned char *buf;
313 int length;
f4d2ff34
RS
314{
315 return (sis_memory_read(mem, buf, length));
316}
317
318void
319sim_info(int verbose)
320{
321 show_stat(&sregs);
322
323
324}
325
326int simstat = OK;
327
f4d2ff34
RS
328void
329sim_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;
a665caa6
RS
341#ifdef _WIN32
342#define SIGTRAP 5
343#endif
f4d2ff34
RS
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
b7b31114
SG
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
367static void
368flush_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}
f4d2ff34
RS
404
405void
406sim_resume(int step, int siggnal)
407{
408 simstat = run_sim(&sregs, 1, 0, 0);
b7b31114 409
a665caa6
RS
410 if (sis_gdb_break) flush_windows ();
411}
412
413int
414sim_trace ()
415{
416 /* FIXME: unfinished */
417 sim_resume (0, 0);
418 return 1;
f4d2ff34
RS
419}
420
421void
422sim_kill(void)
423{
a665caa6 424}
f4d2ff34
RS
425
426void
427sim_do_command(cmd)
428 char *cmd;
429{
430 exec_cmd(&sregs, cmd);
431}
432
a665caa6 433#if 0 /* FIXME: These shouldn't exist. */
f4d2ff34
RS
434
435int
436sim_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)
a665caa6 442 (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
f4d2ff34
RS
443 return 0;
444 } else
445 return 1;
446}
447
448int
449sim_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)
a665caa6 460 (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
f4d2ff34
RS
461 return 0;
462 }
463 return 1;
464}
a665caa6
RS
465
466#endif
This page took 0.062022 seconds and 4 git commands to generate.