public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 16/23] sim/erc32: use readline.h for readline types and functions.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17  9:21   ` Mike Frysinger
  2015-02-17  7:45 ` [PATCH 17/23] sim/erc32: Move local extern declarations into sis.h Jiri Gaisler
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Use gdb's readline.h for readline types.

	* Makefile.in : Add include path to readline.h
	sis.c : Remove locally define readline types.
---
 sim/erc32/Makefile.in |  2 +-
 sim/erc32/sis.c       | 13 ++-----------
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
index f1d79cd..7dfc7da 100644
--- a/sim/erc32/Makefile.in
+++ b/sim/erc32/Makefile.in
@@ -30,7 +30,7 @@ SIM_EXTRA_CLEAN = clean-sis
 # UARTS run at about 115200 baud (simulator time). Add -DFAST_UART to
 # CFLAGS if faster (infinite) UART speed is desired. Might affect the
 # behaviour of UART interrupt routines ...
-SIM_EXTRA_CFLAGS = -DFAST_UART
+SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcdir)/../..
 
 ## COMMON_POST_CONFIG_FRAG
 
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index 2b0871a..a5a81d8 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -35,17 +35,8 @@
 
 /* Structures and functions from readline library */
 
-typedef struct {
-  char *line;
-  char *data;
-} HIST_ENTRY;
-
-extern char *	readline (char *prompt);
-extern void	using_history (void);
-extern void	add_history (char *string);
-extern HIST_ENTRY *remove_history (int which);
-
-
+#include "readline/readline.h"
+#include "readline/history.h"
 
 /* Command history buffer length - MUST be binary */
 #define HIST_LEN	64
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 07/23] sim/erc32: file loading via command line did not work
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (6 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 10/23] sim/erc32: Switched emulated memory to host endian order Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17  9:09   ` Mike Frysinger
  2015-02-17  7:45 ` [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not work due to API change Jiri Gaisler
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* sis.c (main) load binary file from argv parameters
---
 sim/erc32/sis.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index f2aed78..39050d7 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -171,6 +171,7 @@ main(argc, argv)
     char           *cmdq[HIST_LEN];
     int             cmdi = 0;
     int             i;
+    int             lfile = 0;
 
     cfile = 0;
     for (i = 0; i < 64; i++)
@@ -219,7 +220,7 @@ main(argc, argv)
 		exit(1);
 	    }
 	} else {
-	    last_load_addr = bfd_load(argv[stat]);
+	    lfile = stat;
 	}
 	stat++;
     }
@@ -241,6 +242,7 @@ main(argc, argv)
     reset_all();
     init_bpt(&sregs);
     init_sim();
+    if (lfile) last_load_addr = bfd_load(argv[lfile]);
 #ifdef STAT
     reset_stat(&sregs);
 #endif
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 15/23] sim/erc32: access memory subsystem through struct memsys to allow multiple configurations.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (4 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 05/23] sim/erc32: remove unused defines in Makefile and switch off statistics Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 10/23] sim/erc32: Switched emulated memory to host endian order Jiri Gaisler
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Introduce an common API to access emulated memory. This allows
	to emulate different types of SPARC-based CPUs.

	* erc32.c : Export memory operations through struct memsys erc32sys.
	* exec.c (dispatch_instruction) Access memory through common API.
	* func.c, interf.c, sis.c : As above.
	* sis.h : Define struct memsys as common memory API
---
 sim/erc32/erc32.c  | 54 ++++++++++++++++++++++++++++--------------------------
 sim/erc32/exec.c   | 42 +++++++++++++++++++++---------------------
 sim/erc32/func.c   | 37 +++++++++++++++++++++----------------
 sim/erc32/interf.c | 39 +++++++++++++++++++++------------------
 sim/erc32/sis.c    | 15 ++++++---------
 sim/erc32/sis.h    | 46 ++++++++++++++++++++++++++++------------------
 6 files changed, 125 insertions(+), 108 deletions(-)

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 3f25ca7..8d2a6e8 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -39,8 +39,7 @@ extern int32    sparclite, sparclite_board;
 extern int      rom8,wrp,uben;
 extern char     uart_dev1[], uart_dev2[];
 
-int dumbio = 0; /* normal, smart, terminal oriented IO by default */
-int tty_setup = 1; /* default setup if not a tty */
+static int tty_setup = 1; /* default setup if not a tty */
 
 /* MEC registers */
 #define MEC_START 	0x01f80000
@@ -56,11 +55,6 @@ int tty_setup = 1; /* default setup if not a tty */
 extern int errmec;
 #endif
 
-/* The target's byte order is big-endian by default until we load a
-   little-endian program.  */
-
-int	current_target_byte_order = BIG_ENDIAN;
-
 #define MEC_WS	0		/* Waitstates per MEC access (0 ws) */
 #define MOK	0
 
@@ -308,7 +302,7 @@ static host_callback *callback;
 
 /* One-time init */
 
-void
+static void
 init_sim()
 {
     callback = sim_callback;
@@ -317,7 +311,7 @@ init_sim()
 
 /* Power-on reset init */
 
-void
+static void
 reset()
 {
     mec_reset();
@@ -397,7 +391,7 @@ mecparerror()
 
 /* IU error mode manager */
 
-void
+static void
 error_mode(pc)
     uint32          pc;
 {
@@ -468,7 +462,7 @@ decode_mcr()
 
 /* Flush ports when simulator stops */
 
-void
+static void
 sim_halt()
 {
 #ifdef FAST_UART
@@ -476,13 +470,6 @@ sim_halt()
 #endif
 }
 
-int
-sim_stop(SIM_DESC sd)
-{
-  ctrl_c = 1;
-  return 1;
-}
-
 static void
 close_port()
 {
@@ -492,7 +479,7 @@ close_port()
 	fclose(f2in);
 }
 
-void
+static void
 exit_sim()
 {
     close_port();
@@ -944,7 +931,7 @@ mec_write(addr, data)
 
 static int      ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1;
 
-void
+static void
 init_stdio()
 {
     if (dumbio)
@@ -959,7 +946,7 @@ init_stdio()
     }
 }
 
-void
+static void
 restore_stdio()
 {
     if (dumbio)
@@ -1632,7 +1619,7 @@ store_bytes (mem, waddr, data, sz, ws)
 
 /* Memory emulation */
 
-int
+static int
 memory_iread(addr, data, ws)
     uint32          addr;
     uint32         *data;
@@ -1656,7 +1643,7 @@ memory_iread(addr, data, ws)
     return (1);
 }
 
-int
+static int
 memory_read(asi, addr, data, sz, ws)
     int32           asi;
     uint32          addr;
@@ -1727,7 +1714,7 @@ memory_read(asi, addr, data, sz, ws)
     return (1);
 }
 
-int
+static int
 memory_write(asi, addr, data, sz, ws)
     int32           asi;
     uint32          addr;
@@ -1863,7 +1850,7 @@ get_mem_ptr(addr, size)
     return ((char *) -1);
 }
 
-int
+static int
 sis_memory_write(addr, data, length)
     uint32               addr;
     const unsigned char *data;
@@ -1878,7 +1865,7 @@ sis_memory_write(addr, data, length)
     return (length);
 }
 
-int
+static int
 sis_memory_read(addr, data, length)
     uint32          addr;
     char           *data;
@@ -1908,3 +1895,18 @@ boot_init ()
     sregs.r[14] = sregs.r[30] - 96*4;
     mec_mcr |= 1;		/* power-down enabled */
 }
+
+struct memsys erc32sys = {
+    init_sim,
+    reset,
+    error_mode,
+    sim_halt,
+    exit_sim,
+    init_stdio,
+    restore_stdio,
+    memory_iread,
+    memory_read,
+    memory_write,
+    sis_memory_write,
+    sis_memory_read
+};
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index 237bb53..65e10bf 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -1244,9 +1244,9 @@ dispatch_instruction(sregs)
 		else
 		    rdd = &(sregs->g[rd]);
 	    }
-	    mexc = memory_read(asi, address, ddata, 2, &ws);
+	    mexc = ms->memory_read(asi, address, ddata, 2, &ws);
 	    sregs->hold += ws;
-	    mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws);
+	    mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDD;
 	    if (mexc) {
@@ -1267,7 +1267,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1278,7 +1278,7 @@ dispatch_instruction(sregs)
 	case LDSTUBA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
 	case LDSTUB:
-	    mexc = memory_read(asi, address, &data, 0, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 0, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDST;
 	    if (mexc) {
@@ -1288,7 +1288,7 @@ dispatch_instruction(sregs)
 	    data = extract_byte(data, address);
 	    *rdd = data;
 	    data = 0x0ff;
-	    mexc = memory_write(asi, address, &data, 0, &ws);
+	    mexc = ms->memory_write(asi, address, &data, 0, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1302,7 +1302,7 @@ dispatch_instruction(sregs)
 	    if (!chk_asi(sregs, &asi, op3)) break;
 	case LDSB:
 	case LDUB:
-	    mexc = memory_read(asi, address, &data, 0, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 0, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1323,7 +1323,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = memory_read(asi, address, &data, 1, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 1, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1349,7 +1349,7 @@ dispatch_instruction(sregs)
 		    (sregs->frs2 == rd))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    sregs->flrd = rd;
 	    sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
@@ -1375,9 +1375,9 @@ dispatch_instruction(sregs)
 		    ((sregs->frs2 >> 1) == (rd >> 1)))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = memory_read(asi, address, ddata, 2, &ws);
+	    mexc = ms->memory_read(asi, address, ddata, 2, &ws);
 	    sregs->hold += ws;
-	    mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws);
+	    mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDD;
 	    if (mexc) {
@@ -1406,7 +1406,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1428,7 +1428,7 @@ dispatch_instruction(sregs)
 	    if (ebase.simtime < sregs->ftime) {
 		sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = memory_write(asi, address, &sregs->fsr, 2, &ws);
+	    mexc = ms->memory_write(asi, address, &sregs->fsr, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1442,7 +1442,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = memory_write(asi, address, rdd, 2, &ws);
+	    mexc = ms->memory_write(asi, address, rdd, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1451,7 +1451,7 @@ dispatch_instruction(sregs)
 	case STBA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
 	case STB:
-	    mexc = memory_write(asi, address, rdd, 0, &ws);
+	    mexc = ms->memory_write(asi, address, rdd, 0, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1471,7 +1471,7 @@ dispatch_instruction(sregs)
 		else
 		    rdd = &(sregs->g[rd]);
 	    }
-	    mexc = memory_write(asi, address, rdd, 3, &ws);
+	    mexc = ms->memory_write(asi, address, rdd, 3, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_STD;
 #ifdef STAT
@@ -1500,7 +1500,7 @@ dispatch_instruction(sregs)
 		break;
 	    }
 	    rdd = &(sregs->fpq[0]);
-	    mexc = memory_write(asi, address, rdd, 3, &ws);
+	    mexc = ms->memory_write(asi, address, rdd, 3, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_STD;
 #ifdef STAT
@@ -1521,7 +1521,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = memory_write(asi, address, rdd, 1, &ws);
+	    mexc = ms->memory_write(asi, address, rdd, 1, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1540,7 +1540,7 @@ dispatch_instruction(sregs)
 		if (sregs->frd == rd)
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = memory_write(asi, address, &sregs->fsi[rd], 2, &ws);
+	    mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1560,7 +1560,7 @@ dispatch_instruction(sregs)
 		if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = memory_write(asi, address, &sregs->fsi[rd], 3, &ws);
+	    mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 3, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_STD;
 #ifdef STAT
@@ -1577,13 +1577,13 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
 		break;
 	    }
-	    mexc = memory_write(asi, address, rdd, 2, &ws);
+	    mexc = ms->memory_write(asi, address, rdd, 2, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDST;
 	    if (mexc) {
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index 32e2c46..a92a3e6 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -32,7 +32,11 @@
 
 #define	VAL(x)	strtoul(x,(char **)NULL,0)
 
-extern int	current_target_byte_order;
+/* The target's byte order is big-endian by default until we load a
+   little-endian program.  */
+int	current_target_byte_order = BIG_ENDIAN;
+
+int dumbio = 0; /* normal, smart, terminal oriented IO by default */
 struct disassemble_info dinfo;
 struct pstate   sregs;
 extern struct estate ebase;
@@ -53,6 +57,7 @@ extern	int	ext_irl;
 uint32		last_load_addr = 0;
 int		nouartrx = 0;
 host_callback 	*sim_callback;
+struct memsys *ms = &erc32sys;
 
 #ifdef ERRINJ
 uint32		errcnt = 0;
@@ -428,7 +433,7 @@ exec_cmd(sregs, cmd)
 		stat = run_sim(sregs, VAL(cmd1), 0);
 	    }
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "debug", clen) == 0) {
 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
 		sis_verbose = VAL(cmd1);
@@ -478,7 +483,7 @@ exec_cmd(sregs, cmd)
 		stat = run_sim(sregs, UINT64_MAX, 0);
 	    }
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "help", clen) == 0) {
 	    gen_help();
 	} else if (strncmp(cmd1, "history", clen) == 0) {
@@ -552,7 +557,7 @@ exec_cmd(sregs, cmd)
 		stat = run_sim(sregs, VAL(cmd1), 0);
 	    }
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "shell", clen) == 0) {
 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
 		tmp = system(&cmdsave[clen]);
@@ -560,12 +565,12 @@ exec_cmd(sregs, cmd)
 	} else if (strncmp(cmd1, "step", clen) == 0) {
 	    stat = run_sim(sregs, 1, 1);
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "tcont", clen) == 0) {
 	    sregs->tlimit = limcalc(sregs->freq);
 	    stat = run_sim(sregs, UINT64_MAX, 0);
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "tgo", clen) == 0) {
 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
 		len = last_load_addr;
@@ -578,7 +583,7 @@ exec_cmd(sregs, cmd)
 	    printf("resuming at 0x%08x\n",sregs->pc);
 	    stat = run_sim(sregs, UINT64_MAX, 0);
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "tlimit", clen) == 0) {
 	   sregs->tlimit = limcalc(sregs->freq);
 	   if (sregs->tlimit != (uint32) -1)
@@ -592,7 +597,7 @@ exec_cmd(sregs, cmd)
 	    }
 	    printf("\n");
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else if (strncmp(cmd1, "trun", clen) == 0) {
 	    ebase.simtime = 0;
 	    reset_all();
@@ -600,7 +605,7 @@ exec_cmd(sregs, cmd)
 	    sregs->tlimit = limcalc(sregs->freq);
 	    stat = run_sim(sregs, UINT64_MAX, 0);
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt();
 	} else
 	    printf("syntax error\n");
     }
@@ -766,7 +771,7 @@ static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info)
 {
     unsigned char           i[4];
 
-    sis_memory_read(addr, i, 4);
+    ms->sis_memory_read(addr, i, 4);
     dinfo.buffer_vma = addr;
     dinfo.buffer_length = 4;
     dinfo.buffer = i;
@@ -782,10 +787,10 @@ disp_ctrl(sregs)
 
     printf("\n psr: %08X   wim: %08X   tbr: %08X   y: %08X\n",
 	   sregs->psr, sregs->wim, sregs->tbr, sregs->y);
-    sis_memory_read(sregs->pc, (char *) &i, 4);
+    ms->sis_memory_read(sregs->pc, (char *) &i, 4);
     printf("\n  pc: %08X = %08X    ", sregs->pc, i);
     print_insn_sparc_sis(sregs->pc, &dinfo);
-    sis_memory_read(sregs->npc, (char *) &i, 4);
+    ms->sis_memory_read(sregs->npc, (char *) &i, 4);
     printf("\n npc: %08X = %08X    ", sregs->npc, i);
     print_insn_sparc_sis(sregs->npc, &dinfo);
     if (sregs->err_mode)
@@ -814,7 +819,7 @@ disp_mem(addr, len)
     for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
 	printf("\n %8X  ", i);
 	for (j = 0; j < 4; j++) {
-	    sis_memory_read((i + (j * 4)), data, 4);
+	    ms->sis_memory_read((i + (j * 4)), data, 4);
 	    printf("%08x  ", *wdata);
 	    mem[j] = *((int *) &data);
 	}
@@ -841,7 +846,7 @@ dis_mem(addr, len, info)
     uint32          *wdata = (uint32 *) data;
 
     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
-	sis_memory_read(i, data, 4);
+	ms->sis_memory_read(i, data, 4);
 	printf(" %08x  %08x  ", i, *wdata);
 	print_insn_sparc_sis(i, info);
         if (i >= 0xfffffffc) break;
@@ -1005,7 +1010,7 @@ reset_all()
 {
     init_event();		/* Clear event queue */
     init_regs(&sregs);
-    reset();
+    ms->reset();
 #ifdef ERRINJ
     errinjstart();
 #endif
@@ -1126,7 +1131,7 @@ bfd_load(fname)
 #ifdef HOST_LITTLE_ENDIAN
 		    for (i=0;i<count/4;i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
 #endif
-		    sis_memory_write(section_address, buffer, count);
+		    ms->sis_memory_write(section_address, buffer, count);
 
 		    section_address += count;
 		    fptr += count;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 31071bd..612aded 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -37,17 +37,13 @@
 #define PSR_CWP 0x7
 
 extern struct disassemble_info dinfo;
-extern struct pstate sregs;
 extern struct estate ebase;
 
-extern int	current_target_byte_order;
-extern int      ctrl_c;
 extern int      nfp;
 extern int      ift;
 extern int      rom8;
 extern int      wrp;
 extern int      uben;
-extern int      sis_verbose;
 extern char    *sis_version;
 extern struct estate ebase;
 extern struct evcell evbuf[];
@@ -72,7 +68,7 @@ run_sim(sregs, icount, dis)
     if (sis_verbose)
 	(*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
 					  sregs->pc);
-   init_stdio();
+   ms->init_stdio();
    sregs->starttime = get_time();
    irq = 0;
    if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
@@ -92,7 +88,7 @@ run_sim(sregs, icount, dis)
             if (sregs->pc == 0 || sregs->npc == 0)
                 printf ("bogus pc or npc\n");
 #endif
-        mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
+        mexc = ms->memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
 #if 0	/* DELETE ME! for debugging purposes only */
         if (sis_verbose > 2)
             printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
@@ -118,8 +114,8 @@ run_sim(sregs, icount, dis)
 			if (sis_verbose)
 			    (*sim_callback->printf_filtered) (sim_callback,
 							      "SW BP hit at %x\n", sregs->pc);
-                        sim_halt();
-			restore_stdio();
+                        ms->sim_halt();
+			ms->restore_stdio();
 			clearerr(stdin);
 			return (BPT_HIT);
 		    } else
@@ -137,12 +133,12 @@ run_sim(sregs, icount, dis)
 	    icount = 0;
 	}
     }
-    sim_halt();
+    ms->sim_halt();
     sregs->tottime += get_time() - sregs->starttime;
-    restore_stdio();
+    ms->restore_stdio();
     clearerr(stdin);
     if (sregs->err_mode)
-	error_mode(sregs->pc);
+	ms->error_mode(sregs->pc);
     if (sregs->err_mode)
 	return (ERROR);
     if (sregs->bphit) {
@@ -272,7 +268,7 @@ sim_open (kind, callback, abfd, argv)
 #endif
     reset_all();
     ebase.simtime = 0;
-    init_sim();
+    ms->init_sim();
     init_bpt(&sregs);
     reset_stat(&sregs);
 
@@ -286,7 +282,7 @@ sim_close(sd, quitting)
      int quitting;
 {
 
-    exit_sim();
+    ms->exit_sim();
     fcntl(0, F_SETFL, termsave);
 
 };
@@ -368,9 +364,9 @@ sim_write(sd, mem, buf, length)
       for (i=0; i<length; i+=4) {
         ibuf[i] = ntohl(ibufp[i]);
       }
-    return (sis_memory_write(mem, (char *) ibuf, length));
+    return (ms->sis_memory_write(mem, (char *) ibuf, length));
 #else
-    return (sis_memory_write(mem, buf, length));
+    return (ms->sis_memory_write(mem, buf, length));
 #endif
 }
 
@@ -385,7 +381,7 @@ sim_read(sd, mem, buf, length)
     int *ibuf = (int *) buf;
     int i, len;
 
-    len = sis_memory_read(mem, buf, length);
+    len = ms->sis_memory_read(mem, buf, length);
     if (length >= 4)
       for (i=0; i<length; i+=4) {
         *ibuf = htonl(*ibuf);
@@ -393,7 +389,7 @@ sim_read(sd, mem, buf, length)
       }
     return (len);
 #else
-    return (sis_memory_read(mem, buf, length));
+    return (ms->sis_memory_read(mem, buf, length));
 #endif
 }
 
@@ -480,7 +476,7 @@ flush_windows ()
 #endif
 
       for (i = 0; i < 16; i++)
-	memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
+	ms->memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
 		      &ws);
 
       if (win == cwp)
@@ -519,6 +515,13 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
   return NULL;
 }
 
+int
+sim_stop(SIM_DESC sd)
+{
+  ctrl_c = 1;
+  return 1;
+}
+
 #if 0 /* FIXME: These shouldn't exist.  */
 
 int
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index d737216..2b0871a 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -51,16 +51,13 @@ extern HIST_ENTRY *remove_history (int which);
 #define HIST_LEN	64
 
 extern struct disassemble_info dinfo;
-extern struct pstate sregs;
 extern struct estate ebase;
 
-extern int      ctrl_c;
 extern int      nfp;
 extern int      ift;
 extern int      wrp;
 extern int      rom8;
 extern int      uben;
-extern int      sis_verbose;
 extern char    *sis_version;
 extern struct estate ebase;
 extern struct evcell evbuf[];
@@ -86,13 +83,13 @@ run_sim(sregs, icount, dis)
     int             irq, mexc, deb;
 
     sregs->starttime = get_time();
-    init_stdio();
+    ms->init_stdio();
     if (sregs->err_mode) icount = 0;
     deb = dis || sregs->histlen || sregs->bptnum;
     irq = 0;
     while (icount > 0) {
 
-	mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
+	mexc = ms->memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
 	sregs->icnt = 1;
 	if (sregs->annul) {
 	    sregs->annul = 0;
@@ -107,7 +104,7 @@ run_sim(sregs, icount, dis)
 		} else {
 		    if (deb) {
 	    		if ((sregs->bphit = check_bpt(sregs)) != 0) {
-            		    restore_stdio();
+            		    ms->restore_stdio();
 	    		    return (BPT_HIT);
 	    		}
 		        if (sregs->histlen) {
@@ -130,7 +127,7 @@ run_sim(sregs, icount, dis)
 		irq = 0;
 		sregs->err_mode = execute_trap(sregs);
         	if (sregs->err_mode) {
-	            error_mode(sregs->pc);
+	            ms->error_mode(sregs->pc);
 	            icount = 0;
 	        }
 	    }
@@ -142,7 +139,7 @@ run_sim(sregs, icount, dis)
 	}
     }
     sregs->tottime += get_time() - sregs->starttime;
-    restore_stdio();
+    ms->restore_stdio();
     if (sregs->err_mode)
 	return (ERROR);
     if (ctrl_c) {
@@ -247,7 +244,7 @@ main(argc, argv)
     ebase.simtime = 0;
     reset_all();
     init_bpt(&sregs);
-    init_sim();
+    ms->init_sim();
     if (lfile) last_load_addr = bfd_load(argv[lfile]);
 #ifdef STAT
     reset_stat(&sregs);
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 1e41d2a..8f0a9c1 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -163,25 +163,12 @@ struct irqcell {
 /* Prototypes  */
 
 /* erc32.c */
-extern void	init_sim ();
-extern void	reset (void);
-extern void	error_mode (uint32 pc);
-extern void	sim_halt (void);
-extern void	exit_sim (void);
-extern void	init_stdio (void);
-extern void	restore_stdio (void);
-extern int	memory_iread (uint32 addr, uint32 *data, int32 *ws);
-extern int	memory_read (int32 asi, uint32 addr, uint32 *data,
-			     int32 sz, int32 *ws);
-extern int	memory_write (int32 asi, uint32 addr, uint32 *data,
-			      int32 sz, int32 *ws);
-extern int	sis_memory_write (uint32 addr,
-				  const unsigned char *data, uint32 length);
-extern int	sis_memory_read (uint32 addr, char *data,
-				 uint32 length);
+extern struct memsys erc32sys;
 
 /* func.c */
-extern struct pstate  sregs;
+extern struct   pstate  sregs;
+extern int      ctrl_c;
+extern int      sis_verbose;
 extern void	set_regi (struct pstate *sregs, int32 reg,
 			  uint32 rval);
 extern void	get_regi (struct pstate *sregs, int32 reg, char *buf);
@@ -205,7 +192,9 @@ extern void	sys_reset (void);
 extern void	sys_halt (void);
 extern double	get_time (void);
 extern int	nouartrx;
-extern host_callback *sim_callback;
+extern          host_callback *sim_callback;
+extern int	current_target_byte_order;
+extern int      dumbio;
 
 /* exec.c */
 extern int	dispatch_instruction (struct pstate *sregs);
@@ -225,3 +214,24 @@ extern void	set_fsr (uint32 fsr);
 /* help.c */
 extern void	usage (void);
 extern void	gen_help (void);
+
+struct memsys {
+    void	(*init_sim) ();
+    void	(*reset) (void);
+    void	(*error_mode) (uint32 pc);
+    void	(*sim_halt) (void);
+    void	(*exit_sim) (void);
+    void	(*init_stdio) (void);
+    void	(*restore_stdio) (void);
+    int	        (*memory_iread) (uint32 addr, uint32 *data, int32 *ws);
+    int	        (*memory_read) (int32 asi, uint32 addr, uint32 *data,
+			     int32 sz, int32 *ws);
+    int	        (*memory_write) (int32 asi, uint32 addr, uint32 *data,
+			      int32 sz, int32 *ws);
+    int	        (*sis_memory_write) (uint32 addr,
+				  const unsigned char *data, uint32 length);
+    int	        (*sis_memory_read) (uint32 addr, char *data,
+				 uint32 length);
+};
+
+extern struct memsys *ms;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 05/23] sim/erc32: remove unused defines in Makefile and switch off statistics
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (3 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17 11:04   ` Mike Frysinger
  2015-02-17  7:45 ` [PATCH 15/23] sim/erc32: access memory subsystem through struct memsys to allow multiple configurations Jiri Gaisler
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* Makefile.in Remove unused defines
---
 sim/erc32/Makefile.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
index 0ce58a6..52291b3 100644
--- a/sim/erc32/Makefile.in
+++ b/sim/erc32/Makefile.in
@@ -30,7 +30,7 @@ SIM_EXTRA_CLEAN = clean-sis
 # UARTS run at about 115200 baud (simulator time). Add -DFAST_UART to
 # CFLAGS if faster (infinite) UART speed is desired. Might affect the
 # behaviour of UART interrupt routines ...
-SIM_EXTRA_CFLAGS = -DSTAT -DFAST_UART -DIUREV0 -DMECREV0
+SIM_EXTRA_CFLAGS = -DFAST_UART
 
 ## COMMON_POST_CONFIG_FRAG
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 10/23] sim/erc32: Switched emulated memory to host endian order.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (5 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 15/23] sim/erc32: access memory subsystem through struct memsys to allow multiple configurations Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 07/23] sim/erc32: file loading via command line did not work Jiri Gaisler
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Change data ordering in emulated memory from target order (big endian)
	to host order. Improves performance and simplifies most memory
	operations. Requires some byte twisting during stores on little
	endian hosts (intel).

	* erc32.c (fetch_bytes) Remove. (store_bytes) Remove byte twisting.
	(memory_read) Access memory directly. (extract_short,
	extract_short_signed, extract_byte, extract_byte_signed) New
	function for for sub-word LD instructions.

	* func.c (disp_ctrl, dis_mem) Ajust print-out to new data endian.

	* interf.c (sim_open) Convert endian when gdb writes to memory.
---
 sim/erc32/erc32.c  | 167 ++++++++++++-----------------------------------------
 sim/erc32/exec.c   |  58 ++++++++++++++++---
 sim/erc32/func.c   |  33 +++++++----
 sim/erc32/interf.c |  29 ++++++++++
 sim/erc32/sis.c    |   4 ++
 5 files changed, 142 insertions(+), 149 deletions(-)

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 4fa8f61..152eb1e 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -297,11 +297,8 @@ static void	gpt_reload_set (uint32 val);
 static void	timer_ctrl (uint32 val);
 static unsigned char *
 		get_mem_ptr (uint32 addr, uint32 size);
-
-static void	fetch_bytes (int asi, unsigned char *mem,
-			     uint32 *data, int sz);
-
-static void	store_bytes (unsigned char *mem, uint32 *data, int sz);
+static void	store_bytes (unsigned char *mem, uint32 waddr,
+			uint32 *data, int sz, int32 *ws);
 
 extern int	ext_irl;
 
@@ -1525,123 +1522,44 @@ timer_ctrl(val)
 	gpt_start();
 }
 
-
-/* Retrieve data from target memory.  MEM points to location from which
-   to read the data; DATA points to words where retrieved data will be
-   stored in host byte order.  SZ contains log(2) of the number of bytes
-   to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word),
-   or 3 (two words). */
+/* Store data in host byte order.  MEM points to the beginning of the
+   emulated memory; WADDR contains the index the emulated memory,
+   DATA points to words in host byte order to be stored.  SZ contains log(2)
+   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
+   2 (one word), or 3 (two words); WS should return the number of wait-states. */
 
 static void
-fetch_bytes (asi, mem, data, sz)
-    int		    asi;
+store_bytes (mem, waddr, data, sz, ws)
     unsigned char  *mem;
+    uint32	   waddr;
     uint32	   *data;
-    int		    sz;
+    int32	    sz;
+    int32	   *ws;
 {
-    if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
-	|| asi == 8 || asi == 9) {
-	switch (sz) {
-	case 3:
-	    data[1] =  (((uint32) mem[7]) & 0xff) |
-		      ((((uint32) mem[6]) & 0xff) <<  8) |
-		      ((((uint32) mem[5]) & 0xff) << 16) |
-		      ((((uint32) mem[4]) & 0xff) << 24);
-	    /* Fall through to 2 */
-	case 2:
-	    data[0] =  (((uint32) mem[3]) & 0xff) |
-		      ((((uint32) mem[2]) & 0xff) <<  8) |
-		      ((((uint32) mem[1]) & 0xff) << 16) |
-		      ((((uint32) mem[0]) & 0xff) << 24);
-	    break;
-	case 1:
-	    data[0] =  (((uint32) mem[1]) & 0xff) |
-		      ((((uint32) mem[0]) & 0xff) << 8);
-	    break;
+    switch (sz) {
 	case 0:
-	    data[0] = mem[0] & 0xff;
-	    break;
-	    
-	}
-    } else {
-	switch (sz) {
-	case 3:
-	    data[1] = ((((uint32) mem[7]) & 0xff) << 24) |
-		      ((((uint32) mem[6]) & 0xff) << 16) |
-		      ((((uint32) mem[5]) & 0xff) <<  8) |
-		       (((uint32) mem[4]) & 0xff);
-	    /* Fall through to 4 */
-	case 2:
-	    data[0] = ((((uint32) mem[3]) & 0xff) << 24) |
-		      ((((uint32) mem[2]) & 0xff) << 16) |
-		      ((((uint32) mem[1]) & 0xff) <<  8) |
-		       (((uint32) mem[0]) & 0xff);
+#ifdef HOST_LITTLE_ENDIAN
+	    waddr ^= 3;
+#endif
+	    mem[waddr] = *data & 0x0ff;
+	    *ws = mem_ramw_ws + 3;
 	    break;
 	case 1:
-	    data[0] = ((((uint32) mem[1]) & 0xff) <<  8) |
-		       (((uint32) mem[0]) & 0xff);
-	    break;
-	case 0:
-	    data[0] = mem[0] & 0xff;
+#ifdef HOST_LITTLE_ENDIAN
+	    waddr ^= 2;
+#endif
+	    *((unsigned short *) &(mem[waddr])) = *data & 0x0ffff;
+	    *ws = mem_ramw_ws + 3;
 	    break;
-	}
-    }
-}
-
-
-/* Store data in target byte order.  MEM points to location to store data;
-   DATA points to words in host byte order to be stored.  SZ contains log(2)
-   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
-   2 (one word), or 3 (two words). */
-
-static void
-store_bytes (mem, data, sz)
-    unsigned char  *mem;
-    uint32	   *data;
-    int		    sz;
-{
-    if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) {
-	switch (sz) {
-	case 3:
-	    mem[7] = (data[1] >> 24) & 0xff;
-	    mem[6] = (data[1] >> 16) & 0xff;
-	    mem[5] = (data[1] >>  8) & 0xff;
-	    mem[4] = data[1] & 0xff;
-	    /* Fall through to 2 */
 	case 2:
-	    mem[3] = (data[0] >> 24) & 0xff;
-	    mem[2] = (data[0] >> 16) & 0xff;
-	    /* Fall through to 1 */
-	case 1:
-	    mem[1] = (data[0] >>  8) & 0xff;
-	    /* Fall through to 0 */
-	case 0:
-	    mem[0] = data[0] & 0xff;
+	    *((uint32 *) &(mem[waddr])) = *data;
+	    *ws = mem_ramw_ws;
 	    break;
-	}
-    } else {
-	switch (sz) {
 	case 3:
-	    mem[7] = data[1] & 0xff;
-	    mem[6] = (data[1] >>  8) & 0xff;
-	    mem[5] = (data[1] >> 16) & 0xff;
-	    mem[4] = (data[1] >> 24) & 0xff;
-	    /* Fall through to 2 */
-	case 2:
-	    mem[3] = data[0] & 0xff;
-	    mem[2] = (data[0] >>  8) & 0xff;
-	    mem[1] = (data[0] >> 16) & 0xff;
-	    mem[0] = (data[0] >> 24) & 0xff;
-	    break;
-	case 1:
-	    mem[1] = data[0] & 0xff;
-	    mem[0] = (data[0] >> 8) & 0xff;
-	    break;
-	case 0:
-	    mem[0] = data[0] & 0xff;
+	    *((uint32 *) &(mem[waddr])) = data[0];
+	    *((uint32 *) &(mem[waddr + 4])) = data[1];
+	    *ws = 2 * mem_ramw_ws + STD_WS;
 	    break;
-	    
-	}
     }
 }
 
@@ -1671,7 +1589,7 @@ memory_read(asi, addr, data, sz, ws)
 #endif
 
     if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
-	fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz);
+        *data = *((uint32 *) & (ramb[addr & mem_rammask & ~3]));
 	*ws = mem_ramr_ws;
 	return (0);
     } else if ((addr >= MEC_START) && (addr < MEC_END)) {
@@ -1689,7 +1607,7 @@ memory_read(asi, addr, data, sz, ws)
     } else if (era) {
     	if ((addr < 0x100000) || 
 	    ((addr>= 0x80000000) && (addr < 0x80100000))) {
-	    fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz);
+            *data = *((uint32 *) & (romb[addr & ROM_MASK & ~3]));
 	    *ws = 4;
 	    return (0);
 	} else if ((addr >= 0x10000000) && 
@@ -1700,13 +1618,13 @@ memory_read(asi, addr, data, sz, ws)
 	}
 	
     } else  if (addr < mem_romsz) {
-	    fetch_bytes (asi, &romb[addr], data, sz);
+            *data = *((uint32 *) & (romb[addr & ~3]));
 	    *ws = mem_romr_ws;
 	    return (0);
 
 #else
     } else if (addr < mem_romsz) {
-	fetch_bytes (asi, &romb[addr], data, sz);
+        *data = *((uint32 *) & (romb[addr & ~3]));
 	*ws = mem_romr_ws;
 	return (0);
 #endif
@@ -1769,21 +1687,10 @@ memory_write(asi, addr, data, sz, ws)
 	    }
 	}
 
-	store_bytes (&ramb[addr & mem_rammask], data, sz);
-
-	switch (sz) {
-	case 0:
-	case 1:
-	    *ws = mem_ramw_ws + 3;
-	    break;
-	case 2:
-	    *ws = mem_ramw_ws;
-	    break;
-	case 3:
-	    *ws = 2 * mem_ramw_ws + STD_WS;
-	    break;
-	}
+	waddr = addr & mem_rammask;
+	store_bytes (ramb, waddr, data, sz, ws);
 	return (0);
