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