From c10fa7a627eefebf62c32c406949c8f2ef9d804c Mon Sep 17 00:00:00 2001
From: jlarmour <devnull@localhost>
Date: Fri, 30 Jun 2000 16:27:35 +0000
Subject: [PATCH] Merge from eCos master repository on 2000-06-30-08:18:49-BST

---
 host/libcdl/ChangeLog                         |   14 +
 host/libcdl/TODO                              |    7 +
 host/libcdl/cdlcore.hxx                       |   12 +-
 host/libcdl/transact.cxx                      |   39 +-
 host/libcdl/value.cxx                         |    9 +
 host/tools/configtool/ChangeLog               |    7 +
 .../configtool/standalone/common/ChangeLog    |    5 +
 .../configtool/standalone/common/cdl_exec.cxx | 1099 +++++++++++------
 .../configtool/standalone/common/cdl_exec.hxx |   64 +-
 .../standalone/common/ecosconfig.cxx          |  564 +++++----
 .../configtool/standalone/win32/Configtool.rc |    2 +-
 packages/ChangeLog                            |    4 +
 packages/NEWS                                 |    2 +-
 .../devs/eth/arm/ebsa285/current/ChangeLog    |   21 +
 .../current/cdl/ebsa285_eth_drivers.cdl       |   14 +-
 .../ebsa285/current/include/ebsa285_info.h    |    6 +-
 .../eth/arm/ebsa285/current/src/if_ebsa285.c  |   76 +-
 .../devs/serial/sh/cq7708/current/ChangeLog   |   32 +
 .../sh/cq7708/current/cdl/ser_sh_cq7708.cdl   |  136 ++
 .../sh/cq7708/current/src/sh_sci_cq7708.inl   |   98 ++
 .../sh/cq7708/current/src/sh_sci_serial.c     |  496 ++++++++
 packages/ecos.db                              |   12 +-
 packages/hal/arm/arch/current/ChangeLog       |    6 +
 packages/hal/arm/arch/current/src/arm_stub.c  |   54 +-
 .../hal/arm/arch/current/src/hal_mk_defs.c    |    2 +
 packages/hal/common/current/ChangeLog         |   27 +
 .../common/current/include/dbg-threads-api.h  |   20 +-
 packages/hal/common/current/include/hal_if.h  |   51 +-
 packages/hal/common/current/src/hal_if.c      |  191 ++-
 packages/hal/common/current/src/hal_misc.c    |   25 +-
 packages/hal/common/current/src/hal_stub.c    |   56 +-
 packages/hal/powerpc/arch/current/ChangeLog   |    5 +
 .../hal/powerpc/arch/current/src/vectors.S    |   26 -
 packages/hal/powerpc/cogent/current/ChangeLog |   14 +
 .../cogent/current/cdl/hal_powerpc_cogent.cdl |   22 +-
 .../powerpc/cogent/current/include/plf_intr.h |   16 -
 .../powerpc/cogent/current/include/plf_stub.h |    1 -
 .../hal/powerpc/cogent/current/src/hal_diag.c |  274 ++--
 .../hal/powerpc/cogent/current/src/plf_misc.c |   97 --
 packages/hal/powerpc/fads/current/ChangeLog   |    4 +
 .../fads/current/cdl/hal_powerpc_fads.cdl     |   16 -
 packages/hal/powerpc/mbx/current/ChangeLog    |    6 +
 .../powerpc/mbx/current/include/hal_diag.h    |    4 -
 .../hal/powerpc/mbx/current/src/hal_diag.c    |    2 +-
 packages/hal/powerpc/quicc/current/ChangeLog  |   16 +
 .../quicc/current/include/quicc_smc1.h        |   19 +-
 .../powerpc/quicc/current/src/quicc_smc1.c    |  246 ++--
 packages/hal/powerpc/sim/current/ChangeLog    |    7 +
 .../sim/current/cdl/hal_powerpc_sim.cdl       |    2 +
 .../hal/powerpc/sim/current/src/hal_aux.c     |    6 +
 packages/hal/sh/arch/current/ChangeLog        |   35 +
 packages/hal/sh/arch/current/cdl/hal_sh.cdl   |    2 +-
 .../hal/sh/arch/current/include/sh3_sci.h     |   81 ++
 .../hal/sh/arch/current/include/sh3_scif.h    |   88 ++
 packages/hal/sh/arch/current/src/hal_misc.c   |   14 +-
 packages/hal/sh/arch/current/src/sh.ld        |    5 +-
 packages/hal/sh/arch/current/src/sh3_sci.c    |  303 +++++
 packages/hal/sh/arch/current/src/sh3_scif.c   |  337 +++++
 packages/hal/sh/arch/current/src/vectors.S    |  547 ++++----
 packages/hal/sh/cq7708/current/ChangeLog      |   20 +
 .../current/cdl/hal_sh_sh7708_cq7708.cdl      |   36 +-
 .../hal/sh/cq7708/current/include/hal_diag.h  |   12 +
 .../pkgconf/mlt_sh_sh7708_cq7708_rom.h        |    4 +-
 .../pkgconf/mlt_sh_sh7708_cq7708_rom.ldi      |    4 +-
 .../pkgconf/mlt_sh_sh7708_cq7708_rom.mlt      |    4 +-
 .../hal/sh/cq7708/current/include/plf_stub.h  |   28 +-
 packages/hal/sh/cq7708/current/src/hal_diag.c |   98 +-
 packages/hal/sh/cq7708/current/src/plf_misc.c |   57 +-
 packages/hal/sh/edk/current/ChangeLog         |   27 +
 .../hal/sh/edk/current/cdl/hal_sh_edk7708.cdl |   36 +-
 .../hal/sh/edk/current/include/hal_diag.h     |   12 +
 .../include/pkgconf/mlt_sh_edk7708_rom.h      |    4 +-
 .../include/pkgconf/mlt_sh_edk7708_rom.ldi    |    4 +-
 .../include/pkgconf/mlt_sh_edk7708_rom.mlt    |    4 +-
 .../include/pkgconf/mlt_sh_edk7708_romram.h   |    4 +-
 .../include/pkgconf/mlt_sh_edk7708_romram.ldi |    4 +-
 .../include/pkgconf/mlt_sh_edk7708_romram.mlt |    4 +-
 .../hal/sh/edk/current/include/plf_stub.h     |   30 +-
 packages/hal/sh/edk/current/src/hal_diag.c    |  103 +-
 packages/hal/sh/edk/current/src/plf_misc.c    |   57 +-
 packages/hal/v85x/arch/current/ChangeLog      |    9 +
 packages/hal/v85x/arch/current/src/hal_misc.c |    5 -
 .../hal/v85x/arch/current/src/hal_mk_defs.c   |    2 +
 packages/hal/v85x/arch/current/src/vectors.S  |   21 +-
 packages/hal/v85x/ceb_v850/current/ChangeLog  |   12 +
 .../v85x/ceb_v850/current/include/hal_diag.h  |   22 +-
 .../v85x/ceb_v850/current/include/plf_intr.h  |   12 -
 .../v85x/ceb_v850/current/include/plf_stub.h  |   11 +-
 .../hal/v85x/ceb_v850/current/src/hal_diag.c  |  309 +++--
 .../hal/v85x/ceb_v850/current/src/plf_misc.c  |   13 +-
 .../hal/v85x/ceb_v850/current/src/plf_stub.c  |   78 --
 packages/io/serial/current/ChangeLog          |    4 +
 .../current/tests/ser_test_protocol.inl       |    9 +
 packages/kernel/current/ChangeLog             |    8 +
 packages/kernel/current/include/kapi.h        |    3 +
 packages/kernel/current/src/common/kapi.cxx   |    7 +
 packages/net/snmp/agent/current/ChangeLog     |   11 +
 .../agent/current/src/mibgroup/mibII/dot3.c   |    4 +
 .../net/snmp/agent/current/src/snmptask.c     |    2 +-
 packages/net/tcpip/current/ChangeLog          |   20 +
 packages/net/tcpip/current/src/ecos/support.c |  167 ++-
 packages/net/tcpip/current/tests/ping_test.c  |   59 +-
 packages/net/tcpip/current/tests/tcp_echo.c   |   48 +
 103 files changed, 4816 insertions(+), 1918 deletions(-)
 create mode 100644 packages/devs/serial/sh/cq7708/current/ChangeLog
 create mode 100644 packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl
 create mode 100644 packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl
 create mode 100644 packages/devs/serial/sh/cq7708/current/src/sh_sci_serial.c
 create mode 100644 packages/hal/sh/arch/current/include/sh3_sci.h
 create mode 100644 packages/hal/sh/arch/current/include/sh3_scif.h
 create mode 100644 packages/hal/sh/arch/current/src/sh3_sci.c
 create mode 100644 packages/hal/sh/arch/current/src/sh3_scif.c

diff --git a/host/libcdl/ChangeLog b/host/libcdl/ChangeLog
index d485e0e5e..0051bba4a 100644
--- a/host/libcdl/ChangeLog
+++ b/host/libcdl/ChangeLog
@@ -1,3 +1,17 @@
+2000-06-28  Bart Veer  <bartv@redhat.com>
+
+	* transact.cxx, cdlcore.hxx:
+	Add details of the current transaction to the transaction callback
+	class. Previously there was no way of getting hold of the current
+	transaction and hence the toplevel from inside the callback
+	without using statics.
+
+	* value.cxx (set_flavor):
+	Temporarily undo some of the previous value clean-ups, they were
+	causing problems at the application level. The API needs to be
+	changed to eliminate confusion between value and the data part
+	of a bool/value pair.
+
 2000-06-22  Bart Veer  <bartv@redhat.com>
 
 	* value.cxx, interface.cxx:
diff --git a/host/libcdl/TODO b/host/libcdl/TODO
index df0f8c414..950112c0a 100644
--- a/host/libcdl/TODO
+++ b/host/libcdl/TODO
@@ -18,6 +18,10 @@ Minor
 5) make cdl_interfaces into containers? How about cdl_options as well,
    to avoid reparenting problems?
 
+   cdl_interfaces as containers is actually a problem because interfaces
+   are part of the core, and hence do not know about the existence of
+   options and components.
+
 6) allow components and options to be used interchangeably in savefiles. 
 
 7) ecosconfig, create a paths file with details of the source tree
@@ -156,6 +160,9 @@ Intermediate
 13) friend packages, allowing one package to see the implementation
     details of another. Also, handle documentation links between these.
 
+14) API clean-up. Eliminate the confusion between "value" and the data part of
+    a bool/data pair.
+
 Major
 -----
 