+
     } else if ((addr >= MEC_START) && (addr < MEC_END)) {
 	if ((sz != 2) || (asi != 0xb)) {
 	    set_sfsr(MEC_ACC, addr, asi, 0);
@@ -1806,7 +1713,7 @@ memory_write(asi, addr, data, sz, ws)
 	((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) {
 	    addr &= ROM_MASK;
 	    *ws = sz == 3 ? 8 : 4;
-	    store_bytes (&romb[addr], data, sz);
+	    store_bytes (romb, addr, data, sz, ws);
             return (0);
 	} else if ((addr >= 0x10000000) && 
 		   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
@@ -1822,7 +1729,7 @@ memory_write(asi, addr, data, sz, ws)
 	*ws = mem_romw_ws + 1;
 	if (sz == 3)
 	    *ws += mem_romw_ws + STD_WS;
-	store_bytes (&romb[addr], data, sz);
+	store_bytes (romb, addr, data, sz, ws);
         return (0);
 
 #else
@@ -1833,7 +1740,7 @@ memory_write(asi, addr, data, sz, ws)
 	*ws = mem_romw_ws + 1;
 	if (sz == 3)
             *ws += mem_romw_ws + STD_WS;
-	store_bytes (&romb[addr], data, sz);
+	store_bytes (romb, addr, data, sz, ws);
         return (0);
 
 #endif
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index 07f3586..e80e02a 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -371,6 +371,36 @@ div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned)
 }
 
 
+static int
+extract_short(uint32 data, uint32 address)
+{
+    return((data>>((2 - (address & 2))*8)) & 0xffff);
+}
+
+static int
+extract_short_signed(uint32 data, uint32 address)
+{
+    uint32 tmp;
+    tmp = ((data>>((2 - (address & 2))*8)) & 0xffff);
+    if (tmp & 0x8000) tmp |= 0xffff0000;
+    return(tmp);
+}
+
+static int
+extract_byte(uint32 data, uint32 address)
+{
+    return((data>>((3 - (address & 3))*8)) & 0xff);
+}
+
+static int
+extract_byte_signed(uint32 data, uint32 address)
+{
+    uint32 tmp;
+    tmp = ((data>>((3 - (address & 3))*8)) & 0xff);
+    if (tmp & 0x80) tmp |= 0xffffff00;
+    return(tmp);
+}
+
 int
 dispatch_instruction(sregs)
     struct pstate  *sregs;
@@ -1078,7 +1108,8 @@ dispatch_instruction(sregs)
 		    sregs->trap = TRAP_PRIVI;
 		    break;
 		}
-		sregs->psr = (rs1 ^ operand2) & 0x00f03fff;
+		sregs->psr = (sregs->psr & 0xff000000) |
+			(rs1 ^ operand2) & 0x00f03fff;
 		break;
 	    case WRWIM:
 		if (!(sregs->psr & PSR_S)) {
@@ -1214,8 +1245,10 @@ dispatch_instruction(sregs)
 		else
 		    rdd = &(sregs->g[rd]);
 	    }
-	    mexc = memory_read(asi, address, ddata, 3, &ws);
-	    sregs->hold += ws * 2;
+	    mexc = memory_read(asi, address, ddata, 2, &ws);
+	    sregs->hold += ws;
+	    mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws);
+	    sregs->hold += ws;
 	    sregs->icnt = T_LDD;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1253,6 +1286,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_DEXC;
 		break;
 	    }
+	    data = extract_byte(data, address);
 	    *rdd = data;
 	    data = 0x0ff;
 	    mexc = memory_write(asi, address, &data, 0, &ws);
@@ -1275,8 +1309,10 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_DEXC;
 		break;
 	    }
-	    if ((op3 == LDSB) && (data & 0x80))
-		data |= 0xffffff00;
+	    if (op3 == LDSB)
+	        data = extract_byte_signed(data, address);
+	    else
+	        data = extract_byte(data, address);
 	    *rdd = data;
 	    break;
 	case LDSHA:
@@ -1294,8 +1330,10 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_DEXC;
 		break;
 	    }
-	    if ((op3 == LDSH) && (data & 0x8000))
-		data |= 0xffff0000;
+	    if (op3 == LDSH)
+	        data = extract_short_signed(data, address);
+	    else
+	        data = extract_short(data, address);
 	    *rdd = data;
 	    break;
 	case LDF:
@@ -1338,8 +1376,10 @@ dispatch_instruction(sregs)
 		    ((sregs->frs2 >> 1) == (rd >> 1)))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = memory_read(asi, address, ddata, 3, &ws);
-	    sregs->hold += ws * 2;
+	    mexc = memory_read(asi, address, ddata, 2, &ws);
+	    sregs->hold += ws;
+	    mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws);
+	    sregs->hold += ws;
 	    sregs->icnt = T_LDD;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index a3da1c5..25ecd14 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -777,15 +777,15 @@ disp_ctrl(sregs)
     struct pstate  *sregs;
 {
 
-    unsigned char           i[4];
+    uint32           i;
 
     printf("\n psr: %08X   wim: %08X   tbr: %08X   y: %08X\n",
 	   sregs->psr, sregs->wim, sregs->tbr, sregs->y);
-    sis_memory_read(sregs->pc, i, 4);
-    printf("\n  pc: %08X = %02X%02X%02X%02X    ", sregs->pc,i[0],i[1],i[2],i[3]);
+    sis_memory_read(sregs->pc, (char *) &i, 4);
+    printf("\n  pc: %08X = %08X    ", sregs->pc, i);
     print_insn_sparc_sis(sregs->pc, &dinfo);
-    sis_memory_read(sregs->npc, i, 4);
-    printf("\n npc: %08X = %02X%02X%02X%02X    ",sregs->npc,i[0],i[1],i[2],i[3]);
+    sis_memory_read(sregs->npc, (char *) &i, 4);
+    printf("\n npc: %08X = %08X    ", sregs->npc, i);
     print_insn_sparc_sis(sregs->npc, &dinfo);
     if (sregs->err_mode)
 	printf("\n IU in error mode");
@@ -800,21 +800,28 @@ disp_mem(addr, len)
 
     uint32          i;
     unsigned char   data[4];
+    uint32          *wdata = (uint32 *) data;
     uint32          mem[4], j;
     char           *p;
+    int		   end;
 
+#ifdef HOST_LITTLE_ENDIAN
+    end = 3;
+#else
+    end = 0;
+#endif
     for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
 	printf("\n %8X  ", i);
 	for (j = 0; j < 4; j++) {
 	    sis_memory_read((i + (j * 4)), data, 4);
-	    printf("%02x%02x%02x%02x  ", data[0],data[1],data[2],data[3]);
+	    printf("%08x  ", *wdata);
 	    mem[j] = *((int *) &data);
 	}
 	printf("  ");
 	p = (char *) mem;
 	for (j = 0; j < 16; j++) {
-	    if (isprint(p[j]))
-		putchar(p[j]);
+	    if (isprint(p[j^end]))
+		putchar(p[j^end]);
 	    else
 		putchar('.');
 	}
@@ -830,10 +837,11 @@ dis_mem(addr, len, info)
 {
     uint32          i;
     unsigned char   data[4];
+    uint32          *wdata = (uint32 *) data;
 
     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
 	sis_memory_read(i, data, 4);
-	printf(" %08x  %02x%02x%02x%02x  ", i, data[0],data[1],data[2],data[3]);
+	printf(" %08x  %08x  ", i, *wdata);
 	print_insn_sparc_sis(i, info);
         if (i >= 0xfffffffc) break;
 	printf("\n");
@@ -1032,6 +1040,7 @@ bfd_load(fname)
     asection       *section;
     bfd            *pbfd;
     const bfd_arch_info_type *arch;
+    int            i;
 
     pbfd = bfd_openr(fname, 0);
 
@@ -1105,13 +1114,17 @@ bfd_load(fname)
 		fptr = 0;
 
 		while (section_size > 0) {
-		    char            buffer[1024];
 		    int             count;
+		    char            buffer[1024];
+		    uint32          *wbuffer = (uint32 *) buffer;
 
 		    count = min(section_size, 1024);
 
 		    bfd_get_section_contents(pbfd, section, buffer, fptr, count);
 
+#ifdef HOST_LITTLE_ENDIAN
+		    for (i=0;i<count/4;i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
+#endif
 		    sis_memory_write(section_address, buffer, count);
 
 		    section_address += count;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 38a2a0d..3a72e7f 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -265,7 +265,11 @@ sim_open (kind, callback, abfd, argv)
     sregs.freq = freq ? freq : 15;
     termsave = fcntl(0, F_GETFL, 0);
     INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
+#ifdef HOST_LITTLE_ENDIAN
+    dinfo.endian = BFD_ENDIAN_LITTLE;
+#else
     dinfo.endian = BFD_ENDIAN_BIG;
+#endif
     reset_all();
     ebase.simtime = 0;
     init_sim();
@@ -355,7 +359,19 @@ sim_write(sd, mem, buf, length)
     const unsigned char  *buf;
     int             length;
 {
+#ifdef HOST_LITTLE_ENDIAN
+    int *ibufp = (int *) buf;
+    int ibuf[8192];
+    int i, len;
+
+    if (length >= 4)
+      for (i=0; i<length; i+=4) {
+        ibuf[i] = ntohl(ibufp[i]);
+      }
+    return (sis_memory_write(mem, (char *) ibuf, length));
+#else
     return (sis_memory_write(mem, buf, length));
+#endif
 }
 
 int
@@ -365,7 +381,20 @@ sim_read(sd, mem, buf, length)
      unsigned char *buf;
      int length;
 {
+#ifdef HOST_LITTLE_ENDIAN
+    int *ibuf = (int *) buf;
+    int i, len;
+
+    len = sis_memory_read(mem, buf, length);
+    if (length >= 4)
+      for (i=0; i<length; i+=4) {
+        *ibuf = htonl(*ibuf);
+        ibuf++;
+      }
+    return (len);
+#else
     return (sis_memory_read(mem, buf, length));
+#endif
 }
 
 void
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index 97f1b31..c6e9714 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -237,7 +237,11 @@ main(argc, argv)
     sregs.freq = freq;
 
     INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
+#ifdef HOST_LITTLE_ENDIAN
+    dinfo.endian = BFD_ENDIAN_LITTLE;
+#else
     dinfo.endian = BFD_ENDIAN_BIG;
+#endif
 
     termsave = fcntl(0, F_GETFL, 0);
     using_history();
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 02/23] sim/erc32: corrected wrong CPU implementation and version ID in %psr
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 16/23] sim/erc32: use readline.h for readline types and functions Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 17/23] sim/erc32: Move local extern declarations into sis.h Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17 11:03   ` Mike Frysinger
  2015-02-17  7:45 ` [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts Jiri Gaisler
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* exec.c (init_regs) erc32 has vendor ID 1 and version ID 1 in %psr
---
 sim/erc32/exec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index dc86ba3..07f3586 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -2011,7 +2011,7 @@ init_regs(sregs)
     sregs->npc = 4;
     sregs->trap = 0;
     sregs->psr &= 0x00f03fdf;
-    sregs->psr |= 0x080;	/* Set supervisor bit */
+    sregs->psr |= 0x11000080;	/* Set supervisor bit */
     sregs->breakpoint = 0;
     sregs->annul = 0;
     sregs->fpstate = FP_EXE_MODE;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not work due to API change.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (7 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 07/23] sim/erc32: file loading via command line did not work Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17 11:03   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report Jiri Gaisler
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	The API to print_insn_sparc() has changed over the years ...

	* func.c (print_insn_sparc_sis) Add helper function for disassembly.
	(disp_ctrl) Use helper function.
---
 sim/erc32/func.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index d001c58..e6744ee 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -759,6 +759,17 @@ disp_regs(sregs,cwp)
     }
 }
 
+static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info)
+{
+    unsigned char           i[4];
+
+    sis_memory_read(addr, i, 4);
+    dinfo.buffer_vma = addr;
+    dinfo.buffer_length = 4;
+    dinfo.buffer = i;
+    print_insn_sparc(addr, info);
+}
+
 static void
 disp_ctrl(sregs)
     struct pstate  *sregs;
@@ -770,10 +781,10 @@ disp_ctrl(sregs)
 	   sregs->psr, sregs->wim, sregs->tbr, sregs->y);
     sis_memory_read(sregs->pc, i, 4);
     printf("\n  pc: %08X = %02X%02X%02X%02X    ", sregs->pc,i[0],i[1],i[2],i[3]);
-    print_insn_sparc(sregs->pc, &dinfo);
+    print_insn_sparc_sis(sregs->pc, &dinfo);
     sis_memory_read(sregs->npc, i, 4);
     printf("\n npc: %08X = %02X%02X%02X%02X    ",sregs->npc,i[0],i[1],i[2],i[3]);
-    print_insn_sparc(sregs->npc, &dinfo);
+    print_insn_sparc_sis(sregs->npc, &dinfo);
     if (sregs->err_mode)
 	printf("\n IU in error mode");
     printf("\n\n");
@@ -821,7 +832,7 @@ dis_mem(addr, len, info)
     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
 	sis_memory_read(i, data, 4);
 	printf(" %08x  %02x%02x%02x%02x  ", i, data[0],data[1],data[2],data[3]);
-	print_insn_sparc(i, info);
+	print_insn_sparc_sis(i, info);
         if (i >= 0xfffffffc) break;
 	printf("\n");
     }
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (2 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 02/23] sim/erc32: corrected wrong CPU implementation and version ID in %psr Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17  9:05   ` Mike Frysinger
  2015-02-17  7:45 ` [PATCH 05/23] sim/erc32: remove unused defines in Makefile and switch off statistics Jiri Gaisler
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* float.c (get_accex) access FPU control and status words on x64
---
 sim/erc32/float.c | 80 +++++++++++++++++++++++--------------------------------
 1 file changed, 34 insertions(+), 46 deletions(-)

diff --git a/sim/erc32/float.c b/sim/erc32/float.c
index 598b7cc..ce92a39 100644
--- a/sim/erc32/float.c
+++ b/sim/erc32/float.c
@@ -38,7 +38,6 @@
 
 extern uint32	_get_sw (void);
 extern uint32	_get_cw (void);
-static void	__setfpucw (unsigned short fpu_control);
 
 /* This host dependent routine should return the accrued exceptions */
 int
@@ -46,7 +45,7 @@ get_accex()
 {
 #ifdef sparc
     return ((_get_fsr_raw() >> 5) & 0x1F);
-#elif i386
+#elif defined(i386) || defined(__x86_64__)
     uint32 accx;
 
     accx = _get_sw() & 0x3f;
@@ -66,7 +65,7 @@ clear_accex()
 {
 #ifdef sparc
     set_fsr((_get_fsr_raw() & ~0x3e0));
-#elif i386
+#elif defined(i386) || defined(__x86_64__)
     asm("\n"
 ".text\n"
 "	fnclex\n"
@@ -84,9 +83,8 @@ uint32 fsr;
 {
 #ifdef sparc
 	_set_fsr_raw(fsr & ~0x0f800000);
-#elif i386
-     void __setfpucw(unsigned short fpu_control);
-     uint32 rawfsr;
+#elif defined(i386) || defined(__x86_64__)
+     unsigned short rawfsr;
 
      fsr >>= 30;
      switch (fsr) {
@@ -102,9 +100,8 @@ uint32 fsr;
 	  fsr = 1;
 	  break;
      }
-     rawfsr = _get_cw();
-     rawfsr |= (fsr << 10) | 0x3ff;
-     __setfpucw(rawfsr);
+     rawfsr = (fsr << 10) | 0x2FF; /* double precision, all traps masked */
+    __asm__ volatile ("fldcw %0" :: "m" (rawfsr));
 #else
 #warning no fpu trap support for this target
 #endif
@@ -175,45 +172,36 @@ uint32 fsr;
 "\n"
 "    ");
 
+#elif defined(__x86_64__)
+     asm ("\n"
+"\n"
+".text\n"
+".align 8\n"
+".globl _get_sw, __get_sw\n"
+"__get_sw:\n"
+"_get_sw:\n"
+"	  pushq %rbp\n"
+"	  movq %rsp, %rbp\n"
+"	  movl $0, %eax\n"
+"	  fnstsw %ax\n"
+"	  movq %rbp, %rsp\n"
+"	  popq %rbp\n"
+"	  ret\n"
+".align 8\n"
+".globl _get_cw, __get_cw\n"
+"__get_cw:\n"
+"_get_cw:\n"
+"	  pushq %rbp\n"
+"	  movq %rsp, %rbp\n"
+"	  subq $2, %rsp\n"
+"	  fnstcw -2(%rbp)\n"
+"	  movw -2(%rbp), %ax\n"
+"	  movq %rbp, %rsp\n"
+"	  popq %rbp\n"
+"	  ret\n"
+"	  ");
 
 #else
 #warning no fpu trap support for this target
 #endif
 
-#if i386
-/* #if defined _WIN32 || defined __GO32__ */
-/* This is so floating exception handling works on NT
-   These definitions are from the linux fpu_control.h, which
-   doesn't exist on NT.
-
-   default to:
-     - extended precision
-     - rounding to nearest
-     - exceptions on overflow, zero divide and NaN
-*/
-#define _FPU_DEFAULT  0x1372 
-#define _FPU_RESERVED 0xF0C0  /* Reserved bits in cw */
-
-static void
-__setfpucw(unsigned short fpu_control)
-{
-  volatile unsigned short cw;
-
-  /* If user supplied _fpu_control, use it ! */
-  if (!fpu_control)
-  { 
-    /* use defaults */
-    fpu_control = _FPU_DEFAULT;
-  }
-  /* Get Control Word */
-  __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
-  
-  /* mask in */
-  cw &= _FPU_RESERVED;
-  cw = cw | (fpu_control & ~_FPU_RESERVED);
-
-  /* set cw */
-  __asm__ volatile ("fldcw %0" :: "m" (cw));
-}
-/* #endif */
-#endif
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 17/23] sim/erc32: Move local extern declarations into sis.h
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 16/23] sim/erc32: use readline.h for readline types and functions Jiri Gaisler
@ 2015-02-17  7:45 ` Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 02/23] sim/erc32: corrected wrong CPU implementation and version ID in %psr Jiri Gaisler
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* erc32.c : Move extern declarations to sis.h
	* exec.c, func.c, interf.c, sis.c : As above.
---
 sim/erc32/erc32.c  | 10 ----------
 sim/erc32/exec.c   |  7 -------
 sim/erc32/func.c   | 12 ++++--------
 sim/erc32/interf.c | 19 -------------------
 sim/erc32/sis.c    | 20 --------------------
 sim/erc32/sis.h    | 20 ++++++++++++++++++++
 6 files changed, 24 insertions(+), 64 deletions(-)

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 8d2a6e8..1c55579 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -33,12 +33,6 @@
 #include "sis.h"
 #include "sim-config.h"
 
-extern int      ctrl_c;
-extern int32    sis_verbose;
-extern int32    sparclite, sparclite_board;
-extern int      rom8,wrp,uben;
-extern char     uart_dev1[], uart_dev2[];
-
 static int tty_setup = 1; /* default setup if not a tty */
 
 /* MEC registers */
@@ -295,8 +289,6 @@ static unsigned char *
 static void	store_bytes (unsigned char *mem, uint32 waddr,
 			uint32 *data, int sz, int32 *ws);
 
-extern int	ext_irl;
-
 static host_callback *callback;
 
 
@@ -1880,8 +1872,6 @@ sis_memory_read(addr, data, length)
     return (length);
 }
 
-extern struct pstate sregs;
-
 void
 boot_init ()
 {
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index 65e10bf..6d80306 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -24,7 +24,6 @@
 #include <math.h>
 #include <stdio.h>
 
-extern int32    sis_verbose, sparclite;
 int ext_irl = 0;
 
 /* Load/store interlock delay */
@@ -228,10 +227,6 @@ static int	fpexec (uint32 op3, uint32 rd, uint32 rs1, uint32 rs2,
 			struct pstate *sregs);
 static int	chk_asi (struct pstate *sregs, uint32 *asi, uint32 op3);
 
-
-extern struct estate ebase;
-extern int32    nfp,ift;
-
 #ifdef ERRINJ
 extern uint32 errtt, errftt;
 #endif
@@ -2017,8 +2012,6 @@ execute_trap(sregs)
 
 }
 
-extern struct irqcell irqarr[16];
-
 int
 check_interrupts(sregs)
     struct pstate  *sregs;
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index a92a3e6..26cf5ef 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -39,7 +39,10 @@ int	current_target_byte_order = BIG_ENDIAN;
 int dumbio = 0; /* normal, smart, terminal oriented IO by default */
 struct disassemble_info dinfo;
 struct pstate   sregs;
-extern struct estate ebase;
+struct estate   ebase;
+struct evcell   evbuf[EVENT_MAX];
+struct irqcell  irqarr[16];
+
 int             ctrl_c = 0;
 int             sis_verbose = 0;
 char           *sis_version = "2.7.5";
@@ -53,7 +56,6 @@ int             sparclite = 0;		/* emulating SPARClite instructions? */
 int             sparclite_board = 0;	/* emulating SPARClite board RAM? */
 char            uart_dev1[128] = "";
 char            uart_dev2[128] = "";
-extern	int	ext_irl;
 uint32		last_load_addr = 0;
 int		nouartrx = 0;
 host_callback 	*sim_callback;
@@ -716,12 +718,6 @@ init_signals()
 }
 
 
-extern struct disassemble_info dinfo;
-
-struct estate   ebase;
-struct evcell   evbuf[EVENT_MAX];
-struct irqcell  irqarr[16];
-
 static int
 disp_fpu(sregs)
     struct pstate  *sregs;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 612aded..2fab99f 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -36,25 +36,6 @@
 
 #define PSR_CWP 0x7
 
-extern struct disassemble_info dinfo;
-extern struct estate ebase;
-
-extern int      nfp;
-extern int      ift;
-extern int      rom8;
-extern int      wrp;
-extern int      uben;
-extern char    *sis_version;
-extern struct estate ebase;
-extern struct evcell evbuf[];
-extern struct irqcell irqarr[];
-extern int      irqpend, ext_irl;
-extern int      sparclite;
-extern int      dumbio;
-extern int      sparclite_board;
-extern int      termsave;
-extern char     uart_dev1[], uart_dev2[];
-
 int             sis_gdb_break = 1;
 
 int
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index a5a81d8..efd8a63 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -41,26 +41,6 @@
 /* Command history buffer length - MUST be binary */
 #define HIST_LEN	64
 
-extern struct disassemble_info dinfo;
-extern struct estate ebase;
-
-extern int      nfp;
-extern int      ift;
-extern int      wrp;
-extern int      rom8;
-extern int      uben;
-extern char    *sis_version;
-extern struct estate ebase;
-extern struct evcell evbuf[];
-extern struct irqcell irqarr[];
-extern int      irqpend, ext_irl;
-extern int      termsave;
-extern int      sparclite;
-extern int      dumbio;
-extern char     uart_dev1[];
-extern char     uart_dev2[];
-extern uint32   last_load_addr;
-
 #ifdef ERA
 extern int era;
 #endif
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 8f0a9c1..a7bb39a 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -167,8 +167,27 @@ extern struct memsys erc32sys;
 
 /* func.c */
 extern struct   pstate  sregs;
+extern struct   estate ebase;
+extern struct   evcell evbuf[];
+extern struct   irqcell irqarr[];
+extern int      nfp;
+extern int      ift;
 extern int      ctrl_c;
 extern int      sis_verbose;
+extern char    *sis_version;
+extern int      sparclite;
+extern int      sparclite_board;
+extern uint32   last_load_addr;
+extern int      wrp;
+extern int      rom8;
+extern int      uben;
+extern int      irqpend;
+extern int      ext_irl;
+extern int      termsave;
+extern int      dumbio;
+extern char     uart_dev1[];
+extern char     uart_dev2[];
+
 extern void	set_regi (struct pstate *sregs, int32 reg,
 			  uint32 rval);
 extern void	get_regi (struct pstate *sregs, int32 reg, char *buf);
@@ -179,6 +198,7 @@ extern void	init_bpt (struct pstate  *sregs);
 extern void	init_signals (void);
 
 struct disassemble_info;
+extern struct   disassemble_info dinfo;
 extern void	dis_mem (uint32 addr, uint32 len,
 			 struct disassemble_info *info);
 extern void	event (void (*cfunc) (), int32 arg, uint64 delta);
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 00/22] Update of the SPARC SIS simulator
@ 2015-02-17  7:45 Jiri Gaisler
  2015-02-17  7:45 ` [PATCH 16/23] sim/erc32: use readline.h for readline types and functions Jiri Gaisler
                   ` (22 more replies)
  0 siblings, 23 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

This is a 22-part patch that brings the sis simulator into working
order, and adds support for emulation of the leon2 and leon3 cpus.

The sis simulator was written by me in the mid 90's, to emulate the erc32
processor (SPARC V7). It was included into gdb by Cygnus (Stan Shebs?),
and adapted to also emulate the Fujistu Sparlite processor. The simulator
has not been actively maintained for about 15 years, and suffered some
bit-rot. It's primary use has been for RTEMS development. The erc32
processor is now becoming obsolete, and being replaced by leon2 and
leon3 cpus in many ESA and NASA missions. These patches will
allow sis to be useful again, and support the newer leon2/3 processor.

Jiri Gaisler (22):
  sim/erc32: Disassembly in stand-alone mode did not work due to API
    change.
  sim/erc32: corrected wrong CPU implementation and version ID in %psr
  sim/erc32: Perform pseudo-init of system if binary starts from
    non-zero address.
  sim/erc32: Add FPU support on x86_64 hosts.
  sim/erc32: remove unused defines in Makefile and switch off statistics
  sim/erc32: Fix incorrect simulator performance report
  sim/erc32: file loading via command line did not work
  sim/erc32: added -v and -vv command line switches for verbose output
  sim/erc32: removed type mismatch compiler warnings
  sim/erc32: Switched emulated memory to host endian order.
  sim/erc32: use AC_C_BIGENDIAN to probe for host endian.
  sim/erc32: Use separate memory_iread() function for instruction
    fetching.
  sim/erc32: Fix a few compiler warnings
  sim/erc32: Use gdb callback for UART I/O when linked with gdb.
  sim/erc32: access memory subsystem through struct memsys to allow
    multiple configurations.
  sim/erc32: use readline.h for readline types and functions.
  sim/erc32: Move local extern declarations into sis.h
  sim/erc32: Add support for LEON3 processor emulation.
  sim/erc32: Added support for the Leon2 processor
  sim/erc32: Updated documentation
  sim/erc32: add data watchpoint support for all cpu targets.
  Added watchpoint support to gdb simulator interface.

 gdb/remote-sim.c              |   69 +++
 include/gdb/remote-sim.h      |   24 +
 sim/arm/wrapper.c             |   26 +
 sim/avr/interp.c              |   25 +
 sim/bfin/Makefile.in          |    1 +
 sim/common/sim-watch-remote.c |   27 ++
 sim/cr16/interp.c             |   26 +
 sim/cris/Makefile.in          |    1 +
 sim/erc32/Makefile.in         |   33 +-
 sim/erc32/NEWS                |  108 -----
 sim/erc32/README.gdb          |   67 ---
 sim/erc32/README.leon2        |   53 ++
 sim/erc32/README.leon3        |   53 ++
 sim/erc32/README.sis          |  246 ++++------
 sim/erc32/config.in           |   15 +
 sim/erc32/configure           |  225 +++++++++
 sim/erc32/configure.ac        |    1 +
 sim/erc32/end.c               |   27 --
 sim/erc32/erc32.c             |  409 +++++++++-------
 sim/erc32/exec.c              |  349 +++++++++++---
 sim/erc32/float.c             |   80 ++--
 sim/erc32/func.c              |  274 ++++++++---
 sim/erc32/grlib.c             |   98 ++++
 sim/erc32/grlib.h             |   57 +++
 sim/erc32/help.c              |    2 +-
 sim/erc32/interf.c            |  357 ++++++++++----
 sim/erc32/leon2.c             | 1041 ++++++++++++++++++++++++++++++++++++++++
 sim/erc32/leon3.c             | 1066 +++++++++++++++++++++++++++++++++++++++++
 sim/erc32/sis.c               |  138 +++---
 sim/erc32/sis.h               |  116 ++++-
 sim/erc32/startsim            |    4 -
 sim/frv/Makefile.in           |    1 +
 sim/h8300/Makefile.in         |    1 +
 sim/iq2000/Makefile.in        |    1 +
 sim/lm32/Makefile.in          |    1 +
 sim/m32c/gdb-if.c             |   26 +
 sim/m32r/Makefile.in          |    1 +
 sim/m68hc11/Makefile.in       |    1 +
 sim/mcore/interp.c            |   26 +
 sim/microblaze/Makefile.in    |    2 +-
 sim/mips/Makefile.in          |    1 +
 sim/mn10300/Makefile.in       |    1 +
 sim/moxie/interp.c            |   26 +
 sim/msp430/Makefile.in        |    1 +
 sim/ppc/gdb-sim.c             |   26 +
 sim/rl78/gdb-if.c             |   26 +
 sim/rx/gdb-if.c               |   26 +
 sim/sh/interp.c               |   26 +
 sim/sh64/Makefile.in          |    1 +
 sim/v850/Makefile.in          |    3 +-
 50 files changed, 4305 insertions(+), 910 deletions(-)
 create mode 100644 sim/common/sim-watch-remote.c
 delete mode 100644 sim/erc32/NEWS
 delete mode 100644 sim/erc32/README.gdb
 create mode 100644 sim/erc32/README.leon2
 create mode 100644 sim/erc32/README.leon3
 delete mode 100644 sim/erc32/end.c
 create mode 100644 sim/erc32/grlib.c
 create mode 100644 sim/erc32/grlib.h
 create mode 100644 sim/erc32/leon2.c
 create mode 100644 sim/erc32/leon3.c
 delete mode 100644 sim/erc32/startsim

-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 19/23] sim/erc32: Added support for the Leon2 processor
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (20 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 20/23] sim/erc32: Updated documentation Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  8:54 ` [PATCH 00/22] Update of the SPARC SIS simulator Mike Frysinger
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Added memory and I/O sub-system to emulate a LEON2 processor.
	The cache and MMU are not emulated but enough functionallity
	is provided to run any RTEMS and BCC compiled application.
	The code is based on leon3.c and modified to emulate the
	LEON2 address space and peripheral operations.
---
 sim/erc32/Makefile.in |    5 +-
 sim/erc32/exec.c      |    3 +
 sim/erc32/interf.c    |   11 +-
 sim/erc32/leon2.c     | 1041 +++++++++++++++++++++++++++++++++++++++++++++++++
 sim/erc32/sis.c       |    7 +
 sim/erc32/sis.h       |    4 +
 6 files changed, 1067 insertions(+), 4 deletions(-)
 create mode 100644 sim/erc32/leon2.c

diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
index 63b0f0b..3f09b0e 100644
--- a/sim/erc32/Makefile.in
+++ b/sim/erc32/Makefile.in
@@ -21,7 +21,7 @@
 TERMCAP_LIB = @TERMCAP@
 READLINE_LIB = @READLINE@
 
-SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon3.o grlib.o
+SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon2.o leon3.o grlib.o
 SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm
 SIM_EXTRA_ALL = sis
 SIM_EXTRA_INSTALL = install-sis
@@ -35,7 +35,7 @@ SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcdir)/../..
 ## COMMON_POST_CONFIG_FRAG
 
 # `sis' doesn't need interf.o.
-SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon3.o
+SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon2.o leon3.o
 
 sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS)
 	$(CC) $(ALL_CFLAGS) -o sis \
@@ -66,3 +66,4 @@ interf.o: interf.c sis.h
 sis.o: sis.c sis.h
 grlib.o: grlib.c sis.h grlib.h
 leon3.o: leon3.c sis.h grlib.h
+leon2.o: leon2.c sis.h
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index 13d5805..f812ad9 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -2207,6 +2207,9 @@ init_regs(sregs)
     if (cputype == CPU_LEON3)
       sregs->psr |= 0xF3000080;	/* Set supervisor bit */
     else
+    if (cputype == CPU_LEON2)
+      sregs->psr |= 0x00000080;	/* Set supervisor bit */
+    else
       sregs->psr |= 0x11000080;	/* Set supervisor bit */
     sregs->breakpoint = 0;
     sregs->annul = 0;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 6a406ba..9b3666a 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -187,6 +187,10 @@ sim_open (kind, callback, abfd, argv)
             if (strcmp(argv[stat], "-nouartrx") == 0) {
 		nouartrx = 1;
 	    } else
+            if (strcmp(argv[stat], "-leon2") == 0) {
+		ms = &leon2;
+                cputype = CPU_LEON2;
+            } else
             if (strcmp(argv[stat], "-leon3") == 0) {
 		ms = &leon3;
                 cputype = CPU_LEON3;
@@ -228,15 +232,18 @@ sim_open (kind, callback, abfd, argv)
 	stat++;
     }
 
