Patchwork [v5,3/9] sim/erc32: Access memory subsystem through struct memsys.

login
register
mail settings
Submitter Jiri Gaisler
Date April 3, 2015, 8:35 p.m.
Message ID <1428093356-7296-4-git-send-email-jiri@gaisler.se>
Download mbox | patch
Permalink /patch/6003/
State Changes Requested
Delegated to: Mike Frysinger
Headers show

Comments

Jiri Gaisler - April 3, 2015, 8:35 p.m.
Introduce an common API to access emulated memory. This allows
	to emulate different types of SPARC-based CPUs.

	* erc32.c (reset, error_mode, sim_halt, close_port, exit_sim, init_stdio,
	restore_stdio, memory_iread, memory_read, memory_write, sis_memory_write,
	sis_memory_read): Mark static.
	(sim_stop): Move to interf.c.
	(erc32sys): Export memory operations through struct memsys erc32sys.
	* exec.c (dispatch_instruction) : Access memory through common API.
	* func.c (exec_cmd, print_insn_sparc_sis, dis_mem, reset_all, bfd_load): As above.
	* interf.c (run_sim, sim_close, sim_write, sim_read, flush_windows) : As above.
	(sim_stop): Add.
	* sis.c (run_sim, main): Access memory through common API.
	* sis.h : Define struct memsys as common memory API. Remove declaration of
	functions marked as static.
---
 sim/erc32/erc32.c  | 46 +++++++++++++++++++++++++++-------------------
 sim/erc32/exec.c   | 42 +++++++++++++++++++++---------------------
 sim/erc32/func.c   | 31 ++++++++++++++++---------------
 sim/erc32/interf.c | 34 +++++++++++++++++++---------------
 sim/erc32/sis.c    | 15 ++++++---------
 sim/erc32/sis.h    | 42 +++++++++++++++++++++++++-----------------
 6 files changed, 114 insertions(+), 96 deletions(-)
Mike Frysinger - April 19, 2015, 6:44 a.m.
On 03 Apr 2015 22:35, Jiri Gaisler wrote:
> 	* exec.c (dispatch_instruction) : Access memory through common API.

no space before the :

> 	* interf.c (run_sim, sim_close, sim_write, sim_read, flush_windows) : As above.

same here

> 	* sis.h : Define struct memsys as common memory API. Remove declaration of

and here

> --- a/sim/erc32/interf.c
> +++ b/sim/erc32/interf.c
> @@ -37,16 +37,13 @@
>  #define PSR_CWP 0x7
>  
>  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      rom8;
>  extern int      wrp;
>  extern int      uben;
> -extern int      sis_verbose;

the changelog needs to mention deletion of global vars/prototypes/etc...

sorry, i don't point these things out to be difficult ... it's just that they 
would need to be fixed before merging, and i really really don't want to do it 
myself.
-mike

Patch

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 04c40ee..2035082 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -302,7 +302,7 @@  static host_callback *callback;
 
 /* One-time init */
 
-void
+static void
 init_sim()
 {
     callback = sim_callback;
@@ -311,7 +311,7 @@  init_sim()
 
 /* Power-on reset init */
 
-void
+static void
 reset()
 {
     mec_reset();
@@ -391,7 +391,7 @@  mecparerror()
 
 /* IU error mode manager */
 
-void
+static void
 error_mode(pc)
     uint32          pc;
 {
@@ -462,7 +462,7 @@  decode_mcr()
 
 /* Flush ports when simulator stops */
 
-void
+static void
 sim_halt()
 {
 #ifdef FAST_UART
@@ -470,13 +470,6 @@  sim_halt()
 #endif
 }
 
-int
-sim_stop(SIM_DESC sd)
-{
-  ctrl_c = 1;
-  return 1;
-}
-
 static void
 close_port()
 {
@@ -486,7 +479,7 @@  close_port()
 	fclose(f2in);
 }
 
-void
+static void
 exit_sim()
 {
     close_port();
@@ -938,7 +931,7 @@  mec_write(addr, data)
 
 static int      ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1;
 
-void
+static void
 init_stdio()
 {
     if (dumbio)
@@ -953,7 +946,7 @@  init_stdio()
     }
 }
 
-void
+static void
 restore_stdio()
 {
     if (dumbio)
@@ -1609,7 +1602,7 @@  store_bytes (unsigned char *mem, uint32	waddr, uint32 *data, int32 sz, int32 *ws
 
 /* Memory emulation */
 
-int
+static int
 memory_iread (uint32 addr, uint32 *data, int32 *ws)
 {
     uint32          asi;
@@ -1634,7 +1627,7 @@  memory_iread (uint32 addr, uint32 *data, int32 *ws)
     return 1;
 }
 
-int
+static int
 memory_read(asi, addr, data, sz, ws)
     int32           asi;
     uint32          addr;
@@ -1705,7 +1698,7 @@  memory_read(asi, addr, data, sz, ws)
     return 1;
 }
 
-int
+static int
 memory_write(asi, addr, data, sz, ws)
     int32           asi;
     uint32          addr;
@@ -1839,7 +1832,7 @@  get_mem_ptr(addr, size)
     return (char *) -1;
 }
 
-int
+static int
 sis_memory_write(addr, data, length)
     uint32               addr;
     const unsigned char *data;
@@ -1854,7 +1847,7 @@  sis_memory_write(addr, data, length)
     return length;
 }
 
-int
+static int
 sis_memory_read(addr, data, length)
     uint32          addr;
     char           *data;
@@ -1884,3 +1877,18 @@  boot_init (void)
     sregs.r[14] = sregs.r[30] - 96 * 4;
     mec_mcr |= 1;		/* power-down enabled */
 }
+
+const 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 d31032b..866a7de 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 fae4228..b092715 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -53,6 +53,7 @@  extern	int	ext_irl;
 uint32		last_load_addr = 0;
 int		nouartrx = 0;
 host_callback 	*sim_callback;
+const struct memsys *ms = &erc32sys;
 
 #ifdef ERRINJ
 uint32		errcnt = 0;
@@ -421,7 +422,7 @@  exec_cmd(struct pstate *sregs, const char *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);
@@ -472,7 +473,7 @@  exec_cmd(struct pstate *sregs, const char *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) {
@@ -546,7 +547,7 @@  exec_cmd(struct pstate *sregs, const char *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) {
 		if (system(&cmdsave[clen])) {
@@ -556,12 +557,12 @@  exec_cmd(struct pstate *sregs, const char *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;
@@ -574,7 +575,7 @@  exec_cmd(struct pstate *sregs, const char *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)
@@ -588,7 +589,7 @@  exec_cmd(struct pstate *sregs, const char *cmd)
 	    }
 	    printf("\n");
 	    daddr = sregs->pc;
-	    sim_halt();
+	    ms->sim_halt ();
 	} else if (strncmp(cmd1, "trun", clen) == 0) {
 	    ebase.simtime = 0;
 	    reset_all();
@@ -596,7 +597,7 @@  exec_cmd(struct pstate *sregs, const char *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");
     }
@@ -768,7 +769,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;
@@ -784,10 +785,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)
@@ -812,7 +813,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.u8, 4);
+	    ms->sis_memory_read ((i + (j * 4)), data.u8, 4);
 	    printf ("%08x  ", data.u32);
 	    mem[j] = data.u32;
 	}
@@ -841,7 +842,7 @@  dis_mem(addr, len, info)
     } data;
 
     for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
