summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-03-16 15:18:34 +1100
committerChris Johns <chrisj@rtems.org>2016-03-16 15:47:37 +1100
commit0bbd2de7f5306ad15ce544f9c3e9a5d9bb00dc85 (patch)
treeab8c18d55df1f890dec3e1ce56c4e71f5d1cc989 /tools
parent6f8b07c3b6202145fd9b86c38f786c7553eaf0c4 (diff)
4.12: Patches for ERC simualtor for gdb-7.11.
The patches fix the endian checks in the simulator, print filtering, and the run command. Updates #2644.
Diffstat (limited to 'tools')
-rw-r--r--tools/4.12/gdb/gdb-7.11-erc32-common-run.diff472
-rw-r--r--tools/4.12/gdb/gdb-7.11-erc32-endian-fix.diff13
-rw-r--r--tools/4.12/gdb/gdb-7.11-erc32-printf_filtered.diff1103
3 files changed, 1588 insertions, 0 deletions
diff --git a/tools/4.12/gdb/gdb-7.11-erc32-common-run.diff b/tools/4.12/gdb/gdb-7.11-erc32-common-run.diff
new file mode 100644
index 0000000..e59cd78
--- /dev/null
+++ b/tools/4.12/gdb/gdb-7.11-erc32-common-run.diff
@@ -0,0 +1,472 @@
+diff -rNuw gdb-7.11.orig2/sim/erc32/Makefile.in gdb-7.11/sim/erc32/Makefile.in
+--- gdb-7.11.orig2/sim/erc32/Makefile.in 2016-03-16 14:20:34.556597040 +1100
++++ gdb-7.11/sim/erc32/Makefile.in 2016-03-16 14:21:45.736598841 +1100
+@@ -22,7 +22,7 @@
+ READLINE_LIB = @READLINE@
+
+ SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o
+-SIM_RUN_OBJS = sis.o
++SIM_RUN_OBJS = run.o
+ SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm
+ SIM_EXTRA_ALL = sis
+ SIM_EXTRA_INSTALL = install-sis
+@@ -56,4 +56,3 @@
+ srcdir=. ; export srcdir ; \
+ else true ; fi ; \
+ (cd $${srcdir}; autoconf --localdir=../common)
+-
+diff -rNuw gdb-7.11.orig2/sim/erc32/run.c gdb-7.11/sim/erc32/run.c
+--- gdb-7.11.orig2/sim/erc32/run.c 1970-01-01 10:00:00.000000000 +1000
++++ gdb-7.11/sim/erc32/run.c 2016-03-16 14:21:21.556598229 +1100
+@@ -0,0 +1,354 @@
++/* run front end support for all the simulators.
++ Copyright (C) 1992-2015 Free Software Foundation, Inc.
++
++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/>. */
++
++/* Steve Chamberlain sac@cygnus.com,
++ and others at Cygnus. */
++
++#include "config.h"
++
++#include <signal.h>
++#include <stdio.h>
++#ifdef __STDC__
++#include <stdarg.h>
++#else
++#include <varargs.h>
++#endif
++
++#ifdef HAVE_STDLIB_H
++#include <stdlib.h>
++#endif
++
++#ifdef HAVE_STRING_H
++#include <string.h>
++#else
++#ifdef HAVE_STRINGS_H
++#include <strings.h>
++#endif
++#endif
++
++#include "libiberty.h"
++#include "bfd.h"
++#include "gdb/callback.h"
++#include "gdb/remote-sim.h"
++#include "ansidecl.h"
++#include "run-sim.h"
++#include "version.h"
++
++static void usage (int help);
++static void print_version (void);
++extern int optind;
++extern char *optarg;
++
++extern host_callback default_callback;
++
++static char *myname;
++
++extern int getopt ();
++
++#ifdef NEED_UI_LOOP_HOOK
++/* Gdb foolery. This is only needed for gdb using a gui. */
++int (*deprecated_ui_loop_hook) (int signo);
++#endif
++
++static SIM_DESC sd;
++
++static RETSIGTYPE
++cntrl_c (int sig ATTRIBUTE_UNUSED)
++{
++ if (! sim_stop (sd))
++ {
++ fprintf (stderr, "Quit!\n");
++ exit (1);
++ }
++}
++
++int
++main (ac, av)
++ int ac;
++ char **av;
++{
++ RETSIGTYPE (*prev_sigint) ();
++ bfd *abfd;
++ int i;
++ int verbose = 0;
++ int trace = 0;
++#ifdef SIM_HAVE_ENVIRONMENT
++ int operating_p = 0;
++#endif
++ char *name;
++ static char *no_args[4];
++ char **sim_argv = &no_args[0];
++ char **prog_args;
++ enum sim_stop reason;
++ int sigrc;
++
++ myname = av[0] + strlen (av[0]);
++ while (myname > av[0] && myname[-1] != '/')
++ --myname;
++
++ /* The first element of sim_open's argv is the program name. */
++ no_args[0] = av[0];
++#ifdef SIM_HAVE_BIENDIAN
++ no_args[1] = "-E";
++ no_args[2] = "set-later";
++#endif
++
++ /* FIXME: This is currently being migrated into sim_open.
++ Simulators that use functions such as sim_size() still require
++ this. */
++ default_callback.init (&default_callback);
++ //sim_set_callbacks (&default_callback);
++
++#ifdef SIM_TARGET_SWITCHES
++ ac = sim_target_parse_command_line (ac, av);
++#endif
++
++ for (i = 1; av[i]; ++i)
++ {
++ if (strcmp (av[i], "--help") == 0)
++ {
++ usage (1);
++ }
++ else if (strcmp (av[i], "--version") == 0)
++ {
++ print_version ();
++ return 0;
++ }
++ }
++
++ /* FIXME: This is currently being rewritten to have each simulator
++ do all argv processing. */
++
++ while ((i = getopt (ac, av, "a:c:m:op:s:tv")) != EOF)
++ switch (i)
++ {
++ case 'a':
++ /* FIXME: Temporary hack. */
++ {
++ int len = strlen (av[0]) + strlen (optarg);
++ char *argbuf = (char *) alloca (len + 2 + 50);
++ sprintf (argbuf, "%s %s", av[0], optarg);
++#ifdef SIM_HAVE_BIENDIAN
++ /* The desired endianness must be passed to sim_open.
++ The value for "set-later" is set when we know what it is.
++ -E support isn't yet part of the published interface. */
++ strcat (argbuf, " -E set-later");
++#endif
++ sim_argv = buildargv (argbuf);
++ }
++ break;
++#ifdef SIM_HAVE_SIMCACHE
++ case 'c':
++ sim_set_simcache_size (atoi (optarg));
++ break;
++#endif
++ case 'm':
++ /* FIXME: Rename to sim_set_mem_size. */
++ //sim_size (atoi (optarg));
++ break;
++#ifdef SIM_HAVE_ENVIRONMENT
++ case 'o':
++ /* Operating enironment where any signals are delivered to the
++ target. */
++ operating_p = 1;
++ break;
++#endif
++#ifdef SIM_HAVE_PROFILE
++ case 'p':
++ sim_set_profile (atoi (optarg));
++ break;
++ case 's':
++ sim_set_profile_size (atoi (optarg));
++ break;
++#endif
++ case 't':
++ trace = 1;
++ break;
++ case 'v':
++ /* Things that are printed with -v are the kinds of things that
++ gcc -v prints. This is not meant to include detailed tracing
++ or debugging information, just summaries. */
++ verbose = 1;
++ /* sim_set_verbose (1); */
++ break;
++ /* FIXME: Quick hack, to be replaced by more general facility. */
++ default:
++ usage (0);
++ }
++
++ ac -= optind;
++ av += optind;
++ if (ac <= 0)
++ usage (0);
++
++ name = *av;
++ prog_args = av;
++
++ if (verbose)
++ {
++ printf ("%s %s\n", myname, name);
++ }
++
++ abfd = bfd_openr (name, 0);
++ if (!abfd)
++ {
++ fprintf (stderr, "%s: can't open %s: %s\n",
++ myname, name, bfd_errmsg (bfd_get_error ()));
++ exit (1);
++ }
++
++ if (!bfd_check_format (abfd, bfd_object))
++ {
++ fprintf (stderr, "%s: can't load %s: %s\n",
++ myname, name, bfd_errmsg (bfd_get_error ()));
++ exit (1);
++ }
++
++#ifdef SIM_HAVE_BIENDIAN
++ /* The endianness must be passed to sim_open because one may wish to
++ examine/set registers before calling sim_load [which is the other
++ place where one can determine endianness]. We previously passed the
++ endianness via global `target_byte_order' but that's not a clean
++ interface. */
++ for (i = 1; sim_argv[i + 1] != NULL; ++i)
++ continue;
++ if (bfd_big_endian (abfd))
++ sim_argv[i] = "big";
++ else
++ sim_argv[i] = "little";
++#endif
++
++ /* Ensure that any run-time initialisation that needs to be
++ performed by the simulator can occur. */
++ sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, sim_argv);
++ if (sd == 0)
++ exit (1);
++
++ if (sim_load (sd, name, abfd, 0) == SIM_RC_FAIL)
++ exit (1);
++
++ if (sim_create_inferior (sd, abfd, prog_args, NULL) == SIM_RC_FAIL)
++ exit (1);
++
++#ifdef SIM_HAVE_ENVIRONMENT
++ /* NOTE: An old simulator supporting the operating environment MUST
++ provide sim_set_trace() and not sim_trace(). That way
++ sim_stop_reason() can be used to determine any stop reason. */
++ if (trace)
++ sim_set_trace ();
++ sigrc = 0;
++ do
++ {
++ prev_sigint = signal (SIGINT, cntrl_c);
++ sim_resume (sd, 0, sigrc);
++ signal (SIGINT, prev_sigint);
++ sim_stop_reason (sd, &reason, &sigrc);
++ }
++ while (operating_p && reason == sim_stopped && sigrc != SIGINT);
++#else
++ if (trace)
++ {
++ int done = 0;
++ prev_sigint = signal (SIGINT, cntrl_c);
++ while (!done)
++ {
++ // done = sim_trace (sd);
++ }
++ signal (SIGINT, prev_sigint);
++ sim_stop_reason (sd, &reason, &sigrc);
++ }
++ else
++ {
++ prev_sigint = signal (SIGINT, cntrl_c);
++ sigrc = 0;
++ sim_resume (sd, 0, sigrc);
++ signal (SIGINT, prev_sigint);
++ sim_stop_reason (sd, &reason, &sigrc);
++ }
++#endif
++
++ if (verbose)
++ sim_info (sd, 0);
++ sim_close (sd, 0);
++
++ /* If reason is sim_exited, then sigrc holds the exit code which we want
++ to return. If reason is sim_stopped or sim_signalled, then sigrc holds
++ the signal that the simulator received; we want to return that to
++ indicate failure. */
++
++ /* Why did we stop? */
++ switch (reason)
++ {
++ case sim_signalled:
++ case sim_stopped:
++ if (sigrc != 0)
++ fprintf (stderr, "program stopped with signal %d.\n", sigrc);
++ break;
++
++ case sim_exited:
++ break;
++
++ case sim_running:
++ case sim_polling: /* These indicate a serious problem. */
++ abort ();
++ break;
++
++ }
++
++ return sigrc;
++}
++
++static void
++usage (int help)
++{
++ FILE *stream = help ? stdout : stderr;
++
++ fprintf (stream, "Usage: %s [options] program [program args]\n", myname);
++ fprintf (stream, "Options:\n");
++ fprintf (stream, "-a args Pass `args' to simulator.\n");
++#ifdef SIM_HAVE_SIMCACHE
++ fprintf (stream, "-c size Set simulator cache size to `size'.\n");
++#endif
++ fprintf (stream, "-m size Set memory size of simulator, in bytes.\n");
++#ifdef SIM_HAVE_ENVIRONMENT
++ fprintf (stream, "-o Select operating (kernel) environment.\n");
++#endif
++#ifdef SIM_HAVE_PROFILE
++ fprintf (stream, "-p freq Set profiling frequency.\n");
++ fprintf (stream, "-s size Set profiling size.\n");
++#endif
++ fprintf (stream, "-t Perform instruction tracing.\n");
++ fprintf (stream, " Note: Very few simulators support tracing.\n");
++ fprintf (stream, "-v Verbose output.\n");
++ fprintf (stream, "\n");
++ fprintf (stream, "program args Arguments to pass to simulated program.\n");
++ fprintf (stream, " Note: Very few simulators support this.\n");
++#ifdef SIM_TARGET_SWITCHES
++ fprintf (stream, "\nTarget specific options:\n");
++ sim_target_display_usage (help);
++#endif
++
++ if (help && REPORT_BUGS_TO[0])
++ printf ("Report bugs to %s\n", REPORT_BUGS_TO);
++
++ exit (help ? 0 : 1);
++}
++
++static void
++print_version ()
++{
++ printf ("GNU simulator %s%s\n", PKGVERSION, version);
++}
+diff -rNuw gdb-7.11.orig2/sim/erc32/run-sim.h gdb-7.11/sim/erc32/run-sim.h
+--- gdb-7.11.orig2/sim/erc32/run-sim.h 1970-01-01 10:00:00.000000000 +1000
++++ gdb-7.11/sim/erc32/run-sim.h 2016-03-16 14:22:00.512599215 +1100
+@@ -0,0 +1,93 @@
++/* This file defines the part of the interface between the standalone
++ simaulator program - run - and simulator library - libsim.a - that
++ is not used by GDB. The GDB part is described in include/remote-sim.h.
++
++ Copyright 2002-2015 Free Software Foundation, Inc.
++
++ This file is part of GDB.
++
++ 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/>. */
++
++#ifndef RUN_SIM_H
++#define RUN_SIM_H
++
++#ifdef SIM_TARGET_SWITCHES
++ /* Parse the command line, extracting any target specific switches
++ before the generic simulator code gets a chance to complain
++ about them. Returns the adjusted value of argc. */
++int sim_target_parse_command_line (int, char **);
++
++ /* Display a list of target specific switches supported by this
++ target. */
++void sim_target_display_usage (int help);
++
++#endif
++
++/* Provide simulator with a default (global) host_callback_struct.
++ THIS PROCEDURE IS DEPRECATED.
++ GDB and NRUN do not use this interface.
++ This procedure does not take a SIM_DESC argument as it is
++ used before sim_open. */
++
++void sim_set_callbacks (struct host_callback_struct *);
++
++
++/* Set the size of the simulator memory array.
++ THIS PROCEDURE IS DEPRECATED.
++ GDB and NRUN do not use this interface.
++ This procedure does not take a SIM_DESC argument as it is
++ used before sim_open. */
++
++void sim_size (int i);
++
++
++/* Single-step simulator with tracing enabled.
++ THIS PROCEDURE IS DEPRECATED.
++ THIS PROCEDURE IS EVEN MORE DEPRECATED THAN SIM_SET_TRACE
++ GDB and NRUN do not use this interface.
++ This procedure returns: ``0'' indicating that the simulator should
++ be continued using sim_trace() calls; ``1'' indicating that the
++ simulation has finished. */
++
++int sim_trace (SIM_DESC sd);
++
++
++/* Enable tracing.
++ THIS PROCEDURE IS DEPRECATED.
++ GDB and NRUN do not use this interface.
++ This procedure returns: ``0'' indicating that the simulator should
++ be continued using sim_trace() calls; ``1'' indicating that the
++ simulation has finished. */
++
++void sim_set_trace (void);
++
++
++/* Configure the size of the profile buffer.
++ THIS PROCEDURE IS DEPRECATED.
++ GDB and NRUN do not use this interface.
++ This procedure does not take a SIM_DESC argument as it is
++ used before sim_open. */
++
++void sim_set_profile_size (int n);
++
++
++/* Kill the running program.
++ THIS PROCEDURE IS DEPRECATED.
++ GDB and NRUN do not use this interface.
++ This procedure will be replaced as part of the introduction of
++ multi-cpu simulators. */
++
++void sim_kill (SIM_DESC sd);
++
++#endif
diff --git a/tools/4.12/gdb/gdb-7.11-erc32-endian-fix.diff b/tools/4.12/gdb/gdb-7.11-erc32-endian-fix.diff
new file mode 100644
index 0000000..1021664
--- /dev/null
+++ b/tools/4.12/gdb/gdb-7.11-erc32-endian-fix.diff
@@ -0,0 +1,13 @@
+diff -ruw gdb-7.11.orig/sim/erc32/sis.h gdb-7.11/sim/erc32/sis.h
+--- gdb-7.11.orig/sim/erc32/sis.h 2016-03-15 10:24:35.934052479 +1100
++++ gdb-7.11/sim/erc32/sis.h 2016-03-16 13:52:51.988554970 +1100
+@@ -20,7 +20,7 @@
+ #include <sim-config.h>
+ #include <stdint.h>
+
+-#if HOST_BYTE_ORDER == BIG_ENDIAN
++#ifdef WORDS_BIGENDIAN
+ #define HOST_BIG_ENDIAN
+ #define EBT 0
+ #else
+Only in gdb-7.11/sim/erc32: sis.h~
diff --git a/tools/4.12/gdb/gdb-7.11-erc32-printf_filtered.diff b/tools/4.12/gdb/gdb-7.11-erc32-printf_filtered.diff
new file mode 100644
index 0000000..96403ff
--- /dev/null
+++ b/tools/4.12/gdb/gdb-7.11-erc32-printf_filtered.diff
@@ -0,0 +1,1103 @@
+diff -ruw gdb-7.11.orig1/sim/erc32/erc32.c gdb-7.11/sim/erc32/erc32.c
+--- gdb-7.11.orig1/sim/erc32/erc32.c 2016-03-16 14:00:04.632565918 +1100
++++ gdb-7.11/sim/erc32/erc32.c 2016-03-16 14:06:57.604576368 +1100
+@@ -19,6 +19,7 @@
+ /* The control space devices */
+
+ #include "config.h"
++#include <errno.h>
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -36,6 +37,7 @@
+ 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
+@@ -293,12 +295,15 @@
+
+ extern int ext_irl;
+
++static host_callback *callback;
++
+
+ /* One-time init */
+
+ void
+ init_sim()
+ {
++ callback = sim_callback;
+ port_init();
+ }
+
+@@ -321,12 +326,12 @@
+ sys_reset();
+ mec_ersr = 0x8000;
+ if (sis_verbose)
+- printf("Error manager reset - IU in error mode\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error manager reset - IU in error mode\n");
+ } else {
+ sys_halt();
+ mec_ersr |= 0x2000;
+ if (sis_verbose)
+- printf("Error manager halt - IU in error mode\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error manager halt - IU in error mode\n");
+ }
+ } else
+ mec_irq(1);
+@@ -337,12 +342,12 @@
+ sys_reset();
+ mec_ersr = 0x8000;
+ if (sis_verbose)
+- printf("Error manager reset - IU comparison error\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error manager reset - IU comparison error\n");
+ } else {
+ sys_halt();
+ mec_ersr |= 0x2000;
+ if (sis_verbose)
+- printf("Error manager halt - IU comparison error\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error manager halt - IU comparison error\n");
+ }
+ } else
+ mec_irq(1);
+@@ -353,12 +358,12 @@
+ sys_reset();
+ mec_ersr = 0x8000;
+ if (sis_verbose)
+- printf("Error manager reset - MEC hardware error\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error manager reset - MEC hardware error\n");
+ } else {
+ sys_halt();
+ mec_ersr |= 0x2000;
+ if (sis_verbose)
+- printf("Error manager halt - MEC hardware error\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error manager halt - MEC hardware error\n");
+ }
+ } else
+ mec_irq(1);
+@@ -416,7 +421,7 @@
+ mem_rammask = RAM_MASK;
+ }
+ if (sis_verbose)
+- printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
++ (*sim_callback->printf_filtered) (sim_callback, "RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
+ mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10);
+ }
+
+@@ -432,7 +437,7 @@
+ }
+ mem_romw_ws = (mec_wcr >> 8) & 0x0f;
+ if (sis_verbose)
+- printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n",
++ (*sim_callback->printf_filtered) (sim_callback, "Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n",
+ mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws);
+ }
+
+@@ -442,15 +447,15 @@
+ mem_accprot = (mec_wpr[0] | mec_wpr[1]);
+ mem_blockprot = (mec_mcr >> 3) & 1;
+ if (sis_verbose && mem_accprot)
+- printf("Memory block write protection enabled\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Memory block write protection enabled\n");
+ if (mec_mcr & 0x08000) {
+ mec_ersr |= 0x20;
+ decode_ersr();
+ }
+ if (sis_verbose && (mec_mcr & 2))
+- printf("Software reset enabled\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Software reset enabled\n");
+ if (sis_verbose && (mec_mcr & 1))
+- printf("Power-down mode enabled\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Power-down mode enabled\n");
+ }
+
+ /* Flush ports when simulator stops */
+@@ -553,7 +558,7 @@
+ int irq_test;
+
+ if (sis_verbose)
+- printf("interrupt %d acknowledged\n", level);
++ (*sim_callback->printf_filtered) (sim_callback, "interrupt %d acknowledged\n", level);
+ irq_test = mec_tcr & 0x80000;
+ if ((irq_test) && (mec_ifr & (1 << level)))
+ mec_ifr &= ~(1 << level);
+@@ -578,7 +583,7 @@
+ for (i = 15; i > 0; i--) {
+ if (((itmp >> i) & 1) != 0) {
+ if ((sis_verbose) && (i > old_irl))
+- printf("IU irl: %d\n", i);
++ (*sim_callback->printf_filtered) (sim_callback, "IU irl: %d\n", i);
+ ext_irl = i;
+ set_int(i, mec_intack, i);
+ break;
+@@ -753,7 +758,7 @@
+ uint32 data;
+ {
+ if (sis_verbose > 1)
+- printf("MEC write a: %08x, d: %08x\n",addr,data);
++ (*sim_callback->printf_filtered) (sim_callback, "MEC write a: %08x, d: %08x\n",addr,data);
+ switch (addr & 0x0ff) {
+
+ case MEC_MCR:
+@@ -767,7 +772,7 @@
+ sys_reset();
+ mec_ersr = 0x4000;
+ if (sis_verbose)
+- printf(" Software reset issued\n");
++ (*sim_callback->printf_filtered) (sim_callback, " Software reset issued\n");
+ }
+ break;
+
+@@ -782,7 +787,7 @@
+ mec_wpr[0] = (data >> 23) & 0x03;
+ mem_accprot = mec_wpr[0] || mec_wpr[1];
+ if (sis_verbose && mec_wpr[0])
+- printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n",
++ (*sim_callback->printf_filtered) (sim_callback, "Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n",
+ mec_ssa[0] << 2, mec_sea[0] << 2);
+ break;
+ case MEC_SEA1: /* 0x24 */
+@@ -795,7 +800,7 @@
+ mec_wpr[1] = (data >> 23) & 0x03;
+ mem_accprot = mec_wpr[0] || mec_wpr[1];
+ if (sis_verbose && mec_wpr[1])
+- printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n",
++ (*sim_callback->printf_filtered) (sim_callback, "Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n",
+ mec_ssa[1] << 2, mec_sea[1] << 2);
+ break;
+ case MEC_SEA2: /* 0x2c */
+@@ -909,7 +914,7 @@
+ if (wdog_status == init) {
+ wdog_status = disabled;
+ if (sis_verbose)
+- printf("Watchdog disabled\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Watchdog disabled\n");
+ }
+ break;
+
+@@ -936,10 +941,14 @@
+ {
+ 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
+@@ -947,16 +956,18 @@
+ {
+ 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
+@@ -976,39 +987,44 @@
+ }
+ 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);
++ (*sim_callback->printf_filtered) (sim_callback, "Warning, couldn't open output device %s\n", uart_dev1);
+ } else {
+ if (sis_verbose)
+- printf("serial port A on %s\n", uart_dev1);
++ (*sim_callback->printf_filtered) (sim_callback, "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");
++ (*sim_callback->printf_filtered) (sim_callback, "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)
+ if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) {
+- printf("Warning, couldn't open output device %s\n", uart_dev2);
++ (*sim_callback->printf_filtered) (sim_callback, "Warning, couldn't open output device %s\n", uart_dev2);
+ } else {
+ if (sis_verbose)
+- printf("serial port B on %s\n", uart_dev2);
++ (*sim_callback->printf_filtered) (sim_callback, "serial port B on %s\n", uart_dev2);
+ f2in = f2out = fdopen(fd2, "r+");
+ setbuf(f2out, NULL);
+ f2open = 1;
+@@ -1016,20 +1032,22 @@
+ if (f2in) ifd2 = fileno(f2in);
+ if (ifd2 == 0) {
+ if (sis_verbose)
+- printf("serial port B on stdin/stdout\n");
++ (*sim_callback->printf_filtered) (sim_callback, "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;
+@@ -1058,6 +1076,9 @@
+ if (f1open) {
+ anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
+ }
++ else {
++ anum = 0;
++ }
+ if (anum > 0) {
+ aind = 0;
+ if ((aind + 1) < anum)
+@@ -1090,6 +1111,9 @@
+ if (f2open) {
+ bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
+ }
++ else {
++ bnum = 0;
++ }
+ if (bnum > 0) {
+ bind = 0;
+ if ((bind + 1) < bnum)
+@@ -1122,6 +1146,9 @@
+ if (f1open) {
+ anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
+ }
++ else {
++ anum = 0;
++ }
+ if (anum > 0) {
+ Ucontrol |= 0x00000001;
+ aind = 0;
+@@ -1134,6 +1161,9 @@
+ if (f2open) {
+ bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
+ }
++ else {
++ bnum = 0;
++ }
+ if (bnum > 0) {
+ Ucontrol |= 0x00010000;
+ bind = 0;
+@@ -1152,7 +1182,7 @@
+ break;
+ default:
+ if (sis_verbose)
+- printf("Read from unimplemented MEC register (%x)\n", addr);
++ (*sim_callback->printf_filtered) (sim_callback, "Read from unimplemented MEC register (%x)\n", addr);
+
+ }
+ return 0;
+@@ -1174,8 +1204,12 @@
+ 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;
+ }
+ }
+@@ -1198,8 +1232,12 @@
+ 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;
+ }
+ }
+@@ -1229,7 +1267,8 @@
+ break;
+ default:
+ if (sis_verbose)
+- printf("Write to unimplemented MEC register (%x)\n", addr);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "Write to unimplemented MEC register (%x)\n", addr);
+
+ }
+ }
+@@ -1237,19 +1276,37 @@
+ 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 {
+@@ -1263,7 +1320,14 @@
+ 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 {
+@@ -1285,6 +1349,8 @@
+ 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)
+@@ -1301,6 +1367,8 @@
+ 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)
+@@ -1354,7 +1422,7 @@
+ event(wdog_intr, 0, wdog_scaler + 1);
+ } else {
+ if (wdog_rston) {
+- printf("Watchdog reset!\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Watchdog reset!\n");
+ sys_reset();
+ mec_ersr = 0xC000;
+ } else {
+@@ -1372,7 +1440,8 @@
+ {
+ event(wdog_intr, 0, wdog_scaler + 1);
+ if (sis_verbose)
+- printf("Watchdog started, scaler = %d, counter = %d\n",
++ (*sim_callback->printf_filtered) (sim_callback,
++ "Watchdog started, scaler = %d, counter = %d\n",
+ wdog_scaler, wdog_counter);
+ }
+
+@@ -1399,7 +1468,8 @@
+ rtc_enabled = 1;
+ } else {
+ if (sis_verbose)
+- printf("RTC stopped\n\r");
++ (*sim_callback->printf_filtered) (sim_callback,
++ "RTC stopped\n\r");
+ rtc_enabled = 0;
+ }
+ }
+@@ -1408,7 +1478,8 @@
+ rtc_start()
+ {
+ if (sis_verbose)
+- printf("RTC started (period %d)\n\r", rtc_scaler + 1);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "RTC started (period %d)\n\r", rtc_scaler + 1);
+ event(rtc_intr, 0, rtc_scaler + 1);
+ rtc_scaler_start = now();
+ rtc_enabled = 1;
+@@ -1452,7 +1523,7 @@
+ gpt_enabled = 1;
+ } else {
+ if (sis_verbose)
+- printf("GPT stopped\n\r");
++ (*sim_callback->printf_filtered) (sim_callback, "GPT stopped\n\r");
+ gpt_enabled = 0;
+ }
+ }
+@@ -1461,7 +1532,8 @@
+ gpt_start()
+ {
+ if (sis_verbose)
+- printf("GPT started (period %d)\n\r", gpt_scaler + 1);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "GPT started (period %d)\n\r", gpt_scaler + 1);
+ event(gpt_intr, 0, gpt_scaler + 1);
+ gpt_scaler_start = now();
+ gpt_enabled = 1;
+@@ -1566,7 +1638,8 @@
+ }
+
+ if (sis_verbose)
+- printf ("Memory exception at %x (illegal address)\n", addr);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "Memory exception at %x (illegal address)\n", addr);
+ if (sregs.psr & 0x080)
+ asi = 9;
+ else
+@@ -1589,7 +1662,7 @@
+ #ifdef ERRINJ
+ if (errmec) {
+ if (sis_verbose)
+- printf("Inserted MEC error %d\n",errmec);
++ (*sim_callback->printf_filtered) (sim_callback, "Inserted MEC error %d\n",errmec);
+ set_sfsr(errmec, addr, asi, 1);
+ if (errmec == 5) mecparerror();
+ if (errmec == 6) iucomperr();
+@@ -1641,7 +1714,8 @@
+ }
+
+ if (sis_verbose)
+- printf ("Memory exception at %x (illegal address)\n", addr);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "Memory exception at %x (illegal address)\n", addr);
+ set_sfsr(UIMP_ACC, addr, asi, 1);
+ *ws = MEM_EX_WS;
+ return 1;
+@@ -1666,7 +1740,8 @@
+ #ifdef ERRINJ
+ if (errmec) {
+ if (sis_verbose)
+- printf("Inserted MEC error %d\n",errmec);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "Inserted MEC error %d\n",errmec);
+ set_sfsr(errmec, addr, asi, 0);
+ if (errmec == 5) mecparerror();
+ if (errmec == 6) iucomperr();
+@@ -1690,7 +1765,8 @@
+ !((mec_wpr[0] && wphit[0]) || (mec_wpr[1] && wphit[1]))
+ )) {
+ if (sis_verbose)
+- printf("Memory access protection error at 0x%08x\n", addr);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "Memory access protection error at 0x%08x\n", addr);
+ set_sfsr(PROT_EXC, addr, asi, 0);
+ *ws = MEM_EX_WS;
+ return 1;
+diff -ruw gdb-7.11.orig1/sim/erc32/exec.c gdb-7.11/sim/erc32/exec.c
+--- gdb-7.11.orig1/sim/erc32/exec.c 2016-03-16 14:00:04.632565918 +1100
++++ gdb-7.11/sim/erc32/exec.c 2016-03-16 14:08:17.484578389 +1100
+@@ -1903,7 +1903,8 @@
+ if (errftt) {
+ sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14);
+ sregs->fpstate = FP_EXC_PE;
+- if (sis_verbose) printf("Inserted fpu error %X\n",errftt);
++ if (sis_verbose) (*sim_callback->printf_filtered) (sim_callback,
++ "Inserted fpu error %X\n",errftt);
+ errftt = 0;
+ }
+ #endif
+@@ -2023,7 +2024,8 @@
+ #ifdef ERRINJ
+ if (errtt) {
+ sregs->trap = errtt;
+- if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt);
++ if (sis_verbose) (*sim_callback->printf_filtered) (sim_callback,
++ "Inserted error trap 0x%02X\n",errtt);
+ errtt = 0;
+ }
+ #endif
+diff -ruw gdb-7.11.orig1/sim/erc32/func.c gdb-7.11/sim/erc32/func.c
+--- gdb-7.11.orig1/sim/erc32/func.c 2016-03-16 14:00:04.628565918 +1100
++++ gdb-7.11/sim/erc32/func.c 2016-03-16 14:17:33.328592454 +1100
+@@ -47,6 +47,8 @@
+ 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;
+@@ -80,14 +82,15 @@
+ size_t slen;
+
+ if ((fp = fopen(fname, "r")) == NULL) {
+- fprintf(stderr, "couldn't open batch file %s\n", fname);
++ (*sim_callback->printf_filtered) (sim_callback,
++ "couldn't open batch file %s\n", fname);
+ return 0;
+ }
+ while (getline(&lbuf, &len, fp) > -1) {
+ slen = strlen(lbuf);
+ if (slen && (lbuf[slen - 1] == '\n')) {
+ lbuf[slen - 1] = 0;
+- printf("sis> %s\n", lbuf);
++ (*sim_callback->printf_filtered) (sim_callback, "sis> %s\n", lbuf);
+ exec_cmd(sregs, lbuf);
+ }
+ }
+@@ -279,13 +282,13 @@
+ err = 1;
+ switch (err) {
+ case 0:
+- printf("%s = %d (0x%08x)\n", reg, rval, rval);
++ (*sim_callback->printf_filtered) (sim_callback, "%s = %d (0x%08x)\n", reg, rval, rval);
+ break;
+ case 1:
+- printf("no such regiser: %s\n", reg);
++ (*sim_callback->printf_filtered) (sim_callback, "no such regiser: %s\n", reg);
+ break;
+ case 2:
+- printf("cannot set g0\n");
++ (*sim_callback->printf_filtered) (sim_callback, "cannot set g0\n");
+ break;
+ default:
+ break;
+@@ -358,7 +361,7 @@
+ if ((flim > ebase.simtime) && (flim < 4294967296.0)) {
+ lim = (uint32) flim;
+ } else {
+- printf("error in expression\n");
++ (*sim_callback->printf_filtered) (sim_callback, "error in expression\n");
+ lim = -1;
+ }
+ }
+@@ -381,12 +384,12 @@
+ clen = strlen(cmd1);
+ if (strncmp(cmd1, "bp", clen) == 0) {
+ for (i = 0; i < sregs->bptnum; i++) {
+- printf(" %d : 0x%08x\n", i + 1, sregs->bpts[i]);
++ (*sim_callback->printf_filtered) (sim_callback, " %d : 0x%08x\n", i + 1, sregs->bpts[i]);
+ }
+ } else if (strncmp(cmd1, "+bp", clen) == 0) {
+ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+ sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;
+- printf("added breakpoint %d at 0x%08x\n",
++ (*sim_callback->printf_filtered) (sim_callback, "added breakpoint %d at 0x%08x\n",
+ sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);
+ sregs->bptnum += 1;
+ }
+@@ -394,7 +397,7 @@
+ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+ i = VAL(cmd1) - 1;
+ if ((i >= 0) && (i < sregs->bptnum)) {
+- printf("deleted breakpoint %d at 0x%08x\n", i + 1,
++ (*sim_callback->printf_filtered) (sim_callback, "deleted breakpoint %d at 0x%08x\n", i + 1,
+ sregs->bpts[i]);
+ for (; i < sregs->bptnum - 1; i++) {
+ sregs->bpts[i] = sregs->bpts[i + 1];
+@@ -404,7 +407,7 @@
+ }
+ } else if (strncmp(cmd1, "batch", clen) == 0) {
+ if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
+- printf("no file specified\n");
++ (*sim_callback->printf_filtered) (sim_callback, "no file specified\n");
+ } else {
+ batch(sregs, cmd1);
+ }
+@@ -420,7 +423,7 @@
+ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+ sis_verbose = VAL(cmd1);
+ }
+- printf("Debug level = %d\n",sis_verbose);
++ (*sim_callback->printf_filtered) (sim_callback, "Debug level = %d\n",sis_verbose);
+ } else if (strncmp(cmd1, "dis", clen) == 0) {
+ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+ daddr = VAL(cmd1);
+@@ -429,13 +432,13 @@
+ len = VAL(cmd2);
+ } else
+ len = 16;
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+ dis_mem(daddr, len, &dinfo);
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+ daddr += len * 4;
+ } else if (strncmp(cmd1, "echo", clen) == 0) {
+ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
+- printf("%s\n", (&cmdsave[clen+1]));
++ (*sim_callback->printf_filtered) (sim_callback, "%s\n", (&cmdsave[clen+1]));
+ }
+ #ifdef ERRINJ
+ } else if (strncmp(cmd1, "error", clen) == 0) {
+@@ -443,9 +446,9 @@
+ errper = VAL(cmd1);
+ if (errper) {
+ event(errinj, 0, (len = (random()%errper)));
+- printf("Error injection started with period %d\n",len);
++ (*sim_callback->printf_filtered) (sim_callback, "Error injection started with period %d\n",len);
+ }
+- } else printf("Injected errors: %d\n",errcnt);
++ } else (*sim_callback->printf_filtered) (sim_callback, "Injected errors: %d\n",errcnt);
+ #endif
+ } else if (strncmp(cmd1, "float", clen) == 0) {
+ stat = disp_fpu(sregs);
+@@ -459,7 +462,7 @@
+ sregs->npc = sregs->pc + 4;
+ if ((sregs->pc != 0) && (ebase.simtime == 0))
+ boot_init();
+- printf("resuming at 0x%08x\n",sregs->pc);
++ (*sim_callback->printf_filtered) (sim_callback, "resuming at 0x%08x\n",sregs->pc);
+ if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
+ stat = run_sim(sregs, VAL(cmd2), 0);
+ } else {
+@@ -475,7 +478,7 @@
+ if (sregs->histbuf != NULL)
+ free(sregs->histbuf);
+ sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));
+- printf("trace history length = %d\n\r", sregs->histlen);
++ (*sim_callback->printf_filtered) (sim_callback, "trace history length = %d\n\r", sregs->histlen);
+ sregs->histind = 0;
+
+ } else {
+@@ -483,7 +486,7 @@
+ for (i = 0; i < sregs->histlen; i++) {
+ if (j >= sregs->histlen)
+ j = 0;
+- printf(" %8d ", sregs->histbuf[j].time);
++ (*sim_callback->printf_filtered) (sim_callback, " %8d ", sregs->histbuf[j].time);
+ dis_mem(sregs->histbuf[j].addr, 1, &dinfo);
+ j++;
+ }
+@@ -495,7 +498,7 @@
+ while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
+ last_load_addr = bfd_load(cmd1);
+ } else {
+- printf("load: no file specified\n");
++ (*sim_callback->printf_filtered) (sim_callback, "load: no file specified\n");
+ }
+ } else if (strncmp(cmd1, "mem", clen) == 0) {
+ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
+@@ -565,14 +568,14 @@
+ }
+ sregs->pc = len & ~3;
+ sregs->npc = sregs->pc + 4;
+- printf("resuming at 0x%08x\n",sregs->pc);
++ (*sim_callback->printf_filtered) (sim_callback, "resuming at 0x%08x\n",sregs->pc);
+ stat = run_sim(sregs, UINT64_MAX, 0);
+ daddr = sregs->pc;
+ sim_halt();
+ } else if (strncmp(cmd1, "tlimit", clen) == 0) {
+ sregs->tlimit = limcalc(sregs->freq);
+ if (sregs->tlimit != (uint32) -1)
+- printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit,
++ (*sim_callback->printf_filtered) (sim_callback, "simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit,
+ sregs->tlimit / sregs->freq / 1000);
+ } else if (strncmp(cmd1, "tra", clen) == 0) {
+ if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
+@@ -580,7 +583,7 @@
+ } else {
+ stat = run_sim(sregs, VAL(cmd1), 1);
+ }
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+ daddr = sregs->pc;
+ sim_halt();
+ } else if (strncmp(cmd1, "trun", clen) == 0) {
+@@ -592,7 +595,7 @@
+ daddr = sregs->pc;
+ sim_halt();
+ } else
+- printf("syntax error\n");
++ (*sim_callback->printf_filtered) (sim_callback, "syntax error\n");
+ }
+ if (cmdsave2 != NULL)
+ free(cmdsave2);
+@@ -636,42 +639,42 @@
+ sregs->nbranch;
+ #endif
+
+- printf("\n Cycles : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
+- printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
++ (*sim_callback->printf_filtered) (sim_callback, "\n Cycles : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
++ (*sim_callback->printf_filtered) (sim_callback, " Instructions : %9" PRIu64 "\n", sregs->ninst);
+
+ #ifdef STAT
+- printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
+- printf(" load : %9.2f %%\n",
++ (*sim_callback->printf_filtered) (sim_callback, " integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
++ (*sim_callback->printf_filtered) (sim_callback, " load : %9.2f %%\n",
+ 100.0 * (float) sregs->nload / (float) sregs->ninst);
+- printf(" store : %9.2f %%\n",
++ (*sim_callback->printf_filtered) (sim_callback, " store : %9.2f %%\n",
+ 100.0 * (float) sregs->nstore / (float) sregs->ninst);
+- printf(" branch : %9.2f %%\n",
++ (*sim_callback->printf_filtered) (sim_callback, " branch : %9.2f %%\n",
+ 100.0 * (float) sregs->nbranch / (float) sregs->ninst);
+- printf(" float : %9.2f %%\n",
++ (*sim_callback->printf_filtered) (sim_callback, " float : %9.2f %%\n",
+ 100.0 * (float) sregs->finst / (float) sregs->ninst);
+- printf(" Integer CPI : %9.2f\n",
++ (*sim_callback->printf_filtered) (sim_callback, " Integer CPI : %9.2f\n",
+ ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
+ /
+ (float) (sregs->ninst - sregs->finst));
+- printf(" Float CPI : %9.2f\n",
++ (*sim_callback->printf_filtered) (sim_callback, " Float CPI : %9.2f\n",
+ ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
+ #endif
+- printf(" Overall CPI : %9.2f\n",
++ (*sim_callback->printf_filtered) (sim_callback, " 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",
++ (*sim_callback->printf_filtered) (sim_callback, "\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",
++ (*sim_callback->printf_filtered) (sim_callback, " Simulated ERC32 time : %.2f s\n",
+ (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
+- printf(" Processor utilisation : %.2f %%\n",
++ (*sim_callback->printf_filtered) (sim_callback, " Processor utilisation : %.2f %%\n",
+ 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
+- printf(" Real-time performance : %.2f %%\n",
++ (*sim_callback->printf_filtered) (sim_callback, " Real-time performance : %.2f %%\n",
+ 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
+- printf(" Simulator performance : %.2f MIPS\n",
++ (*sim_callback->printf_filtered) (sim_callback, " Simulator performance : %.2f MIPS\n",
+ (double)(sregs->ninst) / sregs->tottime / 1E6);
+- printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime);
++ (*sim_callback->printf_filtered) (sim_callback, " Used time (sys + user) : %.2f s\n\n", sregs->tottime);
+ }
+
+
+@@ -692,7 +695,7 @@
+ int32 sig;
+ {
+ if (sig != 2)
+- printf("\n\n Signal handler error (%d)\n\n", sig);
++ (*sim_callback->printf_filtered) (sim_callback, "\n\n Signal handler error (%d)\n\n", sig);
+ ctrl_c = 1;
+ }
+
+@@ -721,7 +724,7 @@
+ int i;
+ float t;
+
+- printf("\n fsr: %08X\n\n", sregs->fsr);
++ (*sim_callback->printf_filtered) (sim_callback, "\n fsr: %08X\n\n", sregs->fsr);
+
+ #ifdef HOST_LITTLE_ENDIAN
+ for (i = 0; i < 32; i++)
+@@ -730,13 +733,13 @@
+
+ for (i = 0; i < 32; i++) {
+ t = sregs->fs[i];
+- printf(" f%02d %08x %14e ", i, sregs->fsi[i], sregs->fs[i]);
++ (*sim_callback->printf_filtered) (sim_callback, " f%02d %08x %14e ", i, sregs->fsi[i], sregs->fs[i]);
+ if (!(i & 1))
+- printf("%14e\n", sregs->fd[i >> 1]);
++ (*sim_callback->printf_filtered) (sim_callback, "%14e\n", sregs->fd[i >> 1]);
+ else
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+ }
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+ return OK;
+ }
+
+@@ -749,9 +752,9 @@
+ int i;
+
+ cwp = ((cwp & 0x7) << 4);
+- printf("\n\t INS LOCALS OUTS GLOBALS\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n\t INS LOCALS OUTS GLOBALS\n");
+ for (i = 0; i < 8; i++) {
+- printf(" %d: %08X %08X %08X %08X\n", i,
++ (*sim_callback->printf_filtered) (sim_callback, " %d: %08X %08X %08X %08X\n", i,
+ sregs->r[(cwp + i + 24) & 0x7f],
+ sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f],
+ sregs->g[i]);
+@@ -776,7 +779,7 @@
+
+ uint32 i;
+
+- printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n",
++ (*sim_callback->printf_filtered) (sim_callback, "\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);
+ printf ("\n pc: %08X = %08X ", sregs->pc, i);
+@@ -785,8 +788,8 @@
+ 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");
+- printf("\n\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n IU in error mode");
++ (*sim_callback->printf_filtered) (sim_callback, "\n\n");
+ }
+
+ static void
+@@ -804,13 +807,13 @@
+ char *p;
+
+ for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
+- printf("\n %8X ", i);
++ (*sim_callback->printf_filtered) (sim_callback, "\n %8X ", i);
+ for (j = 0; j < 4; j++) {
+ sis_memory_read ((i + (j * 4)), data.u8, 4);
+ printf ("%08x ", data.u32);
+ mem[j] = data.u32;
+ }
+- printf(" ");
++ (*sim_callback->printf_filtered) (sim_callback, " ");
+ p = (char *) mem;
+ for (j = 0; j < 16; j++) {
+ if (isprint (p[j ^ EBT]))
+@@ -819,7 +822,7 @@
+ putchar('.');
+ }
+ }
+- printf("\n\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n\n");
+ }
+
+ void
+@@ -839,7 +842,7 @@
+ printf (" %08x %08x ", i, data.u32);
+ print_insn_sparc_sis(i, info);
+ if (i >= 0xfffffffc) break;
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+ }
+ }
+
+@@ -854,7 +857,7 @@
+ struct evcell *ev1, *evins;
+
+ if (ebase.freeq == NULL) {
+- printf("Error, too many events in event queue\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Error, too many events in event queue\n");
+ return;
+ }
+ ev1 = &ebase.eq;
+@@ -959,7 +962,7 @@
+ uint64 endtime;
+
+ if (ebase.eq.nxt == NULL)
+- printf("Warning: event queue empty - power-down mode not entered\n");
++ (*sim_callback->printf_filtered) (sim_callback, "Warning: event queue empty - power-down mode not entered\n");
+ endtime = ebase.simtime;
+ while (!ext_irl && (ebase.eq.nxt != NULL)) {
+ ebase.simtime = ebase.eq.nxt->time;
+@@ -971,7 +974,7 @@
+ ebase.freeq = evrem;
+ cfunc(arg);
+ if (ctrl_c) {
+- printf("\bwarning: power-down mode interrupted\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\bwarning: power-down mode interrupted\n");
+ break;
+ }
+ }
+@@ -1039,17 +1042,17 @@
+ pbfd = bfd_openr(fname, 0);
+
+ if (pbfd == NULL) {
+- printf("open of %s failed\n", fname);
++ (*sim_callback->printf_filtered) (sim_callback, "open of %s failed\n", fname);
+ return -1;
+ }
+ if (!bfd_check_format(pbfd, bfd_object)) {
+- printf("file %s doesn't seem to be an object file\n", fname);
++ (*sim_callback->printf_filtered) (sim_callback, "file %s doesn't seem to be an object file\n", fname);
+ return -1;
+ }
+
+ arch = bfd_get_arch_info (pbfd);
+ if (sis_verbose)
+- printf("loading %s:", fname);
++ (*sim_callback->printf_filtered) (sim_callback, "loading %s:", fname);
+ for (section = pbfd->sections; section; section = section->next) {
+ if (bfd_get_section_flags(pbfd, section) & SEC_ALLOC) {
+ bfd_vma section_address;
+@@ -1087,7 +1090,7 @@
+ section_size = bfd_section_size(pbfd, section);
+
+ if (sis_verbose)
+- printf("\nsection %s at 0x%08lx (0x%lx bytes)",
++ (*sim_callback->printf_filtered) (sim_callback, "\nsection %s at 0x%08lx (0x%lx bytes)",
+ section_name, section_address, section_size);
+
+ /* Text, data or lit */
+@@ -1113,11 +1116,11 @@
+ }
+ } else /* BSS */
+ if (sis_verbose)
+- printf("(not loaded)");
++ (*sim_callback->printf_filtered) (sim_callback, "(not loaded)");
+ }
+ }
+ if (sis_verbose)
+- printf("\n");
++ (*sim_callback->printf_filtered) (sim_callback, "\n");
+
+ return bfd_get_start_address (pbfd);
+ }
+diff -ruw gdb-7.11.orig1/sim/erc32/interf.c gdb-7.11/sim/erc32/interf.c
+--- gdb-7.11.orig1/sim/erc32/interf.c 2016-03-16 14:00:04.628565918 +1100
++++ gdb-7.11/sim/erc32/interf.c 2016-03-16 14:09:55.832580878 +1100
+@@ -57,8 +57,6 @@
+
+ int sis_gdb_break = 1;
+
+-host_callback *sim_callback;
+-
+ int
+ run_sim(sregs, icount, dis)
+ struct pstate *sregs;
+@@ -89,12 +87,12 @@
+ #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");
++ (*sim_callback->printf_filtered) (sim_callback, "bogus pc or npc\n");
+ #endif
+ 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",
++ (*sim_callback->printf_filtered) (sim_callback, "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],
+@@ -192,6 +190,9 @@
+ 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
+@@ -430,7 +431,7 @@
+ #if 1
+ if (sis_verbose > 2) {
+ uint32 fp = sregs.r[(win * 16 + 30) & 0x7f];
+- printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
++ (*sim_callback->printf_filtered) (sim_callback, "flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
+ }
+ #endif
+
+diff -ruw gdb-7.11.orig1/sim/erc32/sis.c gdb-7.11/sim/erc32/sis.c
+--- gdb-7.11.orig1/sim/erc32/sis.c 2016-03-16 14:00:04.632565918 +1100
++++ gdb-7.11/sim/erc32/sis.c 2016-03-16 14:01:13.052567649 +1100
+@@ -199,6 +199,8 @@
+ #endif
+ } else if (strcmp(argv[stat], "-dumbio") == 0) {
+ dumbio = 1;
++ } else if (strcmp(argv[stat], "-nouartrx") == 0) {
++ nouartrx = 1;
+ } else {
+ printf("unknown option %s\n", argv[stat]);
+ usage();
+@@ -293,4 +295,3 @@
+ }
+ return 0;
+ }
+-
+diff -ruw gdb-7.11.orig1/sim/erc32/sis.h gdb-7.11/sim/erc32/sis.h
+--- gdb-7.11.orig1/sim/erc32/sis.h 2016-03-16 14:00:04.632565918 +1100
++++ gdb-7.11/sim/erc32/sis.h 2016-03-16 14:00:44.488566926 +1100
+@@ -158,7 +158,7 @@
+ /* 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);
+@@ -200,6 +200,8 @@
+ extern void sys_halt (void);
+ extern int bfd_load (const char *fname);
+ extern double get_time (void);
++extern int nouartrx;
++extern host_callback *sim_callback;
+
+ /* exec.c */
+ extern int dispatch_instruction (struct pstate *sregs);