-    if (cputype == CPU_LEON3)
+    if ((cputype == CPU_LEON3) || (cputype == CPU_LEON2))
         sregs.freq = freq ? freq : 50;
     else
         sregs.freq = freq ? freq : 14;
 
     if (sis_verbose) {
 	(*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
-	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jiri@gaisler.se)\n\n");
+	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler (jiri@gaisler.se)\n\n");
         switch (cputype) {
+        case CPU_LEON2:
+            (*sim_callback->printf_filtered) (sim_callback, "LEON2 emulation enabled\n");
+            break;
         case CPU_LEON3:
             (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled\n");
             break;
diff --git a/sim/erc32/leon2.c b/sim/erc32/leon2.c
new file mode 100644
index 0000000..5ab3f79
--- /dev/null
+++ b/sim/erc32/leon2.c
@@ -0,0 +1,1041 @@
+/*
+ * This file is part of SIS.
+ * 
+ * SIS, SPARC instruction simulator V2.5 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 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 <http://www.gnu.org/licenses/>.
+ * 
+ * Leon2 emulation, based on leon3.c .
+ */
+
+/* The control space devices */
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include "sis.h"
+#include "sim-config.h"
+
+static int tty_setup = 1; /* default setup if not a tty */
+
+/* APB registers */
+#define APBSTART	0x80000000
+#define APBEND  	0x80000100
+
+/* Memory exception waitstates */
+#define MEM_EX_WS 	1
+
+#define MOK	0
+
+/* LEON2 APB register addresses */
+
+#define IRQCTRL_IPR	0x094
+#define IRQCTRL_IMR 	0x090
+#define IRQCTRL_ICR 	0x09C
+#define IRQCTRL_IFR 	0x098
+#define TIMER_SCALER	0x060
+#define TIMER_SCLOAD	0x064
+#define LEON2_CONFIG 	0x024
+#define TIMER_TIMER1 	0x040
+#define TIMER_RELOAD1	0x044
+#define TIMER_CTRL1 	0x048
+#define TIMER_TIMER2 	0x050
+#define TIMER_RELOAD2	0x054
+#define TIMER_CTRL2 	0x058
+#define CACHE_CTRL  	0x014
+#define POWER_DOWN  	0x018
+
+#define APBUART_RXTX	0x070
+#define APBUART_STATUS  0x074
+
+/* Size of UART buffers (bytes) */
+#define UARTBUF	1024
+
+/* Number of simulator ticks between flushing the UARTS. 	 */
+/* For good performance, keep above 1000			 */
+#define UART_FLUSH_TIME	  3000
+
+
+/* New uart defines */
+#define UART_TX_TIME	1000
+#define UART_RX_TIME	1000
+#define UARTA_DR	0x1
+#define UARTA_SRE	0x2
+#define UARTA_HRE	0x4
+#define UARTA_OR	0x10
+
+/* IRQCTRL registers */
+
+static uint32   irqctrl_ipr;
+static uint32   irqctrl_imr;
+static uint32   irqctrl_ifr;
+
+/* TIMER registers */
+
+#define NTIMERS  2
+#define TIMER_IRQ 8
+
+static uint32   gpt_scaler;
+static uint32   gpt_scaler_start;
+static uint32   gpt_counter[NTIMERS];
+static uint32   gpt_reload[NTIMERS];
+static uint32   gpt_ctrl[NTIMERS];
+
+/* ROM size 16 Mbyte */
+#define ROM_START 	0x00000000
+#define ROM_MASK 	0x00ffffff
+#define ROM_END 	(ROM_START + ROM_MASK + 1)
+
+/* RAM size 16 Mbyte */
+#define RAM_START 	0x40000000
+#define RAM_MASK 	0x00ffffff
+#define RAM_END 	(RAM_START + RAM_MASK + 1)
+
+/* Memory */
+
+static unsigned char	romb[ROM_END - ROM_START];
+static unsigned char	ramb[RAM_END - RAM_START];
+static uint32   cache_ctrl;
+
+
+/* UART support variables */
+
+static int32    fd1, fd2;	/* file descriptor for input file */
+static int32    Ucontrol;	/* UART status register */
+static unsigned char aq[UARTBUF], bq[UARTBUF];
+static int32    anum, aind = 0;
+static int32    bnum, bind = 0;
+static char     wbufa[UARTBUF], wbufb[UARTBUF];
+static unsigned wnuma;
+static unsigned wnumb;
+static FILE    *f1in, *f1out;
+static struct termios ioc1, ioc2, iocold1, iocold2;
+static int      f1open = 0;
+
+static char     uarta_sreg, uarta_hreg;
+static uint32   uart_stat_reg;
+static uint32   uarta_data;
+
+/* Forward declarations */
+
+static void	mem_init (void);
+static void	close_port (void);
+static void	leon2_reset (void);
+static void	irqctrl_intack (int32 level);
+static void	chk_irq (void);
+static void	set_irq (int32 level);
+static int32	apb_read (uint32 addr, uint32 *data);
+static int	apb_write (uint32 addr, uint32 data);
+static void	port_init (void);
+static uint32	grlib_read_uart (uint32 addr);
+static void	grlib_write_uart (uint32 addr, uint32 data);
+static void	flush_uart (void);
+static void	uarta_tx (void);
+static void	uart_rx (caddr_t arg);
+static void	uart_intr (caddr_t arg);
+static void	uart_irq_start (void);
+static void	gpt_intr (caddr_t arg);
+static void	gpt_init (void);
+static void	gpt_reset (void);
+static void	gpt_scaler_set (uint32 val);
+static void	timer_ctrl (uint32 val, int i);
+static unsigned char *
+		get_mem_ptr (uint32 addr, uint32 size);
+static void	store_bytes (unsigned char *mem, uint32 waddr,
+			uint32 *data, int sz, int32 *ws);
+
+static host_callback *callback;
+
+
+/* One-time init */
+
+static void
+init_sim()
+{
+    callback = sim_callback;
+    grlib_init();
+    mem_init();
+    port_init();
+    gpt_init();
+}
+
+/* Power-on reset init */
+
+static void
+reset()
+{
+    leon2_reset();
+    uart_irq_start();
+    gpt_reset();
+}
+
+/* IU error mode manager */
+
+static void
+error_mode(pc)
+    uint32          pc;
+{
+
+}
+
+
+/* Memory init */
+
+static void
+mem_init()
+{
+
+    if (sis_verbose)
+	printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
+	       RAM_START, (RAM_MASK+1)/1024, (ROM_MASK+1)/1024);
+}
+
+/* Flush ports when simulator stops */
+
+static void
+sim_halt()
+{
+#ifdef FAST_UART
+    flush_uart();
+#endif
+}
+
+static void
+close_port()
+{
+    if (f1open && f1in != stdin)
+	fclose(f1in);
+}
+
+static void
+exit_sim()
+{
+    close_port();
+}
+
+static void
+leon2_reset()
+{
+    int             i;
+
+    irqctrl_ipr = 0;
+    irqctrl_imr = 0;
+    irqctrl_ifr = 0;
+
+    wnuma = wnumb = 0;
+    anum = aind = bnum = bind = 0;
+
+    uart_stat_reg = UARTA_SRE | UARTA_HRE;
+
+    gpt_counter[0] = 0xffffffff;
+    gpt_reload[0] = 0xffffffff;
+    gpt_scaler = 0xffff;
+    gpt_ctrl[0] = 0;
+    gpt_ctrl[1] = 0;
+
+}
+
+
+
+static void
+irqctrl_intack(level)
+    int32           level;
+{
+    int             irq_test;
+
+    if (sis_verbose > 2)
+	printf("interrupt %d acknowledged\n", level);
+    if (irqctrl_ifr & (1 << level))
+	irqctrl_ifr &= ~(1 << level);
+    else
+	irqctrl_ipr &= ~(1 << level);
+   chk_irq();
+}
+
+static void
+chk_irq()
+{
+    int32           i;
+    uint32          itmp;
+    int		    old_irl;
+
+    old_irl = ext_irl;
+    itmp = ((irqctrl_ipr | irqctrl_ifr) & irqctrl_imr) & 0x0fffe;
+    ext_irl = 0;
+    if (itmp != 0) {
+	for (i = 15; i > 0; i--) {
+	    if (((itmp >> i) & 1) != 0) {
+		if ((sis_verbose > 2) && (i > old_irl)) 
+		    printf("IU irl: %d\n", i);
+		ext_irl = i;
+	        set_int(i, irqctrl_intack, i);
+		break;
+	    }
+	}
+    }
+}
+
+static void
+set_irq(level)
+    int32           level;
+{
+    irqctrl_ipr |= (1 << level);
+    chk_irq();
+}
+
+static int32
+apb_read(addr, data)
+    uint32          addr;
+    uint32         *data;
+{
+
+    switch (addr & 0xfff) {
+
+    case APBUART_RXTX:		/* 0x100 */
+    case APBUART_STATUS:	/* 0x104 */
+	*data = grlib_read_uart(addr);
+	break;
+
+    case IRQCTRL_IPR:		/* 0x204 */
+	*data = irqctrl_ipr;
+	break;
+
+    case IRQCTRL_IFR:		/* 0x208 */
+	*data = irqctrl_ifr;
+	break;
+
+    case IRQCTRL_IMR:		/* 0x240 */
+	*data = irqctrl_imr;
+	break;
+
+    case TIMER_SCALER:	/* 0x300 */
+	*data = gpt_scaler - (now() - gpt_scaler_start);
+	break;
+
+    case TIMER_SCLOAD:	/* 0x304 */
+	*data = gpt_scaler;
+	break;
+
+    case LEON2_CONFIG:	/* 0x308 */
+	*data = 0x700310;
+	break;
+
+    case TIMER_TIMER1:	/* 0x310 */
+	*data = gpt_counter[0];
+	break;
+
+    case TIMER_RELOAD1:	/* 0x314 */
+	*data = gpt_reload[0];
+	break;
+
+    case TIMER_CTRL1:		/* 0x318 */
+	*data = gpt_ctrl[0];
+	break;
+
+    case TIMER_TIMER2:	/* 0x320 */
+	*data = gpt_counter[1];
+	break;
+
+    case TIMER_RELOAD2:	/* 0x324 */
+	*data = gpt_reload[1];
+	break;
+
+    case TIMER_CTRL2:		/* 0x328 */
+	*data = gpt_ctrl[1];
+	break;
+
+    case CACHE_CTRL:		/* 0x328 */
+        *data = cache_ctrl;
+	break;
+
+    default:
+	*data = 0;
+	break;
+    }
+
+    if (sis_verbose > 1)
+	printf("APB read  a: %08x, d: %08x\n", addr, *data);
+
+    return (MOK);
+}
+
+static int
+apb_write(addr, data)
+    uint32          addr;
+    uint32          data;
+{
+    if (sis_verbose > 1)
+	printf("APB write a: %08x, d: %08x\n",addr,data);
+    switch (addr & 0xff) {
+
+    case APBUART_RXTX:		/* 0x100 */
+    case APBUART_STATUS:	/* 0x104 */
+	grlib_write_uart(addr, data);
+	break;
+
+    case IRQCTRL_IFR:		/* 0x208 */
+	irqctrl_ifr = data & 0xfffe;
+	chk_irq();
+	break;
+
+    case IRQCTRL_ICR:		/* 0x20C */
+	irqctrl_ipr &= ~data & 0x0fffe;
+	chk_irq();
+	break;
+
+    case IRQCTRL_IMR:		/* 0x240 */
+	irqctrl_imr = data & 0x7ffe;
+	chk_irq();
+	break;
+
+    case TIMER_SCLOAD:	/* 0x304 */
+	gpt_scaler_set(data);
+	break;
+
+    case TIMER_TIMER1:	/* 0x310 */
+	gpt_counter[0] = data;
+	break;
+
+    case TIMER_RELOAD1:	/* 0x314 */
+        gpt_reload[0] = data;
+	break;
+
+    case TIMER_CTRL1:		/* 0x318 */
+	timer_ctrl(data, 0);
+	break;
+
+    case TIMER_TIMER2:	/* 0x320 */
+	gpt_counter[1] = data;
+	break;
+
+    case TIMER_RELOAD2:	/* 0x324 */
+        gpt_reload[1] = data;
+	break;
+
+    case TIMER_CTRL2:		/* 0x328 */
+	timer_ctrl(data, 1);
+	break;
+
+    case POWER_DOWN:		/* 0x328 */
+        wait_for_irq();
+	break;
+
+    case CACHE_CTRL:		/* 0x328 */
+        cache_ctrl = data & 0x1000f;
+	break;
+
+    default:
+	break;
+    }
+    return (MOK);
+}
+
+
+/* APBUART */
+
+static int      ifd1 = -1, ofd1 = -1;
+
+static void
+init_stdio()
+{
+    if (dumbio)
+        return; /* do nothing */
+    if (ifd1 == 0 && f1open) {
+	tcsetattr(0, TCSANOW, &ioc1);
+        tcflush(ifd1, TCIFLUSH);
+    }
+}
+
+static void
+restore_stdio()
+{
+    if (dumbio)
+        return; /* do nothing */
+    if (ifd1 == 0 && f1open && tty_setup)
+	tcsetattr(0, TCSANOW, &iocold1);
+}
+
+#define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
+             ( dumbio || nouartrx \
+               ? (0) /* no bytes read, no delay */   \
+               : (_fd_) == 1 && callback ? \
+                 callback->read_stdin (callback, _buf_, _len_) :  \
+                 read( _fd_, _buf_, _len_ ) )
+
+
+static void
+port_init()
+{
+
+    f1in = stdin;
+    f1out = stdout;
+    if (uart_dev1[0] != 0)
+	if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) {
+	    printf("Warning, couldn't open output device %s\n", uart_dev1);
+	} else {
+	    if (sis_verbose)
+		printf("serial port A on %s\n", uart_dev1);
+	    f1in = f1out = fdopen(fd1, "r+");
+	    setbuf(f1out, NULL);
+	    f1open = 1;
+	}
+    if (f1in) ifd1 = fileno(f1in);
+    if (ifd1 == 0) {
+        if (callback && !callback->isatty(callback, ifd1)) {
+            tty_setup = 0;
+        }
+	if (sis_verbose)
+	    printf("serial port A on stdin/stdout\n");
+        if (!dumbio) {
+            tcgetattr(ifd1, &ioc1);
+            if (tty_setup) {
+            iocold1 = ioc1;
+            ioc1.c_lflag &= ~(ICANON | ECHO);
+            ioc1.c_cc[VMIN] = 0;
+            ioc1.c_cc[VTIME] = 0;
+        }
+        }
+	f1open = 1;
+    }
+
+    if (f1out) {
+	ofd1 = fileno(f1out);
+    	if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL);
+    }
+
+    wnuma = 0;
+
+}
+
+static uint32
+grlib_read_uart(addr)
+    uint32          addr;
+{
+
+    unsigned        tmp;
+
+    tmp = 0;
+    switch (addr & 0xfff) {
+
+    case 0x070:			/* UART 1 RX/TX */
+#ifndef _WIN32
+#ifdef FAST_UART
+
+	if (aind < anum) {
+	    if ((aind + 1) < anum)
+		set_irq(3);
+	    return ((uint32) aq[aind++]);
+	} else {
+	    if (f1open) {
+	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
+	    }
+      else {
+          anum = 0;
+      }
+	    if (anum > 0) {
+		aind = 0;
+		if ((aind + 1) < anum)
+		    set_irq(3);
+		return ((uint32) aq[aind++]);
+	    } else {
+		return ((uint32) aq[aind]);
+	    }
+
+	}
+#else
+	tmp = uarta_data;
+	uarta_data &= ~UART_DR;
+	uart_stat_reg &= ~UARTA_DR;
+	return tmp;
+#endif
+#else
+	return(0);
+#endif
+	break;
+
+    case 0x074:			/* UART status register	 */
+#ifndef _WIN32
+#ifdef FAST_UART
+
+	Ucontrol = 0;
+	if (aind < anum) {
+	    Ucontrol |= 0x00000001;
+	} else {
+	    if (f1open) {
+	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
+            }
+	    else {
+		anum = 0;
+	    }
+	    if (anum > 0) {
+		Ucontrol |= 0x00000001;
+		aind = 0;
+		set_irq(3);
+	    }
+	}
+	Ucontrol |= 0x00000006;
+	return (Ucontrol);
+#else
+	return (uart_stat_reg);
+#endif
+#else
+	return(0x00060006);
+#endif
+	break;
+    default:
+	if (sis_verbose)
+	    printf("Read from unimplemented LEON2 register (%x)\n", addr);
+
+    }
+    return (0);
+}
+
+static void
+grlib_write_uart(addr, data)
+    uint32          addr;
+    uint32          data;
+{
+    unsigned char   c;
+
+    c = (unsigned char) data;
+    switch (addr & 0xfff) {
+
+    case 0x070:			/* UART A */
+#ifdef FAST_UART
+	if (f1open) {
+	    if (wnuma < UARTBUF)
+	        wbufa[wnuma++] = c;
+	    else {
+	        while (wnuma) {
+              if (ofd1 == 1 && callback)
+                  wnuma -= callback->write_stdout(callback, wbufa, wnuma);
+              else
+		    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
+          }
+	        wbufa[wnuma++] = c;
+	    }
+	}
+	set_irq(3);
+#else
+	if (uart_stat_reg & UARTA_SRE) {
+	    uarta_sreg = c;
+	    uart_stat_reg &= ~UARTA_SRE;
+	    event(uarta_tx, 0, UART_TX_TIME);
+	} else {
+	    uarta_hreg = c;
+	    uart_stat_reg &= ~UARTA_HRE;
+	}
+#endif
+	break;
+
+    case 0x074:			/* UART status register */
+#ifndef FAST_UART
+        uart_stat_reg &= 1;
+#endif
+	break;
+    default:
+	if (sis_verbose)
+	    printf("Write to unimplemented APB register (%x)\n", addr);
+
+    }
+}
+
+static void
+flush_uart()
+{
+    while (wnuma && f1open) {
+        if (ofd1 == 1 && callback) {
+            wnuma -= callback->write_stdout(callback, wbufa, wnuma);
+            callback->flush_stdout(callback);
+        }
+        else
+	wnuma -= fwrite(wbufa, 1, wnuma, f1out);
+    }
+}
+
+
+
+static void
+uarta_tx()
+{
+    while (f1open) {
+        if (ofd1 == 1 && callback) {
+            while (callback->write_stdout(callback, &uarta_sreg, 1) != 1);
+        }
+        else {
+            while (fwrite(&uarta_sreg, 1, 1, f1out) != 1);
+        }
+    }
+    if (uart_stat_reg & UARTA_HRE) {
+	uart_stat_reg |= UARTA_SRE;
+    } else {
+	uarta_sreg = uarta_hreg;
+	uart_stat_reg |= UARTA_HRE;
+	event(uarta_tx, 0, UART_TX_TIME);
+    }
+    set_irq(3);
+}
+
+static void
+uart_rx(arg)
+    caddr_t         arg;
+{
+    int32           rsize;
+    char            rxd;
+
+
+    rsize = 0;
+    if (f1open)
+        rsize = DO_STDIO_READ(ifd1, &rxd, 1);
+    else
+        rsize = 0;
+    if (rsize > 0) {
+	uarta_data = rxd;
+	if (uart_stat_reg & UARTA_DR) {
+	    uart_stat_reg |= UARTA_OR;
+	}
+	uart_stat_reg |= UARTA_DR;
+	set_irq(3);
+    }
+    event(uart_rx, 0, UART_RX_TIME);
+}
+
+static void
+uart_intr(arg)
+    caddr_t         arg;
+{
+    grlib_read_uart(APBUART_STATUS);	/* Check for UART interrupts every 1000 clk */
+    flush_uart();		/* Flush UART ports      */
+    event(uart_intr, 0, UART_FLUSH_TIME);
+}
+
+
+static void
+uart_irq_start()
+{
+#ifdef FAST_UART
+    event(uart_intr, 0, UART_FLUSH_TIME);
+#else
+#ifndef _WIN32
+    event(uart_rx, 0, UART_RX_TIME);
+#endif
+#endif
+}
+
+/* TIMER */
+
+static void
+gpt_intr(arg)
+    caddr_t         arg;
+{
+    int i;
+
+    for (i=0; i<NTIMERS; i++) {
+	if (gpt_ctrl[i] & 1) {
+            gpt_counter[i] -= 1;
+            if (gpt_counter[i] == -1) {
+	        set_irq(TIMER_IRQ + i);
+	        if (gpt_ctrl[i] & 2)
+	            gpt_counter[i] = gpt_reload[i];
+            }
+        }
+    }
+    event(gpt_intr, 0, gpt_scaler + 1);
+    gpt_scaler_start = now();
+}
+
+static void
+gpt_init()
+{
+    if (sis_verbose)
+	printf("GPT started (period %d)\n\r", gpt_scaler + 1);
+}
+
+static void
+gpt_reset()
+{
+    event(gpt_intr, 0, gpt_scaler + 1);
+    gpt_scaler_start = now();
+}
+
+static void
+gpt_scaler_set(val)
+    uint32          val;
+{
+    gpt_scaler = val & 0x0ffff;	/* 16-bit scaler */
+}
+
+static void
+timer_ctrl(val, i)
+    uint32       val;
+    int          i;
+{
+    if (val & 4) {  /* reload */
+        gpt_counter[i] = gpt_reload[i];
+    }
+    gpt_ctrl[i] = val & 0xb;
+}
+
+/* Store data in host byte order.  MEM points to the beginning of the
+   emulated memory; WADDR contains the index the emulated memory,
+   DATA points to words in host byte order to be stored.  SZ contains log(2)
+   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
+   2 (one word), or 3 (two words); WS should return the number of wait-states. */
+
+static void
+store_bytes (mem, waddr, data, sz, ws)
+    unsigned char  *mem;
+    uint32	   waddr;
+    uint32	   *data;
+    int32	    sz;
+    int32	   *ws;
+{
+    switch (sz) {
+	case 0:
+#ifdef HOST_LITTLE_ENDIAN
+	    waddr ^= 3;
+#endif
+	    mem[waddr] = *data & 0x0ff;
+	    *ws = 0;
+	    break;
+	case 1:
+#ifdef HOST_LITTLE_ENDIAN
+	    waddr ^= 2;
+#endif
+	    *((unsigned short *) &(mem[waddr])) = *data & 0x0ffff;
+	    *ws = 0;
+	    break;
+	case 2:
+	    *((uint32 *) &(mem[waddr])) = *data;
+	    *ws = 0;
+	    break;
+	case 3:
+	    *((uint32 *) &(mem[waddr])) = data[0];
+	    *((uint32 *) &(mem[waddr + 4])) = data[1];
+	    *ws = 0;
+	    break;
+    }
+}
+
+
+/* Memory emulation */
+
+static int
+memory_iread(addr, data, ws)
+    uint32          addr;
+    uint32         *data;
+    int32          *ws;
+{
+    if ((addr >= RAM_START) && (addr < RAM_END)) {
+        *data = *((uint32 *) & (ramb[addr & RAM_MASK]));
+	*ws = 0;
+	return (0);
+    } else if (addr < ROM_END) {
+        *data = *((uint32 *) & (romb[addr]));
+	*ws = 0;
+	return (0);
+    }
+
+    printf("Memory exception at %x (illegal address)\n", addr);
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+static int
+memory_read(addr, data, sz, ws)
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    int32           mexc;
+
+    if ((addr >= RAM_START) && (addr < RAM_END)) {
+        *data = *((uint32 *) & (ramb[addr & RAM_MASK & ~3]));
+	*ws = 0;
+	return (0);
+    } else if ((addr >= APBSTART) && (addr < APBEND)) {
+	mexc = apb_read(addr, data);
+	if (mexc) {
+	    *ws = MEM_EX_WS;
+	} else {
+	    *ws = 0;
+	}
+	return (mexc);
+    } else if (addr < ROM_END) {
+        *data = *((uint32 *) & (romb[addr & ~3]));
+	*ws = 0;
+	return (0);
+    }
+
+    printf("Memory exception at %x (illegal address)\n", addr);
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+static int
+memory_read_asi(asi, addr, data, sz, ws)
+    int32           asi;
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    return(memory_read(addr, data, sz, ws));
+}
+
+static int
+memory_write(addr, data, sz, ws)
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    uint32          byte_addr;
+    uint32          byte_mask;
+    uint32          waddr;
+    uint32         *ram;
+    int32           mexc;
+    int             i;
+    int             wphit[2];
+
+    if ((addr >= RAM_START) && (addr < RAM_END)) {
+	waddr = addr & RAM_MASK;
+	store_bytes (ramb, waddr, data, sz, ws);
+	return (0);
+
+    } else if ((addr >= APBSTART) && (addr < APBEND)) {
+	if (sz != 2) {
+	    *ws = MEM_EX_WS;
+	    return (1);
+	}
+	apb_write(addr, *data);
+	*ws = 0;
+	return (0);
+
+    } else if (addr < ROM_END) {
+//        return (1);
+	*ws = 0;
+	store_bytes (romb, addr, data, sz, ws);
+        return (0);
+    }
+	
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+static int
+memory_write_asi(asi, addr, data, sz, ws)
+    int32           asi;
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    return(memory_write(addr, data, sz, ws));
+}
+
+static unsigned char  *
+get_mem_ptr(addr, size)
+    uint32          addr;
+    uint32          size;
+{
+    if ((addr + size) < ROM_END) {
+	return (&romb[addr]);
+    } else if ((addr >= RAM_START) && ((addr + size) < RAM_END)) {
+	return (&ramb[addr & RAM_MASK]);
+    }
+
+    return ((char *) -1);
+}
+
+static int
+sis_memory_write(addr, data, length)
+    uint32               addr;
+    const unsigned char *data;
+    uint32               length;
+{
+    char           *mem;
+
+    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
+	return (0);
+
+    memcpy(mem, data, length);
+    return (length);
+}
+
+static int
+sis_memory_read(addr, data, length)
+    uint32          addr;
+    char           *data;
+    uint32          length;
+{
+    char           *mem;
+    int            ws;
+
+    if (length == 4) {
+      memory_read(addr, data, length, &ws);
+      return(4);
+    }
+
+    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
+	return (0);
+
+    memcpy(data, mem, length);
+    return (length);
+}
+
+static void
+boot_init ()
+{
+//    mec_write(MEC_WCR, 0);	/* zero waitstates */
+//    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
+    apb_write(TIMER_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
+    apb_write(TIMER_SCLOAD, sregs.freq-1);
+    apb_write(TIMER_TIMER1, -1);
+    apb_write(TIMER_RELOAD1, -1);
+    apb_write(TIMER_CTRL1, 0x7);
+//    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
+    sregs.wim = 2;
+    sregs.psr = 0x000010e0;
+    sregs.r[30] = RAM_END;
+    sregs.r[14] = sregs.r[30] - 96*4;
+    cache_ctrl = 0x01000f;
+
+}
+
+struct memsys leon2 = {
+    init_sim,
+    reset,
+    error_mode,
+    sim_halt,
+    exit_sim,
+    init_stdio,
+    restore_stdio,
+    memory_iread,
+    memory_read,
+    memory_read_asi,
+    memory_write,
+    memory_write_asi,
+    sis_memory_write,
+    sis_memory_read,
+    boot_init
+};
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index 68ec319..f21ddde 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -180,6 +180,10 @@ main(argc, argv)
 		dumbio = 1;
             } else if (strcmp(argv[stat], "-nouartrx") == 0) {
 		nouartrx = 1;
+            } else if (strcmp(argv[stat], "-leon2") == 0) {
+		ms = &leon2;
+                if (freq == 14) freq = 50;
+                cputype = CPU_LEON2;
             } else if (strcmp(argv[stat], "-leon3") == 0) {
 		ms = &leon3;
                 if (freq == 14) freq = 50;
@@ -200,6 +204,9 @@ main(argc, argv)
     }
 
     switch (cputype) {
+    case CPU_LEON2:	
+	printf(" LEON2 emulation enabled\n");
+	break;
     case CPU_LEON3:	
 	printf(" LEON3 emulation enabled\n");
 	break;
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 98e0e38..637549a 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -184,6 +184,7 @@ struct memsys {
 #define ERROR 3
 #define CTRL_C 4
 
+#define CPU_LEON2  2
 #define CPU_LEON3  3
 
 /* Prototypes  */
@@ -264,5 +265,8 @@ extern void	gen_help (void);
 
 extern struct memsys *ms;
 
+/* leon2.c */
+extern struct memsys leon2;
+
 /* leon3.c */
 extern struct memsys leon3;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 12/23] sim/erc32: Use separate memory_iread() function for instruction fetching.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (16 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 21/23] sim/erc32: add data watchpoint support for all cpu targets Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  7:46 ` [PATCH 13/23] sim/erc32: Fix a few compiler warnings Jiri Gaisler
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Use separate memory_iread() function for instruction fetching.
	Speeds up execution and allows addition of an MMU at a later stage.

	* erc32.c (memory_iread) New function to fetch instructions.
	* interf.c  (run_sim) Use memory_iread.
	* sis.c (run_sim) As above.
---
 sim/erc32/erc32.c  | 24 ++++++++++++++++++++++++
 sim/erc32/interf.c |  5 ++---
 sim/erc32/sis.c    |  8 ++------
 sim/erc32/sis.h    |  2 ++
 4 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index c4474af..34a15de 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -1566,6 +1566,30 @@ store_bytes (mem, waddr, data, sz, ws)
 /* Memory emulation */
 
 int
+memory_iread(addr, data, ws)
+    uint32          addr;
+    uint32         *data;
+    int32          *ws;
+{
+    uint32          asi;
+    if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
+        *data = *((uint32 *) & (ramb[addr & mem_rammask & ~3]));
+	*ws = mem_ramr_ws;
+	return (0);
+    } else if (addr < mem_romsz) {
+        *data = *((uint32 *) & (romb[addr & ~3]));
+	*ws = mem_romr_ws;
+	return (0);
+    }
+
+    printf("Memory exception at %x (illegal address)\n", addr);
+    if (sregs.psr & 0x080) asi = 9; else asi = 8;
+    set_sfsr(UIMP_ACC, addr, asi, 1);
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+int
 memory_read(asi, addr, data, sz, ws)
     int32           asi;
     uint32          addr;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 3a72e7f..981aa11 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -94,9 +94,8 @@ run_sim(sregs, icount, dis)
             if (sregs->pc == 0 || sregs->npc == 0)
                 printf ("bogus pc or npc\n");
 #endif
-        mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst,
-                           2, &sregs->hold);
-#if 1	/* DELETE ME! for debugging purposes only */
+        mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
+#if 0	/* DELETE ME! for debugging purposes only */
         if (sis_verbose > 2)
             printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
                    sregs->pc, sregs->npc,
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index c6e9714..8bc2283 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -83,7 +83,7 @@ run_sim(sregs, icount, dis)
     uint64          icount;
     int             dis;
 {
-    int             irq, mexc, deb, asi;
+    int             irq, mexc, deb;
 
     sregs->starttime = get_time();
     init_stdio();
@@ -92,11 +92,7 @@ run_sim(sregs, icount, dis)
     irq = 0;
     while (icount > 0) {
 
-	if (sregs->psr & 0x080)
-	    asi = 9;
-   	else
-	    asi = 8;
-	mexc = memory_read(asi, sregs->pc, &sregs->inst, 2, &sregs->hold);
+	mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
 	sregs->icnt = 1;
 	if (sregs->annul) {
 	    sregs->annul = 0;
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 330036b..604d344 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -170,6 +170,7 @@ extern void	sim_halt (void);
 extern void	exit_sim (void);
 extern void	init_stdio (void);
 extern void	restore_stdio (void);
+extern int	memory_iread (uint32 addr, uint32 *data, int32 *ws);
 extern int	memory_read (int32 asi, uint32 addr, uint32 *data,
 			     int32 sz, int32 *ws);
 extern int	memory_write (int32 asi, uint32 addr, uint32 *data,
@@ -180,6 +181,7 @@ extern int	sis_memory_read (uint32 addr, char *data,
 				 uint32 length);
 
 /* func.c */
+extern struct pstate  sregs;
 extern void	set_regi (struct pstate *sregs, int32 reg,
 			  uint32 rval);
 extern void	get_regi (struct pstate *sregs, int32 reg, char *buf);
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 11/23] sim/erc32: use AC_C_BIGENDIAN to probe for host endian.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (11 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 14/23] sim/erc32: Use gdb callback for UART I/O when linked with gdb Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  9:19   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address Jiri Gaisler
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Use  AC_C_BIGENDIAN to probe for host endian during build, rather
	then run-time checks throgh end.c.

	* Makefile.in (end, end.h) Remove target rules.
	* end.c Remove unnecessary local checks (end.c)
	* configure, config.in : Regenerate.
	* configure.ac : Use AC_C_BIGENDIAN
	* end.c : Remove.
	* erc32.c : Remove dependecy on end.h
	* exec.c : Remove dependecy on end.h. Use HOST_LITTLE_ENDIAN.
	* func.c : As abve.
	* sis.c : As abve.
---
 sim/erc32/Makefile.in  |  24 ++----
 sim/erc32/config.in    |  15 ++++
 sim/erc32/configure    | 225 +++++++++++++++++++++++++++++++++++++++++++++++++
 sim/erc32/configure.ac |   1 +
 sim/erc32/end.c        |  27 ------
 sim/erc32/erc32.c      |   1 -
 sim/erc32/exec.c       |   7 +-
 sim/erc32/func.c       |   3 +-
 sim/erc32/sis.h        |   8 +-
 9 files changed, 259 insertions(+), 52 deletions(-)
 delete mode 100644 sim/erc32/end.c

diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
index 52291b3..f1d79cd 100644
--- a/sim/erc32/Makefile.in
+++ b/sim/erc32/Makefile.in
@@ -41,21 +41,13 @@ sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS)
 	$(CC) $(ALL_CFLAGS) -o sis \
 	  sis.o $(SIS_OFILES) $(COMMON_OBJS) $(EXTRA_LIBS)
 
-# FIXME: This computes the build host's endianness, doesn't it?
-# There is AC_C_BIGENDIAN but it doesn't handle float endianness.
-# [Are int/float endians every different on a sparc?]
-end: $(srcdir)/end.c
-	$(CC_FOR_BUILD) -I. $(srcdir)/end.c -o end
-end.h: end
-	./end > end.h
-
 # Copy the files into directories where they will be run.
 install-sis: installdirs
 	n=`echo sis | sed '$(program_transform_name)'`; \
 	$(INSTALL_PROGRAM) sis$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT)
 
 clean-sis:
-	rm -f sis end end.h
+	rm -f sis
 
 configure:
 	@echo "Rebuilding configure..."
@@ -65,10 +57,10 @@ configure:
 	(cd $${srcdir}; autoconf --localdir=../common)
 
 # Circumvent Sun Make bug with VPATH.
-erc32.o: erc32.c sis.h end.h
-exec.o: exec.c sis.h end.h
-float.o: float.c sis.h end.h
-func.o: func.c sis.h end.h
-help.o: help.c sis.h end.h
-interf.o: interf.c sis.h end.h 
-sis.o: sis.c sis.h end.h
+erc32.o: erc32.c sis.h
+exec.o: exec.c sis.h
+float.o: float.c sis.h
+func.o: func.c sis.h
+help.o: help.c sis.h
+interf.o: interf.c sis.h
+sis.o: sis.c sis.h
diff --git a/sim/erc32/config.in b/sim/erc32/config.in
index 5fed8c1..b367e14 100644
--- a/sim/erc32/config.in
+++ b/sim/erc32/config.in
@@ -1,5 +1,8 @@
 /* config.in.  Generated from configure.ac by autoheader.  */
 
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
 /* Define to 1 if translation of program messages to the user's native
    language is requested. */
 #undef ENABLE_NLS
@@ -135,6 +138,18 @@
 #endif
 
 
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
 /* Define to 1 if on MINIX. */
 #undef _MINIX
 
diff --git a/sim/erc32/configure b/sim/erc32/configure
index ba43717..ed7a881 100755
--- a/sim/erc32/configure
+++ b/sim/erc32/configure
@@ -13110,6 +13110,230 @@ fi
 
 fi
 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+	     #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
 
 ac_sources="$sim_link_files"
 ac_dests="$sim_link_links"
@@ -13245,6 +13469,7 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
+
 : ${CONFIG_STATUS=./config.status}
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
diff --git a/sim/erc32/configure.ac b/sim/erc32/configure.ac
index bc46091..1646cc5 100644
--- a/sim/erc32/configure.ac
+++ b/sim/erc32/configure.ac
@@ -32,4 +32,5 @@ else
 	       AC_ERROR([the required "readline" library is missing]), $TERMCAP)
 fi
 AC_SUBST(READLINE)
+AC_C_BIGENDIAN
 SIM_AC_OUTPUT
diff --git a/sim/erc32/end.c b/sim/erc32/end.c
deleted file mode 100644
index 9337198..0000000
--- a/sim/erc32/end.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "config.h"
-#include <stdio.h>
-
-int
-main()
-{
-
-    unsigned int    u1;
-    char           *c;
-    double          d1;
-    float          *f1;
-
-    c = (char *) &u1;
-    u1 = 0x0F;
-    if (c[0] == 0x0F)
-	puts("#define HOST_LITTLE_ENDIAN\n");
-    else
-	puts("#define HOST_BIG_ENDIAN\n");
-
-    d1 = 1.0;
-    f1 = (float *) &d1;
-    if (*((int *) f1) != 0x3ff00000)
-	puts("#define HOST_LITTLE_ENDIAN_FLOAT\n");
-    else
-	puts("#define HOST_BIG_ENDIAN_FLOAT\n");
-    return 0;
-}
diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 152eb1e..c4474af 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -30,7 +30,6 @@
 #include <sys/file.h>
 #include <unistd.h>
 #include "sis.h"
-#include "end.h"
 #include "sim-config.h"
 
 extern int      ctrl_c;
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index e80e02a..237bb53 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -21,7 +21,6 @@
 
 #include "config.h"
 #include "sis.h"
-#include "end.h"
 #include <math.h>
 #include <stdio.h>
 
@@ -1736,7 +1735,7 @@ fpexec(op3, rd, rs1, rs2, sregs)
        but what about machines where float values are different endianness
        from integer values? */
 
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     rs1 &= 0x1f;
     switch (opf) {
 	case FADDd:
@@ -1914,7 +1913,7 @@ fpexec(op3, rd, rs1, rs2, sregs)
 
     accex = get_accex();
 
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     switch (opf) {
     case FADDd:
     case FDIVd:
@@ -2061,7 +2060,7 @@ init_regs(sregs)
     sregs->err_mode = 0;
     ext_irl = 0;
     sregs->g[0] = 0;
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     sregs->fdp = (float32 *) sregs->fd;
     sregs->fsi = (int32 *) sregs->fs;
 #else
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index 25ecd14..ee45b3b 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -26,7 +26,6 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include "sis.h"
-#include "end.h"
 #include <dis-asm.h>
 #include "sim-config.h"
 
@@ -726,7 +725,7 @@ disp_fpu(sregs)
 
     printf("\n fsr: %08X\n\n", sregs->fsr);
 
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     for (i = 0; i < 32; i++)
       sregs->fdp[i ^ 1] = sregs->fs[i];
 #endif
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index dc02c65..330036b 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -24,7 +24,11 @@
 #include "gdb/callback.h"
 #include "gdb/remote-sim.h"
 
-#include "end.h"
+#ifdef WORDS_BIGENDIAN
+#define HOST_BIG_ENDIAN
+#else
+#define HOST_LITTLE_ENDIAN
+#endif
 
 #define I_ACC_EXC 1
 
@@ -60,7 +64,7 @@ typedef long long int64;	   /* 64-bit signed int */
 struct pstate {
 
     float64         fd[16];	/* FPU registers */
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     float32         fs[32];
     float32        *fdp;
 #else
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 13/23] sim/erc32: Fix a few compiler warnings
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (17 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 12/23] sim/erc32: Use separate memory_iread() function for instruction fetching Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17 11:08   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation Jiri Gaisler
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Minor edits to remove compiler warnings.
---
 sim/erc32/interf.c | 2 +-
 sim/erc32/sis.h    | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 981aa11..f03f1d5 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -509,7 +509,7 @@ sim_do_command(sd, cmd)
      SIM_DESC sd;
      const char *cmd;
 {
-    exec_cmd(&sregs, cmd);
+    exec_cmd(&sregs, (char *) cmd);
 }
 
 char **
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 604d344..e2bed36 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -203,7 +203,6 @@ extern int	check_bpt (struct pstate *sregs);
 extern void	reset_all (void);
 extern void	sys_reset (void);
 extern void	sys_halt (void);
-extern int	bfd_load (char *fname);
 extern double	get_time (void);
 
 /* exec.c */
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 21/23] sim/erc32: add data watchpoint support for all cpu targets.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (15 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 22/23] Added watchpoint support to gdb simulator interface Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  7:46 ` [PATCH 12/23] sim/erc32: Use separate memory_iread() function for instruction fetching Jiri Gaisler
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Add watchpoint to all processor targets (erc32, leon2, leon3).
---
 sim/erc32/exec.c | 54 +++++++++++++++++++++++++++------
 sim/erc32/func.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 sim/erc32/sis.c  | 32 +++++++++++++++-----
 sim/erc32/sis.h  | 23 +++++++++++++-
 4 files changed, 180 insertions(+), 21 deletions(-)

diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index f812ad9..a81089a 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -395,6 +395,20 @@ extract_byte_signed(uint32 data, uint32 address)
     return(tmp);
 }
 
+/* Decode watchpoint address mask from opcode. Not correct for LDST,
+   SWAP and STFSR but watchpoints will work anyway. */
+
+static unsigned char
+wpmask(uint32 op3)
+{
+    switch (op3 & 3) {
+      case 0: return(3);  /* word */
+      case 1: return(0);  /* byte */
+      case 2: return(1);  /* half-word */
+      case 3: return(7);  /* double word */
+    }
+}
+
 int
 dispatch_instruction(sregs)
     struct pstate  *sregs;