diff --git a/host/libcdl/cdlcore.hxx b/host/libcdl/cdlcore.hxx
index be2eb8680..d019f5e77 100644
--- a/host/libcdl/cdlcore.hxx
+++ b/host/libcdl/cdlcore.hxx
@@ -4656,11 +4656,16 @@ class CdlTransactionCallback {
     friend class CdlTransactionBody;
     
   public:
-    CdlTransactionCallback();
     ~CdlTransactionCallback();
     static void (*get_callback_fn())(const CdlTransactionCallback&);
     static void set_callback_fn(void (*)(const CdlTransactionCallback&));
 
+    // Callback functions should be able to retrieve information
+    // about the current transaction and toplevel, to avoid the use
+    // of statics.
+    CdlTransaction              get_transaction() const;
+    CdlToplevel                 get_toplevel() const;
+    
     // active_changes and legal_values_changes get updated as the
     // transaction proceeds, so a set implementation is more
     // efficient. The others get filled in during a commit operation.
@@ -4681,7 +4686,12 @@ class CdlTransactionCallback {
   protected:
 
   private:
+    CdlTransactionCallback(CdlTransaction);
+    CdlTransaction      transact;
 
+    // Illegal operation.
+    CdlTransactionCallback();
+    
     enum {
         CdlTransactionCallback_Invalid     = 0,
         CdlTransactionCallback_Magic       = 0x0cec3a95
diff --git a/host/libcdl/transact.cxx b/host/libcdl/transact.cxx
index aaed42df6..533b2aa4e 100644
--- a/host/libcdl/transact.cxx
+++ b/host/libcdl/transact.cxx
@@ -66,12 +66,14 @@
 // The callback class is very straightforward. The hard work is done in
 // the transaction class.
 
-CdlTransactionCallback::CdlTransactionCallback()
+CdlTransactionCallback::CdlTransactionCallback(CdlTransaction transact_arg)
 {
     CYG_REPORT_FUNCNAME("CdlTransactionCallback:: constructor");
-    CYG_REPORT_FUNCARG1XV(this);
-
+    CYG_REPORT_FUNCARG2XV(this, transact_arg);
+    CYG_PRECONDITION_CLASSC(transact_arg);
+    
     // The vectors etc. will take care of themselves.
+    transact = transact_arg;
     cdltransactioncallback_cookie = CdlTransactionCallback_Magic;
     
     CYG_POSTCONDITION_THISC();
@@ -85,6 +87,7 @@ CdlTransactionCallback::~CdlTransactionCallback()
     CYG_PRECONDITION_THISC();
 
     cdltransactioncallback_cookie = CdlTransactionCallback_Invalid;
+    transact = 0;
     value_changes.clear();
     active_changes.clear();
     legal_values_changes.clear();
@@ -118,6 +121,32 @@ void (*CdlTransactionCallback::get_callback_fn())(const CdlTransactionCallback&)
     return result;
 }
 
+CdlTransaction
+CdlTransactionCallback::get_transaction() const
+{
+    CYG_REPORT_FUNCNAMETYPE("CdlTransactionCallback::get_transaction", "result %p");
+    CYG_PRECONDITION_THISC();
+
+    CdlTransaction result = transact;
+    CYG_POSTCONDITION_CLASSC(result);
+
+    CYG_REPORT_RETVAL(result);
+    return result;
+}
+
+CdlToplevel
+CdlTransactionCallback::get_toplevel() const
+{
+    CYG_REPORT_FUNCNAMETYPE("CdlTransactionCallback::get_toplevel", "result %p");
+    CYG_PRECONDITION_THISC();
+
+    CdlToplevel result = transact->get_toplevel();
+    CYG_POSTCONDITION_CLASSC(result);
+
+    CYG_REPORT_RETVAL(result);
+    return result;
+}
+
 bool
 CdlTransactionCallback::check_this(cyg_assert_class_zeal zeal) const
 {
@@ -1953,7 +1982,6 @@ CdlTransactionBody::commit()
             CYG_LOOP_INVARIANT_CLASSC(map_i->first);
             CYG_LOOP_INVARIANT_CLASSOC(map_i->second);
             parent->changes[map_i->first] = map_i->second;
-            
             for (conf_i = parent->new_conflicts.begin(); conf_i != parent->new_conflicts.end(); conf_i++) {
                 CYG_LOOP_INVARIANT_CLASSC(*conf_i);
                 (*conf_i)->update_solution_validity(map_i->first);
@@ -2035,11 +2063,10 @@ CdlTransactionBody::commit()
         // should happen before any conflicts get deleted. The actual callback
         // is invoked at the end, once all the changes have been moved to
         // the toplevel.
-        CdlTransactionCallback all_changes;
+        CdlTransactionCallback all_changes(this);
         if (0 != callback_fn) {
             
             for (map_i = changes.begin(); map_i != changes.end(); map_i++) {
-
                 if (0 == map_i->first->get_toplevel()) {
                     continue;
                 }
diff --git a/host/libcdl/value.cxx b/host/libcdl/value.cxx
index 453ed3597..966fa333e 100644
--- a/host/libcdl/value.cxx
+++ b/host/libcdl/value.cxx
@@ -902,7 +902,16 @@ CdlValue::set_flavor(CdlValueFlavor flavor_arg)
             enabled[CdlValueSource_Wizard]      = false;
             enabled[CdlValueSource_User]        = false;
 
+            // BLV - keep the data part at 0 for now. There is too
+            // much confusion in the code between value as a string
+            // representation, and value as the data part of the
+            // bool/data pair. This needs to be fixed, but it requires
+            // significant API changes.
+#if 0            
             CdlSimpleValue simple_val(cdl_int(1));
+#else
+            CdlSimpleValue simple_val(cdl_int(0));
+#endif            
             values[CdlValueSource_Default]      = simple_val;
             values[CdlValueSource_Inferred]     = simple_val;
             values[CdlValueSource_Wizard]       = simple_val;
diff --git a/host/tools/configtool/ChangeLog b/host/tools/configtool/ChangeLog
index b0e0eb008..8d4d2d024 100644
--- a/host/tools/configtool/ChangeLog
+++ b/host/tools/configtool/ChangeLog
@@ -1,3 +1,10 @@
+2000-06-27  John Dallaway  <jld@redhat.com>
+
+	* standalone/win32/Configtool.rc:
+
+	Update menu item text:
+	"eCos Services Page" -> "eCos Product Page".
+
 2000-06-22  John Dallaway  <jld@redhat.com>
 
 	* standalone/common/cdl_exec.cxx:
diff --git a/host/tools/configtool/standalone/common/ChangeLog b/host/tools/configtool/standalone/common/ChangeLog
index e77fbde83..ef7689503 100644
--- a/host/tools/configtool/standalone/common/ChangeLog
+++ b/host/tools/configtool/standalone/common/ChangeLog
@@ -1,3 +1,8 @@
+2000-06-28  Bart Veer  <bartv@redhat.com>
+
+	* cdl_exec.cxx, cdl_exec.hxx, ecosconfig.cxx:
+	Fix up the reporting of conflicts, inference engine changes, etc. 
+
 2000-04-10  Bart Veer  <bartv@redhat.com>
 
 	* cdl_exec.cxx:
diff --git a/host/tools/configtool/standalone/common/cdl_exec.cxx b/host/tools/configtool/standalone/common/cdl_exec.cxx
index f4c9e1e05..39a5618d7 100644
--- a/host/tools/configtool/standalone/common/cdl_exec.cxx
+++ b/host/tools/configtool/standalone/common/cdl_exec.cxx
@@ -39,470 +39,747 @@
 //==========================================================================
 
 #ifdef _MSC_VER
-	#include <direct.h> /* for getcwd() */
+#include <direct.h> /* for getcwd() */
 #else
-	#include <unistd.h> /* for getcwd() */
+#include <unistd.h> /* for getcwd() */
 #endif
 #ifdef __CYGWIN__
-	#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */
+#include <windows.h>
+#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */
 #endif
 #include "build.hxx"
 #include "cdl_exec.hxx"
 
-cdl_exec::cdl_exec (const std::string repository_tree, const std::string savefile_name, const std::string install_tree, bool no_resolve) :
-	pkgdata (NULL),
-	interp (NULL),
-	config (NULL) {
-	repository = repository_tree;
-	savefile = savefile_name;
-	install_prefix = install_tree;
-	CdlTransactionBody::set_inference_callback_fn (&inference_callback);
-	if (no_resolve) {
-		CdlTransactionBody::disable_automatic_inference ();
-	}
+// ----------------------------------------------------------------------------
+bool cdl_exec::quiet            = false;
+bool cdl_exec::verbose          = false;
+bool cdl_exec::ignore_errors    = false;
+
+cdl_exec::cdl_exec (const std::string repository_arg, const std::string savefile_arg,
+                    const std::string install_arg, bool no_resolve_arg)
+    : repository(repository_arg),
+      savefile(savefile_arg),
+      install_prefix(install_arg),
+      no_resolve(no_resolve_arg),
+      pkgdata (NULL),
+      interp (NULL),
+      config (NULL)
+{
+
+    // The inference callback does not actually do anything at present.
+    // In future it may be useful for diagnostic purposes.
+    CdlTransactionBody::set_inference_callback_fn (&inference_callback);
+    
+    // Automatic inference is always disabled. The inference engine
+    // only gets invoked explicitly, after a suitable transaction callback
+    // has been invoked. The problem here is that the transaction callback
+    // has to report changes made by the inference engine but there is
+    // no way of distinguishing between inferred values that come out of
+    // savefiles and inferred values determined by the inference engine.
+    CdlTransactionBody::disable_automatic_inference ();
 }
 
-bool cdl_exec::cmd_new (const std::string cdl_hardware, const std::string cdl_template /* = "default" */, const std::string cdl_version /* = "" */) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::make ("eCos", pkgdata, interp);
-		config->set_hardware (resolve_hardware_alias (cdl_hardware), &diagnostic_handler, &diagnostic_handler);
-		if (pkgdata->is_known_template (cdl_template) && ! cdl_version.empty ()) {
-			const std::vector<std::string> & versions = pkgdata->get_template_versions (cdl_template);
-			if (versions.end () == std::find (versions.begin (), versions.end (), cdl_version)) {
-				throw CdlStringException ("Unknown version " + cdl_version);
-			}
-		}
-		config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler);
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+void
+cdl_exec::set_quiet_mode(bool new_val)
+{
+    quiet = new_val;
 }
 
-bool cdl_exec::cmd_target (const std::string cdl_target) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		config->set_hardware (resolve_hardware_alias (cdl_target), &diagnostic_handler, &diagnostic_handler);
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+void
+cdl_exec::set_verbose_mode(bool new_val)
+{
+    verbose = new_val;
 }
 
-bool cdl_exec::cmd_template (const std::string cdl_template, const std::string cdl_version /* = "" */) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		if (pkgdata->is_known_template (cdl_template) && ! cdl_version.empty ()) {
-			const std::vector<std::string> & versions = pkgdata->get_template_versions (cdl_template);
-			if (versions.end () == std::find (versions.begin (), versions.end (), cdl_version)) {
-				throw CdlStringException ("Unknown version " + cdl_version);
-			}
-		}
-		config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler);
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+void
+cdl_exec::set_ignore_errors_mode(bool new_val)
+{
+    ignore_errors = new_val;
 }
 
-bool cdl_exec::cmd_export (const std::string cdl_savefile) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		config->save (cdl_savefile, /* minimal = */ true);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+void
+cdl_exec::init(bool load_config)
+{
+    pkgdata = CdlPackagesDatabaseBody::make(repository, &diagnostic_handler, &diagnostic_handler);
+    interp  = CdlInterpreterBody::make();
+    if (load_config) {
+        config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
+    }
+}
+
+// ----------------------------------------------------------------------------
+void
+cdl_exec::delete_cdl_data ()
+{
+    if (0 != config) {
+        delete config;
+        config = 0;
+    }
+    if (0 != interp) {
+        delete interp;
+        interp = 0;
+    }
+    if (0 != pkgdata) {
+        delete pkgdata;
+        pkgdata = 0;
+    }
 }
 
-bool cdl_exec::cmd_import (const std::string cdl_savefile) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		config->add (cdl_savefile, &diagnostic_handler, &diagnostic_handler);
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool cdl_exec::cmd_new (const std::string cdl_hardware,
+                        const std::string cdl_template /* = "default" */,
+                        const std::string cdl_version /* = "" */)
+{
+    bool status = false;
+    try {
+        init(false);
+        
+        config = CdlConfigurationBody::make ("eCos", pkgdata, interp);
+
+        // The hardware and template should be loaded in a single transaction.
+        // Validating the target name etc. can be left to libcdl.
+        CdlTransaction transact = CdlTransactionBody::make(config);
+        config->set_hardware(transact, resolve_hardware_alias(cdl_hardware), &diagnostic_handler, &diagnostic_handler);
+        config->set_template(transact, cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler);
+        transact->body();
+        delete transact;
+
+        // Unless inference has been suppressed, make sure that the
+        // inference engine gets invoked and that its results get
+        // reported.
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+
+        // Now report any conflicts which the inference engine could not report. 
+        report_conflicts();
+        
+        // A savefile should be generated/updated even if there are conflicts.
+        // Otherwise the user does not have a chance to edit the savefile
+        // and fix things.
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_add (const std::vector<std::string> cdl_packages) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		for (unsigned int n = 0; n < cdl_packages.size (); n++) {
-			config->load_package (resolve_package_alias (cdl_packages [n]), "", &diagnostic_handler, &diagnostic_handler);
-		}
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_target (const std::string cdl_target)
+{
+    bool status = false;
+    try {
+        init(true);
+        config->set_hardware (resolve_hardware_alias (cdl_target), &diagnostic_handler, &diagnostic_handler);
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_remove (const std::vector<std::string> cdl_packages) {
-	unsigned int n;
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		for (n = 0; n < cdl_packages.size (); n++) {
-			if (! config->lookup (resolve_package_alias (cdl_packages [n]))) {
-				throw CdlStringException ("Unknown package " + cdl_packages [n]);
-			}
-		}
-		for (n = 0; n < cdl_packages.size (); n++) {
-			config->unload_package (resolve_package_alias (cdl_packages [n]));
-		}
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_template (const std::string cdl_template, const std::string cdl_version /* = "" */)
+{
+    bool status = false;
+    try {
+        init(true);
+        config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler);
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages) {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		for (unsigned int n = 0; n < cdl_packages.size (); n++) {
-			config->change_package_version (resolve_package_alias (cdl_packages [n]), cdl_version, &diagnostic_handler, &diagnostic_handler, true);
-		}
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_export (const std::string cdl_savefile)
+{
+    bool status = false;
+    try {
+        init(true);
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        // Exporting to another file should only happen if the
+        // configuration is conflict-free. This is different from
+        // updating the savefile.
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            config->save (cdl_savefile, /* minimal = */ true);
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_tree () {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_import (const std::string cdl_savefile)
+{
+    bool status = false;
+    try {
+        init(true);
+        config->add(cdl_savefile, &diagnostic_handler, &diagnostic_handler);
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
+}
+
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_add (const std::vector<std::string> cdl_packages)
+{
+    bool status = false;
+    try {
+        init(true);
+        for (unsigned int n = 0; n < cdl_packages.size (); n++) {
+            config->load_package (resolve_package_alias (cdl_packages [n]), "", &diagnostic_handler, &diagnostic_handler);
+        }
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
+}
+
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_remove (const std::vector<std::string> cdl_packages)
+{
+    unsigned int n;
+    bool status = false;
+    try {
+        init(true);
+        for (n = 0; n < cdl_packages.size (); n++) {
+            if (! config->lookup (resolve_package_alias (cdl_packages [n]))) {
+                throw CdlStringException ("Unknown package " + cdl_packages [n]);
+            }
+        }
+        for (n = 0; n < cdl_packages.size (); n++) {
+            config->unload_package (resolve_package_alias (cdl_packages [n]));
+        }
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
+}
+
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages)
+{
+    bool status = false;
+    try {
+        init(true);
+        for (unsigned int n = 0; n < cdl_packages.size (); n++) {
+            config->change_package_version(resolve_package_alias (cdl_packages [n]), cdl_version,
+                                           &diagnostic_handler, &diagnostic_handler, true);
+        }
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
+}
+
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_tree ()
+{
+    bool status = false;
+    try {
+        init(true);
+        if (!no_resolve) {
+            CdlTransactionBody::set_callback_fn(&transaction_callback);
+            config->resolve_all_conflicts();
+        }
+        report_conflicts();
+        config->save (savefile);
+        // A build tree should only be generated if there are no conflicts.
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
 #ifdef _MSC_VER
-		char cwd [_MAX_PATH + 1];
+            char cwd [_MAX_PATH + 1];
 #else
-		char cwd [PATH_MAX + 1];
+            char cwd [PATH_MAX + 1];
 #endif
-		getcwd (cwd, sizeof cwd);
+            getcwd (cwd, sizeof cwd);
 #ifdef __CYGWIN__
-		char cwd_win32 [MAXPATHLEN + 1];
-		cygwin_conv_to_win32_path (cwd, cwd_win32);
-		generate_build_tree (config, cwd_win32, install_prefix);
+            char cwd_win32 [MAXPATHLEN + 1];
+            cygwin_conv_to_win32_path (cwd, cwd_win32);
+            generate_build_tree (config, cwd_win32, install_prefix);
 #else
-		generate_build_tree (config, cwd, install_prefix);
+            generate_build_tree (config, cwd, install_prefix);
 #endif
-		config->generate_config_headers (install_prefix.empty () ? "install/include/pkgconf" : install_prefix + "/include/pkgconf");
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+            config->generate_config_headers (install_prefix.empty () ? "install/include/pkgconf" : install_prefix + "/include/pkgconf");
+            status = true;
+        } else {
+            printf("\nUnable to generate build tree, this configuration still contains conflicts.\n");
+            printf("Either resolve the conflicts or use --ignore-errors\n");
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_list () {
-	bool status = false;
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-
-		// list the installed packages
-		std::vector<std::string> packages = pkgdata->get_packages ();
-		std::sort (packages.begin (), packages.end ());
-		for (unsigned int package = 0; package < packages.size (); package++) {
-			const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [package]);
-			printf ("Package %s (%s):\n aliases:", packages [package].c_str (), aliases [0].c_str ());
-			for (unsigned int alias = 1; alias < aliases.size (); alias++) {
-				printf (" %s", aliases [alias].c_str ());
-			}
-			const std::vector<std::string> & versions = pkgdata->get_package_versions (packages [package]);
-			printf ("\n versions:");
-			for (unsigned int version = 0; version < versions.size (); version++) {
-				printf (" %s", versions [version].c_str ());
-			}
-			printf ("\n");
-		}
-
-		// list the available targets
-		std::vector<std::string> targets = pkgdata->get_targets ();
-		std::sort (targets.begin (), targets.end ());
-		for (unsigned int target = 0; target < targets.size (); target++) {
-			const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [target]);
-			printf ("Target %s (%s):\n aliases:", targets [target].c_str (), aliases [0].c_str ());
-			for (unsigned int alias = 1; alias < aliases.size (); alias++) {
-				printf (" %s", aliases [alias].c_str ());
-			}
-			printf ("\n");
-		}
-
-		// list the available templates
-		std::vector<std::string> templates = pkgdata->get_templates ();
-		std::sort (templates.begin (), templates.end ());
-		for (unsigned int templ = 0; templ < templates.size (); templ++) {
-			const std::vector<std::string> & versions = pkgdata->get_template_versions (templates [templ]);
-			printf ("Template %s:\n versions:", templates [templ].c_str ());
-			for (unsigned int version = 0; version < versions.size (); version++) {
-				printf (" %s", versions [version].c_str ());
-			}
-			printf ("\n");
-		}
-
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_list ()
+{
+    bool status = false;
+    try {
+        init(false);
+
+        // list the installed packages
+        std::vector<std::string> packages = pkgdata->get_packages ();
+        std::sort (packages.begin (), packages.end ());
+        for (unsigned int package = 0; package < packages.size (); package++) {
+            const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [package]);
+            printf ("Package %s (%s):\n aliases:", packages [package].c_str (), aliases [0].c_str ());
+            for (unsigned int alias = 1; alias < aliases.size (); alias++) {
+                printf (" %s", aliases [alias].c_str ());
+            }
+            const std::vector<std::string> & versions = pkgdata->get_package_versions (packages [package]);
+            printf ("\n versions:");
+            for (unsigned int version = 0; version < versions.size (); version++) {
+                printf (" %s", versions [version].c_str ());
+            }
+            printf ("\n");
+        }
+
+        // list the available targets
+        std::vector<std::string> targets = pkgdata->get_targets ();
+        std::sort (targets.begin (), targets.end ());
+        for (unsigned int target = 0; target < targets.size (); target++) {
+            const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [target]);
+            printf ("Target %s (%s):\n aliases:", targets [target].c_str (), aliases [0].c_str ());
+            for (unsigned int alias = 1; alias < aliases.size (); alias++) {
+                printf (" %s", aliases [alias].c_str ());
+            }
+            printf ("\n");
+        }
+
+        // list the available templates
+        std::vector<std::string> templates = pkgdata->get_templates ();
+        std::sort (templates.begin (), templates.end ());
+        for (unsigned int templ = 0; templ < templates.size (); templ++) {
+            const std::vector<std::string> & versions = pkgdata->get_template_versions (templates [templ]);
+            printf ("Template %s:\n versions:", templates [templ].c_str ());
+            for (unsigned int version = 0; version < versions.size (); version++) {
+                printf (" %s", versions [version].c_str ());
+            }
+            printf ("\n");
+        }
+
+        status = true;
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_check () {
-	bool status = false;
-	unsigned int n;
-
-	try {
-		CdlTransactionBody::disable_automatic_inference ();
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		config->save (savefile); // tidy up any manual edits
-
-		// report current target and template
-		printf ("Target: %s\n", config->get_hardware ().c_str ());
-		printf ("Template: %s\n", config->get_template ().c_str ());
-		std::vector<std::string> template_packages = pkgdata->get_template_packages (config->get_template ());
-		const std::vector<std::string> & hardware_packages = pkgdata->get_target_packages (config->get_hardware ());
-		for (n = 0; n < hardware_packages.size (); n++) {
-			template_packages.push_back (hardware_packages [n]);
-		}
-
-		// report loaded packages not in the templates
-		const std::vector<CdlLoadable> & loadables = config->get_loadables ();
-		std::vector<std::string> added_packages;
-		std::vector<CdlLoadable>::const_iterator loadable_i;
-		for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) {
-			const CdlNode & node = dynamic_cast<CdlNode> (* loadable_i);
-			if (template_packages.end () == std::find (template_packages.begin (), template_packages.end (), node->get_name ())) {
-				added_packages.push_back (node->get_name ());
-			}
-		}
-		if (added_packages.size ()) {
-			printf ("Added:\n");
-		}
-		for (n = 0; n < added_packages.size (); n++) {
-			printf (" %s\n", added_packages [n].c_str ());
-		}
-
-		// report template packages not in the configuration
-		std::vector<std::string> removed_packages;
-		for (n = 0; n < template_packages.size (); n++) {
-			if (! config->lookup (template_packages [n])) {
-				removed_packages.push_back (template_packages [n]);
-			}
-		}
-		if (removed_packages.size ()) {
-			printf ("Removed:\n");
-		}
-		for (n = 0; n < removed_packages.size (); n++) {
-			printf (" %s\n", removed_packages [n].c_str ());
-		}
-
-		// report packages of non-default version
-		std::vector<CdlValuable> version_packages;
-		for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) {
-			const CdlValuable & valuable = dynamic_cast<CdlValuable> (* loadable_i);
-			if (pkgdata->get_package_versions (valuable->get_name ()) [0] != valuable->get_value ()) {
-				version_packages.push_back (valuable);
-			}
-		}
-		if (version_packages.size ()) {
-			printf ("Version(s):\n");
-		}
-		for (n = 0; n < version_packages.size (); n++) {
-			printf (" %s %s\n", version_packages [n]->get_name ().c_str (), version_packages [n]->get_value ().c_str ());
-		}
-
-		// report conflicts
-		const std::list<CdlConflict> & conflicts = config->get_all_conflicts ();
-		if (conflicts.size ()) {
-			printf ("%u conflict(s):\n", conflicts.size ());
-		} else {
-			printf ("No conflicts\n");
-		}
-		std::list<CdlConflict>::const_iterator conf_i;
-		for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) { // for each conflict
-			report_conflict (* conf_i);
-		}
-
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_check ()
+{
+    bool status = false;
+    unsigned int n;
+
+    try {
+        init(true);
+        // check() should never invoke the inference engine. The user
+        // wants to determine the current status, which should not
+        // change.
+        // However, updating the savefile is worthwhile because it
+        // will now contain more accurate information about the state.
+        config->save (savefile);
+
+        // report current target and template
+        printf ("Target: %s\n", config->get_hardware ().c_str ());
+        printf ("Template: %s\n", config->get_template ().c_str ());
+        std::vector<std::string> template_packages = pkgdata->get_template_packages (config->get_template ());
+        const std::vector<std::string> & hardware_packages = pkgdata->get_target_packages (config->get_hardware ());
+        for (n = 0; n < hardware_packages.size (); n++) {
+            template_packages.push_back (hardware_packages [n]);
+        }
+
+        // report loaded packages not in the templates
+        const std::vector<CdlLoadable> & loadables = config->get_loadables ();
+        std::vector<std::string> added_packages;
+        std::vector<CdlLoadable>::const_iterator loadable_i;
+        for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) {
+            const CdlNode & node = dynamic_cast<CdlNode> (* loadable_i);
+            if (template_packages.end () == std::find (template_packages.begin (), template_packages.end (), node->get_name ())) {
+                added_packages.push_back (node->get_name ());
+            }
+        }
+        if (added_packages.size ()) {
+            printf ("Added:\n");
+        }
+        for (n = 0; n < added_packages.size (); n++) {
+            printf (" %s\n", added_packages [n].c_str ());
+        }
+
+        // report template packages not in the configuration
+        std::vector<std::string> removed_packages;
+        for (n = 0; n < template_packages.size (); n++) {
+            if (! config->lookup (template_packages [n])) {
+                removed_packages.push_back (template_packages [n]);
+            }
+        }
+        if (removed_packages.size ()) {
+            printf ("Removed:\n");
+        }
+        for (n = 0; n < removed_packages.size (); n++) {
+            printf (" %s\n", removed_packages [n].c_str ());
+        }
+
+        // report packages of non-default version
+        std::vector<CdlValuable> version_packages;
+        for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) {
+            const CdlValuable & valuable = dynamic_cast<CdlValuable> (* loadable_i);
+            if (pkgdata->get_package_versions (valuable->get_name ()) [0] != valuable->get_value ()) {
+                version_packages.push_back (valuable);
+            }
+        }
+        if (version_packages.size ()) {
+            printf ("Version(s):\n");
+        }
+        for (n = 0; n < version_packages.size (); n++) {
+            printf (" %s %s\n", version_packages [n]->get_name ().c_str (), version_packages [n]->get_value ().c_str ());
+        }
+
+        // report conflicts
+        const std::list<CdlConflict> & conflicts = config->get_all_conflicts ();
+        if (conflicts.size ()) {
+            printf ("%u conflict(s):\n", conflicts.size ());
+        } else {
+            printf ("No conflicts\n");
+        }
+        report_conflicts();
+
+        status = true;
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-bool cdl_exec::cmd_resolve () {
-	bool status = false;
-
-	try {
-		pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler);
-		interp = CdlInterpreterBody::make ();
-		config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
-		config->resolve_all_conflicts ();
-		config->save (savefile);
-		status = true;
-	} catch (CdlStringException exception) {
-		exception_handler (exception);
-	} catch (...) {
-		exception_handler ();
-	}
-
-	delete_cdl_data ();
-	return status;
+// ----------------------------------------------------------------------------
+bool
+cdl_exec::cmd_resolve ()
+{
+    bool status = false;
+
+    try {
+        init(true);
+        CdlTransactionBody::set_callback_fn(&transaction_callback);
+        config->resolve_all_conflicts ();
+        report_conflicts();
+        config->save (savefile);
+        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
+            status = true;
+        }
+    } catch (CdlStringException exception) {
+        exception_handler (exception);
+    } catch (...) {
+        exception_handler ();
+    }
+
+    delete_cdl_data ();
+    return status;
 }
 
-CdlInferenceCallbackResult cdl_exec::inference_callback (CdlTransaction transaction) {
-	const std::vector<CdlConflict> & resolved_conflicts = transaction->get_resolved_conflicts ();
+// ----------------------------------------------------------------------------
+// The inference callback. This could give some useful diagnostics, or it
+// could do useful things when running in some interactive mode. In batch
+// mode it should not do anything.
+
+CdlInferenceCallbackResult
+cdl_exec::inference_callback (CdlTransaction transaction)
+{
+    return CdlInferenceCallbackResult_Continue;
+}
 
-	// report resolved conflicts
-	if (resolved_conflicts.size ()) {
-		printf ("%u conflict(s) resolved:\n", resolved_conflicts.size ());
-	}
-	for (unsigned int n = 0; n < resolved_conflicts.size (); n++) {
-		report_conflict (resolved_conflicts [n]);
-	}
+// ----------------------------------------------------------------------------
+// Output a message with indentation after newlines.
+static void
+dump_string(unsigned int indent, const std::string& str)
+{
+    bool newline_pending = false;
+    unsigned int i, j;
+    for (i = 0; i < str.size(); i++) {
+        if (newline_pending) {
+            putchar('\n');
+            if ('\n' != str[i]) {
+                for (j = 0; j < indent; j++) {
+                    putchar(' ');
+                }
+            }
+            newline_pending = false;
+        }
+        if ('\n' == str[i]) {
+            newline_pending = true;
+        } else {
+            putchar(str[i]);
+        }
+    }
+    if (newline_pending) {
+        putchar('\n');  // But not the indentation.
+    }
+}
 
-	// accept all changes
-	return CdlInferenceCallbackResult_Continue;
+// ----------------------------------------------------------------------------
+// The transaction callback. This should report any changes that have been
+// made to the configuration. The amount of output depends on the verbosity
+// level selected by the user.
+//
+// 1) quiet     - no output at all
+// 2) default   - list updates done by the inference engine.
+// 3) verbose   - this does not currently add anything.
+// 
+// There is no reporting of new or resolved conflicts. Resolved
+// conflicts are probably of no interest in batch mode. New conflicts
+// will be handled by report_conflicts(). There is also no information
+// given about active state changes, although arguably there should be
+// especially in the case of containers.
+
+void
+cdl_exec::transaction_callback(const CdlTransactionCallback& callback_data)
+{
+    if (quiet) {
+        return;
+    }
+
+    unsigned int i;
+    for (i = 0; i < callback_data.value_changes.size(); i++) {
+        CdlValuable valuable = callback_data.value_changes[i];
+        if (CdlValueSource_Inferred == valuable->get_source()) {
+            std::string msg = std::string("U ") + valuable->get_name() + ", new inferred value ";
+            std::string value = valuable->get_value();
+            if ("" == value) {
+                msg += "\"\"";
+            } else {
+                msg += value;
+            }
+            msg += "\n";
+            dump_string(4, msg);
+        }
+    }
 }
 
-void cdl_exec::report_conflict (CdlConflict conflict) {
-	printf (" %s:\n  %s\n", conflict->get_node ()->get_name ().c_str (), conflict->get_explanation ().c_str ());
+// ----------------------------------------------------------------------------
+// Report the remaining conflicts in the configuration. These indicate
+// problems that the user should fix before going further with the
+// configuration, e.g. before generating a build tree.
+//
+// Quiet verbosity level has no effect on this, but at the verbose level
+// it is a good idea to look for a possible solution to the conflict.
+
+
+void
+cdl_exec::report_conflicts()
+{
+    const std::list<CdlConflict>& all_conflicts = config->get_all_conflicts();
+    std::list<CdlConflict>::const_iterator conf_i;
+    for (conf_i = all_conflicts.begin(); conf_i != all_conflicts.end(); conf_i++) {
+        CdlNode     node = (*conf_i)->get_node();
+
+        std::string msg = std::string("C ") + node->get_name() + ", " + (*conf_i)->get_explanation() + "\n";
+        dump_string(2, msg);
+
+        if (verbose && (*conf_i)->resolution_implemented()) {
+            // See if there is a possible solution to this conflict.
+            // This involves creating a transaction, invoking the
+            // inference engine, and cancelling the transaction
+            // (thus making sure that nothing actually changes).
+            //
+            // NOTE: at some stage libcdl may keep track of solutions
+            // globally. However, although it will know when a solution
+            // becomes invalid it will not necessarily try to resolve
+            // all global conflicts after every change, so attempting
+            // to do this in a transaction may still be necessary.
+            CdlTransaction transact = CdlTransactionBody::make(config);
+            transact->resolve(*conf_i);
+            if ((*conf_i)->has_known_solution()) {
+                std::string soln_msg = "  Possible solution:\n";
+                const std::vector<std::pair<CdlValuable, CdlValue> > & soln = (*conf_i)->get_solution();
+                unsigned int i;
+                for (i = 0; i < soln.size(); i++) {
+                    soln_msg += soln[i].first->get_name() + " -> " + soln[i].second.get_value() + "\n";
+                }
+#if 0
+                // FIXME: currently this member only works for nested sub-transactions.
+                if (transact->user_confirmation_required()) {
+                    msg += "This change affects previous user settings.\n";
+                }
+#endif                
+                dump_string(4, soln_msg);
+            }
+            transact->cancel();
+            delete transact;
+        }
+    }
 }
 
-void cdl_exec::diagnostic_handler (std::string message) {
-	printf ("%s\n", message.c_str ());
+// ----------------------------------------------------------------------------
+void
+cdl_exec::diagnostic_handler (std::string message)
+{
+    printf ("%s\n", message.c_str ());
 }
 
 void cdl_exec::exception_handler (CdlStringException exception) {
-	printf ("%s\n", exception.get_message ().c_str ());
+    printf ("%s\n", exception.get_message ().c_str ());
 }
 
-void cdl_exec::exception_handler () {
-	printf ("Unknown error\n");
+void
+cdl_exec::exception_handler ()
+{
+    printf ("Unknown error\n");
 }
 
-void cdl_exec::delete_cdl_data () {
-	delete config;
-	config = NULL;
-	delete interp;
-	interp = NULL;
-	delete pkgdata;
-	pkgdata = NULL;
-}
 
-std::string cdl_exec::resolve_package_alias (const std::string alias) {
-	std::string package = alias;
-
-	if (! pkgdata->is_known_package (alias)) { // if the alias is not a package name
-		const std::vector<std::string> & packages = pkgdata->get_packages (); // get packages
-		for (unsigned int n = 0; n < packages.size (); n++) { // for each package
-			const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [n]); // get package aliases
-			if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found
-				package = packages [n]; // note the package
-				break;
-			}
-		}
-	}
-	return package;
+// ----------------------------------------------------------------------------
+std::string
+cdl_exec::resolve_package_alias (const std::string alias)
+{
+    std::string package = alias;
+
+    if (! pkgdata->is_known_package (alias)) { // if the alias is not a package name
+        const std::vector<std::string> & packages = pkgdata->get_packages (); // get packages
+        for (unsigned int n = 0; n < packages.size (); n++) { // for each package
+            const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [n]); // get package aliases
+            if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found
+                package = packages [n]; // note the package
+                break;
+            }
+        }
+    }
+    return package;
 }
 
-std::string cdl_exec::resolve_hardware_alias (const std::string alias) {
-	std::string target = alias;
-
-	if (! pkgdata->is_known_target (alias)) { // if the alias is not a target name
-		const std::vector<std::string> & targets = pkgdata->get_targets (); // get targets
-		for (unsigned int n = 0; n < targets.size (); n++) { // for each target
-			const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [n]); // get target aliases
-			if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found
-				target = targets [n]; // note the target
-				break;
-			}
-		}
-	}
-	return target;
+std::string
+cdl_exec::resolve_hardware_alias (const std::string alias)
+{
+    std::string target = alias;
+
+    if (! pkgdata->is_known_target (alias)) { // if the alias is not a target name
+        const std::vector<std::string> & targets = pkgdata->get_targets (); // get targets
+        for (unsigned int n = 0; n < targets.size (); n++) { // for each target
+            const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [n]); // get target aliases
+            if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found
+                target = targets [n]; // note the target
+                break;
+            }
+        }
+    }
+    return target;
 }
diff --git a/host/tools/configtool/standalone/common/cdl_exec.hxx b/host/tools/configtool/standalone/common/cdl_exec.hxx
index ed0f6c0b6..1c1d297ba 100644
--- a/host/tools/configtool/standalone/common/cdl_exec.hxx
+++ b/host/tools/configtool/standalone/common/cdl_exec.hxx
@@ -26,33 +26,43 @@
 
 class cdl_exec {
 public:
-	cdl_exec (const std::string repository_tree, const std::string savefile_name, const std::string install_tree, bool no_resolve);
-	bool cmd_new (const std::string cdl_hardware, const std::string cdl_template = "default", const std::string cdl_version = "");
-	bool cmd_tree ();
-	bool cmd_check ();
-	bool cmd_list ();
-	bool cmd_add (const std::vector<std::string> cdl_packages);
-	bool cmd_remove (const std::vector<std::string> cdl_packages);
-	bool cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages);
-	bool cmd_template (const std::string cdl_template, const std::string cdl_version = "");
-	bool cmd_export (const std::string cdl_savefile);
-	bool cmd_import (const std::string cdl_savefile);
-	bool cmd_target (const std::string cdl_target);
-	bool cmd_resolve ();
+    cdl_exec (const std::string repository_tree, const std::string savefile_name, const std::string install_tree, bool no_resolve);
+    bool cmd_new (const std::string cdl_hardware, const std::string cdl_template = "default", const std::string cdl_version = "");
+    bool cmd_tree ();
+    bool cmd_check ();
+    bool cmd_list ();
+    bool cmd_add (const std::vector<std::string> cdl_packages);
+    bool cmd_remove (const std::vector<std::string> cdl_packages);
+    bool cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages);
+    bool cmd_template (const std::string cdl_template, const std::string cdl_version = "");
+    bool cmd_export (const std::string cdl_savefile);
+    bool cmd_import (const std::string cdl_savefile);
+    bool cmd_target (const std::string cdl_target);
+    bool cmd_resolve ();
 
+    static void set_quiet_mode(bool);
+    static void set_verbose_mode(bool);
+    static void set_ignore_errors_mode(bool);
+    
 protected:
-	std::string repository;
-	std::string savefile;
-	std::string install_prefix;
-	CdlPackagesDatabase pkgdata;
-	CdlInterpreter interp;
-	CdlConfiguration config;
-	void delete_cdl_data ();
-	static void diagnostic_handler (std::string message);
-	void exception_handler (CdlStringException exception);
-	void exception_handler ();
-	static void report_conflict (CdlConflict conflict);
-	static CdlInferenceCallbackResult inference_callback (CdlTransaction transaction);
-	std::string resolve_package_alias (const std::string alias);
-	std::string resolve_hardware_alias (const std::string alias);
+    static bool quiet;
+    static bool verbose;
+    static bool ignore_errors;
+    std::string repository;
+    std::string savefile;
+    std::string install_prefix;
+    bool no_resolve;
+    CdlPackagesDatabase pkgdata;
+    CdlInterpreter interp;
+    CdlConfiguration config;
+    void init(bool /* load */);
+    void delete_cdl_data ();
+    static void diagnostic_handler (std::string message);
+    void exception_handler (CdlStringException exception);
+    void exception_handler ();
+    void report_conflicts();
+    static CdlInferenceCallbackResult inference_callback (CdlTransaction transaction);
+    static void transaction_callback(const CdlTransactionCallback&);
+    std::string resolve_package_alias (const std::string alias);
+    std::string resolve_hardware_alias (const std::string alias);
 };
diff --git a/host/tools/configtool/standalone/common/ecosconfig.cxx b/host/tools/configtool/standalone/common/ecosconfig.cxx
index 52cbaa34e..3e98a831b 100644
--- a/host/tools/configtool/standalone/common/ecosconfig.cxx
+++ b/host/tools/configtool/standalone/common/ecosconfig.cxx
@@ -39,11 +39,12 @@
 //==========================================================================
 
 #ifndef _MSC_VER
-	#include <sys/param.h>
-	#include <unistd.h> /* for realpath() */
+#include <sys/param.h>
+#include <unistd.h> /* for realpath() */
 #endif
 #ifdef __CYGWIN__
-	#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */
+#include <windows.h>
+#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */
 #endif
 #include "cdl_exec.hxx"
 #include "ecosconfig.hxx"
@@ -51,243 +52,376 @@
 #define TOOL_VERSION "1.3.net"
 #define TOOL_COPYRIGHT "Copyright (c) 2000 Red Hat, Inc."
 #define DEFAULT_SAVE_FILE "ecos.ecc"
+static char* tool = "ecosconfig";
 
 int main (int argc, char * argv []) {
 
-	// process command qualifiers
-	std::string repository;     // --srcdir=
-	std::string savefile;       // --config=
-	std::string install_prefix; // --prefix=
-	bool version = false;       // --version
-	bool no_resolve = false;    // --no-resolve
-	int command_index;
-	for (command_index = 1; command_index < argc; command_index++) { // for each command line argument
-		if (0 == strncmp (argv [command_index], "--srcdir=", 9)) {
-			repository = & argv [command_index] [9];
-		} else if (0 == strncmp (argv [command_index], "--config=", 9)) {
-			savefile = & argv [command_index] [9];
-		} else if (0 == strncmp (argv [command_index], "--prefix=", 9)) {
-			install_prefix = & argv [command_index] [9];
-		} else if (0 == strcmp (argv [command_index], "--version")) {
-			version = true;
-		} else if (0 == strcmp (argv [command_index], "--no-resolve")) {
-			no_resolve = true;
-		} else { // the argument is not a qualifier
-			break; // end of qualifiers
-		}
-	}
+    // process command qualifiers
+    std::string repository;     // --srcdir=
+    std::string savefile;       // --config=
+    std::string install_prefix; // --prefix=
+    bool version = false;       // --version
+    bool no_resolve = false;    // --no-resolve
+    bool quiet = false;         // -q, --quiet
+    bool verbose = false;       // -v, --verbose
+    bool ignore_errors = false; // -i, --ignore-errors
+    bool help = false;          // --help
+        
+    // getopt() cannot easily be used here since this code has to
+    // build with VC++ as well.
+    bool args_ok = true;
+    int command_index;
+    for (command_index = 1; command_index < argc; command_index++) { // for each command line argument
+        char* arg = argv[command_index];
+        if (0 == strcmp(arg, "--help")) {
+            help = true;
+        } else if ((0 == strcmp(arg, "-q")) || (0 == strcmp(arg, "--quiet"))) {
+            // Allow repeated use of -q and -v to override each other.
+            // This is useful in conjunction with shell aliases.
+            quiet = true;
+            verbose = false;
+        } else if ((0 == strcmp(arg, "-v")) || (0 == strcmp(arg, "--verbose"))) {
+            verbose = true;
+            quiet = false;
+        } else if ((0 == strcmp(arg, "-i")) || (0 == strcmp(arg, "--ignore-errors"))) {
+            // Duplicate use of -i and the other flags is harmless.
+            ignore_errors = true;
+        } else if (0 == strcmp(arg, "--version")) {
+            version = true;
+        } else if (0 == strcmp(arg, "--no-resolve")) {
+            no_resolve = true;
+        } else if (0 == strncmp(arg, "--srcdir", 8)) {
+            // Duplicate use of --srcdir and other data-containing options should
+            // be marked as an error.
+            if ("" != repository) {
+                fprintf(stderr, "%s: the `--srcdir' option should be used only once.\n", tool);
+                args_ok = false;
+            } else {
+                if ('=' == arg[8]) {
+                    repository = std::string(arg + 9);
+                    if ("" == repository) {
+                        fprintf(stderr, "%s: missing component repository after `--srcdir='\n", tool);
+                        args_ok = false;
+                    }
+                } else if ('\0' == arg[8]) {
+                    command_index++;
+                    if (command_index == argc) {
+                        fprintf(stderr, "%s: missing component repository after `--srcdir'\n", tool);
+                        args_ok = false;
+                    } else {
+                        repository = argv[command_index];
+                    }
+                } else {
+                    fprintf(stderr, "%s: invalid option `%s'\n", tool, arg);
+                    args_ok = false;
+                }
+            }
+        } else if (0 == strncmp(arg, "--config", 8)) {
+            if ("" != savefile) {
+                fprintf(stderr, "%s: the `--config' option should be used only once.\n", tool);
+                args_ok = false;
+            } else {
+                if ('=' == arg[8]) {
+                    savefile = std::string(arg + 9);
+                    if ("" == savefile) {
+                        fprintf(stderr, "%s: missing configuration savefile after `--config='\n", tool);
+                        args_ok = false;
+                    }
+                } else if ('\0' == arg[8]) {
+                    command_index++;
+                    if (command_index == argc) {
+                        fprintf(stderr, "%s: missing configuration savefile after `--config'\n", tool);
+                        args_ok = false;
+                    } else {
+                        savefile = argv[command_index];
+                    }
+                } else {
+                    fprintf(stderr, "%s: invalid option `%s'\n", tool, arg);
+                    args_ok = false;
+                }
+            }
+        } else if (0 == strncmp(arg, "--prefix", 8)) {
+            if ("" != install_prefix) {
+                fprintf(stderr, "%s: the `--prefix' option should be used only once.\n", tool);
+                args_ok = false;
+            } else {
+                if ('=' == arg[8]) {
+                    install_prefix = std::string(arg + 9);
+                    if ("" == install_prefix) {
+                        fprintf(stderr, "%s: missing install prefix after `--prefix='\n", tool);
+                        args_ok = false;
+                    }
+                } else if ('\0' == arg[8]) {
+                    command_index++;
+                    if (command_index == argc) {
+                        fprintf(stderr, "%s: missing install prefix after `--prefix'\n", tool);
+                        args_ok = false;
+                    } else {
+                        install_prefix = argv[command_index];
+                    }
+                } else {
+                    fprintf(stderr, "%s: invalid option `%s'\n", tool, arg);
+                    args_ok = false;
+                }
+            }
+        } else {
+            // The argument is not a qualifier
+            // However, none of the sub-commands begin with a -
+            if ('-' == arg[0]) {
+                fprintf(stderr, "%s: unknown option `%s'\n", tool, arg);
+                args_ok = false;
+            }
+            break; // end of qualifiers
+        }
+    }
 
-	// usage message
-	if (command_index == argc) { // if there is no command
-		if (version) { // if the tool version was requested
-			printf ("ecosconfig %s (%s %s)\n%s\n", TOOL_VERSION, __DATE__, __TIME__, TOOL_COPYRIGHT);
-		} else { // the tool version was not requested
-			usage_message (); // print the usage message
-		}
-		return EXIT_SUCCESS;
-	}
-
-	// set the default save file
-	if (savefile.empty ()) { // if the save file was not specified on the command line
-		savefile = DEFAULT_SAVE_FILE; // use the default save file
-	}
+#if 0
+    printf("args_ok is %d\n", args_ok);
+    printf("help is %d\n", help);
+    printf("version is %d\n", version);
+    printf("no_resolve is %d\n", no_resolve);
+    printf("quiet is %d\n", quiet);
+    printf("verbose is %d\n", verbose);
+    printf("ignore_errors is %d\n", ignore_errors);
+    printf("repository is %s\n", repository.c_str());
+    printf("savefile is %s\n", savefile.c_str());
+    printf("install_prefix is %s\n", install_prefix.c_str());
+    exit(EXIT_SUCCESS);
+#endif
+    
+    // Usually argv[command_index] will be a sub-command, unless
+    // --help or --version has been used.
+    
+    // Always output the version number, irrespective of subsequent
+    // commands or any problems. This can be useful in batch jobs.
+    if (version) {
+        printf ("ecosconfig %s (%s %s)\n%s\n", TOOL_VERSION, __DATE__, __TIME__, TOOL_COPYRIGHT);
+        if (command_index == argc) {
+            return EXIT_SUCCESS;
+        }
+    }
+    // Cope with --help and any user errors. If --help is used then
+    // subsequent arguments should be ignored, as should any problems
+    // with the arguments. This allows the user to type a partial
+    // command, then switch to --help, and use shell history editing
+    // to complete/correct the command.
+    if (help || !args_ok || (command_index == argc)) {
+        usage_message();
+        return help ? EXIT_SUCCESS : EXIT_FAILURE;
+    }
+    
+    // set the default save file
+    if (savefile.empty ()) { // if the save file was not specified on the command line
+        savefile = DEFAULT_SAVE_FILE; // use the default save file
+    }
 
-	// find the repository
-	if (repository.empty ()) { // if the repository was not specified on the command line
-		const char * env_var = getenv ("ECOS_REPOSITORY");
-		if (env_var) { // if the ECOS_REPOSITORY environment variable is defined
-			repository = env_var;
-		} else { // the ECOS_REPOSITORY environment variable is not defined
-			// assume that the tool is located in the root of the repository
+    // find the repository
+    if (repository.empty ()) { // if the repository was not specified on the command line
+        const char * env_var = getenv ("ECOS_REPOSITORY");
+        if (env_var) { // if the ECOS_REPOSITORY environment variable is defined
+            repository = env_var;
+        } else { // the ECOS_REPOSITORY environment variable is not defined
+            // assume that the tool is located in the root of the repository
 #ifdef _MSC_VER
-			char toolpath [_MAX_PATH + 1];
-			_fullpath (toolpath, argv [0], sizeof (toolpath)); // get the absolute path to the tool
+            char toolpath [_MAX_PATH + 1];
+            _fullpath (toolpath, argv [0], sizeof (toolpath)); // get the absolute path to the tool
 #else
-			char toolpath [MAXPATHLEN + 1];
-			realpath (argv [0], toolpath); // get the absolute path to the tool
+            // NOTE: portability problem. realpath() is not a POSIX function.
+            // Alternative code may be needed on some platforms.
+            char toolpath [MAXPATHLEN + 1];
+            realpath (argv [0], toolpath); // get the absolute path to the tool
 #endif
-			repository = toolpath;
-			for (unsigned int n = repository.size () - 1; n > 0; n--) { // for each char starting at the tail
-				if (('\\' == repository [n]) || ('/' == repository [n])) { // if the char is a directory separator
-					repository.resize (n); // remove the filename from the filepath
-					break;
-				}
-			}
-		}
-	}
+            repository = toolpath;
+            for (unsigned int n = repository.size () - 1; n > 0; n--) { // for each char starting at the tail
+                if (('\\' == repository [n]) || ('/' == repository [n])) { // if the char is a directory separator
+                    repository.resize (n); // remove the filename from the filepath
+                    break;
+                }
+            }
+        }
+    }
 
 #ifdef __CYGWIN__
-	// convert cygwin paths to win32 paths
-	char buffer [MAXPATHLEN + 1];
-	cygwin_conv_to_win32_path (repository.c_str (), buffer);
-	repository = buffer;
-	cygwin_conv_to_win32_path (savefile.c_str (), buffer);
-	savefile = buffer;
-	if (! install_prefix.empty ()) { // cygwin_conv_to_win32_path() does not copy an empty string
-		cygwin_conv_to_win32_path (install_prefix.c_str (), buffer);
-		install_prefix = buffer;
-	}
+    // convert cygwin paths to win32 paths
+    char buffer [MAXPATHLEN + 1];
+    cygwin_conv_to_win32_path (repository.c_str (), buffer);
+    repository = buffer;
+    cygwin_conv_to_win32_path (savefile.c_str (), buffer);
+    savefile = buffer;
+    if (! install_prefix.empty ()) { // cygwin_conv_to_win32_path() does not copy an empty string
+        cygwin_conv_to_win32_path (install_prefix.c_str (), buffer);
+        install_prefix = buffer;
+    }
 #endif
 
-	// process the command
-	cdl_exec exec (trim_path (repository), savefile, trim_path (install_prefix), no_resolve);
-	const std::string command = argv [command_index];
-	bool status = true;
-
-	if ("new" == command) {
-		if (command_index + 2 == argc) {
-			status = exec.cmd_new (argv [command_index + 1]);
-		} else if (command_index + 3 == argc) {
-			status = exec.cmd_new (argv [command_index + 1], argv [command_index + 2]);
-		} else if (command_index + 4 == argc) {
-			status = exec.cmd_new (argv [command_index + 1], argv [command_index + 2], argv [command_index + 3]);
-		} else {
-			status = false;
-			usage_message ();
-		}
-
-	} else if ("tree" == command) {
-		if (command_index + 1 == argc) {
-			status = exec.cmd_tree ();
-		} else {
-			status = false;
-			usage_message ();
-		}
-
-	} else if ("list" == command) {
-		if (command_index + 1 == argc) {
-			status = exec.cmd_list ();
-		} else {
-			status = false;
-			usage_message ();
-		}
-
-	} else if ("check" == command) {
-		if (command_index + 1 == argc) {
-			status = exec.cmd_check ();
-		} else {
-			status = false;
-			usage_message ();
-		}
-
-	} else if ("resolve" == command) {
-		if (command_index + 1 == argc) {
-			status = exec.cmd_resolve ();
-		} else {
-			status = false;
-			usage_message ();
-		}
-
-	} else if ("add" == command) {
-		if (command_index + 1 < argc) {
-			std::vector<std::string> packages;
-			for (int n = command_index + 1; n < argc; n++) {
-				packages.push_back (argv [n]);
-			}
-			status = exec.cmd_add (packages);
-		} else {
-			status = false;
-			usage_message ();
-		}
-
-	} else if ("remove" == command) {
-		if (command_index + 1 < argc) {
-			std::vector<std::string> packages;
-			for (int n = command_index + 1; n < argc; n++) {
-				packages.push_back (argv [n]);
-			}
-			status = exec.cmd_remove (packages);
-		} else {
-			status = false;
-			usage_message ();
-		}
+    // Initialize the cdl_exec code (not quite sure why this needs a
+    // separate object rather than just a bunch of statics). 
+    cdl_exec exec (trim_path (repository), savefile, trim_path (install_prefix), no_resolve);
+    cdl_exec::set_quiet_mode(quiet);
+    cdl_exec::set_verbose_mode(verbose);
+    cdl_exec::set_ignore_errors_mode(ignore_errors);
+    
+    // Now identify and process the sub-command.
+    const std::string command = argv [command_index];
+    command_index++;
+    bool status = false;
 
-	} else if ("version" == command) {
-		if (command_index + 2 < argc) {
-			std::vector<std::string> packages;
-			for (int n = command_index + 2; n < argc; n++) {
-				packages.push_back (argv [n]);
-			}
-			status = exec.cmd_version (argv [command_index + 1], packages);
-		} else {
-			status = false;
-			usage_message ();
-		}
+    if ("new" == command) {
+        // Usage: ecosconfig new <target> [template [version]]
+        if ((command_index == argc) || ((command_index + 3) <= argc)) {
+            usage_message();
+        } else {
+            // The default values for template and template_version
+            // are part of the cdl_exec class, so cdl_exec::cmd_new() has
+            // to be invoked with the right number of arguments.
+            if ((command_index + 1) == argc) {
+                status = exec.cmd_new(argv[command_index]);
+            } else if ((command_index + 2) == argc) {
+                status = exec.cmd_new(argv[command_index], argv[command_index + 1]);
+            } else {
+                status = exec.cmd_new(argv[command_index], argv[command_index + 1], argv[command_index + 2]);
+            }
+        }
+    } else if ("tree" == command) {
+        // Usage: ecosconfig tree
+        if (command_index == argc) {
+            status = exec.cmd_tree ();
+        } else {
+            usage_message ();
+        }
+    } else if ("list" == command) {
+        // Usage: ecosconfig list
+        if (command_index == argc) {
+            status = exec.cmd_list ();
+        } else {
+            usage_message ();
+        }
+    } else if ("check" == command) {
+        // Usage: ecosconfig check
+        if (command_index == argc) {
+            status = exec.cmd_check ();
+        } else {
+            usage_message ();
+        }
+    } else if ("resolve" == command) {
+        // Usage: ecosconfig resolve
+        if (command_index == argc) {
+            status = exec.cmd_resolve ();
+        } else {
+            usage_message ();
+        }
+    } else if ("add" == command) {
+        // Usage: ecosconfig add <package> [<package2> ...]
+        if (command_index < argc) {
+            std::vector<std::string> packages;
+            for (int n = command_index; n < argc; n++) {
+                packages.push_back (argv [n]);
+            }
+            status = exec.cmd_add (packages);
+        } else {
+            usage_message ();
+        }
+    } else if ("remove" == command) {
+        // Usage: ecosconfig remove <package> [<package2> ...]
+        if (command_index < argc) {
+            std::vector<std::string> packages;
+            for (int n = command_index; n < argc; n++) {
+                packages.push_back (argv [n]);
+            }
+            status = exec.cmd_remove (packages);
+        } else {
+            usage_message ();
+        }
+    } else if ("version" == command) {
+        // Usage: ecosconfig version <version> <package> [<package2> ...]
+        // Note that it is not possible to change several packages to different versions. 
+        if (command_index + 1 < argc) {
+            std::vector<std::string> packages;
+            for (int n = command_index + 1; n < argc; n++) {
+                packages.push_back (argv [n]);
+            }
+            status = exec.cmd_version (argv [command_index], packages);
+        } else {
+            usage_message ();
+        }
 
-	} else if ("target" == command) {
-		if (command_index + 2 == argc) {
-			status = exec.cmd_target (argv [command_index + 1]);
-		} else {
-			status = false;
-			usage_message ();
-		}
+    } else if ("target" == command) {
+        // Usage: ecosconfig target <target>
+        if (command_index + 1 == argc) {
+            status = exec.cmd_target (argv [command_index]);
+        } else {
+            usage_message ();
+        }
 
-	} else if ("template" == command) {
-		if (command_index + 2 == argc) {
-			status = exec.cmd_template (argv [command_index + 1]);
-		} else if (command_index + 3 == argc) {
-			status = exec.cmd_template (argv [command_index + 1], argv [command_index + 2]);
-		} else {
-			status = false;
-			usage_message ();
-		}
+    } else if ("template" == command) {
+        // Usage: ecosconfig template <template> [<version>]
+        if (command_index + 1 == argc) {
+            status = exec.cmd_template (argv [command_index]);
+        } else if (command_index + 2 == argc) {
+            status = exec.cmd_template (argv [command_index], argv [command_index]);
+        } else {
+            usage_message ();
+        }
 
-	} else if ("export" == command) {
-		if (command_index + 2 == argc) {
-			status = exec.cmd_export (argv [command_index + 1]);
-		} else {
-			status = false;
-			usage_message ();
-		}
+    } else if ("export" == command) {
+        // Usage: ecosconfige export <filename>
+        if (command_index + 1 == argc) {
+            status = exec.cmd_export (argv [command_index]);
+        } else {
+            usage_message ();
+        }
 
-	} else if ("import" == command) {
-		if (command_index + 2 == argc) {
-			status = exec.cmd_import (argv [command_index + 1]);
-		} else {
-			status = false;
-			usage_message ();
-		}
+    } else if ("import" == command) {
+        // Usage: ecosconfig import <filename>
+        if (command_index + 1 == argc) {
+            status = exec.cmd_import (argv [command_index]);
+        } else {
+            usage_message ();
+        }
 
-	} else {
-		status = false;
-		usage_message ();
-	}
+    } else {
+        usage_message ();
+    }
 
-	return status ? EXIT_SUCCESS : EXIT_FAILURE;
+    return status ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
 // remove the trailing directory separator from a file path if present
 std::string trim_path (const std::string input) {
-	std::string output = input;
-	if (! output.empty ()) {
-		const char last_char = output [output.size () - 1];
-		if (('\\' == last_char) || ('/' == last_char)) { // if the last char is a directory separator
-			output.resize (output.size () - 1); // remove the last char
-		}
-	}
-	return output;
+    std::string output = input;
+    if (! output.empty ()) {
+        const char last_char = output [output.size () - 1];
+        if (('\\' == last_char) || ('/' == last_char)) { // if the last char is a directory separator
+            output.resize (output.size () - 1); // remove the last char
+        }
+    }
+    return output;
 }
 
 // print a usage message
 void usage_message () {
-	printf ("Usage: ecosconfig [ qualifier ... ] [ command ]\n");
-	printf ("  commands are:\n");
-	printf ("    list                                       : list repository contents\n");
-	printf ("    new TARGET [ TEMPLATE [ VERSION ] ]        : create a configuration\n");
-	printf ("    target TARGET                              : change the target hardware\n");
-	printf ("    template TEMPLATE [ VERSION ]              : change the template\n");
-	printf ("    add PACKAGE [ PACKAGE ... ]                : add package(s)\n");
-	printf ("    remove PACKAGE [ PACKAGE ... ]             : remove package(s)\n");
-	printf ("    version VERSION PACKAGE [ PACKAGE ... ]    : change version of package(s)\n");
-	printf ("    export FILE                                : export minimal config info\n");
-	printf ("    import FILE                                : import additional config info\n");
-	printf ("    check                                      : check the configuration\n");
-	printf ("    resolve                                    : resolve conflicts\n");
-	printf ("    tree                                       : create a build tree\n");
-	printf ("  qualifiers are:\n");
-	printf ("    --config=FILE                              : the configuration file\n");
-	printf ("    --prefix=DIRECTORY                         : the install prefix\n");
-	printf ("    --srcdir=DIRECTORY                         : the source repository\n");
-	printf ("    --no-resolve                               : disable conflict resolution\n");
-	printf ("    --version                                  : show version and copyright\n");
+    printf ("Usage: ecosconfig [ qualifier ... ] [ command ]\n");
+    printf ("  commands are:\n");
+    printf ("    list                                       : list repository contents\n");
+    printf ("    new TARGET [ TEMPLATE [ VERSION ] ]        : create a configuration\n");
+    printf ("    target TARGET                              : change the target hardware\n");
+    printf ("    template TEMPLATE [ VERSION ]              : change the template\n");
+    printf ("    add PACKAGE [ PACKAGE ... ]                : add package(s)\n");
+    printf ("    remove PACKAGE [ PACKAGE ... ]             : remove package(s)\n");
+    printf ("    version VERSION PACKAGE [ PACKAGE ... ]    : change version of package(s)\n");
+    printf ("    export FILE                                : export minimal config info\n");
+    printf ("    import FILE                                : import additional config info\n");
+    printf ("    check                                      : check the configuration\n");
+    printf ("    resolve                                    : resolve conflicts\n");
+    printf ("    tree                                       : create a build tree\n");
+    printf ("  qualifiers are:\n");
+    printf ("    --config=FILE                              : the configuration file\n");
+    printf ("    --prefix=DIRECTORY                         : the install prefix\n");
+    printf ("    --srcdir=DIRECTORY                         : the source repository\n");
+    printf ("    --no-resolve                               : disable conflict resolution\n");
+    printf ("    --version                                  : show version and copyright\n");
+    printf ("    -q, --quiet                                : reduce verbosity\n");    
+    printf ("    -v, --verbose                              : increase verbosity\n");    
+    printf ("    -i, --ignore-errors                        : ignore unresolved conflicts\n");
+    printf ("    --help                                     : display this message\n");
 }
diff --git a/host/tools/configtool/standalone/win32/Configtool.rc b/host/tools/configtool/standalone/win32/Configtool.rc
index 4a83d8aa1..05f7eb7ba 100644
--- a/host/tools/configtool/standalone/win32/Configtool.rc
+++ b/host/tools/configtool/standalone/win32/Configtool.rc
@@ -158,7 +158,7 @@ BEGIN
         POPUP "Red Hat on the &Web"
         BEGIN
             MENUITEM "&Red Hat Home Page",          ID_HELP_RED_HATONTHEWEB
-            MENUITEM "&eCos Services Page",         ID_HELP_ECOSHOME
+            MENUITEM "&eCos Product Page",         ID_HELP_ECOSHOME
             MENUITEM "eCos &Net Release Page",      ID_HELP_ECOS
             MENUITEM SEPARATOR
             MENUITEM "µ&ITRON Specification",       ID_HELP_UITRON
diff --git a/packages/ChangeLog b/packages/ChangeLog
index 1ee876232..880f27623 100644
--- a/packages/ChangeLog
+++ b/packages/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-23  Jesper Skov  <jskov@redhat.com>
+
+	* ecos.db: Added CqREEK serial package.
+
 2000-06-22  Jesper Skov  <jskov@redhat.com>
 
 	* ecos.db: Added io_wallclock alias.
diff --git a/packages/NEWS b/packages/NEWS
index 95ebcd104..71772b0c1 100644
--- a/packages/NEWS
+++ b/packages/NEWS
@@ -9,7 +9,7 @@
 * Serial device drivers added for systems based on NEC V850 SA1 (70F3017)
   or SB1 (70F3033) processors
 * Hitachi SH3 CqREEK (cq7708) platform HAL support added
-  Contributed by Haruki Kashiwaya [Still untested, serial not imported]
+  Contributed by Haruki Kashiwaya
 * Watchdog reworked much like wallclock.
   Common code and API in io/watchdog, simpler (smaller) low-level drivers in
   devs/watchdog/<arch>.
diff --git a/packages/devs/eth/arm/ebsa285/current/ChangeLog b/packages/devs/eth/arm/ebsa285/current/ChangeLog
index e966cb378..74502f10c 100644
--- a/packages/devs/eth/arm/ebsa285/current/ChangeLog
+++ b/packages/devs/eth/arm/ebsa285/current/ChangeLog
@@ -1,3 +1,24 @@
+2000-06-27  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* cdl/ebsa285_eth_drivers.cdl: Add sesquipedalian option
+	CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS in (now)
+	component CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS to control
+	keeping (well, harvesting really) the i82559's internal stats.
+	Reputedly, it doesn't service the net whilst this is happening, so
+	it could be viewed a bad thing.  Hence the option.
+
+	* include/ebsa285_info.h: Only describe the I82559_COUNTERS
+	i82559_counters[2]; structs if full stats are to be kept.
+
+	* src/if_ebsa285.c (update_statistics): Only include this if full
+	stats are to be kept.
+
+2000-06-27  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* src/if_ebsa285.c (ResetRxRing): Re-do the management of the
+	RxRing; have an end-of-list flag (EL) in the last entry, and as
+	you unload filled slots, drag it round after you.
+
 2000-06-14  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* cdl/ebsa285_eth_drivers.cdl: Add option to control statistics
diff --git a/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl b/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl
index 3eae3dbc4..fc1c1691c 100644
--- a/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl
+++ b/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl
@@ -83,7 +83,7 @@ cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 {
 	    connection."
     }
 
-    cdl_option CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS {
+    cdl_component CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS {
 	display "Keep Ethernet statistics"
 	default_value 1
 	description   "
@@ -92,6 +92,18 @@ cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 {
 	    for network management.  SNMP for example uses this
 	    information.  There is some performance cost in maintaining
 	    this information; disable this option to recoup that."
+
+	cdl_option CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS {
+	    display "Keep i82559 Internal statistics"
+	    default_value 1
+	    description   "
+	        The i82559 keeps internal counters, and it is possible to
+	        acquire these.  But the i82559 (reputedly) does not service
+	        the network whilst uploading the data to RAM from its
+	        internal registers.  If throughput is a problem, disable
+	        this option to acquire only those statistics gathered by
+	        software, so that the i82559 never sleeps."
+	}
     }
 
     cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM {
diff --git a/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h b/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h
index 7a76c7b3c..0a244a9d5 100644
--- a/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h
+++ b/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h
@@ -97,7 +97,9 @@ typedef struct {
 
 
 extern STATISTICS statistics[2];
+#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS
 extern I82559_COUNTERS i82559_counters[2];
+#endif
 
 #endif // KEEP_STATISTICS
 
@@ -183,7 +185,7 @@ void update_statistics(struct i82559* p_i82559);
 #endif
 
 
-#ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS
 #define ETH_STATS_INIT( p ) \
         int _tmp;           \
         update_statistics( (struct i82559 *)((p)->driver_private) )
@@ -223,6 +225,7 @@ void update_statistics(struct i82559* p_i82559);
  (statistics[ ((struct i82559 *)((p)->driver_private))->index \
      ].tx_dropped)
 
+#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS
 #define ETH_DEV_STATSALIGNMENTERRORS( p ) \
  (i82559_counters[ ((struct i82559 *)((p)->driver_private))->index  \
      ].rx_align_errors)
@@ -277,6 +280,7 @@ void update_statistics(struct i82559* p_i82559);
 // (i82559_counters[ ((struct i82559 *)((p)->driver_private))->index  \ 
 //     ].)
 
+#endif // CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS
 
 #endif // KEEP_STATISTICS
 
diff --git a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
index 97908db85..001dc31cb 100644
--- a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
+++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
@@ -242,7 +242,10 @@ static inline cyg_uint32 bus_to_virt(cyg_uint32 p_memory)
 //
 // ------------------------------------------------------------------------
 typedef struct rfd {
-    volatile cyg_uint32 status;         // result of receive operation
+    volatile union {
+        cyg_uint32 u32_status;         // result of receive operation
+        cyg_uint16 u16_status[2];
+    } u_status;
     volatile cyg_uint32 link;           // offset from RU base to next RFD
     volatile cyg_uint32 rdb_address;    // pointer to Rx data buffer
     volatile cyg_uint32 count:14,       // number of bytes received +
@@ -252,6 +255,16 @@ typedef struct rfd {
     volatile cyg_uint8 buffer[0];       // data buffer (simple mode)
 } RFD;
 
+// The status is split into two shorts to get atomic access to the EL bit;
+// the upper word is not written by the device, so we can just hit it,
+// leaving the lower word (which the device updates) alone.  Otherwise
+// there's a race condition between software moving the end-of-list (EL)
+// bit round and the device writing into the previous slot.
+
+#define rxstatus    u_status.u32_status
+#define rxstatus_hi u_status.u16_status[1]
+#define rxstatus_lo u_status.u16_status[0]
+
 #define RFD_STATUS_EL   0x80000000      // 1=last RFD in RFA
 #define RFD_STATUS_S    0x40000000      // 1=suspend RU after receiving frame
 #define RFD_STATUS_H    0x00100000      // 1=RFD is a header RFD
@@ -259,6 +272,14 @@ typedef struct rfd {
 #define RFD_STATUS_C    0x00008000      // completion of received frame
 #define RFD_STATUS_OK   0x00002000      // frame received with no errors
 
+#define RFD_STATUS_HI_EL   0x8000       // 1=last RFD in RFA
+#define RFD_STATUS_HI_S    0x4000       // 1=suspend RU after receiving frame
+#define RFD_STATUS_HI_H    0x0010       // 1=RFD is a header RFD
+#define RFD_STATUS_HI_SF   0x0008       // 0=simplified, 1=flexible mode
+
+#define RFD_STATUS_LO_C    0x8000       // completion of received frame
+#define RFD_STATUS_LO_OK   0x2000       // frame received with no errors
+
 #define RFD_RX_CRC          0x00000800  // crc error
 #define RFD_RX_ALIGNMENT    0x00000400  // alignment error
 #define RFD_RX_RESOURCE     0x00000200  // out of space, no resources
@@ -288,7 +309,7 @@ typedef struct rbd {
 //
 // ------------------------------------------------------------------------
 typedef struct txcb {
-    volatile cyg_uint32 status:16,      // result of transmit operation
+    volatile cyg_uint32 txstatus:16,      // result of transmit operation
         command:16;                     // transmit command
     volatile cyg_uint32 link;           // offset from RU base to next RFD
     volatile cyg_uint32 tbd_address;    // pointer to Rx data buffer
@@ -931,6 +952,7 @@ static void i82559_start( struct eth_drv_sc *sc,
     ioaddr = p_i82559->io_address; // get 82559's I/O address
 
 #ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS
     p_i82559->p_statistics =
         p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS));
     memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS));
@@ -941,6 +963,7 @@ static void i82559_start( struct eth_drv_sc *sc,
 
     wait_for_cmd_done(ioaddr); // make sure no command operating
     OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump
+#endif
 #endif
 
     // Set the base address
@@ -1075,7 +1098,7 @@ static void ResetRxRing(struct i82559* p_i82559)
         CYG_ASSERT( p_i82559->rx_ring[
                  ( i ? (i-1) : (MAX_RX_DESCRIPTORS-1) )
             ]->link == VIRT_TO_BUS(p_rfd), "rfd linked list broken" );
-        p_rfd->status = 0;
+        p_rfd->rxstatus = 0;
         p_rfd->count = 0;
         p_rfd->f = 0;
         p_rfd->eof = 0;
@@ -1083,6 +1106,8 @@ static void ResetRxRing(struct i82559* p_i82559)
         p_rfd->size = MAX_RX_PACKET_SIZE;
     }
     p_i82559->next_rx_descriptor = 0;
+    // And set an end-of-list marker in the previous one.
+    p_rfd->rxstatus = RFD_STATUS_EL;
 }
 
 // ------------------------------------------------------------------------
@@ -1113,8 +1138,8 @@ static void PacketRxReady(struct i82559* p_i82559)
     CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
     CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
 
-    while ( p_rfd->status & RFD_STATUS_C ) {
-        p_rfd->status |= RFD_STATUS_EL;
+    while ( p_rfd->rxstatus & RFD_STATUS_C ) {
+        p_rfd->rxstatus_hi |= RFD_STATUS_HI_EL;
         length = p_rfd->count;
 
 #ifdef DEBUG_82559
@@ -1130,7 +1155,18 @@ static void PacketRxReady(struct i82559* p_i82559)
         p_rfd->count = 0;
         p_rfd->f = 0;
         p_rfd->eof = 0;
-        p_rfd->status = 0;
+        p_rfd->rxstatus_lo = 0;
+
+        // The just-emptied slot is now ready for re-use and already marked EL;
+        // we can now remove the EL marker from the previous one.
+        if ( 0 == next_descriptor )
+            p_rfd = p_i82559->rx_ring[ MAX_RX_DESCRIPTORS-1 ];
+        else
+            p_rfd = p_i82559->rx_ring[ next_descriptor-1 ];
+        // The previous one: check it *was* marked before clearing.
+        CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No prev EL" );
+        p_rfd->rxstatus_hi = 0; // that word is not written by the device.
+
 #ifdef KEEP_STATISTICS
         statistics[p_i82559->index].rx_deliver++;
 #endif
@@ -1154,6 +1190,9 @@ static void PacketRxReady(struct i82559* p_i82559)
 #ifdef KEEP_STATISTICS
         statistics[p_i82559->index].rx_restart++;
 #endif
+        // There's an end-of-list marker out there somewhere...
+        // So mop it up; it takes a little time but this is infrequent.
+        ResetRxRing( p_i82559 );  
         next_descriptor = 0;        // re-initialize next desc.
         // wait for SCB command complete
         wait_for_cmd_done(ioaddr);
@@ -1195,17 +1234,20 @@ static void i82559_recv( struct eth_drv_sc *sc,
     CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
     CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
 
-    CYG_ASSERT( p_rfd->status & RFD_STATUS_C, "No complete frame" );
-    CYG_ASSERT( p_rfd->status & RFD_STATUS_EL, "No marked frame" );
+    CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_C, "No complete frame" );
+    CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_EL, "No marked frame" );
+
+    CYG_ASSERT( p_rfd->rxstatus_lo & RFD_STATUS_LO_C, "No complete frame 2" );
+    CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No marked frame 2" );
     
-    if ( 0 == (p_rfd->status & RFD_STATUS_C) )
+    if ( 0 == (p_rfd->rxstatus & RFD_STATUS_C) )
         return;
         
     total_len = p_rfd->count;
     
 #ifdef DEBUG_82559
     os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",
-              p_i82559->index, (int)p_i82559, p_rfd->status, sg_len, total_len);
+              p_i82559->index, (int)p_i82559, p_rfd->rxstatus, sg_len, total_len);
 #endif
 
     // Copy the data to the network stack
@@ -1292,7 +1334,7 @@ static void ResetTxRing(struct i82559* p_i82559)
         CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
         CYG_ASSERT( (cyg_uint8 *)p_txcb <  i82559_heap_free, "txcb over" );
 
-        p_txcb->status = 0;
+        p_txcb->txstatus = 0;
         p_txcb->command = 0;
         p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb);
         p_txcb->tbd_address = 0xFFFFFFFF;
@@ -1385,7 +1427,7 @@ static void TxDone(struct i82559* p_i82559)
     // the remove one if the queue is full AND its status is nonzero:
     while (  (tx_descriptor_remove != p_i82559->tx_descriptor_active) ||
              ( p_i82559->tx_queue_full &&
-              (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->status) ) ) {
+              (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->txstatus) ) ) {
         unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ];
 #ifdef DEBUG_82559
         os_printf("TxDone %d %x: KEY %x\n",
@@ -1491,7 +1533,7 @@ i82559_send(struct eth_drv_sc *sc,
         CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
         CYG_ASSERT( (cyg_uint8 *)p_txcb <  i82559_heap_free, "txcb over" );
 
-        p_txcb->status = 0;
+        p_txcb->txstatus = 0;
         p_txcb->command = TxCB_CMD_TRANSMIT | TxCB_CMD_S
                                 | TxCB_CMD_I | TxCB_CMD_EL;
         p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb);
@@ -2304,6 +2346,7 @@ static int i82559_ioctl(struct eth_drv_sc *sc, unsigned long key,
 // ------------------------------------------------------------------------
 
 #ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS
 void update_statistics(struct i82559* p_i82559)
 {
     I82559_COUNTERS *p_statistics;
@@ -2335,6 +2378,7 @@ void update_statistics(struct i82559* p_i82559)
     Acknowledge82559Interrupt(p_i82559);
     UnMask82559Interrupt(p_i82559);
 }
+#endif
 #endif // KEEP_STATISTICS
 
 // ------------------------------------------------------------------------
@@ -2347,7 +2391,7 @@ void update_statistics(struct i82559* p_i82559)
 void dump_txcb(TxCB *p_txcb)
 {
     os_printf("TxCB @ %x\n", (int)p_txcb);
-    os_printf("status = %04X ", p_txcb->status);
+    os_printf("status = %04X ", p_txcb->txstatus);
     os_printf("command = %04X ", p_txcb->command);
     os_printf("link = %08X ", p_txcb->link);
     os_printf("tbd = %08X ", p_txcb->tbd_address);
@@ -2461,9 +2505,9 @@ void DisplayStatistics(void)
 
 void dump_rfd(RFD *p_rfd, int anyway )
 {
-    if ( (0 != p_rfd->status) || anyway ) {
+    if ( (0 != p_rfd->rxstatus) || anyway ) {
         os_printf("RFD @ %x = ", (int)p_rfd);
-        os_printf("status = %x ", p_rfd->status);
+        os_printf("status = %x ", p_rfd->rxstatus);
         os_printf("link = %x ", p_rfd->link);
 //        os_printf("rdb_address = %x ", p_rfd->rdb_address);
         os_printf("count = %x ", p_rfd->count);
diff --git a/packages/devs/serial/sh/cq7708/current/ChangeLog b/packages/devs/serial/sh/cq7708/current/ChangeLog
new file mode 100644
index 000000000..ee3f8f71b
--- /dev/null
+++ b/packages/devs/serial/sh/cq7708/current/ChangeLog
@@ -0,0 +1,32 @@
+2000-06-23  Jesper Skov  <jskov@redhat.com>
+
+
+	* Imported sources contributed by Haruki Kashiwaya
+	(kashiwaya at redhat dot com). Still need to fix this to properly
+	share the driver with the EDK (and any other platform using SCI).
+
+//===========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//===========================================================================
diff --git a/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl b/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl
new file mode 100644
index 000000000..b6cf54fc2
--- /dev/null
+++ b/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl
@@ -0,0 +1,136 @@
+# ====================================================================
+#
+#      ser_sh_cq7708.cdl
+#
+#      eCos serial SH/CQ7708 configuration data
+#
+# ====================================================================
+#####COPYRIGHTBEGIN####
+#                                                                          
+# -------------------------------------------                              
+# The contents of this file are subject to the Red Hat eCos Public License 
+# Version 1.1 (the "License"); you may not use this file except in         
+# compliance with the License.  You may obtain a copy of the License at    
+# http://www.redhat.com/                                                   
+#                                                                          
+# Software distributed under the License is distributed on an "AS IS"      
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+# License for the specific language governing rights and limitations under 
+# the License.                                                             
+#                                                                          
+# The Original Code is eCos - Embedded Configurable Operating System,      
+# released September 30, 1998.                                             
+#                                                                          
+# The Initial Developer of the Original Code is Red Hat.                   
+# Portions created by Red Hat are                                          
+# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Contributors:
+# Date:           1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_CQ7708 {
+    display       "SH3 cq7708 serial device drivers"
+
+    parent        CYGPKG_IO_SERIAL_DEVICES
+    active_if     CYGPKG_IO_SERIAL
+    active_if     CYGPKG_HAL_SH_SH7708_CQ7708
+
+    requires      CYGPKG_ERROR
+    include_dir   cyg/io
+    include_files ; # none _exported_ whatsoever
+    description   "
+           This option enables the serial device drivers for the
+           CQ SH3 cq7708 board."
+    doc           redirect/ecos-device-drivers.html
+
+
+    define_proc {
+        puts $::cdl_system_header "/***** serial driver proc output start *****/"
+        puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_sh_cq7708.h>"
+        puts $::cdl_system_header "/*****  serial driver proc output end  *****/"
+    }
+
+cdl_component CYGPKG_IO_SERIAL_SH_CQ7708_SCI {
+    display       "SH3 CQ7708 SCI device driver"
+    flavor        bool
+    default_value 1
+    description   "
+        This option includes the serial device driver for the SCI port."
+
+    compile       -library=libextras.a   sh_sci_serial.c
+
+    cdl_option CYGDAT_IO_SERIAL_SH_CQ7708_SCI_NAME {
+        display       "Device name for SH3 CQ7708 SCI"
+        flavor        data
+        default_value {"\"/dev/ser1\""}
+        description   "
+            This option specifies the device name for the SCI port."
+    }
+
+    cdl_option CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BAUD {
+        display       "Baud rate for the SH SCI driver"
+        flavor        data
+        legal_values  { 4800 9600 14400 19200 38400 57600 115200 }
+        default_value 38400
+        description   "
+            This option specifies the default baud rate (speed) for the 
+            SCI port."
+    }
+
+    cdl_option CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BUFSIZE {
+        display       "Buffer size for the SH SCI driver"
+        flavor        data
+        legal_values  0 to 8192
+        default_value 128
+        description   "
+            This option specifies the size of the internal buffers used for
+            the SCI port."
+    }
+}
+
+    cdl_component CYGPKG_IO_SERIAL_SH_CQ7708_OPTIONS {
+        display "Serial device driver build options"
+        flavor  none
+        description   "
+	    Package specific build options including control over
+	    compiler flags used only in building this package,
+	    and details of which tests are built."
+
+
+        cdl_option CYGPKG_IO_SERIAL_SH_CQ7708_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building these serial device drivers. These flags are used in addition
+                to the set of global flags."
+        }
+
+        cdl_option CYGPKG_IO_SERIAL_SH_CQ7708_CFLAGS_REMOVE {
+            display "Suppressed compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building these serial device drivers. These flags are removed from
+                the set of global flags if present."
+        }
+    }
+}
+
+# EOF ser_sh_cq7708.cdl
diff --git a/packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl b/packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl
new file mode 100644
index 000000000..6a70d790b
--- /dev/null
+++ b/packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl
@@ -0,0 +1,98 @@
+//==========================================================================
+//
+//      io/serial/sh/sh_sci_cq7708.c
+//
+//      Serial I/O Interface Module definitions for SH3/CQ7708
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:jskov
+// Date:        1999-06-16
+// Purpose:     Defines SCI serial resources for SH3/CQ7708.
+// Description: 
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Controller bases in the SH3/CQ7708 (only one)
+#define SH_SERIAL_SCI_BASE       0xfffffe80
+
+// The SCI controller register layout on the SH3/CQ7708.
+#define SCI_SCSMR                0      // serial mode register
+#define SCI_SCBRR                2      // bit rate register
+#define SCI_SCSCR                4      // serial control register
+#define SCI_SCTDR                6      // transmit data register
+#define SCI_SCSSR                8      // serial status register
+#define SCI_SCRDR                10     // receive data register
+#define SCI_SCSPTR               -4     // serial port register
+
+static sh_sci_info sh_serial_info = {CYGARC_REG_SCSPTR,
+                                     CYGNUM_HAL_INTERRUPT_SCI_ERI,
+                                     CYGNUM_HAL_INTERRUPT_SCI_RXI,
+                                     CYGNUM_HAL_INTERRUPT_SCI_TXI,
+                                     SH_SERIAL_SCI_BASE};
+
+#if CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BUFSIZE > 0
+static unsigned char sh_serial_out_buf[CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BUFSIZE];
+static unsigned char sh_serial_in_buf[CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sh_serial_channel,
+                                       sh_serial_funs, 
+                                       sh_serial_info,
+                                       CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BAUD),
+                                       CYG_SERIAL_STOP_DEFAULT,
+                                       CYG_SERIAL_PARITY_DEFAULT,
+                                       CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                                       CYG_SERIAL_FLAGS_DEFAULT,
+                                       &sh_serial_out_buf[0], 
+                                       sizeof(sh_serial_out_buf),
+                                       &sh_serial_in_buf[0],  
+                                       sizeof(sh_serial_in_buf)
+    );
+#else
+static SERIAL_CHANNEL(sh_serial_channel,
+                      sh_serial_funs, 
+                      sh_serial_info,
+                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BAUD),
+                      CYG_SERIAL_STOP_DEFAULT,
+                      CYG_SERIAL_PARITY_DEFAULT,
+                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                      CYG_SERIAL_FLAGS_DEFAULT
+    );
+#endif
+
+DEVTAB_ENTRY(sh_serial_io,
+             CYGDAT_IO_SERIAL_SH_CQ7708_SCI_NAME,
+             0,                 // Does not depend on a lower level interface
+             &cyg_io_serial_devio, 
+             sh_serial_init, 
+             sh_serial_lookup,          // Serial driver may need initializing
+             &sh_serial_channel
+    );
+
diff --git a/packages/devs/serial/sh/cq7708/current/src/sh_sci_serial.c b/packages/devs/serial/sh/cq7708/current/src/sh_sci_serial.c
new file mode 100644
index 000000000..976fbb36f
--- /dev/null
+++ b/packages/devs/serial/sh/cq7708/current/src/sh_sci_serial.c
@@ -0,0 +1,496 @@
+//==========================================================================
+//
+//      io/serial/sh/sh_sci_serial.c
+//
+//      SH Serial SCI I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:gthomas, jskov
+// Date:        1999-05-24
+// Purpose:     SH Serial I/O module (interrupt driven version)
+// Description: 
+//
+// Note: Since interrupt sources from the same SCI channel share the same
+//       interrupt level, there is no risk of races when altering the
+//       channel's control register from ISRs and DSRs. However, when 
+//       altering the control register from user-level code, interrupts
+//       must be disabled while the register is being accessed.
+//
+// FIXME: Receiving in polled mode prevents duplex transfers from working for
+//        some reason.
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+#include <cyg/hal/sh_regs.h>
+
+#ifdef CYGPKG_IO_SERIAL_SH_CQ7708
+#define __CYGPKG_IO_SERIAL_SH_SCI_INL "sh_sci_cq7708.inl"
+#endif
+
+
+// Only compile driver if an inline file with driver details was selected.
+#ifdef __CYGPKG_IO_SERIAL_SH_SCI_INL
+
+static short select_word_length[] = {
+    -1,
+    -1,
+    CYGARC_REG_SCSMR_CHR,               // 7 bits
+    0                                   // 8 bits
+};
+
+static short select_stop_bits[] = {
+    -1,
+    0,                                  // 1 stop bit
+    -1,
+    CYGARC_REG_SCSMR_STOP               // 2 stop bits
+};
+
+static short select_parity[] = {
+    0,                                  // No parity
+    CYGARC_REG_SCSMR_PE,                // Even parity
+    CYGARC_REG_SCSMR_PE|CYGARC_REG_SCSMR_OE, // Odd parity
+    -1,
+    -1
+};
+
+static unsigned short select_baud[] = {
+    0,    // Unused
+    CYGARC_SCBRR_CKSx(50)<<8 | CYGARC_SCBRR_N(50),
+    CYGARC_SCBRR_CKSx(75)<<8 | CYGARC_SCBRR_N(75),
+    CYGARC_SCBRR_CKSx(110)<<8 | CYGARC_SCBRR_N(110),
+    CYGARC_SCBRR_CKSx(134)<<8 | CYGARC_SCBRR_N(134),
+    CYGARC_SCBRR_CKSx(150)<<8 | CYGARC_SCBRR_N(150),
+    CYGARC_SCBRR_CKSx(200)<<8 | CYGARC_SCBRR_N(200),
+    CYGARC_SCBRR_CKSx(300)<<8 | CYGARC_SCBRR_N(300),
+    CYGARC_SCBRR_CKSx(600)<<8 | CYGARC_SCBRR_N(600),
+    CYGARC_SCBRR_CKSx(1200)<<8 | CYGARC_SCBRR_N(1200),
+    CYGARC_SCBRR_CKSx(1800)<<8 | CYGARC_SCBRR_N(1800),
+    CYGARC_SCBRR_CKSx(2400)<<8 | CYGARC_SCBRR_N(2400),
+    CYGARC_SCBRR_CKSx(3600)<<8 | CYGARC_SCBRR_N(3600),
+    CYGARC_SCBRR_CKSx(4800)<<8 | CYGARC_SCBRR_N(4800),
+    CYGARC_SCBRR_CKSx(7200)<<8 | CYGARC_SCBRR_N(7200),
+    CYGARC_SCBRR_CKSx(9600)<<8 | CYGARC_SCBRR_N(9600),
+    CYGARC_SCBRR_CKSx(14400)<<8 | CYGARC_SCBRR_N(14400),
+    CYGARC_SCBRR_CKSx(19200)<<8 | CYGARC_SCBRR_N(19200),
+    CYGARC_SCBRR_CKSx(38400)<<8 | CYGARC_SCBRR_N(38400),
+    CYGARC_SCBRR_CKSx(57600)<<8 | CYGARC_SCBRR_N(57600),
+    CYGARC_SCBRR_CKSx(115200)<<8 | CYGARC_SCBRR_N(115200),
+    CYGARC_SCBRR_CKSx(230400)<<8 | CYGARC_SCBRR_N(230400)
+};
+
+
+typedef struct sh_sci_info {
+    CYG_ADDRWORD   data;                // Pointer to data register
+    
+    CYG_WORD       er_int_num,          // Error interrupt number
+                   rx_int_num,          // Receive interrupt number
+                   tx_int_num;          // Transmit interrupt number
+
+    CYG_ADDRWORD   ctrl_base;           // Base address of SCI controller
+
+    cyg_interrupt  serial_er_interrupt, 
+                   serial_rx_interrupt, 
+                   serial_tx_interrupt;
+    cyg_handle_t   serial_er_interrupt_handle, 
+                   serial_rx_interrupt_handle, 
+                   serial_tx_interrupt_handle;
+
+    bool           tx_enabled;
+} sh_sci_info;
+
+static bool sh_serial_init(struct cyg_devtab_entry *tab);
+static bool sh_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo sh_serial_lookup(struct cyg_devtab_entry **tab, 
+                                   struct cyg_devtab_entry *sub_tab,
+                                   const char *name);
+static unsigned char sh_serial_getc(serial_channel *chan);
+static bool sh_serial_set_config(serial_channel *chan, cyg_serial_info_t *config);
+static void sh_serial_start_xmit(serial_channel *chan);
+static void sh_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void       sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, 
+                                   cyg_addrword_t data);
+static cyg_uint32 sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void       sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, 
+                                   cyg_addrword_t data);
+static cyg_uint32 sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void       sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, 
+                                   cyg_addrword_t data);
+
+static SERIAL_FUNS(sh_serial_funs, 
+                   sh_serial_putc, 
+                   sh_serial_getc,
+                   sh_serial_set_config,
+                   sh_serial_start_xmit,
+                   sh_serial_stop_xmit
+    );
+
+#include __CYGPKG_IO_SERIAL_SH_SCI_INL
+
+// Internal function to actually configure the hardware to desired baud rate,
+// etc.
+static bool
+sh_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, 
+                      bool init)
+{
+    cyg_uint16 baud_divisor = select_baud[new_config->baud];
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    cyg_uint8 _scr, _smr;
+
+    // Check configuration request
+    if ((-1 == select_word_length[(new_config->word_length -
+                                  CYGNUM_SERIAL_WORD_LENGTH_5)])
+        || -1 == select_stop_bits[new_config->stop]
+        || -1 == select_parity[new_config->parity]
+        || baud_divisor == 0)
+        return false;
+
+    // Disable SCI interrupts while changing hardware
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, 0);
+
+    // Set databits, stopbits and parity.
+    _smr = select_word_length[(new_config->word_length -
+                               CYGNUM_SERIAL_WORD_LENGTH_5)] | 
+        select_stop_bits[new_config->stop] |
+        select_parity[new_config->parity];
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr);
+
+    // Set baud rate.
+    _smr &= ~CYGARC_REG_SCSMR_CKSx_MASK;
+    _smr |= baud_divisor >> 8;
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr);
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCBRR, baud_divisor & 0xff);
+
+    // Clear the status register.
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 0);
+
+    if (init) {
+        // Always enable transmitter and receiver.
+        _scr = CYGARC_REG_SCSCR_TE | CYGARC_REG_SCSCR_RE;
+
+        if (chan->out_cbuf.len != 0)
+            _scr |= CYGARC_REG_SCSCR_TIE; // enable tx interrupts
+
+        if (chan->in_cbuf.len != 0)
+            _scr |= CYGARC_REG_SCSCR_RIE; // enable rx interrupts
+    }
+     
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+    if (new_config != &chan->config) {
+        chan->config = *new_config;
+    }
+    return true;
+}
+
+// Function to initialize the device.  Called at bootstrap time.
+static bool 
+sh_serial_init(struct cyg_devtab_entry *tab)
+{
+    serial_channel *chan = (serial_channel *)tab->priv;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+    diag_printf("SH SERIAL init - dev: %x.%d\n", 
+                sh_chan->data, sh_chan->rx_int_num);
+#endif
+    // Really only required for interrupt driven devices
+    (chan->callbacks->serial_init)(chan);
+
+    if (chan->out_cbuf.len != 0) {
+        cyg_drv_interrupt_create(sh_chan->tx_int_num,
+                                 3,
+                                 (cyg_addrword_t)chan, // Data item passed to interrupt handler
+                                 sh_serial_tx_ISR,
+                                 sh_serial_tx_DSR,
+                                 &sh_chan->serial_tx_interrupt_handle,
+                                 &sh_chan->serial_tx_interrupt);
+        cyg_drv_interrupt_attach(sh_chan->serial_tx_interrupt_handle);
+        cyg_drv_interrupt_unmask(sh_chan->tx_int_num);
+        sh_chan->tx_enabled = false;
+    }
+    if (chan->in_cbuf.len != 0) {
+        // Receive interrupt
+        cyg_drv_interrupt_create(sh_chan->rx_int_num,
+                                 3,
+                                 (cyg_addrword_t)chan, // Data item passed to interrupt handler
+                                 sh_serial_rx_ISR,
+                                 sh_serial_rx_DSR,
+                                 &sh_chan->serial_rx_interrupt_handle,
+                                 &sh_chan->serial_rx_interrupt);
+        cyg_drv_interrupt_attach(sh_chan->serial_rx_interrupt_handle);
+        // Receive error interrupt
+        cyg_drv_interrupt_create(sh_chan->er_int_num,
+                                 3,
+                                 (cyg_addrword_t)chan, // Data item passed to interrupt handler
+                                 sh_serial_er_ISR,
+                                 sh_serial_er_DSR,
+                                 &sh_chan->serial_er_interrupt_handle,
+                                 &sh_chan->serial_er_interrupt);
+        cyg_drv_interrupt_attach(sh_chan->serial_er_interrupt_handle);
+        // This unmasks both interrupt sources.
+        cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+    }
+    sh_serial_config_port(chan, &chan->config, true);
+    return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo 
+sh_serial_lookup(struct cyg_devtab_entry **tab, 
+                  struct cyg_devtab_entry *sub_tab,
+                  const char *name)
+{
+    serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+    // Really only required for interrupt driven devices
+    (chan->callbacks->serial_init)(chan);
+    return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+sh_serial_putc(serial_channel *chan, unsigned char c)
+{
+    cyg_uint8 _ssr;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+    if (_ssr & CYGARC_REG_SCSSR_TDRE) {
+// Transmit buffer is empty
+        HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCTDR, c);
+        // Clear empty flag.
+        HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 
+                        CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_TDRE);
+        return true;
+    } else {
+// No space
+        return false;
+    }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char 
+sh_serial_getc(serial_channel *chan)
+{
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    unsigned char c;
+    cyg_uint8 _ssr;
+
+    do {
+        HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+    } while ((_ssr & CYGARC_REG_SCSSR_RDRF) == 0);
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, c);
+
+    // Clear buffer full flag.
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 
+                    CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
+
+    return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static bool 
+sh_serial_set_config(serial_channel *chan, cyg_serial_info_t *config)
+{
+    return sh_serial_config_port(chan, config, false);
+}
+
+// Enable the transmitter on the device
+static void
+sh_serial_start_xmit(serial_channel *chan)
+{
+    cyg_uint8 _scr;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+    sh_chan->tx_enabled = true;
+
+    // Mask the interrupts (all sources of the unit) while changing
+    // the CR since a rx interrupt in the middle of this would result
+    // in a bad CR state.
+    cyg_drv_interrupt_mask(sh_chan->rx_int_num);
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    _scr |= CYGARC_REG_SCSCR_TIE;       // Enable xmit interrupt
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+    cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+}
+
+// Disable the transmitter on the device
+static void 
+sh_serial_stop_xmit(serial_channel *chan)
+{
+    cyg_uint8 _scr;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+    sh_chan->tx_enabled = false;
+
+    // Mask the interrupts (all sources of the unit) while changing
+    // the CR since a rx interrupt in the middle of this would result
+    // in a bad CR state.
+    cyg_drv_interrupt_mask(sh_chan->rx_int_num);
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    _scr &= ~CYGARC_REG_SCSCR_TIE;      // Disable xmit interrupt
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+    cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+}
+
+// Serial I/O - low level tx interrupt handler (ISR)
+static cyg_uint32 
+sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    cyg_uint8 _scr;
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    _scr &= ~CYGARC_REG_SCSCR_TIE;      // mask out tx interrupts
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+    return CYG_ISR_CALL_DSR;  // Cause DSR to be run
+}
+
+// Serial I/O - high level tx interrupt handler (DSR)
+static void       
+sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+    (chan->callbacks->xmt_char)(chan);
+
+    if (sh_chan->tx_enabled) {
+        cyg_uint8 _scr;
+
+        HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+        _scr |= CYGARC_REG_SCSCR_TIE;       // unmask tx interrupts
+        HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    }
+}
+
+// Serial I/O - low level RX interrupt handler (ISR)
+static cyg_uint32 
+sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    cyg_uint8 _scr;
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    _scr &= ~CYGARC_REG_SCSCR_RIE;      // mask rx interrupts
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    return CYG_ISR_CALL_DSR;  // Cause DSR to be run
+}
+
+// Serial I/O - high level rx interrupt handler (DSR)
+static void       
+sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    cyg_uint8 _ssr, _scr;
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+    if (_ssr & CYGARC_REG_SCSSR_RDRF) {
+        cyg_uint8 _c;
+        HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, _c);
+        // Clear buffer full flag.
+        HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 
+                        CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
+
+        (chan->callbacks->rcv_char)(chan, _c);
+    }
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    _scr |= CYGARC_REG_SCSCR_RIE;       // unmask rx interrupts
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+}
+
+static volatile int sh_serial_error_orer = 0;
+static volatile int sh_serial_error_fer = 0;
+static volatile int sh_serial_error_per = 0;
+
+// Serial I/O - low level error interrupt handler (ISR)
+static cyg_uint32 
+sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    cyg_uint8 _scr;
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    _scr &= ~CYGARC_REG_SCSCR_RIE;      // mask rx interrupts
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+    return CYG_ISR_CALL_DSR;  // Cause DSR to be run
+}
+
+// Serial I/O - high level error interrupt handler (DSR)
+static void       
+sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+    cyg_uint8 _ssr, _ssr2;
+
+    HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+    _ssr2 = CYGARC_REG_SCSSR_CLEARMASK;
+
+    if (_ssr & CYGARC_REG_SCSSR_ORER) {
+        _ssr2 &= ~CYGARC_REG_SCSSR_ORER;
+        sh_serial_error_orer++;
+    }
+    if (_ssr & CYGARC_REG_SCSSR_FER) {
+        _ssr2 &= ~CYGARC_REG_SCSSR_FER;
+        sh_serial_error_fer++;
+    }
+    if (_ssr & CYGARC_REG_SCSSR_PER) {
+        _ssr2 &= ~CYGARC_REG_SCSSR_PER;
+        sh_serial_error_per++;
+    }
+    HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr2);
+}
+
+#endif // ifdef __CYGPKG_IO_SERIAL_SH_SCI
+
diff --git a/packages/ecos.db b/packages/ecos.db
index df43f30aa..1c4b47507 100644
--- a/packages/ecos.db
+++ b/packages/ecos.db
@@ -208,6 +208,16 @@ package CYGPKG_IO_SERIAL_SH_EDK7708 {
     description       "SH3 EDK7708 serial device drivers"
 }
 
+package CYGPKG_IO_SERIAL_SH_CQ7708 {
+    alias             { "SH3 cq7708 serial device drivers"
+                        devs_serial_sh3_cq7708
+                        devs_serial_sh_cq7708 cq7708_serial_driver }
+    hardware
+    directory	      devs/serial/sh/cq7708
+    script	      ser_sh_cq7708.cdl	
+    description       "SH3 cq7708 serial device drivers"
+}
+
 
 package CYGPKG_IO_SERIAL_V85X_V850 {
     alias             { "NEC V850 serial device drivers"
@@ -507,7 +517,6 @@ package CYGPKG_HAL_SH_EDK7708 {
            The edk HAL package provides the support needed to run
            eCos on a Hitachi SH3 EDK7708 board."
 }
-
 package CYGPKG_HAL_SH_SH7708_CQ7708 {
         alias           { "CqREEK SH7708 board" hal_sh_cq sh_cq_hal }
         directory       hal/sh/cq7708
@@ -940,6 +949,7 @@ target cq7708 {
         alias { "CqREEK SH7708 board" cq7708 }
         packages { CYGPKG_HAL_SH
                    CYGPKG_HAL_SH_SH7708_CQ7708
+	           CYGPKG_IO_SERIAL_SH_CQ7708
         }
         enable      { CYGPKG_HAL_SH_7708 }
         description "
diff --git a/packages/hal/arm/arch/current/ChangeLog b/packages/hal/arm/arch/current/ChangeLog
index ce0c42ef2..3821cfb0b 100644
--- a/packages/hal/arm/arch/current/ChangeLog
+++ b/packages/hal/arm/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_mk_defs.c:
+	* src/arm_stub.c: 
+	Fix compiler warnings.
+
 2000-06-19  Gary Thomas  <gthomas@redhat.com>
 
 	* src/vectors.S: Changes for virtual vector support.
diff --git a/packages/hal/arm/arch/current/src/arm_stub.c b/packages/hal/arm/arch/current/src/arm_stub.c
index 1b85acffe..36714a88d 100644
--- a/packages/hal/arm/arch/current/src/arm_stub.c
+++ b/packages/hal/arm/arch/current/src/arm_stub.c
@@ -553,33 +553,6 @@ static instrBuffer break_buffer;
 
 volatile int cyg_hal_gdb_running_step = 0;
 
-void 
-cyg_hal_gdb_interrupt (target_register_t pc)
-{
-    // Clear flag that we Continued instead of Stepping
-    cyg_hal_gdb_running_step = 0;
-    // and override existing break? So that a ^C takes effect...
-    if (0 != break_buffer.targetAddr)
-        cyg_hal_gdb_remove_break( break_buffer.targetAddr );
-
-    if (0 == break_buffer.targetAddr) {
-        cyg_uint32 cpsr = get_register(PS);
-
-        if (cpsr & CPSR_THUMB_ENABLE) {
-            break_buffer.targetAddr = MAKE_THUMB_ADDR((cyg_uint32)pc);
-            break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc;
-            *(cyg_uint16*)pc = HAL_BREAKINST_THUMB;
-        } else {
-            break_buffer.targetAddr = (cyg_uint32)pc;
-            break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc;
-            *(cyg_uint32*)pc = HAL_BREAKINST_ARM;
-        }
-
-        __data_cache(CACHE_FLUSH);
-        __instruction_cache(CACHE_FLUSH);
-    }
-}
-
 // This function is passed thumb/arm information about the PC address
 // in bit 0. This information is passed on to the break_buffer.
 void 
@@ -627,6 +600,33 @@ cyg_hal_gdb_remove_break (target_register_t pc)
     return 0;
 }
 
+void 
+cyg_hal_gdb_interrupt (target_register_t pc)
+{
+    // Clear flag that we Continued instead of Stepping
+    cyg_hal_gdb_running_step = 0;
+    // and override existing break? So that a ^C takes effect...
+    if (0 != break_buffer.targetAddr)
+        cyg_hal_gdb_remove_break( break_buffer.targetAddr );
+
+    if (0 == break_buffer.targetAddr) {
+        cyg_uint32 cpsr = get_register(PS);
+
+        if (cpsr & CPSR_THUMB_ENABLE) {
+            break_buffer.targetAddr = MAKE_THUMB_ADDR((cyg_uint32)pc);
+            break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc;
+            *(cyg_uint16*)pc = HAL_BREAKINST_THUMB;
+        } else {
+            break_buffer.targetAddr = (cyg_uint32)pc;
+            break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc;
+            *(cyg_uint32*)pc = HAL_BREAKINST_ARM;
+        }
+
+        __data_cache(CACHE_FLUSH);
+        __instruction_cache(CACHE_FLUSH);
+    }
+}
+
 int
 cyg_hal_gdb_break_is_set (void)
 {
diff --git a/packages/hal/arm/arch/current/src/hal_mk_defs.c b/packages/hal/arm/arch/current/src/hal_mk_defs.c
index 2344c0862..8994973c5 100644
--- a/packages/hal/arm/arch/current/src/hal_mk_defs.c
+++ b/packages/hal/arm/arch/current/src/hal_mk_defs.c
@@ -106,6 +106,8 @@ main(void)
 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT)
     DEFINE(CYGNUM_CALL_IF_TABLE_SIZE, CYGNUM_CALL_IF_TABLE_SIZE);
 #endif
+
+    return 0;
 }
 
 
diff --git a/packages/hal/common/current/ChangeLog b/packages/hal/common/current/ChangeLog
index 6aa00d8cf..e811f4e70 100644
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,30 @@
+2000-06-29  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_stub.c (cyg_hal_gdb_diag_putc): Check console interrupt
+	flag and breakpoint if set.
+
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_stub.c (cyg_hal_gdb_diag_putc): Don't try to set
+	breakpoints in ROM startup - just disable interrupts. Also, use
+	procs table function to disable device interrupts.
+
+	* include/hal_if.h: Mark vector/comms arrays volatile to avoid
+	compiler confusion.
+
+	* include/dbg-threads-api.h: Fix C/C++ declaration issues.
+
+	* src/hal_stub.c: Moved stub platform init call below vector table
+	setup.
+
+	* src/hal_misc.c:
+	* src/hal_if.c:
+	* include/hal_if.h: DBG_ISR_VECTOR and SET_TIMEOUT functions added
+	to comms table. Added DELAY_US function to vector table. Made
+	switching of debug channel dis/enable Ctrl-c interrupts as
+	well. Made ctrlc_isr code use new vector entries. All this amounts
+	to a properly switchable debug channel.
+
 2000-06-21  Jesper Skov  <jskov@redhat.com>
 
 	* src/hal_stub.c: Fixed clients of vector procs tables to pass
diff --git a/packages/hal/common/current/include/dbg-threads-api.h b/packages/hal/common/current/include/dbg-threads-api.h
index 046b0a1a3..effdd007e 100644
--- a/packages/hal/common/current/include/dbg-threads-api.h
+++ b/packages/hal/common/current/include/dbg-threads-api.h
@@ -66,21 +66,21 @@ struct dbg_capabilities
 
 
 /* fill in the list of thread aware capabilities */
-extern int dbg_thread_capabilities(struct dbg_capabilities * cbp) ;
+externC int dbg_thread_capabilities(struct dbg_capabilities * cbp) ;
 
 
 /* Fillin the identifier of the current thread */
 /* return 1 if defined, 0 if not defined */
-extern int dbg_currthread(threadref * varparm) ;
+externC int dbg_currthread(threadref * varparm) ;
 
 /* Return the unique ID number of the current thread. */
-extern int dbg_currthread_id(void);
+externC int dbg_currthread_id(void);
 
 /* get the first or next member of the list of known threads */
-extern int dbg_threadlist(int startflag,
-                          threadref * lastthreadid,
-                          threadref * next_thread
-                          ) ;
+externC int dbg_threadlist(int startflag,
+                           threadref * lastthreadid,
+                           threadref * next_thread
+    ) ;
 
 /* return 1 if next_threadid has been filled in with a value */
 /* return 0 if there are none or no more */
@@ -106,7 +106,7 @@ struct cygmon_thread_debug_info
 
 
 
-extern int dbg_threadinfo(
+externC int dbg_threadinfo(
                           threadref * threadid,
                           struct cygmon_thread_debug_info * info) ;
 
@@ -119,7 +119,7 @@ registers which are NOT in the O.S. thread context. Their default values
 have already been assigned.
 */
 
-extern int dbg_getthreadreg(
+externC int dbg_getthreadreg(
                             threadref * osthreadid, 
                             int regcount, /* count of registers in the array */
                             void * regval) ; /* fillin this array */
@@ -131,7 +131,7 @@ which are defined in the saved context of thread or process identified
 by osthreadid. Return 0 if the threadis does not map to a known
 process or other error. Return 1 if the setting is successful.  */
 
-extern int dbg_setthreadreg(
+externC int dbg_setthreadreg(
                             threadref * osthreadid, 
                             int regcount , /* number of registers */
                             void * regval) ;
diff --git a/packages/hal/common/current/include/hal_if.h b/packages/hal/common/current/include/hal_if.h
index 17bd6f97d..07f91fc58 100644
--- a/packages/hal/common/current/include/hal_if.h
+++ b/packages/hal/common/current/include/hal_if.h
@@ -51,6 +51,8 @@
 #include <cyg/hal/dbg-threads-api.h>
 #include <cyg/hal/dbg-thread-syscall.h>
 
+#include <stdarg.h>
+
 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 
 //--------------------------------------------------------------------------
@@ -93,6 +95,20 @@ typedef enum {
      * Enable comm port interrupt.
      */
     __COMMCTL_IRQ_ENABLE,
+
+    /*
+     * Returns the number of the interrupt vector used by the debug
+     * interrupt handler.
+     */
+    __COMMCTL_DBG_ISR_VECTOR,
+
+    /*
+     * Returns the current timeout value and sets a new timeout.
+     * Timeout resolution is in milliseconds.
+     *   old_timeout = (*__control)(__COMMCTL_SET_TIMEOUT, 
+     *                              cyg_int32 new_timeout);
+     */
+    __COMMCTL_SET_TIMEOUT,
 } __comm_control_cmd_t;
 
 
@@ -102,10 +118,12 @@ typedef enum {
 #define CYGNUM_COMM_IF_PUTC                       3
 #define CYGNUM_COMM_IF_GETC                       4
 #define CYGNUM_COMM_IF_CONTROL                    5
+#define CYGNUM_COMM_IF_DBG_ISR                    6
+#define CYGNUM_COMM_IF_GETC_TIMEOUT               7
 
 #define CYGNUM_COMM_IF_TABLE_SIZE                 8
 
-typedef CYG_ADDRWORD hal_virtual_comm_table_t[CYGNUM_COMM_IF_TABLE_SIZE];
+typedef volatile CYG_ADDRWORD hal_virtual_comm_table_t[CYGNUM_COMM_IF_TABLE_SIZE];
 
 // The below is a (messy) attempt at adding some type safety to the
 // above array. At the same time, the accessors allow the
@@ -151,6 +169,19 @@ typedef int (*__comm_if_control_t)(void *__ch_data,
 #define CYGACC_COMM_IF_CONTROL_SET(_t_, _x_) \
  (_t_)[CYGNUM_COMM_IF_CONTROL]=(CYG_ADDRWORD)(_x_)
 
+typedef int (*__comm_if_dbg_isr_t)(void *__ch_data, 
+                               int* __ctrlc, CYG_ADDRWORD __vector,
+                               CYG_ADDRWORD __data);
+#define CYGACC_COMM_IF_DBG_ISR(_t_) \
+ ((__comm_if_dbg_isr_t)(((_t_))[CYGNUM_COMM_IF_DBG_ISR]))
+#define CYGACC_COMM_IF_DBG_ISR_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_DBG_ISR]=(CYG_ADDRWORD)(_x_)
+
+typedef cyg_bool (*__comm_if_getc_timeout_t)(void* __ch_data, cyg_uint8* __ch);
+#define CYGACC_COMM_IF_GETC_TIMEOUT(_t_) \
+ ((__comm_if_getc_timeout_t)(((_t_))[CYGNUM_COMM_IF_GETC_TIMEOUT]))
+#define CYGACC_COMM_IF_GETC_TIMEOUT_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_GETC_TIMEOUT]=(CYG_ADDRWORD)(_x_)
 
 //--------------------------------------------------------------------------
 // Main calling interface table. Will be assigned a location by the 
@@ -175,14 +206,15 @@ typedef int (*__comm_if_control_t)(void *__ch_data,
 #define CYGNUM_CALL_IF_DBG_SYSCALL                15 // conflict!
 #define CYGNUM_CALL_IF_RESET                      16
 #define CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG     17
+#define CYGNUM_CALL_IF_DELAY_US                   18
 
-#define CYGNUM_CALL_IF_LAST_ENTRY                 CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG
+#define CYGNUM_CALL_IF_LAST_ENTRY                 CYGNUM_CALL_IF_DELAY_US
 
 #define CYGNUM_CALL_IF_INSTALL_BPT_FN             35
 
 #define CYGNUM_CALL_IF_TABLE_SIZE                 64
 
-externC CYG_ADDRWORD hal_virtual_vector_table[CYGNUM_CALL_IF_TABLE_SIZE];
+externC volatile CYG_ADDRWORD hal_virtual_vector_table[CYGNUM_CALL_IF_TABLE_SIZE];
 
 // Table version is simply the number of the last active entry in the table
 // (except INSTALL_BPT_FN since it's so high).
@@ -323,6 +355,12 @@ typedef int __call_if_console_interrupt_flag_t;
 #define CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(_x_) \
  hal_virtual_vector_table[CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG]=(CYG_ADDRWORD)(_x_)
 
+typedef void (*__call_if_delay_us_t)(cyg_int32 usecs);
+#define CYGACC_CALL_IF_DELAY_US() \
+ ((__call_if_delay_us_t)hal_virtual_vector_table[CYGNUM_CALL_IF_DELAY_US])
+#define CYGACC_CALL_IF_DELAY_US_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_DELAY_US]=(CYG_ADDRWORD)(_x_)
+
 typedef void (*__call_if_install_bpt_fn_t)(void *__epc);
 #define CYGACC_CALL_IF_INSTALL_BPT_FN() \
  ((__call_if_install_bpt_fn_t)hal_virtual_vector_table[CYGNUM_CALL_IF_INSTALL_BPT_FN])
@@ -335,13 +373,18 @@ externC void hal_if_diag_init(void);
 externC void hal_if_diag_write_char(char c);
 externC void hal_if_diag_read_char(char *c);
 
+//--------------------------------------------------------------------------
+// Ctrl-c support.
+externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+#define HAL_CTRLC_ISR hal_ctrlc_isr
+
 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 
 //--------------------------------------------------------------------------
 // Functions provided by the HAL interface.
 externC void hal_if_init(void);
 
-
 //--------------------------------------------------------------------------
 // Configuration control for the interface services.
 // When this is set, code should initialize the vector table wherever
diff --git a/packages/hal/common/current/src/hal_if.c b/packages/hal/common/current/src/hal_if.c
index a05f4f03a..b4d5a30ef 100644
--- a/packages/hal/common/current/src/hal_if.c
+++ b/packages/hal/common/current/src/hal_if.c
@@ -41,6 +41,10 @@
 
 #include <pkgconf/hal.h>
 
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+#endif
+
 #include <cyg/infra/cyg_ass.h>          // assertions
 
 #include <cyg/hal/hal_arch.h>           // set/restore GP
@@ -49,26 +53,64 @@
 #include <cyg/hal/hal_if.h>             // our interface
 
 #include <cyg/hal/hal_diag.h>           // Diag IO
+#include <cyg/hal/hal_misc.h>           // User break
 
 #include <cyg/hal/hal_stub.h>           // stub functionality
 #include <cyg/hal/plf_stub.h>           // reset entry - FIXME, should be moved
 
+#include <cyg/hal/hal_intr.h>           // hal_vsr_table and others
+
 
 //--------------------------------------------------------------------------
 
 externC void patch_dbg_syscalls(void * vector);
 externC void init_thread_syscall(void * vector);
 
-externC CYG_ADDRWORD hal_interrupt_handlers[];
-externC CYG_ADDRWORD hal_vsr_table[];
-
 //--------------------------------------------------------------------------
 // Implementations and function wrappers for monitor services
+
 #ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+static void
+delay_us(cyg_int32 usecs)
+{
+#ifdef CYGPKG_KERNEL
+    cyg_int32 start, elapsed;
+    cyg_int32 usec_ticks, slice;
+    CYGARC_HAL_SAVE_GP();
+
+    // How many ticks total we should wait for.
+    usec_ticks = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+    usec_ticks /= CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000;
+
+    do {
+        // Spin in slices of 1/2 the RTC period. Allows interrupts
+        // time to run without messing up the algorithm. If we spun
+        // for 1 period (or more) of the RTC, there'd be also problems
+        // figuring out when the timer wrapped.  We may lose a tick or
+        // two for each cycle but it shouldn't matter much.
+        slice = usec_ticks % (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD / 2);
+    
+        HAL_CLOCK_READ(&start);
+        do {
+            HAL_CLOCK_READ(&elapsed);
+            elapsed = (elapsed - start); // counts up!
+            if (elapsed < 0)
+                elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+        } while (elapsed < slice);
+
+        // Adjust by elapsed, not slice, since an interrupt may have
+        // been stalling us for some time.
+        usec_ticks -= elapsed;
+    } while (usec_ticks > 0);
+
+    CYGARC_HAL_RESTORE_GP();
+#endif
+}
 
 static void
 reset(void)
 {
+    CYGARC_HAL_SAVE_GP();
     // With luck, the platform defines some magic that will cause a hardware
     // reset.
     HAL_STUB_PLATFORM_RESET();
@@ -83,6 +125,8 @@ reset(void)
 #else
 #error " no RESET_ENTRY"
 #endif
+
+    CYGARC_HAL_RESTORE_GP();
 }
 
 // This is the system's default kill signal routine. Unless overridden
@@ -92,7 +136,11 @@ reset(void)
 static int
 kill_by_reset(int __irq_nr, void* __regs)
 {
+    CYGARC_HAL_SAVE_GP();
+
     reset();
+
+    CYGARC_HAL_RESTORE_GP();
     return 0;
 }
 
@@ -110,12 +158,14 @@ nop_service(void)
 
 static hal_virtual_comm_table_t comm_channels[CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+1];
 
-
-
 static int
 set_debug_comm(int __comm_id)
 {
     static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;
+    hal_virtual_comm_table_t* __chan;
+    int interrupt_state = 0;
+    int res = 1, update = 0;
+    CYGARC_HAL_SAVE_GP();
 
     CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER
                && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS,
@@ -124,36 +174,56 @@ set_debug_comm(int __comm_id)
     switch (__comm_id) {
     case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:
         if (__selected_id > 0)
-            return __selected_id-1;
-        if (__selected_id == 0)
-            return CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
-        return __selected_id;
+            res = __selected_id-1;
+        else if (__selected_id == 0)
+            res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
+        else 
+            res = __selected_id;
+        break;
 
     case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:
         CYGACC_CALL_IF_DEBUG_PROCS_SET(0);
         __selected_id = __comm_id;
-        return 1;
+        break;
 
     case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:
         __comm_id = 0;
+        update = 1;
         break;
 
     default:
         __comm_id++;                    // skip mangler entry
+        update = 1;
         break;
     }
-    
-    __selected_id = __comm_id;
-    
-    CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]);
 
-    return 1;
+    if (update) {
+        // Find the interrupt state of the channel.
+        __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+        if (__chan)
+            interrupt_state = CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE);
+
+        __selected_id = __comm_id;
+        CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]);
+
+        // Set interrupt state on the new channel.
+        __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+        if (interrupt_state)
+            CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_ENABLE);
+        else
+            CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
 }
 
 static int
 set_console_comm(int __comm_id)
 {
     static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;
+    int res = 1, update = 0;
+    CYGARC_HAL_SAVE_GP();
 
     CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER
                && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS,
@@ -162,30 +232,37 @@ set_console_comm(int __comm_id)
     switch (__comm_id) {
     case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:
         if (__selected_id > 0)
-            return __selected_id-1;
-        if (__selected_id == 0)
-            return CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
-        return __selected_id;
+            res = __selected_id-1;
+        else if (__selected_id == 0)
+            res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
+        else
+            res = __selected_id;
+        break;
 
     case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:
         CYGACC_CALL_IF_CONSOLE_PROCS_SET(0);
         __selected_id = __comm_id;
-        return 1;
+        break;
 
     case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:
         __comm_id = 0;
+        update = 1;
         break;
 
     default:
         __comm_id++;                    // skip mangler entry
+        update = 1;
         break;
     }
     
-    __selected_id = __comm_id;
+    if (update) {
+        __selected_id = __comm_id;
     
-    CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]);
+        CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]);
+    }
 
-    return 1;
+    CYGARC_HAL_RESTORE_GP();
+    return res;
 }
 
 //----------------------------------
