From 0bbd2de7f5306ad15ce544f9c3e9a5d9bb00dc85 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Wed, 16 Mar 2016 15:18:34 +1100 Subject: 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. --- tools/4.12/gdb/gdb-7.11-erc32-common-run.diff | 472 +++++++++ tools/4.12/gdb/gdb-7.11-erc32-endian-fix.diff | 13 + tools/4.12/gdb/gdb-7.11-erc32-printf_filtered.diff | 1103 ++++++++++++++++++++ 3 files changed, 1588 insertions(+) create mode 100644 tools/4.12/gdb/gdb-7.11-erc32-common-run.diff create mode 100644 tools/4.12/gdb/gdb-7.11-erc32-endian-fix.diff create mode 100644 tools/4.12/gdb/gdb-7.11-erc32-printf_filtered.diff (limited to 'tools') 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 . */ ++ ++/* Steve Chamberlain sac@cygnus.com, ++ and others at Cygnus. */ ++ ++#include "config.h" ++ ++#include ++#include ++#ifdef __STDC__ ++#include ++#else ++#include ++#endif ++ ++#ifdef HAVE_STDLIB_H ++#include ++#endif ++ ++#ifdef HAVE_STRING_H ++#include ++#else ++#ifdef HAVE_STRINGS_H ++#include ++#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 . */ ++ ++#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 + #include + +-#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 + #include + #include + #include +@@ -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); -- cgit v1.2.3