@@ -698,6 +712,12 @@ dispatch_instruction(sregs)
 		}
 		if (eicc & 1) {
 		    sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f));
+		    if ((sregs->trap == 129) && (sis_gdb_break) &&
+		    		(sregs->inst == 0x91d02001))
+		    {
+			sregs->trap = WPT_TRAP;
+			sregs->bphit = 1;
+		    }
 		}
 		break;
 
@@ -1211,18 +1231,25 @@ dispatch_instruction(sregs)
 
 	address = rs1 + operand2;
 
-	if (sregs->psr & PSR_S)
-	    asi = 11;
-	 else
-	    asi = 10;
-
 	if (op3 & 4) {
 	    sregs->icnt = T_ST;	/* Set store instruction count */
+	    if (sregs->wpwnum) {
+	       if (sregs->wphit = check_wpw(sregs, address, wpmask(op3))) {
+	           sregs->trap = WPT_TRAP;
+		   break;
+	       }
+	    }
 #ifdef STAT
 	    sregs->nstore++;
 #endif
 	} else {
 	    sregs->icnt = T_LD;	/* Set load instruction count */
+	    if (sregs->wprnum) {
+	       if (sregs->wphit = check_wpr(sregs, address, wpmask(op3))) {
+	           sregs->trap = WPT_TRAP;
+		   break;
+	       }
+	    }
 #ifdef STAT
 	    sregs->nload++;
 #endif
@@ -2133,12 +2160,18 @@ execute_trap(sregs)
 {
     int32           cwp;
 
-    if (sregs->trap == 256) {
-	sregs->pc = 0;
-	sregs->npc = 4;
-	sregs->trap = 0;
-    } else if (sregs->trap == 257) {
+    if (sregs->trap >= 256) {
+	switch (sregs->trap) {
+	case 256:
+	    sregs->pc = 0;
+	    sregs->npc = 4;
+	    sregs->trap = 0;
+	    break;
+	case ERROR_TRAP:
 	    return (ERROR);
+	case WPT_TRAP:
+	    return (WPT_HIT);
+	}
     } else {
 
 	if ((sregs->psr & PSR_ET) == 0)
@@ -2231,6 +2264,7 @@ init_regs(sregs)
     sregs->fpu_pres = !nfp;
     set_fsr(sregs->fsr);
     sregs->bphit = 0;
+    sregs->wphit = 0;
     sregs->ildreg = 0;
     sregs->ildtime = 0;
 
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index 6f985a1..b4e0755 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -60,7 +60,8 @@ uint32		last_load_addr = 0;
 int		nouartrx = 0;
 host_callback 	*sim_callback;
 struct memsys *ms = &erc32sys;
-int		cputype = 0;		/* 0 = erc32, 3 = leon3 */
+int		cputype = 0;		/* 0 = erc32, 2 = leon2,3 = leon3 */
+int             sis_gdb_break;
 
 #ifdef ERRINJ
 uint32		errcnt = 0;
@@ -619,7 +620,54 @@ exec_cmd(sregs, cmd)
 	    stat = run_sim(sregs, UINT64_MAX, 0);
 	    daddr = sregs->pc;
 	    ms->sim_halt();
-	} else
+	} else if (strncmp(cmd1, "wp", clen) == 0) {
+	    for (i = 0; i < sregs->wprnum; i++) {
+		printf("  %d : 0x%08x (read)\n", i + 1, sregs->wprs[i]);
+	    }
+	    for (i = 0; i < sregs->wpwnum; i++) {
+		printf("  %d : 0x%08x (write)\n", i + 1, sregs->wpws[i]);
+	    }
+	} else if (strncmp(cmd1, "+wpr", clen) == 0) {
+	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+		sregs->wprs[sregs->wprnum] = VAL(cmd1) & ~0x3;
+		sregs->wprm[sregs->wprnum] = 3;
+		printf("added read watchpoint %d at 0x%08x\n",
+		       sregs->wprnum + 1, sregs->wprs[sregs->wprnum]);
+		sregs->wprnum += 1;
+	    }
+	} else if (strncmp(cmd1, "-wpr", clen) == 0) {
+	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+		i = VAL(cmd1) - 1;
+		if ((i >= 0) && (i < sregs->wprnum)) {
+		    printf("deleted read watchpoint %d at 0x%08x\n", i + 1,
+			   sregs->wprs[i]);
+		    for (; i < sregs->wprnum - 1; i++) {
+			sregs->wprs[i] = sregs->wprs[i + 1];
+		    }
+		    sregs->wprnum -= 1;
+		}
+	    }
+	} else if (strncmp(cmd1, "+wpw", clen) == 0) {
+	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+		sregs->wpws[sregs->wpwnum] = VAL(cmd1) & ~0x3;
+		sregs->wpwm[sregs->wpwnum] = 3;
+		printf("added write watchpoint %d at 0x%08x\n",
+		       sregs->wpwnum + 1, sregs->wpws[sregs->wpwnum]);
+		sregs->wpwnum += 1;
+	    }
+	} else if (strncmp(cmd1, "-wpw", clen) == 0) {
+	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+		i = VAL(cmd1) - 1;
+		if ((i >= 0) && (i < sregs->wpwnum)) {
+		    printf("deleted write watchpoint %d at 0x%08x\n", i + 1,
+			   sregs->wpws[i]);
+		    for (; i < sregs->wpwnum - 1; i++) {
+			sregs->wpws[i] = sregs->wpws[i + 1];
+		    }
+		    sregs->wpwnum -= 1;
+		}
+	    }
+	} else 
 	    printf("syntax error\n");
     }
     if (cmdsave != NULL)
@@ -703,6 +751,8 @@ init_bpt(sregs)
     struct pstate  *sregs;
 {
     sregs->bptnum = 0;
+    sregs->wprnum = 0;
+    sregs->wpwnum = 0;
     sregs->histlen = 0;
     sregs->histind = 0;
     sregs->histbuf = NULL;
@@ -1012,6 +1062,44 @@ check_bpt(sregs)
     return (0);
 }
 
+int
+check_wpr(sregs, address, mask)
+    struct pstate  *sregs;
+    int32          address;
+    unsigned char  mask;
+{
+    int32           i, msk;
+
+    for (i = 0; i < sregs->wprnum; i++) {
+	msk = ~(mask | sregs->wprm[i]);
+	if (((address ^ sregs->wprs[i]) & msk) == 0) {
+	    sregs->wpaddress = address;
+            if (sregs->wphit) return (0);
+	    return (WPT_HIT);
+	}
+    }
+    return (0);
+}
+
+int
+check_wpw(sregs, address, mask)
+    struct pstate  *sregs;
+    int32          address;
+    unsigned char  mask;
+{
+    int32           i, msk;
+
+    for (i = 0; i < sregs->wpwnum; i++) {
+	msk = ~(mask | sregs->wpwm[i]);
+	if (((address ^ sregs->wpws[i]) & msk) == 0) {
+	    sregs->wpaddress = address;
+            if (sregs->wphit) return (0);
+	    return (WPT_HIT);
+	}
+    }
+    return (0);
+}
+
 void
 reset_all()
 {
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index f21ddde..345f867 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -74,11 +74,7 @@ run_sim(sregs, icount, dis)
 		    sregs->trap = I_ACC_EXC;
 		} else {
 		    if (deb) {
-	    		if ((sregs->bphit = check_bpt(sregs)) != 0) {
-            		    ms->restore_stdio();
-	    		    return (BPT_HIT);
-	    		}
-		        if (sregs->histlen) {
+			if (sregs->histlen) {
 			    sregs->histbuf[sregs->histind].addr = sregs->pc;
 			    sregs->histbuf[sregs->histind].time = ebase.simtime;
 			    sregs->histind++;
@@ -89,14 +85,25 @@ run_sim(sregs, icount, dis)
 			    printf(" %8llu ", ebase.simtime);
 			    dis_mem(sregs->pc, 1, &dinfo);
 		        }
+			if ((sregs->bptnum) && (sregs->bphit = check_bpt(sregs)))
+	                    icount = 0;
+			else {
+		            dispatch_instruction(sregs);
+		            icount--;
+			}
+		    } else {
+		        dispatch_instruction(sregs);
+		        icount--;
 		    }
-		    dispatch_instruction(sregs);
-		    icount--;
 		}
 	    }
 	    if (sregs->trap) {
 		irq = 0;
-		sregs->err_mode = execute_trap(sregs);
+		if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
+		    sregs->err_mode = 0;
+                    sregs->trap = 0;
+	            icount = 0;
+		}
         	if (sregs->err_mode) {
 	            ms->error_mode(sregs->pc);
 	            icount = 0;
@@ -117,6 +124,10 @@ run_sim(sregs, icount, dis)
 	ctrl_c = 0;
 	return (CTRL_C);
     }
+    if (sregs->bphit)
+        return (BPT_HIT);
+    if (sregs->wphit)
+        return (WPT_HIT);
     return (TIME_OUT);
 }
 
@@ -283,6 +294,11 @@ main(argc, argv)
 	    printf(" %8llu ", ebase.simtime);
 	    dis_mem(sregs.pc, 1, &dinfo);
 	    break;
+	case WPT_HIT:
+	    printf("watchpoint at 0x%08x reached, pc = 0x%08x\n",
+	        sregs.wpaddress, sregs.pc);
+	    sregs.wphit = 1;
+	    break;
 	default:
 	    break;
 	}
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 637549a..93e0da9 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -38,8 +38,10 @@
 /* Maximum # of floating point queue */
 #define FPUQN	1
 
-/* Maximum # of breakpoints */
+/* Maximum # of breakpoints and watchpoints */
 #define BPT_MAX	256
+#define WPR_MAX	256
+#define WPW_MAX	256
 
 struct histype {
     unsigned        addr;
@@ -102,6 +104,14 @@ struct pstate {
     uint32          bptnum;
     uint32          bphit;
     uint32          bpts[BPT_MAX];	/* Breakpoints */
+    uint32          wprnum;
+    uint32          wphit;
+    uint32          wprs[WPR_MAX];	/* Read Watchpoints */
+    unsigned char   wprm[WPR_MAX];	/* Read Watchpoint masks*/
+    uint32          wpwnum;
+    uint32          wpws[WPW_MAX];	/* Write Watchpoints */
+    unsigned char   wpwm[WPW_MAX];	/* Write Watchpoint masks */
+    uint32          wpaddress;
 
     uint32          ltime;	/* Load interlock time */
     uint32          hold;	/* IU hold cycles in current inst */
@@ -178,12 +188,19 @@ struct memsys {
 };
 
 
+/* return values for run_sim */
 #define OK 0
 #define TIME_OUT 1
 #define BPT_HIT 2
 #define ERROR 3
 #define CTRL_C 4
+#define WPT_HIT 5
 
+/* special simulator trap types */
+#define ERROR_TRAP 257
+#define WPT_TRAP   258
+
+/* cpu type defines */
 #define CPU_LEON2  2
 #define CPU_LEON3  3
 
@@ -234,6 +251,9 @@ extern void	advance_time (struct pstate  *sregs);
 extern uint32	now (void);
 extern int	wait_for_irq (void);
 extern int	check_bpt (struct pstate *sregs);
+extern int 	check_wpr(struct pstate *sregs, int32 address, unsigned char mask);
+extern int 	check_wpw(struct pstate *sregs, int32 address, unsigned char mask);
+
 extern void	reset_all (void);
 extern void	sys_reset (void);
 extern void	sys_halt (void);
@@ -243,6 +263,7 @@ extern          host_callback *sim_callback;
 extern int	current_target_byte_order;
 extern int      dumbio;
 extern int      cputype;
+extern int	sis_gdb_break;
 
 /* exec.c */
 extern int	dispatch_instruction (struct pstate *sregs);
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 22/23] Added watchpoint support to gdb simulator interface.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (14 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 08/23] sim/erc32: added -v and -vv command line switches for verbose output Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  7:46 ` [PATCH 21/23] sim/erc32: add data watchpoint support for all cpu targets Jiri Gaisler
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Currently, only thw sparc sim supports watchpoints. Stubs for the
	watchpoint functions were added to all other built-in sims
	to avoid linking errors.
---
 gdb/remote-sim.c              |  69 +++++++++++++
 include/gdb/remote-sim.h      |  24 +++++
 sim/arm/wrapper.c             |  26 +++++
 sim/avr/interp.c              |  25 +++++
 sim/bfin/Makefile.in          |   1 +
 sim/common/sim-watch-remote.c |  27 +++++
 sim/cr16/interp.c             |  26 +++++
 sim/cris/Makefile.in          |   1 +
 sim/erc32/interf.c            | 235 ++++++++++++++++++++++++++++++++----------
 sim/frv/Makefile.in           |   1 +
 sim/h8300/Makefile.in         |   1 +
 sim/iq2000/Makefile.in        |   1 +
 sim/lm32/Makefile.in          |   1 +
 sim/m32c/gdb-if.c             |  26 +++++
 sim/m32r/Makefile.in          |   1 +
 sim/m68hc11/Makefile.in       |   1 +
 sim/mcore/interp.c            |  26 +++++
 sim/microblaze/Makefile.in    |   2 +-
 sim/mips/Makefile.in          |   1 +
 sim/mn10300/Makefile.in       |   1 +
 sim/moxie/interp.c            |  26 +++++
 sim/msp430/Makefile.in        |   1 +
 sim/ppc/gdb-sim.c             |  26 +++++
 sim/rl78/gdb-if.c             |  26 +++++
 sim/rx/gdb-if.c               |  26 +++++
 sim/sh/interp.c               |  26 +++++
 sim/sh64/Makefile.in          |   1 +
 sim/v850/Makefile.in          |   3 +-
 28 files changed, 577 insertions(+), 54 deletions(-)
 create mode 100644 sim/common/sim-watch-remote.c

diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index 8901548..4721860 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -1294,6 +1294,70 @@ gdbsim_has_memory (struct target_ops *ops)
   return 1;
 }
 
+static int
+gdbsim_insert_watchpoint (struct target_ops *self,
+			CORE_ADDR addr, int len, int type,
+			struct expression *cond)
+{
+  struct sim_inferior_data *sim_data
+      = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+
+  if (remote_debug)
+    fprintf_unfiltered (gdb_stdlog, "gdbsim_insert_watchpoint: %d\n", type);
+
+  if (sim_set_watchpoint (sim_data->gdbsim_desc, addr, len, type) != SIM_RC_OK)
+    return -1;
+
+  return 0;
+}
+
+static int
+gdbsim_remove_watchpoint (struct target_ops *self,
+			CORE_ADDR addr, int len, int type,
+			struct expression *cond)
+{
+  struct sim_inferior_data *sim_data
+      = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+
+  if (remote_debug)
+    fprintf_unfiltered (gdb_stdlog, "gdbsim_remove_watchpoint: %d\n", type);
+
+  if (sim_clear_watchpoint (sim_data->gdbsim_desc, addr, len, type) != SIM_RC_OK)
+    return -1;
+
+  return 0;
+}
+
+
+static int
+gdbsim_can_use_hw_breakpoint (struct target_ops *self,
+			 int type, int cnt, int othertype)
+{
+  struct sim_inferior_data *sim_data
+      = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+
+  return (sim_can_use_hw_breakpoint(sim_data->gdbsim_desc, type, cnt, othertype));
+}
+
+static int
+gdbsim_stopped_by_watchpoint (struct target_ops *ops)
+{
+  struct sim_inferior_data *sim_data
+      = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+
+  return (sim_stopped_by_watchpoint(sim_data->gdbsim_desc));;
+}
+
+static int
+gdbsim_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr)
+{
+  struct sim_inferior_data *sim_data
+      = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+
+  *addr = sim_watchpoint_address(sim_data->gdbsim_desc);;
+  return (1);
+}
+
 /* Define the target subroutine names.  */
 
 struct target_ops gdbsim_ops;
@@ -1316,6 +1380,11 @@ init_gdbsim_ops (void)
   gdbsim_ops.to_files_info = gdbsim_files_info;
   gdbsim_ops.to_insert_breakpoint = memory_insert_breakpoint;
   gdbsim_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  gdbsim_ops.to_insert_watchpoint = gdbsim_insert_watchpoint;
+  gdbsim_ops.to_remove_watchpoint = gdbsim_remove_watchpoint;
+  gdbsim_ops.to_stopped_by_watchpoint = gdbsim_stopped_by_watchpoint;
+  gdbsim_ops.to_can_use_hw_breakpoint = gdbsim_can_use_hw_breakpoint;
+  gdbsim_ops.to_stopped_data_address = gdbsim_stopped_data_address;
   gdbsim_ops.to_kill = gdbsim_kill;
   gdbsim_ops.to_load = gdbsim_load;
   gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
diff --git a/include/gdb/remote-sim.h b/include/gdb/remote-sim.h
index c335d4f..ac2c474 100644
--- a/include/gdb/remote-sim.h
+++ b/include/gdb/remote-sim.h
@@ -280,6 +280,30 @@ void sim_do_command (SIM_DESC sd, const char *cmd);
 
 char **sim_complete_command (SIM_DESC sd, const char *text, const char *word);
 
+/* Add hardware watchpoint. See to_insert_watchpoint() in target.h
+   for description of parameters. */
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type);
+
+/* Remove hardware watchpoint. See to_remove_watchpoint() in target.h
+   for description of parameters. */
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type);
+
+/* Returns data address when watchpoint has been hit. See
+   to_stopped_data_address() in target.h for description. */
+
+int sim_watchpoint_address (SIM_DESC sd);
+
+/* Returns 1 if simulator was stopped by watchpoint hit. */
+
+int sim_stopped_by_watchpoint(SIM_DESC sd);
+
+/* Returns non-zero if we can set a hardware watchpoint of type TYPE.
+   See to_can_use_hw_breakpoint() in target.h for details. */
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c
index 132beff..56b2bb3 100644
--- a/sim/arm/wrapper.c
+++ b/sim/arm/wrapper.c
@@ -1016,3 +1016,29 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
 {
   return NULL;
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/avr/interp.c b/sim/avr/interp.c
index 7c8f81b..36eec32 100644
--- a/sim/avr/interp.c
+++ b/sim/avr/interp.c
@@ -1859,3 +1859,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
 {
   return NULL;
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+	  return 0;
+}
diff --git a/sim/bfin/Makefile.in b/sim/bfin/Makefile.in
index 69b4cca..f0af3ed 100644
--- a/sim/bfin/Makefile.in
+++ b/sim/bfin/Makefile.in
@@ -39,6 +39,7 @@ SIM_OBJS = \
 	sim-reg.o \
 	sim-resume.o \
 	sim-stop.o \
+	sim-watch-remote.o \
 	@BFIN_SIM_EXTRA_OBJS@ \
 	$(SIM_EXTRA_OBJS)
 
diff --git a/sim/common/sim-watch-remote.c b/sim/common/sim-watch-remote.c
new file mode 100644
index 0000000..279bb06
--- /dev/null
+++ b/sim/common/sim-watch-remote.c
@@ -0,0 +1,27 @@
+
+#include "gdb/remote-sim.h"
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
diff --git a/sim/cr16/interp.c b/sim/cr16/interp.c
index e04ccc4..c5d5c8d 100644
--- a/sim/cr16/interp.c
+++ b/sim/cr16/interp.c
@@ -1584,3 +1584,29 @@ sim_load (SIM_DESC sd, const char *prog, struct bfd *abfd, int from_tty)
   prog_bfd_was_opened_p = abfd == NULL;
   return SIM_RC_OK;
 } 
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/cris/Makefile.in b/sim/cris/Makefile.in
index 2f3ef57..555992c 100644
--- a/sim/cris/Makefile.in
+++ b/sim/cris/Makefile.in
@@ -30,6 +30,7 @@ SIM_OBJS = \
 	sim-hrw.o \
 	sim-model.o \
 	sim-reg.o \
+	sim-watch-remote.o \
 	cgen-utils.o cgen-trace.o cgen-scache.o \
 	cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
 	sim-if.o arch.o \
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 9b3666a..f5474d3 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -36,8 +36,6 @@
 
 #define PSR_CWP 0x7
 
-int             sis_gdb_break = 1;
-
 int
 run_sim(sregs, icount, dis)
     struct pstate  *sregs;
@@ -52,37 +50,14 @@ run_sim(sregs, icount, dis)
    ms->init_stdio();
    sregs->starttime = get_time();
    irq = 0;
+   if (sregs->err_mode) icount = 0;
    if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
-   while (!sregs->err_mode & (icount > 0)) {
-
+   while (icount > 0) {
 	sregs->fhold = 0;
-	sregs->hold = 0;
 	sregs->icnt = 1;
-
-        if (sregs->psr & 0x080)
-            sregs->asi = 8;
-        else
-            sregs->asi = 9;
-
-#if 0	/* DELETE ME! for debugging purposes only */
-        if (sis_verbose > 1)
-            if (sregs->pc == 0 || sregs->npc == 0)
-                printf ("bogus pc or npc\n");
-#endif
         mexc = ms->memory_iread(sregs->pc, &sregs->inst, &sregs->hold);
-#if 0	/* DELETE ME! for debugging purposes only */
-        if (sis_verbose > 2)
-            printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
-                   sregs->pc, sregs->npc,
-                   sregs->r[(((sregs->psr & 7) << 4) + 14) & 0x7f],
-                   sregs->r[(((sregs->psr & 7) << 4) + 30) & 0x7f],
-                   sregs->wim,
-                   sregs->psr & 7,
-                   sregs->inst);
-#endif
         if (sregs->annul) {
             sregs->annul = 0;
-            sregs->icnt = 1;
             sregs->pc = sregs->npc;
             sregs->npc = sregs->npc + 4;
         } else {
@@ -91,47 +66,40 @@ run_sim(sregs, icount, dis)
 		if (mexc) {
 		    sregs->trap = I_ACC_EXC;
 		} else {
-		    if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
-			if (sis_verbose)
-			    (*sim_callback->printf_filtered) (sim_callback,
-							      "SW BP hit at %x\n", sregs->pc);
-                        ms->sim_halt();
-			ms->restore_stdio();
-			clearerr(stdin);
-			return (BPT_HIT);
-		    } else
-			dispatch_instruction(sregs);
+		    dispatch_instruction(sregs);
+		    icount--;
 		}
-		icount--;
 	    }
 	    if (sregs->trap) {
                 irq = 0;
-		sregs->err_mode = execute_trap(sregs);
+		if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
+		    sregs->err_mode = 0;
+		    sregs->trap = 0;
+		    icount = 0;
+		}
+		if (sregs->err_mode) icount = 0;
+
 	    }
 	}
 	advance_time(sregs);
-	if (ctrl_c) {
+	if (ctrl_c) 
 	    icount = 0;
-	}
     }
     ms->sim_halt();
     sregs->tottime += get_time() - sregs->starttime;
     ms->restore_stdio();
     clearerr(stdin);
-    if (sregs->err_mode)
+    if (sregs->err_mode) {
 	ms->error_mode(sregs->pc);
-    if (sregs->err_mode)
 	return (ERROR);
-    if (sregs->bphit) {
-	if (sis_verbose)
-	    (*sim_callback->printf_filtered) (sim_callback,
-					      "HW BP hit at %x\n", sregs->pc);
-	return (BPT_HIT);
     }
     if (ctrl_c) {
 	ctrl_c = 0;
+	sregs->wphit = sregs->bphit = 0;
 	return (CTRL_C);
     }
+    if ((sregs->bphit) || (sregs->wphit))
+	return (BPT_HIT);
     return (TIME_OUT);
 }
 
@@ -161,6 +129,7 @@ sim_open (kind, callback, abfd, argv)
     int             freq = 0;
 
     sim_callback = callback;
+    sis_gdb_break = 1;
 
     while (argv[argc])
       argc++;
@@ -413,12 +382,15 @@ sim_stop_reason(sd, reason, sigrc)
 {
 
     switch (simstat) {
-	case CTRL_C:
+    case CTRL_C:
 	*reason = sim_stopped;
 	*sigrc = GDB_SIGNAL_INT;
 	break;
     case OK:
     case TIME_OUT:
+	*reason = sim_stopped;
+	*sigrc = 0;
+	break;
     case BPT_HIT:
 	*reason = sim_stopped;
 	*sigrc = GDB_SIGNAL_TRAP;
@@ -427,8 +399,10 @@ sim_stop_reason(sd, reason, sigrc)
 	*sigrc = 0;
 	*reason = sim_exited;
     }
-    ctrl_c = 0;
-    simstat = OK;
+
+    if (sis_verbose)
+	(*sim_callback->printf_filtered) (sim_callback, 
+	    "sim_stop_reason %x : %x\n", *reason, *sigrc);
 }
 
 /* Flush all register windows out to the stack.  Starting after the invalid
@@ -489,7 +463,25 @@ flush_windows ()
 void
 sim_resume(SIM_DESC sd, int step, int siggnal)
 {
-    simstat = run_sim(&sregs, UINT64_MAX, 0);
+    if (sis_verbose)
+	(*sim_callback->printf_filtered) (sim_callback, 
+	    "sim_resume %x : %x : %x : %x : 0x%08x\n", step, siggnal, sregs.bphit, sregs.wphit, sregs.pc);
+    if (step) {
+	sregs.bphit = 0;
+	sregs.wphit = 1;
+        simstat = run_sim(&sregs, 1, 0);
+	sregs.bphit = 0;
+	sregs.wphit = 0;
+    } else if (sregs.bphit || sregs.wphit) {
+	sregs.bphit = 0;
+	sregs.wphit = 1;
+        simstat = run_sim(&sregs, 1, 0);
+	sregs.bphit = sregs.wphit = 0;
+        simstat = run_sim(&sregs, UINT64_MAX, 0);
+	sregs.bphit = 0;
+    }
+    else
+        simstat = run_sim(&sregs, UINT64_MAX, 0);
 
     if (sis_gdb_break) flush_windows ();
 }
@@ -524,6 +516,145 @@ sim_stop(SIM_DESC sd)
   return 1;
 }
 
+static int
+sis_insert_watchpoint_read(int addr, unsigned char mask)
+{
+    if (sregs.wprnum < WPR_MAX) {
+	sregs.wprs[sregs.wprnum] = addr;
+	sregs.wprm[sregs.wprnum] = mask;
+	sregs.wprnum++;
+	if (sis_verbose)
+	    (*sim_callback->printf_filtered) (sim_callback, "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 < sregs.wprnum) && (sregs.wprs[i] != addr))
+	i++;
+    if (addr == sregs.wprs[i]) {
+	for (; i < sregs.wprnum - 1; i++)
+	    sregs.wprs[i] = sregs.wprs[i + 1];
+	sregs.wprnum -= 1;
+	if (sis_verbose)
+	    (*sim_callback->printf_filtered) (sim_callback, "removed read watchpoint at %x\n", addr);
+	return 0;
+    }
+    return 1;
+}
+
+static int
+sis_insert_watchpoint_write(int32 addr, unsigned char mask)
+{
+    if (sregs.wpwnum < WPR_MAX) {
+	sregs.wpws[sregs.wpwnum] = addr;
+	sregs.wpwm[sregs.wpwnum] = mask;
+	sregs.wpwnum++;
+	if (sis_verbose)
+	    (*sim_callback->printf_filtered) (sim_callback, "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 < sregs.wpwnum) && (sregs.wpws[i] != addr))
+	i++;
+    if (addr == sregs.wpws[i]) {
+	for (; i < sregs.wpwnum - 1; i++)
+	    sregs.wpws[i] = sregs.wpws[i + 1];
+	sregs.wpwnum -= 1;
+	if (sis_verbose)
+	    (*sim_callback->printf_filtered) (sim_callback, "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)
+       (*sim_callback->printf_filtered) (sim_callback, "sim_stopped_by_watchpoint %x\n", sregs.wphit);
+    return((sregs.wphit != 0));
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+    return(sregs.wpaddress);
+}
+
 #if 0 /* FIXME: These shouldn't exist.  */
 
 int
diff --git a/sim/frv/Makefile.in b/sim/frv/Makefile.in
index ed7a592..974b422 100644
--- a/sim/frv/Makefile.in
+++ b/sim/frv/Makefile.in
@@ -26,6 +26,7 @@ SIM_OBJS = \
 	sim-hrw.o \
 	sim-model.o \
 	sim-reg.o \
+	sim-watch-remote.o \
 	cgen-utils.o cgen-trace.o cgen-scache.o cgen-fpu.o cgen-accfp.o \
 	cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
 	sim-if.o arch.o \
diff --git a/sim/h8300/Makefile.in b/sim/h8300/Makefile.in
index f077331..f4afe42 100644
--- a/sim/h8300/Makefile.in
+++ b/sim/h8300/Makefile.in
@@ -25,6 +25,7 @@ SIM_OBJS = compile.o \
 	   sim-cpu.o \
 	   sim-engine.o \
 	   sim-load.o \
+	   sim-watch-remote.o \
 	   $(SIM_EXTRA_OBJS)
 
 ## COMMON_POST_CONFIG_FRAG
diff --git a/sim/iq2000/Makefile.in b/sim/iq2000/Makefile.in
index 96ff04f..1d187da 100644
--- a/sim/iq2000/Makefile.in
+++ b/sim/iq2000/Makefile.in
@@ -32,6 +32,7 @@ SIM_OBJS = \
 	cgen-utils.o cgen-trace.o cgen-scache.o \
 	cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
 	sim-if.o arch.o \
+	sim-watch-remote.o \
 	$(IQ2000_OBJS) \
 	$(CONFIG_DEVICES)
 
diff --git a/sim/lm32/Makefile.in b/sim/lm32/Makefile.in
index 05cf53b..d8d5a2a 100644
--- a/sim/lm32/Makefile.in
+++ b/sim/lm32/Makefile.in
@@ -15,6 +15,7 @@ SIM_OBJS = \
         cgen-utils.o cgen-trace.o cgen-scache.o \
         cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
         sim-if.o arch.o \
+	sim-watch-remote.o \
         cpu.o decode.o sem.o model.o mloop.o \
         lm32.o traps.o user.o 
 
diff --git a/sim/m32c/gdb-if.c b/sim/m32c/gdb-if.c
index a617b7c..b45a4cb 100644
--- a/sim/m32c/gdb-if.c
+++ b/sim/m32c/gdb-if.c
@@ -710,3 +710,29 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
 {
   return NULL;
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/m32r/Makefile.in b/sim/m32r/Makefile.in
index 2841a1b..50f75a0 100644
--- a/sim/m32r/Makefile.in
+++ b/sim/m32r/Makefile.in
@@ -34,6 +34,7 @@ SIM_OBJS = \
 	cgen-utils.o cgen-trace.o cgen-scache.o \
 	cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
 	sim-if.o arch.o \
+	sim-watch-remote.o \
 	$(M32R_OBJS) \
 	$(M32RX_OBJS) \
 	$(M32R2_OBJS) \
diff --git a/sim/m68hc11/Makefile.in b/sim/m68hc11/Makefile.in
index a5de10a5..a2413a9 100644
--- a/sim/m68hc11/Makefile.in
+++ b/sim/m68hc11/Makefile.in
@@ -31,6 +31,7 @@ SIM_OBJS = $(M68HC11_OBJS) \
 	sim-stop.o \
 	sim-hrw.o \
 	sim-reason.o \
+	sim-watch-remote.o \
         $(SIM_EXTRA_OBJS)
 
 SIM_PROFILE= -DPROFILE=1 -DWITH_PROFILE=-1
diff --git a/sim/mcore/interp.c b/sim/mcore/interp.c
index 73da916..66e7168 100644
--- a/sim/mcore/interp.c
+++ b/sim/mcore/interp.c
@@ -2204,3 +2204,29 @@ sim_set_callbacks (ptr)
 {
   callback = ptr; 
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/microblaze/Makefile.in b/sim/microblaze/Makefile.in
index f76c2e6..97a6a2a 100644
--- a/sim/microblaze/Makefile.in
+++ b/sim/microblaze/Makefile.in
@@ -17,7 +17,7 @@
 
 ## COMMON_PRE_CONFIG_FRAG
 
-SIM_OBJS = interp.o sim-load.o
+SIM_OBJS = interp.o sim-load.o sim-watch-remote.o
 SIM_EXTRA_LIBS = -lm
 SIM_EXTRA_CLEAN = microblaze-clean
 
diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in
index 985f4e5..22b4714 100644
--- a/sim/mips/Makefile.in
+++ b/sim/mips/Makefile.in
@@ -54,6 +54,7 @@ SIM_OBJS = \
 	sim-stop.o \
 	sim-resume.o \
 	sim-reason.o \
+	sim-watch-remote.o
 
 
 # List of flags to always pass to $(CC).
diff --git a/sim/mn10300/Makefile.in b/sim/mn10300/Makefile.in
index 5b8d32c..74529a3 100644
--- a/sim/mn10300/Makefile.in
+++ b/sim/mn10300/Makefile.in
@@ -27,6 +27,7 @@ MN10300_OBJS = \
 	sim-resume.o \
 	sim-reason.o \
 	sim-stop.o \
+	sim-watch-remote.o \
 	dv-sockser.o
 
 SIM_OBJS = $(MN10300_OBJS) interp.o
diff --git a/sim/moxie/interp.c b/sim/moxie/interp.c
index 4362c66..ca964c0 100644
--- a/sim/moxie/interp.c
+++ b/sim/moxie/interp.c
@@ -1380,3 +1380,29 @@ sim_set_callbacks (ptr)
 {
   callback = ptr; 
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/msp430/Makefile.in b/sim/msp430/Makefile.in
index 240d308..6c7a486 100644
--- a/sim/msp430/Makefile.in
+++ b/sim/msp430/Makefile.in
@@ -36,6 +36,7 @@ SIM_OBJS = \
         sim-reg.o \
         sim-resume.o \
         sim-stop.o \
+        sim-watch-remote.o \
         $(SIM_EXTRA_OBJS)
 
 # List of extra dependencies.
diff --git a/sim/ppc/gdb-sim.c b/sim/ppc/gdb-sim.c
index 9a9dc6a..3055776 100644
--- a/sim/ppc/gdb-sim.c
+++ b/sim/ppc/gdb-sim.c
@@ -1296,3 +1296,29 @@ sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
   return psim_write_register(simulator, MAX_NR_PROCESSORS,
 			     buf, regname, raw_transfer);
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/rl78/gdb-if.c b/sim/rl78/gdb-if.c
index f8712bf..4ed2910 100644
--- a/sim/rl78/gdb-if.c
+++ b/sim/rl78/gdb-if.c
@@ -571,3 +571,29 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
 {
     return NULL;
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/rx/gdb-if.c b/sim/rx/gdb-if.c
index 3ccea98..b0226c5 100644
--- a/sim/rx/gdb-if.c
+++ b/sim/rx/gdb-if.c
@@ -853,3 +853,29 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
 {
   return NULL;
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/sh/interp.c b/sim/sh/interp.c
index c854174..f1bcd06 100644
--- a/sim/sh/interp.c
+++ b/sim/sh/interp.c
@@ -2780,3 +2780,29 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word)
 {
   return NULL;
 }
+
+int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type)
+{
+  return -1;
+}
+
+int sim_stopped_by_watchpoint (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_watchpoint_address (SIM_DESC sd)
+{
+  return 0;
+}
+
+int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype)
+{
+  return 0;
+}
+
diff --git a/sim/sh64/Makefile.in b/sim/sh64/Makefile.in
index d87dd4a..744682d 100644
--- a/sim/sh64/Makefile.in
+++ b/sim/sh64/Makefile.in
@@ -34,6 +34,7 @@ SIM_OBJS = \
 	cgen-utils.o cgen-trace.o cgen-scache.o \
 	cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
 	sim-if.o arch.o \
+	sim-watch-remote.o \
 	$(SH64_OBJS) \
 	$(CONFIG_DEVICES)
 
diff --git a/sim/v850/Makefile.in b/sim/v850/Makefile.in
index 693d675..4ce2e35 100644
--- a/sim/v850/Makefile.in
+++ b/sim/v850/Makefile.in
@@ -28,7 +28,8 @@ SIM_OBJS = \
 	sim-hrw.o \
 	sim-resume.o \
 	sim-reason.o \
-	sim-stop.o
+	sim-stop.o \
+	sim-watch-remote.o
 
 SIM_RUN_OBJS = nrun.o
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 14/23] sim/erc32: Use gdb callback for UART I/O when linked with gdb.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (10 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  7:46 ` [PATCH 11/23] sim/erc32: use AC_C_BIGENDIAN to probe for host endian Jiri Gaisler
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Use the host_callback feature for printing when linked with gdb.
---
 sim/erc32/erc32.c  | 97 +++++++++++++++++++++++++++++++++++++++++++++---------
 sim/erc32/func.c   |  2 ++
 sim/erc32/interf.c |  5 +--
 sim/erc32/sis.c    |  2 ++
 sim/erc32/sis.h    |  4 ++-
 5 files changed, 92 insertions(+), 18 deletions(-)

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 34a15de..3f25ca7 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -22,6 +22,7 @@
 /* The control space devices */
 
 #include "config.h"
+#include <errno.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <string.h>
@@ -39,6 +40,7 @@ extern int      rom8,wrp,uben;
 extern char     uart_dev1[], uart_dev2[];
 
 int dumbio = 0; /* normal, smart, terminal oriented IO by default */
+int tty_setup = 1; /* default setup if not a tty */
 
 /* MEC registers */
 #define MEC_START 	0x01f80000
@@ -301,12 +303,15 @@ static void	store_bytes (unsigned char *mem, uint32 waddr,
 
 extern int	ext_irl;
 
+static host_callback *callback;
+
 
 /* One-time init */
 
 void
 init_sim()
 {
+    callback = sim_callback;
     port_init();
 }
 
@@ -944,10 +949,14 @@ init_stdio()
 {
     if (dumbio)
         return; /* do nothing */
-    if (!ifd1)
+    if (ifd1 == 0 && f1open) {
 	tcsetattr(0, TCSANOW, &ioc1);
-    if (!ifd2)
+        tcflush(ifd1, TCIFLUSH);
+    }
+    if (ifd2 == 0 && f1open) {
 	tcsetattr(0, TCSANOW, &ioc2);
+        tcflush(ifd2, TCIFLUSH);
+    }
 }
 
 void
@@ -955,16 +964,18 @@ restore_stdio()
 {
     if (dumbio)
         return; /* do nothing */
-    if (!ifd1)
+    if (ifd1 == 0 && f1open && tty_setup)
 	tcsetattr(0, TCSANOW, &iocold1);
-    if (!ifd2)
+    if (ifd2 == 0 && f2open && tty_setup)
 	tcsetattr(0, TCSANOW, &iocold2);
 }
 
 #define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
-             ( dumbio                                \
+             ( dumbio || nouartrx \
                ? (0) /* no bytes read, no delay */   \
-               : read( _fd_, _buf_, _len_ ) )
+               : (_fd_) == 1 && callback ? \
+                 callback->read_stdin (callback, _buf_, _len_) :  \
+                 read( _fd_, _buf_, _len_ ) )
 
 
 static void
@@ -994,21 +1005,26 @@ port_init()
 	}
     if (f1in) ifd1 = fileno(f1in);
     if (ifd1 == 0) {
+        if (callback && !callback->isatty(callback, ifd1)) {
+            tty_setup = 0;
+        }
 	if (sis_verbose)
 	    printf("serial port A on stdin/stdout\n");
         if (!dumbio) {
             tcgetattr(ifd1, &ioc1);
+            if (tty_setup) {
             iocold1 = ioc1;
             ioc1.c_lflag &= ~(ICANON | ECHO);
             ioc1.c_cc[VMIN] = 0;
             ioc1.c_cc[VTIME] = 0;
         }
+        }
 	f1open = 1;
     }
 
     if (f1out) {
 	ofd1 = fileno(f1out);
-    	if (!dumbio && ofd1 == 1) setbuf(f1out, NULL);
+    	if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL);
     }
 
     if (uart_dev2[0] != 0)