@@ -194,21 +271,25 @@ set_console_comm(int __comm_id)
 static void
 flush_icache(void *__p, int __nbytes)
 {
+    CYGARC_HAL_SAVE_GP();
 #ifdef HAL_ICACHE_FLUSH
     HAL_ICACHE_FLUSH( __p , __nbytes );
 #elif defined(HAL_ICACHE_INVALIDATE)
     HAL_ICACHE_INVALIDATE();
 #endif
+    CYGARC_HAL_RESTORE_GP();
 }
 
 static void
 flush_dcache(void *__p, int __nbytes)
 {
+    CYGARC_HAL_SAVE_GP();
 #ifdef HAL_DCACHE_FLUSH
     HAL_DCACHE_FLUSH( __p , __nbytes );
 #elif defined(HAL_DCACHE_INVALIDATE)
     HAL_DCACHE_INVALIDATE();
 #endif
+    CYGARC_HAL_RESTORE_GP();
 }
 
 #endif
@@ -222,10 +303,10 @@ flush_dcache(void *__p, int __nbytes)
 // routines for that channel. The platform HAL also has the necessary
 // information to determine if the channel is already initialized by
 // a debug agent (either builtin or in ROM).
-void 
+void
 hal_if_diag_init(void)
 {
-#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+#ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
     cyg_hal_plf_comms_init();
 #endif
 
@@ -249,6 +330,12 @@ hal_if_diag_write_char(char c)
         __chan = CYGACC_CALL_IF_DEBUG_PROCS();
         CYGACC_COMM_IF_PUTC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), c);
     }
