From 865b177d0e2fd534270ef158030e7c3056a930e3 Mon Sep 17 00:00:00 2001 From: Jiri Gaisler Date: Fri, 22 Mar 2019 10:00:07 +0100 Subject: Standalone sis - initial commit --- interf.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 interf.c (limited to 'interf.c') diff --git a/interf.c b/interf.c new file mode 100644 index 0000000..e79a6cb --- /dev/null +++ b/interf.c @@ -0,0 +1,321 @@ +/* This file is part of SIS (SPARC instruction simulator) + + Copyright (C) 1995-2017 Free Software Foundation, Inc. + Contributed by 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 3 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, see . */ + +#include "config.h" +#include +#include +#include +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#include "sis.h" + +#define PSR_CWP 0x7 +#define SIM_DESC int +#define SIM_ADDR uint32 +#define SIM_RC int +#define SIM_RC_FAIL 0 +#define SIM_RC_OK 1 +#define EBREAK 0x00100073 +#define CEBREAK 0x90002 + +static int +run_sim_gdb(icount, dis) + uint64 icount; + int dis; +{ + int res; + + if ((sregs[cpu].pc != 0) && (ebase.simtime == 0)) + ms->boot_init (); + res = run_sim(icount, dis); + ms->sim_halt(); + clearerr(stdin); + return res; +} + +void +sim_close(sd, quitting) + SIM_DESC sd; + int quitting; +{ + + ms->exit_sim (); +#if defined(F_GETFL) && defined(F_SETFL) + fcntl(0, F_SETFL, termsave); +#endif + +}; + +void +sim_create_inferior() +{ + int i; + + if (sis_verbose) + printf("interf: sim_create_inferior()"); + ebase.simtime = 0; + ebase.simstart = 0; + reset_all(); + reset_stat(sregs); + for (i=0; isis_memory_write ((mem + i) ^ arch->endian, &buf[i], 1); + } + return length; +} + +int +sim_read (uint32 mem, unsigned char *buf, int length) +{ + int i, len; + + for (i = 0; i < length; i++) { + ms->sis_memory_read ((mem + i) ^ arch->endian, &buf[i], 1); + } + return length; +} + +void +sim_info(sd, verbose) + SIM_DESC sd; + int verbose; +{ + show_stat(&sregs[cpu]); +} + +int simstat = OK; + +void +sim_resume(int step) +{ + if (step) + simstat = run_sim_gdb(1, 0); + else + simstat = run_sim_gdb(UINT64_MAX/2, 0); + + if (sis_gdb_break && (cputype != CPU_RISCV)) + flush_windows (&sregs[cpu]); +} + +int +sim_stop (SIM_DESC sd) +{ + ctrl_c = 1; + return 1; +} + +static int +sis_insert_watchpoint_read(int addr, unsigned char mask) +{ + if (ebase.wprnum < WPR_MAX) { + ebase.wprs[ebase.wprnum] = addr; + ebase.wprm[ebase.wprnum] = mask; + ebase.wprnum++; + if (sis_verbose) + printf ("inserted read watchpoint at %x\n", addr); + return SIM_RC_OK; + } else + return SIM_RC_FAIL; +} + +static int +sis_remove_watchpoint_read(int addr) +{ + int i = 0; + + while ((i < ebase.wprnum) && (ebase.wprs[i] != addr)) + i++; + if (addr == ebase.wprs[i]) { + for (; i < ebase.wprnum - 1; i++) + ebase.wprs[i] = ebase.wprs[i + 1]; + ebase.wprnum -= 1; + if (sis_verbose) + printf ("removed read watchpoint at %x\n", addr); + return 0; + } + return 1; +} + +static int +sis_insert_watchpoint_write(int32 addr, unsigned char mask) +{ + if (ebase.wpwnum < WPR_MAX) { + ebase.wpws[ebase.wpwnum] = addr; + ebase.wpwm[ebase.wpwnum] = mask; + ebase.wpwnum++; + if (sis_verbose) + printf ("sim_insert_watchpoint_write: 0x%08x : %x\n", addr, mask); + return SIM_RC_OK; + } else + return SIM_RC_FAIL; +} + +static int +sis_remove_watchpoint_write(int addr) +{ + int i = 0; + + while ((i < ebase.wpwnum) && (ebase.wpws[i] != addr)) + i++; + if (addr == ebase.wpws[i]) { + for (; i < ebase.wpwnum - 1; i++) + ebase.wpws[i] = ebase.wpws[i + 1]; + ebase.wpwnum -= 1; + if (sis_verbose) + printf ("removed write watchpoint at %x\n", addr); + return SIM_RC_OK; + } + return SIM_RC_FAIL; +} + +int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) +{ + if (type == 2) /* bp_hardware_breakpoint not supported */ + return 0; + else + return 1; +} + + +int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) +{ + int res; + unsigned char mask; + + switch (length) { + case 1: mask = 0; break; + case 2: mask = 1; break; + case 4: mask = 3; break; + default: mask = 7; break; + } + + switch (type) { + case 0: + res = sis_insert_watchpoint_write (mem, mask); + break; + case 1: + res = sis_insert_watchpoint_read (mem, mask); + break; + case 2: + if ((res = sis_insert_watchpoint_write (mem, mask)) == SIM_RC_OK) + res = sis_insert_watchpoint_read (mem, mask); + if (res == SIM_RC_FAIL) + sis_remove_watchpoint_read (mem); + break; + default: + res = -1; + } + return (res); +} + + +int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) +{ + int res; + switch (type) { + case 0: + res = sis_remove_watchpoint_write (mem); + break; + case 1: + res = sis_remove_watchpoint_read (mem); + break; + case 2: + if ((res = sis_remove_watchpoint_write (mem)) == SIM_RC_OK) + res = sis_remove_watchpoint_read (mem); + else + sis_remove_watchpoint_read (mem); + break; + default: + res = -1; + } + return (res); +} + +int sim_stopped_by_watchpoint (SIM_DESC sd) +{ + if (sis_verbose) + printf ("sim_stopped_by_watchpoint %x\n", ebase.wphit); + return((ebase.wphit != 0)); +} + +int sim_watchpoint_address (SIM_DESC sd) +{ + if (sis_verbose) + printf("sim__watchpoint_address %x\n", ebase.wpaddress); + return(ebase.wpaddress); +} + +int +sim_insert_swbreakpoint(uint32 addr, int len) +{ + uint32 breakinsn; + + if (ebase.bptnum < BPT_MAX) { + ebase.bpts[ebase.bptnum] = addr; + ms->sis_memory_read (addr, (char *) &ebase.bpsave[ebase.bptnum] , len); + if (len == 4) { + breakinsn = EBREAK; + ms->sis_memory_write (addr, (char *) &breakinsn , 4); + } else { + breakinsn = CEBREAK; + ms->sis_memory_write (addr, (char *) &breakinsn , 2); + } + if (sis_verbose) + printf("sim_insert_swbreakpoint: added breakpoint %d at 0x%08x\n", ebase.bptnum + 1, addr); + ebase.bptnum += 1; + return 1; + } + return 0; /* Too many breakpoints */ +} + +int +sim_remove_swbreakpoint(uint32 addr, int len) +{ + int i; + + /* find breakpoint to remove */ + for (i=0; isis_memory_write (addr, (char *) &ebase.bpsave[i] , len); + if (sis_verbose) + printf("sim_remove_swbreakpoint: remove breakpoint %d at 0x%08x\n", i, addr); + /* shift down remaining breakpoints */ + for (; i