@@ -1027,17 +1043,19 @@ port_init()
 	    printf("serial port B on stdin/stdout\n");
         if (!dumbio) {
             tcgetattr(ifd2, &ioc2);
+            if (tty_setup) {
             iocold2 = ioc2;
             ioc2.c_lflag &= ~(ICANON | ECHO);
             ioc2.c_cc[VMIN] = 0;
             ioc2.c_cc[VTIME] = 0;
         }
+        }
 	f2open = 1;
     }
 
     if (f2out) {
 	ofd2 = fileno(f2out);
-        if (!dumbio && ofd2 == 1) setbuf(f2out, NULL);
+        if (!dumbio && tty_setup && ofd2 == 1) setbuf(f2out, NULL);
     }
 
     wnuma = wnumb = 0;
@@ -1066,6 +1084,9 @@ read_uart(addr)
 	    if (f1open) {
 	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
 	    }
+      else {
+          anum = 0;
+      }
 	    if (anum > 0) {
 		aind = 0;
 		if ((aind + 1) < anum)
@@ -1098,6 +1119,9 @@ read_uart(addr)
 	    if (f2open) {
 		bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
 	    }
+	    else {
+		bnum = 0;
+	    }
 	    if (bnum > 0) {
 		bind = 0;
 		if ((bind + 1) < bnum)
@@ -1130,6 +1154,9 @@ read_uart(addr)
 	    if (f1open) {
 	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
             }
+	    else {
+		anum = 0;
+	    }
 	    if (anum > 0) {
 		Ucontrol |= 0x00000001;
 		aind = 0;
@@ -1142,6 +1169,9 @@ read_uart(addr)
 	    if (f2open) {
 		bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
 	    }
+	    else {
+		bnum = 0;
+	    }
 	    if (bnum > 0) {
 		Ucontrol |= 0x00010000;
 		bind = 0;
@@ -1182,8 +1212,12 @@ write_uart(addr, data)
 	    if (wnuma < UARTBUF)
 	        wbufa[wnuma++] = c;
 	    else {
-	        while (wnuma)
+	        while (wnuma) {
+              if (ofd1 == 1 && callback)
+                  wnuma -= callback->write_stdout(callback, wbufa, wnuma);
+              else
 		    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
+          }
 	        wbufa[wnuma++] = c;
 	    }
 	}
@@ -1206,8 +1240,12 @@ write_uart(addr, data)
 	    if (wnumb < UARTBUF)
 		wbufb[wnumb++] = c;
 	    else {
-		while (wnumb)
+          while (wnumb) {
+              if (ofd1 == 1 && callback)
+                  wnumb -= callback->write_stdout(callback, wbufb, wnumb);
+              else
 		    wnumb -= fwrite(wbufb, 1, wnumb, f2out);
+          }
 		wbufb[wnumb++] = c;
 	    }
 	}
@@ -1245,19 +1283,37 @@ write_uart(addr, data)
 static void
 flush_uart()
 {
-    while (wnuma && f1open)
+    while (wnuma && f1open) {
+        if (ofd1 == 1 && callback) {
+            wnuma -= callback->write_stdout(callback, wbufa, wnuma);
+            callback->flush_stdout(callback);
+        }
+        else
 	wnuma -= fwrite(wbufa, 1, wnuma, f1out);
-    while (wnumb && f2open)
+    }
+    while (wnumb && f2open) {
+        if (ofd2 == 1 && callback) {
+            wnuma -= callback->write_stdout(callback, wbufb, wnuma);
+            callback->flush_stdout(callback);
+        }
+        else
 	wnumb -= fwrite(wbufb, 1, wnumb, f2out);
 }
+}
 
 
 
 static void
 uarta_tx()
 {
-
-    while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1);
+    while (f1open) {
+        if (ofd1 == 1 && callback) {
+            while (callback->write_stdout(callback, &uarta_sreg, 1) != 1);
+        }
+        else {
+            while (fwrite(&uarta_sreg, 1, 1, f1out) != 1);
+        }
+    }
     if (uart_stat_reg & UARTA_HRE) {
 	uart_stat_reg |= UARTA_SRE;
     } else {
@@ -1271,7 +1327,14 @@ uarta_tx()
 static void
 uartb_tx()
 {
-    while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1);
+    while (f2open) {
+        if (ofd2 == 1 && callback) {
+            while (callback->write_stdout(callback, &uarta_sreg, 1) != 1);
+        }
+        else {
+            while (fwrite(&uartb_sreg, 1, 1, f2out) != 1);
+        }
+    }
     if (uart_stat_reg & UARTB_HRE) {
 	uart_stat_reg |= UARTB_SRE;
     } else {
@@ -1293,6 +1356,8 @@ uart_rx(arg)
     rsize = 0;
     if (f1open)
         rsize = DO_STDIO_READ(ifd1, &rxd, 1);
+    else
+        rsize = 0;
     if (rsize > 0) {
 	uarta_data = UART_DR | rxd;
 	if (uart_stat_reg & UARTA_HRE)
@@ -1309,6 +1374,8 @@ uart_rx(arg)
     rsize = 0;
     if (f2open)
         rsize = DO_STDIO_READ(ifd2, &rxd, 1);
+    else
+        rsize = 0;
     if (rsize) {
 	uartb_data = UART_DR | rxd;
 	if (uart_stat_reg & UARTB_HRE)
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index ee45b3b..32e2c46 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -51,6 +51,8 @@ char            uart_dev1[128] = "";
 char            uart_dev2[128] = "";
 extern	int	ext_irl;
 uint32		last_load_addr = 0;
+int		nouartrx = 0;
+host_callback 	*sim_callback;
 
 #ifdef ERRINJ
 uint32		errcnt = 0;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index f03f1d5..31071bd 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -61,8 +61,6 @@ extern char     uart_dev1[], uart_dev2[];
 
 int             sis_gdb_break = 1;
 
-host_callback *sim_callback;
-
 int
 run_sim(sregs, icount, dis)
     struct pstate  *sregs;
@@ -209,6 +207,9 @@ sim_open (kind, callback, abfd, argv)
             if (strcmp(argv[stat], "-dumbio") == 0) {
 		dumbio = 1;
 	    } else
+            if (strcmp(argv[stat], "-nouartrx") == 0) {
+		nouartrx = 1;
+	    } else
             if (strcmp(argv[stat], "-wrp") == 0) {
                 wrp = 1;
 	    } else
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index 8bc2283..d737216 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -210,6 +210,8 @@ main(argc, argv)
 #endif
             } else if (strcmp(argv[stat], "-dumbio") == 0) {
 		dumbio = 1;
+            } else if (strcmp(argv[stat], "-nouartrx") == 0) {
+		nouartrx = 1;
             } else if (strcmp(argv[stat], "-v") == 0) {
 		sis_verbose = 1;
             } else if (strcmp(argv[stat], "-vv") == 0) {
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index e2bed36..1e41d2a 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -163,7 +163,7 @@ struct irqcell {
 /* Prototypes  */
 
 /* erc32.c */
-extern void	init_sim (void);
+extern void	init_sim ();
 extern void	reset (void);
 extern void	error_mode (uint32 pc);
 extern void	sim_halt (void);
@@ -204,6 +204,8 @@ extern void	reset_all (void);
 extern void	sys_reset (void);
 extern void	sys_halt (void);
 extern double	get_time (void);
+extern int	nouartrx;
+extern host_callback *sim_callback;
 
 /* exec.c */
 extern int	dispatch_instruction (struct pstate *sregs);
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (9 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  9:10   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 14/23] sim/erc32: Use gdb callback for UART I/O when linked with gdb Jiri Gaisler
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* func.c (batch, exec_cmd) save return value to avoid warnings.
	Also print simulation time as long long.
---
 sim/erc32/func.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index 1661175..a3da1c5 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -81,6 +81,7 @@ batch(sregs, fname)
 {
     FILE           *fp;
     char            lbuf[1024];
+    char           *tmp;
 
     if ((fp = fopen(fname, "r")) == NULL) {
 	fprintf(stderr, "couldn't open batch file %s\n", fname);
@@ -88,7 +89,7 @@ batch(sregs, fname)
     }
     while (!feof(fp)) {
 	lbuf[0] = 0;
-	fgets(lbuf, 1023, fp);
+	tmp = fgets(lbuf, 1023, fp);
 	if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n'))
 	    lbuf[strlen(lbuf) - 1] = 0;
 	printf("sis> %s\n", lbuf);
@@ -382,7 +383,7 @@ exec_cmd(sregs, cmd)
 {
     char           *cmd1, *cmd2;
     int32           stat;
-    uint32          len, i, clen, j;
+    uint32          len, i, clen, j, tmp;
     static uint32   daddr = 0;
     char           *cmdsave;
 
@@ -553,7 +554,7 @@ exec_cmd(sregs, cmd)
 	    sim_halt();
 	} else if (strncmp(cmd1, "shell", clen) == 0) {
 	    if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
-		system(&cmdsave[clen]);
+		tmp = system(&cmdsave[clen]);
 	    }
 	} else if (strncmp(cmd1, "step", clen) == 0) {
 	    stat = run_sim(sregs, 1, 1);
@@ -641,8 +642,8 @@ show_stat(sregs)
 	sregs->nbranch;
 #endif
 
-    printf("\n Cycles       : %9d\n\r", ebase.simtime - sregs->simstart);
-    printf(" Instructions : %9d\n", sregs->ninst);
+    printf("\n Cycles       : %9llu\n\r", ebase.simtime - sregs->simstart);
+    printf(" Instructions : %9llu\n", sregs->ninst);
 
 #ifdef STAT
     printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (18 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 13/23] sim/erc32: Fix a few compiler warnings Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17 15:58   ` Eli Zaretskii
  2015-02-17  7:46 ` [PATCH 20/23] sim/erc32: Updated documentation Jiri Gaisler
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Added memory and I/O sub-system to emulate a LEON3 processor.
	The cache and MMU are not emulated but enough functionallity
	is provided to run any RTEMS and BCC compiled application.
	The code is based on erc32.c and modified to emulate the
	LEON3 address space and peripheral operations.ZZ
---
 sim/erc32/Makefile.in  |    6 +-
 sim/erc32/README.leon3 |   53 +++
 sim/erc32/README.sis   |   79 ++--
 sim/erc32/erc32.c      |   48 ++-
 sim/erc32/exec.c       |  228 +++++++++--
 sim/erc32/func.c       |   51 ++-
 sim/erc32/grlib.c      |   98 +++++
 sim/erc32/grlib.h      |   57 +++
 sim/erc32/interf.c     |   26 +-
 sim/erc32/leon3.c      | 1066 ++++++++++++++++++++++++++++++++++++++++++++++++
 sim/erc32/sis.c        |   22 +-
 sim/erc32/sis.h        |   49 ++-
 12 files changed, 1658 insertions(+), 125 deletions(-)
 create mode 100644 sim/erc32/README.leon3
 create mode 100644 sim/erc32/grlib.c
 create mode 100644 sim/erc32/grlib.h
 create mode 100644 sim/erc32/leon3.c

diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
index 7dfc7da..63b0f0b 100644
--- a/sim/erc32/Makefile.in
+++ b/sim/erc32/Makefile.in
@@ -21,7 +21,7 @@
 TERMCAP_LIB = @TERMCAP@
 READLINE_LIB = @READLINE@
 
-SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o
+SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon3.o grlib.o
 SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm
 SIM_EXTRA_ALL = sis
 SIM_EXTRA_INSTALL = install-sis
@@ -35,7 +35,7 @@ SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcdir)/../..
 ## COMMON_POST_CONFIG_FRAG
 
 # `sis' doesn't need interf.o.
-SIS_OFILES = exec.o erc32.o func.o help.o float.o
+SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon3.o
 
 sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS)
 	$(CC) $(ALL_CFLAGS) -o sis \
@@ -64,3 +64,5 @@ func.o: func.c sis.h
 help.o: help.c sis.h
 interf.o: interf.c sis.h
 sis.o: sis.c sis.h
+grlib.o: grlib.c sis.h grlib.h
+leon3.o: leon3.c sis.h grlib.h
diff --git a/sim/erc32/README.leon3 b/sim/erc32/README.leon3
new file mode 100644
index 0000000..00ab14a
--- /dev/null
+++ b/sim/erc32/README.leon3
@@ -0,0 +1,53 @@
+
+1. LEON3 emulation
+
+The file 'leon3.c' contains a model of simple LEON3 sub-system. It 
+contains 16 Mbyte ROM and 16 Mbyte RAM. Standard peripherals
+such as interrupt controller, UART and timer are provided.
+The model can execute leon3 binaries that do not require an
+MMU.
+
+To start sis in Leon3 mode, add the -leon3 switch. In gdb,
+use 'target sim -leon3' .
+
+1.1 UART
+
+The UART emulates an APBUART and is located at address 0x80000100.
+The following registers are implemeted:
+
+- UART RX and TX register	(0x80000100)
+- UART status register		(0x80000104)
+
+The UART generates interrupt 3.
+
+1.2 Timer unit (GPTIMER)
+
+The GPTIMER programmable counter is emulated and located at
+address 0x80000300. It is configured with two timers and separate
+interrupts (8 and 9).
+
+1.3 Interrupt controller
+
+The IRQMP interrupt controller is implemented as described in the
+GRLIB IP manual, with the exception of the interrupt level register.
+Extended interrupts are not supported. The registers are located
+at address 0x80000200.
+
+1.5 Memory interface
+
+The following memory areas are valid for the Leon3 simulator:
+
+0x00000000 - 0x01000000		ROM (16 Mbyte, loaded at start-up)
+0x40000000 - 0x41000000		RAM (16 Mbyte, loaded at start-up)
+0x80000000 - 0x81000000		APB bus, including plug&play
+0xFFFFF000 - 0xFFFFFFFF		AHB plug&play area
+
+Access to non-existing memory will result in a memory exception trap.
+
+1.8 Power-down mode
+
+The Leon3 power-down feature (%asr19) is supported. When power-down is
+entered, time is skipped forward until the next event in the event queue.
+However, if the simulator event queue is empty, power-down mode is not
+entered since no interrupt would be generated to exit from the mode. A
+Ctrl-C in the simulator window will exit the power-down mode.
diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis
index b119f03..eb4a683 100644
--- a/sim/erc32/README.sis
+++ b/sim/erc32/README.sis
@@ -1,10 +1,10 @@
 
-SIS - Sparc Instruction Simulator README file  (v2.0, 05-02-1996)
+SIS - Sparc Instruction Simulator README file  (v2.8, 10-11-2014)
 -------------------------------------------------------------------
 
 1. Introduction
 
-The SIS is a SPARC V7 architecture simulator. It consist of two parts,
+The SIS is a SPARC V7/V8 architecture simulator. It consist of two parts,
 the simulator core and a user defined memory module. The simulator
 core executes the instructions while the memory module emulates memory
 and peripherals. 
@@ -13,28 +13,28 @@ and peripherals.
 
 The simulator is started as follows: 
 
-sis [-uart1 uart_device1] [-uart2 uart_device2] 
+sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] 
     [-nfp] [-freq frequency] [-c batch_file] [files] 
 
-The default uart devices for SIS are /dev/ptypc and /dev/ptypd. The
--uart[1,2] switch can be used to connect the uarts to other devices.
-Use 'tip /dev/ttypc'  to connect a terminal emulator to the uarts.
+By default, SIS emaultes an ERC32 system. The -leon3 switch
+enables emulation of a LEON3 SOC system.
+
+The emulated console uart is connected stdin/stdout. The -uart[1,2]
+switch can be used to connect the uarts to other devices.
+
 The '-nfp' will disable the simulated FPU, so each FPU instruction will
 generate a FPU disabled trap. The '-freq' switch can be used to define
 which "frequency" the simulator runs at. This is used by the 'perf'
 command to calculated the MIPS figure for a particular configuration.
-The give frequency must be an integer indicating the frequency in MHz.
+The frequency must be an integer indicating the frequency in MHz.
 
 The -c option indicates that sis commands should be read from 'batch_file' 
 at startup.
 
-Files to be loaded must be in one of the supported formats (see INSTALLATION),
-and will be loaded into the simulated memory. The file formats are
-automatically recognised.
+Files to be loaded must be in one of the supported formats (elf, a.out, srec),
+and will be loaded into the simulated memory.
 
-The script 'startsim' will start the simulator in one xterm window and
-open a terminal emulator (tip) connected to the UART A in a second
-xterm window. Below is description of commands  that are recognized by 
+Below is description of commands  that are recognized by 
 the simulator. The command-line is parsed using GNU readline. A command
 history of 64 commands is maintained. Use the up/down arrows to recall
 previous commands. For more details, see the readline documentation.
@@ -77,8 +77,8 @@ Prints the FPU registers
 go <address> [inst_count]
 
 The go command will set pc to <address> and npc to <address> + 4, and start
-execution. No other initialisation will be done. If inst_count is given, 
-execution will stop after the specified number of instructions.
+execution. If inst_count is given, execution will stop after the specified
+number of instructions.
 
 help
 
@@ -146,14 +146,20 @@ interpreted as 'cont'.
 
 3. Simulator core
 
-The SIS emulates the behavior of the 90C601E and 90C602E sparc IU and
-FPU from Matra MHS. These are roughly equivalent to the Cypress C601
-and C602.  The simulator is cycle true, i.e a simulator time is
+In ERC32 mode, SIS emulates the behavior of the 90C601E and 90C602E
+sparc IU and FPU from Matra MHS. These are roughly equivalent to the
+Cypress C601 and C602. The simulator is cycle true, i.e a simulator time is
 maintained and inremented according the IU and FPU instruction timing.
 The parallel execution between the IU and FPU is modelled, as well as
-stalls due to operand dependencies (FPU). The core interacts with the
-user-defined memory modules through a number of functions. The memory
-module must provide the following functions:
+stalls due to operand dependencies (FPU).
+
+In Leon3 mode, the core emulates the Leon3 SPARC V8 core from
+Gaisler Research. All SPARC V8 instructions are supported but
+emaultion is not fully cycle-true as the cache is not emulated.
+
+The core interacts with the user-defined memory modules through
+a number of functions. The memory module must provide the following
+functions:
 
 int memory_read(asi,addr,data,ws)
 int asi;
@@ -272,7 +278,7 @@ See 'erc32.c' for examples on how to use events and interrupts.
 
 5. Memory module
 
-The supplied memory module (erc32.c) emulates the functions of memory and
+The ERC32 memory module (erc32.c) emulates the functions of memory and
 the MEC asic developed for the 90C601/2. It includes the following functions:
 
 * UART A & B
@@ -284,28 +290,27 @@ the MEC asic developed for the 90C601/2. It includes the following functions:
 * 512 Kbyte ROM
 * 4 Mbyte RAM
 
-See README.erc32 on how the MEC functions are emulated.  For a detailed MEC
-specification, look at the ERC32 home page at URL:
+See README.erc32 on how the MEC functions are emulated.
 
-http://www.estec.esa.nl/wsmwww/erc32
+The Leon3 memory module (leon3.c) emulates on-chip peripherals and
+external memory for a simple Leon3 system. The modules includes the
+following functions:
 
-6. Compile and linking programs
+* AHB and APB buses with plug&play
+* UART (APBUART)
+* Interrupt controller (IRQMP)
+* Timer unit with two timers (GPTIMER)
+* PROM/SRAM memory controller (SRCTRL)
+* 16 Mbyte PROM, 16 Mbyte SRAM
 
-The directory 'examples' contain some code fragments for SIS.
-The script gccx indicates how the native sunos gcc and linker can be used
-to produce executables for the simulator. To compile and link the provided
-'hello.c', type 'gccx hello.c'. This will build the executable 'hello'.
-Start the simulator by running 'startsim hello', and issue the command 'run.
-After the program is terminated, the IU will be force to error mode through
-a software trap and halt. 
+See README.leon3 for further details on Leon3 emulation.
 
-The programs are linked with a start-up file, srt0.S. This file includes
-the traptable and window underflow/overflow trap routines.
+6. Compile and linking programs
 
 7. IU and FPU instruction timing.
 
-The simulator provides cycle true simulation. The following table shows
-the emulated instruction timing for 90C601E & 90C602E:
+The simulator provides cycle true simulation for ERC32. The following table
+shows the emulated instruction timing for 90C601E & 90C602E:
 
 Instructions	      Cycles
 
diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 1c55579..0846bab 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -1636,19 +1636,20 @@ memory_iread(addr, data, ws)
 }
 
 static int
-memory_read(asi, addr, data, sz, ws)
-    int32           asi;
+memory_read(addr, data, sz, ws)
     uint32          addr;
     uint32         *data;
     int32           sz;
     int32          *ws;
 {
     int32           mexc;
+    int32           asi;
 
 #ifdef ERRINJ
     if (errmec) {
 	if (sis_verbose)
 	    printf("Inserted MEC error %d\n",errmec);
+        if (sregs.psr & 0x080) asi = 11; else asi = 10;
 	set_sfsr(errmec, addr, asi, 1);
 	if (errmec == 5) mecparerror();
 	if (errmec == 6) iucomperr();
@@ -1662,6 +1663,7 @@ memory_read(asi, addr, data, sz, ws)
 	*ws = mem_ramr_ws;
 	return (0);
     } else if ((addr >= MEC_START) && (addr < MEC_END)) {
+        if (sregs.psr & 0x080) asi = 11; else asi = 10;
 	mexc = mec_read(addr, asi, data);
 	if (mexc) {
 	    set_sfsr(MEC_ACC, addr, asi, 1);
@@ -1701,19 +1703,30 @@ memory_read(asi, addr, data, sz, ws)
     }
 
     printf("Memory exception at %x (illegal address)\n", addr);
+    if (sregs.psr & 0x080) asi = 11; else asi = 10;
     set_sfsr(UIMP_ACC, addr, asi, 1);
     *ws = MEM_EX_WS;
     return (1);
 }
 
 static int
-memory_write(asi, addr, data, sz, ws)
+memory_read_asi(asi, addr, data, sz, ws)
     int32           asi;
     uint32          addr;
     uint32         *data;
     int32           sz;
     int32          *ws;
 {
+    return(memory_read(addr, data, sz, ws));
+}
+
+static int
+memory_write(addr, data, sz, ws)
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
     uint32          byte_addr;
     uint32          byte_mask;
     uint32          waddr;
@@ -1721,11 +1734,13 @@ memory_write(asi, addr, data, sz, ws)
     int32           mexc;
     int             i;
     int             wphit[2];
+    int32           asi;
 
 #ifdef ERRINJ
     if (errmec) {
 	if (sis_verbose)
 	    printf("Inserted MEC error %d\n",errmec);
+        if (sregs.psr & 0x080) asi = 11; else asi = 10;
 	set_sfsr(errmec, addr, asi, 0);
 	if (errmec == 5) mecparerror();
 	if (errmec == 6) iucomperr();
@@ -1738,6 +1753,7 @@ memory_write(asi, addr, data, sz, ws)
 	if (mem_accprot) {
 
 	    waddr = (addr & 0x7fffff) >> 2;
+            if (sregs.psr & 0x080) asi = 11; else asi = 10;
 	    for (i = 0; i < 2; i++)
 		wphit[i] =
 		    (((asi == 0xa) && (mec_wpr[i] & 1)) ||
@@ -1761,6 +1777,7 @@ memory_write(asi, addr, data, sz, ws)
 	return (0);
 
     } else if ((addr >= MEC_START) && (addr < MEC_END)) {
+        if (sregs.psr & 0x080) asi = 11; else asi = 10;
 	if ((sz != 2) || (asi != 0xb)) {
 	    set_sfsr(MEC_ACC, addr, asi, 0);
 	    *ws = MEM_EX_WS;
@@ -1817,10 +1834,22 @@ memory_write(asi, addr, data, sz, ws)
     }
 	
     *ws = MEM_EX_WS;
+    if (sregs.psr & 0x080) asi = 11; else asi = 10;
     set_sfsr(UIMP_ACC, addr, asi, 0);
     return (1);
 }
 
+static int
+memory_write_asi(asi, addr, data, sz, ws)
+    int32           asi;
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    return(memory_write(addr, data, sz, ws));
+}
+
 static unsigned char  *
 get_mem_ptr(addr, size)
     uint32          addr;
@@ -1864,6 +1893,12 @@ sis_memory_read(addr, data, length)
     uint32          length;
 {
     char           *mem;
+    int            ws;
+
+    if (length == 4) {
+      memory_read(addr, data, length, &ws);
+      return(4);
+    }
 
     if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
 	return (0);
@@ -1872,7 +1907,7 @@ sis_memory_read(addr, data, length)
     return (length);
 }
 
-void
+static void
 boot_init ()
 {
     mec_write(MEC_WCR, 0);	/* zero waitstates */
@@ -1896,7 +1931,10 @@ struct memsys erc32sys = {
     restore_stdio,
     memory_iread,
     memory_read,
+    memory_read_asi,
     memory_write,
+    memory_write_asi,
     sis_memory_write,
-    sis_memory_read
+    sis_memory_read,
+    boot_init
 };
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index 6d80306..13d5805 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -1065,17 +1065,17 @@ dispatch_instruction(sregs)
 		*rdd = sregs->psr;
 		break;
 	    case RDY:
-                if (!sparclite)
+                if ((!sparclite) && (cputype != CPU_LEON3))
                     *rdd = sregs->y;
                 else {
                     int rs1_is_asr = (sregs->inst >> 14) & 0x1f;
                     if ( 0 == rs1_is_asr )
                         *rdd = sregs->y;
-                    else if ( 17 == rs1_is_asr )
+                    else if ( 17 == rs1_is_asr ) {
                         *rdd = sregs->asr17;
+                    }
                     else {
                         sregs->trap = TRAP_UNIMP;
-                        break;
                     }
                 }
 		break;
@@ -1121,13 +1121,19 @@ dispatch_instruction(sregs)
 		    ((rs1 ^ operand2) & 0xfffff000);
 		break;
 	    case WRY:
-                if (!sparclite)
+                if ((!sparclite) && (cputype != CPU_LEON3))
                     sregs->y = (rs1 ^ operand2);
                 else {
                     if ( 0 == rd )
                         sregs->y = (rs1 ^ operand2);
-                    else if ( 17 == rd )
-                        sregs->asr17 = (rs1 ^ operand2);
+                    else if ( 17 == rd ) {
+                        if (sparclite)
+                            sregs->asr17 = (rs1 ^ operand2);
+                    }
+                    else if ( 19 == rd ) {
+                        if (cputype == CPU_LEON3)
+                            wait_for_irq();
+                    }
                     else {
                         sregs->trap = TRAP_UNIMP;
                         break;
@@ -1227,6 +1233,32 @@ dispatch_instruction(sregs)
 	switch (op3) {
 	case LDDA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x7) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    if (rd & 1) {
+		rd &= 0x1e;
+		if (rd > 7)
+		    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
+		else
+		    rdd = &(sregs->g[rd]);
+	    }
+	    mexc = ms->memory_read_asi(asi, address, ddata, 2, &ws);
+	    sregs->hold += ws;
+	    mexc |= ms->memory_read_asi(asi, address+4, &ddata[1], 2, &ws);
+	    sregs->hold += ws;
+	    sregs->icnt = T_LDD;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+	    } else {
+		rdd[0] = ddata[0];
+		rdd[1] = ddata[1];
+#ifdef STAT
+		sregs->nload++;	/* Double load counts twice */
+#endif
+	    }
+	    break;
 	case LDD:
 	    if (address & 0x7) {
 		sregs->trap = TRAP_UNALI;
@@ -1239,9 +1271,9 @@ dispatch_instruction(sregs)
 		else
 		    rdd = &(sregs->g[rd]);
 	    }
-	    mexc = ms->memory_read(asi, address, ddata, 2, &ws);
+	    mexc = ms->memory_read(address, ddata, 2, &ws);
 	    sregs->hold += ws;
-	    mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws);
+	    mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDD;
 	    if (mexc) {
@@ -1257,12 +1289,24 @@ dispatch_instruction(sregs)
 
 	case LDA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x3) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    mexc = ms->memory_read_asi(asi, address, &data, 2, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+	    } else {
+		*rdd = data;
+	    }
+	    break;
 	case LD:
 	    if (address & 0x3) {
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1272,8 +1316,27 @@ dispatch_instruction(sregs)
 	    break;
 	case LDSTUBA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    mexc = ms->memory_read_asi(asi, address, &data, 0, &ws);
+	    sregs->hold += ws;
+	    sregs->icnt = T_LDST;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+		break;
+	    }
+	    data = extract_byte(data, address);
+	    *rdd = data;
+	    data = 0x0ff;
+	    mexc = ms->memory_write_asi(asi, address, &data, 0, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+	    }
+#ifdef STAT
+	    sregs->nload++;
+#endif
+	    break;
 	case LDSTUB:
-	    mexc = ms->memory_read(asi, address, &data, 0, &ws);
+	    mexc = ms->memory_read(address, &data, 0, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDST;
 	    if (mexc) {
@@ -1283,7 +1346,7 @@ dispatch_instruction(sregs)
 	    data = extract_byte(data, address);
 	    *rdd = data;
 	    data = 0x0ff;
-	    mexc = ms->memory_write(asi, address, &data, 0, &ws);
+	    mexc = ms->memory_write(address, &data, 0, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1295,9 +1358,21 @@ dispatch_instruction(sregs)
 	case LDSBA:
 	case LDUBA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    mexc = ms->memory_read_asi(asi, address, &data, 0, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+		break;
+	    }
+	    if (op3 == LDSB)
+	        data = extract_byte_signed(data, address);
+	    else
+	        data = extract_byte(data, address);
+	    *rdd = data;
+	    break;
 	case LDSB:
 	case LDUB:
-	    mexc = ms->memory_read(asi, address, &data, 0, &ws);
+	    mexc = ms->memory_read(address, &data, 0, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1312,13 +1387,29 @@ dispatch_instruction(sregs)
 	case LDSHA:
 	case LDUHA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x1) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    mexc = ms->memory_read_asi(asi, address, &data, 1, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+		break;
+	    }
+	    if (op3 == LDSH)
+	        data = extract_short_signed(data, address);
+	    else
+	        data = extract_short(data, address);
+	    *rdd = data;
+	    break;
 	case LDSH:
 	case LDUH:
 	    if (address & 0x1) {
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = ms->memory_read(asi, address, &data, 1, &ws);
+	    mexc = ms->memory_read(address, &data, 1, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1344,7 +1435,7 @@ dispatch_instruction(sregs)
 		    (sregs->frs2 == rd))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    sregs->flrd = rd;
 	    sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
@@ -1370,9 +1461,9 @@ dispatch_instruction(sregs)
 		    ((sregs->frs2 >> 1) == (rd >> 1)))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = ms->memory_read(asi, address, ddata, 2, &ws);
+	    mexc = ms->memory_read(address, ddata, 2, &ws);
 	    sregs->hold += ws;
-	    mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws);
+	    mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDD;
 	    if (mexc) {
@@ -1401,7 +1492,7 @@ dispatch_instruction(sregs)
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1423,7 +1514,7 @@ dispatch_instruction(sregs)
 	    if (ebase.simtime < sregs->ftime) {
 		sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = ms->memory_write(asi, address, &sregs->fsr, 2, &ws);
+	    mexc = ms->memory_write(address, &sregs->fsr, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1432,12 +1523,22 @@ dispatch_instruction(sregs)
 
 	case STA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x3) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    mexc = ms->memory_write_asi(asi, address, rdd, 2, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+	    }
+	    break;
 	case ST:
 	    if (address & 0x3) {
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = ms->memory_write(asi, address, rdd, 2, &ws);
+	    mexc = ms->memory_write(address, rdd, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1445,8 +1546,14 @@ dispatch_instruction(sregs)
 	    break;
 	case STBA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    mexc = ms->memory_write_asi(asi, address, rdd, 0, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+	    }
+	    break;
 	case STB:
-	    mexc = ms->memory_write(asi, address, rdd, 0, &ws);
+	    mexc = ms->memory_write(address, rdd, 0, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1454,6 +1561,28 @@ dispatch_instruction(sregs)
 	    break;
 	case STDA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x7) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    if (rd & 1) {
+		rd &= 0x1e;
+		if (rd > 7)
+		    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
+		else
+		    rdd = &(sregs->g[rd]);
+	    }
+	    mexc = ms->memory_write_asi(asi, address, rdd, 3, &ws);
+	    sregs->hold += ws;
+	    sregs->icnt = T_STD;
+#ifdef STAT
+	    sregs->nstore++;	/* Double store counts twice */
+#endif
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+		break;
+	    }
+	    break;
 	case STD:
 	    if (address & 0x7) {
 		sregs->trap = TRAP_UNALI;
@@ -1466,7 +1595,7 @@ dispatch_instruction(sregs)
 		else
 		    rdd = &(sregs->g[rd]);
 	    }
-	    mexc = ms->memory_write(asi, address, rdd, 3, &ws);
+	    mexc = ms->memory_write(address, rdd, 3, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_STD;
 #ifdef STAT
@@ -1495,7 +1624,7 @@ dispatch_instruction(sregs)
 		break;
 	    }
 	    rdd = &(sregs->fpq[0]);
-	    mexc = ms->memory_write(asi, address, rdd, 3, &ws);
+	    mexc = ms->memory_write(address, rdd, 3, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_STD;
 #ifdef STAT
@@ -1511,12 +1640,22 @@ dispatch_instruction(sregs)
 	    break;
 	case STHA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x1) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    mexc = ms->memory_write_asi(asi, address, rdd, 1, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+	    }
+	    break;
 	case STH:
 	    if (address & 0x1) {
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = ms->memory_write(asi, address, rdd, 1, &ws);
+	    mexc = ms->memory_write(address, rdd, 1, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1535,7 +1674,7 @@ dispatch_instruction(sregs)
 		if (sregs->frd == rd)
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 2, &ws);
+	    mexc = ms->memory_write(address, &sregs->fsi[rd], 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
@@ -1555,7 +1694,7 @@ dispatch_instruction(sregs)
 		if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
 		    sregs->fhold += (sregs->ftime - ebase.simtime);
 	    }
-	    mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 3, &ws);
+	    mexc = ms->memory_write(address, &sregs->fsi[rd], 3, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_STD;
 #ifdef STAT
@@ -1567,18 +1706,40 @@ dispatch_instruction(sregs)
 	    break;
 	case SWAPA:
 	    if (!chk_asi(sregs, &asi, op3)) break;
+	    if (address & 0x3) {
+		sregs->trap = TRAP_UNALI;
+		break;
+	    }
+	    mexc = ms->memory_read_asi(asi, address, &data, 2, &ws);
+	    sregs->hold += ws;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+		break;
+	    }
+	    mexc = ms->memory_write_asi(asi, address, rdd, 2, &ws);
+	    sregs->hold += ws;
+	    sregs->icnt = T_LDST;
+	    if (mexc) {
+		sregs->trap = TRAP_DEXC;
+		break;
+	    } else
+		*rdd = data;
+#ifdef STAT
+	    sregs->nload++;
+#endif
+	    break;
 	case SWAP:
 	    if (address & 0x3) {
 		sregs->trap = TRAP_UNALI;
 		break;
 	    }
-	    mexc = ms->memory_read(asi, address, &data, 2, &ws);
+	    mexc = ms->memory_read(address, &data, 2, &ws);
 	    sregs->hold += ws;
 	    if (mexc) {
 		sregs->trap = TRAP_DEXC;
 		break;
 	    }
-	    mexc = ms->memory_write(asi, address, rdd, 2, &ws);
+	    mexc = ms->memory_write(address, rdd, 2, &ws);
 	    sregs->hold += ws;
 	    sregs->icnt = T_LDST;
 	    if (mexc) {
@@ -1814,7 +1975,7 @@ fpexec(op3, rd, rs1, rs2, sregs)
 	sregs->ftime += T_FDIVd;
 	break;
     case FMOVs:
-	sregs->fs[rd] = sregs->fs[rs2];
+	sregs->fsi[rd] = sregs->fsi[rs2];
 	sregs->ftime += T_FMOVs;
 	sregs->frs1 = 32;	/* rs1 ignored */
 	break;
@@ -1996,7 +2157,7 @@ execute_trap(sregs)
 	sregs->pc = sregs->tbr;
 	sregs->npc = sregs->tbr + 4;
 
-        if ( 0 != (1 & sregs->asr17) ) {
+        if ( 0 != (1 & (sregs->asr17 >> 13)) ) {
             /* single vector trapping! */
             sregs->pc = sregs->tbr & 0xfffff000;
             sregs->npc = sregs->pc + 4;
@@ -2043,7 +2204,10 @@ init_regs(sregs)
     sregs->npc = 4;
     sregs->trap = 0;
     sregs->psr &= 0x00f03fdf;
-    sregs->psr |= 0x11000080;	/* Set supervisor bit */
+    if (cputype == CPU_LEON3)
+      sregs->psr |= 0xF3000080;	/* Set supervisor bit */
+    else
+      sregs->psr |= 0x11000080;	/* Set supervisor bit */
     sregs->breakpoint = 0;
     sregs->annul = 0;
     sregs->fpstate = FP_EXE_MODE;
@@ -2072,4 +2236,8 @@ init_regs(sregs)
 
     sregs->rett_err = 0;
     sregs->jmpltime = 0;
+    if (cputype == CPU_LEON3) {
+        sregs->asr17 = 0x107;
+        if (!nfp) sregs->asr17 |= (3 << 10);  /* Meiko FPU */
+    } 
 }
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index 26cf5ef..6f985a1 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -45,7 +45,7 @@ struct irqcell  irqarr[16];
 
 int             ctrl_c = 0;
 int             sis_verbose = 0;
-char           *sis_version = "2.7.5";
+char           *sis_version = "2.8";
 int             nfp = 0;
 int             ift = 0;
 int             wrp = 0;
@@ -60,6 +60,7 @@ uint32		last_load_addr = 0;
 int		nouartrx = 0;
 host_callback 	*sim_callback;
 struct memsys *ms = &erc32sys;
+int		cputype = 0;		/* 0 = erc32, 3 = leon3 */
 
 #ifdef ERRINJ
 uint32		errcnt = 0;
@@ -477,7 +478,7 @@ exec_cmd(sregs, cmd)
 	    }
 	    sregs->pc = len & ~3;
 	    sregs->npc = sregs->pc + 4;
-	    if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
+	    if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
 	    printf("resuming at 0x%08x\n",sregs->pc);
 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
 		stat = run_sim(sregs, VAL(cmd2), 0);
@@ -553,6 +554,11 @@ exec_cmd(sregs, cmd)
 	    ebase.simtime = 0;
 	    reset_all();
 	    reset_stat(sregs);
+            if (last_load_addr != 0) {
+	        sregs->pc = last_load_addr & ~3;
+	        sregs->npc = sregs->pc + 4;
+            }
+	    if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
 	    if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
 		stat = run_sim(sregs, UINT64_MAX, 0);
 	    } else {
@@ -604,6 +610,11 @@ exec_cmd(sregs, cmd)
 	    ebase.simtime = 0;
 	    reset_all();
 	    reset_stat(sregs);
+            if (last_load_addr != 0) {
+	        sregs->pc = last_load_addr & ~3;
+	        sregs->npc = sregs->pc + 4;
+            }
+	    if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
 	    sregs->tlimit = limcalc(sregs->freq);
 	    stat = run_sim(sregs, UINT64_MAX, 0);
 	    daddr = sregs->pc;
@@ -639,8 +650,8 @@ void
 show_stat(sregs)
     struct pstate  *sregs;
 {
-    uint32          iinst;
-    uint32          stime;
+    uint64          iinst;
+    uint64          stime;
 
     if (sregs->tottime == 0.0) sregs->tottime +=1E-6;
     stime = ebase.simtime - sregs->simstart;	/* Total simulated time */
@@ -654,31 +665,31 @@ show_stat(sregs)
     printf(" Instructions : %9llu\n", sregs->ninst);
 
 #ifdef STAT
-    printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
+    printf("   integer    : %9.2f %%\n", 100.0 * (double) iinst / (double) sregs->ninst);
     printf("   load       : %9.2f %%\n",
-	   100.0 * (float) sregs->nload / (float) sregs->ninst);
+	   100.0 * (double) sregs->nload / (double) sregs->ninst);
     printf("   store      : %9.2f %%\n",
-	   100.0 * (float) sregs->nstore / (float) sregs->ninst);
+	   100.0 * (double) sregs->nstore / (double) sregs->ninst);
     printf("   branch     : %9.2f %%\n",
-	   100.0 * (float) sregs->nbranch / (float) sregs->ninst);
+	   100.0 * (double) sregs->nbranch / (double) sregs->ninst);
     printf("   float      : %9.2f %%\n",
-	   100.0 * (float) sregs->finst / (float) sregs->ninst);
+	   100.0 * (double) sregs->finst / (double) sregs->ninst);
     printf(" Integer CPI  : %9.2f\n",
-	   ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
+	   ((double) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
 	   /
-	   (float) (sregs->ninst - sregs->finst));
+	   (double) (sregs->ninst - sregs->finst));
     printf(" Float CPI    : %9.2f\n",
-	   ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
+	   ((double) sregs->fholdt / (double) sregs->finst) + 1.0);
 #endif
     printf(" Overall CPI  : %9.2f\n",
-	   (float) (stime - sregs->pwdtime) / (float) sregs->ninst);
-    printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
-	   sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime),
-	   sregs->freq * (float) (sregs->ninst - sregs->finst) /
-	   (float) (stime - sregs->pwdtime),
-     sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
-    printf(" Simulated ERC32 time        : %.2f s\n", (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
-    printf(" Processor utilisation       : %.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
+	   (double) (stime - sregs->pwdtime) / (double) sregs->ninst);
+    printf("\n CPU performance (%4.1f MHz)  : %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
+	   sregs->freq, sregs->freq * (double) sregs->ninst / (double) (stime - sregs->pwdtime),
+	   sregs->freq * (double) (sregs->ninst - sregs->finst) /
+	   (double) (stime - sregs->pwdtime),
+     sregs->freq * (double) sregs->finst / (double) (stime - sregs->pwdtime));
+    printf(" Simulated CPU time          : %.2f s\n", (double) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
+    printf(" Processor utilisation       : %.2f %%\n", 100.0 * (1.0 - ((double) sregs->pwdtime / (double) stime)));
     printf(" Real-time performance       : %.2f %%\n", 100.0/
       ((sregs->tottime) / ((double) (stime) / (sregs->freq * 1.0E6))));
     printf(" Simulator performance       : %.2f MIPS\n",(double)(sregs->ninst)/sregs->tottime/1E6);
diff --git a/sim/erc32/grlib.c b/sim/erc32/grlib.c
new file mode 100644
index 0000000..42a3ed0
--- /dev/null
+++ b/sim/erc32/grlib.c
@@ -0,0 +1,98 @@
+/*
+ * This file is part of SIS.
+ * 
+ * SIS, SPARC instruction simulator. Copyright (C) 2014 Jiri Gaisler
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ * 
+ */
+
+
+#include "sis.h"
+#include "grlib.h"
+
+
+/* APB PNP */
+
+static uint32 apbppmem[32*2];    /* 32-entry APB PP AREA */
+static int apbppindex;
+
+int grlib_apbpp_add(uint32 id, uint32 addr)
+{
+    apbppmem[apbppindex++] = id;
+    apbppmem[apbppindex++] = addr;
+    if(apbppindex >= (32*2)) apbppindex = 0; /* prevent overflow of area */
+    return(apbppindex);
+}
+
+uint32 grlib_apbpnp_read(uint32 addr)
+{
+    uint32 read_data;
+    addr &= 0xff;
+    read_data = apbppmem[addr>>2];
+
+    return read_data;
+}
+
+/* AHB PNP */
+
+static uint32 ahbppmem[128*8];    /* 128-entry AHB PP AREA */
+static int ahbmppindex;
+static int ahbsppindex = 64*8;
+
+int grlib_ahbmpp_add(uint32 id)
+{
+    ahbppmem[ahbmppindex] = id;
+    ahbmppindex += 8;
+    if(ahbmppindex >= (64*8)) ahbmppindex = 0; /* prevent overflow of area */
+    return(ahbmppindex);
+}
+
+int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2,
+                     uint32 addr3, uint32 addr4)
+{
+    ahbppmem[ahbsppindex] = id;
+    ahbsppindex += 4;
+    ahbppmem[ahbsppindex++] = addr1;
+    ahbppmem[ahbsppindex++] = addr2;
+    ahbppmem[ahbsppindex++] = addr3;
+    ahbppmem[ahbsppindex++] = addr4;
+    if(ahbsppindex >= (128*8)) ahbsppindex = 64*8; /* prevent overflow of area */
+    return(ahbsppindex);
+}
+
+uint32 grlib_ahbpnp_read(uint32 addr)
+{
+    uint32 read_data;
+
+    addr &= 0xfff;
+    read_data = ahbppmem[addr>>2];
+    return read_data;
+
+}
+
+void grlib_init()
+{
+    /* Add PP records for Leon3, APB bridge and interrupt controller
+       as this is not done elsewhere */
+
+    grlib_ahbmpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_LEON3, 0, 0));
+    grlib_ahbspp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_APBMST, 0, 0),
+                     GRLIB_PP_AHBADDR(0x80000000, 0xFFF, 0, 0, 2),
+                     0, 0, 0);
+
+    grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_IRQMP, 2, 0),
+                    GRLIB_PP_APBADDR(0x80000200, 0xFFF));
+
+}
diff --git a/sim/erc32/grlib.h b/sim/erc32/grlib.h
new file mode 100644
index 0000000..4d52211
--- /dev/null
+++ b/sim/erc32/grlib.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of SIS.
+ * 
+ * SIS, SPARC instruction simulator. Copyright (C) 2014 Jiri Gaisler
+ * 
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+/* Definitions for AMBA PNP in Gaisler Research GRLIB SOC */
+
+/* Vendors */
+#define VENDOR_GAISLER    1
+#define VENDOR_PENDER     2
+#define VENDOR_ESA        4
+#define VENDOR_DLR       10
+
+/* Devices */
+#define GAISLER_LEON3    0x003
+#define GAISLER_APBMST   0x006
+#define GAISLER_SRCTRL   0x008
+#define GAISLER_APBUART  0x00C
+#define GAISLER_IRQMP    0x00D
+#define GAISLER_GPTIMER  0x011
+#define ESA_MCTRL        0x00F
+
+/* How to build entries in the plug&play area */
+#define GRLIB_PP_ID(v, d, x, i) ((v & 0xff) << 24) | ((d & 0x3ff) << 12) |\
+                                ((x & 0x1f) << 5) | (i & 0x1f)
+#define GRLIB_PP_AHBADDR(a, m, p, c, t) (a & 0xfff00000) | ((m & 0xfff) << 4) |\
+                         ((p & 1) << 17) | ((c & 1) << 16) | (t & 0x3)
+#define GRLIB_PP_APBADDR(a, m) ((a & 0xfff00)<< 12) | ((m & 0xfff) << 4) | 1
+
+#define AHBPP_START   0xFFFFF000
+#define AHBPP_END     0xFFFFFFFF
+#define APBPP_START   0x800FF000
+#define APBPP_END     0x800FFFFF
+
+int grlib_apbpp_add(uint32 id, uint32 addr);
+int grlib_ahbmpp_add(uint32 id);
+int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2,
+                     uint32 addr3, uint32 addr4);
+uint32 grlib_ahbpnp_read(uint32 addr);
+uint32 grlib_apbpnp_read(uint32 addr);
+void grlib_init();
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 2fab99f..6a406ba 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -52,7 +52,7 @@ run_sim(sregs, icount, dis)
    ms->init_stdio();
    sregs->starttime = get_time();
    irq = 0;
-   if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
+   if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
    while (!sregs->err_mode & (icount > 0)) {
 
 	sregs->fhold = 0;
@@ -187,6 +187,10 @@ sim_open (kind, callback, abfd, argv)
             if (strcmp(argv[stat], "-nouartrx") == 0) {
 		nouartrx = 1;
 	    } else
+            if (strcmp(argv[stat], "-leon3") == 0) {
+		ms = &leon3;
+                cputype = CPU_LEON3;
+            } else
             if (strcmp(argv[stat], "-wrp") == 0) {
                 wrp = 1;
 	    } else
@@ -224,9 +228,21 @@ sim_open (kind, callback, abfd, argv)
 	stat++;
     }
 
+    if (cputype == CPU_LEON3)
+        sregs.freq = freq ? freq : 50;
+    else
+        sregs.freq = freq ? freq : 14;
+
     if (sis_verbose) {
 	(*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
-	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
+	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jiri@gaisler.se)\n\n");
+        switch (cputype) {
+        case CPU_LEON3:
+            (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled\n");
+            break;
+        default:
+            (*sim_callback->printf_filtered) (sim_callback, "ERC32 emulation enabled\n");
+        }
 	if (nfp)
 	  (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
 	if (sparclite)
@@ -235,11 +251,9 @@ sim_open (kind, callback, abfd, argv)
 	  (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
 	if (sis_gdb_break == 0)
 	  (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
-	if (freq)
-	  (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
+	  (*sim_callback->printf_filtered) (sim_callback, "CPU freq %3.1f MHz\n", sregs.freq);
     }
 
-    sregs.freq = freq ? freq : 15;
     termsave = fcntl(0, F_GETFL, 0);
     INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
 #ifdef HOST_LITTLE_ENDIAN
@@ -457,7 +471,7 @@ flush_windows ()
 #endif
 
       for (i = 0; i < 16; i++)
-	ms->memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
+	ms->memory_write (sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
 		      &ws);
 
       if (win == cwp)
diff --git a/sim/erc32/leon3.c b/sim/erc32/leon3.c
new file mode 100644
index 0000000..e79169e
--- /dev/null
+++ b/sim/erc32/leon3.c
@@ -0,0 +1,1066 @@
+/*
+ * This file is part of SIS.
+ * 
+ * SIS, SPARC instruction simulator V2.5 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 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 <http://www.gnu.org/licenses/>.
+ * 
+ * Leon3 emulation, loosely based on erc32.c .
+ */
+
+/* The control space devices */
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include "sis.h"
+#include "grlib.h"
+#include "sim-config.h"
+
+static int tty_setup = 1; /* default setup if not a tty */
+
+/* APB registers */
+#define APBSTART	0x80000000
+#define APBEND  	0x80100000
+
+/* Memory exception waitstates */
+#define MEM_EX_WS 	1
+
+#define MOK	0
+
+/* LEON3 APB register addresses */
+
+#define IRQMP_IPR		0x204
+#define IRQMP_IMR 	0x240
+#define IRQMP_ICR 	0x20C
+#define IRQMP_IFR 	0x208
+#define GPTIMER_SCALER  0x300
+#define GPTIMER_SCLOAD  0x304
+#define GPTIMER_CONFIG  0x308
+#define GPTIMER_TIMER1 	0x310
+#define GPTIMER_RELOAD1	0x314
+#define GPTIMER_CTRL1 	0x318
+#define GPTIMER_TIMER2 	0x320
+#define GPTIMER_RELOAD2	0x324
+#define GPTIMER_CTRL2 	0x328
+
+#define APBUART_RXTX	0x100
+#define APBUART_STATUS  0x104
+
+/* Size of UART buffers (bytes) */
+#define UARTBUF	1024
+
+/* Number of simulator ticks between flushing the UARTS. 	 */
+/* For good performance, keep above 1000			 */
+#define UART_FLUSH_TIME	  3000
+
+
+/* New uart defines */
+#define UART_TX_TIME	1000
+#define UART_RX_TIME	1000
+#define UARTA_DR	0x1
+#define UARTA_SRE	0x2
+#define UARTA_HRE	0x4
+#define UARTA_OR	0x10
+
+/* IRQMP registers */
+
+static uint32   irqmp_ipr;
+static uint32   irqmp_imr;
+static uint32   irqmp_ifr;
+
+/* GPTIMER registers */
+
+#define NGPTIMERS  2
+#define GPTIMER_IRQ 8
+
+static uint32   gpt_scaler;
+static uint32   gpt_scaler_start;
+static uint32   gpt_counter[NGPTIMERS];
+static uint32   gpt_reload[NGPTIMERS];
+static uint32   gpt_ctrl[NGPTIMERS];
+
+/* ROM size 16 Mbyte */
+#define ROM_START 	0x00000000
+#define ROM_MASK 	0x00ffffff
+#define ROM_END 	(ROM_START + ROM_MASK + 1)
+
+/* RAM size 16 Mbyte */
+#define RAM_START 	0x40000000
+#define RAM_MASK 	0x00ffffff
+#define RAM_END 	(RAM_START + RAM_MASK + 1)
+
+/* Memory */
+
+static unsigned char	romb[ROM_END - ROM_START];
+static unsigned char	ramb[RAM_END - RAM_START];
+static uint32   cache_ctrl;
+
+
+/* UART support variables */
+
+static int32    fd1, fd2;	/* file descriptor for input file */
+static int32    Ucontrol;	/* UART status register */
+static unsigned char aq[UARTBUF], bq[UARTBUF];
+static int32    anum, aind = 0;
+static int32    bnum, bind = 0;
+static char     wbufa[UARTBUF], wbufb[UARTBUF];
+static unsigned wnuma;
+static unsigned wnumb;
+static FILE    *f1in, *f1out;
+static struct termios ioc1, ioc2, iocold1, iocold2;
+static int      f1open = 0;
+
+static char     uarta_sreg, uarta_hreg;
+static uint32   uart_stat_reg;
+static uint32   uarta_data;
+
+/* Forward declarations */
+
+static void	mem_init (void);
+static void	close_port (void);
+static void	leon3_reset (void);
+static void	irqmp_intack (int32 level);
+static void	chk_irq (void);
+static void	set_irq (int32 level);
+static int32	apb_read (uint32 addr, uint32 *data);
+static int	apb_write (uint32 addr, uint32 data);
+static void	port_init (void);
+static uint32	grlib_read_uart (uint32 addr);
+static void	grlib_write_uart (uint32 addr, uint32 data);
+static void	flush_uart (void);
+static void	uarta_tx (void);
+static void	uart_rx (caddr_t arg);
+static void	uart_intr (caddr_t arg);
+static void	uart_irq_start (void);
+static void	gpt_intr (caddr_t arg);
+static void	gpt_init (void);
+static void	gpt_reset (void);
+static void	gpt_scaler_set (uint32 val);
+static void	timer_ctrl (uint32 val, int i);
+static unsigned char *
+		get_mem_ptr (uint32 addr, uint32 size);
+static void	store_bytes (unsigned char *mem, uint32 waddr,
+			uint32 *data, int sz, int32 *ws);
+
+static host_callback *callback;
+
+
+/* One-time init */
+
+static void
+init_sim()
+{
+    callback = sim_callback;
+    grlib_init();
+    mem_init();
+    port_init();
+    gpt_init();
+}
+
+/* Power-on reset init */
+
+static void
+reset()
+{
+    leon3_reset();
+    uart_irq_start();
+    gpt_reset();
+}
+
+/* IU error mode manager */
+
+static void
+error_mode(pc)
+    uint32          pc;
+{
+
+}
+
+
+/* Memory init */
+
+static void
+mem_init()
+{
+
+/* Add AMBA P&P record for SRCTRL memory controller */
+
+    grlib_ahbspp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_SRCTRL, 0, 0),
+                     GRLIB_PP_AHBADDR(0x00000000, 0xE00, 1, 1, 2),
+                     GRLIB_PP_AHBADDR(0x40000000, 0xC00, 1, 1, 2),
+                     GRLIB_PP_AHBADDR(0x20000000, 0xE00, 0, 0, 2),
+                     0);
+    if (sis_verbose)
+	printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
+	       RAM_START, (RAM_MASK+1)/1024, (ROM_MASK+1)/1024);
+}
+
+/* Flush ports when simulator stops */
+
+static void
+sim_halt()
+{
+#ifdef FAST_UART
+    flush_uart();
+#endif
+}
+
+static void
+close_port()
+{
+    if (f1open && f1in != stdin)
+	fclose(f1in);
+}
+
+static void
+exit_sim()
+{
+    close_port();
+}
+
+static void
+leon3_reset()
+{
+    int             i;
+
+    irqmp_ipr = 0;
+    irqmp_imr = 0;
+    irqmp_ifr = 0;
+
+    wnuma = wnumb = 0;
+    anum = aind = bnum = bind = 0;
+
+    uart_stat_reg = UARTA_SRE | UARTA_HRE;
+
+    gpt_counter[0] = 0xffffffff;
+    gpt_reload[0] = 0xffffffff;
+    gpt_scaler = 0xffff;
+    gpt_ctrl[0] = 0;
+    gpt_ctrl[1] = 0;
+
+}
+
+
+
+static void
+irqmp_intack(level)
+    int32           level;
+{
+    int             irq_test;
+
+    if (sis_verbose > 2)
+	printf("interrupt %d acknowledged\n", level);
+    if (irqmp_ifr & (1 << level))
+	irqmp_ifr &= ~(1 << level);
+    else
+	irqmp_ipr &= ~(1 << level);
+   chk_irq();
+}
+
+static void
+chk_irq()
+{
+    int32           i;
+    uint32          itmp;
+    int		    old_irl;
+
+    old_irl = ext_irl;
+    itmp = ((irqmp_ipr | irqmp_ifr) & irqmp_imr) & 0x0fffe;
+    ext_irl = 0;
+    if (itmp != 0) {
+	for (i = 15; i > 0; i--) {
+	    if (((itmp >> i) & 1) != 0) {
+		if ((sis_verbose > 2) && (i > old_irl)) 
+		    printf("IU irl: %d\n", i);
+		ext_irl = i;
+	        set_int(i, irqmp_intack, i);
+		break;
+	    }
+	}
+    }
+}
+
+static void
+set_irq(level)
+    int32           level;
+{
+    irqmp_ipr |= (1 << level);
+    chk_irq();
+}
+
+static int32
+apb_read(addr, data)
+    uint32          addr;
+    uint32         *data;
+{
+
+    switch (addr & 0xfff) {
+
+    case APBUART_RXTX:		/* 0x100 */
+    case APBUART_STATUS:	/* 0x104 */
+	*data = grlib_read_uart(addr);
+	break;
+
+    case IRQMP_IPR:		/* 0x204 */
+	*data = irqmp_ipr;
+	break;
+
+    case IRQMP_IFR:		/* 0x208 */
+	*data = irqmp_ifr;
+	break;
+
+    case IRQMP_IMR:		/* 0x240 */
+	*data = irqmp_imr;
+	break;
+
+    case GPTIMER_SCALER:	/* 0x300 */
+	*data = gpt_scaler - (now() - gpt_scaler_start);
+	break;
+
+    case GPTIMER_SCLOAD:	/* 0x304 */
+	*data = gpt_scaler;
+	break;
+
+    case GPTIMER_CONFIG:	/* 0x308 */
+	*data = 0x100 | (GPTIMER_IRQ << 3) | NGPTIMERS;
+	break;
+
+    case GPTIMER_TIMER1:	/* 0x310 */
+	*data = gpt_counter[0];
+	break;
+
+    case GPTIMER_RELOAD1:	/* 0x314 */
+	*data = gpt_reload[0];
+	break;
+
+    case GPTIMER_CTRL1:		/* 0x318 */
+	*data = gpt_ctrl[0];
+	break;
+
+    case GPTIMER_TIMER2:	/* 0x320 */
+	*data = gpt_counter[1];
+	break;
+
+    case GPTIMER_RELOAD2:	/* 0x324 */
+	*data = gpt_reload[1];
+	break;
+
+    case GPTIMER_CTRL2:		/* 0x328 */
+	*data = gpt_ctrl[1];
+	break;
+
+    default:
+	*data = 0;
+	break;
+    }
+
+    if (sis_verbose > 1)
+	printf("APB read  a: %08x, d: %08x\n", addr, *data);
+
+    return (MOK);
+}
+
+static int
+apb_write(addr, data)
+    uint32          addr;
+    uint32          data;
+{
+    if (sis_verbose > 1)
+	printf("APB write a: %08x, d: %08x\n",addr,data);
+    switch (addr & 0xfff) {
+
+    case APBUART_RXTX:		/* 0x100 */
+    case APBUART_STATUS:	/* 0x104 */
+	grlib_write_uart(addr, data);
+	break;
+
+    case IRQMP_IFR:		/* 0x208 */
+	irqmp_ifr = data & 0xfffe;
+	chk_irq();
+	break;
+
+    case IRQMP_ICR:		/* 0x20C */
+	irqmp_ipr &= ~data & 0x0fffe;
+	chk_irq();
+	break;
+
+    case IRQMP_IMR:		/* 0x240 */
+	irqmp_imr = data & 0x7ffe;
+	chk_irq();
+	break;
+
+    case GPTIMER_SCLOAD:	/* 0x304 */
+	gpt_scaler_set(data);
+	break;
+
+    case GPTIMER_TIMER1:	/* 0x310 */
+	gpt_counter[0] = data;
+	break;
+
+    case GPTIMER_RELOAD1:	/* 0x314 */
+        gpt_reload[0] = data;
+	break;
+
+    case GPTIMER_CTRL1:		/* 0x318 */
+	timer_ctrl(data, 0);
+	break;
+
+    case GPTIMER_TIMER2:	/* 0x320 */
+	gpt_counter[1] = data;
+	break;
+
+    case GPTIMER_RELOAD2:	/* 0x324 */
+        gpt_reload[1] = data;
+	break;
+
+    case GPTIMER_CTRL2:		/* 0x328 */
+	timer_ctrl(data, 1);
+	break;
+
+    default:
+	break;
+    }
+    return (MOK);
+}
+
+
+/* APBUART */
+
+static int      ifd1 = -1, ofd1 = -1;
+
+static void
+init_stdio()
+{
+    if (dumbio)
+        return; /* do nothing */
+    if (ifd1 == 0 && f1open) {
+	tcsetattr(0, TCSANOW, &ioc1);
+        tcflush(ifd1, TCIFLUSH);
+    }
+}
+
+static void
+restore_stdio()
+{
+    if (dumbio)
+        return; /* do nothing */
+    if (ifd1 == 0 && f1open && tty_setup)
+	tcsetattr(0, TCSANOW, &iocold1);
+}
+
+#define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
+             ( dumbio || nouartrx \
+               ? (0) /* no bytes read, no delay */   \
+               : (_fd_) == 1 && callback ? \
+                 callback->read_stdin (callback, _buf_, _len_) :  \
+                 read( _fd_, _buf_, _len_ ) )
+
+
+static void
+port_init()
+{
+
+    f1in = stdin;
+    f1out = stdout;
+    if (uart_dev1[0] != 0)
+	if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) {
+	    printf("Warning, couldn't open output device %s\n", uart_dev1);
+	} else {
+	    if (sis_verbose)
+		printf("serial port A on %s\n", uart_dev1);
+	    f1in = f1out = fdopen(fd1, "r+");
+	    setbuf(f1out, NULL);
+	    f1open = 1;
+	}
+    if (f1in) ifd1 = fileno(f1in);
+    if (ifd1 == 0) {
+        if (callback && !callback->isatty(callback, ifd1)) {
+            tty_setup = 0;
+        }
+	if (sis_verbose)
+	    printf("serial port A on stdin/stdout\n");
+        if (!dumbio) {
+            tcgetattr(ifd1, &ioc1);
+            if (tty_setup) {
+            iocold1 = ioc1;
+            ioc1.c_lflag &= ~(ICANON | ECHO);
+            ioc1.c_cc[VMIN] = 0;
+            ioc1.c_cc[VTIME] = 0;
+        }
+        }
+	f1open = 1;
+    }
+
+    if (f1out) {
+	ofd1 = fileno(f1out);
+    	if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL);
+    }
+
+    wnuma = 0;
+
+
+    grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_APBUART, 1, 3),
+                    GRLIB_PP_APBADDR(0x80000100, 0xFFF));
+}
+
+static uint32
+grlib_read_uart(addr)
+    uint32          addr;
+{
+
+    unsigned        tmp;
+
+    tmp = 0;
+    switch (addr & 0xff) {
+
+    case 0x00:			/* UART 1 RX/TX */
+#ifndef _WIN32
+#ifdef FAST_UART
+
+	if (aind < anum) {
+	    if ((aind + 1) < anum)
+		set_irq(3);
+	    return ((uint32) aq[aind++]);
+	} else {
+	    if (f1open) {
+	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
+	    }
+      else {
+          anum = 0;
+      }
+	    if (anum > 0) {
+		aind = 0;
+		if ((aind + 1) < anum)
+		    set_irq(3);
+		return ((uint32) aq[aind++]);
+	    } else {
+		return ((uint32) aq[aind]);
+	    }
+
+	}
+#else
+	tmp = uarta_data;
+	uarta_data &= ~UART_DR;
+	uart_stat_reg &= ~UARTA_DR;
+	return tmp;
+#endif
+#else
+	return(0);
+#endif
+	break;
+
+    case 0x04:			/* UART status register	 */
+#ifndef _WIN32
+#ifdef FAST_UART
+
+	Ucontrol = 0;
+	if (aind < anum) {
+	    Ucontrol |= 0x00000001;
+	} else {
+	    if (f1open) {
+	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
+            }
+	    else {
+		anum = 0;
+	    }
+	    if (anum > 0) {
+		Ucontrol |= 0x00000001;
+		aind = 0;
+		set_irq(3);
+	    }
+	}
+	Ucontrol |= 0x00000006;
+	return (Ucontrol);
+#else
+	return (uart_stat_reg);
+#endif
+#else
+	return(0x00060006);
+#endif
+	break;
+    default:
+	if (sis_verbose)
+	    printf("Read from unimplemented MEC register (%x)\n", addr);
+
+    }
+    return (0);
+}
+
+static void
+grlib_write_uart(addr, data)
+    uint32          addr;
+    uint32          data;
+{
+    unsigned char   c;
+
+    c = (unsigned char) data;
+    switch (addr & 0xff) {
+
+    case 0x00:			/* UART A */
+#ifdef FAST_UART
+	if (f1open) {
+	    if (wnuma < UARTBUF)
+	        wbufa[wnuma++] = c;
+	    else {
+	        while (wnuma) {
+              if (ofd1 == 1 && callback)
+                  wnuma -= callback->write_stdout(callback, wbufa, wnuma);
+              else
+		    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
+          }
+	        wbufa[wnuma++] = c;
+	    }
+	}
+	set_irq(3);
+#else
+	if (uart_stat_reg & UARTA_SRE) {
+	    uarta_sreg = c;
+	    uart_stat_reg &= ~UARTA_SRE;
+	    event(uarta_tx, 0, UART_TX_TIME);
+	} else {
+	    uarta_hreg = c;
+	    uart_stat_reg &= ~UARTA_HRE;
+	}
+#endif
+	break;
+
+    case 0x04:			/* UART status register */
+#ifndef FAST_UART
+        uart_stat_reg &= 1;
+#endif
+	break;
+    default:
+	if (sis_verbose)
+	    printf("Write to unimplemented APB register (%x)\n", addr);
+
+    }
+}
+
+static void
+flush_uart()
+{
+    while (wnuma && f1open) {
+        if (ofd1 == 1 && callback) {
+            wnuma -= callback->write_stdout(callback, wbufa, wnuma);
+            callback->flush_stdout(callback);
+        }
+        else
+	wnuma -= fwrite(wbufa, 1, wnuma, f1out);
+    }
+}
+
+
+
+static void
+uarta_tx()
+{
+    while (f1open) {
+        if (ofd1 == 1 && callback) {
+            while (callback->write_stdout(callback, &uarta_sreg, 1) != 1);
+        }
+        else {
+            while (fwrite(&uarta_sreg, 1, 1, f1out) != 1);
+        }
+    }
+    if (uart_stat_reg & UARTA_HRE) {
+	uart_stat_reg |= UARTA_SRE;
+    } else {
+	uarta_sreg = uarta_hreg;
+	uart_stat_reg |= UARTA_HRE;
+	event(uarta_tx, 0, UART_TX_TIME);
+    }
+    set_irq(3);
+}
+
+static void
+uart_rx(arg)
+    caddr_t         arg;
+{
+    int32           rsize;
+    char            rxd;
+
+
+    rsize = 0;
+    if (f1open)
+        rsize = DO_STDIO_READ(ifd1, &rxd, 1);
+    else
+        rsize = 0;
+    if (rsize > 0) {
+	uarta_data = rxd;
+	if (uart_stat_reg & UARTA_DR) {
+	    uart_stat_reg |= UARTA_OR;
+	}
+	uart_stat_reg |= UARTA_DR;
+	set_irq(3);
+    }
+    event(uart_rx, 0, UART_RX_TIME);
+}
+
+static void
+uart_intr(arg)
+    caddr_t         arg;
+{
+    grlib_read_uart(APBUART_STATUS); /* Check for UART interrupts every 1000 clk */
+    flush_uart();		/* Flush UART ports      */
+    event(uart_intr, 0, UART_FLUSH_TIME);
+}
+
+
+static void
+uart_irq_start()
+{
+#ifdef FAST_UART
+    event(uart_intr, 0, UART_FLUSH_TIME);
+#else
+#ifndef _WIN32
+    event(uart_rx, 0, UART_RX_TIME);
+#endif
+#endif
+}
+
+/* GPTIMER */
+
+static void
+gpt_intr(arg)
+    caddr_t         arg;
+{
+    int i;
+
+    for (i=0; i<NGPTIMERS; i++) {
+	if (gpt_ctrl[i] & 1) {
+            gpt_counter[i] -= 1;
+            if (gpt_counter[i] == -1) {
+	        if (gpt_ctrl[i] & 8)
+	            set_irq(GPTIMER_IRQ + i);
+	        if (gpt_ctrl[i] & 2)
+	            gpt_counter[i] = gpt_reload[i];
+            }
+        }
+    }
+    event(gpt_intr, 0, gpt_scaler + 1);
+    gpt_scaler_start = now();
+}
+
+static void
+gpt_init()
+{
+    if (sis_verbose)
+	printf("GPT started (period %d)\n\r", gpt_scaler + 1);
+
+    grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_GPTIMER, 0, 8),
+                    GRLIB_PP_APBADDR(0x80000300, 0xFFF));
+}
+
+static void
+gpt_reset()
+{
+    event(gpt_intr, 0, gpt_scaler + 1);
+    gpt_scaler_start = now();
+}
+
+static void
+gpt_scaler_set(val)
+    uint32          val;
+{
+    gpt_scaler = val & 0x0ffff;	/* 16-bit scaler */
+}
+
+static void
+timer_ctrl(val, i)
+    uint32       val;
+    int          i;
+{
+    if (val & 4) {  /* reload */
+        gpt_counter[i] = gpt_reload[i];
+    }
+    gpt_ctrl[i] = val & 0xb;
+}
+
+/* Store data in host byte order.  MEM points to the beginning of the
+   emulated memory; WADDR contains the index the emulated memory,
+   DATA points to words in host byte order to be stored.  SZ contains log(2)
+   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
+   2 (one word), or 3 (two words); WS should return the number of wait-states. */
+
+static void
+store_bytes (mem, waddr, data, sz, ws)
+    unsigned char  *mem;
+    uint32	   waddr;
+    uint32	   *data;
+    int32	    sz;
+    int32	   *ws;
+{
+    switch (sz) {
+	case 0:
+#ifdef HOST_LITTLE_ENDIAN
+	    waddr ^= 3;
+#endif
+	    mem[waddr] = *data & 0x0ff;
+	    *ws = 0;
+	    break;
+	case 1:
+#ifdef HOST_LITTLE_ENDIAN
+	    waddr ^= 2;
+#endif
+	    *((unsigned short *) &(mem[waddr])) = *data & 0x0ffff;
+	    *ws = 0;
+	    break;
+	case 2:
+	    *((uint32 *) &(mem[waddr])) = *data;
+	    *ws = 0;
+	    break;
+	case 3:
+	    *((uint32 *) &(mem[waddr])) = data[0];
+	    *((uint32 *) &(mem[waddr + 4])) = data[1];
+	    *ws = 0;
+	    break;
+    }
+}
+
+
+/* Memory emulation */
+
+static int
+memory_iread(addr, data, ws)
+    uint32          addr;
+    uint32         *data;
+    int32          *ws;
+{
+    if ((addr >= RAM_START) && (addr < RAM_END)) {
+        *data = *((uint32 *) & (ramb[addr & RAM_MASK]));
+	*ws = 0;
+	return (0);
+    } else if (addr < ROM_END) {
+        *data = *((uint32 *) & (romb[addr]));
+	*ws = 0;
+	return (0);
+    }
+
+    printf("Memory exception at %x (illegal address)\n", addr);
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+static int
+memory_read(addr, data, sz, ws)
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    int32           mexc;
+
+    if ((addr >= RAM_START) && (addr < RAM_END)) {
+        *data = *((uint32 *) & (ramb[addr & RAM_MASK & ~3]));
+	*ws = 0;
+	return (0);
+    } else if ((addr >= APBPP_START) && (addr <= APBPP_END)) {
+        *data = grlib_apbpnp_read(addr);
+        if (sis_verbose > 1)
+	     printf("APB PP read a: %08x, d: %08x\n",addr, *data);
+	*ws = 4;
+	return (0);
+    } else if ((addr >= APBSTART) && (addr < APBEND)) {
+	mexc = apb_read(addr, data);
+	if (mexc) {
+	    *ws = MEM_EX_WS;
+	} else {
+	    *ws = 0;
+	}
+	return (mexc);
+    } else if ((addr >= AHBPP_START) && (addr <= AHBPP_END)) {
+        if (sis_verbose > 1)
+	     printf("AHB PP read a: %08x, d: %08x\n",addr, *data);
+        *data = grlib_ahbpnp_read(addr);
+	*ws = 4;
+	return (0);
+    } else if (addr < ROM_END) {
+        *data = *((uint32 *) & (romb[addr & ~3]));
+	*ws = 0;
+	return (0);
+    }
+
+    printf("Memory exception at %x (illegal address)\n", addr);
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+static int
+memory_read_asi(asi, addr, data, sz, ws)
+    int32           asi;
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    if (asi == 2) {
+        if (addr == 0)
+            *data = cache_ctrl;
+        else
+            *data = 0;
+        return MOK;
+    } else
+        return(memory_read(addr, data, sz, ws));
+}
+
+static int
+memory_write(addr, data, sz, ws)
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    uint32          byte_addr;
+    uint32          byte_mask;
+    uint32          waddr;
+    uint32         *ram;
+    int32           mexc;
+    int             i;
+    int             wphit[2];
+
+    if ((addr >= RAM_START) && (addr < RAM_END)) {
+	waddr = addr & RAM_MASK;
+	store_bytes (ramb, waddr, data, sz, ws);
+	return (0);
+
+    } else if ((addr >= APBSTART) && (addr < APBEND)) {
+	if (sz != 2) {
+	    *ws = MEM_EX_WS;
+	    return (1);
+	}
+	apb_write(addr, *data);
+	*ws = 0;
+	return (0);
+
+    } else if (addr < ROM_END) {
+//        return (1);
+	*ws = 0;
+	store_bytes (romb, addr, data, sz, ws);
+        return (0);
+    }
+	
+    *ws = MEM_EX_WS;
+    return (1);
+}
+
+static int
+memory_write_asi(asi, addr, data, sz, ws)
+    int32           asi;
+    uint32          addr;
+    uint32         *data;
+    int32           sz;
+    int32          *ws;
+{
+    if (asi == 2) {
+        cache_ctrl = *data & 0x81000f;
+        if (sis_verbose)
+            printf("cache ctrl reg : 0x%08x\n", cache_ctrl);
+        return MOK;
+    } else
+        return(memory_write(addr, data, sz, ws));
+}
+
+static unsigned char  *
+get_mem_ptr(addr, size)
+    uint32          addr;
+    uint32          size;
+{
+    if ((addr + size) < ROM_END) {
+	return (&romb[addr]);
+    } else if ((addr >= RAM_START) && ((addr + size) < RAM_END)) {
+	return (&ramb[addr & RAM_MASK]);
+    }
+
+    return ((char *) -1);
+}
+
+static int
+sis_memory_write(addr, data, length)
+    uint32               addr;
+    const unsigned char *data;
+    uint32               length;
+{
+    char           *mem;
+
+    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
+	return (0);
+
+    memcpy(mem, data, length);
+    return (length);
+}
+
+static int
+sis_memory_read(addr, data, length)
+    uint32          addr;
+    char           *data;
+    uint32          length;
+{
+    char           *mem;
+    int            ws;
+
+    if (length == 4) {
+      memory_read(addr, data, length, &ws);
+      return(4);
+    }
+
+    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
+	return (0);
+
+    memcpy(data, mem, length);
+    return (length);
+}
+
+static void
+boot_init ()
+{
+//    mec_write(MEC_WCR, 0);	/* zero waitstates */
+//    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
+    apb_write(GPTIMER_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
+    apb_write(GPTIMER_SCLOAD, sregs.freq-1);
+    apb_write(GPTIMER_TIMER1, -1);
+    apb_write(GPTIMER_RELOAD1, -1);
+    apb_write(GPTIMER_CTRL1, 0x7);
+//    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
+    sregs.wim = 2;
+    sregs.psr = 0xF30010e0;
+    sregs.r[30] = RAM_END;
+    sregs.r[14] = sregs.r[30] - 96*4;
+    cache_ctrl = 0x81000f;
+}
+
+struct memsys leon3 = {
+    init_sim,
+    reset,
+    error_mode,
+    sim_halt,
+    exit_sim,
+    init_stdio,
+    restore_stdio,
+    memory_iread,
+    memory_read,
+    memory_read_asi,
+    memory_write,
+    memory_write_asi,
+    sis_memory_write,
+    sis_memory_read,
+    boot_init
+};
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index efd8a63..68ec319 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -141,7 +141,7 @@ main(argc, argv)
     for (i = 0; i < 64; i++)
 	cmdq[i] = 0;
     printf("\n SIS - SPARC instruction simulator %s,  copyright Jiri Gaisler 1995\n", sis_version);
-    printf(" Bug-reports to jgais@wd.estec.esa.nl\n\n");
+    printf(" Bug-reports to jiri@gaisler.se\n\n");
     while (stat < argc) {
 	if (argv[stat][0] == '-') {
 	    if (strcmp(argv[stat], "-v") == 0) {
@@ -180,6 +180,10 @@ main(argc, argv)
 		dumbio = 1;
             } else if (strcmp(argv[stat], "-nouartrx") == 0) {
 		nouartrx = 1;
+            } else if (strcmp(argv[stat], "-leon3") == 0) {
+		ms = &leon3;
+                if (freq == 14) freq = 50;
+                cputype = CPU_LEON3;
             } else if (strcmp(argv[stat], "-v") == 0) {
 		sis_verbose = 1;
             } else if (strcmp(argv[stat], "-vv") == 0) {
@@ -194,13 +198,19 @@ main(argc, argv)
 	}
 	stat++;
     }
+
+    switch (cputype) {
+    case CPU_LEON3:	
+	printf(" LEON3 emulation enabled\n");
+	break;
+    default:
+	printf(" ERC32 emulation enabled\n");
+    }
+
     if (nfp)
-	printf("FPU disabled\n");
-#ifdef ERA
-    if (era)
-	printf("ERA ECC emulation enabled\n");
-#endif
+	printf(" FPU disabled\n");
     sregs.freq = freq;
+    printf("\n");
 
     INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
 #ifdef HOST_LITTLE_ENDIAN
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index a7bb39a..98e0e38 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -153,6 +153,30 @@ struct irqcell {
     int32           arg;
 };
 
+struct memsys {
+    void	(*init_sim) ();
+    void	(*reset) (void);
+    void	(*error_mode) (uint32 pc);
+    void	(*sim_halt) (void);
+    void	(*exit_sim) (void);
+    void	(*init_stdio) (void);
+    void	(*restore_stdio) (void);
+    int	        (*memory_iread) (uint32 addr, uint32 *data, int32 *ws);
+    int	        (*memory_read) (uint32 addr, uint32 *data,
+			     int32 sz, int32 *ws);
+    int	        (*memory_read_asi) (int32 asi, uint32 addr, uint32 *data,
+			     int32 sz, int32 *ws);
+    int	        (*memory_write) (uint32 addr, uint32 *data,
+			      int32 sz, int32 *ws);
+    int	        (*memory_write_asi) (int32 asi, uint32 addr, uint32 *data,
+			      int32 sz, int32 *ws);
+    int	        (*sis_memory_write) (uint32 addr,
+				  const unsigned char *data, uint32 length);
+    int	        (*sis_memory_read) (uint32 addr, char *data,
+				 uint32 length);
+    void	(*boot_init) (void);
+};
+
 
 #define OK 0
 #define TIME_OUT 1
@@ -160,6 +184,8 @@ struct irqcell {
 #define ERROR 3
 #define CTRL_C 4
 
+#define CPU_LEON3  3
+
 /* Prototypes  */
 
 /* erc32.c */
@@ -215,6 +241,7 @@ extern int	nouartrx;
 extern          host_callback *sim_callback;
 extern int	current_target_byte_order;
 extern int      dumbio;
+extern int      cputype;
 
 /* exec.c */
 extern int	dispatch_instruction (struct pstate *sregs);
@@ -235,23 +262,7 @@ extern void	set_fsr (uint32 fsr);
 extern void	usage (void);
 extern void	gen_help (void);
 
-struct memsys {
-    void	(*init_sim) ();
-    void	(*reset) (void);
-    void	(*error_mode) (uint32 pc);
-    void	(*sim_halt) (void);
-    void	(*exit_sim) (void);
-    void	(*init_stdio) (void);
-    void	(*restore_stdio) (void);
-    int	        (*memory_iread) (uint32 addr, uint32 *data, int32 *ws);
-    int	        (*memory_read) (int32 asi, uint32 addr, uint32 *data,
-			     int32 sz, int32 *ws);
-    int	        (*memory_write) (int32 asi, uint32 addr, uint32 *data,
-			      int32 sz, int32 *ws);
-    int	        (*sis_memory_write) (uint32 addr,
-				  const unsigned char *data, uint32 length);
-    int	        (*sis_memory_read) (uint32 addr, char *data,
-				 uint32 length);
-};
-
 extern struct memsys *ms;
+
+/* leon3.c */
+extern struct memsys leon3;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 20/23] sim/erc32: Updated documentation
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (19 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17 11:03   ` Mike Frysinger
  2015-02-17 15:52   ` Eli Zaretskii
  2015-02-17  7:46 ` [PATCH 19/23] sim/erc32: Added support for the Leon2 processor Jiri Gaisler
  2015-02-17  8:54 ` [PATCH 00/22] Update of the SPARC SIS simulator Mike Frysinger
  22 siblings, 2 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	Cleaned up documentation. Obsolote README files were removed,
	main documentation on operation is now in READMEM.sis.
---
 sim/erc32/NEWS         | 108 ----------------------------
 sim/erc32/README.gdb   |  67 ------------------
 sim/erc32/README.leon2 |  53 ++++++++++++++
 sim/erc32/README.sis   | 189 +++++++++++++++++--------------------------------
 sim/erc32/startsim     |   4 --
 5 files changed, 116 insertions(+), 305 deletions(-)
 delete mode 100644 sim/erc32/NEWS
 delete mode 100644 sim/erc32/README.gdb
 create mode 100644 sim/erc32/README.leon2
 delete mode 100644 sim/erc32/startsim

diff --git a/sim/erc32/NEWS b/sim/erc32/NEWS
deleted file mode 100644
index dd24b7b..0000000
--- a/sim/erc32/NEWS
+++ /dev/null
@@ -1,108 +0,0 @@
-
-version 2.0 05-02-96
---------------------
-
-* Switched to bfd library. Any supported format (elf, coff, ...) can be used.
-* The UART devices can be set through -uart1 and -uart2 switches.
-* Switched to GNU readline.
-* Added -c option to run batch files at startup
-* 'reg' command can show different register windows (eg 'reg w3').
-* Use 'help' for online help on simulator commands
-
-version 1.8.1 20-01-96
---------------------
-
-* added -mevrev0 switch to simulate MEC rev.0 bugs in timer and uart
-
-* added -iurev0 switch to simulate IU rev.0 jmpl/restore bug
-
-* Added sis command 'batch' to run batch files
-
-
-version 1.8 30-10-95
---------------------
-
-* Added s-record support. Use the '-s' switch with sis or the 'load' command.
-
-* IU load dependencies are now modelled
-
-version 1.7 30-10-95
---------------------
-
-* Power-down mode implemented in erc32.c.
-  
-* Performance display shows the ratio between simulator-time and real-time.
-
-
-version 1.6.2 25-10-95
---------------------
-
-* The UARTs can now be run at a given speed (simulator time) to better
-  simulate the behaviour of interrupt routines. The "true mode" is
-  selected through a compile switch in the makefile.
-
-
-version 1.6 28-09-95
---------------------
-
-* Major reorganisation of the code. mec.c and mem.c merged into erc32.c.
-
-* The load command does NOT longer load the initialised data at an address
-  defined by .bdata. This is done in srt0.s using _environ.
-
-* Additional MEC functionallity added - software reset, memory access
-  protection and waitstate configuration register.
-
-* interf.c - a GDB interface added
-
-* -v switch (verbose) added
-
-version 1.5 14-09-95
---------------------
-
-* Added a instruction trace buffer, enabled through the 'hist' command.
-
-* Added a 'perf' command to display statistics such as instruction mix,
-  CPI, FPU holds etc.
-
-* Added -nfp switch to disable FPU.
-
-* Added -freq switch to set simulated frequency.
-
-version 1.4 22-08-95
---------------------
-
-* A -g is provided for those who have problems with GNU readline(). 
-
-version 1.3 26-07-95
---------------------
-
-* No major news, just a bug fix release ...
-
-
-version 1.2 13-07-95
---------------------
-
-* Added setting of IU registers through the 'reg' command. See README.
-
-* The GNU readline() function is used for command input. However, a
-ctrl-D still kills the simulator ...
-
-
-version 1.1 07-07-95
---------------------
-
-
-* Added a 'go' command
-
-* Added cycle counting for interrupt overhead.
-
-* Function 'get_mem_ptr' takes one more parameter to avoid segmentation 
-   faults if a.out files are loaded outside the simulated memory. See README.
-
-* Added user-defined function sim_stop().
-
-* Added a reset command. See README.
-
-* Implemented buffered output for MEC uarts to improve output speed.
-
diff --git a/sim/erc32/README.gdb b/sim/erc32/README.gdb
deleted file mode 100644
index 619fcb3..0000000
--- a/sim/erc32/README.gdb
+++ /dev/null
@@ -1,67 +0,0 @@
-How to use SIS with GDB
------------------------
-
-1. Building GDB with SIS
-
-To build GDB with the SIS/ERC32 simulator, configure with option
-'--target sparc-erc32-aout' and build as usual.
-
-2. Attaching the simulator
-
-To attach GDB to the simulator, use:
-
-target sim [options] [files]
-
-The following options are supported:
-
- -nfp		Disable FPU. FPops will cause an FPU disabled trap.
-
- -freq <f>	Set the simulated "system clock" to <f> MHz.
-
- -v		Verbose mode.
-
- -nogdb		Disable GDB breakpoint handling (see below)
-
-The listed [files] are expected to be in aout format and will be
-loaded in the simulator memory prior. This could be used to load
-a boot block at address 0x0 if the application is linked to run
-from RAM (0x2000000).
-
-To start debugging a program type 'load <program>' and debug as
-usual. 
-
-The native simulator commands can be reached using the GDB 'sim'
-command:
-
-sim <sis_command>
-
-Direct simulator commands during a GDB session must be issued
-with care not to disturb GDB's operation ... 
-
-For info on supported ERC32 functionality, see README.sis.
-
-
-3. Loading aout files
-
-The GDB load command loads an aout file into the simulator
-memory with the data section starting directly after the text
-section regardless of wich start address was specified for the data
-at link time! This means that your applications either has to include
-a routine that initialise the data segment at the proper address or
-link with the data placed directly after the text section.
-
-A copying routine is fairly simple, just copy all data between
-_etext and _data to a memory loaction starting at _environ. This
-should be done at the same time as the bss is cleared (in srt0.s).
-
-
-4. GDB breakpoint handling
-
-GDB inserts breakpoint in the form of the 'ta 1' instruction. The
-GDB-integrated simulator will therefore recognize the breakpoint
-instruction and return control to GDB. If the application uses
-'ta 1', the breakpoint detection can be disabled with the -nogdb
-switch. In this case however, GDB breakpoints will not work.
-
-
-Report problems to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)
diff --git a/sim/erc32/README.leon2 b/sim/erc32/README.leon2
new file mode 100644
index 0000000..3820eca
--- /dev/null
+++ b/sim/erc32/README.leon2
@@ -0,0 +1,53 @@
+
+1. LEON2 emulation
+
+The file 'leon2.c' contains a model of simple LEON2 sub-system. It 
+contains 16 Mbyte ROM and 16 Mbyte RAM. Standard peripherals
+such as interrupt controller, UART and timer are provided.
+The model can execute leon2 binaries that do not require an
+MMU.
+
+To start sis in Leon2 mode, add the -leon2 switch. In gdb,
+use 'target sim -leon2' .
+
+1.1 UART
+
+One LEON2 UART is emaulted, and is located at address 0x80000070.
+The following registers are implemeted:
+
+- UART RX and TX register	(0x80000070)
+- UART status register		(0x80000074)
+
+The UART generates interrupt 3.
+
+1.2 Timer unit 
+
+The LEON2 timer unit is emulated and located at address 0x80000040.
+It is configured with two timers and separate interrupts (8 and 9).
+The scaler is configured to 16 bits, while the counters are 32 bits.
+
+1.3 Interrupt controller
+
+The interrupt controller is implemented as described in the
+LEON2 IP manual, with the exception of the interrupt level register.
+Secondary interrupts are not supported. The registers are located
+at address 0x80000090.
+
+1.5 Memory interface
+
+The following memory areas are valid for the Leon3 simulator:
+
+0x00000000 - 0x01000000		ROM (16 Mbyte, loaded at start-up)
+0x40000000 - 0x41000000		RAM (16 Mbyte, loaded at start-up)
+0x80000000 - 0x81000000		APB bus, including plug&play
+0xFFFFF000 - 0xFFFFFFFF		AHB plug&play area
+
+Access to non-existing memory will result in a memory exception trap.
+
+1.8 Power-down mode
+
+The Leon2 power-down register (0x80000018) is supported. When power-down is
+entered, time is skipped forward until the next event in the event queue.
+However, if the simulator event queue is empty, power-down mode is not
+entered since no interrupt would be generated to exit from the mode. A
+Ctrl-C in the simulator window will exit the power-down mode.
diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis
index eb4a683..59c4c64 100644
--- a/sim/erc32/README.sis
+++ b/sim/erc32/README.sis
@@ -13,11 +13,12 @@ and peripherals.
 
 The simulator is started as follows: 
 
-sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] 
+sis [-leon2] [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] 
     [-nfp] [-freq frequency] [-c batch_file] [files] 
 
-By default, SIS emaultes an ERC32 system. The -leon3 switch
-enables emulation of a LEON3 SOC system.
+By default, SIS emaultes an ERC32 system. The -leon2 switch enables
+LEON2 emaultion, while the -leon3 switch enables emulation of a 
+LEON3 SOC system.
 
 The emulated console uart is connected stdin/stdout. The -uart[1,2]
 switch can be used to connect the uarts to other devices.
@@ -143,6 +144,50 @@ Typing a 'Ctrl-C' will interrupt a running simulator.
 Short forms of the commands are allowed, e.g 'c' 'co' or 'con' are all
 interpreted as 'cont'. 
 
+2 Using SIS with gdb
+
+2.1 Attaching the simulator
+
+To attach GDB to the simulator, use:
+
+target sim [options]
+
+The following options are supported:
+
+ -leon2         Emulate a LEON2 system
+
+ -leon3         Emulate a LEON3 system
+
+ -nfp           Disable FPU. FPops will cause an FPU disabled trap.
+
+ -freq <f>      Set the simulated "system clock" to <f> MHz.
+
+ -v             Verbose mode.
+
+ -nogdb         Disable GDB breakpoint handling (see below)
+
+To start debugging a program type 'load <program>' and debug as
+usual.
+
+The native simulator commands can be reached using the GDB 'sim'
+command:
+
+sim <sis_command>
+
+Direct simulator commands during a GDB session must be issued
+with care not to disturb GDB's operation ...
+
+A program can be restarted in gdb by first issuing the load command,
+followed by run.
+
+2.2 GDB breakpoint handling
+
+GDB inserts breakpoint in the form of the 'ta 1' instruction. The
+GDB-integrated simulator will therefore recognize the breakpoint
+instruction and return control to GDB. If the application uses
+'ta 1', the breakpoint detection can be disabled with the -nogdb
+switch. In this case however, GDB breakpoints will not work.
+
 
 3. Simulator core
 
@@ -153,129 +198,10 @@ maintained and inremented according the IU and FPU instruction timing.
 The parallel execution between the IU and FPU is modelled, as well as
 stalls due to operand dependencies (FPU).
 
-In Leon3 mode, the core emulates the Leon3 SPARC V8 core from
+In Leon2/3 mode, the core emulates the Leon2/3 SPARC V8 core from
 Gaisler Research. All SPARC V8 instructions are supported but
 emaultion is not fully cycle-true as the cache is not emulated.
 
-The core interacts with the user-defined memory modules through
-a number of functions. The memory module must provide the following
-functions:
-
-int memory_read(asi,addr,data,ws)
-int asi;
-unsigned int addr;
-unsigned int *data;
-int *ws;
-
-int memory_write(asi,addr,data,sz,ws)
-int asi;
-unsigned int addr;
-unsigned int *data;
-int sz;
-int *ws;
-
-int sis_memory_read(addr, data, length)
-unsigned int addr;
-char   *data;
-unsigned int length;
-
-int sis_memory_write(addr, data, length)
-unsigned int addr;
-char    *data;
-unsigned int length;
-
-int init_sim()
-
-int reset()
-
-int error_mode(pc)
-unsigned int pc;
-
-memory_read() is used by the simulator to fetch instructions and
-operands.  The address space identifier (asi) and address is passed as
-parameters. The read data should be assigned to the data pointer
-(*data) and the number of waitstate to *ws. 'memory_read' should return
-0 on success and 1 on failure. A failure will cause a data or
-instruction fetch trap. memory_read() always reads one 32-bit word.
-
-sis_memory_read() is used by the simulator to display and disassemble
-memory contants. The function should copy 'length' bytes of the simulated
-memory starting at 'addr' to '*data'.
-The sis_memory_read() should return 1 on success and 0 on failure.
-Failure should only be indicated if access to unimplemented memory is attempted.
-
-memory_write() is used to write to memory. In addition to the asi
-and address parameters, the size of the written data is given by 'sz'.
-The pointer *data points to the data to be written. The 'sz' is coded
-as follows:
-
-  sz	access type
-  0	  byte
-  1	  halfword
-  2	  word
-  3	  double-word
-
-If a double word is written, the most significant word is in data[0] and
-the least significant in data[1].
-
-sis_memory_write() is used by the simulator during loading of programs.
-The function should copy 'length' bytes from *data to the simulated
-memory starting at 'addr'. sis_memory_write() should return 1 on 
-success and 0 on failure. Failure should only be indicated if access 
-to unimplemented memory is attempted. See erc32.c for more details 
-on how to define the memory emulation functions.
-
-The 'init_sim' is called once when the simulator is started. This function
-should be used to perform initialisations of user defined memory or 
-peripherals that only have to be done once, such as opening files etc.
-
-The 'reset' is called every time the simulator is reset, i.e. when a
-'run' command is given. This function should be used to simulate a power
-on reset of memory and peripherals.
-
-error_mode() is called by the simulator when the IU goes into error mode,
-typically if a trap is caused when traps are disabled. The memory module
-can then take actions, such as issue a reset.
-
-sys_reset() can be called by the memory module to reset the simulator. A
-reset will empty the event queue and perform a power-on reset.
-
-4. Events and interrupts
-
-The simulator supports an event queue and the generation of processor
-interrupts. The following functions are available to the user-defined
-memory module:
-
-event(cfunc,arg,delta)
-void (*cfunc)();
-int arg;
-unsigned int delta;
-
-set_int(level,callback,arg)
-int level;
-void (*callback)();
-int arg;
-
-clear_int(level)
-int level;
-
-sim_stop()
-
-The 'event' functions will schedule the execution of the function 'cfunc'
-at time 'now + delta' clock cycles. The parameter 'arg' is passed as a 
-parameter to 'cfunc'.
-
-The 'set_int' function set the processor interrupt 'level'. When the interrupt
-is taken, the function 'callback' is called with the argument 'arg'. This
-will also clear the interrupt. An interrupt can be cleared before it is
-taken by calling 'clear_int' with the appropriate interrupt level.
-
-The sim_stop function is called each time the simulator stops execution.
-It can be used to flush buffered devices to get a clean state during
-single stepping etc.
-
-See 'erc32.c' for examples on how to use events and interrupts.
-
 5. Memory module
 
 The ERC32 memory module (erc32.c) emulates the functions of memory and
@@ -292,6 +218,19 @@ the MEC asic developed for the 90C601/2. It includes the following functions:
 
 See README.erc32 on how the MEC functions are emulated.
 
+The Leon2 memory module (leon2.c) emulates on-chip peripherals and
+external memory for a simple Leon2 system. The modules includes the
+following functions:
+
+* AHB and APB buses
+* One UART
+* Interrupt controller
+* Timer unit with two timers
+* PROM/SRAM memory controller
+* 16 Mbyte PROM, 16 Mbyte SRAM
+
+See README.leon2 for further details on Leon3 emulation.
+
 The Leon3 memory module (leon3.c) emulates on-chip peripherals and
 external memory for a simple Leon3 system. The modules includes the
 following functions:
@@ -305,9 +244,7 @@ following functions:
 
 See README.leon3 for further details on Leon3 emulation.
 
-6. Compile and linking programs
-
-7. IU and FPU instruction timing.
+6. IU and FPU instruction timing.
 
 The simulator provides cycle true simulation for ERC32. The following table
 shows the emulated instruction timing for 90C601E & 90C602E:
diff --git a/sim/erc32/startsim b/sim/erc32/startsim
deleted file mode 100644
index 1b9b41c..0000000
--- a/sim/erc32/startsim
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-xterm -e sis $* &
-xterm -e tip /dev/ttypc &
-
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (12 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 11/23] sim/erc32: use AC_C_BIGENDIAN to probe for host endian Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  8:59   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 08/23] sim/erc32: added -v and -vv command line switches for verbose output Jiri Gaisler
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

