aboutsummaryrefslogtreecommitdiff
path: root/sim/erc32/interf.c
diff options
context:
space:
mode:
authorRob Savoye <rob@cygnus>1996-05-20 02:46:07 +0000
committerRob Savoye <rob@cygnus>1996-05-20 02:46:07 +0000
commitf4d2ff34bef1789eef9bed93572993ee023270e2 (patch)
tree8627672c208e2f884decca146c9aefdcfd5bbb99 /sim/erc32/interf.c
parent41756e56ee00510ee7044119d0b033ea536dae5b (diff)
downloadfsf-binutils-gdb-f4d2ff34bef1789eef9bed93572993ee023270e2.zip
fsf-binutils-gdb-f4d2ff34bef1789eef9bed93572993ee023270e2.tar.gz
fsf-binutils-gdb-f4d2ff34bef1789eef9bed93572993ee023270e2.tar.bz2
New sparc simulator from the ESA.
Diffstat (limited to 'sim/erc32/interf.c')
-rw-r--r--sim/erc32/interf.c372
1 files changed, 372 insertions, 0 deletions
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
new file mode 100644
index 0000000..e81fbf3
--- /dev/null
+++ b/sim/erc32/interf.c
@@ -0,0 +1,372 @@
+/*
+ * This file is part of SIS.
+ *
+ * SIS, SPARC instruction simulator V1.6 Copyright (C) 1995 Jiri Gaisler,
+ * European Space Agency
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <signal.h>
+#include <string.h>
+#include <stdio.h>
+#include "sis.h"
+#include "bfd.h"
+#include <dis-asm.h>
+
+#ifndef fprintf
+extern fprintf();
+#endif
+
+#define VAL(x) strtol(x,(char *)NULL,0)
+
+extern char **buildargv(char *input);
+
+extern struct disassemble_info dinfo;
+extern struct pstate sregs;
+extern struct estate ebase;
+
+extern int ctrl_c;
+extern int nfp;
+extern int sis_verbose;
+extern char *sis_version;
+extern struct estate ebase;
+extern struct evcell evbuf[];
+extern struct irqcell irqarr[];
+extern int irqpend, ext_irl;
+extern char uart_dev1[], uart_dev2[];
+
+int sis_gdb_break = 1;
+
+#ifdef IUREV0
+extern int iurev0;
+#endif
+
+#ifdef MECREV0
+extern int mecrev0;
+#endif
+
+run_sim(sregs, go, icount, dis)
+ struct pstate *sregs;
+ int go;
+ unsigned int icount;
+ int dis;
+{
+ int mexc, ws;
+
+ if (sis_verbose)
+ printf_filtered("resuming at %x\n", sregs->pc);
+ sregs->starttime = time(NULL);
+ while ((!sregs->err_mode & (go || (icount > 0))) &&
+ ((sregs->bptnum == 0) || !(sregs->bphit = check_bpt(sregs)))) {
+
+ sregs->fhold = 0;
+ sregs->hold = 0;
+ sregs->icnt = 0;
+
+ check_interrupts(sregs);
+ if (sregs->trap) {
+ sregs->err_mode = execute_trap(sregs);
+ } else {
+ if (sregs->psr & 0x080)
+ sregs->asi = 8;
+ else
+ sregs->asi = 9;
+#ifdef IUREV0
+ if (iurev0 && sregs->rett_err) {
+ sregs->asi &= ~0x1;
+ sregs->asi |= ((sregs->psr & 0x040) >> 6);
+ }
+#endif
+
+ mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, &sregs->hold);
+ if (sregs->annul) {
+ sregs->annul = 0;
+ sregs->icnt = 1;
+ sregs->pc = sregs->npc;
+ sregs->npc = sregs->npc + 4;
+ } else {
+ if (mexc) {
+ sregs->trap = I_ACC_EXC;
+ } else {
+ if (sregs->histlen) {
+ sregs->histbuf[sregs->histind].addr = sregs->pc;
+ sregs->histbuf[sregs->histind].time = ebase.simtime;
+ sregs->histind++;
+ if (sregs->histind >= sregs->histlen)
+ sregs->histind = 0;
+ }
+ if (dis) {
+ printf(" %8d ", ebase.simtime);
+ dis_mem(sregs->pc, 1, &dinfo);
+ }
+ if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
+ if (sis_verbose)
+ printf_filtered("SW BP hit at %x\n", sregs->pc);
+ return (BPT_HIT);
+ } else
+ dispatch_instruction(sregs);
+ }
+ icount--;
+ }
+ if (sregs->trap) {
+ sregs->err_mode = execute_trap(sregs);
+ }
+ }
+ advance_time(sregs);
+ if (ctrl_c) {
+ go = icount = 0;
+ }
+ }
+ sregs->tottime += time(NULL) - sregs->starttime;
+ if (sregs->err_mode)
+ error_mode(sregs->pc);
+ if (sregs->err_mode)
+ return (ERROR);
+ if (sregs->bphit) {
+ if (sis_verbose)
+ printf_filtered("HW BP hit at %x\n", sregs->pc);
+ return (BPT_HIT);
+ }
+ if (ctrl_c) {
+ ctrl_c = 0;
+ return (CTRL_C);
+ }
+ return (TIME_OUT);
+}
+
+
+void
+sim_open(char *args)
+{
+
+ int argc = 0;
+ char **argv;
+ int cont = 1;
+ int stat = 0;
+ int grdl = 0;
+ int freq = 15;
+
+ printf_filtered("\n SIS - SPARC instruction simulator %s\n", sis_version);
+ printf_filtered(" Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
+ argv = buildargv(args);
+ if (argv != NULL)
+ while (argv[argc])
+ argc++;
+ while (stat < argc) {
+ if (argv[stat][0] == '-') {
+ if (strcmp(argv[stat], "-v") == 0) {
+ sis_verbose = 1;
+ }
+#ifdef IUREV0
+ if (strcmp(argv[stat], "-iurev0") == 0) {
+ iurev0 = 1;
+ printf_filtered(" simulating IU rev.0 jmpl/restore bug\n");
+ }
+#endif
+#ifdef MECREV0
+ if (strcmp(argv[stat], "-mecrev0") == 0) {
+ mecrev0 = 1;
+ printf_filtered(" simulating MEC rev.0 timer and uart interrupt bug\n");
+ }
+#endif
+ if (strcmp(argv[stat], "-nfp") == 0) {
+ printf_filtered("no FPU\n");
+ nfp = 1;
+ }
+ if (strcmp(argv[stat], "-uart1") == 0) {
+ if ((stat + 1) < argc)
+ strcpy(uart_dev1, argv[++stat]);
+ }
+ if (strcmp(argv[stat], "-uart2") == 0) {
+ if ((stat + 1) < argc)
+ strcpy(uart_dev2, argv[++stat]);
+ }
+ if (strcmp(argv[stat], "-nogdb") == 0) {
+ printf_filtered("disabling GDB trap handling for breakpoints\n");
+ sis_gdb_break = 0;
+ }
+ if (strcmp(argv[stat], "-freq") == 0)
+ if ((stat + 1) < argc) {
+ freq = VAL(argv[++stat]);
+ printf_filtered(" ERC32 freq %d Mhz\n", freq);
+ }
+ } else
+ bfd_load(argv[stat]);
+ stat++;
+ }
+ freeargv(argv);
+ sregs.freq = freq;
+
+ INIT_DISASSEMBLE_INFO(dinfo, stdout, fprintf);
+ init_signals();
+ reset_all();
+ ebase.simtime = 0;
+ init_sim();
+ init_bpt(&sregs);
+ reset_stat(&sregs);
+}
+
+void
+sim_close(int quitting)
+{
+
+ exit_sim();
+
+};
+
+int
+sim_load(char *prog, int from_tty)
+{
+ bfd_load(*prog);
+ return (0);
+}
+
+void
+sim_create_inferior(int start_address, char **argv, char **env)
+{
+ ebase.simtime = 0;
+ reset_all();
+ reset_stat(&sregs);
+ sregs.pc = start_address & ~3;
+ sregs.npc = sregs.pc + 4;
+
+}
+
+void
+sim_store_register(regno, value)
+ int regno;
+ unsigned char *value;
+{
+ /* FIXME: Review the computation of regval. */
+ int regval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
+ set_regi(&sregs, regno, regval);
+}
+
+
+void
+sim_fetch_register(regno, buf)
+ int regno;
+ unsigned char *buf;
+{
+ get_regi(&sregs, regno, buf);
+}
+
+int
+sim_write(mem, buf, length)
+ int mem;
+ unsigned char *buf;
+ int length;
+{
+ return (sis_memory_write(mem, buf, length));
+}
+
+int
+sim_read(int mem, unsigned char *buf, int length)
+{
+ return (sis_memory_read(mem, buf, length));
+}
+
+void
+sim_info(int verbose)
+{
+ show_stat(&sregs);
+
+
+}
+
+int simstat = OK;
+
+enum sim_stop {
+ sim_exited, sim_stopped, sim_signalled
+};
+
+void
+sim_stop_reason(enum sim_stop * reason, int *sigrc)
+{
+
+ switch (simstat) {
+ case CTRL_C:
+ *reason = sim_stopped;
+ *sigrc = SIGINT;
+ break;
+ case OK:
+ case TIME_OUT:
+ case BPT_HIT:
+ *reason = sim_stopped;
+ *sigrc = SIGTRAP;
+ break;
+ case ERROR:
+ *sigrc = 0;
+ *reason = sim_exited;
+ }
+ ctrl_c = 0;
+ simstat = OK;
+}
+
+
+void
+sim_resume(int step, int siggnal)
+{
+ simstat = run_sim(&sregs, 1, 0, 0);
+}
+
+void
+sim_kill(void)
+{
+};
+
+
+
+void
+sim_do_command(cmd)
+ char *cmd;
+{
+ exec_cmd(&sregs, cmd);
+}
+
+
+
+int
+sim_insert_breakpoint(int addr)
+{
+ if (sregs.bptnum < BPT_MAX) {
+ sregs.bpts[sregs.bptnum] = addr & ~0x3;
+ sregs.bptnum++;
+ if (sis_verbose)
+ printf_filtered("inserted HW BP at %x\n", addr);
+ return 0;
+ } else
+ return 1;
+}
+
+int
+sim_remove_breakpoint(int addr)
+{
+ int i = 0;
+
+ while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
+ i++;
+ if (addr == sregs.bpts[i]) {
+ for (; i < sregs.bptnum - 1; i++)
+ sregs.bpts[i] = sregs.bpts[i + 1];
+ sregs.bptnum -= 1;
+ if (sis_verbose)
+ printf_filtered("removed HW BP at %x\n", addr);
+ return 0;
+ }
+ return 1;
+}