+
+    // Check interrupt flag
+    if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {
+        cyg_hal_user_break(0);
+        CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
+    }
 }
 
 void 
@@ -265,6 +352,43 @@ hal_if_diag_read_char(char *c)
 }
 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
+//=============================================================================
+// CtrlC support
+//=============================================================================
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
+    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+
+struct Hal_SavedRegisters *hal_saved_interrupt_state;
+
+void
+hal_ctrlc_isr_init(void)
+{
+    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+#if 1 // Prevents crash on older stubs
+    if (CYGNUM_CALL_IF_TABLE_VERSION != CYGACC_CALL_IF_VERSION())
+        return;
+#endif
+
+    CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), 
+                                    __COMMCTL_IRQ_ENABLE);
+}
+
+cyg_uint32
+hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+    int isr_ret, ctrlc = 0;
+
+    isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan),
+                                              &ctrlc, vector, data);
+    if (ctrlc)
+        cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
+    return isr_ret;
+}
+#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT || CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
+
 //--------------------------------------------------------------------------
 // Init function. It should be called from the platform initialization code.
 // For monitor configurations it will initialize the calling interface table,
@@ -298,9 +422,10 @@ hal_if_init(void)
         CYGACC_CALL_IF_ICTRL_TABLE_SET(hal_interrupt_handlers);
         CYGACC_CALL_IF_EXC_TABLE_SET(hal_vsr_table);
 
-        // Reset and kill vector
+        // Miscellaneous services with wrappers in this file.
         CYGACC_CALL_IF_RESET_SET(reset);
         CYGACC_CALL_IF_KILL_VECTOR_SET(kill_by_reset);
+        CYGACC_CALL_IF_DELAY_US_SET(delay_us);
 
         // Comm controls
         CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm);
@@ -310,11 +435,12 @@ hal_if_init(void)
         CYGACC_CALL_IF_FLUSH_ICACHE_SET(flush_icache);
         CYGACC_CALL_IF_FLUSH_DCACHE_SET(flush_dcache);
 
-        // Clear console procs entry. If platform has been configured
-        // to use a separate console port, it will be set up later
-        // (hal_diag_init). Alternatively (if this is a stub) it will
-        // be initialized with the output mangler (O-packetizer for
-        // GDB) which uses the debug comms.
+        // Clear debug and console procs entries. If platform has been
+        // configured to use a separate console port, it will be set
+        // up later (hal_diag_init). Alternatively (if this is a stub)
+        // it will be initialized with the output mangler
+        // (O-packetizer for GDB) which uses the debug comms.
+        set_debug_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);
         set_console_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);
 
         // Data entries not currently supported in eCos
@@ -324,6 +450,9 @@ hal_if_init(void)
     }
 #endif
 
+    // Reset console interrupt flag.
+    CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
+
     // Set up services provided by clients
 #if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)   &&  \
     ( defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \
diff --git a/packages/hal/common/current/src/hal_misc.c b/packages/hal/common/current/src/hal_misc.c
index 70c81eeaf..d838efaeb 100644
--- a/packages/hal/common/current/src/hal_misc.c
+++ b/packages/hal/common/current/src/hal_misc.c
@@ -120,13 +120,28 @@ hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
 {
     cyg_uint32 result;
 
-#if (defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)        \
-     || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)) && \
-    defined(CYGHWR_HAL_GDB_PORT_VECTOR) &&              \
-    defined(HAL_CTRLC_ISR)
+#if (defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)           \
+     || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)) &&    \
+        (defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) ||     \
+          defined(CYGHWR_HAL_GDB_PORT_VECTOR) &&           \
+          defined(HAL_CTRLC_ISR))
 
 #ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN    
+#if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+    int gdb_vector = -1;
+    // This check only to avoid crash on older stubs in case of unhandled
+    // interrupts. It is a bit messy, but required in a transition period.
+    if (CYGNUM_CALL_IF_TABLE_VERSION == CYGACC_CALL_IF_VERSION()) {
+        hal_virtual_comm_table_t* comm = CYGACC_CALL_IF_DEBUG_PROCS();
+        gdb_vector 
+            = CYGACC_COMM_IF_CONTROL(*comm)(CYGACC_COMM_IF_CH_DATA(*comm),
+                                            __COMMCTL_DBG_ISR_VECTOR);
+    }
+    if( vector == gdb_vector )
+#else
+    // Old code using hardwired channels. This should go away eventually.
     if( vector == CYGHWR_HAL_GDB_PORT_VECTOR )
+#endif
 #endif        
     {
         result = HAL_CTRLC_ISR( vector, data );
@@ -137,7 +152,7 @@ hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
     result = hal_arch_default_isr (vector, data);
     if( 0 != result) return result;
 
-    CYG_TRACE1(true, "Interrupt: %d", vector);
+    CYG_TRACE2(true, "Interrupt: %d, Data: 0x%08x", vector, data);
     CYG_FAIL("Spurious Interrupt!!!");
     return 0;
 }
diff --git a/packages/hal/common/current/src/hal_stub.c b/packages/hal/common/current/src/hal_stub.c
index c9d90804e..391529d3d 100644
--- a/packages/hal/common/current/src/hal_stub.c
+++ b/packages/hal/common/current/src/hal_stub.c
@@ -72,8 +72,10 @@ target_register_t registers[NUMREGS];
 target_register_t alt_registers[NUMREGS] ;  // Thread or saved process state
 target_register_t * _registers = registers; // Pointer to current set of registers
 
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
 // Interrupt control.
 static volatile __PFI __interruptible_control;
+#endif
 
 //-----------------------------------------------------------------------------
 // Register access
@@ -240,18 +242,34 @@ interruptible(int state)
 {
     static int __interrupts_suspended = 0;
 
-    if (__interruptible_control) {
-        if (state) {
-            __interrupts_suspended--;
-            if (0 >= __interrupts_suspended) {
-                __interrupts_suspended = 0;
+    if (state) {
+        __interrupts_suspended--;
+        if (0 >= __interrupts_suspended) {
+            __interrupts_suspended = 0;
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
+            {
+                hal_virtual_comm_table_t* __chan;
+                __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+                CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_ENABLE);
+            }
+#else                
+            if (__interruptible_control)
                 __interruptible_control(1);
+#endif
+        }
+    } else {
+        __interrupts_suspended++;
+        if (1 == __interrupts_suspended)
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
+            {
+                hal_virtual_comm_table_t* __chan;
+                __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+                CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE);
             }
-        } else {
-            __interrupts_suspended++;
-            if (1 == __interrupts_suspended)
+#else                
+            if (__interruptible_control)
                 __interruptible_control(0);
-        }
+#endif
     }
 }
 
@@ -299,7 +317,11 @@ cyg_hal_gdb_diag_putc(void* __ch_data, cyg_uint8 c)
         // while we are in the middle of sending a packet. The serial
         // receive interrupt will be seen when we re-enable interrupts
         // later.
+#ifdef CYG_HAL_STARTUP_ROM
+        HAL_DISABLE_INTERRUPTS(old);
+#else
         CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
+#endif
         
         while(1)
         {
@@ -336,7 +358,11 @@ cyg_hal_gdb_diag_putc(void* __ch_data, cyg_uint8 c)
 
         pos = 0;
         // And re-enable interrupts
+#ifdef CYG_HAL_STARTUP_ROM
+        HAL_RESTORE_INTERRUPTS(old);
+#else
         CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
+#endif
     }
 
     CYGARC_HAL_RESTORE_GP();
@@ -454,9 +480,11 @@ __install_traps (void)
     __cleanup_vec = &handle_exception_cleanup;
     __init_vec    = &handle_exception_init;
 
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
     // Control of GDB interrupts.
     __interruptible_control = HAL_STUB_PLATFORM_INTERRUPTIBLE;
+#endif
 #endif
 
     // Nothing further to do, handle_exception will be called when an
@@ -474,11 +502,6 @@ initHardware (void)
     initialized = 1;
 
 #if !defined(CYGPKG_CYGMON)
-#ifdef HAL_STUB_PLATFORM_INIT
-    // If the platform defines any initialization code, call it here.
-    HAL_STUB_PLATFORM_INIT();
-#endif        
-                
     // Get serial port initialized.
     HAL_STUB_PLATFORM_INIT_SERIAL();
 
@@ -507,6 +530,11 @@ initHardware (void)
         // Set the debug channel.
         CYGACC_CALL_IF_SET_DEBUG_COMM()(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
     }
+
+#ifdef HAL_STUB_PLATFORM_INIT
+    // If the platform defines any initialization code, call it here.
+    HAL_STUB_PLATFORM_INIT();
+#endif        
 #endif
 
 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
diff --git a/packages/hal/powerpc/arch/current/ChangeLog b/packages/hal/powerpc/arch/current/ChangeLog
index ec4e46d63..4397e3766 100644
--- a/packages/hal/powerpc/arch/current/ChangeLog
+++ b/packages/hal/powerpc/arch/current/ChangeLog
@@ -1,3 +1,8 @@
+2000-06-27  Jesper Skov  <jskov@redhat.com>
+
+	* src/vectors.S: Removed unnecessary
+	CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT checks.
+
 2000-06-15  Jesper Skov  <jskov@redhat.com>
 
 	* include/hal_intr.h: Added HAL_DEFAULT_ISR.
diff --git a/packages/hal/powerpc/arch/current/src/vectors.S b/packages/hal/powerpc/arch/current/src/vectors.S
index 10dc01d02..f31a2add3 100644
--- a/packages/hal/powerpc/arch/current/src/vectors.S
+++ b/packages/hal/powerpc/arch/current/src/vectors.S
@@ -347,10 +347,8 @@ _start:
         # Variant HALs may need to do something special before we continue
         bl      hal_variant_init
 
-#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
         # Platform initialization
         bl      hal_platform_init
-#endif
         
         # MMU and cache are controlled by the same option since caching
         # on the PPC does not make sense without the MMU to mark regions
@@ -378,12 +376,10 @@ _start:
 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
         bl      initialize_stub
 #endif
-#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
     || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
         .extern hal_ctrlc_isr_init
         bl     hal_ctrlc_isr_init
-#endif
 #endif
         
         bl      cyg_start                       # call cyg_start
@@ -657,19 +653,6 @@ cyg_hal_default_interrupt_vsr:
 
         hal_intc_decode r15,r14                # get table index
 
-#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT  // this should go away
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-        .extern cyg_hal_gdb_isr
-        lwz     r3,CYGARC_PPCREG_PC(r14)        # for serial receive irq.
-        bl      cyg_hal_gdb_isr                 # (arg1 is PC)
-        cmpwi   r3,0x0000                       # Call ISR proper?
-        beq     2f                              # (r3 is 0 when skipping
-                                                #  to avoid DSR call)
-1:
-#endif
-
-#else // the below should remain        
-
 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
     || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
 	# If we are supporting Ctrl-C interrupts from GDB, we must squirrel
@@ -681,7 +664,6 @@ cyg_hal_default_interrupt_vsr:
 	stw	r14,0(r3)
 	
 #endif
-#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 
 #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
 
@@ -707,14 +689,6 @@ cyg_hal_default_interrupt_vsr:
 
         bctrl                                   # branch to ctr reg and link
 
-#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT  // this should go away
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-        # If interrupt was caused by GDB, the ISR call above
-        # is skipped by jumping here.
-2:
-#endif
-#endif
-        
 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
 
         # If we are returning from the last nested interrupt, move back
diff --git a/packages/hal/powerpc/cogent/current/ChangeLog b/packages/hal/powerpc/cogent/current/ChangeLog
index 686caa614..799fb58d2 100644
--- a/packages/hal/powerpc/cogent/current/ChangeLog
+++ b/packages/hal/powerpc/cogent/current/ChangeLog
@@ -1,3 +1,17 @@
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_diag.c: Cleanup.
+
+2000-06-26  Jesper Skov  <jskov@redhat.com>
+
+	* cdl/hal_powerpc_cogent.cdl: Removed ROM_DEBUG option.
+
+	* include/plf_intr.h: 
+	* src/plf_misc.c: Removed Ctrl-c code.
+
+	* src/hal_diag.c: Snip cruft. Added non-block/timout
+	features. Moved Ctrl-c support code here.
+
 2000-06-21  Jesper Skov  <jskov@redhat.com>
 
 	* src/plf_stub.c: Provide plf stub init which prints build date
diff --git a/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl b/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl
index 12d1a1e23..484808020 100644
--- a/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl
+++ b/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl
@@ -90,10 +90,10 @@ cdl_package CYGPKG_HAL_POWERPC_COGENT {
     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
         display          "Debug serial port"
         flavor data
-        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        legal_values     0 to 1
         default_value    1
         description      "
-           The MBX board has only one serial port. This option
+           The Cogent board has two serial ports. This option
            chooses which port will be used to connect to a host
            running GDB."
     }
@@ -104,26 +104,10 @@ cdl_package CYGPKG_HAL_POWERPC_COGENT {
         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
         default_value    1
         description      "
-           The MBX board has only one serial port.  This option
+           The Cogent board has two serial ports and an LCD.  This option
            chooses which port will be used for diagnostic output."
     }
 
-    # This option is only used when USE_ROM_MONITOR is enabled - but
-    # it cannot be a sub-option to that option, since the code uses the
-    # definition in a preprocessor comparison.
-    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_ROM_DEBUG_CHANNEL {
-        display          "Debug serial port used by ROM monitor"
-        flavor data
-        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
-        default_value    1
-        description      "
-            The MBX board has only one serial port.  This
-            option tells the code which port is in use by the ROM
-            monitor. It should only be necessary to change this
-            option if a non-standard configurated eCos GDB stub is
-            used."
-    }
-
     cdl_option CYGHWR_HAL_POWERPC_BOARD_SPEED {
         display          "Development board clock speed (MHz)"
         flavor           data
diff --git a/packages/hal/powerpc/cogent/current/include/plf_intr.h b/packages/hal/powerpc/cogent/current/include/plf_intr.h
index 1ce9235ff..e5098f631 100644
--- a/packages/hal/powerpc/cogent/current/include/plf_intr.h
+++ b/packages/hal/powerpc/cogent/current/include/plf_intr.h
@@ -48,22 +48,6 @@
 //
 //==========================================================================
 
-//--------------------------------------------------------------------------
-// Control-C support.
-
-#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
-
-// Serial interrupts are feed to IRQ1 (vector 0x08) on the Cogent
-// board.
-# define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_SIU_IRQ1
-
-externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
-
-# define HAL_CTRLC_ISR hal_ctrlc_isr
-
-#endif
-
 //--------------------------------------------------------------------------
 #endif // ifndef CYGONCE_HAL_PLF_INTR_H
 // End of plf_intr.h
diff --git a/packages/hal/powerpc/cogent/current/include/plf_stub.h b/packages/hal/powerpc/cogent/current/include/plf_stub.h
index 240472710..fcbf2aa1a 100644
--- a/packages/hal/powerpc/cogent/current/include/plf_stub.h
+++ b/packages/hal/powerpc/cogent/current/include/plf_stub.h
@@ -69,7 +69,6 @@ externC void cyg_hal_plf_comms_init(void);
 
 #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
 #define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
-#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    hal_cma_stub_init_break_irq()
 
 //----------------------------------------------------------------------------
 // Stub initializer.
diff --git a/packages/hal/powerpc/cogent/current/src/hal_diag.c b/packages/hal/powerpc/cogent/current/src/hal_diag.c
index bb0f6bb58..d7a832a03 100644
--- a/packages/hal/powerpc/cogent/current/src/hal_diag.c
+++ b/packages/hal/powerpc/cogent/current/src/hal_diag.c
@@ -45,11 +45,9 @@
 
 #include <cyg/hal/hal_diag.h>           // our header.
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
-#include <cyg/hal/hal_stub.h>           // CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION
-#endif
-
 #include <cyg/infra/cyg_type.h>         // base types, externC
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_misc.h>           // Helper functions
 #include <cyg/hal/hal_io.h>             // IO macros
 #include <cyg/hal/hal_intr.h>           // Interrupt macros
 
@@ -57,6 +55,9 @@
 #include <cyg/hal/hal_if.h>             // Calling-if API
 
 
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
 static void cyg_hal_plf_serial_init(void);
 static void cyg_hal_plf_lcd_init(void);
 
@@ -73,17 +74,7 @@ cyg_hal_plf_comms_init(void)
     cyg_hal_plf_serial_init();
     cyg_hal_plf_lcd_init();
 }