Binaries produced by most erc32 tool-chains do not include
system initialization. sis will detect this and initialize
necessary registers for memory and timer control.

	* erc32.c (mec_read) allow simulator memory size to be read
	by application. (boot_init) initialize memory and timers if
	start address is not 0.

	* erc32,c (exe_cmd) call boot_init if start address not 0
	* interf.c (run_sim) Likewise
---
 sim/erc32/erc32.c  | 24 ++++++++++++++++++++++++
 sim/erc32/func.c   |  1 +
 sim/erc32/interf.c |  1 +
 3 files changed, 26 insertions(+)

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 4d4177e..4fa8f61 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -743,6 +743,14 @@ mec_read(addr, asi, data)
 	*data = read_uart(addr);
 	break;
 
+    case 0xF4:		/* simulator RAM size in bytes */
+	*data = 4096*1024;
+	break;
+
+    case 0xF8:		/* simulator ROM size in bytes */
+	*data = 1024*1024;
+	break;
+
     default:
 	set_sfsr(MEC_ACC, addr, asi, 1);
 	return (1);
@@ -1887,3 +1895,19 @@ sis_memory_read(addr, data, length)
     memcpy(data, mem, length);
     return (length);
 }
+
+extern struct pstate sregs;
+
+void
+boot_init ()
+{
+    mec_write(MEC_WCR, 0);	/* zero waitstates */
+    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
+    mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
+    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
+    sregs.wim = 2;
+    sregs.psr = 0x110010e0;
+    sregs.r[30] = RAM_END;
+    sregs.r[14] = sregs.r[30] - 96*4;
+    mec_mcr |= 1;		/* power-down enabled */
+}
diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index e6744ee..7034393 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -468,6 +468,7 @@ exec_cmd(sregs, cmd)
 	    }
 	    sregs->pc = len & ~3;
 	    sregs->npc = sregs->pc + 4;
