diff options
author | Rob Savoye <rob@cygnus> | 1996-05-20 02:46:07 +0000 |
---|---|---|
committer | Rob Savoye <rob@cygnus> | 1996-05-20 02:46:07 +0000 |
commit | f4d2ff34bef1789eef9bed93572993ee023270e2 (patch) | |
tree | 8627672c208e2f884decca146c9aefdcfd5bbb99 /sim/erc32/interf.c | |
parent | 41756e56ee00510ee7044119d0b033ea536dae5b (diff) | |
download | gdb-f4d2ff34bef1789eef9bed93572993ee023270e2.zip gdb-f4d2ff34bef1789eef9bed93572993ee023270e2.tar.gz gdb-f4d2ff34bef1789eef9bed93572993ee023270e2.tar.bz2 |
New sparc simulator from the ESA.
Diffstat (limited to 'sim/erc32/interf.c')
-rw-r--r-- | sim/erc32/interf.c | 372 |
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; +} |