-
-#if 0
-#ifdef CYGSEM_HAL_ROM_MONITOR
-    // It's handy to have the LCD initialized at reset when using it
-    // for debugging output.
-    {
-        diag_write_string ("eCos ROM   " __TIME__ "\n");
-        diag_write_string (__DATE__ "\n");
-    }
-#endif
-#endif
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
 
 //=============================================================================
 // Serial driver
@@ -127,6 +118,8 @@ cyg_hal_plf_comms_init(void)
 // The interrupt identification register bits.
 #define SIO_IIR_IP      0x01            // 0 if interrupt pending
 #define SIO_IIR_ID_MASK 0x0e            // mask for interrupt ID bits
+#define ISR_Tx  0x02
+#define ISR_Rx  0x04
 
 // The line status register bits.
 #define SIO_LSR_DR      0x01            // data ready
@@ -163,7 +156,6 @@ cyg_hal_plf_comms_init(void)
 #define SIO_FCR_FCR1   0x02             // clear RCVR FIFO
 #define SIO_FCR_FCR2   0x04             // clear XMIT FIFO
 
-
 static void
 init_serial_channel( cyg_uint8* base )
 {
@@ -210,21 +202,32 @@ init_serial_channel( cyg_uint8* base )
                     (SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2));
 }
 
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8* base = (cyg_uint8*)__ch_data;
+    cyg_uint8 lsr;
+
+    HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
+    if ((lsr & SIO_LSR_DR) == 0)
+        return false;
+
+    HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, *ch);
+
+    return true;
+}
+
+
 cyg_uint8
 cyg_hal_plf_serial_getc(void* __ch_data)
 {
-    cyg_uint8* base = (cyg_uint8*)__ch_data;
-    cyg_uint8 c, lsr;
+    cyg_uint8 ch;
     CYGARC_HAL_SAVE_GP();
 
-    do {
-        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
-    } while ((lsr & SIO_LSR_DR) == 0);
-
-    HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, c);
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
 
     CYGARC_HAL_RESTORE_GP();
-    return c;
+    return ch;
 }
 
 void
@@ -274,18 +277,116 @@ cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
     CYGARC_HAL_RESTORE_GP();
 }
 
+static cyg_int32 msec_timeout[2] = { 1000, 1000 };
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    // delay in .1 ms steps
+    delay_count = msec_timeout[__ch_data == (void*)CYG_DEV_SERIAL_BASE_A ? 0 : 1] * 10;
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US()(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
 static int
 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
 {
-    // Do nothing (yet).
-    return 0;
+    static int irq_state = 0;
+    cyg_uint8* base = (cyg_uint8*)__ch_data;
+    cyg_uint8 ier;
+    int ret = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1);
+        HAL_INTERRUPT_SET_LEVEL(CYGNUM_HAL_INTERRUPT_SIU_IRQ1, 1);
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_IER, ier);
+        ier |= SIO_IER_ERDAI;
+        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_IER, ier);
+        irq_state = 1;
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1);
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_IER, ier);
+        ier &= ~SIO_IER_ERDAI;
+        HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_IER, ier);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = CYGNUM_HAL_INTERRUPT_SIU_IRQ1;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = msec_timeout[__ch_data == (void*)CYG_DEV_SERIAL_BASE_A ? 0 : 1];
+        msec_timeout[__ch_data == (void*)CYG_DEV_SERIAL_BASE_A ? 0 : 1] 
+            = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
 }
 
-#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    cyg_uint8* base = (cyg_uint8*)__ch_data;
+    cyg_uint8 _iir;
+    int res = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    HAL_READ_UINT8(base+CYG_DEV_SERIAL_IIR, _iir);
+    _iir &= SIO_IIR_ID_MASK;
+
+    *__ctrlc = 0;
+    if ( ISR_Rx == _iir ) {
+        cyg_uint8 c, lsr;
+        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
+        if (lsr & SIO_LSR_DR) {
+
+            HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, c);
+
+            if( cyg_hal_is_break( &c , 1 ) )
+                *__ctrlc = 1;
+        }
+
+        // Acknowledge the interrupt
+        HAL_INTERRUPT_ACKNOWLEDGE(CYGNUM_HAL_INTERRUPT_SIU_IRQ1);
+        res = CYG_ISR_HANDLED;
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
 
 static void
 cyg_hal_plf_serial_init(void)
 {
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
     // Disable interrupts.
     HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1);
 
@@ -293,43 +394,48 @@ cyg_hal_plf_serial_init(void)
     init_serial_channel((cyg_uint8*)CYG_DEV_SERIAL_BASE_A);
     init_serial_channel((cyg_uint8*)CYG_DEV_SERIAL_BASE_B);
 
-#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
-    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
-    {
-        // Setup procs in the vector table
-        hal_virtual_comm_table_t* comm;
-        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-
-        // Set channel 0
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);
-        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
-        CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_A);
-        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
-        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
-        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
-        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
-        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
-
-        // Set channel 1
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(1);
-        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
-        CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_B);
-        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
-        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
-        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
-        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
-        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
-     
-        // Restore original console
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
-    }
-#endif
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_A);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+    // Set channel 1
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(1);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_B);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+    
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
 }
 
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
 
 //=============================================================================
 // LCD driver
 //=============================================================================
+
+// The LCD driver is only used by the new vector code. Cannot be used
+// by the old compatibility cruft.
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
 // FEMA 162B 16 character x 2 line LCD
 // base addresses and register offsets *
 
@@ -486,9 +592,6 @@ cyg_hal_plf_lcd_getc(void* __ch_data)
     return 0;
 }
 
-#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
-    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
-
 static void
 cyg_hal_plf_lcd_write(void* __ch_data, const cyg_uint8* __buf, 
                          cyg_uint32 __len)
@@ -519,36 +622,31 @@ cyg_hal_plf_lcd_control(void *__ch_data, __comm_control_cmd_t __func, ...)
     return 0;
 }
 
-#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
-
 static void
 cyg_hal_plf_lcd_init(void)
 {
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
     // Init channel
     init_lcd_channel((cyg_uint8*)LCD_BASE);
 
-#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
-    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
-    {
-        // Setup procs in the vector table
-        hal_virtual_comm_table_t* comm;
-        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-
-        // Set channel 2
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(2);
-        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
-        CYGACC_COMM_IF_CH_DATA_SET(*comm, LCD_BASE);
-        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_lcd_write);
-        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_lcd_read);
-        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_lcd_putc);
-        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_lcd_getc);
-        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_lcd_control);
-
-        // Restore original console
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
-    }
-#endif
+    // Setup procs in the vector table
+
+    // Set channel 2
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(2);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, LCD_BASE);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_lcd_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_lcd_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_lcd_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_lcd_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_lcd_control);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
 }
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
 
 //=============================================================================
 // Compatibility with older stubs
@@ -556,6 +654,10 @@ cyg_hal_plf_lcd_init(void)
 
 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
+#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+#include <cyg/hal/hal_stub.h>           // CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION
+#endif
+
 //-----------------------------------------------------------------------------
 // Assumption: all diagnostic output must be GDB packetized unless
 // this is a configuration for a stand-alone ROM system.
@@ -575,7 +677,7 @@ cyg_hal_plf_lcd_init(void)
 
 void hal_diag_init(void)
 {
-    cyg_hal_plf_comms_init();
+    init_serial_channel(__BASE);
 }
 
 void hal_diag_write_char(char __c)
@@ -595,7 +697,7 @@ void
 hal_diag_init(void)
 {
     // Init devices
-    cyg_hal_plf_comms_init();
+    init_serial_channel(__BASE);
 }
 
 void 
diff --git a/packages/hal/powerpc/cogent/current/src/plf_misc.c b/packages/hal/powerpc/cogent/current/src/plf_misc.c
index 8e6354372..8708865d0 100644
--- a/packages/hal/powerpc/cogent/current/src/plf_misc.c
+++ b/packages/hal/powerpc/cogent/current/src/plf_misc.c
@@ -68,101 +68,4 @@ hal_platform_init(void)
     hal_if_init();
 }
 
-
-//--------------------------------------------------------------------------
-// Control C ISR support
-
-#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
-
-#if (1 == CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL)
-#define CYG_DEVICE_SERIAL_RS232_16550_BASE CYG_DEVICE_SERIAL_RS232_16550_BASE_B
-#else
-#define CYG_DEVICE_SERIAL_RS232_16550_BASE CYG_DEVICE_SERIAL_RS232_16550_BASE_A
-#endif
-
-//-----------------------------------------------------------------------------
-// There are two serial ports.
-#define CYG_DEVICE_SERIAL_RS232_16550_BASE_A    0xe900047 // port A
-#define CYG_DEVICE_SERIAL_RS232_16550_BASE_B    0xe900007 // port B
-
-// receiver buffer register, read, dlab = 0
-#define CYG_DEVICE_SERIAL_RS232_16550_RBR \
-    ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x00)
-// interrupt enable register, read/write, dlab = 0
-#define CYG_DEVICE_SERIAL_RS232_16550_IER \
-    ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x08)
-// interrupt identification register, read, dlab = 0
-#define CYG_DEVICE_SERIAL_RS232_16550_IIR \
-    ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x10)
-// line status register, read
-#define CYG_DEVICE_SERIAL_RS232_16550_LSR \
-    ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x28)
-
-
-// The interrupt enable register bits.
-#define SIO_IER_ERDAI   0x01            // enable received data available irq
-#define SIO_IER_ETHREI  0x02            // enable THR empty interrupt
-#define SIO_IER_ELSI    0x04            // enable receiver line status irq
-#define SIO_IER_EMSI    0x08            // enable modem status interrupt
-
-// The interrupt identification register bits.
-#define SIO_IIR_IP      0x01            // 0 if interrupt pending
-#define SIO_IIR_ID_MASK 0x0e            // mask for interrupt ID bits
-#define ISR_Tx  0x02
-#define ISR_Rx  0x04
-
-// The line status register bits.
-#define SIO_LSR_DR      0x01            // data ready
-#define SIO_LSR_OE      0x02            // overrun error
-#define SIO_LSR_PE      0x04            // parity error
-#define SIO_LSR_FE      0x08            // framing error
-#define SIO_LSR_BI      0x10            // break interrupt
-#define SIO_LSR_THRE    0x20            // transmitter holding register empty
-#define SIO_LSR_TEMT    0x40            // transmitter register empty
-#define SIO_LSR_ERR     0x80            // any error condition
-
-struct Hal_SavedRegisters *hal_saved_interrupt_state;
-
-void hal_ctrlc_isr_init(void)
-{
-    // Enable serial receive interrupts.
-    HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_IER, SIO_IER_ERDAI);
-
-    HAL_INTERRUPT_SET_LEVEL(CYGHWR_HAL_GDB_PORT_VECTOR, 1);
-    HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR);
-}
-
-cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
-{
-    cyg_uint8 _iir;
-
-
-    HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_IIR, _iir);
-    _iir &= SIO_IIR_ID_MASK;
-
-    if ( ISR_Rx == _iir ) {
-
-        cyg_uint8 c, lsr;
-
-        HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LSR, lsr);
-        if (lsr & SIO_LSR_DR) {
-
-            HAL_READ_UINT8( CYG_DEVICE_SERIAL_RS232_16550_RBR, c );
-
-            if( cyg_hal_is_break( &c , 1 ) )
-                cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
-        }
-
-        // Acknowledge the interrupt
-        HAL_INTERRUPT_ACKNOWLEDGE(CYGHWR_HAL_GDB_PORT_VECTOR);
-
-        return CYG_ISR_HANDLED;
-    }
-
-    return 0;
-}
-
-#endif
-
 // EOF plf_misc.c
diff --git a/packages/hal/powerpc/fads/current/ChangeLog b/packages/hal/powerpc/fads/current/ChangeLog
index 26b9f8f39..c5fe01258 100644
--- a/packages/hal/powerpc/fads/current/ChangeLog
+++ b/packages/hal/powerpc/fads/current/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-26  Jesper Skov  <jskov@redhat.com>
+
+	* cdl/hal_powerpc_fads.cdl: Removed ROM_DEBUG_CHANNEL option.
+
 2000-06-15  Jesper Skov  <jskov@redhat.com>
 
 	* src/hal_diag.c: 
diff --git a/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl b/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl
index 2d8cda44a..c2ef2b92c 100644
--- a/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl
+++ b/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl
@@ -102,22 +102,6 @@ cdl_package CYGPKG_HAL_POWERPC_FADS {
            chooses which port will be used for diagnostic output."
     }
 
-    # This option is only used when USE_ROM_MONITOR is enabled - but
-    # it cannot be a sub-option to that option, since the code uses the
-    # definition in a preprocessor comparison.
-    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_ROM_DEBUG_CHANNEL {
-        display          "Debug serial port used by ROM monitor"
-        flavor data
-        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
-        default_value    0
-        description      "
-            The FADS board has only one serial port.  This
-            option tells the code which port is in use by the ROM
-            monitor. It should only be necessary to change this
-            option if a non-standard configurated eCos GDB stub is
-            used."
-    }
-
     # Real-time clock/counter specifics
     cdl_component CYGNUM_HAL_RTC_CONSTANTS {
         display       "Real-time clock constants."
diff --git a/packages/hal/powerpc/mbx/current/ChangeLog b/packages/hal/powerpc/mbx/current/ChangeLog
index 8071d4c8f..d4a43206b 100644
--- a/packages/hal/powerpc/mbx/current/ChangeLog
+++ b/packages/hal/powerpc/mbx/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* include/hal_diag.h: 
+	* src/hal_diag.c: 
+	Cleanup.
+
 2000-06-22  John Dallaway  <jld@redhat.com>
 
 	* include/pkgconf/mlt_powerpc_mbx_rom.mlt:
diff --git a/packages/hal/powerpc/mbx/current/include/hal_diag.h b/packages/hal/powerpc/mbx/current/include/hal_diag.h
index b73f64b4f..974b6813a 100644
--- a/packages/hal/powerpc/mbx/current/include/hal_diag.h
+++ b/packages/hal/powerpc/mbx/current/include/hal_diag.h
@@ -69,10 +69,6 @@
 
 #include <cyg/infra/cyg_type.h>
 
-externC void cyg_hal_plf_serial_init(void);
-externC void cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch);
-externC cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data);
-
 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
 
 #include <cyg/hal/hal_if.h>
diff --git a/packages/hal/powerpc/mbx/current/src/hal_diag.c b/packages/hal/powerpc/mbx/current/src/hal_diag.c
index 399631745..a5e6e06ab 100644
--- a/packages/hal/powerpc/mbx/current/src/hal_diag.c
+++ b/packages/hal/powerpc/mbx/current/src/hal_diag.c
@@ -134,7 +134,7 @@ void hal_diag_init(void)
     eppc = eppc_base();
 
     // init the actual serial port
-    cyg_hal_plf_serial_init();
+    cyg_hal_plf_serial_init_channel();
 #ifndef CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL
 #ifndef CYG_HAL_STARTUP_ROM
     // We are talking to GDB; ack the "go" packet!
diff --git a/packages/hal/powerpc/quicc/current/ChangeLog b/packages/hal/powerpc/quicc/current/ChangeLog
index 1f84dde09..c2da6b3f1 100644
--- a/packages/hal/powerpc/quicc/current/ChangeLog
+++ b/packages/hal/powerpc/quicc/current/ChangeLog
@@ -1,3 +1,19 @@
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* include/quicc_smc1.h: 
+	* src/quicc_smc1.c: Cleanup.
+
+2000-06-26  Jesper Skov  <jskov@redhat.com>
+
+	* include/quicc_smc1.h:
+	* src/quicc_smc1.c: Added non-block/timout features. Reworked
+	Ctrl-c support code.
+
+2000-06-22  Jesper Skov  <jskov@redhat.com>
+
+	* src/quicc_smc1.c: Fix compiler warning. Add functions to deal
+	with ctrl-c interrupts from the device.
+
 2000-06-21  Jesper Skov  <jskov@redhat.com>
 
 	* src/quicc_smc1.c: 
diff --git a/packages/hal/powerpc/quicc/current/include/quicc_smc1.h b/packages/hal/powerpc/quicc/current/include/quicc_smc1.h
index 60dfd0463..945d7a71c 100644
--- a/packages/hal/powerpc/quicc/current/include/quicc_smc1.h
+++ b/packages/hal/powerpc/quicc/current/include/quicc_smc1.h
@@ -48,21 +48,14 @@
 #include <cyg/infra/cyg_type.h>
 #include <cyg/hal/quicc/ppc8xx.h>             // FIXME: bad, but need eppc_base
 
+
+#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+// This one should only be used by old-stub compatibility code!
+externC void cyg_hal_plf_serial_init_channel(void);
+#endif
+
 externC void cyg_hal_plf_serial_init(void);
 externC void cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch);
 externC cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data);
 
-//--------------------------------------------------------------------------
-// Control-C support.
-
-#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
-
-#define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_CPM_SMC1
-externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
-
-# define HAL_CTRLC_ISR hal_ctrlc_isr
-
-#endif
-
 #endif /* CYGONCE_HAL_PPC_QUICC_SMC1_H */
diff --git a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c
index b6795e70c..78e2ecfb6 100644
--- a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c
+++ b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c
@@ -60,14 +60,11 @@
 
 #include <cyg/hal/quicc/quicc_smc1.h>
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
 #include <cyg/hal/hal_stub.h>           // target_register_t
 #include <cyg/hal/hal_intr.h>           // HAL_INTERRUPT_UNMASK(...)
 #include <cyg/hal/hal_if.h>             // Calling interface definitions
 #include <cyg/hal/hal_misc.h>           // Helper functions
 #include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
-#endif
 
 #define UART_BIT_RATE(n) (((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/16)/n)
 #define UART_BAUD_RATE CYGNUM_HAL_QUICC_DIAG_BAUD
@@ -92,8 +89,8 @@
  *  The basic initialization steps are from Section 16.15.8
  *  of that manual.
  */	
-static void
-init_smc1_uart(void)
+void
+cyg_hal_plf_serial_init_channel(void)
 {
     EPPC *eppc;
     volatile struct smc_uart_pram *uart_pram;
@@ -286,22 +283,22 @@ cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch)
     CYGARC_HAL_RESTORE_GP();
 }
 
-cyg_uint8
-cyg_hal_plf_serial_getc(void* __ch_data)
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
 {
     volatile struct cp_bufdesc *bd;
-    char ch;
     EPPC *eppc = (EPPC*) __ch_data;
     volatile struct smc_uart_pram *uart_pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u;
     int cache_state;
-    CYGARC_HAL_SAVE_GP();
 
     /* rx buffer descriptor */
     bd = (struct cp_bufdesc *)((char *)eppc + uart_pram->rbptr);
 
-    while (bd->ctrl & QUICC_BD_CTL_Ready) ;
+    if (bd->ctrl & QUICC_BD_CTL_Ready)
+        return false;
 
-    ch = bd->buffer[0];
+    *ch = bd->buffer[0];
 
     bd->length = 0;
     bd->buffer[0] = '\0';
@@ -312,10 +309,26 @@ cyg_hal_plf_serial_getc(void* __ch_data)
         HAL_DCACHE_INVALIDATE(bd->buffer, uart_pram->mrblr);  // Make sure no stale data
     }
 
+    return true;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
     CYGARC_HAL_RESTORE_GP();
     return ch;
 }
 
+
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
 static void
 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
                          cyg_uint32 __len)
@@ -339,132 +352,82 @@ cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
     CYGARC_HAL_RESTORE_GP();
 }
 
-static int
-cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
-{
-    // Do nothing (yet).
-    return 0;
-}
+cyg_int32 msec_timeout = 1000;
 
-/*
- * Early initialization of comm channels. Must not rely
- * on interrupts, yet. Interrupt operation can be enabled
- * in _bsp_board_init().
- */
-void
-cyg_hal_plf_serial_init(void)
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
 {
-    volatile EPPC *eppc = eppc_base();
-    int i;
-
-    static int init = 0;  // It's wrong to do this more than once
-    if (init) return;
-    init++;
-
-    /*
-     *  Reset communications processor
-     */
-    eppc->cp_cr = QUICC_CPM_CR_RESET | QUICC_CPM_CR_BUSY;
-    for (i = 0; i < 100000; i++);
-
-    init_smc1_uart();
+    int delay_count = msec_timeout * 10; // delay in .1 ms steps
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
 
-#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
-    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
-    {
-        // Setup procs in the vector table
-        hal_virtual_comm_table_t* comm;
-        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-
-        // Set channel 0
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);// Should be configurable!
-        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
-        CYGACC_COMM_IF_CH_DATA_SET(*comm, eppc_base());
-        CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
-        CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
-        CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
-        CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
-        CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
-
-        // Restore original console
-        CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US()(100);
     }
-#endif
-}
-
-#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // the below should be removed
 
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
 
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-// This ISR is called from the interrupt handler. This should only
-// happen when there is no real serial driver, so the code shouldn't
-// mess anything up.
-int cyg_hal_gdb_isr( target_register_t pc )
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
 {
-    EPPC *eppc = eppc_base();
-    struct cp_bufdesc *bd;
-    char ch;
-
-    eppc->smc_regs[0].smc_smce = 0xff;
-
-    /* rx buffer descriptors */
-    bd = (struct cp_bufdesc *)((char *)eppc_base() + Rxbd);
+    static int irq_state = 0;
+    int ret = 0;
+    CYGARC_HAL_SAVE_GP();
 
-    if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) {
-        // then there be a character waiting
-        ch = bd->buffer[0];
-        bd->length = 1;
-        bd->ctrl   = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int;
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1);
+        irq_state = 1;
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = CYGNUM_HAL_INTERRUPT_CPM_SMC1;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
 
-        if ( 3 == ch ) {
-            // Ctrl-C: set a breakpoint at PC so GDB will display the
-            // correct program context when stopping rather than the
-            // interrupt handler.
-            cyg_hal_gdb_interrupt( pc );
+        va_start(ap, __func);
 
-            // Interrupt handled. Don't call ISR proper. At return
-            // from the VSR, execution will stop at the breakpoint
-            // just set.
+        ret = msec_timeout;
+        msec_timeout = va_arg(ap, cyg_uint32);
 
-            eppc->cpmi_cisr = 0x10;
-            return 0;
-        }
+        va_end(ap);
+    }        
+    default:
+        break;
     }
-    eppc->cpmi_cisr = 0x10; // acknowledge the Rx event anyway
-                            // in case it was left over from polled reception
-    // Not caused by GDB. Call ISR proper.
-    return 1;
-}
-#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-
-
-#else // the below stays
-
-#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
-
-struct Hal_SavedRegisters *hal_saved_interrupt_state;
-
-void
-hal_ctrlc_isr_init(void)
-{
-    HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR);
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
 }
 
-
-cyg_uint32
-hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
 {
-    EPPC *eppc = eppc_base();
+    EPPC *eppc = (EPPC*) __ch_data;
     struct cp_bufdesc *bd;
     char ch;
+    int res = 0;
+    CYGARC_HAL_SAVE_GP();
 
+    *__ctrlc = 0;
     if (eppc->smc_regs[0].smc_smce & QUICC_SMCE_RX) {
 
         eppc->smc_regs[0].smc_smce = QUICC_SMCE_RX;
 
         /* rx buffer descriptors */
-        bd = (struct cp_bufdesc *)((char *)eppc_base() + Rxbd);
+        bd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
 
         if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) {
             
@@ -474,19 +437,62 @@ hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
             bd->ctrl   = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int;
         
             if( cyg_hal_is_break( &ch , 1 ) )
-                cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
+                *__ctrlc = 1;
         }
 
         // Interrupt handled. Acknowledge it.
         eppc->cpmi_cisr = 0x10;
-        return CYG_ISR_HANDLED;
+        res = CYG_ISR_HANDLED;
     }
 
-    // Not a serial interrupt.
-    return 0;
+    CYGARC_HAL_RESTORE_GP();
+    return res;
 }
-#endif
-#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+/*
+ * Early initialization of comm channels. Must not rely
+ * on interrupts, yet. Interrupt operation can be enabled
+ * in _bsp_board_init().
+ */
+void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+    volatile EPPC *eppc = eppc_base();
+    int i;
+
+    static int init = 0;  // It's wrong to do this more than once
+    if (init) return;
+    init++;
+
+    /*
+     *  Reset communications processor
+     */
+    eppc->cp_cr = QUICC_CPM_CR_RESET | QUICC_CPM_CR_BUSY;
+    for (i = 0; i < 100000; i++);
+
+    cyg_hal_plf_serial_init_channel();
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);// Should be configurable!
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, eppc_base());
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
 
 #endif // CYGPKG_HAL_POWERPC_MPC860
 // EOF quicc_smc1.c
diff --git a/packages/hal/powerpc/sim/current/ChangeLog b/packages/hal/powerpc/sim/current/ChangeLog
index 5d1cecc33..0eb14046d 100644
--- a/packages/hal/powerpc/sim/current/ChangeLog
+++ b/packages/hal/powerpc/sim/current/ChangeLog
@@ -1,3 +1,10 @@
+2000-06-27  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_aux.c (hal_platform_init): Added.
+
+	* cdl/hal_powerpc_sim.cdl: Does not support CTRLC (sim handles
+	that, no target code required).
+
 2000-04-11  Jesper Skov  <jskov@redhat.com>
 
 	* cdl/hal_powerpc_sim.cdl: Force inclusion of vectors, disable
diff --git a/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl b/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl
index 57ad89371..2c8fdde8d 100644
--- a/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl
+++ b/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl
@@ -55,6 +55,8 @@ cdl_package CYGPKG_HAL_POWERPC_SIM {
 
     compile       sim.S hal_aux.c
 
+    implements CYGINT_HAL_DEBUG_GDB_CTRLC_UNSUPPORTED
+
     define_proc {
         puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_powerpc_ppc60x.h>"
         puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_powerpc_sim.h>"
diff --git a/packages/hal/powerpc/sim/current/src/hal_aux.c b/packages/hal/powerpc/sim/current/src/hal_aux.c
index 13743d26e..0de5b2ef8 100644
--- a/packages/hal/powerpc/sim/current/src/hal_aux.c
+++ b/packages/hal/powerpc/sim/current/src/hal_aux.c
@@ -55,4 +55,10 @@ CYGARC_MEMDESC_TABLE CYGBLD_ATTRIB_WEAK = {
     CYGARC_MEMDESC_TABLE_END
 };
 
+//-----------------------------------------------------------------------------
+void
+hal_platform_init(void)
+{
+}
+
 // EOF hal_aux.c
diff --git a/packages/hal/sh/arch/current/ChangeLog b/packages/hal/sh/arch/current/ChangeLog
index fa58ab9ce..e5f65fe30 100644
--- a/packages/hal/sh/arch/current/ChangeLog
+++ b/packages/hal/sh/arch/current/ChangeLog
@@ -1,3 +1,38 @@
+2000-06-29  Gary Thomas  <gthomas@redhat.com>
+
+	* src/vectors.S: Reorg initialization (reset) code to be all
+	in one, non-fixed location.  Required for platforms with more
+	complex initialization sequences.
+
+2000-06-29  Jesper Skov  <jskov@redhat.com>
+
+	* src/sh3_sci.c:
+	* src/sh3_scif.c:
+	Use per-channel data structure instead of code cruft.
+
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* include/sh3_sci.h:    [added]
+	* include/sh3_scif.h:   [added] 
+	* include/sh3_scif.inl: [removed]
+	* include/sh_sci.inl:   [removed]
+	* src/sh3_sci.c:        [added]
+	* src/sh3_scif.c:       [added]
+	* cdl/hal_sh.cdl:
+	Rewrote serial drivers for comm procs usage.
+	
+2000-06-27  Jesper Skov  <jskov@redhat.com>
+
+	* src/vectors.S: Added arch and platform init calls. Added ctrlc
+	init call. Replaced old BREAK magic with new ctrlc magic.
+
+	* src/sh.ld: Added extra _ on NETDEVTAB labels. Define
+	hal_virtual_vector_table.
+
+	* src/hal_misc.c: hal_default_isr moved to common HAL.
+
+	* cdl/hal_sh.cdl: Also build simple drivers.
+
 2000-06-15  Jesper Skov  <jskov@redhat.com>
 
 	* include/hal_intr.h: Added HAL_DEFAULT_ISR.
diff --git a/packages/hal/sh/arch/current/cdl/hal_sh.cdl b/packages/hal/sh/arch/current/cdl/hal_sh.cdl
index 903204425..b133dfe02 100644
--- a/packages/hal/sh/arch/current/cdl/hal_sh.cdl
+++ b/packages/hal/sh/arch/current/cdl/hal_sh.cdl
@@ -58,7 +58,7 @@ cdl_package CYGPKG_HAL_SH {
         requires 1 == CYGINT_HAL_SH_VARIANT
     }
 
-    compile       hal_misc.c context.S sh_stub.c
+    compile       hal_misc.c context.S sh_stub.c sh3_sci.c sh3_scif.c
 
     # The "-o file" is a workaround for CR100958 - without it the
     # output file would end up in the source directory under CygWin.
diff --git a/packages/hal/sh/arch/current/include/sh3_sci.h b/packages/hal/sh/arch/current/include/sh3_sci.h
new file mode 100644
index 000000000..eab5879b7
--- /dev/null
+++ b/packages/hal/sh/arch/current/include/sh3_sci.h
@@ -0,0 +1,81 @@
+//=============================================================================
+//
+//      sh3_sci.h
+//
+//      Simple driver for the SH Serial Communication Interface (SCI)
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:jskov
+// Date:        1999-05-17
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGNUM_HAL_SH_SH3_SCI_PORTS
+
+//--------------------------------------------------------------------------
+// SCI register offsets
+#ifdef CYGARC_SH_MOD_SCI_V2
+# define _REG_SCSPTR             -0x4 // serial port register
+#endif
+#define _REG_SCSMR                0x0 // serial mode register
+#define _REG_SCBRR                0x2 // bit rate register
+#define _REG_SCSCR                0x4 // serial control register
+#define _REG_SCTDR                0x6 // transmit data register
+#define _REG_SCSSR                0x8 // serial status register
+#define _REG_SCRDR                0xa // receive data register
+
+//--------------------------------------------------------------------------
+
+typedef struct {
+    cyg_uint8* base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+} channel_data_t;
+
+//--------------------------------------------------------------------------
+
+#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+// This one should only be used by old-stub compatibility code!
+externC void cyg_hal_plf_sci_init_channel(const channel_data_t* chan);
+#endif
+
+externC cyg_uint8 cyg_hal_plf_sci_getc(void* __ch_data);
+externC void cyg_hal_plf_sci_putc(void* __ch_data, cyg_uint8 c);
+externC void cyg_hal_plf_sci_init(int sci_index, int comm_index, 
+                                  int rcv_vect, cyg_uint8* base);
+
+
+#endif // CYGNUM_HAL_SH_SH3_SCI_PORTS
+//-----------------------------------------------------------------------------
+// end of sh3_sci.h
diff --git a/packages/hal/sh/arch/current/include/sh3_scif.h b/packages/hal/sh/arch/current/include/sh3_scif.h
new file mode 100644
index 000000000..d88e1fa4a
--- /dev/null
+++ b/packages/hal/sh/arch/current/include/sh3_scif.h
@@ -0,0 +1,88 @@
+//=============================================================================
+//
+//      sh3_scif.h
+//
+//      Simple driver for the SH3 Serial Communication Interface with FIFO
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:jskov
+// Date:        2000-03-30
+// Description: Simple driver for the SH Serial Communication Interface
+//              The driver can be used for either the SCIF or the IRDA
+//              modules (the latter can act as the former).
+//              Clients of this file can configure the behavior with:
+//              CYGNUM_SCIF_PORTS: number of SCI ports
+//
+// Note:        It should be possible to configure a channel to IRDA mode.
+//              Worry about that when some board needs it.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGNUM_HAL_SH_SH3_SCIF_PORTS
+
+//--------------------------------------------------------------------------
+// SCIF register offsets
+#define _REG_SCSMR  0x00
+#define _REG_SCBRR  0x02
+#define _REG_SCSCR  0x04
+#define _REG_SCFTDR 0x06
+#define _REG_SCSSR  0x08
+#define _REG_SCFRDR 0x0a
+#define _REG_SCFCR  0x0c
+#define _REG_SCFDR  0x0e
+
+//--------------------------------------------------------------------------
+
+typedef struct {
+    cyg_uint8* base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+} channel_data_t;
+
+//--------------------------------------------------------------------------
+
+#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+// This one should only be used by old-stub compatibility code!
+externC void cyg_hal_plf_scif_init_channel(const channel_data_t* chan);
+#endif
+
+externC cyg_uint8 cyg_hal_plf_scif_getc(void* __ch_data);
+externC void cyg_hal_plf_scif_putc(void* __ch_data, cyg_uint8 c);
+void cyg_hal_plf_scif_init(int scif_index, int comm_index, 
+                           int rcv_vect, cyg_uint8* base);
+
+
+#endif // CYGNUM_HAL_SH_SH3_SCIF_PORTS
+//-----------------------------------------------------------------------------
+// end of sh3_scif.h
diff --git a/packages/hal/sh/arch/current/src/hal_misc.c b/packages/hal/sh/arch/current/src/hal_misc.c
index c25decd28..b47723f22 100644
--- a/packages/hal/sh/arch/current/src/hal_misc.c
+++ b/packages/hal/sh/arch/current/src/hal_misc.c
@@ -125,12 +125,8 @@ cyg_hal_exception_handler(HAL_SavedRegisters *regs)
 //---------------------------------------------------------------------------
 // Default ISR
 externC cyg_uint32
-hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
 {
-    diag_printf("Interrupt: %d\n", vector);
-
-    CYG_FAIL("Spurious Interrupt!!!");
-
     return 0;
 }
 
@@ -205,5 +201,13 @@ cyg_hal_enable_caches(void)
     HAL_UCACHE_ENABLE();
 }
 
+//---------------------------------------------------------------------------
+// SH3 variant stuff
+// This should be split out...
+void
+hal_variant_init(void)
+{
+}
+
 //---------------------------------------------------------------------------
 // End of hal_misc.c
diff --git a/packages/hal/sh/arch/current/src/sh.ld b/packages/hal/sh/arch/current/src/sh.ld
index 332bd5170..b0bde1286 100644
--- a/packages/hal/sh/arch/current/src/sh.ld
+++ b/packages/hal/sh/arch/current/src/sh.ld
@@ -103,7 +103,7 @@ GROUP(libtarget.a libgcc.a)
       KEEP(*(SORT(.dtors*))) ___DTOR_END__ = ABSOLUTE(.);                     \
     . = ALIGN(8);                                                             \
     ___DEVTAB__ = ABSOLUTE (.); KEEP (*(SORT (.devtab*))) ___DEVTAB_END__ = ABSOLUTE (.); \
-    __NETDEVTAB__ = ABSOLUTE (.); KEEP (*(SORT (.netdevtab*))) __NETDEVTAB_END__ = ABSOLUTE (.); \
+    ___NETDEVTAB__ = ABSOLUTE (.); KEEP (*(SORT (.netdevtab*))) ___NETDEVTAB_END__ = ABSOLUTE (.); \
     } > _region_                                                                \
     __rom_data_start = LOADADDR(.data);                                       \
     __ram_data_end = .; PROVIDE(__ram_data_end = .);                          \
@@ -122,6 +122,7 @@ GROUP(libtarget.a libgcc.a)
 #include CYGHWR_MEMORY_LAYOUT_LDI
 #include CYGBLD_HAL_PLATFORM_H
 
-// Define VSR table to reside at fixed address.
+// Define VSR and vector tables to reside at fixed address.
 _hal_vsr_table = CYGHWR_HAL_VSR_TABLE;
+_hal_virtual_vector_table = CYGHWR_HAL_VECTOR_TABLE;
 