+	    if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
 	    printf("resuming at 0x%08x\n",sregs->pc);
 	    if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
 		stat = run_sim(sregs, VAL(cmd2), 0);
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 63b3f38..9ac455f 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -78,6 +78,7 @@ run_sim(sregs, icount, dis)
    init_stdio();
    sregs->starttime = time(NULL);
    irq = 0;
+   if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
    while (!sregs->err_mode & (icount > 0)) {
 
 	sregs->fhold = 0;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 08/23] sim/erc32: added -v and -vv command line switches for verbose output
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (13 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  9:13   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 22/23] Added watchpoint support to gdb simulator interface Jiri Gaisler
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* help.c (usage) update usage help print-out

	* sis.c (run_sim) increase debug level with -v and -vv. Also print
	simulation time in long long format.
---
 sim/erc32/help.c |  2 +-
 sim/erc32/sis.c  | 10 +++++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/sim/erc32/help.c b/sim/erc32/help.c
index 21c2a77..6d74e79 100644
--- a/sim/erc32/help.c
+++ b/sim/erc32/help.c
@@ -7,8 +7,8 @@ usage()
 {
 
     printf("usage: sis [-uart1 uart_device1] [-uart2 uart_device2]\n");
+    printf("[-sparclite] [-dumbio] [-v] [-vv]\n");
     printf("[-nfp] [-freq frequency] [-c batch_file] [files]\n");
-    printf("[-sparclite] [-dumbio]\n");
 }
 
 void
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index 39050d7..97f1b31 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -122,7 +122,7 @@ run_sim(sregs, icount, dis)
 			        sregs->histind = 0;
 		        }
 		        if (dis) {
-			    printf(" %8u ", ebase.simtime);
+			    printf(" %8llu ", ebase.simtime);
 			    dis_mem(sregs->pc, 1, &dinfo);
 		        }
 		    }
