[PATCH 2/2] Add Jiri Gaisler SIS patch set for gdb 7.9

Joel Sherrill joel.sherrill at oarcorp.com
Thu Mar 26 18:22:03 UTC 2015


This patch set adds a lot of new capability including support for
the leon2 and leon3. It also eliminates the difference between
the initial state of the simulated erc32 and the real hardware.
---
 ...isassembly-in-stand-alone-mode-did-not-wo.patch |   61 +
 ...orrected-wrong-CPU-implementation-and-ver.patch |   27 +
 ...erform-pseudo-init-if-binary-linked-to-no.patch |   89 +
 ...-sim-erc32-Use-fenv.h-for-host-FPU-access.patch |  241 ++
 ...emove-unused-defines-in-Makefile-and-swit.patch |   27 +
 ...ix-incorrect-simulator-performance-report.patch |  174 ++
 ...ile-loading-via-command-line-did-not-work.patch |   43 +
 ...dded-v-command-line-switch-for-verbose-ou.patch |  123 +
 ...2-Removed-type-mismatch-compiler-warnings.patch |   66 +
 ...witched-emulated-memory-to-host-endian-or.patch |  564 +++++
 ...se-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch |  564 +++++
 ...se-memory_iread-function-for-instruction-.patch |  119 +
 ...013-sim-erc32-Fix-a-few-compiler-warnings.patch |   72 +
 ...se-gdb-callback-for-UART-I-O-when-linked-.patch |  358 +++
 ...ccess-memory-subsystem-through-struct-mem.patch |  804 +++++++
 ...se-readline.h-for-readline-types-and-func.patch |   55 +
 ...Move-local-extern-declarations-into-sis.h.patch |  224 ++
 ...Add-support-for-LEON3-processor-emulation.patch | 2434 ++++++++++++++++++++
 ...Add-support-for-LEON2-processor-emulation.patch | 1188 ++++++++++
 .../7.9/0020-sim-erc32-Updated-documentation.patch |  516 +++++
 ...021-sim-erc32-Add-data-watchpoint-support.patch |  377 +++
 ...hpoint-support-to-gdb-simulator-interface.patch | 1025 +++++++++
 ...LF-loading-could-fail-on-unaligned-sectio.patch |   39 +
 23 files changed, 9190 insertions(+)
 create mode 100644 tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0011-sim-erc32-use-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch
 create mode 100644 tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch

diff --git a/tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch b/tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch
new file mode 100644
index 0000000..e48ff75
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch
@@ -0,0 +1,61 @@
+From 723f3af6060ee39c89f2b79954a39c7bdee39f99 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 22:40:25 +0200
+Subject: [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not
+ work.
+
+	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");
+     }
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch b/tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch
new file mode 100644
index 0000000..9a93323
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch
@@ -0,0 +1,27 @@
+From 7a40f4ae5b9e3a9078d445976c3557fae69c60e5 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 22:52:37 +0200
+Subject: [PATCH 02/23] sim/erc32: Corrected wrong CPU implementation and
+ version ID in psr
+
+	* 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;
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch b/tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch
new file mode 100644
index 0000000..dca67f4
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch
@@ -0,0 +1,89 @@
+From 78a59b9928b59065cbffca153db9620c0ff80036 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 22:53:56 +0200
+Subject: [PATCH 03/23] sim/erc32: Perform pseudo-init if binary linked to
+ non-zero address.
+
+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   |  2 ++
+ sim/erc32/interf.c |  1 +
+ 3 files changed, 27 insertions(+)
+
+diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
+index 4d4177e..0f3e870 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 (void)
++{
++    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..6526085 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -468,6 +468,8 @@ 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;
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch b/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
new file mode 100644
index 0000000..2ca90f6
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
@@ -0,0 +1,241 @@
+From 7002592cb4072303c6a286e1c6479df99ae151b3 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Thu, 19 Feb 2015 22:14:36 +0100
+Subject: [PATCH 04/23] sim/erc32: Use fenv.h for host FPU access
+
+	* float.c (get_accex, clear_accex, set_fsr) Use functions from fenv.h
+	instead of custom assembly.
+---
+ sim/erc32/float.c | 191 +++++++++---------------------------------------------
+ 1 file changed, 30 insertions(+), 161 deletions(-)
+
+diff --git a/sim/erc32/float.c b/sim/erc32/float.c
+index 598b7cc..40c133b 100644
+--- a/sim/erc32/float.c
++++ b/sim/erc32/float.c
+@@ -28,53 +28,38 @@
+  * 4. Clear host exception bits
+  *
+  *
+- * This can also be done using ieee_flags() library routine on sun.
+  */
+ 
+ #include "config.h"
+ #include "sis.h"
++#include <fenv.h>
+ 
+-/* Forward declarations */
+-
+-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 */
++/* This routine should return the accrued exceptions */
+ int
+ get_accex()
+ {
+-#ifdef sparc
+-    return ((_get_fsr_raw() >> 5) & 0x1F);
+-#elif i386
+-    uint32 accx;
+-
+-    accx = _get_sw() & 0x3f;
+-    accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) |
+-	   (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5);
++    int fexc, accx;
++
++    fexc = fetestexcept(FE_ALL_EXCEPT);
++    accx = 0;
++    if (fexc & FE_INEXACT)
++        accx |= 1;
++    if (fexc & FE_DIVBYZERO)
++        accx |= 2;
++    if (fexc & FE_UNDERFLOW)
++        accx |= 4;
++    if (fexc & FE_OVERFLOW)
++        accx |= 8;
++    if (fexc & FE_INVALID)
++        accx |= 0x10;
+     return(accx);
+-#else
+-    return(0);
+-#warning no fpu trap support for this target
+-#endif
+-
+ }
+ 
+ /* How to clear the accrued exceptions */
+ void
+ clear_accex()
+ {
+-#ifdef sparc
+-    set_fsr((_get_fsr_raw() & ~0x3e0));
+-#elif i386
+-    asm("\n"
+-".text\n"
+-"	fnclex\n"
+-"\n"
+-"    ");
+-#else
+-#warning no fpu trap support for this target
+-#endif
++    feclearexcept(FE_ALL_EXCEPT);
+ }
+ 
+ /* How to map SPARC FSR onto the host */
+@@ -82,138 +67,22 @@ void
+ set_fsr(fsr)
+ uint32 fsr;
+ {
+-#ifdef sparc
+-	_set_fsr_raw(fsr & ~0x0f800000);
+-#elif i386
+-     void __setfpucw(unsigned short fpu_control);
+-     uint32 rawfsr;
++    int fround;
+ 
+-     fsr >>= 30;
+-     switch (fsr) {
++    fsr >>= 30;
++    switch (fsr) {
+ 	case 0: 
+-	case 2:
+-	  break;
+-
++	    fround = FE_TONEAREST;
++	    break;
+ 	case 1:
+-	  fsr = 3;
+-	  break;
+-
++	    fround = FE_TOWARDZERO;
++	    break;
++	case 2:
++	    fround = FE_UPWARD;
++	    break;
+ 	case 3:
+-	  fsr = 1;
+-	  break;
++	    fround = FE_DOWNWARD;
++	    break;
+      }
+-     rawfsr = _get_cw();
+-     rawfsr |= (fsr << 10) | 0x3ff;
+-     __setfpucw(rawfsr);
+-#else
+-#warning no fpu trap support for this target
+-#endif
+-}
+-
+-
+-/* Host dependent support functions */
+-
+-#ifdef sparc
+-
+-    asm("\n"
+-"\n"
+-".text\n"
+-"        .align 4\n"
+-"        .global __set_fsr_raw,_set_fsr_raw\n"
+-"__set_fsr_raw:\n"
+-"_set_fsr_raw:\n"
+-"        save %sp,-104,%sp\n"
+-"        st %i0,[%fp+68]\n"
+-"        ld [%fp+68], %fsr\n"
+-"        mov 0,%i0\n"
+-"        ret\n"
+-"        restore\n"
+-"\n"
+-"        .align 4\n"
+-"        .global __get_fsr_raw\n"
+-"        .global _get_fsr_raw\n"
+-"__get_fsr_raw:\n"
+-"_get_fsr_raw:\n"
+-"        save %sp,-104,%sp\n"
+-"        st %fsr,[%fp+68]\n"
+-"        ld [%fp+68], %i0\n"
+-"        ret\n"
+-"        restore\n"
+-"\n"
+-"    ");
+-
+-#elif i386
+-
+-    asm("\n"
+-"\n"
+-".text\n"
+-"        .align 8\n"
+-".globl _get_sw,__get_sw\n"
+-"__get_sw:\n"
+-"_get_sw:\n"
+-"        pushl %ebp\n"
+-"        movl %esp,%ebp\n"
+-"        movl $0,%eax\n"
+-"        fnstsw %ax\n"
+-"        movl %ebp,%esp\n"
+-"        popl %ebp\n"
+-"        ret\n"
+-"\n"
+-"        .align 8\n"
+-".globl _get_cw,__get_cw\n"
+-"__get_cw:\n"
+-"_get_cw:\n"
+-"        pushl %ebp\n"
+-"        movl %esp,%ebp\n"
+-"        subw $2,%esp\n"
+-"        fnstcw -2(%ebp)\n"
+-"        movw -2(%ebp),%eax\n"
+-"        movl %ebp,%esp\n"
+-"        popl %ebp\n"
+-"        ret\n"
+-"\n"
+-"\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));
++     fesetround(fround);
+ }
+-/* #endif */
+-#endif
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch b/tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch
new file mode 100644
index 0000000..94e71b0
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch
@@ -0,0 +1,27 @@
+From 03166e64ac4eb1b6b89e80dd5a54d7193ffd9099 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 22:58:33 +0200
+Subject: [PATCH 05/23] sim/erc32: Remove unused defines in Makefile and switch
+ off statistics
+
+	* 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 9c166ce..418e7e4 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
+ 
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch b/tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch
new file mode 100644
index 0000000..4244172
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch
@@ -0,0 +1,174 @@
+From 623a6089a6202cc9fb40c0a7235fb7398ea3dfbe Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 23:00:05 +0200
+Subject: [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report
+
+	* 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   | 35 ++++++++++++++++++++++++++---------
+ sim/erc32/interf.c |  5 ++---
+ sim/erc32/sis.c    |  5 ++---
+ sim/erc32/sis.h    |  5 +++--
+ 4 files changed, 33 insertions(+), 17 deletions(-)
+
+diff --git a/sim/erc32/func.c b/sim/erc32/func.c
+index 6526085..06c00b4 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -613,7 +613,7 @@ void
+ reset_stat(sregs)
+     struct pstate  *sregs;
+ {
+-    sregs->tottime = 0;
++    sregs->tottime = 0.0;
+     sregs->pwdtime = 0;
+     sregs->ninst = 0;
+     sregs->fholdt = 0;
+@@ -632,9 +632,10 @@ 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
+ 
+@@ -669,12 +670,15 @@ 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);
+ }
+ 
+ 
+@@ -1128,3 +1132,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);
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch b/tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch
new file mode 100644
index 0000000..e6b4364
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch
@@ -0,0 +1,43 @@
+From bdf71b87a2aff21de63accd86f8814b576f8a766 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 23:00:43 +0200
+Subject: [PATCH 07/23] sim/erc32: File loading via command line did not work
+
+	* sis.c (main) load binary file from argv parameters
+---
+ sim/erc32/sis.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
+index f2aed78..d7fa245 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,8 @@ 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
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch b/tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch
new file mode 100644
index 0000000..92e6cdb
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch
@@ -0,0 +1,123 @@
+From f13f6b1731a63b0b79df7232f675f3f8d44be074 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 23:01:13 +0200
+Subject: [PATCH 08/23] sim/erc32: Added -v command line switch for verbose
+ output
+
+	* help.c (usage) update usage help print-out
+
+	* sis.c (run_sim) increase debug level with -v. Also print
+	simulation time in long long format.
+---
+ sim/erc32/func.c | 5 +++--
+ sim/erc32/help.c | 2 +-
+ sim/erc32/sis.c  | 9 ++++++---
+ sim/erc32/sis.h  | 5 +++++
+ 4 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/sim/erc32/func.c b/sim/erc32/func.c
+index 06c00b4..f1d5bd7 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -29,6 +29,7 @@
+ #include "end.h"
+ #include <dis-asm.h>
+ #include "sim-config.h"
++#include <inttypes.h>
+ 
+ 
+ #define	VAL(x)	strtoul(x,(char **)NULL,0)
+@@ -643,8 +644,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       : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
++    printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
+ 
+ #ifdef STAT
+     printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
+diff --git a/sim/erc32/help.c b/sim/erc32/help.c
+index 21c2a77..9813bda 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] \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 d7fa245..7c18c1e 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -30,6 +30,7 @@
+ #include "sis.h"
+ #include <dis-asm.h>
+ #include "sim-config.h"
++#include <inttypes.h>
+ 
+ #define	VAL(x)	strtol(x,(char **)NULL,0)
+ 
+@@ -122,7 +123,7 @@ run_sim(sregs, icount, dis)
+ 			        sregs->histind = 0;
+ 		        }
+ 		        if (dis) {
+-			    printf(" %8u ", ebase.simtime);
++			    printf(" %8" PRIu64 " ", ebase.simtime);
+ 			    dis_mem(sregs->pc, 1, &dinfo);
+ 		        }
+ 		    }
+@@ -214,6 +215,8 @@ main(argc, argv)
+ #endif
+             } else if (strcmp(argv[stat], "-dumbio") == 0) {
+ 		dumbio = 1;
++            } else if (strcmp(argv[stat], "-v") == 0) {
++		sis_verbose += 1;
+ 	    } else {
+ 		printf("unknown option %s\n", argv[stat]);
+ 		usage();
+@@ -280,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 %" PRIu64 " (%.3f ms)\n", ebase.simtime,
+ 	      ((double) ebase.simtime / (double) sregs.freq) / 1000.0);
+ 	    break;
+ 	case BPT_HIT:
+@@ -290,7 +293,7 @@ main(argc, argv)
+ 	case ERROR:
+ 	    printf("IU in error mode (%d)\n", sregs.trap);
+ 	    stat = 0;
+-	    printf(" %8d ", ebase.simtime);
++	    printf(" %8" PRIu64 " ", ebase.simtime);
+ 	    dis_mem(sregs.pc, 1, &dinfo);
+ 	    break;
+ 	default:
+diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
+index dc02c65..1ff6ced 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -52,8 +52,13 @@ typedef float   float32;	/* 32-bit float */
+ typedef double  float64;	/* 64-bit float */
+ 
+ /* FIXME: what about host compilers that don't support 64-bit ints? */
++#ifdef __LP64__
++typedef unsigned long uint64; /* 64-bit unsigned int */
++typedef long int64;	   /* 64-bit signed int */
++#else
+ typedef unsigned long long uint64; /* 64-bit unsigned int */
+ typedef long long int64;	   /* 64-bit signed int */
++#endif
+ 
+ #define UINT64_MAX 18446744073709551615ULL
+ 
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch b/tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch
new file mode 100644
index 0000000..a10b8b7
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch
@@ -0,0 +1,66 @@
+From b65439074a4f4b2b6f5e5756124de49d4821656b Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 23:02:01 +0200
+Subject: [PATCH 09/23] sim/erc32: Removed type mismatch compiler warnings
+
+	* func.c (batch, exec_cmd) save return value to avoid warnings.
+	(batch) replace fgets() with getline().
+---
+ sim/erc32/func.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/sim/erc32/func.c b/sim/erc32/func.c
+index f1d5bd7..a715f0f 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -81,20 +81,23 @@ batch(sregs, fname)
+     char           *fname;
+ {
+     FILE           *fp;
+-    char            lbuf[1024];
++    char           *lbuf = NULL;
++    size_t         len = 0;
++    ssize_t        tmp;
+ 
+     if ((fp = fopen(fname, "r")) == NULL) {
+ 	fprintf(stderr, "couldn't open batch file %s\n", fname);
+ 	return (0);
+     }
+     while (!feof(fp)) {
+-	lbuf[0] = 0;
+-	fgets(lbuf, 1023, fp);
+-	if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n'))
++	tmp = getline(&lbuf, &len, fp);
++	if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n')) {
+ 	    lbuf[strlen(lbuf) - 1] = 0;
+-	printf("sis> %s\n", lbuf);
+-	exec_cmd(sregs, lbuf);
++	    printf("sis> %s\n", lbuf);
++	    exec_cmd(sregs, lbuf);
++	}
+     }
++    if (lbuf) free(lbuf);
+     fclose(fp);
+     return (1);
+ }
+@@ -383,7 +386,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;
+ 
+@@ -555,7 +558,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);
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch b/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch
new file mode 100644
index 0000000..04f5e90
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch
@@ -0,0 +1,564 @@
+From 335799e56181cd0d1ff8128b20b01835e344ee43 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 23:39:33 +0200
+Subject: [PATCH 10/23] sim/erc32: Switched emulated memory to host endian
+ order.
+
+	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 0f3e870..7c80e13 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 a715f0f..bcccf6d 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -785,15 +785,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");
+@@ -808,21 +808,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('.');
+ 	}
+@@ -838,10 +845,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");
+@@ -1040,6 +1048,7 @@ bfd_load(fname)
+     asection       *section;
+     bfd            *pbfd;
+     const bfd_arch_info_type *arch;
++    int            i;
+ 
+     pbfd = bfd_openr(fname, 0);
+ 
+@@ -1113,13 +1122,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 7c18c1e..523d8aa 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -236,7 +236,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();
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0011-sim-erc32-use-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch b/tools/4.11/gdb/sparc/7.9/0011-sim-erc32-use-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch
new file mode 100644
index 0000000..3632610
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0011-sim-erc32-use-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch
@@ -0,0 +1,564 @@
+From fb01b2350dd60d0ec99e5f1a3b262add609507f7 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 16:50:55 +0100
+Subject: [PATCH 11/23] sim/erc32: use SIM_AC_OPTION_HOSTENDIAN to probe for
+ host endianess
+
+	* Makefile.in (end, end.h) Remove target rules.
+	* end.c Remove unnecessary local checks (end.c)
+	* configure, config.in : Regenerate.
+	* configure.ac : Use SIM_AC_OPTION_HOSTENDIAN
+	* erc32.c : Remove dependecy on end.h
+	* exec.c : Remove dependecy on end.h. Use HOST_LITTLE_ENDIAN.
+	* func.c : As above.
+	* sis.c : As above.
+---
+ sim/erc32/Makefile.in  |  18 +---
+ sim/erc32/config.in    |  15 +++
+ sim/erc32/configure    | 260 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ 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        |   9 +-
+ 9 files changed, 284 insertions(+), 57 deletions(-)
+ delete mode 100644 sim/erc32/end.c
+
+diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
+index 418e7e4..e0860a0 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..."
+@@ -64,11 +56,3 @@ configure:
+ 	else true ; fi ; \
+ 	(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
+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..cbdcea5 100755
+--- a/sim/erc32/configure
++++ b/sim/erc32/configure
+@@ -761,6 +761,7 @@ enable_sim_trace
+ enable_sim_profile
+ with_pkgversion
+ with_bugurl
++enable_sim_hostendian
+ '
+       ac_precious_vars='build_alias
+ host_alias
+@@ -1403,6 +1404,7 @@ Optional Features:
+   --enable-sim-stdio			Specify whether to use stdio for console input/output.
+   --enable-sim-trace=opts		Enable tracing flags
+   --enable-sim-profile=opts		Enable profiling flags
++  --enable-sim-hostendian=end		Specify host byte endian orientation.
+ 
+ Optional Packages:
+   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+@@ -8121,7 +8123,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
+       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ 	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+-	10.[012]*)
++	10.[012][,.]*)
+ 	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 	10.*)
+ 	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+@@ -10144,7 +10146,7 @@ _LT_EOF
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -12354,7 +12356,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 12357 "configure"
++#line 12359 "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -12460,7 +12462,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 12463 "configure"
++#line 12465 "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -13111,6 +13113,255 @@ fi
+ fi
+ 
+ 
++# Check whether --enable-sim-hostendian was given.
++if test "${enable_sim_hostendian+set}" = set; then :
++  enableval=$enable_sim_hostendian; case "${enableval}" in
++  no)	 sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";;
++  b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";;
++  l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";;
++  *)	 as_fn_error "\"Unknown value $enableval for --enable-sim-hostendian\"" "$LINENO" 5; sim_hostendian="";;
++esac
++if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then
++  echo "Setting hostendian flags = $sim_hostendian" 6>&1
++fi
++else
++
++if test "x$cross_compiling" = "xno"; then
++   { $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
++
++  if test $ac_cv_c_bigendian = yes; then
++    sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN"
++  else
++    sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN"
++  fi
++else
++  sim_hostendian="-DWITH_HOST_BYTE_ORDER=0"
++fi
++fi
++
++
+ ac_sources="$sim_link_files"
+ ac_dests="$sim_link_links"
+ while test -n "$ac_sources"; do
+@@ -13245,6 +13496,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..854845c 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)
++SIM_AC_OPTION_HOSTENDIAN
+ 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 7c80e13..eac49f7 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 bcccf6d..ab21e3c 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"
+ #include <inttypes.h>
+@@ -734,7 +733,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 1ff6ced..ef5b149 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -23,8 +23,13 @@
+ #include "ansidecl.h"
+ #include "gdb/callback.h"
+ #include "gdb/remote-sim.h"
++#include <sim-config.h>
+ 
+-#include "end.h"
++#if WITH_HOST_BYTE_ORDER==BIG_ENDIAN
++#define HOST_BIG_ENDIAN
++#else
++#define HOST_LITTLE_ENDIAN
++#endif
+ 
+ #define I_ACC_EXC 1
+ 
+@@ -65,7 +70,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
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch b/tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch
new file mode 100644
index 0000000..73aa065
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch
@@ -0,0 +1,119 @@
+From d468feaaf511b29880faa297476ff98a9ef81b32 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 30 Aug 2014 23:47:46 +0200
+Subject: [PATCH 12/23] sim/erc32: Use memory_iread() function for instruction
+ fetching.
+
+	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 eac49f7..03b40dc 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 523d8aa..e109874 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -84,7 +84,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();
+@@ -93,11 +93,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 ef5b149..fb733de 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -176,6 +176,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,
+@@ -186,6 +187,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);
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch b/tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch
new file mode 100644
index 0000000..6e0fd1d
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch
@@ -0,0 +1,72 @@
+From e254c756b852c82ee705ff42f921e6dd9ba509e6 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sun, 31 Aug 2014 23:31:52 +0200
+Subject: [PATCH 13/23] sim/erc32: Fix a few compiler warnings
+
+	* func.c Minor edits to remove compiler warnings.
+	* func.c, sis.h (exec_cmd) make second argument const char.
+---
+ sim/erc32/func.c | 9 ++++++---
+ sim/erc32/sis.h  | 3 +--
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/sim/erc32/func.c b/sim/erc32/func.c
+index ab21e3c..70b42c9 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -380,18 +380,19 @@ limcalc (freq)
+     
+ int
+ exec_cmd(sregs, cmd)
+-    char           *cmd;
++    const char *cmd;
+     struct pstate  *sregs;
+ {
+     char           *cmd1, *cmd2;
+     int32           stat;
+     uint32          len, i, clen, j, tmp;
+     static uint32   daddr = 0;
+-    char           *cmdsave;
++    char           *cmdsave, *cmdsave2 = NULL;
+ 
+     stat = OK;
+     cmdsave = strdup(cmd);
+-    if ((cmd1 = strtok(cmd, " \t")) != NULL) {
++    cmdsave2 = strdup(cmd);
++    if ((cmd1 = strtok(cmdsave2, " \t")) != NULL) {
+ 	clen = strlen(cmd1);
+ 	if (strncmp(cmd1, "bp", clen) == 0) {
+ 	    for (i = 0; i < sregs->bptnum; i++) {
+@@ -606,6 +607,8 @@ exec_cmd(sregs, cmd)
+ 	} else
+ 	    printf("syntax error\n");
+     }
++    if (cmdsave2 != NULL)
++	free(cmdsave2);
+     if (cmdsave != NULL)
+ 	free(cmdsave);
+     return (stat);
+diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
+index fb733de..4ecf885 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -191,7 +191,7 @@ 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);
+-extern int	exec_cmd (struct pstate *sregs, char *cmd);
++extern int	exec_cmd (struct pstate *sregs, const char *cmd);
+ extern void	reset_stat (struct pstate  *sregs);
+ extern void	show_stat (struct pstate  *sregs);
+ extern void	init_bpt (struct pstate  *sregs);
+@@ -209,7 +209,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 */
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch b/tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch
new file mode 100644
index 0000000..cddb450
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch
@@ -0,0 +1,358 @@
+From edd201819d2399e2a7dc87e328aa6c5cf3088104 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 19:14:55 +0100
+Subject: [PATCH 14/23] sim/erc32: Use gdb callback for UART I/O when linked
+ with gdb.
+
+	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 03b40dc..c1ee435 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 70b42c9..440bff1 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -52,6 +52,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 981aa11..004d0bb 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 e109874..1f834a0 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -211,6 +211,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 {
+diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
+index 4ecf885..5226666 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -169,7 +169,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);
+@@ -210,6 +210,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);
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch b/tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch
new file mode 100644
index 0000000..c925b22
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch
@@ -0,0 +1,804 @@
+From 02c87814c10d896ae4946ef7c0358448b4d4eb61 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 21:48:10 +0100
+Subject: [PATCH 15/23] sim/erc32: Access memory subsystem through struct
+ memsys.
+
+	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 c1ee435..d0cacf9 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 (void)
+     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 440bff1..e789099 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -33,7 +33,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;
+@@ -54,6 +58,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;
+@@ -432,7 +437,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);
+@@ -483,7 +488,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) {
+@@ -557,7 +562,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]);
+@@ -565,12 +570,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;
+@@ -583,7 +588,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)
+@@ -597,7 +602,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();
+@@ -605,7 +610,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");
+     }
+@@ -777,7 +782,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;
+@@ -793,10 +798,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)
+@@ -825,7 +830,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);
+ 	}
+@@ -852,7 +857,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;
+@@ -1016,7 +1021,7 @@ reset_all()
+ {
+     init_event();		/* Clear event queue */
+     init_regs(&sregs);
+-    reset();
++    ms->reset();
+ #ifdef ERRINJ
+     errinjstart();
+ #endif
+@@ -1137,7 +1142,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 004d0bb..3f937f3 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 1f834a0..8c89166 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -52,16 +52,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[];
+@@ -87,13 +84,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;
+@@ -108,7 +105,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) {
+@@ -131,7 +128,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;
+ 	        }
+ 	    }
+@@ -143,7 +140,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) {
+@@ -246,7 +243,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 5226666..e0390e6 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -169,25 +169,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);
+@@ -211,7 +198,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);
+@@ -231,3 +220,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;
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch b/tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch
new file mode 100644
index 0000000..a21bd14
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch
@@ -0,0 +1,55 @@
+From 8907865aa0256164fd732c795ce8c9c3c42621a8 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 18 Oct 2014 23:38:02 +0200
+Subject: [PATCH 16/23] sim/erc32: Use readline.h for readline types and
+ functions.
+
+	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 e0860a0..4f86017 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$(srcroot)
+ 
+ ## COMMON_POST_CONFIG_FRAG
+ 
+diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
+index 8c89166..79757ae 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -36,17 +36,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
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch b/tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch
new file mode 100644
index 0000000..efd6636
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch
@@ -0,0 +1,224 @@
+From 82bbac32bcd1c2c65930f13daa9de7b327c310ea Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 21:58:00 +0100
+Subject: [PATCH 17/23] sim/erc32: Move local extern declarations into sis.h
+
+	* 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 d0cacf9..89c745a 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 (void)
+ {
+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 e789099..0d00f48 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -40,7 +40,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";
+@@ -54,7 +57,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;
+@@ -727,12 +729,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 3f937f3..ab1a38c 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 79757ae..d833da3 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -42,26 +42,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 e0390e6..8a48f29 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -173,8 +173,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);
+@@ -185,6 +204,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);
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch b/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch
new file mode 100644
index 0000000..8a20bff
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch
@@ -0,0 +1,2434 @@
+From d3e77f683adc96e3fc8395f21b8e440ee923a092 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 22:47:49 +0100
+Subject: [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation.
+
+	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.
+---
+ sim/erc32/Makefile.in  |    4 +-
+ sim/erc32/README.leon3 |   53 +++
+ sim/erc32/README.sis   |   81 ++--
+ sim/erc32/erc32.c      |   48 ++-
+ sim/erc32/exec.c       |  228 +++++++++--
+ sim/erc32/func.c       |   57 +--
+ 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, 1660 insertions(+), 129 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 4f86017..e40eb79 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$(srcroot)
+ ## 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 \
+diff --git a/sim/erc32/README.leon3 b/sim/erc32/README.leon3
+new file mode 100644
+index 0000000..f6701a5
+--- /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..124e577 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 emulates an ERC32 system. The -leon3 switch
++enables emulation of a LEON3 SOC system.
++
++The emulated console uart is connected to 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
+-maintained and inremented according the IU and FPU instruction timing.
++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 incremented 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
++emulation 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 89c745a..0e1a2ed 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 (void)
+ {
+     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..6292998 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 0d00f48..a22e800 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -46,7 +46,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;
+@@ -61,6 +61,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;
+@@ -482,7 +483,7 @@ exec_cmd(sregs, cmd)
+ 	    sregs->pc = len & ~3;
+ 	    sregs->npc = sregs->pc + 4;
+ 	    if ((sregs->pc != 0) && (ebase.simtime == 0))
+-	        boot_init();
++	        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);
+@@ -558,6 +559,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 {
+@@ -609,6 +615,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;
+@@ -646,8 +657,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;
+@@ -662,37 +673,37 @@ show_stat(sregs)
+     printf(" Instructions : %9" PRIu64 "\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);
++	  (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 - ((float) sregs->pwdtime / (float) stime)));
++	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))));
++	100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
+     printf(" Simulator performance       : %.2f MIPS\n",
+-        (double)(sregs->ninst) / sregs->tottime / 1E6);
++	(double)(sregs->ninst) / sregs->tottime / 1E6);
+     printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);
+ }
+ 
+diff --git a/sim/erc32/grlib.c b/sim/erc32/grlib.c
+new file mode 100644
+index 0000000..edb304e
+--- /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..1c03329
+--- /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 ab1a38c..8f3b27d 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 at wd.estec.esa.nl)\n");
++	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jiri at 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..26ea2b2
+--- /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 d833da3..0e19270 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -142,7 +142,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 at wd.estec.esa.nl\n\n");
++    printf(" Bug-reports to jiri at gaisler.se\n\n");
+     while (stat < argc) {
+ 	if (argv[stat][0] == '-') {
+ 	    if (strcmp(argv[stat], "-v") == 0) {
+@@ -181,6 +181,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 {
+@@ -193,13 +197,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 8a48f29..a551b4a 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -159,6 +159,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
+@@ -166,6 +190,8 @@ struct irqcell {
+ #define ERROR 3
+ #define CTRL_C 4
+ 
++#define CPU_LEON3  3
++
+ /* Prototypes  */
+ 
+ /* erc32.c */
+@@ -221,6 +247,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);
+@@ -241,23 +268,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;
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch b/tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch
new file mode 100644
index 0000000..7076933
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch
@@ -0,0 +1,1188 @@
+From 2c2afb029df432bd32f72789944cec2717861f7e Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 22:54:34 +0100
+Subject: [PATCH 19/23] sim/erc32: Add support for LEON2 processor emulation.
+
+	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 |    4 +-
+ 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, 1066 insertions(+), 4 deletions(-)
+ create mode 100644 sim/erc32/leon2.c
+
+diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
+index e40eb79..bee357b 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$(srcroot)
+ ## 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 \
+diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
+index 6292998..f4a0124 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 8f3b27d..8988f23 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 at gaisler.se)\n\n");
++	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler (jiri at 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..cf86167
+--- /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 0e19270..99d5286 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -181,6 +181,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;
+@@ -199,6 +203,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 a551b4a..c043504 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -190,6 +190,7 @@ struct memsys {
+ #define ERROR 3
+ #define CTRL_C 4
+ 
++#define CPU_LEON2  2
+ #define CPU_LEON3  3
+ 
+ /* Prototypes  */
+@@ -270,5 +271,8 @@ extern void	gen_help (void);
+ 
+ extern struct memsys *ms;
+ 
++/* leon2.c */
++extern struct memsys leon2;
++
+ /* leon3.c */
+ extern struct memsys leon3;
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch b/tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch
new file mode 100644
index 0000000..3676f6b
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch
@@ -0,0 +1,516 @@
+From f2694ee29b6f598d1361d59a3858f46b0a495450 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Wed, 18 Feb 2015 23:10:51 +0100
+Subject: [PATCH 20/23] sim/erc32: Updated documentation.
+
+	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   | 193 ++++++++++++++++---------------------------------
+ sim/erc32/startsim     |   4 -
+ 5 files changed, 117 insertions(+), 308 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 at wd.estec.esa.nl)
+diff --git a/sim/erc32/README.leon2 b/sim/erc32/README.leon2
+new file mode 100644
+index 0000000..19f2fbb
+--- /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 124e577..27e6ede 100644
+--- a/sim/erc32/README.sis
++++ b/sim/erc32/README.sis
+@@ -11,13 +11,14 @@ and peripherals.
+ 
+ 2. Usage
+ 
+-The simulator is started as follows: 
++The simulator is started as follows:
+ 
+-sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2]
+-    [-nfp] [-freq frequency] [-c batch_file] [files] 
++sis [-leon2] [-leon3] [-uart1 uart_device1] [-uart2 uart_device2]
++    [-nfp] [-freq frequency] [-c batch_file] [-v] [files]
+ 
+-By default, SIS emulates an ERC32 system. The -leon3 switch
+-enables emulation of a LEON3 SOC system.
++By default, SIS emulates an ERC32 system. The -leon2 switch enables
++LEON2 emulation, while the -leon3 switch enables emulation of a
++LEON3 SOC system.
+ 
+ The emulated console uart is connected to stdin/stdout. The -uart[1,2]
+ switch can be used to connect the uarts to other devices.
+@@ -143,8 +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
+ 
+-3. Simulator core
++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.
++
++3. 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.
++
++
++4. Simulator core
+ 
+ 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
+@@ -153,129 +196,10 @@ maintained and incremented 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
+ emulation 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 +216,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 Leon2 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 +242,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 &
+-
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch b/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch
new file mode 100644
index 0000000..7078cc3
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch
@@ -0,0 +1,377 @@
+From 933b0b5f256713f50959cd1f1c6ad565f40b12ab Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Thu, 19 Feb 2015 23:21:02 +0100
+Subject: [PATCH 21/23] sim/erc32: Add data watchpoint support
+
+	Add watchpoint to all processor targets (erc32, leon2, leon3).
+---
+ sim/erc32/exec.c | 54 +++++++++++++++++++++++++++-------
+ sim/erc32/func.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ sim/erc32/sis.c  | 32 +++++++++++++++-----
+ sim/erc32/sis.h  | 23 ++++++++++++++-
+ 4 files changed, 179 insertions(+), 20 deletions(-)
+
+diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
+index f4a0124..134e789 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 a22e800..7a8a4e4 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -61,7 +61,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;
+@@ -624,6 +625,53 @@ exec_cmd(sregs, cmd)
+ 	    stat = run_sim(sregs, UINT64_MAX, 0);
+ 	    daddr = sregs->pc;
+ 	    ms->sim_halt();
++	} 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");
+     }
+@@ -714,6 +762,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;
+@@ -1023,6 +1073,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 99d5286..7c984bc 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -75,11 +75,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++;
+@@ -90,14 +86,25 @@ run_sim(sregs, icount, dis)
+ 			    printf(" %8" PRIu64 " ", 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;
+@@ -118,6 +125,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(" %8" PRIu64 " ", 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 c043504..fda5f01 100644
+--- a/sim/erc32/sis.h
++++ b/sim/erc32/sis.h
+@@ -39,8 +39,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;
+@@ -108,6 +110,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 */
+@@ -184,12 +194,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
+ 
+@@ -240,6 +257,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);
+@@ -249,6 +269,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);
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch b/tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch
new file mode 100644
index 0000000..6a1e0ee
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch
@@ -0,0 +1,1025 @@
+From b2a82dcd2f4779119cc1a87591a7ab9eebc3ea61 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Mon, 8 Dec 2014 23:06:17 +0100
+Subject: [PATCH 22/23] Add watchpoint support to gdb simulator interface.
+
+	Currently, only the 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             |  25 +++++
+ sim/avr/interp.c              |  25 +++++
+ sim/bfin/Makefile.in          |   1 +
+ sim/common/sim-watch-remote.c |  27 +++++
+ sim/cr16/interp.c             |  25 +++++
+ 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             |  25 +++++
+ sim/m32r/Makefile.in          |   1 +
+ sim/m68hc11/Makefile.in       |   1 +
+ sim/mcore/interp.c            |  25 +++++
+ sim/microblaze/Makefile.in    |   2 +-
+ sim/mips/Makefile.in          |   1 +
+ sim/mn10300/Makefile.in       |   1 +
+ sim/moxie/interp.c            |  25 +++++
+ sim/msp430/Makefile.in        |   1 +
+ sim/ppc/gdb-sim.c             |  25 +++++
+ sim/rl78/gdb-if.c             |  25 +++++
+ sim/rx/gdb-if.c               |  25 +++++
+ sim/sh/interp.c               |  25 +++++
+ sim/sh64/Makefile.in          |   1 +
+ sim/v850/Makefile.in          |   3 +-
+ 28 files changed, 568 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 fd2fd58..af17e85 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 3dca380..36fef3c 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 0ccc7fb..a6871ad 100644
+--- a/sim/arm/wrapper.c
++++ b/sim/arm/wrapper.c
+@@ -1016,3 +1016,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/avr/interp.c b/sim/avr/interp.c
+index 8ae4887..c9f944c 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 b6cfeb5..d3fa401 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 9c85948..1c79258 100644
+--- a/sim/cr16/interp.c
++++ b/sim/cr16/interp.c
+@@ -1584,3 +1584,28 @@ 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 a4332c8..6607c32 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 8988f23..b2f81c5 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 ea34bf2..1e1398d 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 7a569bd..3337b89 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 7606b26..c079248 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 62ec28c..b8560d5 100644
+--- a/sim/m32c/gdb-if.c
++++ b/sim/m32c/gdb-if.c
+@@ -710,3 +710,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/m32r/Makefile.in b/sim/m32r/Makefile.in
+index 12a6a8d..dfa7bd0 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 fac0b24..62915d1 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 d2edd12..003bb80 100644
+--- a/sim/mcore/interp.c
++++ b/sim/mcore/interp.c
+@@ -2204,3 +2204,28 @@ 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 dda4650..49be635 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 c94e531..0a8cd86 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 5f449af..3e86b41 100644
+--- a/sim/moxie/interp.c
++++ b/sim/moxie/interp.c
+@@ -1475,3 +1475,28 @@ 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 e398d0d..5982f4b 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 0269458..3ce3016 100644
+--- a/sim/ppc/gdb-sim.c
++++ b/sim/ppc/gdb-sim.c
+@@ -1296,3 +1296,28 @@ 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 6317a73..262e3e1 100644
+--- a/sim/rl78/gdb-if.c
++++ b/sim/rl78/gdb-if.c
+@@ -571,3 +571,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/rx/gdb-if.c b/sim/rx/gdb-if.c
+index 762c3d2..8140a8b 100644
+--- a/sim/rx/gdb-if.c
++++ b/sim/rx/gdb-if.c
+@@ -853,3 +853,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/sh/interp.c b/sim/sh/interp.c
+index c854174..24f03ed 100644
+--- a/sim/sh/interp.c
++++ b/sim/sh/interp.c
+@@ -2780,3 +2780,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/sh64/Makefile.in b/sim/sh64/Makefile.in
+index 0022d8e..a9cf62a 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 067158f..ad24cd8 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
+ 
+-- 
+1.9.1
+
diff --git a/tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch b/tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch
new file mode 100644
index 0000000..4a80399
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch
@@ -0,0 +1,39 @@
+From 7cecef8c4569896ec7c16c6fc51ef0c5ce7aa7f1 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri at gaisler.se>
+Date: Sat, 21 Mar 2015 18:31:15 +0100
+Subject: [PATCH 23/23] sim/erc32: ELF loading could fail on unaligned
+ sections.
+
+Endian swapping on little-endian hosts could fail if ELF section
+length not a multiple of 4.
+
+	func.c (bfd_load): Pad section buffers with zeros and round
+	section size upwards towards nearest 4-multiple.
+---
+ sim/erc32/func.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sim/erc32/func.c b/sim/erc32/func.c
+index 7a8a4e4..31948a6 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -1231,13 +1231,13 @@ bfd_load(fname)
+ 		    uint32          *wbuffer = (uint32 *) buffer;
+ 
+ 		    count = min(section_size, 1024);
+-
++		    wbuffer[(count - 1) / 4] = 0; /* clear last word in buffer  */
+ 		    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
++		    for (i=0;i<(count+3)/4;i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
+ #endif
+-		    ms->sis_memory_write(section_address, buffer, count);
++		    ms->sis_memory_write(section_address, buffer, (count + 3) & ~3);
+ 
+ 		    section_address += count;
+ 		    fptr += count;
+-- 
+1.9.1
+
-- 
1.9.3



More information about the devel mailing list