diff --git a/packages/hal/sh/arch/current/src/sh3_sci.c b/packages/hal/sh/arch/current/src/sh3_sci.c
new file mode 100644
index 000000000..f03ff64c7
--- /dev/null
+++ b/packages/hal/sh/arch/current/src/sh3_sci.c
@@ -0,0 +1,303 @@
+//=============================================================================
+//
+//      sh3_sci.c
+//
+//      Simple driver for the SH Serial Communication Interface (SCI)
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:jskov
+// Date:        1999-05-17
+// Description: Simple driver for the SH Serial Communication Interface
+//              Clients of this file can configure the behavior with:
+//              CYGNUM_SCI_PORTS:  number of SCI ports
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGNUM_HAL_SH_SH3_SCI_PORTS
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP
+#include <cyg/hal/hal_if.h>             // Calling-if API
+#include <cyg/hal/sh_regs.h>            // serial register definitions
+
+#include <cyg/hal/sh3_sci.h>            // our header
+
+//--------------------------------------------------------------------------
+
+void
+cyg_hal_plf_sci_init_channel(const channel_data_t* chan)
+{
+    cyg_uint8 tmp;
+    cyg_uint8* base = chan->base;
+
+    // Disable Tx/Rx interrupts, but enable Tx/Rx
+    HAL_WRITE_UINT8(base+_REG_SCSCR,
+                    CYGARC_REG_SCSCR_TE|CYGARC_REG_SCSCR_RE);
+
+    // 8-1-no parity.
+    HAL_WRITE_UINT8(base+_REG_SCSMR, 0);
+
+    // Set speed to 38400
+    HAL_READ_UINT8(base+_REG_SCSMR, tmp);
+    tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
+    tmp |= CYGARC_SCBRR_CKSx(38400);
+    HAL_WRITE_UINT8(base+_REG_SCSMR, tmp);
+    HAL_WRITE_UINT8(base+_REG_SCBRR, CYGARC_SCBRR_N(38400));
+}
+
+static cyg_bool
+cyg_hal_plf_sci_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint8 sr;
+
+    HAL_READ_UINT8(base+_REG_SCSSR, sr);
+    if ((sr & CYGARC_REG_SCSSR_RDRF) == 0)
+        return false;
+
+    HAL_READ_UINT8(base+_REG_SCRDR, *ch);
+
+    // Clear buffer full flag.
+    HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_RDRF);
+
+    return true;
+}
+
+cyg_uint8
+cyg_hal_plf_sci_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_sci_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+void
+cyg_hal_plf_sci_putc(void* __ch_data, cyg_uint8 c)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint8 sr;
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+        HAL_READ_UINT8(base+_REG_SCSSR, sr);
+    } while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
+
+    HAL_WRITE_UINT8(base+_REG_SCTDR, c);
+
+    // Clear empty flag.
+    HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_TDRE);
+
+    // Hang around until the character has been safely sent.
+    do {
+        HAL_READ_UINT8(base+_REG_SCSSR, sr);
+    } while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static channel_data_t channels[CYGNUM_HAL_SH_SH3_SCI_PORTS];
+
+static void
+cyg_hal_plf_sci_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_sci_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_sci_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_sci_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_sci_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    int delay_count;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+    for(;;) {
+        res = cyg_hal_plf_sci_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US()(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_sci_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8 scr;
+    int ret = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
+        scr |= CYGARC_REG_SCSCR_RIE;
+        HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
+        scr &= ~CYGARC_REG_SCSCR_RIE;
+        HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_sci_isr(void *__ch_data, int* __ctrlc, 
+                    CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    cyg_uint8 c, sr;
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    int res = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    *__ctrlc = 0;
+    HAL_READ_UINT8(base+_REG_SCSSR, sr);
+    if (sr & CYGARC_REG_SCSSR_RDRF) {
+        HAL_READ_UINT8(base+_REG_SCRDR, c);
+
+        // Clear buffer full flag.
+        HAL_WRITE_UINT8(base+_REG_SCSSR, 
+                        CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
+
+        if( cyg_hal_is_break( &c , 1 ) )
+            *__ctrlc = 1;
+
+        res = CYG_ISR_HANDLED;
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+void
+cyg_hal_plf_sci_init(int sci_index, int comm_index, 
+                     int rcv_vect, cyg_uint8* base)
+{
+    channel_data_t* chan = &channels[sci_index];
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Initialize channel table
+    chan->base = base;
+    chan->isr_vector = rcv_vect;
+    chan->msec_timeout = 1000;
+
+    // Disable interrupts.
+    HAL_INTERRUPT_MASK(chan->isr_vector);
+
+    // Init channel
+    
+    cyg_hal_plf_sci_init_channel(chan);
+
+    // Setup procs in the vector table
+
+    // Initialize channel procs
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(comm_index);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_sci_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_sci_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_sci_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_sci_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_sci_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_sci_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_sci_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+#endif // CYGNUM_HAL_SH_SH3_SCI_PORTS
+
+//-----------------------------------------------------------------------------
+// end of sh_sci.c
diff --git a/packages/hal/sh/arch/current/src/sh3_scif.c b/packages/hal/sh/arch/current/src/sh3_scif.c
new file mode 100644
index 000000000..a87187656
--- /dev/null
+++ b/packages/hal/sh/arch/current/src/sh3_scif.c
@@ -0,0 +1,337 @@
+//=============================================================================
+//
+//      sh3_scif.c
+//
+//      Simple driver for the SH3 Serial Communication Interface with FIFO
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:jskov
+// Date:        2000-03-30
+// Description: Simple driver for the SH Serial Communication Interface
+//              The driver can be used for either the SCIF or the IRDA
+//              modules (the latter can act as the former).
+//              Clients of this file can configure the behavior with:
+//              CYGNUM_SCIF_PORTS: number of SCI ports
+//
+// Note:        It should be possible to configure a channel to IRDA mode.
+//              Worry about that when some board needs it.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGNUM_HAL_SH_SH3_SCIF_PORTS
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP
+#include <cyg/hal/hal_if.h>             // Calling-if API
+#include <cyg/hal/sh_regs.h>            // serial register definitions
+#include <cyg/hal/sh_stub.h>            // target_register_t
+
+#include <cyg/hal/sh3_scif.h>           // our header
+
+//--------------------------------------------------------------------------
+
+void
+cyg_hal_plf_scif_init_channel(const channel_data_t* chan)
+{
+    cyg_uint8* base = chan->base;
+    cyg_uint8 tmp;
+    cyg_uint16 sr;
+
+    // Disable everything.
+    HAL_WRITE_UINT8(base+_REG_SCSCR, 0);
+
+    // Reset FIFO.
+    HAL_WRITE_UINT8(base+_REG_SCFCR, 
+                    CYGARC_REG_SCFCR2_TFRST|CYGARC_REG_SCFCR2_RFRST);
+
+    // 8-1-no parity.
+    HAL_WRITE_UINT8(base+_REG_SCSMR, 0);
+
+    // Set speed to 38400
+    HAL_READ_UINT8(base+_REG_SCSMR, tmp);
+    tmp &= ~CYGARC_REG_SCSMR2_CKSx_MASK;
+    tmp |= CYGARC_SCBRR2_CKSx(38400);
+    HAL_WRITE_UINT8(base+_REG_SCSMR, tmp);
+    HAL_WRITE_UINT8(base+_REG_SCBRR, CYGARC_SCBRR2_N(38400));
+
+    // Let things settle: Here we should should wait the equivalent of
+    // one bit interval, i.e. 1/38400 second, but until we have
+    // something like the Linux delay loop, it's hard to do reliably. So
+    // just move on and hope for the best (this is unlikely to cause
+    // problems since the CPU has just come out of reset anyway).
+
+    // Clear status register (read back first).
+    HAL_READ_UINT16(base+_REG_SCSSR, sr);
+    HAL_WRITE_UINT16(base+_REG_SCSSR, 0);
+
+    // Bring FIFO out of reset and set to trigger on every char in
+    // FIFO (or C-c input would not be processed).
+    HAL_WRITE_UINT8(base+_REG_SCFCR, 
+                    CYGARC_REG_SCFCR2_RTRG_1|CYGARC_REG_SCFCR2_TTRG_1);
+
+    // Leave Tx/Rx interrupts disabled, but enable Tx/Rx
+    HAL_WRITE_UINT8(base+_REG_SCSCR, 
+                    CYGARC_REG_SCSCR2_TE|CYGARC_REG_SCSCR2_RE);
+}
+
+static cyg_bool
+cyg_hal_plf_scif_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint16 fdr, sr;
+
+    HAL_READ_UINT16(base+_REG_SCFDR, fdr);
+    if ((fdr & CYGARC_REG_SCFDR2_RCOUNT_MASK) == 0)
+        return false;
+
+    HAL_READ_UINT8(base+_REG_SCFRDR, *ch);
+
+    // Clear FIFO full flag (read before clearing)
+    HAL_READ_UINT16(base+_REG_SCSSR, sr);
+    HAL_WRITE_UINT16(base+_REG_SCSSR,
+                    CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF);
+
+    return true;
+}
+
+cyg_uint8
+cyg_hal_plf_scif_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_scif_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+void
+cyg_hal_plf_scif_putc(void* __ch_data, cyg_uint8 c)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint16 fdr, sr;
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+        HAL_READ_UINT16(base+_REG_SCFDR, fdr);
+    } while (((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) >> CYGARC_REG_SCFDR2_TCOUNT_shift) == 16);
+
+    HAL_WRITE_UINT8(base+_REG_SCFTDR, c);
+
+    // Clear FIFO-empty/transmit end flags (read back SR first)
+    HAL_READ_UINT16(base+_REG_SCSSR, sr);
+    HAL_WRITE_UINT16(base+_REG_SCSSR, CYGARC_REG_SCSSR2_CLEARMASK   
+                     & ~(CYGARC_REG_SCSSR2_TDFE | CYGARC_REG_SCSSR2_TEND ));
+
+    // Hang around until the character has been safely sent.
+    do {
+        HAL_READ_UINT16(base+_REG_SCFDR, fdr);
+    } while ((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) != 0);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static channel_data_t channels[CYGNUM_HAL_SH_SH3_SCIF_PORTS];
+
+static void
+cyg_hal_plf_scif_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_scif_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_scif_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_scif_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_scif_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    int delay_count;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+    for(;;) {
+        res = cyg_hal_plf_scif_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US()(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_scif_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8 scr;
+    int ret = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
+        scr |= CYGARC_REG_SCSCR2_RIE;
+        HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
+        scr &= ~CYGARC_REG_SCSCR2_RIE;
+        HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_scif_isr(void *__ch_data, int* __ctrlc, 
+                     CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    cyg_uint8 c;
+    cyg_uint16 fdr, sr;
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    int res = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    *__ctrlc = 0;
+    HAL_READ_UINT16(base+_REG_SCFDR, fdr);
+    if ((fdr & CYGARC_REG_SCFDR2_RCOUNT_MASK) != 0) {
+        HAL_READ_UINT8(base+_REG_SCFRDR, c);
+
+        // Clear buffer full flag (read back first).
+        HAL_READ_UINT16(base+_REG_SCSSR, sr);
+        HAL_WRITE_UINT16(base+_REG_SCSSR, 
+                         CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF);
+
+        if( cyg_hal_is_break( &c , 1 ) )
+            *__ctrlc = 1;
+
+        res = CYG_ISR_HANDLED;
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+void
+cyg_hal_plf_scif_init(int scif_index, int comm_index, 
+                      int rcv_vect, cyg_uint8* base)
+{
+    channel_data_t* chan = &channels[scif_index];
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Initialize channel table
+    chan->base = base;
+    chan->isr_vector = rcv_vect;
+    chan->msec_timeout = 1000;
+
+    // Disable interrupts.
+    HAL_INTERRUPT_MASK(chan->isr_vector);
+
+    // Init channel
+    cyg_hal_plf_scif_init_channel(chan);
+
+    // Setup procs in the vector table
+
+    // Initialize channel procs
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(comm_index);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_scif_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_scif_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_scif_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_scif_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_scif_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_scif_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_scif_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+#endif // CYGNUM_HAL_SH_SH3_SCIF_PORTS
+
+//-----------------------------------------------------------------------------
+// end of sh3_scif.c
diff --git a/packages/hal/sh/arch/current/src/vectors.S b/packages/hal/sh/arch/current/src/vectors.S
index 039352c75..9174087a2 100644
--- a/packages/hal/sh/arch/current/src/vectors.S
+++ b/packages/hal/sh/arch/current/src/vectors.S
@@ -32,7 +32,7 @@
 #######DESCRIPTIONBEGIN####
 ##
 ## Author(s):    jskov
-## Contributors: jskov
+## Contributors: jskov, gthomas
 ## Date:         1999-05-01
 ## Purpose:      SH exception vectors
 ## Description:  This file defines the code placed into the exception
@@ -97,167 +97,18 @@
 # be expected to provide the proper address space (at that time we
 # jump to the VMA base of the code).
 
+        .org    0x000
         .globl __reset;
 __reset:
-
-        # Initialize CPU
-        mov.l   $nCYG_SR,r1             ! Put CPU in a well-known state
-        ldc     r1,sr
-        mov     #0,r0
-        mov     #CYGARC_REG_CCR,r1      ! Disable cache
-        mov.l   r0,@r1
-        mov     #CYGARC_REG_MMUCR,r1    ! Disable MMU
-        mov.l   r0,@r1
-        mov     #CYGARC_REG_BBRA,r1     ! Disable UBC Channel A
-        mov.w   r0,@r1
-        mov     #CYGARC_REG_BBRB,r1     ! Disable UBC Channel B
-        mov.w   r0,@r1
-        mov     #CYGARC_REG_BRCR,r1     ! Reset UBC common register
-        mov.w   r0,@r1
-        mov.l   $CYGARC_REG_TSTR,r1     ! Disable timers
-        mov.b   r0,@r1
-        mov.l   $CYGARC_REG_IPRA,r1     ! Disable interrupt request sources
-        mov.w   r0,@r1
-        mov.l   $CYGARC_REG_IPRB,r1
-        mov.w   r0,@r1
-#ifdef CYGARC_SH_MOD_INTC_V2
-        mov.l   $CYGARC_REG_IPRC,r1
-        mov.w   r0,@r1
-        mov.l   $CYGARC_REG_IPRD,r1
-        mov.w   r0,@r1
-        mov.l   $CYGARC_REG_IPRE,r1
-        mov.w   r0,@r1
-        mov.l   $CYGARC_REG_ICR1,r1     ! Set interrupt controller to IRQ mode
-        mov.w   r0,@r1
-#endif
-
-        # Initialize VBR if necessary
-#if     !defined(CYG_HAL_STARTUP_RAM) ||                \
-        (       defined(CYG_HAL_STARTUP_RAM) &&         \
-                !defined(CYGSEM_HAL_USE_ROM_MONITOR))
-        mov.l   $__reset,r1             ! Set VBR
-        ldc     r1,vbr
-#endif
-
-        
-#ifdef __DEBUG
-        mov     #0,r0
-        mov     #1,r1
-        mov     #2,r2
-        mov     #3,r3
-        mov     #4,r4
-        mov     #5,r5
-        mov     #6,r6
-        mov     #7,r7
-        mov     #8,r8
-        mov     #9,r9
-        mov     #10,r10
-        mov     #11,r11
-        mov     #12,r12
-        mov     #13,r13
-        mov     #14,r14
-#endif
-        
-        # Call platform specific hardware initialization
-        # This may include memory controller initialization. It is not
-        # safe to access RAM until after this point.
-        hal_hardware_init
-
-        # Now copy necessary bits to RAM and jump to the VMA base
-
-#ifdef CYG_HAL_STARTUP_ROM
-
-        # Copy data from ROM to ram
-        mov.l   $__rom_data_start,r3    ! r3 = rom start
-        mov.l   $__ram_data_start,r4    ! r4 = ram start
-        mov.l   $__ram_data_end,r5      ! r5 = ram end
-        
-        cmp/eq  r4,r5                   ! skip if no data
-        bt      2f
-1:      mov.l   @r3+,r0                 ! get word from ROM
-        mov.l   r0,@r4                  ! store in RAM
-        add     #4,r4
-        cmp/eq  r4,r5                   ! compare
-        bf      1b                      ! loop if not yet done
-2:
-
-        # Jump to the proper VMA base of the code.
-        mov.l   $_complete_setup,r0
-        jmp     @r0
-         nop
-        .align 2
-
-        .extern __rom_data_start
-        .extern __ram_data_start
-        .extern __ram_data_end
-
-$__rom_data_start:
-        .long   __rom_data_start
-$__ram_data_start:
-        .long   __ram_data_start
-$__ram_data_end:
-        .long   __ram_data_end
-$_complete_setup:
-        .long _complete_setup
-
-#elif defined(CYG_HAL_STARTUP_ROMRAM)
-
-        # Copy everything to the proper VMA base and jump to it.
-        mov.l   $_vectors_lma,r0
-        mov.l   $_vectors_vma,r1
-        mov.l   $_end,r2
-1:      mov.l   @r0+,r3                 ! get word from ROM
-        mov.l   r3,@r1                  ! store in RAM
-        add     #4,r1
-        cmp/eq  r1,r2                   ! compare
-        bf      1b                      ! loop if not yet done
-        mov.l   $_complete_setup,r0
+        mov.l   $__reset_platform,r0
         jmp     @r0
          nop
-        .align  2
-
-        .extern __vector_code_lma
 
-$_vectors_lma:
-        .long __vector_code_lma
-$_vectors_vma:
-        .long __reset
-$_end:
-        .long _end
-$_complete_setup:
-        .long _complete_setup
-
-#else
-
-        # Jump to remaining setup code. Relative branch is OK since VMA=LMA.
-        bra   _complete_setup
+# Note: this is the unmapped, shadow address of the start of code
+# Sadly, it is too far to just branch to.                        
+$__reset_platform:      
+        .long   __reset_platform-__reset+0xA0000000
                 
-#endif
-
-        .align  2
-
-$nCYG_SR:
-        .long   CYG_SR
-$CYGARC_REG_TSTR:
-        .long   CYGARC_REG_TSTR
-$CYGARC_REG_IPRA:
-        .long   CYGARC_REG_IPRA
-$CYGARC_REG_IPRB:
-        .long   CYGARC_REG_IPRB
-#ifdef CYGARC_SH_MOD_INTC_V2
-$CYGARC_REG_IPRC:
-        .long   CYGARC_REG_IPRC
-$CYGARC_REG_IPRD:
-        .long   CYGARC_REG_IPRD
-$CYGARC_REG_IPRE:
-        .long   CYGARC_REG_IPRE
-$CYGARC_REG_ICR1:
-        .long   CYGARC_REG_ICR1
-#endif
-
-$__reset:
-        .long   __reset
-
 #---------------------------------------------------------------------------
 # Exception entry
         
@@ -280,91 +131,7 @@ __exception:
         .align   2
 $_hal_vsr_table:
         .long   _hal_vsr_table
-
-#-----------------------------------------------------------------------------
-# Complete target initialization and setup.
-# [Placed here to make use of gap between exception and interrupt entry points]
-# After this point we can use absolute addressing modes and access all the
-# memory in the system.
-
-_complete_setup:
-                
-        # Set up monitor related stuff (vectors primarily)
-        hal_mon_init
-
-        # set up stack
-        mov.l    $__startup_stack,r15
-
-        # clear BSS
-        mov.l   $__bss_start,r3         ! r3 = start
-        mov.l   $__bss_end,r4           ! r4 = end
-        mov     #0,r0                   ! r0 = 0
-1:      cmp/eq  r3,r4                   ! skip if no bss
-        bt      2f
-        mov.l   r0,@r3                  ! store zero
-        add     #4,r3
-        bra     1b                      ! loop
-         nop
-2:
-
-        # It is now safe to call C functions which may rely on initialized
-        # data.
         
-#        # Initialize MMU.
-#        .extern hal_MMU_init
-#        jsr      hal_MMU_init
-#         nop
-        
-        # Enable caches
-        mov.l    $_cyg_hal_enable_caches,r1
-        jsr      @r1
-         nop
-
-        # call c++ constructors
-        mov.l    $_cyg_hal_invoke_constructors,r1
-        jsr      @r1
-         nop
-
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-        mov.l    $_initialize_stub,r1
-        jsr      @r1
-         nop
-#endif
-
-        mov.l    $_cyg_start,r1
-        jsr      @r1
-         nop
-9:      
-        bra      9b                     ! if we return, loop
-         nop
-
-        .align  2
-$__startup_stack:
-        .long   __startup_stack
-
-        .extern __bss_start
-        .extern __bss_end
-        .extern _cyg_hal_invoke_constructors
-        .extern _cyg_start
-
-$__bss_start:
-        .long   __bss_start
-$__bss_end:
-        .long   __bss_end
-$_cyg_hal_invoke_constructors:
-        .long   _cyg_hal_invoke_constructors
-$_cyg_hal_enable_caches:
-        .long   _cyg_hal_enable_caches
-$_cyg_start:
-        .long   _cyg_start
-
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-        .extern _initialize_stub
-$_initialize_stub:
-        .long   _initialize_stub
-#endif
-
-
 #---------------------------------------------------------------------------
 # This code handles the common part of all exception handlers.
 # It saves the machine state onto the stack  and then calls
@@ -530,7 +297,6 @@ __interrupt:
 $_hal_vsr_table_int:
         .long    _hal_vsr_table+CYGNUM_HAL_VECTOR_INTERRUPT*4
 
-
 #---------------------------------------------------------------------------
 # Common interrupt handling code.
 
@@ -669,24 +435,14 @@ $_cyg_instrument:
 #endif //  CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
 
 
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-        mov     r4,r10                   ! save across call.
-        mov     #CYGARC_SHREG_PC,r4
-        add     r8,r4
-        mov.l   @r4,r4
-        mov.l   $_cyg_hal_gdb_isr,r1
-        jsr     @r1                     ! returns 1 if the proper isr must be
-         nop                            ! called (i.e., if it was not a GDB 
-        mov     r10,r4                  ! interrupt)
-        cmp/eq  #0,r0
-        bt      skip_isr_proper
-        bra     2f
-         nop
-        .align  2
-        .extern _cyg_hal_gdb_isr
-$_cyg_hal_gdb_isr:
-        .long   _cyg_hal_gdb_isr
-2:
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+	# If we are supporting Ctrl-C interrupts from GDB, we must squirrel
+	# away a pointer to the save interrupt state here so that we can
+	# plant a breakpoint at some later time.
+	
+	mov.l	$_hal_saved_interrupt_state,r1
+	mov.l	r8,@r1
 #endif
 
 #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
@@ -731,12 +487,6 @@ $_cyg_hal_gdb_isr:
         jsr     @r1                     ! r4=vector, r5=data
          nop
 
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-        # If interrupt was caused by GDB, the ISR call above
-        # is skipped by jumping here.
-skip_isr_proper:
-#endif
-
 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
 
         # If we are returning from the last nested interrupt, move back
@@ -867,6 +617,13 @@ $int_state_marker:
         .long   0x77777771
 #endif
 
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+        .extern _hal_saved_interrupt_state
+$_hal_saved_interrupt_state:
+        .long   _hal_saved_interrupt_state
+#endif
+
 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK 
 $__interrupt_stack:
         .long   __interrupt_stack
@@ -909,6 +666,266 @@ $_interrupt_end:
         .long   _interrupt_end
 #endif
 
+#---------------------------------------------------------------------------
+# Platform initialization (reset)
+__reset_platform:               
+        # Initialize CPU
+        mov.l   $nCYG_SR,r1             ! Put CPU in a well-known state
+        ldc     r1,sr
+        mov     #0,r0
+        mov     #CYGARC_REG_CCR,r1      ! Disable cache
+        mov.l   r0,@r1
+        mov     #CYGARC_REG_MMUCR,r1    ! Disable MMU
+        mov.l   r0,@r1
+        mov     #CYGARC_REG_BBRA,r1     ! Disable UBC Channel A
+        mov.w   r0,@r1
+        mov     #CYGARC_REG_BBRB,r1     ! Disable UBC Channel B
+        mov.w   r0,@r1
+        mov     #CYGARC_REG_BRCR,r1     ! Reset UBC common register
+        mov.w   r0,@r1
+        mov.l   $CYGARC_REG_TSTR,r1     ! Disable timers
+        mov.b   r0,@r1
+        mov.l   $CYGARC_REG_IPRA,r1     ! Disable interrupt request sources
+        mov.w   r0,@r1
+        mov.l   $CYGARC_REG_IPRB,r1
+        mov.w   r0,@r1
+#ifdef CYGARC_SH_MOD_INTC_V2
+        mov.l   $CYGARC_REG_IPRC,r1
+        mov.w   r0,@r1
+        mov.l   $CYGARC_REG_IPRD,r1
+        mov.w   r0,@r1
+        mov.l   $CYGARC_REG_IPRE,r1
+        mov.w   r0,@r1
+        mov.l   $CYGARC_REG_ICR1,r1     ! Set interrupt controller to IRQ mode
+        mov.w   r0,@r1
+#endif
+
+        # Initialize VBR if necessary
+#if     !defined(CYG_HAL_STARTUP_RAM) ||                \
+        (       defined(CYG_HAL_STARTUP_RAM) &&         \
+                !defined(CYGSEM_HAL_USE_ROM_MONITOR))
+        mov.l   $__reset,r1             ! Set VBR
+        ldc     r1,vbr
+#endif
+
+        
+#ifdef __DEBUG
+        mov     #0,r0
+        mov     #1,r1
+        mov     #2,r2
+        mov     #3,r3
+        mov     #4,r4
+        mov     #5,r5
+        mov     #6,r6
+        mov     #7,r7
+        mov     #8,r8
+        mov     #9,r9
+        mov     #10,r10
+        mov     #11,r11
+        mov     #12,r12
+        mov     #13,r13
+        mov     #14,r14
+#endif
+        
+        # Call platform specific hardware initialization
+        # This may include memory controller initialization. It is not
+        # safe to access RAM until after this point.
+        hal_hardware_init
+
+        # Now copy necessary bits to RAM and jump to the VMA base
+
+#ifdef CYG_HAL_STARTUP_ROM
+
+        # Copy data from ROM to ram
+        mov.l   $__rom_data_start,r3    ! r3 = rom start
+        mov.l   $__ram_data_start,r4    ! r4 = ram start
+        mov.l   $__ram_data_end,r5      ! r5 = ram end
+        
+        cmp/eq  r4,r5                   ! skip if no data
+        bt      2f
+1:      mov.l   @r3+,r0                 ! get word from ROM
+        mov.l   r0,@r4                  ! store in RAM
+        add     #4,r4
+        cmp/eq  r4,r5                   ! compare
+        bf      1b                      ! loop if not yet done
+2:
+
+        # Jump to the proper VMA base of the code.
+        mov.l   $_complete_setup,r0
+        jmp     @r0
+         nop
+        .align 2
+
+        .extern __rom_data_start
+        .extern __ram_data_start
+        .extern __ram_data_end
+
+$__rom_data_start:
+        .long   __rom_data_start
+$__ram_data_start:
+        .long   __ram_data_start
+$__ram_data_end:
+        .long   __ram_data_end
+$_complete_setup:
+        .long _complete_setup
+
+#elif defined(CYG_HAL_STARTUP_ROMRAM)
+
+        # Copy everything to the proper VMA base and jump to it.
+        mov.l   $_vectors_lma,r0
+        mov.l   $_vectors_vma,r1
+        mov.l   $_end,r2
+1:      mov.l   @r0+,r3                 ! get word from ROM
+        mov.l   r3,@r1                  ! store in RAM
+        add     #4,r1
+        cmp/eq  r1,r2                   ! compare
+        bf      1b                      ! loop if not yet done
+        mov.l   $_complete_setup,r0
+        jmp     @r0
+         nop
+        .align  2
+
+        .extern __vector_code_lma
+
+$_vectors_lma:
+        .long __vector_code_lma
+$_vectors_vma:
+        .long __reset
+$_end:
+        .long _end
+$_complete_setup:
+        .long _complete_setup
+
+#else
+
+        # Jump to remaining setup code. Relative branch is OK since VMA=LMA.
+        bra   _complete_setup
+                
+#endif
+
+        .align  2
+
+$nCYG_SR:
+        .long   CYG_SR
+$CYGARC_REG_TSTR:
+        .long   CYGARC_REG_TSTR
+$CYGARC_REG_IPRA:
+        .long   CYGARC_REG_IPRA
+$CYGARC_REG_IPRB:
+        .long   CYGARC_REG_IPRB
+#ifdef CYGARC_SH_MOD_INTC_V2
+$CYGARC_REG_IPRC:
+        .long   CYGARC_REG_IPRC
+$CYGARC_REG_IPRD:
+        .long   CYGARC_REG_IPRD
+$CYGARC_REG_IPRE:
+        .long   CYGARC_REG_IPRE
+$CYGARC_REG_ICR1:
+        .long   CYGARC_REG_ICR1
+#endif
+
+$__reset:
+        .long   __reset
+
+#-----------------------------------------------------------------------------
+# Complete target initialization and setup.
+# After this point we can use absolute addressing modes and access all the
+# memory in the system.
+
+_complete_setup:
+                
+        # Set up monitor related stuff (vectors primarily)
+        hal_mon_init
+
+        # set up stack
+        mov.l    $__startup_stack,r15
+
+        # clear BSS
+        mov.l   $__bss_start,r3         ! r3 = start
+        mov.l   $__bss_end,r4           ! r4 = end
+        mov     #0,r0                   ! r0 = 0
+1:      cmp/eq  r3,r4                   ! skip if no bss
+        bt      2f
+        mov.l   r0,@r3                  ! store zero
+        add     #4,r3
+        bra     1b                      ! loop
+         nop
+2:
+
+        # It is now safe to call C functions which may rely on initialized
+        # data.
+        
+#        # Initialize MMU.
+#        .extern hal_MMU_init
+#        jsr      hal_MMU_init
+#         nop
+        
+        # Enable caches
+        mov.l    $_cyg_hal_enable_caches,r1
+        jsr      @r1
+         nop
+
+        # Variant HALs may need to do something special before we continue
+        mov.l    $_hal_variant_init,r1
+        jsr      @r1
+         nop
+
+        # Platform initialization
+        mov.l    $_hal_platform_init,r1
+        jsr      @r1
+         nop
+        
+        # call c++ constructors
+        mov.l    $_cyg_hal_invoke_constructors,r1
+        jsr      @r1
+         nop
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+        mov.l    $_initialize_stub,r1
+        jsr      @r1
+         nop
+#endif
+
+        mov.l    $_cyg_start,r1
+        jsr      @r1
+         nop
+9:      
+        bra      9b                     ! if we return, loop
+         nop
+
+        .align  2
+$__startup_stack:
+        .long   __startup_stack
+
+        .extern __bss_start
+        .extern __bss_end
+        .extern _cyg_hal_invoke_constructors
+        .extern _hal_variant_init
+        .extern _hal_platform_init
+        .extern _cyg_start
+
+$__bss_start:
+        .long   __bss_start
+$__bss_end:
+        .long   __bss_end
+$_cyg_hal_invoke_constructors:
+        .long   _cyg_hal_invoke_constructors
+$_cyg_hal_enable_caches:
+        .long   _cyg_hal_enable_caches
+$_hal_variant_init:
+        .long   _hal_variant_init
+$_hal_platform_init:
+        .long   _hal_platform_init
+$_cyg_start:
+        .long   _cyg_start
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+        .extern _initialize_stub
+$_initialize_stub:
+        .long   _initialize_stub
+#endif
+                        
+
 #---------------------------------------------------------------------------
 # Cache operations
 # These need to be written in assembly to ensure they do not rely on data
diff --git a/packages/hal/sh/cq7708/current/ChangeLog b/packages/hal/sh/cq7708/current/ChangeLog
index 83f516ab0..5a359e0b4 100644
--- a/packages/hal/sh/cq7708/current/ChangeLog
+++ b/packages/hal/sh/cq7708/current/ChangeLog
@@ -1,3 +1,23 @@
+2000-06-29  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_diag.c: serial driver API changes.
+
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* src/plf_stub.c: [deleted]
+	* src/plf_misc.c: 
+	* src/hal_diag.c: 
+	* include/pkgconf/mlt_sh_sh7708_cq7708_ram.h: 
+	* include/pkgconf/mlt_sh_sh7708_cq7708_ram.ldi: 
+	* include/pkgconf/mlt_sh_sh7708_cq7708_ram.mlt: 
+	* include/pkgconf/mlt_sh_sh7708_cq7708_rom.h: 
+	* include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi: 
+	* include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt: 
+	* include/plf_stub.h: 
+	* include/hal_diag.h: 
+	* cdl/hal_sh_sh7708_cq7708.cdl: 
+	Changed to use virtual vector code.
+
 2000-06-06  Jesper Skov  <jskov@redhat.com>
 
 	* cdl/hal_sh_sh7708_cq7708.cdl: Added CYGHWR_HAL_SH_BOARD_SPEED
diff --git a/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl b/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl
index 6f764ce7b..c2b94bede 100644
--- a/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl
+++ b/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl
@@ -49,16 +49,19 @@ cdl_package CYGPKG_HAL_SH_SH7708_CQ7708 {
         The cq HAL package provides the support needed to run
         eCos on a CqREEK SH7708 board."
 
-    compile       hal_diag.c plf_stub.c plf_misc.c
+    compile       hal_diag.c plf_misc.c
 
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
 
     define_proc {
         puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_sh.h>"
         puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_sh_sh7708_cq7708.h>"
 
+        puts $::cdl_header "#define CYGNUM_HAL_SH_SH3_SCI_PORTS 1"
         puts $::cdl_header "#define CYGHWR_HAL_VSR_TABLE 0x0c000000"
+        puts $::cdl_header "#define CYGHWR_HAL_VECTOR_TABLE 0x0c000100"
     }
 
     cdl_component CYG_HAL_STARTUP {
@@ -79,6 +82,33 @@ cdl_package CYGPKG_HAL_SH_SH7708_CQ7708 {
            equivalent technology."
     }
 
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        calculated   1
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+           The CQ/7708 board has only one serial port. This option
+           chooses which port will be used to connect to a host
+           running GDB."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+        display          "Diagnostic serial port"
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+           The CQ/7708 board has only one serial port.  This option
+           chooses which port will be used for diagnostic output."
+    }
+
     cdl_option CYGHWR_HAL_SH_BOARD_SPEED {
         display          "Development board clock speed (MHz)"
         flavor           data
@@ -162,8 +192,8 @@ cdl_package CYGPKG_HAL_SH_SH7708_CQ7708 {
             requires CYGSEM_HAL_ROM_MONITOR
             requires CYGBLD_BUILD_COMMON_GDB_STUBS
             requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-            requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-            requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+            requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+            requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
             requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
             requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
             no_define
diff --git a/packages/hal/sh/cq7708/current/include/hal_diag.h b/packages/hal/sh/cq7708/current/include/hal_diag.h
index dcf08a9ae..aad6245ef 100644
--- a/packages/hal/sh/cq7708/current/include/hal_diag.h
+++ b/packages/hal/sh/cq7708/current/include/hal_diag.h
@@ -49,6 +49,16 @@
 
 #include <cyg/infra/cyg_type.h>
 
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+#else // everything by steam
+
 //-----------------------------------------------------------------------------
 // functions implemented in hal_diag.c
 
@@ -66,6 +76,8 @@ externC void hal_diag_read_char(char *c);
 
 #define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_)
 
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
 //-----------------------------------------------------------------------------
 // Simple LED control.
 externC void hal_diag_led_on( void );
diff --git a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h
index 384921661..6be1936b8 100644
--- a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h
+++ b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h
@@ -5,8 +5,8 @@
 #include <cyg/infra/cyg_type.h>
 #include <stddef.h>
 
-#define CYGMEM_REGION_ram (0xc000100)
-#define CYGMEM_REGION_ram_SIZE (0x3fff00)
+#define CYGMEM_REGION_ram (0xc000200)
+#define CYGMEM_REGION_ram_SIZE (0x3ffe00)
 #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
 #define CYGMEM_REGION_rom (0xa0000000)
 #define CYGMEM_REGION_rom_SIZE (0x8000)
diff --git a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi
index 0f0653f4d..38836b0eb 100644
--- a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi
+++ b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi
@@ -4,7 +4,7 @@
 
 MEMORY
 {
-    ram : ORIGIN = 0xc000100, LENGTH = 0x3fff00
+    ram : ORIGIN = 0xc000200, LENGTH = 0x3ffe00
     rom : ORIGIN = 0xa0000000, LENGTH = 0x8000
 }
 
@@ -18,7 +18,7 @@ SECTIONS
     SECTION_rodata (rom, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
     SECTION_gcc_except_table (rom, ALIGN (0x1), LMA_EQ_VMA)
-    SECTION_data (ram, 0xc000100, FOLLOWING (.gcc_except_table))
+    SECTION_data (ram, 0xc000200, FOLLOWING (.gcc_except_table))
     SECTION_bss (ram, ALIGN (0x10), LMA_EQ_VMA)
     SECTIONS_END
 }
diff --git a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt
index f469a6d21..7454fc353 100644
--- a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt
+++ b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt
@@ -1,7 +1,7 @@
 version 0
-region ram c000100 3fff00 0 !
+region ram c000200 3ffe00 0 !
 region rom a0000000 8000 1 !
-section data 0 1 1 1 1 1 0 0 c000100 bss !
+section data 0 1 1 1 1 1 0 0 c000200 bss !
 section bss 0 10 0 1 0 0 0 0 !
 section vectors 0 1 0 1 1 1 1 1 a0000000 a0000000 text text !
 section text 0 4 0 1 0 1 0 1 fini fini !
diff --git a/packages/hal/sh/cq7708/current/include/plf_stub.h b/packages/hal/sh/cq7708/current/include/plf_stub.h
index 9fbddf8db..8dfe578f1 100644
--- a/packages/hal/sh/cq7708/current/include/plf_stub.h
+++ b/packages/hal/sh/cq7708/current/include/plf_stub.h
@@ -47,10 +47,6 @@
 #include <pkgconf/system.h>
 #include <pkgconf/hal.h>
 
-#ifdef CYGPKG_IO_SERIAL
-#include <pkgconf/io_serial.h>
-#endif
-
 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
 
 #include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM, externC
@@ -60,19 +56,16 @@
 #include <cyg/hal/hal_diag.h>           // hal_diag_led_on
 
 //----------------------------------------------------------------------------
-// Define serial stuff.
-externC void hal_sci_stub_init_serial( void );
-externC int  hal_sci_stub_get_char( void );
-externC void hal_sci_stub_put_char( int c );
-externC int  hal_sci_stub_interruptible( int state );
-externC void hal_sci_stub_init_break_irq( void );
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
 
-#define HAL_STUB_PLATFORM_INIT_SERIAL()       hal_sci_stub_init_serial()
-#define HAL_STUB_PLATFORM_GET_CHAR()          hal_sci_stub_get_char()
-#define HAL_STUB_PLATFORM_PUT_CHAR(c)         hal_sci_stub_put_char((c))
 #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
-#define HAL_STUB_PLATFORM_INTERRUPTIBLE       (&hal_sci_stub_interruptible)
-#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    hal_sci_stub_init_break_irq()
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
 
 //----------------------------------------------------------------------------
 // Stub initializer.
@@ -82,14 +75,15 @@ externC void hal_sci_stub_init_break_irq( void );
 # define HAL_STUB_PLATFORM_INIT()              CYG_EMPTY_STATEMENT
 #endif
 
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
 //----------------------------------------------------------------------------
 // Reset.
 // Block interrupts and cause an exception. This forces a reset.
 #define HAL_STUB_PLATFORM_RESET() \
     asm volatile ("ldc %0,sr;trapa #0x00;" : : "r" (CYGARC_REG_SR_BL))
     
-
-#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#define HAL_STUB_PLATFORM_RESET_ENTRY 0xa0000000
 
 //-----------------------------------------------------------------------------
 #endif // CYGONCE_HAL_PLF_STUB_H
diff --git a/packages/hal/sh/cq7708/current/src/hal_diag.c b/packages/hal/sh/cq7708/current/src/hal_diag.c
index 606081f3a..f5c2d9630 100644
--- a/packages/hal/sh/cq7708/current/src/hal_diag.c
+++ b/packages/hal/sh/cq7708/current/src/hal_diag.c
@@ -45,18 +45,63 @@
 
 #include <cyg/hal/hal_diag.h>           // our header.
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
-#include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
-#endif
-
 #include <cyg/infra/cyg_type.h>         // base types, externC
 #include <cyg/hal/hal_io.h>             // IO macros
 #include <cyg/hal/hal_intr.h>           // Interrupt macros
+#include <cyg/hal/sh3_sci.h>            // driver API
+#include <cyg/hal/hal_misc.h>           // Helper functions
 
-#include <cyg/hal/sh_sci.inl>
+#define SCI_BASE ((cyg_uint8*)0xfffffe80)
 
 //-----------------------------------------------------------------------------
 
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_sci_init(0, 0, CYGNUM_HAL_INTERRUPT_SCI_RXI, SCI_BASE);
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+//=============================================================================
+// Led control
+//=============================================================================
+#define LED   0xa8000000
+
+void
+hal_diag_led_on( void )
+{
+    HAL_WRITE_UINT8(LED, 0x18);
+}
+
+void
+hal_diag_led_off( void )
+{
+    HAL_WRITE_UINT8(LED, 0);
+}
+
+//=============================================================================
+// Compatibility with older stubs
+//=============================================================================
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+static channel_data_t channel = { (cyg_uint8*)SCI_BASE, 0, 0};
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+#include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
+#endif
+
 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs)
 
 #define CYG_HAL_DIAG_GDB
@@ -71,24 +116,21 @@
 
 void hal_diag_init(void)
 {
-    hal_sci_init_serial();
+    cyg_hal_plf_sci_init_channel(&channel);
 }
 
 void 
 hal_diag_write_char_serial( char c )
 {
-    hal_sci_put_char(c);
+    cyg_hal_plf_sci_putc(&channel, c);
 }
 
 void
 hal_diag_read_char(char *c)
 {
-    *c = (char) hal_sci_get_char();
+    *c = (char) cyg_hal_plf_sci_getc(&channel);
 }
 
-externC cyg_bool cyg_hal_is_break(char *buf, int size);
-externC void cyg_hal_user_break(CYG_ADDRWORD *regs);
-
 // Packet function
 void 
 hal_diag_write_char(char c)
@@ -124,26 +166,26 @@ hal_diag_write_char(char c)
             cyg_uint8 csum = 0;
             int i;
         
-            hal_diag_write_char_serial('$');
-            hal_diag_write_char_serial('O');
+            cyg_hal_plf_sci_putc(&channel, '$');
+            cyg_hal_plf_sci_putc(&channel, 'O');
             csum += 'O';
             for( i = 0; i < pos; i++ )
             {
                 char ch = line[i];
                 char h = hex[(ch>>4)&0xF];
                 char l = hex[ch&0xF];
-                hal_diag_write_char_serial(h);
-                hal_diag_write_char_serial(l);
+                cyg_hal_plf_sci_putc(&channel, h);
+                cyg_hal_plf_sci_putc(&channel, l);
                 csum += h;
                 csum += l;
             }
-            hal_diag_write_char_serial('#');
-            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
-            hal_diag_write_char_serial(hex[csum&0xF]);
+            cyg_hal_plf_sci_putc(&channel, '#');
+            cyg_hal_plf_sci_putc(&channel, hex[(csum>>4)&0xF]);
+            cyg_hal_plf_sci_putc(&channel, hex[csum&0xF]);
 
             // Wait for the ACK character '+' from GDB here and handle
             // receiving a ^C instead.
-            hal_diag_read_char(&c1);
+            c1 = (char) cyg_hal_plf_sci_getc(&channel);
 
             if( c1 == '+' )
                 break;              // a good acknowledge
@@ -165,25 +207,11 @@ hal_diag_write_char(char c)
 #endif
     }
 #else // CYG_HAL_DIAG_GDB
-    hal_diag_write_char_serial(c);
+    cyg_hal_plf_sci_putc(&channel, c);
 #endif
 }
 
-//-----------------------------------------------------------------------------
-// Led control
-#define LED   0xa8000000
-
-void
-hal_diag_led_on( void )
-{
-    HAL_WRITE_UINT8(LED, 0x18);
-}
-
-void
-hal_diag_led_off( void )
-{
-    HAL_WRITE_UINT8(LED, 0);
-}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
 //-----------------------------------------------------------------------------
 // End of hal_diag.c
diff --git a/packages/hal/sh/cq7708/current/src/plf_misc.c b/packages/hal/sh/cq7708/current/src/plf_misc.c
index 2ffea80af..861cb7fb6 100644
--- a/packages/hal/sh/cq7708/current/src/plf_misc.c
+++ b/packages/hal/sh/cq7708/current/src/plf_misc.c
@@ -44,59 +44,14 @@
 
 #include <pkgconf/hal.h>
 
-#include <cyg/infra/cyg_type.h>         // Base types
-
-#include <cyg/hal/hal_arch.h>           // architectural definitions
-
-#include <cyg/hal/hal_intr.h>           // Interrupt handling
-
-#include <cyg/hal/hal_cache.h>          // Cache handling
-
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-#include <cyg/hal/hal_stub.h>           // stub functionality
-#endif
+#include <cyg/hal/hal_if.h>             // interfacing API
 
 //--------------------------------------------------------------------------
-// Functions to support the detection and execution of a user provoked
-// program break. These are usually called from interrupt routines.
-
-cyg_bool
-cyg_hal_is_break(char *buf, int size)
-{
-    while( size )
-        if( buf[--size] == 0x03 ) return true;
-
-    return false;
-}
-
 void
-cyg_hal_user_break( CYG_ADDRWORD *regs )
+hal_platform_init(void)
 {
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-    HAL_SavedRegisters *__sreg = (HAL_SavedRegisters *)regs;
-    target_register_t __pc;
-
-    if (__sreg)
-        __pc = (target_register_t) __sreg->pc;
-    else
-        __pc = (target_register_t) &&safe_breakpoint;
-    
-    // Note: This would be better for the else case but doesn't work
-    // at the moment.  CR: 101357
-    // __pc = (target_register_t) __builtin_return_address(0);
-
-    cyg_hal_gdb_interrupt (__pc);
-
- safe_breakpoint:
-#elif defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs)
-
-    // Note: Need to communicate to the ROM stub instead
-    HAL_BREAKPOINT(breakinst);
-
-#else
-
-    HAL_BREAKPOINT(breakinst);
-
-#endif
-
+    hal_if_init();
 }
+
+//--------------------------------------------------------------------------
+// eof plf_misc.c
diff --git a/packages/hal/sh/edk/current/ChangeLog b/packages/hal/sh/edk/current/ChangeLog
index 46506da3a..2761b3ed8 100644
--- a/packages/hal/sh/edk/current/ChangeLog
+++ b/packages/hal/sh/edk/current/ChangeLog
@@ -1,3 +1,30 @@
+2000-06-29  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_diag.c: serial driver API changes.
+
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_diag.c: Include hal_if file.
+	
+2000-06-28  Jesper Skov  <jskov@redhat.com>
+
+	* src/plf_misc.c: 
+	* src/hal_diag.c:
+	* src/plf_stub.c: [deleted]
+	* include/pkgconf/mlt_sh_edk7708_ram.h: 
+	* include/pkgconf/mlt_sh_edk7708_ram.ldi: 
+	* include/pkgconf/mlt_sh_edk7708_ram.mlt: 
+	* include/pkgconf/mlt_sh_edk7708_rom.h: 
+	* include/pkgconf/mlt_sh_edk7708_rom.ldi: 
+	* include/pkgconf/mlt_sh_edk7708_rom.mlt: 
+	* include/pkgconf/mlt_sh_edk7708_romram.h: 
+	* include/pkgconf/mlt_sh_edk7708_romram.ldi: 
+	* include/pkgconf/mlt_sh_edk7708_romram.mlt: 
+	* include/plf_stub.h: 
+	* include/hal_diag.h: 
+	* cdl/hal_sh_edk7708.cdl: 
+	Changed to use virtual vector table.
+
 1999-06-19  John Dallaway  <jld@redhat.com>
 
 	* cdl/hal_sh_edk7708.cdl: Tidy display strings.
diff --git a/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl b/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl
index ec6c792ea..86161c19e 100644
--- a/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl
+++ b/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl
@@ -49,16 +49,19 @@ cdl_package CYGPKG_HAL_SH_EDK7708 {
         The edk HAL package provides the support needed to run
         eCos on a Hitachi SH3 EDK7708 board."
 
-    compile       hal_diag.c plf_stub.c plf_misc.c
+    compile       hal_diag.c plf_misc.c
 
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
 
     define_proc {
         puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_sh.h>"
         puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_sh_edk7708.h>"
 
+        puts $::cdl_header "#define CYGNUM_HAL_SH_SH3_SCI_PORTS 1"
         puts $::cdl_header "#define CYGHWR_HAL_VSR_TABLE 0x08000000"
+        puts $::cdl_header "#define CYGHWR_HAL_VECTOR_TABLE 0x08000100"
     }
 
     cdl_component CYG_HAL_STARTUP {
@@ -82,6 +85,33 @@ cdl_package CYGPKG_HAL_SH_EDK7708 {
            increased RAM footprint."
     }
 
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        calculated   1
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+           The EDK/7708 board has only one serial port. This option
+           chooses which port will be used to connect to a host
+           running GDB."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+        display          "Diagnostic serial port"
+        flavor data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    0
+        description      "
+           The EDK/7708 board has only one serial port.  This option
+           chooses which port will be used for diagnostic output."
+    }
+
     cdl_option CYGHWR_HAL_SH_BOARD_SPEED {
         display          "Development board clock speed (MHz)"
         flavor           data
@@ -165,8 +195,8 @@ cdl_package CYGPKG_HAL_SH_EDK7708 {
             requires CYGSEM_HAL_ROM_MONITOR
             requires CYGBLD_BUILD_COMMON_GDB_STUBS
             requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-            requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-            requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+            requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+            requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
             requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
             requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
             no_define
diff --git a/packages/hal/sh/edk/current/include/hal_diag.h b/packages/hal/sh/edk/current/include/hal_diag.h
index dcf08a9ae..aad6245ef 100644
--- a/packages/hal/sh/edk/current/include/hal_diag.h
+++ b/packages/hal/sh/edk/current/include/hal_diag.h
@@ -49,6 +49,16 @@
 
 #include <cyg/infra/cyg_type.h>
 
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+#else // everything by steam
+
 //-----------------------------------------------------------------------------
 // functions implemented in hal_diag.c
 
@@ -66,6 +76,8 @@ externC void hal_diag_read_char(char *c);
 
 #define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_)
 
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
 //-----------------------------------------------------------------------------
 // Simple LED control.
 externC void hal_diag_led_on( void );
diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h
index 73f0cf466..ad1d89991 100644
--- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h
+++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h
@@ -5,8 +5,8 @@
 #include <cyg/infra/cyg_type.h>
 #include <stddef.h>
 
-#define CYGMEM_REGION_ram (0x8000100)
-#define CYGMEM_REGION_ram_SIZE (0xfff00)
+#define CYGMEM_REGION_ram (0x8000200)
+#define CYGMEM_REGION_ram_SIZE (0xffe00)
 #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
 #define CYGMEM_REGION_rom (0xa0000000)
 #define CYGMEM_REGION_rom_SIZE (0x20000)
diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi
index 668871151..a3bd43e5e 100644
--- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi
+++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi
@@ -31,7 +31,7 @@
 MEMORY
 {
     rom : ORIGIN = 0xa0000000, LENGTH = 0x20000
-    ram : ORIGIN = 0x08000100, LENGTH = 0xfff00
+    ram : ORIGIN = 0x08000200, LENGTH = 0xffe00
 }
 
 SECTIONS
@@ -44,7 +44,7 @@ SECTIONS
     SECTION_rodata (rom, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
     SECTION_gcc_except_table (rom, ALIGN (0x1), LMA_EQ_VMA)
-    SECTION_data (ram, 0x08000100, FOLLOWING (.gcc_except_table))
+    SECTION_data (ram, 0x08000200, FOLLOWING (.gcc_except_table))
     SECTION_bss (ram, ALIGN (0x10), LMA_EQ_VMA)
     SECTIONS_END
 }
diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt
index 92f21c2da..3530282c0 100644
--- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt
+++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt
@@ -1,7 +1,7 @@
 version 0
-region ram 8000100 fff00 0 !
+region ram 8000200 ffe00 0 !
 region rom a0000000 20000 1 !
-section data 0 1 1 1 1 1 0 0 8000100 bss !
+section data 0 1 1 1 1 1 0 0 8000200 bss !
 section bss 0 10 0 1 0 0 0 0 !
 section vectors 0 1 0 1 1 1 1 1 a0000000 a0000000 text text !
 section text 0 4 0 1 0 1 0 1 fini fini !
diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h
index 9179b2f9e..4cb7e1173 100644
--- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h
+++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h
@@ -5,8 +5,8 @@
 #include <cyg/infra/cyg_type.h>
 #include <stddef.h>
 
-#define CYGMEM_REGION_ram (0x8000100)
-#define CYGMEM_REGION_ram_SIZE (0xfff00)
+#define CYGMEM_REGION_ram (0x8000200)
+#define CYGMEM_REGION_ram_SIZE (0xffe00)
 #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
 #define CYGMEM_REGION_rom (0xa0000000)
 #define CYGMEM_REGION_rom_SIZE (0x20000)
diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi
index 325bb2876..c76e2482c 100644
--- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi
+++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi
@@ -4,14 +4,14 @@
 
 MEMORY
 {
-    ram : ORIGIN = 0x8000100, LENGTH = 0xfff00
+    ram : ORIGIN = 0x8000200, LENGTH = 0xffe00
     rom : ORIGIN = 0xa0000000, LENGTH = 0x20000
 }
 
 SECTIONS
 {
     SECTIONS_BEGIN
-    SECTION_vectors (ram, 0x8000100, AT (0xa0000000))
+    SECTION_vectors (ram, 0x8000200, AT (0xa0000000))
     SECTION_text (ram, ALIGN (0x10), FOLLOWING (.vectors))
     SECTION_fini (ram, ALIGN (0x10), FOLLOWING (.text))
     SECTION_rodata1 (ram, ALIGN (0x10), FOLLOWING (.fini))
diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt
index e8c6b924d..7bd5562a1 100644
--- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt
+++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt
@@ -1,7 +1,7 @@
 version 0
-region ram 8000100 fff00 0 !
+region ram 8000200 ffe00 0 !
 region rom a0000000 20000 1 !
-section vectors 0 10 1 1 1 1 1 1 8000100 a0000000 text text !
+section vectors 0 10 1 1 1 1 1 1 8000200 a0000000 text text !
 section text 0 10 1 1 0 1 0 1 fini fini !
 section fini 0 10 1 1 0 1 0 1 rodata1 rodata1 !
 section rodata1 0 10 1 1 0 1 0 1 rodata rodata !
diff --git a/packages/hal/sh/edk/current/include/plf_stub.h b/packages/hal/sh/edk/current/include/plf_stub.h
index 548027448..219c63413 100644
--- a/packages/hal/sh/edk/current/include/plf_stub.h
+++ b/packages/hal/sh/edk/current/include/plf_stub.h
@@ -47,10 +47,6 @@
 #include <pkgconf/system.h>
 #include <pkgconf/hal.h>
 
-#ifdef CYGPKG_IO_SERIAL
-#include <pkgconf/io_serial.h>
-#endif
-
 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
 
 #include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM, externC
@@ -60,19 +56,16 @@
 #include <cyg/hal/hal_diag.h>           // hal_diag_led_on
 
 //----------------------------------------------------------------------------
-// Define serial stuff.
-externC void hal_sci_stub_init_serial( void );
-externC int  hal_sci_stub_get_char( void );
-externC void hal_sci_stub_put_char( int c );
-externC int  hal_sci_stub_interruptible( int state );
-externC void hal_sci_stub_init_break_irq( void );
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
 
-#define HAL_STUB_PLATFORM_INIT_SERIAL()       hal_sci_stub_init_serial()
-#define HAL_STUB_PLATFORM_GET_CHAR()          hal_sci_stub_get_char()
-#define HAL_STUB_PLATFORM_PUT_CHAR(c)         hal_sci_stub_put_char((c))
 #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
-#define HAL_STUB_PLATFORM_INTERRUPTIBLE       (&hal_sci_stub_interruptible)
-#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    hal_sci_stub_init_break_irq()
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
 
 //----------------------------------------------------------------------------
 // Stub initializer.
@@ -82,15 +75,16 @@ externC void hal_sci_stub_init_break_irq( void );
 # define HAL_STUB_PLATFORM_INIT()              CYG_EMPTY_STATEMENT
 #endif
 
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
 //----------------------------------------------------------------------------
 // Reset.
 // Block interrupts and cause an exception. This forces a reset.
 #define HAL_STUB_PLATFORM_RESET() \
     asm volatile ("ldc %0,sr;trapa #0x00;" : : "r" (CYGARC_REG_SR_BL))
-    
-
-#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
 
+#define HAL_STUB_PLATFORM_RESET_ENTRY 0xa0000000
+    
 //-----------------------------------------------------------------------------
 #endif // CYGONCE_HAL_PLF_STUB_H
 // End of plf_stub.h
diff --git a/packages/hal/sh/edk/current/src/hal_diag.c b/packages/hal/sh/edk/current/src/hal_diag.c
index 77009befc..36bc6c586 100644
--- a/packages/hal/sh/edk/current/src/hal_diag.c
+++ b/packages/hal/sh/edk/current/src/hal_diag.c
@@ -45,18 +45,66 @@
 
 #include <cyg/hal/hal_diag.h>           // our header.
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
-#include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
-#endif
-
 #include <cyg/infra/cyg_type.h>         // base types, externC
 #include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // Calling interface
 #include <cyg/hal/hal_intr.h>           // Interrupt macros
+#include <cyg/hal/sh3_sci.h>            // driver API
+#include <cyg/hal/hal_misc.h>           // Helper functions
 
-#include <cyg/hal/sh_sci.inl>
+#define SCI_BASE ((cyg_uint8*)0xfffffe80)
 
 //-----------------------------------------------------------------------------
 
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_sci_init(0, 0, CYGNUM_HAL_INTERRUPT_SCI_RXI, SCI_BASE);
+}
+
+#endif //  CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+//=============================================================================
+// Led control
+//=============================================================================
+#define LED_ON   0x04000000
+#define LED_OFF  0x18000000
+
+void
+hal_diag_led_on( void )
+{
+    HAL_WRITE_UINT8(LED_ON, 0);
+}
+
+void
+hal_diag_led_off( void )
+{
+    HAL_WRITE_UINT8(LED_OFF, 0);
+}
+
+
+//=============================================================================
+// Compatibility with older stubs
+//=============================================================================
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+static channel_data_t channel = { (cyg_uint8*)SCI_BASE, 0, 0};
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+#include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
+#endif
+
 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs)
 
 #define CYG_HAL_DIAG_GDB
@@ -71,24 +119,21 @@
 
 void hal_diag_init(void)
 {
-    hal_sci_init_serial();
+    cyg_hal_plf_sci_init_channel(&channel);
 }
 
 void 
 hal_diag_write_char_serial( char c )
 {
-    hal_sci_put_char(c);
+    cyg_hal_plf_sci_putc(&channel, c);
 }
 
 void
 hal_diag_read_char(char *c)
 {
-    *c = (char) hal_sci_get_char();
+    *c = (char) cyg_hal_plf_sci_getc(&channel);
 }
 
-externC cyg_bool cyg_hal_is_break(char *buf, int size);
-externC void cyg_hal_user_break(CYG_ADDRWORD *regs);
-
 // Packet function
 void 
 hal_diag_write_char(char c)
@@ -124,26 +169,26 @@ hal_diag_write_char(char c)
             cyg_uint8 csum = 0;
             int i;
         
-            hal_diag_write_char_serial('$');
-            hal_diag_write_char_serial('O');
+            cyg_hal_plf_sci_putc(&channel, '$');
+            cyg_hal_plf_sci_putc(&channel, 'O');
             csum += 'O';
             for( i = 0; i < pos; i++ )
             {
                 char ch = line[i];
                 char h = hex[(ch>>4)&0xF];
                 char l = hex[ch&0xF];
-                hal_diag_write_char_serial(h);
-                hal_diag_write_char_serial(l);
+                cyg_hal_plf_sci_putc(&channel, h);
+                cyg_hal_plf_sci_putc(&channel, l);
                 csum += h;
                 csum += l;
             }
-            hal_diag_write_char_serial('#');
-            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
-            hal_diag_write_char_serial(hex[csum&0xF]);
+            cyg_hal_plf_sci_putc(&channel, '#');
+            cyg_hal_plf_sci_putc(&channel, hex[(csum>>4)&0xF]);
+            cyg_hal_plf_sci_putc(&channel, hex[csum&0xF]);
 
             // Wait for the ACK character '+' from GDB here and handle
             // receiving a ^C instead.
-            hal_diag_read_char(&c1);
+            c1 = (char) cyg_hal_plf_sci_getc(&channel);
 
             if( c1 == '+' )
                 break;              // a good acknowledge
@@ -165,26 +210,10 @@ hal_diag_write_char(char c)
 #endif
     }
 #else // CYG_HAL_DIAG_GDB
-    hal_diag_write_char_serial(c);
+    cyg_hal_plf_sci_putc(&channel, c);
 #endif
 }
-
-//-----------------------------------------------------------------------------
-// Led control
-#define LED_ON   0x04000000
-#define LED_OFF  0x18000000
-
-void
-hal_diag_led_on( void )
-{
-    HAL_WRITE_UINT8(LED_ON, 0);
-}
-
-void
-hal_diag_led_off( void )
-{
-    HAL_WRITE_UINT8(LED_OFF, 0);
-}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
 //-----------------------------------------------------------------------------
 // End of hal_diag.c
diff --git a/packages/hal/sh/edk/current/src/plf_misc.c b/packages/hal/sh/edk/current/src/plf_misc.c
index 2ffea80af..861cb7fb6 100644
--- a/packages/hal/sh/edk/current/src/plf_misc.c
+++ b/packages/hal/sh/edk/current/src/plf_misc.c
@@ -44,59 +44,14 @@
 
 #include <pkgconf/hal.h>
 
-#include <cyg/infra/cyg_type.h>         // Base types
-
-#include <cyg/hal/hal_arch.h>           // architectural definitions
-
-#include <cyg/hal/hal_intr.h>           // Interrupt handling
-
-#include <cyg/hal/hal_cache.h>          // Cache handling
-
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-#include <cyg/hal/hal_stub.h>           // stub functionality
-#endif
+#include <cyg/hal/hal_if.h>             // interfacing API
 
 //--------------------------------------------------------------------------
-// Functions to support the detection and execution of a user provoked
-// program break. These are usually called from interrupt routines.
-
-cyg_bool
-cyg_hal_is_break(char *buf, int size)
-{
-    while( size )
-        if( buf[--size] == 0x03 ) return true;
-
-    return false;
-}
-
 void
-cyg_hal_user_break( CYG_ADDRWORD *regs )
+hal_platform_init(void)
 {
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-    HAL_SavedRegisters *__sreg = (HAL_SavedRegisters *)regs;
-    target_register_t __pc;
-
-    if (__sreg)
-        __pc = (target_register_t) __sreg->pc;
-    else
-        __pc = (target_register_t) &&safe_breakpoint;
-    
-    // Note: This would be better for the else case but doesn't work
-    // at the moment.  CR: 101357
-    // __pc = (target_register_t) __builtin_return_address(0);
-
-    cyg_hal_gdb_interrupt (__pc);
-
- safe_breakpoint:
-#elif defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs)
-
-    // Note: Need to communicate to the ROM stub instead
-    HAL_BREAKPOINT(breakinst);
-
-#else
-
-    HAL_BREAKPOINT(breakinst);
-
-#endif
-
+    hal_if_init();
 }
+
+//--------------------------------------------------------------------------
+// eof plf_misc.c
diff --git a/packages/hal/v85x/arch/current/ChangeLog b/packages/hal/v85x/arch/current/ChangeLog
index bb1f19257..3f455c166 100644
--- a/packages/hal/v85x/arch/current/ChangeLog
+++ b/packages/hal/v85x/arch/current/ChangeLog
@@ -1,3 +1,12 @@
+2000-06-27  Jesper Skov  <jskov@redhat.com>
+
+	* src/vectors.S:
+	* src/hal_mk_defs.c: 
+	Fix compiler warnings.
+
+	* src/hal_misc.c (hal_default_isr): Let common version do the
+	checks.
+
 2000-06-15  Gary Thomas  <gthomas@redhat.com>
 
 	* src/hal_mk_defs.c: 
diff --git a/packages/hal/v85x/arch/current/src/hal_misc.c b/packages/hal/v85x/arch/current/src/hal_misc.c
index e3c4077b7..dc59ac348 100644
--- a/packages/hal/v85x/arch/current/src/hal_misc.c
+++ b/packages/hal/v85x/arch/current/src/hal_misc.c
@@ -141,11 +141,6 @@ cyg_hal_invoke_constructors (void)
 externC cyg_uint32
 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
 {
-    CYG_TRACE1(true, "Interrupt: %d", vector);
-
-    diag_printf("Spurious Interrupt!!! - vector: %d, data: %x\n", vector, 
-                data);
-    CYG_FAIL("Spurious Interrupt!!!");
     return 0;
 }
 #else
diff --git a/packages/hal/v85x/arch/current/src/hal_mk_defs.c b/packages/hal/v85x/arch/current/src/hal_mk_defs.c
index 45571cfc1..8e0014d5a 100644
--- a/packages/hal/v85x/arch/current/src/hal_mk_defs.c
+++ b/packages/hal/v85x/arch/current/src/hal_mk_defs.c
@@ -160,6 +160,8 @@ main(void)
 #endif
 
     // Variant definitions - want these to be included instead.
+
+    return 0;
 }
 
 //--------------------------------------------------------------------------
diff --git a/packages/hal/v85x/arch/current/src/vectors.S b/packages/hal/v85x/arch/current/src/vectors.S
index c11877734..d93ef35de 100644
--- a/packages/hal/v85x/arch/current/src/vectors.S
+++ b/packages/hal/v85x/arch/current/src/vectors.S
@@ -83,7 +83,7 @@ reset_vector:
 #ifdef CYG_HAL_STARTUP_ROM
 //
 // These are the hardware exception vectors.
-//                        
+//
 __ROM_vsr:
         // 0x000
         jr      start
@@ -92,12 +92,12 @@ __ROM_vsr:
         .rept   CYGNUM_HAL_EXCEPTION_COUNT-1
         EXCEPTION
         .endr
-        .set    VECTOR, 8                
+        .set    VECTOR, 8
         .rept   CYGNUM_HAL_ISR_COUNT
         INTERRUPT
-        .endr               
+        .endr
 #endif  // CYG_HAL_STARTUP_ROM
-        
+
         .globl  start
 start:
         // Perform hardware initialization
@@ -113,7 +113,7 @@ start:
         addi    4,r6,r6
         addi    4,r7,r7
         cmp     r7,r8
-        bne     1b 
+        bne     1b
 #endif
         // Initialize stack
         lea     __startup_stack,r1
@@ -125,7 +125,7 @@ start:
 1:      st.w    r0,0[r6]
         addi    4,r6,r6
         cmp     r6,r7
-        bne     1b        
+        bne     1b
 
 #ifdef CYG_HAL_STARTUP_ROM
         // Built initial trap VSR tables
@@ -135,13 +135,13 @@ start:
         lea     __ROM_vsr,r7
         mov     r6,r8
         sub     r7,r8
-        lea     0x003FFFFF,r7        
+        lea     0x003FFFFF,r7
         and     r7,r8
         lea     0x07800000,r7
         or      r7,r8
 #else
         lea     0x00000794,r8   // jr 0x0100xx0
-#endif                
+#endif
 10:     st.w    r8,0[r6]
         addi    16,r6,r6
         cmp     r6,r9
@@ -169,8 +169,8 @@ start:
 10:     st.w    r8,0[r6]
         addi    4,r6,r6
         addi    -1,r7,r7
-        bne     10b        
-#endif        
+        bne     10b
+#endif
         jarl    _initialize_stub,r31
 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
@@ -550,4 +550,3 @@ _hal_interrupt_objects:
 	.rept	CYGNUM_HAL_ISR_COUNT
 	.long	0
 	.endr
-        
\ No newline at end of file
diff --git a/packages/hal/v85x/ceb_v850/current/ChangeLog b/packages/hal/v85x/ceb_v850/current/ChangeLog
index b54a7c866..b909e07c5 100644
--- a/packages/hal/v85x/ceb_v850/current/ChangeLog
+++ b/packages/hal/v85x/ceb_v850/current/ChangeLog
@@ -1,3 +1,15 @@
+2000-06-27  Jesper Skov  <jskov@redhat.com>
+
+	* src/plf_misc.c: Fix compiler warnings.
+
+	* src/plf_stub.c: 
+	* src/hal_diag.c:
+	* include/plf_stub.h: 
+	* include/plf_intr.h: 
+	* include/hal_diag.h:
+	Moved Ctrl-c handling to driver code. Use new comms procs
+	semantics. 
+
 2000-06-17  Gary Thomas  <gthomas@redhat.com>
 
 	* include/plf_intr.h: 
diff --git a/packages/hal/v85x/ceb_v850/current/include/hal_diag.h b/packages/hal/v85x/ceb_v850/current/include/hal_diag.h
index d8ede1322..3e84642d0 100644
--- a/packages/hal/v85x/ceb_v850/current/include/hal_diag.h
+++ b/packages/hal/v85x/ceb_v850/current/include/hal_diag.h
@@ -49,14 +49,6 @@
 
 #include <cyg/infra/cyg_type.h>
 
-/*---------------------------------------------------------------------------*/
-/* functions implemented in hal_diag.c                                       */
-
-
-externC void hal_diag_init(void);
-externC void hal_diag_write_char(char c);
-externC void hal_diag_read_char(char *c);
-
 /*---------------------------------------------------------------------------*/
 
 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
@@ -67,18 +59,12 @@ externC void hal_diag_read_char(char *c);
 #define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
 #define HAL_DIAG_READ_CHAR(_c_)  hal_if_diag_read_char(&_c_)
 
-#ifndef CYGPRI_CONSOLE_PROCS_HANDLED
-externC void hal_plf_init_serial(void);
-externC void hal_plf_write_char(int);
-externC int  hal_plf_get_char(void);
-
-# define HAL_PLF_DIAG_RAW_INIT()          hal_plf_init_serial()
-# define HAL_PLF_DIAG_RAW_WRITE_CHAR(_c_) hal_plf_write_char(_c_)
-# define HAL_PLF_DIAG_RAW_READ_CHAR(_c_)  (_c_) = hal_plf_get_char()
-#endif
-
 #else
 
+externC void hal_diag_init(void);
+externC void hal_diag_write_char(char c);
+externC void hal_diag_read_char(char *c);
+
 #define HAL_DIAG_INIT()          hal_diag_init()
 #define HAL_DIAG_WRITE_CHAR(_c_) hal_diag_write_char(_c_)
 #define HAL_DIAG_READ_CHAR(_c_)  hal_diag_read_char(&_c_)
diff --git a/packages/hal/v85x/ceb_v850/current/include/plf_intr.h b/packages/hal/v85x/ceb_v850/current/include/plf_intr.h
index 5f2fda0db..8f608fe0d 100644
--- a/packages/hal/v85x/ceb_v850/current/include/plf_intr.h
+++ b/packages/hal/v85x/ceb_v850/current/include/plf_intr.h
@@ -115,9 +115,6 @@
 // The vector used by the Real time clock.
 #define CYGNUM_HAL_INTERRUPT_RTC               CYGNUM_HAL_VECTOR_INTTM10
 
-// Vector used to detect ^C
-#define CYGHWR_HAL_GDB_PORT_VECTOR             CYGNUM_HAL_VECTOR_INTCSI1
-
 // Mapping from interrupt numbers to hardware registers
 #define CYG_HAL_V85X_INTERRUPT_CONTROL_REGISTERS        \
     (volatile unsigned char *)V850_REG_WDTIC,           \
@@ -151,15 +148,6 @@
     (volatile unsigned char *)V850_REG_DMAIC2,          \
     (volatile unsigned char *)V850_REG_WTIC
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
-
-extern struct Hal_SavedRegisters *hal_saved_interrupt_state;
-extern void hal_ctrlc_isr_init(void);
-extern cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
-#define HAL_CTRLC_ISR(_v_,_d_)   hal_ctrlc_isr(_v_, _d_)
-#endif
-
 //--------------------------------------------------------------------------
 #endif // ifndef CYGONCE_HAL_PLF_INTR_H
 // End of plf_intr.h
diff --git a/packages/hal/v85x/ceb_v850/current/include/plf_stub.h b/packages/hal/v85x/ceb_v850/current/include/plf_stub.h
index c46c56b03..b8678d64f 100644
--- a/packages/hal/v85x/ceb_v850/current/include/plf_stub.h
+++ b/packages/hal/v85x/ceb_v850/current/include/plf_stub.h
@@ -54,16 +54,11 @@
 
 //----------------------------------------------------------------------------
 // Define serial stuff.
-extern void hal_plf_init_serial( void );
-extern int  hal_plf_get_char( void );
-extern void hal_plf_put_char( int c );
-extern int  hal_plf_interruptible( int );
+externC void cyg_hal_plf_comms_init(void);
 
-#define HAL_STUB_PLATFORM_INIT_SERIAL()       hal_plf_init_serial()
-#define HAL_STUB_PLATFORM_GET_CHAR()          hal_plf_get_char()
-#define HAL_STUB_PLATFORM_PUT_CHAR(c)         hal_plf_put_char((c))
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
 #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
-#define HAL_STUB_PLATFORM_INTERRUPTIBLE       hal_plf_interruptible
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
 #define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    CYG_EMPTY_STATEMENT
 
 //----------------------------------------------------------------------------
diff --git a/packages/hal/v85x/ceb_v850/current/src/hal_diag.c b/packages/hal/v85x/ceb_v850/current/src/hal_diag.c
index 95b90d6f9..4fc18b2cd 100644
--- a/packages/hal/v85x/ceb_v850/current/src/hal_diag.c
+++ b/packages/hal/v85x/ceb_v850/current/src/hal_diag.c
@@ -33,7 +33,7 @@
 //
 // Author(s):   nickg, gthomas
 // Contributors:nickg, gthomas
-// Date:        1998-03-02
+// Date:        2000-05-22
 // Purpose:     HAL diagnostic output
 // Description: Implementations of HAL diagnostic output support.
 //
@@ -54,27 +54,13 @@
 #include <cyg/hal/hal_io.h>             // IO macros
 #include <cyg/hal/hal_diag.h>
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
 #include <cyg/hal/hal_stub.h>           // target_register_t
-#include <cyg/hal/hal_intr.h>           // HAL_INTERRUPT_UNMASK(...)
 #include <cyg/hal/hal_if.h>             // Calling interface definitions
 #include <cyg/hal/hal_misc.h>           // Helper functions
 #include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
-#endif
 
 #include <cyg/hal/v850_common.h>        // hardware registers, etc.
 
-// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e.
-// totally stand-alone) system.
-
-#if defined(CYG_HAL_STARTUP_ROM) && !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
-#define HAL_DIAG_USES_HARDWARE
-#else
-#if defined(CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL)
-#define HAL_DIAG_USES_HARDWARE
-#endif
-#endif
 
 #if (CYGHWR_HAL_V85X_V850_CEB_DIAG_BAUD == 9600)
 #define BAUD_COUNT    0xDD
@@ -95,51 +81,243 @@
 /*---------------------------------------------------------------------------*/
 // CEB-v850
 
+void
+init_serial_channel(void* base)
+{
+    volatile unsigned char *mode = (volatile unsigned char *)V850_REG_ASIM0;
+    volatile unsigned char *brgc = (volatile unsigned char *)V850_REG_BRGC0;
+    volatile unsigned char *brgm = (volatile unsigned char *)V850_REG_BRGM0;
+    volatile unsigned char *rxstat = (volatile unsigned char *)V850_REG_SRIC0;
+    volatile unsigned char *rxerr = (volatile unsigned char *)V850_REG_SERIC0;
+    volatile unsigned char *txstat = (volatile unsigned char *)V850_REG_STIC0;
+
+    *mode = 0xC8;
+    *brgc = BAUD_COUNT;
+    *brgm = BAUD_DIVISOR;
+    *rxstat = 0x47;
+    *rxerr = 0;
+    *txstat = 0x47;
+}
+
 // Actually send character down the wire
 void
-hal_diag_write_char_serial(char c)
+cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 c)
 {
     volatile unsigned char *TxDATA = (volatile unsigned char *)V850_REG_TXS0;
     volatile unsigned char *TxSTAT = (volatile unsigned char *)V850_REG_STIC0;
+    CYGARC_HAL_SAVE_GP();
+
     // Send character
     *TxDATA = (unsigned char)c;
     // Wait for Tx not busy
-    while ((*TxSTAT & 0x80) == 0x00) ;
+    while ((*TxSTAT & 0x80) == 0x00);
     *TxSTAT &= ~0x80;
+
+    CYGARC_HAL_RESTORE_GP();
 }
 
-bool
-hal_diag_read_serial(char *c)
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
 {
     volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0;
     volatile unsigned char *RxSTAT = (volatile unsigned char *)V850_REG_SRIC0;
-    volatile unsigned char *RxERR = (volatile unsigned char *)V850_REG_SERIC0;
-    int timeout = 0;
-    while ((*RxSTAT & 0x80) == 0x00) {
-        if (++timeout == 50000) return false;
-    }
-    *c = (char)*RxDATA;
+
+    if ((*RxSTAT & 0x80) == 0x00)
+        return false;
+
+    *ch = (char)*RxDATA;
     *RxSTAT &= ~0x80;
     return true;
 }
 
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_int32 msec_timeout = 1000;
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count = msec_timeout * 10; // delay in .1 ms steps
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US()(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    int ret = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        HAL_INTERRUPT_UNMASK(CYGNUM_HAL_VECTOR_INTCSI1);
+        irq_state = 1;
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_INTERRUPT_MASK(CYGNUM_HAL_VECTOR_INTCSI1);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = CYGNUM_HAL_VECTOR_INTCSI1;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = msec_timeout;
+        msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0;
+    cyg_uint8 c;
+    int res = 0;
+    CYGARC_HAL_SAVE_GP();
+
+    c = (char)*RxDATA;
+    *__ctrlc = 0;
+    if( cyg_hal_is_break( &c , 1 ) )
+        *__ctrlc = 1;
+
+    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_VECTOR_INTCSI1);
+
+    res = CYG_ISR_HANDLED;
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Disable interrupts.
+    HAL_INTERRUPT_MASK(CYGNUM_HAL_VECTOR_INTCSI1);
+
+    // Init channels
+    init_serial_channel((cyg_uint8*)0);
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, 0);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+    
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+//=============================================================================
+// Compatibility with older stubs
+//=============================================================================
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e.
+// totally stand-alone) system.
+
+//#ifdef CYGSEM_HAL_ROM_MONITOR
+//#define CYG_HAL_STARTUP_ROM
+//#undef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+//#endif
+
+#if defined(CYG_HAL_STARTUP_ROM) && !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+#define HAL_DIAG_USES_HARDWARE
+#else
+#if defined(CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL)
+#define HAL_DIAG_USES_HARDWARE
+#endif
+#endif
+
 void hal_diag_init(void)
 {
-    static int init = 0;
-    volatile unsigned char *mode = (volatile unsigned char *)V850_REG_ASIM0;
-    volatile unsigned char *brgc = (volatile unsigned char *)V850_REG_BRGC0;
-    volatile unsigned char *brgm = (volatile unsigned char *)V850_REG_BRGM0;
-    volatile unsigned char *rxstat = (volatile unsigned char *)V850_REG_SRIC0;
-    volatile unsigned char *rxerr = (volatile unsigned char *)V850_REG_SERIC0;
-    volatile unsigned char *txstat = (volatile unsigned char *)V850_REG_STIC0;
-    if (init) return;
-    init++;
-    *mode = 0xC8;
-    *brgc = BAUD_COUNT;
-    *brgm = BAUD_DIVISOR;
-    *rxstat = 0x47;
-    *rxerr = 0;
-    *txstat = 0x47;
+    init_serial_channel(0);
 }
 
 #ifdef HAL_DIAG_USES_HARDWARE
@@ -148,14 +326,13 @@ void hal_diag_write_char(char c)
 {
     CYG_INTERRUPT_STATE old;
     HAL_DISABLE_INTERRUPTS(old);
-    hal_diag_init();
-    hal_diag_write_char_serial(c);
+    cyg_hal_plf_serial_putc(0, c);
     HAL_RESTORE_INTERRUPTS(old);
 }
 
 void hal_diag_read_char(char *c)
 {
-    while (!hal_diag_read_serial(c)) ;
+    *c = cyg_hal_plf_serial_getc(0);
 }
 
 #else // HAL_DIAG relies on GDB
@@ -163,7 +340,7 @@ void hal_diag_read_char(char *c)
 void 
 hal_diag_read_char(char *c)
 {
-    while (!hal_diag_read_serial(c)) ;
+    *c = cyg_hal_plf_serial_getc(0);
 }
 
 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
@@ -205,41 +382,40 @@ hal_diag_write_char(char c)
             int i;
             char c1;
         
-            hal_diag_write_char_serial('$');
-            hal_diag_write_char_serial('O');
+            cyg_hal_plf_serial_putc(0, '$');
+            cyg_hal_plf_serial_putc(0, 'O');
             csum += 'O';
             for( i = 0; i < pos; i++ )
             {
                 char ch = line[i];
                 char h = hex[(ch>>4)&0xF];
                 char l = hex[ch&0xF];
-                hal_diag_write_char_serial(h);
-                hal_diag_write_char_serial(l);
+                cyg_hal_plf_serial_putc(0, h);
+                cyg_hal_plf_serial_putc(0, l);
                 csum += h;
                 csum += l;
             }
-            hal_diag_write_char_serial('#');
-            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
-            hal_diag_write_char_serial(hex[csum&0xF]);
+            cyg_hal_plf_serial_putc(0, '#');
+            cyg_hal_plf_serial_putc(0, hex[(csum>>4)&0xF]);
+            cyg_hal_plf_serial_putc(0, hex[csum&0xF]);
 
             // Wait for the ACK character '+' from GDB here and handle
             // receiving a ^C instead.  This is the reason for this clause
             // being a loop.
-            if (!hal_diag_read_serial(&c1))
-                continue;   // No response - try sending packet again
+            c1 = cyg_hal_plf_serial_getc(0);
 
             if( c1 == '+' )
                 break;              // a good acknowledge
 
 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) && \
     defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
-            cyg_drv_interrupt_acknowledge(CYGHWR_HAL_GDB_PORT_VECTOR);
+            cyg_drv_interrupt_acknowledge(CYGNUM_HAL_VECTOR_INTCSI1);
             if( c1 == 3 ) {
                 // Ctrl-C: breakpoint.
 #if 0  // FIXME - __builtin_return_address() doesn't work
                 cyg_hal_gdb_interrupt (__builtin_return_address(0));
 #else
-                cyg_hal_gdb_interrupt (hal_diag_write_char_break);
+                cyg_hal_gdb_interrupt((CYG_ADDRWORD)hal_diag_write_char_break);
 #endif
                 break;
             }
@@ -262,28 +438,7 @@ hal_diag_write_char(char c)
 }
 #endif  // USE HARDWARE
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
-    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
-
-struct Hal_SavedRegisters *hal_saved_interrupt_state;
-
-void
-hal_ctrlc_isr_init(void)
-{
-    HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR);
-}
-
-cyg_uint32
-hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
-{
-    volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0;
-    unsigned char ch;
-    ch = (char)*RxDATA;
-    if( cyg_hal_is_break( &ch , 1 ) )
-        cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
-    return CYG_ISR_HANDLED;
-}
-#endif
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
 
 /*---------------------------------------------------------------------------*/
 /* End of hal_diag.c */
diff --git a/packages/hal/v85x/ceb_v850/current/src/plf_misc.c b/packages/hal/v85x/ceb_v850/current/src/plf_misc.c
index 2c1ca7864..246429116 100644
--- a/packages/hal/v85x/ceb_v850/current/src/plf_misc.c
+++ b/packages/hal/v85x/ceb_v850/current/src/plf_misc.c
@@ -55,6 +55,8 @@
 
 #include <cyg/hal/hal_if.h>             // ROM monitor interfaces
 
+#include <cyg/infra/diag.h>             // diag_printf
+
 extern void show_hex4(unsigned long val);
 extern void show_hex1(unsigned long val);
 extern void show_8bit_reg(void *addr);
@@ -63,7 +65,6 @@ extern void show_led(int p);
 void
 cyg_hal_platform_hardware_init(void)
 {
-    int i;
     hal_if_init();  // Initialize GDB[ROM]/eCos interfaces
     show_led(' ');
     show_led(' ');
@@ -92,9 +93,9 @@ show_8bit_reg(void *addr)
     unsigned char *reg = (unsigned char *)addr;
     unsigned char val = *reg;
     show_led(' ');
-    show_hex4(reg);
+    show_hex4((unsigned long)reg);
     show_led('=');
-    show_hex1(val);
+    show_hex1((unsigned long)val);
     show_led('/');
 }
 
@@ -302,7 +303,7 @@ extern void _hal_thread_switch_context(HAL_SavedRegisters **to, HAL_SavedRegiste
 
 void hal_thread_load_context(CYG_ADDRESS to)
 {
-    HAL_SavedRegisters **new_context = to;
+    HAL_SavedRegisters **new_context = (HAL_SavedRegisters **)to;
 #if 0
     diag_printf("Load context: %x\n", *new_context);
     show_regs(*new_context);
@@ -312,8 +313,8 @@ void hal_thread_load_context(CYG_ADDRESS to)
 
 void hal_thread_switch_context(CYG_ADDRESS to, CYG_ADDRESS from)
 {
-    HAL_SavedRegisters **old_context = from;
-    HAL_SavedRegisters **new_context = to;
+    HAL_SavedRegisters **old_context = (HAL_SavedRegisters **)from;
+    HAL_SavedRegisters **new_context = (HAL_SavedRegisters **)to;
 #if 0
     diag_printf("Switch context - old: %x, new: %x\n", *old_context, *new_context);
     show_regs(*new_context);
diff --git a/packages/hal/v85x/ceb_v850/current/src/plf_stub.c b/packages/hal/v85x/ceb_v850/current/src/plf_stub.c
index f802deffb..3771d081c 100644
--- a/packages/hal/v85x/ceb_v850/current/src/plf_stub.c
+++ b/packages/hal/v85x/ceb_v850/current/src/plf_stub.c
@@ -54,84 +54,6 @@
 
 #include <cyg/hal/v850_common.h>
 
-/*---------------------------------------------------------------------------*/
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-static cyg_interrupt gdb_interrupt;
-static cyg_handle_t  gdb_interrupt_handle;
-#define CYG_DEVICE_SERIAL_INT CYGNUM_HAL_VECTOR_INTCSI1
-
-// This ISR is called only for serial receive interrupts.
-int 
-cyg_hal_gdb_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
-{
-    volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0;
-    cyg_uint8 c;    
-
-    c = *RxDATA;  // Fetch the character
-    if( 3 == c ) {  // ^C
-        // Ctrl-C: set a breakpoint at PC so GDB will display the
-        // correct program context when stopping rather than the
-        // interrupt handler.
-        cyg_hal_gdb_interrupt (regs->pc);
-        cyg_drv_interrupt_acknowledge(CYG_DEVICE_SERIAL_INT);
-    }
-    return 0;  // No need to run DSR
-}
-
-int 
-hal_plf_interruptible(int state)
-{
-    if (state) {
-        cyg_drv_interrupt_unmask(CYG_DEVICE_SERIAL_INT);
-    } else {
-        cyg_drv_interrupt_mask(CYG_DEVICE_SERIAL_INT);
-    }
-
-    return 0;
-}
-#endif
-
-void hal_plf_init_serial()
-{
-#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
-    cyg_drv_interrupt_create(CYG_DEVICE_SERIAL_INT,
-                             99,                     // Priority - what goes here?
-                             0,                      //  Data item passed to interrupt handler
-                             cyg_hal_gdb_isr,
-                             0,
-                             &gdb_interrupt_handle,
-                             &gdb_interrupt);
-    cyg_drv_interrupt_attach(gdb_interrupt_handle);
-    cyg_drv_interrupt_unmask(CYG_DEVICE_SERIAL_INT);
-#endif
-}
-
-/*---------------------------------------------------------------------------*/
-
-void hal_plf_put_char( int c)
-{
-    hal_diag_write_char_serial(c);
-}
-
-/*---------------------------------------------------------------------------*/
-
-int hal_plf_get_char( void )
-{
-    volatile unsigned char *LED = (volatile unsigned char *)V850_REG_P10;
-    char c;
-    unsigned char led = *LED & 0x7F;
-    if (led == 0) {
-        led = 0x01;
-    } else {
-        led <<= 1;
-    }
-    *LED = 0x80 | led;
-    hal_diag_read_char(&c);
-    *LED &= 0x7F;
-    return c;
-}
-
-
 //-----------------------------------------------------------------------------
 // Stub init
 
diff --git a/packages/io/serial/current/ChangeLog b/packages/io/serial/current/ChangeLog
index 63bc7471c..635a7db71 100644
--- a/packages/io/serial/current/ChangeLog
+++ b/packages/io/serial/current/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-23  Jesper Skov  <jskov@redhat.com>
+
+	* tests/ser_test_protocol.inl: Added cq7708 definitions.
+
 2000-05-28  Gary Thomas  <gthomas@redhat.com>
 
 	* tests/ser_test_protocol.inl: Rename NEC V85x drivers.
diff --git a/packages/io/serial/current/tests/ser_test_protocol.inl b/packages/io/serial/current/tests/ser_test_protocol.inl
index f1c779b28..702ee774f 100644
--- a/packages/io/serial/current/tests/ser_test_protocol.inl
+++ b/packages/io/serial/current/tests/ser_test_protocol.inl
@@ -196,6 +196,15 @@
 #  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
 # endif
 #endif
+#if defined(CYGPKG_HAL_SH)                      \
+    && defined(CYGPKG_IO_SERIAL_SH_CQ7708)     \
+    && defined(CYGPKG_IO_SERIAL_SH_CQ7708_SCI)
+# define TEST_CRASH_ID "cq7708"
+# define TEST_SER_DEV CYGDAT_IO_SERIAL_SH_CQ7708_SCI_NAME
+# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)
+#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
+# endif
+#endif
 #if defined(CYGPKG_HAL_I386_PC)                         \
     && defined(CYGPKG_IO_SERIAL_I386_PC)                \
     && defined(CYGPKG_IO_SERIAL_I386_PC_SERIAL0)
diff --git a/packages/kernel/current/ChangeLog b/packages/kernel/current/ChangeLog
index 9042873a7..24dcabc67 100644
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,11 @@
+2000-06-23  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* include/kapi.h (cyg_scheduler_read_lock): New function, to
+	return the value of the scheduler lock; this for implementing SPLX
+	in the network stack.
+
+	* src/common/kapi.cxx (cyg_scheduler_read_lock): New function.
+
 2000-06-16  Gary Thomas  <gthomas@redhat.com>
 
 	* cdl/kernel.cdl: Remove exception tests for CMA230 - not supported
diff --git a/packages/kernel/current/include/kapi.h b/packages/kernel/current/include/kapi.h
index 38118c426..ef9bdcbe3 100644
--- a/packages/kernel/current/include/kapi.h
+++ b/packages/kernel/current/include/kapi.h
@@ -133,6 +133,9 @@ void cyg_scheduler_unlock(void);
 /* subsequent call to 'cyg_scheduler_unlock()' will completely unlock.      */
 void cyg_scheduler_safe_lock(void);
     
+/* Read the scheduler lock value. */
+cyg_ucount32 cyg_scheduler_read_lock(void);
+
 /*---------------------------------------------------------------------------*/
 /* Thread operations */
 
diff --git a/packages/kernel/current/src/common/kapi.cxx b/packages/kernel/current/src/common/kapi.cxx
index 6ee11846e..5f89c3b0a 100644
--- a/packages/kernel/current/src/common/kapi.cxx
+++ b/packages/kernel/current/src/common/kapi.cxx
@@ -137,6 +137,13 @@ externC void cyg_scheduler_unlock(void)
         Cyg_Scheduler::unlock();
 }
 
+/* Read the scheduler lock value. */
+externC cyg_ucount32 cyg_scheduler_read_lock(void)
+{
+    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
+    return slock;
+}
+
 /*---------------------------------------------------------------------------*/
 /* Thread operations */
 
diff --git a/packages/net/snmp/agent/current/ChangeLog b/packages/net/snmp/agent/current/ChangeLog
index bc335b048..3abf31f87 100644
--- a/packages/net/snmp/agent/current/ChangeLog
+++ b/packages/net/snmp/agent/current/ChangeLog
@@ -1,3 +1,14 @@
+2000-06-27  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* src/mibgroup/mibII/dot3.c (var_dot3StatsTable): Forgot the
+	DOT3STATSINDEX for loopback, so it claimed index 0.  Fixed.
+
+2000-06-26  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* src/snmptask.c (cyg_net_snmp_init): Change the priority of the
+	SNMP thread; make it one less important than the network thread of
+	which it is a client.
+
 2000-06-19  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* src/mibgroup/mibII/dot3.c (var_dot3StatsTable): Don't trip over
diff --git a/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c b/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c
index 715c4ef56..3e9446049 100644
--- a/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c
+++ b/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c
@@ -242,6 +242,10 @@ var_dot3StatsTable(struct variable *vp,
 
     if ( IFT_LOOP == ifp->if_type ) {
         switch(vp->magic) {
+        case DOT3STATSINDEX:
+            long_ret = name[(*length)-1];
+            return (unsigned char *) &long_ret;
+
         case DOT3STATSETHERCHIPSET:
             *var_len = sizeof(nullobjid);
             return (unsigned char *) nullobjid;
diff --git a/packages/net/snmp/agent/current/src/snmptask.c b/packages/net/snmp/agent/current/src/snmptask.c
index 30446776d..2e980db5e 100644
--- a/packages/net/snmp/agent/current/src/snmptask.c
+++ b/packages/net/snmp/agent/current/src/snmptask.c
@@ -176,7 +176,7 @@ cyg_net_snmp_init(void)
 {
 
     // Create network background thread
-    cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY-2, // Priority
+    cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+1, // Priority, just lower than the net
                       snmpd,                    // entry
                       0,                        // entry parameter
                       "snmpd",                  // Name
diff --git a/packages/net/tcpip/current/ChangeLog b/packages/net/tcpip/current/ChangeLog
index 2db54304f..a9fba6bb0 100644
--- a/packages/net/tcpip/current/ChangeLog
+++ b/packages/net/tcpip/current/ChangeLog
@@ -1,3 +1,23 @@
+2000-06-26  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* tests/ping_test.c (net_test): Added use of the
+	CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff now that the test
+	passes (consequent on the change below); also use larger ping
+	packets now that that is working also.
+
+	* tests/tcp_echo.c (echo_test): Added use of the
+	CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff now that the test
+	passes (consequent on the change below).
+
+2000-06-26  Hugo Tyson  <hmt@cygnus.co.uk>
+
+	* src/ecos/support.c (cyg_splnet): Use the scheduler lock and a
+	mutex instead of disable-interrupts for SPLX type processing.  A
+	mutex is used at splsoftnet because that is client threads - we do
+	not want them to pre-empt the rest of the app.  This enables the
+	real-time response testing for the EBSA285 to succeed (interrupts
+	every 1mS, DSRs delayed by at most 2mS).
+
 2000-06-23  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* src/ecos/support.c (cyg_net_mbuf_alloc, cyg_kmem_init): Align
diff --git a/packages/net/tcpip/current/src/ecos/support.c b/packages/net/tcpip/current/src/ecos/support.c
index 2889a9aa5..51e604c0a 100644
--- a/packages/net/tcpip/current/src/ecos/support.c
+++ b/packages/net/tcpip/current/src/ecos/support.c
@@ -102,11 +102,111 @@ cyg_panic(const char *msg, ...)
     cyg_test_exit();  // FIXME
 }
 
+
+// ------------------------------------------------------------------------
+#define SPLSOFTNET_IS_A_MUTEX 1
+// ------------------------------------------------------------------------
+#ifdef SPLSOFTNET_IS_A_MUTEX
+
+#define MUTEX 0x50F750F7
+#define HOLD  MUTEX+1
+
+static cyg_mutex_t mutex;
+static volatile cyg_handle_t owner;
+
+#define SPLINIT() CYG_MACRO_START               \
+    cyg_mutex_init( &mutex );                   \
+    owner = 0;                                  \
+CYG_MACRO_END
+
+// use the scheduler lock for SPLX() and a mutex for softnet
+
+static inline cyg_uint32
+cyg_splin_softnet(void)
+{
+    if ( 0 == cyg_scheduler_read_lock() ) {
+        cyg_handle_t self = cyg_thread_self();
+        if ( self != owner ) {
+            cyg_mutex_lock( &mutex ); // Perfectly OK for this to wait
+            owner = self;
+            return MUTEX; // release when restoring here
+        }
+        return HOLD; // do not release when restoring to this value
+    }
+    cyg_scheduler_lock();
+    return cyg_scheduler_read_lock() - 1;
+}
+
+static inline cyg_uint32
+cyg_splin(void)
+{
+    cyg_scheduler_lock();
+    return cyg_scheduler_read_lock() - 1;
+}
+
+static inline void
+cyg_splout(cyg_uint32 orig)
+{
+    if ( MUTEX == orig ) {
+        CYG_ASSERT( cyg_thread_self() == owner, "Not owner release!" );
+        cyg_scheduler_lock();
+        owner = 0;
+        cyg_mutex_unlock( &mutex );
+        cyg_scheduler_unlock();
+        return;
+    }
+    if ( HOLD == orig ) {
+        CYG_ASSERT( cyg_thread_self() == owner, "Not owner hold!" );
+        return;
+    }
+    CYG_ASSERT( 0 == (0xffff0000 & orig), "Scary splx value" );
+    while ( cyg_scheduler_read_lock() > orig )
+        cyg_scheduler_unlock();
+}
+
+#define SPL_ENTER(x)    (x) = cyg_splin()
+#define SPL_SOFTNET(x)  (x) = cyg_splin_softnet()
+#define SPL_EXIT(x)     cyg_splout((x))
+
+#else
+#if 1
+
+// use the scheduler lock for SPLX()
+static inline cyg_uint32
+cyg_splin(void)
+{
+    cyg_scheduler_lock();
+    return cyg_scheduler_read_lock() - 1;
+}
+
+static inline void
+cyg_splout(cyg_uint32 orig)
+{
+    CYG_ASSERT( 0 == (0xffff0000 & orig), "Scary splx value" );
+    while ( cyg_scheduler_read_lock() > orig )
+        cyg_scheduler_unlock();
+}
+
+#define SPL_ENTER(x)    (x) = cyg_splin()
+#define SPL_SOFTNET(x)  (x) = cyg_splin()
+#define SPL_EXIT(x)     cyg_splout((x))
+
+#else
+
+// Old interrupt based version
+#define SPL_ENTER(x)    HAL_DISABLE_INTERRUPTS((x))
+#define SPL_SOFTNET(x)  HAL_DISABLE_INTERRUPTS((x))
+#define SPL_EXIT(x)     HAL_RESTORE_INTERRUPTS((x))
+
+#endif
+#endif
+// ------------------------------------------------------------------------
+
 cyg_uint32
 cyg_splimp(void)
 {
     cyg_uint32 old_ints;
-    HAL_DISABLE_INTERRUPTS(old_ints);
+    SPL_ENTER(old_ints);
     return old_ints;
 }
 
@@ -114,7 +214,7 @@ cyg_uint32
 cyg_splnet(void)
 {
     cyg_uint32 old_ints;
-    HAL_DISABLE_INTERRUPTS(old_ints);
+    SPL_ENTER(old_ints);
     return old_ints;
 }
 
@@ -122,7 +222,7 @@ cyg_uint32
 cyg_splclock(void)
 {
     cyg_uint32 old_ints;
-    HAL_DISABLE_INTERRUPTS(old_ints);
+    SPL_ENTER(old_ints);
     return old_ints;
 }
 
@@ -130,14 +230,14 @@ cyg_uint32
 cyg_splsoftnet(void)
 {
     cyg_uint32 old_ints;
-    HAL_DISABLE_INTERRUPTS(old_ints);
+    SPL_SOFTNET(old_ints);
     return old_ints;
 }
 
 void
 cyg_splx(cyg_uint32 old_lev)
 {
-    HAL_RESTORE_INTERRUPTS(old_lev);
+    SPL_EXIT(old_lev);
 }
 
 void
@@ -497,11 +597,19 @@ cyg_wakeup(void *chan)
 int       
 cyg_tsleep(void *chan, int pri, char *wmesg, int timo)
 {
-    int i, res;
+    int i, res = 0;
     struct wakeup_event *ev;    
     cyg_tick_count_t sleep_time;
-    res = 0;
+#ifdef SPLSOFTNET_IS_A_MUTEX
+    int olock; // this does the same as safe_lock() but keeping the old state
+    cyg_scheduler_lock(); // ...around.
+    olock = cyg_scheduler_read_lock();
+    if ( olock > 1 )
+        cyg_scheduler_unlock();
+#else
     cyg_scheduler_safe_lock();  // Ensure safe scan
+#endif
+
     for (i = 0, ev = wakeup_list;  i < CYGPKG_NET_NUM_WAKEUP_EVENTS;  i++, ev++) {
         if (ev->chan == 0) {
             ev->chan = chan;
@@ -511,16 +619,41 @@ cyg_tsleep(void *chan, int pri, char *wmesg, int timo)
     if (i == CYGPKG_NET_NUM_WAKEUP_EVENTS) {
         panic("no sleep slots");
     }
-    cyg_scheduler_unlock();
-    if (timo) {
-        sleep_time = cyg_current_time() + timo;
-        if (!cyg_semaphore_timed_wait(&ev->sem, sleep_time)) {
-            res = ETIMEDOUT;
-            ev->chan = 0;  // Free slot
+    CYG_ASSERT( 1 == cyg_scheduler_read_lock(), "Sleep won't!" );
+
+#ifdef SPLSOFTNET_IS_A_MUTEX
+    {   // Then we must release the mutex when we wait - if we have it
+        cyg_handle_t self = cyg_thread_self();
+        if ( self == owner ) {
+            owner = 0;
+            cyg_mutex_unlock( &mutex );
+        } else {
+            self = 0; // Flag no need to reclaim
         }
-    } else {
-        cyg_semaphore_wait(&ev->sem);
+#endif
+
+        // This part actually does the wait:
+        cyg_scheduler_unlock();
+        if (timo) {
+            sleep_time = cyg_current_time() + timo;
+            if (!cyg_semaphore_timed_wait(&ev->sem, sleep_time)) {
+                res = ETIMEDOUT;
+                ev->chan = 0;  // Free slot
+            }
+        } else {
+            cyg_semaphore_wait(&ev->sem);
+        }
+
+#ifdef SPLSOFTNET_IS_A_MUTEX
+        if ( self ) { // return to previous state
+            cyg_mutex_lock( &mutex ); // this might wait
+            owner = self; // got it now...
+        }
+        if ( olock > 1 )
+            cyg_scheduler_lock();
     }
+#endif
+
     return res;
 }
 
@@ -590,6 +723,10 @@ cyg_net_init(void)
     cyg_do_net_init();  // Just forces the linking in of the initializer/constructor
     // Initialize interrupt "flags"
     cyg_flag_init(&netint_flags);
+    // Anthing else needed?
+#ifdef SPLINIT
+    SPLINIT();
+#endif
     // Create network background thread
     cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY, // Priority
                       cyg_netint,               // entry
diff --git a/packages/net/tcpip/current/tests/ping_test.c b/packages/net/tcpip/current/tests/ping_test.c
index 2d4091671..06575bf12 100644
--- a/packages/net/tcpip/current/tests/ping_test.c
+++ b/packages/net/tcpip/current/tests/ping_test.c
@@ -56,6 +56,37 @@
 
 #include <network.h>
 
+#include <pkgconf/system.h>
+#include <pkgconf/net.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGBLD_DEVS_ETH_DEVICE_H    // Get the device config if it exists
+#include CYGBLD_DEVS_ETH_DEVICE_H  // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME
+#endif
+
+#ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test?
+# ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists
+#  include CYGTST_DEVS_ETH_TEST_NET_REALTIME
+# endif
+#endif
+
+// Fill in the blanks if necessary
+#ifndef TNR_OFF
+# define TNR_OFF()
+#endif
+#ifndef TNR_ON
+# define TNR_ON()
+#endif
+#ifndef TNR_INIT
+# define TNR_INIT()
+#endif
+#ifndef TNR_PRINT_ACTIVITY
+# define TNR_PRINT_ACTIVITY()
+#endif
+
+
+
 #define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
 static char stack[STACK_SIZE];
 static cyg_thread thread_data;
@@ -63,18 +94,20 @@ static cyg_handle_t thread_handle;
 
 #define NUM_PINGS 16
 #define MAX_PACKET 4096
+#define MIN_PACKET   64
+#define MAX_SEND   4000
+
+#define PACKET_ADD  ((MAX_SEND - MIN_PACKET)/NUM_PINGS)
+#define nPACKET_ADD  1 
+
 static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET];
 
 #define UNIQUEID 0x1234
 
-extern void
-cyg_test_exit(void);
-
 void
 pexit(char *s)
 {
-    perror(s);
-    cyg_test_exit();
+    CYG_TEST_FAIL_FINISH(s);
 }
 
 // Compute INET checksum
@@ -149,7 +182,7 @@ static void
 ping_host(int s, struct sockaddr_in *host)
 {
     struct icmp *icmp = (struct icmp *)pkt1;
-    int icmp_len = 64;
+    int icmp_len = MIN_PACKET;
     int seq, ok_recv, bogus_recv;
     cyg_tick_count_t *tp;
     long *dp;
@@ -159,7 +192,8 @@ ping_host(int s, struct sockaddr_in *host)
     ok_recv = 0;
     bogus_recv = 0;
     diag_printf("PING server %s\n", inet_ntoa(host->sin_addr));
-    for (seq = 0;  seq < NUM_PINGS;  seq++) {
+    for (seq = 0;  seq < NUM_PINGS;  seq++, icmp_len += PACKET_ADD ) {
+        TNR_ON();
         // Build ICMP packet
         icmp->icmp_type = ICMP_ECHO;
         icmp->icmp_code = 0;
@@ -177,12 +211,14 @@ ping_host(int s, struct sockaddr_in *host)
         icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8);
         // Send it off
         if (sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host)) < 0) {
+            TNR_OFF();
             perror("sendto");
             continue;
         }
         // Wait for a response
         fromlen = sizeof(from);
         len = recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&from, &fromlen);
+        TNR_OFF();
         if (len < 0) {
             perror("recvfrom");
         } else {
@@ -193,6 +229,7 @@ ping_host(int s, struct sockaddr_in *host)
             }
         }
     }
+    TNR_OFF();
     diag_printf("Sent %d packets, received %d OK, %d bad\n", NUM_PINGS, ok_recv, bogus_recv);
 }
 
@@ -205,12 +242,12 @@ ping_test(struct bootp *bp)
     int s;
 
     if ((p = getprotobyname("icmp")) == (struct protoent *)0) {
-        perror("getprotobyname");
+        pexit("getprotobyname");
         return;
     }
     s = socket(AF_INET, SOCK_RAW, p->p_proto);
     if (s < 0) {
-        perror("socket");
+        pexit("socket");
         return;
     }
     tv.tv_sec = 1;
@@ -230,6 +267,7 @@ void
 net_test(cyg_addrword_t p)
 {
     diag_printf("Start PING test\n");
+    TNR_INIT();
     init_all_network_interfaces();
 #ifdef CYGHWR_NET_DRIVER_ETH0
     if (eth0_up) {
@@ -241,7 +279,8 @@ net_test(cyg_addrword_t p)
         ping_test(&eth1_bootp_data);
     }
 #endif
-    cyg_test_exit();
+    TNR_PRINT_ACTIVITY();
+    CYG_TEST_PASS_FINISH("Ping test OK");
 }
 
 void
diff --git a/packages/net/tcpip/current/tests/tcp_echo.c b/packages/net/tcpip/current/tests/tcp_echo.c
index b5e425be2..63d7c298d 100644
--- a/packages/net/tcpip/current/tests/tcp_echo.c
+++ b/packages/net/tcpip/current/tests/tcp_echo.c
@@ -57,6 +57,35 @@
 //
 //==========================================================================
 
+#include <pkgconf/system.h>
+#include <pkgconf/net.h>
+
+#ifdef CYGBLD_DEVS_ETH_DEVICE_H    // Get the device config if it exists
+#include CYGBLD_DEVS_ETH_DEVICE_H  // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME
+#endif
+
+#ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test?
+# ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists
+#  include CYGTST_DEVS_ETH_TEST_NET_REALTIME
+# endif
+#endif
+
+
+// Fill in the blanks if necessary
+#ifndef TNR_OFF
+# define TNR_OFF()
+#endif
+#ifndef TNR_ON
+# define TNR_ON()
+#endif
+#ifndef TNR_INIT
+# define TNR_INIT()
+#endif
+#ifndef TNR_PRINT_ACTIVITY
+# define TNR_PRINT_ACTIVITY()
+#endif
+
+
 // Network throughput test code
 
 #include <lib/libkern/libkern.h>
@@ -118,6 +147,7 @@ cyg_test_exit(void);
 void
 pexit(char *s)
 {
+    TNR_OFF();
     perror(s);
     cyg_test_exit();
 }
@@ -449,26 +479,34 @@ echo_test(cyg_addrword_t p)
     starttime = cyg_current_time();
     start_load(params.load);
 
+    TNR_ON();
+
     // Echo the data from the source to the sink hosts
     for (i = 0;  i < params.nbufs;  i++) {
         if ((len = do_read(e_source, data_buf, params.bufsize)) != params.bufsize) {
+            TNR_OFF();
             diag_printf("Can't read buf #%d: ", i+1);
             if (len < 0) {
                 perror("I/O error");
             } else {
                 diag_printf("short read - only %d bytes\n", len);
             }
+            TNR_ON();
         }
         if ((len = do_write(e_sink, data_buf, params.bufsize)) != params.bufsize) {
+            TNR_OFF();
             diag_printf("Can't write buf #%d: ", i+1);
             if (len < 0) {
                 perror("I/O error");
             } else {
                 diag_printf("short write - only %d bytes\n", len);
             }
+            TNR_ON();
         }
     }
 
+    TNR_OFF();
+
     // Wait for the data to drain and the "sink" to tell us all is OK.
     if (do_read(e_sink, &status, sizeof(status)) != sizeof(status)) {
         pexit("Can't receive ACK from 'sink' host");
@@ -511,7 +549,15 @@ net_test(cyg_addrword_t param)
     diag_printf("Start TCP test - ECHO mode\n");
     init_all_network_interfaces();
     calibrate_load(DESIRED_BACKGROUND_LOAD);
+    TNR_INIT();
+#ifdef CYGPKG_SNMPAGENT
+    {
+        extern void cyg_net_snmp_init(void);
+        cyg_net_snmp_init();
+    }
+#endif
     echo_test(param);
+    TNR_PRINT_ACTIVITY();
     cyg_test_exit();
 }
 
@@ -558,3 +604,5 @@ cyg_start(void)
     }
     cyg_scheduler_start();
 }
+
+// EOF tcp_echo.c
-- 
GitLab