@@ -214,6 +214,10 @@ main(argc, argv)
 #endif
             } else if (strcmp(argv[stat], "-dumbio") == 0) {
 		dumbio = 1;
+            } else if (strcmp(argv[stat], "-v") == 0) {
+		sis_verbose = 1;
+            } else if (strcmp(argv[stat], "-vv") == 0) {
+		sis_verbose = 2;
 	    } else {
 		printf("unknown option %s\n", argv[stat]);
 		usage();
@@ -279,7 +283,7 @@ main(argc, argv)
 	case CTRL_C:
 	    printf("\b\bInterrupt!\n");
 	case TIME_OUT:
-	    printf(" Stopped at time %d (%.3f ms)\n", ebase.simtime, 
+	    printf(" Stopped at time %llu (%.3f ms)\n", ebase.simtime,
 	      ((double) ebase.simtime / (double) sregs.freq) / 1000.0);
 	    break;
 	case BPT_HIT:
@@ -289,7 +293,7 @@ main(argc, argv)
 	case ERROR:
 	    printf("IU in error mode (%d)\n", sregs.trap);
 	    stat = 0;
-	    printf(" %8d ", ebase.simtime);
+	    printf(" %8llu ", ebase.simtime);
 	    dis_mem(sregs.pc, 1, &dinfo);
 	    break;
 	default:
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (8 preceding siblings ...)
  2015-02-17  7:45 ` [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not work due to API change Jiri Gaisler
@ 2015-02-17  7:46 ` Jiri Gaisler
  2015-02-17  9:07   ` Mike Frysinger
  2015-02-17  7:46 ` [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings Jiri Gaisler
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17  7:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiri Gaisler

	* func.c (reset_stat, show_stat) switch to double in time keeping
	(get_time) new function to get system time
	* sis.h Likewise
	* interf.c (run_sim) use get_time() for system time
	* sis.c (run_sim) Likewise
---
 sim/erc32/func.c   | 31 ++++++++++++++++++++++---------
 sim/erc32/interf.c |  5 ++---
 sim/erc32/sis.c    |  5 ++---
 sim/erc32/sis.h    |  5 +++--
 4 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/sim/erc32/func.c b/sim/erc32/func.c
index 7034393..1661175 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -612,7 +612,7 @@ void
 reset_stat(sregs)
     struct pstate  *sregs;
 {
-    sregs->tottime = 0;
+    sregs->tottime = 0.0;
     sregs->pwdtime = 0;
     sregs->ninst = 0;
     sregs->fholdt = 0;
@@ -631,9 +631,9 @@ show_stat(sregs)
     struct pstate  *sregs;
 {
     uint32          iinst;
-    uint32          stime, tottime;
+    uint32          stime;
 
-    if (sregs->tottime == 0) tottime = 1; else tottime = sregs->tottime;
+    if (sregs->tottime == 0.0) sregs->tottime +=1E-6;
     stime = ebase.simtime - sregs->simstart;	/* Total simulated time */
 #ifdef STAT
 
@@ -668,12 +668,12 @@ show_stat(sregs)
 	   sregs->freq * (float) (sregs->ninst - sregs->finst) /
 	   (float) (stime - sregs->pwdtime),
      sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
-    printf(" Simulated ERC32 time        : %5.2f ms\n", (float) (ebase.simtime - sregs->simstart) / 1000.0 / sregs->freq);
-    printf(" Processor utilisation       : %5.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
-    printf(" Real-time / simulator-time  : 1/%.2f \n",
-      ((float) sregs->tottime) / ((float) (stime) / (sregs->freq * 1.0E6)));
-    printf(" Simulator performance       : %d KIPS\n",sregs->ninst/tottime/1000);
-    printf(" Used time (sys + user)      : %3d s\n\n", sregs->tottime);
+    printf(" Simulated ERC32 time        : %.2f s\n", (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
+    printf(" Processor utilisation       : %.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
+    printf(" Real-time performance       : %.2f %%\n", 100.0/
+      ((sregs->tottime) / ((double) (stime) / (sregs->freq * 1.0E6))));
+    printf(" Simulator performance       : %.2f MIPS\n",(double)(sregs->ninst)/sregs->tottime/1E6);
+    printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);
 }
 
 
@@ -1127,3 +1127,16 @@ bfd_load(fname)
 
     return(bfd_get_start_address (pbfd));
 }
+
+
+double get_time (void)
+{
+    double usec;
+
+    struct timeval tm;
+
+    gettimeofday (&tm, NULL);
+    usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec);
+    return (usec / 1E6);
+
+}
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 9ac455f..38a2a0d 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -24,7 +24,6 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <time.h>
 #include <sys/fcntl.h>
 #include "sis.h"
 #include "libiberty.h"
@@ -76,7 +75,7 @@ run_sim(sregs, icount, dis)
 	(*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
 					  sregs->pc);
    init_stdio();
-   sregs->starttime = time(NULL);
+   sregs->starttime = get_time();
    irq = 0;
    if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
    while (!sregs->err_mode & (icount > 0)) {
@@ -142,7 +141,7 @@ run_sim(sregs, icount, dis)
 	}
     }
     sim_halt();
-    sregs->tottime += time(NULL) - sregs->starttime;
+    sregs->tottime += get_time() - sregs->starttime;
     restore_stdio();
     clearerr(stdin);
     if (sregs->err_mode)
diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
index 89e6f02..f2aed78 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -26,7 +26,6 @@
 #include <stdlib.h>
 #endif
 #include <stdio.h>
-#include <time.h>
 #include <sys/fcntl.h>
 #include "sis.h"
 #include <dis-asm.h>
@@ -86,7 +85,7 @@ run_sim(sregs, icount, dis)
 {
     int             irq, mexc, deb, asi;
 
-    sregs->starttime = time(NULL);
+    sregs->starttime = get_time();
     init_stdio();
     if (sregs->err_mode) icount = 0;
     deb = dis || sregs->histlen || sregs->bptnum;
@@ -146,7 +145,7 @@ run_sim(sregs, icount, dis)
 	    if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1;
 	}
     }
-    sregs->tottime += time(NULL) - sregs->starttime;
+    sregs->tottime += get_time() - sregs->starttime;
     restore_stdio();
     if (sregs->err_mode)
 	return (ERROR);
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index f49d45d..dc02c65 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -110,14 +110,14 @@ struct pstate {
     float32         freq;	/* Simulated processor frequency */
 
 
-    uint64          tottime;
+    double          tottime;
     uint64          ninst;
     uint64          fholdt;
     uint64          holdt;
     uint64          icntt;
     uint64          finst;
     uint64          simstart;
-    uint64          starttime;
+    double          starttime;
     uint64          tlimit;	/* Simulation time limit */
     uint64          pwdtime;	/* Cycles in power-down mode */
     uint64          nstore;	/* Number of load instructions */
@@ -198,6 +198,7 @@ extern void	reset_all (void);
 extern void	sys_reset (void);
 extern void	sys_halt (void);
 extern int	bfd_load (char *fname);
+extern double	get_time (void);
 
 /* exec.c */
 extern int	dispatch_instruction (struct pstate *sregs);
-- 
2.1.0

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/22] Update of the SPARC SIS simulator
  2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
                   ` (21 preceding siblings ...)
  2015-02-17  7:46 ` [PATCH 19/23] sim/erc32: Added support for the Leon2 processor Jiri Gaisler
@ 2015-02-17  8:54 ` Mike Frysinger
  2015-02-17 14:41   ` Jiri Gaisler
  22 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  8:54 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1026 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> This is a 22-part patch that brings the sis simulator into working
> order, and adds support for emulation of the leon2 and leon3 cpus.
> 
> The sis simulator was written by me in the mid 90's, to emulate the erc32
> processor (SPARC V7). It was included into gdb by Cygnus (Stan Shebs?),
> and adapted to also emulate the Fujistu Sparlite processor. The simulator
> has not been actively maintained for about 15 years, and suffered some
> bit-rot. It's primary use has been for RTEMS development. The erc32
> processor is now becoming obsolete, and being replaced by leon2 and
> leon3 cpus in many ESA and NASA missions. These patches will
> allow sis to be useful again, and support the newer leon2/3 processor.

it would be nice if there was a testsuite.  how are you verifying things 
continue to work and there are no regressions ?

should be easy to add some basic .s files to verify insns ... lots of examples 
in the testsuite/sim/ subdirs already.
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
  2015-02-17  7:46 ` [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address Jiri Gaisler
@ 2015-02-17  8:59   ` Mike Frysinger
  2015-02-18 14:40     ` Jiri Gaisler
  0 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  8:59 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1465 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> +extern struct pstate sregs;
> +
> +void
> +boot_init ()

in C, you need to do (void) to avoid ugliness.

also looks like this is missing an update to a header to add the prototype ?

> +{
> +    mec_write(MEC_WCR, 0);	/* zero waitstates */
> +    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
> +    mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
> +    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
> +    sregs.wim = 2;
> +    sregs.psr = 0x110010e0;
> +    sregs.r[30] = RAM_END;
> +    sregs.r[14] = sregs.r[30] - 96*4;
> +    mec_mcr |= 1;		/* power-down enabled */
> +}

why isn't sregs passed in as an arg ?  looks like both callers have a pointer to 
it already.

> --- a/sim/erc32/func.c
> +++ b/sim/erc32/func.c
> @@ -468,6 +468,7 @@ exec_cmd(sregs, cmd)
>  	    }
>  	    sregs->pc = len & ~3;
>  	    sregs->npc = sregs->pc + 4;
> +	    if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();

i know the code base doesn't follow GNU style already, but lets at least start 
moving in that direction.  i.e. uncuddle this:
	if (...)
	  boot_init();

> --- a/sim/erc32/interf.c
> +++ b/sim/erc32/interf.c
> @@ -78,6 +78,7 @@ run_sim(sregs, icount, dis)
>     init_stdio();
>     sregs->starttime = time(NULL);
>     irq = 0;
> +   if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();

same here
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts.
  2015-02-17  7:45 ` [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts Jiri Gaisler
@ 2015-02-17  9:05   ` Mike Frysinger
  2015-02-19 20:45     ` Jiri Gaisler
  0 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:05 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 325 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> 	* float.c (get_accex) access FPU control and status words on x64

shouldn't you gut this file and use <fenv.h> instead for a portable method ?
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fenv.h.html

at the very least, you could cut over to <fpu_control.h> ...
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report
  2015-02-17  7:46 ` [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report Jiri Gaisler
@ 2015-02-17  9:07   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:07 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1008 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> --- a/sim/erc32/func.c
> +++ b/sim/erc32/func.c
>  
> -    if (sregs->tottime == 0) tottime = 1; else tottime = sregs->tottime;
> +    if (sregs->tottime == 0.0) sregs->tottime +=1E-6;

should uncuddle the statement

needs a space after the "+=" operator

> +    printf(" Simulated ERC32 time        : %.2f s\n", (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
> +    printf(" Processor utilisation       : %.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
> +    printf(" Real-time performance       : %.2f %%\n", 100.0/
> +      ((sregs->tottime) / ((double) (stime) / (sregs->freq * 1.0E6))));
> +    printf(" Simulator performance       : %.2f MIPS\n",(double)(sregs->ninst)/sregs->tottime/1E6);
> +    printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);

please line wrap these longer ones, and put spaces in the right places: after 
commas, around math operators, etc...
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 07/23] sim/erc32: file loading via command line did not work
  2015-02-17  7:45 ` [PATCH 07/23] sim/erc32: file loading via command line did not work Jiri Gaisler
@ 2015-02-17  9:09   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:09 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 123 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> +    if (lfile) last_load_addr = bfd_load(argv[lfile]);

uncuddle please
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings
  2015-02-17  7:46 ` [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings Jiri Gaisler
@ 2015-02-17  9:10   ` Mike Frysinger
  2015-02-18 14:41     ` Jiri Gaisler
  0 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:10 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 290 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> --- a/sim/erc32/func.c
> +++ b/sim/erc32/func.c
>
> -	fgets(lbuf, 1023, fp);
> +	tmp = fgets(lbuf, 1023, fp);

not a new issue, but fgets needs to die in a fire.  getline is a trivial API and 
does a lot of nice stuff for you :).
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 08/23] sim/erc32: added -v and -vv command line switches for verbose output
  2015-02-17  7:46 ` [PATCH 08/23] sim/erc32: added -v and -vv command line switches for verbose output Jiri Gaisler
@ 2015-02-17  9:13   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:13 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 790 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> --- a/sim/erc32/sis.c
> +++ b/sim/erc32/sis.c
>
> -			    printf(" %8u ", ebase.simtime);
> +			    printf(" %8llu ", ebase.simtime);

if i'm reading things correctly, simtime is a uint64, which means you should 
include inttypes.h and use PRIu64 here instead of hardcoding llu.

same goes for the other changes you're making like this below.

> @@ -214,6 +214,10 @@ main(argc, argv)
>  #endif
>              } else if (strcmp(argv[stat], "-dumbio") == 0) {
>  		dumbio = 1;
> +            } else if (strcmp(argv[stat], "-v") == 0) {
> +		sis_verbose = 1;
> +            } else if (strcmp(argv[stat], "-vv") == 0) {
> +		sis_verbose = 2;

what about -v -v ?  maybe the -v handler should increment sim_verbose instead
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 11/23] sim/erc32: use AC_C_BIGENDIAN to probe for host endian.
  2015-02-17  7:46 ` [PATCH 11/23] sim/erc32: use AC_C_BIGENDIAN to probe for host endian Jiri Gaisler
@ 2015-02-17  9:19   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:19 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 960 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> Use  AC_C_BIGENDIAN to probe for host endian during build, rather

the sim tree provides SIM_AC_OPTION_HOSTENDIAN which you should use instead.  
then you can use WITH_HOST_BYTE_ORDER in the source and compare it to 
LITTLE_ENDIAN or BIG_ENDIAN.  just include <sim-config.h> for it.

> --- a/sim/erc32/Makefile.in
> +++ b/sim/erc32/Makefile.in
>  
>  # Circumvent Sun Make bug with VPATH.
> -erc32.o: erc32.c sis.h end.h
> -exec.o: exec.c sis.h end.h
> -float.o: float.c sis.h end.h
> -func.o: func.c sis.h end.h
> -help.o: help.c sis.h end.h
> -interf.o: interf.c sis.h end.h 
> -sis.o: sis.c sis.h end.h
> +erc32.o: erc32.c sis.h
> +exec.o: exec.c sis.h
> +float.o: float.c sis.h
> +func.o: func.c sis.h
> +help.o: help.c sis.h
> +interf.o: interf.c sis.h
> +sis.o: sis.c sis.h

you should be able to delete all this stuff.  the build system will generate the 
deps for you now.
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 16/23] sim/erc32: use readline.h for readline types and functions.
  2015-02-17  7:45 ` [PATCH 16/23] sim/erc32: use readline.h for readline types and functions Jiri Gaisler
@ 2015-02-17  9:21   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17  9:21 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 231 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> --- a/sim/erc32/Makefile.in
> +++ b/sim/erc32/Makefile.in
>
> -SIM_EXTRA_CFLAGS = -DFAST_UART
> +SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcdir)/../..

pretty sure you mean -I$(srcroot)
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not work due to API change.
  2015-02-17  7:45 ` [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not work due to API change Jiri Gaisler
@ 2015-02-17 11:03   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17 11:03 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> 	The API to print_insn_sparc() has changed over the years ...

i'm sure you know way more about this than i, so rubber stamp lgtm ;)
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 02/23] sim/erc32: corrected wrong CPU implementation and version ID in %psr
  2015-02-17  7:45 ` [PATCH 02/23] sim/erc32: corrected wrong CPU implementation and version ID in %psr Jiri Gaisler
@ 2015-02-17 11:03   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17 11:03 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 23 bytes --]

rubberstamp lgtm
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 20/23] sim/erc32: Updated documentation
  2015-02-17  7:46 ` [PATCH 20/23] sim/erc32: Updated documentation Jiri Gaisler
@ 2015-02-17 11:03   ` Mike Frysinger
  2015-02-17 15:52   ` Eli Zaretskii
  1 sibling, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17 11:03 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> 	Cleaned up documentation. Obsolote README files were removed,
> 	main documentation on operation is now in READMEM.sis.

looks fine
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 05/23] sim/erc32: remove unused defines in Makefile and switch off statistics
  2015-02-17  7:45 ` [PATCH 05/23] sim/erc32: remove unused defines in Makefile and switch off statistics Jiri Gaisler
@ 2015-02-17 11:04   ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17 11:04 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 11 bytes --]

lgtm
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 13/23] sim/erc32: Fix a few compiler warnings
  2015-02-17  7:46 ` [PATCH 13/23] sim/erc32: Fix a few compiler warnings Jiri Gaisler
@ 2015-02-17 11:08   ` Mike Frysinger
  2015-02-18 16:21     ` Jiri Gaisler
  0 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-17 11:08 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 745 bytes --]

On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> 	Minor edits to remove compiler warnings.

if you're really interested in doing this, you could add SIM_AC_OPTION_WARNINGS 
to the erc32/configure.ac script ...

> --- a/sim/erc32/interf.c
> +++ b/sim/erc32/interf.c
> @@ -509,7 +509,7 @@ sim_do_command(sd, cmd)
>       SIM_DESC sd;
>       const char *cmd;
>  {
> -    exec_cmd(&sregs, cmd);
> +    exec_cmd(&sregs, (char *) cmd);
>  }

shouldn't exec_cmd be changed to take a const char * instead ?  looks to me like 
it treats it as constant ... it does a strdup(cmd) and only operates on the 
result.

looking further, seems like it this func really should use buildargv/freeargv 
rather than tokenize things itself ?
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/22] Update of the SPARC SIS simulator
  2015-02-17  8:54 ` [PATCH 00/22] Update of the SPARC SIS simulator Mike Frysinger
@ 2015-02-17 14:41   ` Jiri Gaisler
  2015-02-18  0:16     ` Mike Frysinger
  0 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-17 14:41 UTC (permalink / raw)
  To: gdb-patches


On 02/17/2015 09:54 AM, Mike Frysinger wrote:
> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>> This is a 22-part patch that brings the sis simulator into working
>> order, and adds support for emulation of the leon2 and leon3 cpus.
>>
>> The sis simulator was written by me in the mid 90's, to emulate the erc32
>> processor (SPARC V7). It was included into gdb by Cygnus (Stan Shebs?),
>> and adapted to also emulate the Fujistu Sparlite processor. The simulator
>> has not been actively maintained for about 15 years, and suffered some
>> bit-rot. It's primary use has been for RTEMS development. The erc32
>> processor is now becoming obsolete, and being replaced by leon2 and
>> leon3 cpus in many ESA and NASA missions. These patches will
>> allow sis to be useful again, and support the newer leon2/3 processor.
> it would be nice if there was a testsuite.  how are you verifying things
> continue to work and there are no regressions ?
>
> should be easy to add some basic .s files to verify insns ... lots of examples
> in the testsuite/sim/ subdirs already.
> -mike
I have a set of pre-compiled binaries to test for basic SPARC and FPU
compliance. On top of that, I run the RTEMS testsuite which is rather
extensive. Is it acceptable to drop a few SPARC binaries to the gdb
testuite/sim, or does it all have to be in source? The test applications
are typically written in C, so we would need a full C cross-compiler to
build them ...

Jiri.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 20/23] sim/erc32: Updated documentation
  2015-02-17  7:46 ` [PATCH 20/23] sim/erc32: Updated documentation Jiri Gaisler
  2015-02-17 11:03   ` Mike Frysinger
@ 2015-02-17 15:52   ` Eli Zaretskii
  1 sibling, 0 replies; 52+ messages in thread
From: Eli Zaretskii @ 2015-02-17 15:52 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches, jiri

> From: Jiri Gaisler <jiri@gaisler.se>
> Cc: Jiri Gaisler <jiri@gaisler.se>
> Date: Tue, 17 Feb 2015 08:44:57 +0100
> 
> 	Cleaned up documentation. Obsolote README files were removed,
> 	main documentation on operation is now in READMEM.sis.

Thanks.

> +One LEON2 UART is emaulted, and is located at address 0x80000070.
                     ^^^^^^^^
A typo.

> +The following registers are implemeted:
                               ^^^^^^^^^^
Another one.

> +LEON2 emaultion, while the -leon3 switch enables emulation of a 
         ^^^^^^^^^
And here.

> +Direct simulator commands during a GDB session must be issued
> +with care not to disturb GDB's operation ...
> +
> +A program can be restarted in gdb by first issuing the load command,
> +followed by run.

Please use either "gdb" or "GDB" consistently.

The documentation patches are OK with the above fixed.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation.
  2015-02-17  7:46 ` [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation Jiri Gaisler
@ 2015-02-17 15:58   ` Eli Zaretskii
  0 siblings, 0 replies; 52+ messages in thread
From: Eli Zaretskii @ 2015-02-17 15:58 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

> From: Jiri Gaisler <jiri@gaisler.se>
> Cc: Jiri Gaisler <jiri@gaisler.se>
> Date: Tue, 17 Feb 2015 08:44:55 +0100
> 
> +By default, SIS emaultes an ERC32 system. The -leon3 switch
                   ^^^^^^^^
A typo.

> +The emulated console uart is connected stdin/stdout. The -uart[1,2]
                                ^^^^^^^^^^^^^^^^^^^^^^
I guess "to stdin/stdout" is better.

> +emaultion is not fully cycle-true as the cache is not emulated.
   ^^^^^^^^^
A typo.

The documentation parts are OK after correcting these.

Thanks.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 00/22] Update of the SPARC SIS simulator
  2015-02-17 14:41   ` Jiri Gaisler
@ 2015-02-18  0:16     ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-18  0:16 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2222 bytes --]

On 17 Feb 2015 15:40, Jiri Gaisler wrote:
> On 02/17/2015 09:54 AM, Mike Frysinger wrote:
> > On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >> This is a 22-part patch that brings the sis simulator into working
> >> order, and adds support for emulation of the leon2 and leon3 cpus.
> >>
> >> The sis simulator was written by me in the mid 90's, to emulate the erc32
> >> processor (SPARC V7). It was included into gdb by Cygnus (Stan Shebs?),
> >> and adapted to also emulate the Fujistu Sparlite processor. The simulator
> >> has not been actively maintained for about 15 years, and suffered some
> >> bit-rot. It's primary use has been for RTEMS development. The erc32
> >> processor is now becoming obsolete, and being replaced by leon2 and
> >> leon3 cpus in many ESA and NASA missions. These patches will
> >> allow sis to be useful again, and support the newer leon2/3 processor.
> >
> > it would be nice if there was a testsuite.  how are you verifying things
> > continue to work and there are no regressions ?
> >
> > should be easy to add some basic .s files to verify insns ... lots of examples
> > in the testsuite/sim/ subdirs already.
>
> I have a set of pre-compiled binaries to test for basic SPARC and FPU
> compliance. On top of that, I run the RTEMS testsuite which is rather
> extensive. Is it acceptable to drop a few SPARC binaries to the gdb
> testuite/sim, or does it all have to be in source? The test applications
> are typically written in C, so we would need a full C cross-compiler to
> build them ...

unfortunately, it would have to be source, and i imagine the FSF would want the 
copyright for it.  i guess to mitigate, we could update the erc32 README with 
notes for how to test things.

the sim prefers .s/.S files because they can be assembled+linked entirely on 
their own (in the combined binutils+gdb tree), but .c files are certainly not 
banned.  if you look in the bfin/ subdir, you can see how i handle missing 
compiler support and fall back to SKIPing those tests.

i tend to prefer `make check` myself so that when i'm making common changes, i 
can run all the builtin testsuites to have some confidence i'm not breaking 
people.
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
  2015-02-17  8:59   ` Mike Frysinger
@ 2015-02-18 14:40     ` Jiri Gaisler
  2015-02-18 16:53       ` Mike Frysinger
  0 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-18 14:40 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1158 bytes --]



On 02/17/2015 09:59 AM, Mike Frysinger wrote:
> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>> +extern struct pstate sregs;
>> +
>> +void
>> +boot_init ()
> 
> in C, you need to do (void) to avoid ugliness.

Will fix.

> 
> also looks like this is missing an update to a header to add the prototype ?

This is done in patch (17/23).

> 
>> +{
>> +    mec_write(MEC_WCR, 0);	/* zero waitstates */
>> +    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
>> +    mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
>> +    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
>> +    sregs.wim = 2;
>> +    sregs.psr = 0x110010e0;
>> +    sregs.r[30] = RAM_END;
>> +    sregs.r[14] = sregs.r[30] - 96*4;
>> +    mec_mcr |= 1;		/* power-down enabled */
>> +}
> 
> why isn't sregs passed in as an arg ?  looks like both callers have a pointer to 
> it already.

I am saving this for next major update - SMP support. All globals will then
be removed and the full cpu state will be in a struct that is passed to the
simulation engine. In this way I can simulate multiple cpu's.

Jiri.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings
  2015-02-17  9:10   ` Mike Frysinger
@ 2015-02-18 14:41     ` Jiri Gaisler
  2015-02-18 16:57       ` Mike Frysinger
  0 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-18 14:41 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 461 bytes --]



On 02/17/2015 10:10 AM, Mike Frysinger wrote:
> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>> --- a/sim/erc32/func.c
>> +++ b/sim/erc32/func.c
>>
>> -	fgets(lbuf, 1023, fp);
>> +	tmp = fgets(lbuf, 1023, fp);
> 
> not a new issue, but fgets needs to die in a fire.  getline is a trivial API and 
> does a lot of nice stuff for you :).
> -mike
> 

I thought fgets was secure, as it cannot write past the (statically) allocated buffer.

Jiri.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 13/23] sim/erc32: Fix a few compiler warnings
  2015-02-17 11:08   ` Mike Frysinger
@ 2015-02-18 16:21     ` Jiri Gaisler
  2015-02-18 16:51       ` Mike Frysinger
  0 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-18 16:21 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1000 bytes --]



On 02/17/2015 12:07 PM, Mike Frysinger wrote:
> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>> 	Minor edits to remove compiler warnings.
> 
> if you're really interested in doing this, you could add SIM_AC_OPTION_WARNINGS 
> to the erc32/configure.ac script ...
> 
>> --- a/sim/erc32/interf.c
>> +++ b/sim/erc32/interf.c
>> @@ -509,7 +509,7 @@ sim_do_command(sd, cmd)
>>       SIM_DESC sd;
>>       const char *cmd;
>>  {
>> -    exec_cmd(&sregs, cmd);
>> +    exec_cmd(&sregs, (char *) cmd);
>>  }
> 
> shouldn't exec_cmd be changed to take a const char * instead ?  looks to me like 
> it treats it as constant ... it does a strdup(cmd) and only operates on the 
> result.

I am passing cmd to strok() at one place, so const char cannot be used.

> 
> looking further, seems like it this func really should use buildargv/freeargv 
> rather than tokenize things itself ?
> -mike
> 

I will keep this on my soon-todo list. Please bare with it this time ...

Jiri.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 13/23] sim/erc32: Fix a few compiler warnings
  2015-02-18 16:21     ` Jiri Gaisler
@ 2015-02-18 16:51       ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-18 16:51 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1308 bytes --]

On 18 Feb 2015 17:21, Jiri Gaisler wrote:
> On 02/17/2015 12:07 PM, Mike Frysinger wrote:
> > On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >> 	Minor edits to remove compiler warnings.
> > 
> > if you're really interested in doing this, you could add SIM_AC_OPTION_WARNINGS 
> > to the erc32/configure.ac script ...
> > 
> >> --- a/sim/erc32/interf.c
> >> +++ b/sim/erc32/interf.c
> >> @@ -509,7 +509,7 @@ sim_do_command(sd, cmd)
> >>       SIM_DESC sd;
> >>       const char *cmd;
> >>  {
> >> -    exec_cmd(&sregs, cmd);
> >> +    exec_cmd(&sregs, (char *) cmd);
> >>  }
> > 
> > shouldn't exec_cmd be changed to take a const char * instead ?  looks to me like 
> > it treats it as constant ... it does a strdup(cmd) and only operates on the 
> > result.
> 
> I am passing cmd to strok() at one place, so const char cannot be used.

ah, i see that now yes.  i'm not sure deploying the cast is correct as the API 
allows for a constant to be passed in at which time this would crash.

> > looking further, seems like it this func really should use buildargv/freeargv 
> > rather than tokenize things itself ?
> 
> I will keep this on my soon-todo list. Please bare with it this time ...

np.  in the meantime, adding a second dupe should allow for minimal code change.
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
  2015-02-18 14:40     ` Jiri Gaisler
@ 2015-02-18 16:53       ` Mike Frysinger
  2015-02-19 16:11         ` Jiri Gaisler
  0 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-18 16:53 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1413 bytes --]

On 18 Feb 2015 15:40, Jiri Gaisler wrote:
> On 02/17/2015 09:59 AM, Mike Frysinger wrote:
> > On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >> +extern struct pstate sregs;
> >> +
> >> +void
> >> +boot_init ()
> > 
> > also looks like this is missing an update to a header to add the prototype ?
> 
> This is done in patch (17/23).

ok, but patches things really should be standalone.  although your series is
pretty good already in terms of splitting things apart.

> >> +{
> >> +    mec_write(MEC_WCR, 0);	/* zero waitstates */
> >> +    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
> >> +    mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
> >> +    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
> >> +    sregs.wim = 2;
> >> +    sregs.psr = 0x110010e0;
> >> +    sregs.r[30] = RAM_END;
> >> +    sregs.r[14] = sregs.r[30] - 96*4;
> >> +    mec_mcr |= 1;		/* power-down enabled */
> >> +}
> > 
> > why isn't sregs passed in as an arg ?  looks like both callers have a pointer to 
> > it already.
> 
> I am saving this for next major update - SMP support. All globals will then
> be removed and the full cpu state will be in a struct that is passed to the
> simulation engine. In this way I can simulate multiple cpu's.

can't this particular bit be done already ?  or is the global pointer diff from
the local one ?
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings
  2015-02-18 14:41     ` Jiri Gaisler
@ 2015-02-18 16:57       ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-18 16:57 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 679 bytes --]

On 18 Feb 2015 15:40, Jiri Gaisler wrote:
> On 02/17/2015 10:10 AM, Mike Frysinger wrote:
> > On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >> --- a/sim/erc32/func.c
> >> +++ b/sim/erc32/func.c
> >>
> >> -	fgets(lbuf, 1023, fp);
> >> +	tmp = fgets(lbuf, 1023, fp);
> > 
> > not a new issue, but fgets needs to die in a fire.  getline is a trivial API and 
> > does a lot of nice stuff for you :).
> 
> I thought fgets was secure, as it cannot write past the (statically) allocated buffer.

it also mishandles lines longer than the arbitrarily picked length :)

i guess i should rephrase:
 - gets() must be nuked from orbit
 - fgets() should die in a fire
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
  2015-02-18 16:53       ` Mike Frysinger
@ 2015-02-19 16:11         ` Jiri Gaisler
  2015-02-19 17:48           ` Mike Frysinger
  0 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-19 16:11 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1754 bytes --]



On 02/18/2015 05:53 PM, Mike Frysinger wrote:
> On 18 Feb 2015 15:40, Jiri Gaisler wrote:
>> On 02/17/2015 09:59 AM, Mike Frysinger wrote:
>>> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>>>> +extern struct pstate sregs;
>>>> +
>>>> +void
>>>> +boot_init ()
>>>
>>> also looks like this is missing an update to a header to add the prototype ?
>>
>> This is done in patch (17/23).
> 
> ok, but patches things really should be standalone.  although your series is
> pretty good already in terms of splitting things apart.
> 
>>>> +{
>>>> +    mec_write(MEC_WCR, 0);	/* zero waitstates */
>>>> +    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
>>>> +    mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
>>>> +    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
>>>> +    sregs.wim = 2;
>>>> +    sregs.psr = 0x110010e0;
>>>> +    sregs.r[30] = RAM_END;
>>>> +    sregs.r[14] = sregs.r[30] - 96*4;
>>>> +    mec_mcr |= 1;		/* power-down enabled */
>>>> +}
>>>
>>> why isn't sregs passed in as an arg ?  looks like both callers have a pointer to 
>>> it already.
>>
>> I am saving this for next major update - SMP support. All globals will then
>> be removed and the full cpu state will be in a struct that is passed to the
>> simulation engine. In this way I can simulate multiple cpu's.
> 
> can't this particular bit be done already ?  or is the global pointer diff from
> the local one ?

The global pointer is not different from the local, but since the global is
used in so many places it does not seem logical to switch to a local copy just
here. That is why I would like to keep this as is and remove all globals in
a later patch.

Jiri.

> -mike
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
  2015-02-19 16:11         ` Jiri Gaisler
@ 2015-02-19 17:48           ` Mike Frysinger
  0 siblings, 0 replies; 52+ messages in thread
From: Mike Frysinger @ 2015-02-19 17:48 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1840 bytes --]

On 19 Feb 2015 17:11, Jiri Gaisler wrote:
> On 02/18/2015 05:53 PM, Mike Frysinger wrote:
> > On 18 Feb 2015 15:40, Jiri Gaisler wrote:
> >> On 02/17/2015 09:59 AM, Mike Frysinger wrote:
> >>> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >>>> +{
> >>>> +    mec_write(MEC_WCR, 0);	/* zero waitstates */
> >>>> +    mec_write(MEC_TRAPD, 0);	/* turn off watch-dog */
> >>>> +    mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
> >>>> +    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
> >>>> +    sregs.wim = 2;
> >>>> +    sregs.psr = 0x110010e0;
> >>>> +    sregs.r[30] = RAM_END;
> >>>> +    sregs.r[14] = sregs.r[30] - 96*4;
> >>>> +    mec_mcr |= 1;		/* power-down enabled */
> >>>> +}
> >>>
> >>> why isn't sregs passed in as an arg ?  looks like both callers have a pointer to 
> >>> it already.
> >>
> >> I am saving this for next major update - SMP support. All globals will then
> >> be removed and the full cpu state will be in a struct that is passed to the
> >> simulation engine. In this way I can simulate multiple cpu's.
> > 
> > can't this particular bit be done already ?  or is the global pointer diff from
> > the local one ?
> 
> The global pointer is not different from the local, but since the global is
> used in so many places it does not seem logical to switch to a local copy just
> here. That is why I would like to keep this as is and remove all globals in
> a later patch.

there's already funcs that accept it as a pointer and operate on it in this 
code base.  since you're creating this function for the first time, it seems 
natural to include the right change from the start to reduce code shuffling 
later on.

if you're really set on this route though, i won't belabor the point (even if i 
think i'm right ;]).
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts.
  2015-02-17  9:05   ` Mike Frysinger
@ 2015-02-19 20:45     ` Jiri Gaisler
  2015-02-22  4:40       ` Mike Frysinger
  0 siblings, 1 reply; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-19 20:45 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 782 bytes --]



On 02/17/2015 10:05 AM, Mike Frysinger wrote:
> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>> 	* float.c (get_accex) access FPU control and status words on x64
> 
> shouldn't you gut this file and use <fenv.h> instead for a portable method ?
> http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fenv.h.html
> 
> at the very least, you could cut over to <fpu_control.h> ...
> -mike
> 

I will switch to fenv.h, but this will produce less accurate results
on Intel hardware. double on SPARC V8 has 53-bit mantissa while Intel has
both 53- and 64-bit, and 64-bit is default. To get accurate SPARC V8 FPU
operations, the Intel FPU should be switched to 53-bit, but the fenv.h
does not have an API for this. I guess we will have to live with that ...

Jiri.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts.
  2015-02-19 20:45     ` Jiri Gaisler
@ 2015-02-22  4:40       ` Mike Frysinger
  2015-02-22 21:43         ` Jiri Gaisler
  0 siblings, 1 reply; 52+ messages in thread
From: Mike Frysinger @ 2015-02-22  4:40 UTC (permalink / raw)
  To: Jiri Gaisler; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1088 bytes --]

On 19 Feb 2015 21:45, Jiri Gaisler wrote:
> On 02/17/2015 10:05 AM, Mike Frysinger wrote:
> > On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >> 	* float.c (get_accex) access FPU control and status words on x64
> > 
> > shouldn't you gut this file and use <fenv.h> instead for a portable method ?
> > http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fenv.h.html
> > 
> > at the very least, you could cut over to <fpu_control.h> ...
> 
> I will switch to fenv.h, but this will produce less accurate results
> on Intel hardware. double on SPARC V8 has 53-bit mantissa while Intel has
> both 53- and 64-bit, and 64-bit is default. To get accurate SPARC V8 FPU
> operations, the Intel FPU should be switched to 53-bit, but the fenv.h
> does not have an API for this. I guess we will have to live with that ...

if you wanted to keep a little inline asm to just that particular bit twiddle, 
that should be fine.

normally the sims are functional ... but i guess this part of the simulator is 
relying on the inaccuracies of floating point to trade for speed ?
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts.
  2015-02-22  4:40       ` Mike Frysinger
@ 2015-02-22 21:43         ` Jiri Gaisler
  0 siblings, 0 replies; 52+ messages in thread
From: Jiri Gaisler @ 2015-02-22 21:43 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1564 bytes --]



On 02/22/2015 05:40 AM, Mike Frysinger wrote:
> On 19 Feb 2015 21:45, Jiri Gaisler wrote:
>> On 02/17/2015 10:05 AM, Mike Frysinger wrote:
>>> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>>>> 	* float.c (get_accex) access FPU control and status words on x64
>>>
>>> shouldn't you gut this file and use <fenv.h> instead for a portable method ?
>>> http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fenv.h.html
>>>
>>> at the very least, you could cut over to <fpu_control.h> ...
>>
>> I will switch to fenv.h, but this will produce less accurate results
>> on Intel hardware. double on SPARC V8 has 53-bit mantissa while Intel has
>> both 53- and 64-bit, and 64-bit is default. To get accurate SPARC V8 FPU
>> operations, the Intel FPU should be switched to 53-bit, but the fenv.h
>> does not have an API for this. I guess we will have to live with that ...
> 
> if you wanted to keep a little inline asm to just that particular bit twiddle, 
> that should be fine.

Can't be bothered, I like the idea of dropping the assembly fully.

> 
> normally the sims are functional ... but i guess this part of the simulator is 
> relying on the inaccuracies of floating point to trade for speed ?
> -mike

Yes, instead of emulating the FPU (soft-float libs) we use the host FPU directly.
Works fine when the host is standard IEEE-754 compatible, but can lead to minor
discrepancies when the host has extended precision (like Intel/AMD). If somebody
really cares, he can run sis on a non-x86 box (SPARC, ARM or PowerPC).

Jiri.



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2015-02-22 21:43 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-17  7:45 [PATCH 00/22] Update of the SPARC SIS simulator Jiri Gaisler
2015-02-17  7:45 ` [PATCH 16/23] sim/erc32: use readline.h for readline types and functions Jiri Gaisler
2015-02-17  9:21   ` Mike Frysinger
2015-02-17  7:45 ` [PATCH 17/23] sim/erc32: Move local extern declarations into sis.h Jiri Gaisler
2015-02-17  7:45 ` [PATCH 02/23] sim/erc32: corrected wrong CPU implementation and version ID in %psr Jiri Gaisler
2015-02-17 11:03   ` Mike Frysinger
2015-02-17  7:45 ` [PATCH 04/23] sim/erc32: Add FPU support on x86_64 hosts Jiri Gaisler
2015-02-17  9:05   ` Mike Frysinger
2015-02-19 20:45     ` Jiri Gaisler
2015-02-22  4:40       ` Mike Frysinger
2015-02-22 21:43         ` Jiri Gaisler
2015-02-17  7:45 ` [PATCH 05/23] sim/erc32: remove unused defines in Makefile and switch off statistics Jiri Gaisler
2015-02-17 11:04   ` Mike Frysinger
2015-02-17  7:45 ` [PATCH 15/23] sim/erc32: access memory subsystem through struct memsys to allow multiple configurations Jiri Gaisler
2015-02-17  7:45 ` [PATCH 10/23] sim/erc32: Switched emulated memory to host endian order Jiri Gaisler
2015-02-17  7:45 ` [PATCH 07/23] sim/erc32: file loading via command line did not work Jiri Gaisler
2015-02-17  9:09   ` Mike Frysinger
2015-02-17  7:45 ` [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not work due to API change Jiri Gaisler
2015-02-17 11:03   ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report Jiri Gaisler
2015-02-17  9:07   ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 09/23] sim/erc32: removed type mismatch compiler warnings Jiri Gaisler
2015-02-17  9:10   ` Mike Frysinger
2015-02-18 14:41     ` Jiri Gaisler
2015-02-18 16:57       ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 14/23] sim/erc32: Use gdb callback for UART I/O when linked with gdb Jiri Gaisler
2015-02-17  7:46 ` [PATCH 11/23] sim/erc32: use AC_C_BIGENDIAN to probe for host endian Jiri Gaisler
2015-02-17  9:19   ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address Jiri Gaisler
2015-02-17  8:59   ` Mike Frysinger
2015-02-18 14:40     ` Jiri Gaisler
2015-02-18 16:53       ` Mike Frysinger
2015-02-19 16:11         ` Jiri Gaisler
2015-02-19 17:48           ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 08/23] sim/erc32: added -v and -vv command line switches for verbose output Jiri Gaisler
2015-02-17  9:13   ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 22/23] Added watchpoint support to gdb simulator interface Jiri Gaisler
2015-02-17  7:46 ` [PATCH 21/23] sim/erc32: add data watchpoint support for all cpu targets Jiri Gaisler
2015-02-17  7:46 ` [PATCH 12/23] sim/erc32: Use separate memory_iread() function for instruction fetching Jiri Gaisler
2015-02-17  7:46 ` [PATCH 13/23] sim/erc32: Fix a few compiler warnings Jiri Gaisler
2015-02-17 11:08   ` Mike Frysinger
2015-02-18 16:21     ` Jiri Gaisler
2015-02-18 16:51       ` Mike Frysinger
2015-02-17  7:46 ` [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation Jiri Gaisler
2015-02-17 15:58   ` Eli Zaretskii
2015-02-17  7:46 ` [PATCH 20/23] sim/erc32: Updated documentation Jiri Gaisler
2015-02-17 11:03   ` Mike Frysinger
2015-02-17 15:52   ` Eli Zaretskii
2015-02-17  7:46 ` [PATCH 19/23] sim/erc32: Added support for the Leon2 processor Jiri Gaisler
2015-02-17  8:54 ` [PATCH 00/22] Update of the SPARC SIS simulator Mike Frysinger
2015-02-17 14:41   ` Jiri Gaisler
2015-02-18  0:16     ` Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).