-	sis_memory_read (i, data.u8, 4);
+	ms->sis_memory_read (i, data.u8, 4);
 	printf (" %08x  %08x  ", i, data.u32);
 	print_insn_sparc_sis(i, info);
         if (i >= 0xfffffffc) break;
@@ -1005,7 +1006,7 @@  reset_all()
 {
     init_event();		/* Clear event queue */
     init_regs(&sregs);
-    reset();
+    ms->reset ();
 #ifdef ERRINJ
     errinjstart();
 #endif
@@ -1111,7 +1112,7 @@  bfd_load (const char *fname)
 		    bfd_get_section_contents(pbfd, section, buffer, fptr, count);
 
 		    for (i = 0; i < count; i++)
-			sis_memory_write((section_address + i) ^ EBT, &buffer[i], 1);
+			ms->sis_memory_write ((section_address + i) ^ EBT, &buffer[i], 1);
 
 		    section_address += count;
 		    fptr += count;
diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
index 3abfe3e..7b19bed 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -37,16 +37,13 @@ 
 #define PSR_CWP 0x7
 
 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      rom8;
 extern int      wrp;
 extern int      uben;
-extern int      sis_verbose;
 extern char    *sis_version;
 extern struct estate ebase;
 extern struct evcell evbuf[];
@@ -71,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))
@@ -92,7 +89,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 +115,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 +134,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) {
@@ -259,7 +256,7 @@  sim_open (kind, callback, abfd, argv)
 #endif
     reset_all();
     ebase.simtime = 0;
-    init_sim();
+    ms->init_sim ();
     init_bpt(&sregs);
     reset_stat(&sregs);
 
@@ -273,7 +270,7 @@  sim_close(sd, quitting)
      int quitting;
 {
 
-    exit_sim();
+    ms->exit_sim ();
     fcntl(0, F_SETFL, termsave);
 
 };
@@ -341,7 +338,7 @@  sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
     int i, len;
 
     for (i = 0; i < length; i++) {
-	sis_memory_write ((mem + i) ^ EBT, &buf[i], 1);
+	ms->sis_memory_write ((mem + i) ^ EBT, &buf[i], 1);
     }
     return length;
 }
@@ -351,7 +348,7 @@  sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
     int i, len;
 
     for (i = 0; i < length; i++) {
-	sis_memory_read ((mem + i) ^ EBT, &buf[i], 1);
+	ms->sis_memory_read ((mem + i) ^ EBT, &buf[i], 1);
     }
     return length;
 }
@@ -439,7 +436,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)
@@ -469,6 +466,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 51ba901..cfea688 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -43,16 +43,13 @@ 
 #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[];
@@ -78,13 +75,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;
@@ -99,7 +96,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) {
@@ -122,7 +119,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;
 	        }
 	    }
@@ -134,7 +131,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) {
@@ -237,7 +234,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
diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
index 11a17f1..ac5a8bb 100644
--- a/sim/erc32/sis.h
+++ b/sim/erc32/sis.h
@@ -164,25 +164,12 @@  struct irqcell {
 /* Prototypes  */
 
 /* erc32.c */
-extern void	init_sim (void);
-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 const 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);
@@ -229,3 +216,24 @@  extern void	set_fsr (uint32 fsr);
 /* help.c */
 extern void	usage (void);
 extern void	gen_help (void);
+
+struct memsys {
+    void	(*init_sim) (void);
+    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 const struct memsys *ms;