changeset 182:f62680ef1804

Merge from eCos master repository on 2001-09-07-06:43:02-BST
author jlarmour
date Wed, 12 Sep 2001 00:59:17 +0000
parents d61da071934c
children 9160a8005d76
files host/tools/configtool/common/common/build.cxx host/tools/configtool/standalone/wxwin/CHANGES.txt host/tools/configtool/standalone/wxwin/README.txt host/tools/configtool/standalone/wxwin/TODO.txt host/tools/configtool/standalone/wxwin/about.htm host/tools/configtool/standalone/wxwin/aboutdlg.cpp host/tools/configtool/standalone/wxwin/admindlg.cpp host/tools/configtool/standalone/wxwin/admindlg.h host/tools/configtool/standalone/wxwin/appsettings.cpp host/tools/configtool/standalone/wxwin/appsettings.h host/tools/configtool/standalone/wxwin/bitmaps/splash16.png host/tools/configtool/standalone/wxwin/configtool.cpp host/tools/configtool/standalone/wxwin/configtool.h host/tools/configtool/standalone/wxwin/configtooldoc.cpp host/tools/configtool/standalone/wxwin/ecutils.cpp host/tools/configtool/standalone/wxwin/ecutils.h host/tools/configtool/standalone/wxwin/mainwin.cpp host/tools/configtool/standalone/wxwin/settingsdlg.cpp host/tools/configtool/standalone/wxwin/setup/configtool.iss host/tools/configtool/standalone/wxwin/setup/makesetup.sh host/tools/configtool/standalone/wxwin/setup/maketarball.sh host/tools/configtool/standalone/wxwin/symbols.h packages/ChangeLog packages/NEWS packages/compat/posix/current/ChangeLog packages/compat/posix/current/cdl/posix.cdl packages/devs/eth/amd/pcnet/current/ChangeLog packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h packages/devs/eth/amd/pcnet/current/src/if_pcnet.c packages/devs/eth/arm/ebsa285/current/ChangeLog packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c packages/devs/eth/arm/iq80310/current/ChangeLog packages/devs/eth/arm/iq80310/current/src/if_iq80310.c packages/devs/eth/cf/current/ChangeLog packages/devs/eth/cf/current/src/if_sc_lpe.c packages/devs/eth/intel/i82559/current/ChangeLog packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl packages/devs/eth/intel/i82559/current/src/if_i82559.c packages/devs/eth/ns/dp83902a/current/ChangeLog packages/devs/eth/ns/dp83902a/current/include/dp83902a.h packages/devs/eth/powerpc/fec/current/ChangeLog packages/devs/eth/powerpc/fec/current/src/if_fec.c packages/devs/eth/powerpc/quicc/current/ChangeLog packages/devs/eth/powerpc/quicc/current/src/if_quicc.c packages/devs/flash/intel/strata/current/ChangeLog packages/devs/flash/intel/strata/current/src/flash_program_buf.c packages/devs/kbd/arm/ipaq/current/ChangeLog packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl packages/devs/serial/arm/iq80310/current/ChangeLog packages/devs/serial/arm/iq80310/current/include/arm_iq80310_ser.inl packages/devs/touch/arm/ipaq/current/ChangeLog packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl packages/ecos.db packages/hal/arm/arch/current/ChangeLog packages/hal/arm/arch/current/src/arm_stub.c packages/hal/arm/ebsa285/current/ChangeLog packages/hal/arm/ebsa285/current/src/redboot_cmds.c packages/hal/arm/iq80310/current/ChangeLog packages/hal/arm/iq80310/current/cdl/hal_arm_iq80310.cdl packages/hal/arm/iq80310/current/include/hal_platform_setup.h packages/hal/arm/iq80310/current/src/diag/cycduart.c packages/hal/arm/iq80310/current/src/diag/ether_test.c packages/hal/arm/iq80310/current/src/diag/pci_serv.c packages/hal/arm/iq80310/current/src/iq80310_misc.c packages/hal/arm/iq80310/current/src/iq80310_pci.c packages/hal/arm/sa11x0/ipaq/current/ChangeLog packages/hal/arm/sa11x0/ipaq/current/src/lcd_support.c packages/hal/arm/sa11x0/ipaq/current/src/redboot_cmds.c packages/hal/arm/sa11x0/var/current/ChangeLog packages/hal/arm/sa11x0/var/current/src/redboot_linux_exec.c packages/hal/common/current/ChangeLog packages/hal/common/current/src/generic-stub.c packages/hal/i386/arch/current/ChangeLog packages/hal/i386/arch/current/cdl/hal_i386.cdl packages/hal/i386/arch/current/include/arch.inc packages/hal/i386/arch/current/include/hal_arch.h packages/hal/i386/arch/current/include/hal_intr.h packages/hal/i386/arch/current/include/hal_io.h packages/hal/i386/arch/current/src/i386.ld packages/hal/i386/arch/current/src/vectors.S packages/hal/i386/pc/current/ChangeLog packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.ldi packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.mlt packages/hal/i386/pc/current/misc/redboot_FLOPPY.ecm packages/hal/i386/pc/current/misc/redboot_ROM.ecm packages/hal/i386/pc/current/src/plf_misc.c packages/hal/i386/pcmb/current/ChangeLog packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl packages/hal/i386/pcmb/current/include/pcmb_intr.h packages/hal/i386/pcmb/current/include/pcmb_io.h packages/hal/i386/pcmb/current/src/pcmb_misc.c packages/hal/mips/arch/current/ChangeLog packages/hal/mips/arch/current/src/redboot_linux_exec.c packages/hal/mips/rm7000/ocelot/current/ChangeLog packages/hal/mips/rm7000/ocelot/current/cdl/hal_mips_rm7000_ocelot.cdl packages/hal/mn10300/stb/current/ChangeLog packages/hal/mn10300/stb/current/src/plf_misc.c packages/hal/powerpc/mpc8xx/current/ChangeLog packages/hal/powerpc/mpc8xx/current/src/mpc8xxrev.c packages/hal/sh/arch/current/ChangeLog packages/hal/sh/arch/current/src/sh_stub.c packages/hal/sh/sh3/current/ChangeLog packages/hal/sh/sh3/current/include/mod_7729.h packages/hal/sh/sh3/current/include/mod_regs_ubc.h packages/infra/current/ChangeLog packages/infra/current/cdl/infra.cdl packages/infra/current/include/cyg_ass.h packages/infra/current/include/cyg_type.h packages/infra/current/include/diag.h packages/infra/current/src/buffer.cxx packages/infra/current/src/diag.cxx packages/infra/current/src/eprintf.c packages/infra/current/src/fancy.cxx packages/infra/current/src/null.cxx packages/infra/current/src/simple.cxx packages/io/eth/current/ChangeLog packages/io/eth/current/cdl/eth_drivers.cdl packages/io/eth/current/src/net/eth_drv.c packages/io/eth/current/src/stand_alone/eth_drv.c packages/io/pci/current/ChangeLog packages/io/pci/current/src/pci.c packages/kernel/current/ChangeLog packages/kernel/current/cdl/instrument.cdl packages/kernel/current/cdl/kernel.cdl packages/kernel/current/cdl/thread.cdl packages/kernel/current/host/instr/dump_instr.c packages/kernel/current/host/instr/instrument.sh packages/kernel/current/host/instr/readme.txt packages/kernel/current/include/instrmnt.h packages/kernel/current/include/instrument_desc.h packages/kernel/current/include/intr.hxx packages/kernel/current/include/kapidata.h packages/kernel/current/include/mqueue.inl packages/kernel/current/include/smp.hxx packages/kernel/current/include/thread.hxx packages/kernel/current/include/thread.inl packages/kernel/current/src/common/kapi.cxx packages/kernel/current/src/common/thread.cxx packages/kernel/current/src/instrmnt/meminst.cxx packages/kernel/current/src/instrmnt/nullinst.cxx packages/kernel/current/src/intr/intr.cxx packages/kernel/current/src/sched/mlqueue.cxx packages/kernel/current/src/sync/mutex.cxx packages/kernel/current/tests/intr0.cxx packages/kernel/current/tests/kintr0.c packages/kernel/current/tests/smp.cxx packages/kernel/current/tests/timeslice.c packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/include/net/net.h packages/redboot/current/include/redboot.h packages/redboot/current/src/flash.c packages/redboot/current/src/fs/disk.c packages/redboot/current/src/fs/e2fs.c packages/redboot/current/src/fs/ide.c packages/redboot/current/src/io.c packages/redboot/current/src/load.c packages/redboot/current/src/main.c packages/redboot/current/src/misc_funs.c packages/redboot/current/src/net/enet.c packages/redboot/current/src/net/inet_addr.c packages/redboot/current/src/net/net_io.c packages/redboot/current/src/net/ping.c packages/redboot/current/src/net/pktbuf.c packages/redboot/current/src/net/udp.c packages/redboot/current/src/parse.c packages/redboot/current/src/printf.c packages/redboot/current/src/syscall.c packages/redboot/current/src/xyzModem.c packages/redboot/current/src/xyzModem.h packages/templates/redboot/ChangeLog packages/templates/redboot/current.ect
diffstat 173 files changed, 6108 insertions(+), 1938 deletions(-) [+]
line wrap: on
line diff
--- a/host/tools/configtool/common/common/build.cxx
+++ b/host/tools/configtool/common/common/build.cxx
@@ -39,7 +39,7 @@
 //####DESCRIPTIONEND####
 //==========================================================================
 
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
 	#include <windows.h> /* for GetShortPathNameA() */
 #endif
 #ifdef __CYGWIN__
@@ -120,7 +120,7 @@ static void path_to_vector (std::string 
 
 // eliminate spaces from a DOS filepath by substituting the
 // short form of path components containing spaces
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
 std::string nospace_path (const std::string input) {
 	// split the path into a vector of path components
 	std::vector <std::string> long_path_vector;
@@ -151,7 +151,7 @@ std::string nospace_path (const std::str
 
 // convert a DOS filepath to a Cygwin filepath
 std::string cygpath (const std::string input) {
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
 	// remove spaces from the DOS filepath
 	const std::string path = nospace_path (input);
 	std::string output;
@@ -323,7 +323,7 @@ bool generate_makefile (const CdlConfigu
 	fprintf (stream, "export COMMAND_PREFIX := %s\n", command_prefix.c_str ());
 	fprintf (stream, "export CC := $(COMMAND_PREFIX)gcc\n");
 	fprintf (stream, "export OBJCOPY := $(COMMAND_PREFIX)objcopy\n");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
     fprintf (stream, "export HOST := CYGWIN\n");
 #else
     fprintf (stream, "export HOST := UNIX\n");
@@ -415,7 +415,7 @@ bool generate_makefile (const CdlConfigu
 	fprintf (stream, "\n\n");
 	for (count = 0; count < info.headers.size (); count++) { // for each header
 		fprintf (stream, "$(PREFIX)/include/%s: $(REPOSITORY)/$(PACKAGE)/%s\n", info.headers [count].destination.c_str (), info.headers [count].source.c_str ());
-#if defined(_WIN32) && (ECOS_USE_CYGDRIVE == 1)
+#if (defined(_WIN32) || defined(__CYGWIN__)) && (ECOS_USE_CYGDRIVE == 1)
         fprintf (stream, "ifeq ($(HOST),CYGWIN)\n");
 	    fprintf (stream, "\t@mkdir -p `cygpath -w \"$(dir $@)\" | sed \"s/\\\\\\\\\\/\\\\//g\"`\n");
         fprintf (stream, "else\n");
@@ -482,7 +482,7 @@ bool generate_toplevel_makefile (const C
 
 	// generate the variables
 	fprintf (stream, "export REPOSITORY := %s\n", cygpath (config->get_database ()->get_component_repository ()).c_str ());
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
     fprintf (stream, "export HOST := CYGWIN\n");
 #else
     fprintf (stream, "export HOST := UNIX\n");
@@ -545,7 +545,7 @@ bool generate_toplevel_makefile (const C
 
 // generates the directory structure for the build and install trees
 bool generate_build_tree (const CdlConfiguration config, const std::string build_tree, const std::string install_tree /* = "" */ ) {
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
 	// convert backslash directory separators to forward slashes under Win32
 	const std::string build_dir = replace_char (build_tree, '\\', '/');
 	const std::string install_dir = install_tree.empty () ? build_dir + "/install" : replace_char (install_tree, '\\', '/');
--- a/host/tools/configtool/standalone/wxwin/CHANGES.txt
+++ b/host/tools/configtool/standalone/wxwin/CHANGES.txt
@@ -1,6 +1,28 @@
 Release History for eCos Configuration Tool 2
 =============================================
 
+*** Version 2.07, September 5th 2001
+
+- Image (png) files and about.htm now incorporated into configtool.bin,
+  which is an ordinary zip file.
+
+
+*** Version 2.06, August 30th 2001
+
+- Now saves the width of the configuration tree pane.
+
+- New -r (--edit-only) command-line switch which suppresses creation
+  of build trees when saving .ecc files.
+
+- Added -v (--version), -h (--help) switches, and under Unix the
+  resulting output goes on the terminal, not a dialog box.
+
+- The build tree will now only get generated when the file is saved instead
+  of when a new document is created or template selected.
+
+- Added recursive process killing for implementing Stop command.
+
+
 *** Version 2.05, August 10th 2001
 
 - Fixed a bug in the administration dialog that only looked at the filename of the
--- a/host/tools/configtool/standalone/wxwin/README.txt
+++ b/host/tools/configtool/standalone/wxwin/README.txt
@@ -116,9 +116,7 @@ Installing the Configuration Tool
   The following files will be extracted to the installation directory:
 
   configtool
-  ecoslogo.png
-  rhlogo.png
-  about.htm
+  configtool.bin
   README.txt
   license.txt
   ecosplatforms.tar.gz
--- a/host/tools/configtool/standalone/wxwin/TODO.txt
+++ b/host/tools/configtool/standalone/wxwin/TODO.txt
@@ -31,3 +31,6 @@ To-Do List for Configuration Tool 2.x
 
   Bart says: "The whole makefile generation system needs a major overhaul."
 
+- Make as many UI elements as possible copyable to the clipboard, such as the
+  name and description for a configuration option. Can do this via the right-click
+  menus.
--- a/host/tools/configtool/standalone/wxwin/about.htm
+++ b/host/tools/configtool/standalone/wxwin/about.htm
@@ -10,7 +10,7 @@
   <table>
   <tr>
   <td>
-  <IMG src="rhlogo.png" align=left vspace=2>
+  <IMG src="memory:rhlogo.png" align=left vspace=2>
   </td>
 
   <td bgcolor="#101010">
@@ -60,7 +60,7 @@ Drew Moseley<BR>
   </td>
   
 <td valign=center align=center>
-<IMG src="ecoslogosmall.png" align=center>
+<IMG src="memory:ecoslogosmall.png" align=center>
 </td>
 
   <td valign=top align=left>
--- a/host/tools/configtool/standalone/wxwin/aboutdlg.cpp
+++ b/host/tools/configtool/standalone/wxwin/aboutdlg.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/11
-// Version:     $Id: aboutdlg.cpp,v 1.11 2001/06/27 14:07:05 julians Exp $
+// Version:     $Id: aboutdlg.cpp,v 1.12 2001/09/05 14:35:53 julians Exp $
 // Purpose:
 // Description: Implementation file for ecAboutDialog
 // Requires:
@@ -52,6 +52,7 @@
 #include "wx/wxhtml.h"
 #include "wx/datetime.h"
 #include "wx/file.h"
+#include "wx/fs_mem.h"
 
 #ifdef __BORLANDC__
     #pragma hdrstop
@@ -81,23 +82,28 @@ ecAboutDialog::ecAboutDialog( wxWindow *
 
 bool ecAboutDialog::AddControls(wxWindow* parent)
 {
-    wxSetWorkingDirectory(wxGetApp().GetAppDir());
-    wxString htmlFile(wxGetApp().GetFullAppPath(wxT("about.htm")));
+    wxString htmlText;
 
-    wxString htmlText;
-    if (wxFileExists(htmlFile))
+    if (!wxGetApp().GetMemoryTextResource(wxT("about.htm"), htmlText))
     {
-        wxFile file;
-        file.Open(htmlFile, wxFile::read);
-        long len = file.Length();
-        char* buf = htmlText.GetWriteBuf(len + 1);
-        file.Read(buf, len);
-        buf[len] = 0;
-        htmlText.UngetWriteBuf();
+        wxSetWorkingDirectory(wxGetApp().GetAppDir());
+        wxString htmlFile(wxGetApp().GetFullAppPath(wxT("about.htm")));
+        
+        if (wxFileExists(htmlFile))
+        {
+            wxFile file;
+            file.Open(htmlFile, wxFile::read);
+            long len = file.Length();
+            char* buf = htmlText.GetWriteBuf(len + 1);
+            file.Read(buf, len);
+            buf[len] = 0;
+            htmlText.UngetWriteBuf();
+        }
     }
-    else
+
+    if (htmlText.IsEmpty())
     {
-        htmlText.Printf(wxT("<html><head><title>Warning</title></head><body><P>Sorry, could not find file for About dialog, %s<P></body></html>"), (const wxChar*) htmlFile);
+        htmlText.Printf(wxT("<html><head><title>Warning</title></head><body><P>Sorry, could not find resource for About dialog<P></body></html>"));
     }
 
     // Customize the HTML
--- a/host/tools/configtool/standalone/wxwin/admindlg.cpp
+++ b/host/tools/configtool/standalone/wxwin/admindlg.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/28
-// Version:     $Id: admindlg.cpp,v 1.5 2001/08/10 14:58:21 julians Exp $
+// Version:     $Id: admindlg.cpp,v 1.6 2001/08/22 16:50:32 julians Exp $
 // Purpose:
 // Description: Implementation file for ecAdminDialog
 // Requires:
@@ -245,7 +245,7 @@ void ecAdminDialog::OnAdd(wxCommandEvent
                 wxString strCommand;
                 strCommand.Printf(wxT("add %s --extract_license"), (const wxChar*) strPathName);
                 strCommand.Replace(wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile
-                EvalTclFile (3, strCommand);
+                EvalTclFile (3, strCommand, _("Adding package"));
 
                 wxString strLicenseFile = m_strRepository + wxString(wxFILE_SEP_PATH) + wxT("pkgadd.txt");
 #ifdef __WXMSW__
@@ -280,7 +280,7 @@ void ecAdminDialog::OnAdd(wxCommandEvent
                 
                 strCommand.Printf (wxT("add %s --accept_license"), (const wxChar*) strPathName);
                 strCommand.Replace (wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile
-                if (! EvalTclFile (3, strCommand))  // if not successful
+                if (! EvalTclFile (3, strCommand, _("Adding package")))  // if not successful
                 {
                     // try the next file
                 }
@@ -398,7 +398,7 @@ bool ecAdminDialog::RemovePackageVersion
     wxString strCommand;
     wxString itemText(treeCtrl->GetItemText (hTreeItem));
     strCommand.Printf (wxT("remove %s --version %s"), (const wxChar*) pstrPackage, (const wxChar*) itemText);
-    if (! EvalTclFile (3, strCommand)) // if not successful
+    if (! EvalTclFile (3, strCommand, wxT("Removing package"))) // if not successful
         return false;
     
     treeCtrl->Delete (hTreeItem); // remove the selected item from the tree
@@ -505,9 +505,9 @@ bool ecAdminDialog::PopulatePackageTree 
 }
 
 
-bool ecAdminDialog::EvalTclFile(int nargc, const wxString& Argv)
+bool ecAdminDialog::EvalTclFile(int nargc, const wxString& Argv, const wxString& msg)
 {
-    wxProgressDialog dlgWait(_("Adding Package"), _("Please wait..."), 100, this);
+    wxProgressDialog dlgWait(msg, _("Please wait..."), 100, this);
 
     dlgWait.Update(50);
 
--- a/host/tools/configtool/standalone/wxwin/admindlg.h
+++ b/host/tools/configtool/standalone/wxwin/admindlg.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/28
-// Version:     $Id: admindlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $
+// Version:     $Id: admindlg.h,v 1.3 2001/08/22 16:50:32 julians Exp $
 // Purpose:
 // Description: Header file for ecAdminDialog
 // Requires:
@@ -70,7 +70,7 @@ public:
     void CreateControls(wxWindow* parent);
 	bool FindUserToolsPath();
 	bool RemovePackageVersion (wxTreeItemId hTreeItem);
-	bool EvalTclFile (int nargc, const wxString& argv);
+	bool EvalTclFile (int nargc, const wxString& argv, const wxString& msg);
 	void ClearPackageTree ();
 	bool PopulatePackageTree (const wxString& packageDatabase);
 
--- a/host/tools/configtool/standalone/wxwin/appsettings.cpp
+++ b/host/tools/configtool/standalone/wxwin/appsettings.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/29
-// Version:     $Id: appsettings.cpp,v 1.22 2001/06/26 17:26:35 julians Exp $
+// Version:     $Id: appsettings.cpp,v 1.24 2001/09/05 14:35:53 julians Exp $
 // Purpose:
 // Description: Implementation file for the ecSettings
 // Requires:
@@ -90,7 +90,7 @@ ecSettings::ecSettings()
     m_showToolBar = TRUE;
     m_frameSize = wxRect(0, 0, 600, 500);
     m_appName = _("eCos Configuration Tool");
-    m_showSplashScreen = FALSE;
+    m_showSplashScreen = TRUE;
     m_userName = wxEmptyString;
     m_serialNumber = 0;
     m_frameStatus = ecSHOW_STATUS_NORMAL;
@@ -101,6 +101,7 @@ ecSettings::ecSettings()
     m_shortDescrSashSize = wxSize(1000, 80);
     m_memorySashSize = wxSize(1000, 50);
     m_outputSashSize = wxSize(1000, 50);
+    m_configPaneWidth = 200;
     
     m_showConflictsWindow = FALSE;
     m_showPropertiesWindow = TRUE;
@@ -127,6 +128,8 @@ ecSettings::ecSettings()
     m_findDirection = TRUE; // Down is TRUE, Up is FALSE
     m_findSearchWhat = _("Macro names"); // Macro names, item names etc.
     m_findDialogPos = wxPoint(-1, -1);
+
+    m_editSaveFileOnly = FALSE;
 }
 
 // Copy constructor
@@ -148,7 +151,7 @@ void ecSettings::Copy(const ecSettings& 
     m_propertiesSashSize = settings.m_propertiesSashSize;
     m_memorySashSize = settings.m_memorySashSize;
     m_outputSashSize = settings.m_outputSashSize;
-    
+    m_configPaneWidth = settings.m_configPaneWidth;    
     m_showMacroNames = settings.m_showMacroNames;
     
     m_bUseCustomViewer = settings.m_bUseCustomViewer;
@@ -170,6 +173,8 @@ void ecSettings::Copy(const ecSettings& 
 
     m_userToolsDir = settings.m_userToolsDir;
     m_buildToolsDir = settings.m_buildToolsDir;
+
+    m_editSaveFileOnly = settings.m_editSaveFileOnly;
 }
 
 ecSettings::~ecSettings()
@@ -245,6 +250,7 @@ bool ecSettings::LoadConfig()
     
     config.Read(_("/Window Size/TreeSashWidth"), & m_treeSashSize.x);
     config.Read(_("/Window Size/TreeSashHeight"), & m_treeSashSize.y);
+    config.Read(_("/Window Size/ConfigPaneWidth"), & m_configPaneWidth);
     config.Read(_("/Window Size/ConflictsWidth"), & m_conflictsSashSize.x);
     config.Read(_("/Window Size/ConflictsHeight"), & m_conflictsSashSize.y);
     config.Read(_("/Window Size/PropertiesWidth"), & m_propertiesSashSize.x);
@@ -554,6 +560,7 @@ bool ecSettings::SaveConfig()
     config.Write(_("/Window Size/WindowHeight"), (long) m_frameSize.height);
     config.Write(_("/Window Size/TreeSashWidth"), (long) m_treeSashSize.x);
     config.Write(_("/Window Size/TreeSashHeight"), (long) m_treeSashSize.y);
+    config.Write(_("/Window Size/ConfigPaneWidth"), (long) m_configPaneWidth);
     config.Write(_("/Window Size/ConflictsWidth"), (long) m_conflictsSashSize.x);
     config.Write(_("/Window Size/ConflictsHeight"), (long) m_conflictsSashSize.y);
     config.Write(_("/Window Size/PropertiesWidth"), (long) m_propertiesSashSize.x);
--- a/host/tools/configtool/standalone/wxwin/appsettings.h
+++ b/host/tools/configtool/standalone/wxwin/appsettings.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/29
-// Version:     $Id: appsettings.h,v 1.9 2001/06/26 17:26:35 julians Exp $
+// Version:     $Id: appsettings.h,v 1.10 2001/08/22 16:50:32 julians Exp $
 // Purpose:
 // Description: Header file for the ConfigTool application settings
 // Requires:
@@ -192,6 +192,7 @@ public:
 	wxSize					m_shortDescrSashSize;
 	wxSize					m_memorySashSize;
 	wxSize					m_outputSashSize;
+    int                     m_configPaneWidth; // The sash to the right of the tree
     bool                    m_showConflictsWindow;
     bool                    m_showPropertiesWindow;
     bool                    m_showShortDescrWindow;
@@ -201,6 +202,10 @@ public:
     // Are we showing macro names, or ordinary names?
     bool                    m_showMacroNames ;
 
+    // Are we merely editing the .ecc file and not saving build trees?
+    // This option is specified on the command line and not saved.
+    bool                    m_editSaveFileOnly;
+
     // Viewers & browsers
     bool                    m_bUseCustomViewer;
     bool                    m_bUseExternalBrowser;
index 901e793fd4b3f8adb2c33577ab75b0bc57129d15..7351f93a5be6debeb0c3cac487e32ffe300cdca1
GIT binary patch
literal 4550
zc$}qFcQhLgyADYuF=N&!5~TK4vn65^rA154(pFJhZA!$Z)K*$sjoPD1idbJ&6|E5=
zrL{-xJ#T;K`|I9w?;qc}&pGdT&hxzQfA90YvBtM`=%_iV0RRA<p04Iy0Duw#08prc
zfPWoMj{T6o1oqK0)B=w{uh7X-%knI<{I#GSx)$C50KLyYMd2dQF#gw+GRBx{{bgEO
z_G~22rWPNw^n=?LuH{j$z7I|w20c2=PdWeEb-A{-xp}#JczStwczJnA&gI4f0F1(V
zn(C(hq(5&4-MRk7+8JFd#7(kqih0cayYLcA$MXz$r2-(j0^>>n=(h@F(CN+>_#z1@
z#C(1KtpW%vAIzIVNp&V!jC#$JqAkTVA&<I$>u4^S*ebVDpx1<YCKIJ)ID<c)Mhf?*
z&5zyPB(P=5HpuRV?k*1ISj5>U;QkwmL;5jkN;QLf*U3o&C6!h=P%QeRe6o*G%A?vC
z`Q+@IcovxkniH><*FKIZDZju6Cx4EMgHjWGZgJX)W$t=^Ox-G#tF=B(*gVxc3>aFt
zMtkw<8brklTX*4VSWqK3C)?4$mVzn2&rbOnN`WvTZA7g<IJbYtp)nLv3WqoVx?5@o
z=|WtBze)BWil=0>sX(CdAWikps^rC}b<Vt@n>_K(f8GU!<{vMaYkz~hsg2A>PIJX0
zOO;7I;X}(SaCpAc)9uK;I97Gx?Cn$B-=>KhBH}po#f?Fm!X-+$VmTt0Mc7-KD%4%O
zFj+*@VCxm-;t|K?zNrQ~2f)!|CuWYL?b^Fx1=Yo?SJk)q-p8W|c|xpd$ZO&;EHimR
zfTW_D`$<$QZ(y0y+IBi(phZyf`DGAssAKo^=K@}pq2V`CWX1|)0Dxp3F~q|pS@NE#
za_(k!l)VU5aWW%iGOf-G$VD+T4iUR6ABSzRfy<9;e_$t0l=B=9udkIH+9d2hnJ_3B
z15<W6CZ*gf2`QKPB+qFnM4Aq@nLBGMayjd;quI?4{iZMx4m9t&x+~TuGjzgcQF^Jh
zITD&huUGlK83N81>&)tk8Qh>q?6`1ItFZ;~AC2cN1UuQA&6+b#4eri-;XYc`8aFYl
z(Lq7<PbV6M6<q{qL&PupSiV9o6~9Ka+Bk4zad}_FnWIl!Xs;&kTsyUReK^~~GSBxL
z4KN6!Gs_-2y^y{rOxo?(t9NU}#V1c$cSE}J-hd&(A8<mE%y$fk*B)oHwwnsE1e~)I
z!(OuMAP$K%Qn(`KE48?{qn20;I2U|x>xApQOJdRJLoX}SATVuCo9*6{lZ-rw+{y=B
zwN8yv1L1kXEEBkAm<v)QZLlRdVG!AP3Ob;@@ar~KZi^m}zi-(!k*5}VcEpHckAHxj
zu?0^7@{(7_!o>-f)lH<38^|7d5hlSfq}1@q^3jn$PjFXc8S-d}HztDAXo;??G`^-7
z-MT8<pp_G!0jTUYBx>x}i)9Yr9H0vUbcn$WDVd(*bBS-fR2n~+BPb)=!c#J&Xb_Zc
z*C!O8vCVYF+_9iUeU4EqP#c43Vm=#K#p<rS_4bZLUW-O~2IKu1G4>|f378uC$5M$!
zF7~mQ-I2Q=#`DyyMB*XIi3ubtCn&kr*8hwhzhpsFdB6SK1)4nxZl7ULy456?C-`Vw
z4tM3A_U7V|)<Y;D+`5nQl8FY`GXg`^3w~j;naRrbzk8AOSi$joaHsrZOhHdxeQZ}k
z&@idv_)}PN<Sl_qis0FK<r>K|w~&|T*5>E~wc6C_d4?C;bsle<if>Ft?s<q7@hSRP
zQ4X+CE4EMCm&*ZbvhAIqsKk1#-H$7J8YLwoZZWJc(=$@WA6@<acoA3=tC1QQSJfKA
zAr0HOynCkGsurs|jxwh#Lh1NJ7INoU>B|vP0l^jIu7W)Xy1q|gT*uGW^1(t@eI$vv
zv8G?+!#W~OFF;NzmIe_X>Y&j7z$<2cc!N^+ACNM?7hDbNWcUOFVNoy$r8*n}3Wxv4
zf}8eX1DR_gHPR#K2|gWzKG>c1-3iqiGkqf_vC$!M3V7%c7;i-I-Grbe{H)F7Z>W+t
zVy-(uxhya0_iiJeQk$g8p4JTf)M)v9076$MG^J-6sBGNDFg4;VpC!R_EyypB2hgs*
zP8)S8w*qUuZ%pm>K~%rKUWnEi!J1F0V>83@@#v|PETp2XAo0c>p?SY6za~y=dfQPg
zPK|FgJDOR}$G#BI(v-iHSx7Bw%OQaQO*^*(tsJ}|PvkKbpu^KEZ4&)*z=sy?9o&|T
z^3`P@R&cci`?sE?tfyoP?+StDF6ge5G?jYrJ0YjA#))eK+iSWd_!1KqoQZFKM}ktg
zi?AoPA!4~^MrEydrDnXrc3>Y*ICj@G8J(IgFHV0(gC;(O^s$uM!}vH0g>!8ZS;BC|
z>C<$$x4OS&S6E%UcKgCSy3Jpd)K@s_NMtsqw1rC{t1qQ1#$)KL;4dA*zvz5qxSwY!
z=zmIDS@ZWaR4*eO-LHNQz$F+PgkIrN2In#~d<HHNtYx{jR)L;Ks!N5{eM~hFKC3YC
z&0^ETBw{jI<E;H2c{|#U;-i|Un<JWpILn>7p`L{{i}0LVs2@8@`|Vkj3XhRo9c}A(
zy8;R+sVsnG)hJ7UH~YJ+31tvA>*B+{WJdfW4~CB4zQ+@lwuT)aDcq}d^Ewq&S7{*&
z{ySw>QdW@PwX=eLZAT?gn7i#CUC7nq=PeTILT3)NSo%DX`zipmh8GRQw)M$&QG*M9
ziU13prtbouM2Wtk`StD(d>Kd;DtHe2;?cCM8pK6>qMZ93<|Pv)FCpiI^n()4mHj@w
zA-X;9Eb;!R0gt)U!4V<#9fXZ#=G&IJtE+|+=27yMFKFEMQ??(Sc<e@>Iyx7%r-6zb
zdsXQH4fy2O!W@}jkZX}>uIGqCMY>PUrN2ADXt}a^R0c=n9D7*Xw*OFv%_CC$mEVZR
zS1K`U+q3wbRQpDKXPgZewK1zMTN$Q!d50%|t7IEGn#(|JxIcV}S@`%C7(93QahliD
z438Bp@$Z;Mz+UPwRn~PsVU<iH%N!((2)}ZJSijQI@vaUqXXR&L-O#LC&PV(csQf$?
zjFQvI<}D)s@{(_eF<;W%dqwU)PNvm$z!o}$<9kN=*GyU*@SwP#TBW<tv;a0IUiHbc
z{xc=mt+~uWSLfONBHfU;|4ygfTYbkyu!q_}hV@IdVwGyu({HRprhM)uC#EDfj!}oB
z2Yaca%)Kc<^*<Tw4H;G&L#(IUxY1Bm!lVo)?VdqAuufd_ELFr&6~D&wUVEXl4aXAv
zL|6$DbiC38RO7n4rPMbM9~OLY=is1W5Nt`TJWe|$upKyu&it~Y2|{)pdv!*RNMafP
zUq9vFBDwK@I>S6Tosz??efN^|Dz_J=frpPDv{{R|r@L|m^#>k;yX;}0Or@Icwfy`#
z7;R;q5dv(pLtqgQBkUJ{tEQr;QSZt>nqx>7(6?K$V^0~VA14fCDfDQ)Ei;*>l9`vg
zzIHCo#-UG-Hgk>>!xCgF8cC2}h=WTnTFTNbr}uEmUu^BKn$o!tS$(FT8lW0k8L#!z
zHEj!~mbl=fb>>nnY|-#2v-TF4&HNkEH+fWTVtHV6N+kS5_7(499?FPX-(Z9r`mokm
zh!3=UVTX{6`WgwpJ3ebK#GZimhsPBOqg*5CV9y+ye+nR`8L$R;c_@{1<Mjmdr@|^~
z@7pBc`DPPXdmrVP37IqYZ$-RE`j5uu$#!cDzyN+{MX{VpYJrhH%};jXdT8@bn-HpV
zf35^s-rR_^n^ymVW9Alk{b?zkgVhv2z@Icl)^dQ{3#+>eLoHLWvvTrP_$}i?*dxi7
zofR75ALw#9PRbO!V1h~(1-VmGK!UN8RA_Ny<0xFH-2olU)FG#(ddo5SwE!+yicbZc
zYKfsA`J+&f+9&;%6|jn~G@^mufiU#A{!l;W5LrPBiIUlRtg;i)wTYjS8#U4Ouu>M#
z_6`doAuK=>@l1#pTw(>8>*@yPr;9klqK(sGv$jCcSe6JxvJyPVq-_VuF-P;`P_0es
zo}YexXUgBYFD_Q#D<$@j(>lv%mn4|b*~yi+CBYfLy#D*B#fy!tE1*Cmt!rvdRh^If
z=U1?-C#0h8gs=sbd4FDdJt#Fg91Lke_uPy2F6)8?s;oaZOks*|r#_*@DYw38QjTGN
zB(=f*+yU(HyhW1FHimh}ekD|>Dil=o+B{dPn08@CCLawMDz?>BTIz%TC^R-?|ALLv
z=J&)-WhF5G#IRtEKO|q}XTyl8FE?Xhc63STF#Fzpqh5$A^A)r8_$PS^(zTI*%D&_>
zLn>=$?}rFtUj?6UZpOALyrTn20m(5upyz)&#|U{|vKlAh&zAYwi8eJ;G~LqvnmEWz
zH*yB62f{Y^CGTS&mL=-*!RF;}Z}{xByMx*|!t<LW?TbqXD_}AGd%~?JuaBG%pIr;z
zyPA(J{>|hh*{Kj#+mYGhCtjW?jYcIcpovy#Kq}4!Wa8_WtWhm@$>DH%+O4e4x3^nh
z7>D`*g1iL;FOcNBiVW!5Gt>%>Bps%|*h&0yE4%i3eEL@Ugg$b6ENx$3>rAgPPRukM
zZ64ZC81GP3$W!gYq|i@8X20r)*%_kDs$dHDD8u~+FQAqermI^l;F{1+^M6er(4mR9
zfj<Z4qa;0D#4I};#6?{2<V76>?i&}IQ;)ZE`Uih=&1r-INufX-*L(Aw+U=_0#-$bC
zTjb5*)wy2M3=~&u_Lz|js>p!dTzadWQh(3Pd-)-wkttin&MKXEWjzdkw1vAp(QV$L
z@$(B4hE5zIS0(nK9SJIpGN!-!b3N8T=ug0JYI7NUPQQdU+~f56C=6qkyx31c%{>Jz
zA^X?Q6f_E~e{j|{>#SA2-mh_+{Wa|}^*Df=wr=yQ%bn~BG$~@$nIC6-z49t<Hgc7>
zAv1Y(#nYbF)#yT_NgVVl`a_vK+7(*hq&g~YC%(wEMonJ4CF|yue@lTOHEWr5rb0#{
zXlc6&Aw{QNkhE7Q461JB<ec*rBc$GNHn6LL!wX>L0VJ#iKWIJensp=m72?I0)@+W>
z#dIyWRQgO0(=(-^y>X4LJCH!-EH9D|9}KPZj2bK8guqc@-|0l<ghm^Rg-=m7yG(N+
zU7&^{@xn_=8jQQpFP|y{_}^95c|-HoVoT$`Si}WNmA+HiZ8X|?Zxm)VG}p>DgdQ&9
zl5ym8&|u7iIUCH1jaIc}<OidPc$r+z(sef2>o`Ypo#W;&S3OJ5KHrfp8`FAk2vjSh
zrqF^q2Z}a<_>uw*O)Qa{nqBuc(Mg*lqejx8p?lNRy%&6OD9BVqZ8!PnJs4hGbkbck
zcAXn8mKlz<ibe2z*lv!c#Jsfe*AVPXeuZzRa0vc9-dm?UhJM-%Y$*+r5!=@M(W+>Y
z9?R(iujEr88#W6D+XsPJ!~4VHCu0)41^wgKkv_pITKqThgjoOXW$uFEans5or7^h%
zx?Zo3q`{T?KUzF0;dVg38$=oQ_`M<ykQr8bWrh89tju!@Mw3-(j)Y3%;j(gIpwU=C
z3N45&Jd8Y@Q&N?U^Z*jbWv*btjfi2>e+_PYkAGlLcEGz~zD6$kX+$)h`N0(u;8>g!
z1f>8z=OW6ggn7jU1+ooXGwNOPs!+**3pU`@2Ls=|ZvuVdPCgYe>fK*0#+H-A-8yp(
zW17)FtUi+xdM(k!a(q4OdHM}a7%5^n0R6w;8lDBj#Dus6H`AB5@2~bU1O7r!>$YY!
H+7A0)^8+%5
--- a/host/tools/configtool/standalone/wxwin/configtool.cpp
+++ b/host/tools/configtool/standalone/wxwin/configtool.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/24
-// Version:     $Id: configtool.cpp,v 1.40 2001/07/16 14:02:56 julians Exp $
+// Version:     $Id: configtool.cpp,v 1.46 2001/09/05 14:35:53 julians Exp $
 // Purpose:
 // Description: Implementation file for the ConfigTool application class
 // Requires:
@@ -74,6 +74,8 @@
 #include "wx/process.h"
 #include "wx/mimetype.h"
 #include "wx/txtstrm.h"
+#include "wx/wfstream.h"
+#include "wx/fs_mem.h"
 
 #include "configtool.h"
 #include "configtoolview.h"
@@ -85,6 +87,7 @@
 #include "shortdescrwin.h"
 #include "conflictwin.h"
 #include "propertywin.h"
+#include "symbols.h"
 
 // ----------------------------------------------------------------------------
 // resources
@@ -115,6 +118,9 @@ static const wxCmdLineEntryDesc sg_cmdLi
     { wxCMD_LINE_OPTION, "s", "size",    "output block size", wxCMD_LINE_VAL_NUMBER },
     { wxCMD_LINE_OPTION, "d", "date",    "output file date", wxCMD_LINE_VAL_DATE },
 */
+    { wxCMD_LINE_SWITCH, "h", "help",   "displays help on the command line parameters" },
+    { wxCMD_LINE_SWITCH, "e", "edit-only",    "edit save file only" },
+    { wxCMD_LINE_SWITCH, "v", "version",    "print version" },
 
     { wxCMD_LINE_PARAM,  NULL, NULL, "input file 1", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
     { wxCMD_LINE_PARAM,  NULL, NULL, "input file 2", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
@@ -134,11 +140,16 @@ ecApp::ecApp()
     m_pipedProcess = NULL;
     m_valuesLocked = 0;
     m_helpController = NULL;
+    m_fileSystem = new wxFileSystem;
+#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
+    m_zipHandler = new wxZipFSHandler;
+#endif
 }
 
 ecApp::~ecApp()
 {
     delete m_whatsThisMenu;
+    delete m_fileSystem;
 }
 
 // 'Main program' equivalent: the program execution "starts" here
@@ -157,7 +168,7 @@ bool ecApp::OnInit()
 
     // Required for advanced HTML help
 #if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
-      wxFileSystem::AddHandler(new wxZipFSHandler);
+    wxFileSystem::AddHandler(m_zipHandler);
 #endif
 
     wxString currentDir = wxGetCwd();
@@ -175,6 +186,10 @@ bool ecApp::OnInit()
         m_appDir = wxPathOnly(m_appDir);
 #endif
 
+    // Load resources from binary resources archive, or failing that, from
+    // Windows resources or plain files
+    LoadResources();
+
     wxGetEnv(wxT("PATH"), & m_strOriginalPath);
 
     // Create a document manager
@@ -203,6 +218,33 @@ bool ecApp::OnInit()
     if (!m_settings.m_lastFilename.IsEmpty())
         templ->SetDirectory(wxPathOnly(m_settings.m_lastFilename));
 
+    // Parse the command-line parameters and options
+    wxCmdLineParser parser(sg_cmdLineDesc, argc, argv);
+    int res;
+    {
+        wxLogNull log;
+        res = parser.Parse();
+    }
+    if (res == -1 || res > 0 || parser.Found(wxT("h")))
+    {
+#ifdef __WXGTK__
+	wxLog::SetActiveTarget(new wxLogStderr);
+#endif
+        parser.Usage();
+        return FALSE;
+    }
+    if (parser.Found(wxT("v")))
+    {
+#ifdef __WXGTK__
+	wxLog::SetActiveTarget(new wxLogStderr);
+#endif
+	wxString msg;
+	msg.Printf(wxT("eCos Configuration Tool (c) Red Hat, 2001 Version %.2f, %s"), ecCONFIGURATION_TOOL_VERSION, __DATE__);
+        wxLogMessage(msg);
+        return FALSE;
+    }
+
+/*
 #ifdef __WXMSW__
     wxBitmap bitmap(wxBITMAP(splash));
 #else
@@ -210,9 +252,11 @@ bool ecApp::OnInit()
     if (wxFileExists("splash16.png"))
         bitmap.LoadFile("splash16.png", wxBITMAP_TYPE_PNG);
 #endif
-    if (bitmap.Ok() && GetSettings().m_showSplashScreen)
+*/
+
+    if (m_splashScreenBitmap.Ok() && GetSettings().m_showSplashScreen)
     {
-        m_splashScreen = new ecSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
+        m_splashScreen = new ecSplashScreen(m_splashScreenBitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
             6000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxFRAME_FLOAT_ON_PARENT|wxSTAY_ON_TOP);
     }
 
@@ -227,6 +271,9 @@ bool ecApp::OnInit()
     SetTopWindow(frame);
     frame->Show(TRUE);
     SendIdleEvents(); // Otherwise UI updates aren't done, because it's busy loading the repository
+#ifdef __WXMSW__
+    ::UpdateWindow((HWND) frame->GetHWND());
+#endif
 
     InitializeWindowSettings(FALSE /* beforeWindowConstruction */) ;
 
@@ -235,14 +282,9 @@ bool ecApp::OnInit()
 
     wxYieldIfNeeded();
 
-    // Parse the command-line parameters and options
-    wxCmdLineParser parser(sg_cmdLineDesc, argc, argv);
-    int res = parser.Parse();
-    if (res == -1 || res > 0)
-    {
-        parser.Usage();
-        return FALSE;
-    }
+    if (parser.Found(wxT("e")))
+        GetSettings().m_editSaveFileOnly = TRUE;
+
     wxString filenameToOpen1, filenameToOpen2;
     if (parser.GetParamCount() > 0)
     {
@@ -427,6 +469,153 @@ bool ecApp::OnInit()
     return TRUE;
 }
 
+// Load resources from disk
+bool ecApp::LoadResources()
+{
+    wxFileSystem::AddHandler(new wxMemoryFSHandler);
+
+    LoadBitmapResource(m_splashScreenBitmap, wxT("splash16.png"), wxBITMAP_TYPE_PNG, FALSE);
+
+    wxBitmap bitmap1, bitmap2, bitmap3;
+    LoadBitmapResource(bitmap1, wxT("ecoslogo.png"), wxBITMAP_TYPE_PNG, TRUE);
+    LoadBitmapResource(bitmap2, wxT("ecoslogosmall.png"), wxBITMAP_TYPE_PNG, TRUE);
+    LoadBitmapResource(bitmap3, wxT("rhlogo.png"), wxBITMAP_TYPE_PNG, TRUE);
+
+    wxString aboutText;
+    LoadTextResource(aboutText, wxT("about.htm"), TRUE);
+
+    VersionStampSplashScreen();
+
+    return TRUE;
+}
+
+// Load resources from zip resource file or disk
+bool ecApp::LoadBitmapResource(wxBitmap& bitmap, const wxString& filename, int bitmapType, bool addToMemoryFS)
+{
+    wxString archive(GetFullAppPath(wxT("configtool.bin")));
+
+#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
+    wxFSFile* file = m_fileSystem->OpenFile(archive + wxString(wxT("#zip:")) + filename);
+    if (file)
+    {
+        wxInputStream* stream = file->GetStream();
+        
+        wxImage image(* stream, bitmapType);
+        bitmap = image.ConvertToBitmap();
+        
+        delete file;
+    }
+#endif
+
+#ifdef __WXMSW__
+    if (!bitmap.Ok())
+        bitmap.LoadFile(filename, wxBITMAP_TYPE_BMP_RESOURCE);
+#endif
+
+    if (!bitmap.Ok() && wxFileExists(GetFullAppPath(filename)))
+        bitmap.LoadFile(GetFullAppPath(filename), bitmapType);
+
+
+    if (bitmap.Ok() && addToMemoryFS)
+        wxMemoryFSHandler::AddFile(filename, bitmap, bitmapType);
+
+    return bitmap.Ok();
+}
+
+// Load resources from zip resource file or disk
+bool ecApp::LoadTextResource(wxString& text, const wxString& filename, bool addToMemoryFS)
+{
+    wxString archive(GetFullAppPath(wxT("configtool.bin")));
+
+    bool success = FALSE;
+
+#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
+    wxFSFile* file = m_fileSystem->OpenFile(archive + wxString(wxT("#zip:")) + filename);
+    if (file)
+    {
+        wxInputStream* stream = file->GetStream();
+
+        char* buf = text.GetWriteBuf(stream->GetSize() + 1);
+        stream->Read((void*) buf, stream->GetSize());
+        buf[stream->GetSize()] = 0;
+        text.UngetWriteBuf();
+
+        success = TRUE;
+        
+        delete file;
+    }
+#endif
+
+    if (!success && wxFileExists(GetFullAppPath(filename)))
+    {
+        wxFileInputStream str(GetFullAppPath(filename));
+
+        char* buf = text.GetWriteBuf(str.GetSize() + 1);
+        str.Read((void*) buf, str.GetSize());
+        buf[str.GetSize()] = 0;
+        text.UngetWriteBuf();
+
+        success = TRUE;
+    }
+
+    if (success && addToMemoryFS)
+        wxMemoryFSHandler::AddFile(filename, text);
+
+    return success;
+}
+
+// Get a text resource from the memory filesystem
+bool ecApp::GetMemoryTextResource(const wxString& filename, wxString& text)
+{
+    wxString s(wxString(wxT("memory:")) + filename);
+    wxFSFile* file = wxGetApp().GetFileSystem()->OpenFile(s);
+    if (file)
+    {
+        wxInputStream* stream = file->GetStream();
+
+        char* buf = text.GetWriteBuf(stream->GetSize() + 1);
+        stream->Read((void*) buf, stream->GetSize());
+        buf[stream->GetSize()] = 0;
+        text.UngetWriteBuf();
+
+        delete file;
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+// Version-stamp the splash screen
+bool ecApp::VersionStampSplashScreen()
+{
+    if (m_splashScreenBitmap.Ok())
+    {
+        wxMemoryDC dc;
+        dc.SelectObject(m_splashScreenBitmap);
+
+        wxColour textColour(19, 49, 4);
+        dc.SetTextForeground(textColour);
+        dc.SetBackgroundMode(wxTRANSPARENT);
+        dc.SetFont(wxFont(11, wxSWISS, wxNORMAL, wxBOLD, FALSE));
+
+        // Bottom left of area to start drawing at
+
+        wxString verString;
+        verString.Printf("%.2f", ecCONFIGURATION_TOOL_VERSION);
+
+        int x = 339; int y = 236;
+        int w, h;
+        dc.GetTextExtent(verString, & w, & h);
+        dc.DrawText(verString, x, y - h);
+
+        dc.SelectObject(wxNullBitmap);
+
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
 // Initialize window settings object
 bool ecApp::InitializeWindowSettings(bool beforeWindowConstruction)
 {
@@ -628,7 +817,8 @@ void ecApp::SetStatusText(const wxString
         if (clearFailingRulesPane)
             mainFrame->GetStatusBar()->SetStatusText(wxT(""), ecFailRulePane);
 #ifdef __WXMSW__
-        wxYield();
+        ::UpdateWindow((HWND) mainFrame->GetHWND());
+        //wxYield();
 #endif
     }
 }
--- a/host/tools/configtool/standalone/wxwin/configtool.h
+++ b/host/tools/configtool/standalone/wxwin/configtool.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/24
-// Version:     $Id: configtool.h,v 1.25 2001/08/10 14:58:21 julians Exp $
+// Version:     $Id: configtool.h,v 1.26 2001/09/05 14:35:53 julians Exp $
 // Purpose:
 // Description: main header file for the ConfigTool application
 // Requires:
@@ -99,6 +99,9 @@ class ecPipedProcess;
 #define ecUSE_EXPERIMENTAL_CODE 1
 #endif
 
+class WXDLLEXPORT wxZipFSHandler;
+class WXDLLEXPORT wxFileSystem;
+
 // Define a new application type, each program should derive a class from wxApp
 class ecApp : public wxApp
 {
@@ -138,6 +141,21 @@ public:
     // Initialize window settings object
     bool InitializeWindowSettings(bool beforeWindowConstruction);
 
+    // Load resources from disk
+    bool LoadResources();
+
+    // Load a bitmap resource from resource.bin
+    bool LoadBitmapResource(wxBitmap& bitmap, const wxString& filename, int bitmapType, bool addToMemoryFS);
+
+    // Load a text resource from resource.bin
+    bool LoadTextResource(wxString& text, const wxString& filename, bool addToMemoryFS);
+
+    // Get a text resource from the memory filesystem
+    bool GetMemoryTextResource(const wxString& filename, wxString& text);
+
+    // Version-stamp the splash screen
+    bool VersionStampSplashScreen();
+
 //// Accessors
 
     // Get settings
@@ -182,6 +200,8 @@ public:
     wxString GetHelpFile() const { return m_helpFile; }
     void SetHelpFile(const wxString& file) { m_helpFile = file; }
 
+    wxFileSystem* GetFileSystem() const { return m_fileSystem; }
+
     // Lock out value changes while conflicts are being resolved, for example
     bool GetValuesLocked() { return (m_valuesLocked > 0); }
     void LockValues() { m_valuesLocked ++; }
@@ -210,6 +230,9 @@ public:
     ecConfigToolDoc*    m_currentDoc;
     wxString            m_helpFile;
     ecPipedProcess*     m_pipedProcess;
+    wxBitmap            m_splashScreenBitmap;
+    wxZipFSHandler*     m_zipHandler;
+    wxFileSystem*       m_fileSystem;
 
 DECLARE_EVENT_TABLE()
 };
--- a/host/tools/configtool/standalone/wxwin/configtooldoc.cpp
+++ b/host/tools/configtool/standalone/wxwin/configtooldoc.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/10/05
-// Version:     $Id: configtooldoc.cpp,v 1.36 2001/08/10 14:58:21 julians Exp $
+// Version:     $Id: configtooldoc.cpp,v 1.41 2001/09/03 17:18:18 julians Exp $
 // Purpose:
 // Description: Implementation file for the ecConfigToolDoc class
 // Requires:
@@ -294,22 +294,28 @@ bool ecConfigToolDoc::OnSaveDocument(con
             ecFileName buildFilename(m_strBuildTree);
             ecFileName installFilename(m_strInstallTree);
 
-            if (!buildFilename.CreateDirectory() || !installFilename.CreateDirectory())
+            if (!wxGetApp().GetSettings().m_editSaveFileOnly)
             {
-                wxString msg;
-                msg.Printf(_("Failed to save %s"), (const wxChar*) filename);
-
-                wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION);
-                rc = FALSE;
+                if (!buildFilename.CreateDirectory() || !installFilename.CreateDirectory())
+                {
+                    wxString msg;
+                    msg.Printf(_("Failed to save %s"), (const wxChar*) filename);
+                    
+                    wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION);
+                    rc = FALSE;
+                }
+                else if (GenerateHeaders() && CopyMLTFiles())
+                {
+                    // in each case errors already emitted
+                    // copy new MLT files to the build tree as necessary
+                    rc=generate_build_tree (GetCdlConfig(), ecUtils::UnicodeToStdStr(m_strBuildTree), ecUtils::UnicodeToStdStr(m_strInstallTree));
+                    rc = TRUE;
+                }
             }
-            else if (GenerateHeaders() && CopyMLTFiles())
+            else
             {
-                // in each case errors already emitted
-                // copy new MLT files to the build tree as necessary
-                rc=generate_build_tree (GetCdlConfig(), ecUtils::UnicodeToStdStr(m_strBuildTree), ecUtils::UnicodeToStdStr(m_strInstallTree));
                 rc = TRUE;
             }
-
         }
     }
     if(rc)
@@ -440,11 +446,12 @@ bool ecConfigToolDoc::OnOpenDocument(con
 
         UpdateFailingRuleCount();
 
-        UpdateBuildInfo();
+        SetFilename(filename);
+
+	// UpdateBuildInfo(); // Don't create directories on opening file
 
         rc = TRUE;
 
-        SetFilename(filename);
 
         ecConfigToolHint hint(NULL, ecFilenameChanged);
         UpdateAllViews (NULL, & hint);
@@ -722,7 +729,8 @@ bool ecConfigToolDoc::OpenRepository(con
                 }
 #ifdef __WXMSW__
                 // Ensure display gets updated
-                wxYield();
+                ::UpdateWindow((HWND) mainFrame->GetHWND());
+                //wxYield();
 #endif
                 strNewRepository=dlg.GetFolder();
             } else
@@ -1010,7 +1018,9 @@ void ecConfigToolDoc::RegenerateData()
     SwitchMemoryLayout (TRUE); // the hardware template may have changed
 #endif
 
-    UpdateBuildInfo();
+    if (GetDocumentSaved() && !wxGetApp().GetSettings().m_editSaveFileOnly)
+        UpdateBuildInfo();
+    
     // TODO
     // CConfigTool::GetControlView()->SelectItem(Item(0));
 }
@@ -1379,7 +1389,12 @@ bool ecConfigToolDoc::ShowExternalHtmlHe
     if (strURL.Left(7) == wxT("http://") || strURL.Left(7) == wxT("file://"))
         url = strURL;
     else
-        url = docDir + sep + strURL;
+    {
+	if (wxIsAbsolutePath(strURL))
+	    url = strURL;
+	else
+            url = docDir + sep + strURL;
+    }
 
     wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(wxT("html"));
     if ( !ft )
--- a/host/tools/configtool/standalone/wxwin/ecutils.cpp
+++ b/host/tools/configtool/standalone/wxwin/ecutils.cpp
@@ -524,11 +524,9 @@ bool ecUtils::CopyFile(LPCTSTR pszSource
 
   if(rc){
     // Files are identical
-    TRACE(wxT("Copy not necessary: '%s' to '%s'\n"),pszSource,pszDest);
   } else {
     rc=TRUE==::CopyFile(pszSource,pszDest,FALSE);
     if(rc){
-      TRACE(wxT("Copied '%s' to '%s'\n"),pszSource,pszDest);
     } else {
       MessageBoxF(wxT("Failed to copy '%s' to '%s' - %s"),pszSource,pszDest,GetLastErrorMessageString());
     }
@@ -1010,205 +1008,6 @@ bool wxWindowSettings::ApplyFontsToWindo
     return TRUE;
 }
 
-#if TODO
-
-#ifdef _WIN32
-class wxProcessInfo: public wxObject
-{
-public:
-    wxProcessInfo() {}
-
-    wxProcessInfo *pParent;
-#ifdef _WIN32
-    __int64 tCreation;
-#endif
-    Time tCpu;
-    int PID;
-    int PPID;
-    bool IsChildOf(int pid) const;
-};
-
-void wxSetProcessInfoParents(CSubprocess::PInfoArray &arPinfo)
-{
-  int i;
-  for(i=0;i<(signed)arPinfo.size();i++){
-    PInfo &p=arPinfo[i];
-    p.pParent=0;
-    for(int j=0;j<(signed)arPinfo.size();j++){
-      if(arPinfo[j].PID==p.PPID 
-#ifdef _WIN32
-        && arPinfo[j].tCreation<p.tCreation
-#endif
-        )
-      {
-        arPinfo[i].pParent=&arPinfo[j];
-        break;
-      }
-    }
-  }
-
-  // Check for circularity
-  bool bCircularity=false;
-  for(i=0;i<(signed)arPinfo.size();i++){
-    PInfo *p=&arPinfo[i];
-    for(int j=0;j<(signed)arPinfo.size() && p;j++){
-      p=p->pParent;
-    }
-    // If all is well, p should be NULL here.  Otherwise we have a loop.
-    if(p){
-      // Make sure it can't foul things up:
-      arPinfo[i].pParent=0;
-      bCircularity=true;
-    }
-  }
-  
-  if(bCircularity){
-    ERROR(_T("!!! Circularly linked process list at index %d\n"),i);
-    for(int k=0;k<(signed)arPinfo.size();k++){
-      const PInfo &p=arPinfo[k];
-      ERROR(_T("%d: %s ppid=%4d\n"),k,(LPCTSTR)Name(p.PID),p.PPID);
-    }
-  }
-}
-
-bool CSubprocess::PInfo::IsChildOf(int pid) const
-{
-  for(PInfo *p=pParent;p && p!=this;p=p->pParent) { // guard against circular linkage
-    if(p->PID==pid){
-      return true;
-    }
-  }
-  return false;
-}
-
-
-bool wxGetChildProcesses(wxList& children)
-{
-    int osVersion = wxGetOsVersion() ;
-    HINSTANCE hInstLib1 = wxWINDOWS_NT==osVersion ? LoadLibrary(_T("PSAPI.DLL")):LoadLibrary(_T("Kernel32.DLL")) ;
-    HINSTANCE hInstLib2 = wxWINDOWS_NT==osVersion ? LoadLibrary(_T("NTDLL.DLL")):NULL;
-    
-    bool rc=false;
-    children.Clear();
-    // If Windows NT:
-    switch (osVersion)
-    {
-    case wxWINDOWS_NT:
-        if(hInstLib1)
-        {
-            
-            // Get procedure addresses.
-            static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( hInstLib1, "EnumProcesses" ) ;
-            if (lpfEnumProcesses)
-            {
-                
-                if (hInstLib2)
-                {
-                    
-                    static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) =
-                        (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( hInstLib2,"NtQueryInformationProcess" ) ;
-                    
-                    if(lpfNtQueryInformationProcess)
-                    {
-                        DWORD dwMaxPids=256;
-                        DWORD dwPidSize;
-                        DWORD *arPids = NULL ;
-                        do {
-                            delete [] arPids;
-                            arPids=new DWORD[dwMaxPids];
-                        } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ;
-                        
-                        if(dwPidSize/sizeof(DWORD)<dwMaxPids)
-                        {
-                            rc=true;
-                            for ( DWORD dwIndex = 0 ; (signed)dwIndex < dwPidSize/sizeof(DWORD); dwIndex++ ) {
-                                // Regardless of OpenProcess success or failure, we
-                                // still call the enum func with the ProcID.
-                                DWORD pid=arPids[dwIndex];
-                                HANDLE hProcess=::OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid ); 
-                                if (hProcess ) {
-                                    struct {
-                                        DWORD ExitStatus; // receives process termination status
-                                        DWORD PebBaseAddress; // receives process environment block address
-                                        DWORD AffinityMask; // receives process affinity mask
-                                        DWORD BasePriority; // receives process priority class
-                                        ULONG UniqueProcessId; // receives process identifier
-                                        ULONG InheritedFromUniqueProcessId; // receives parent process identifier
-                                    } pbi;
-                                    memset( &pbi, 0, sizeof(pbi)); 
-                                    DWORD retLen; 
-                                    __int64 ftCreation,ftExit,ftKernel,ftUser;
-                                    if(lpfNtQueryInformationProcess(hProcess, 0 /*ProcessBasicInformation*/, &pbi, sizeof(pbi), &retLen)>=0 &&
-                                        TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){
-                                        // The second test is important.  It excludes orphaned processes who appear to have been adopted by virtue of a new
-                                        // process having been created with the same ID as their original parent.
-                                        wxProcessInfo* p = new wxProcessInfo;
-                                        p->PID=pid;
-                                        p->PPID=pbi.InheritedFromUniqueProcessId;
-                                        p->tCreation=ftCreation;
-                                        p->tCpu=Time((ftKernel+ftUser)/10000);
-                                        children.Append(p);
-                                    }
-                                    
-                                    CloseHandle(hProcess); 
-                                    
-                                }
-                            }
-                        }
-                        delete [] arPids;
-                    }          
-                }
-            }      
-        }
-        break;
-    case wxWIN95:
-        
-        if( hInstLib1) {
-            
-            static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)=
-                (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( hInstLib1,"CreateToolhelp32Snapshot" ) ;
-            static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)=
-                (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32First" ) ;
-            static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)=
-                (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32Next" ) ;
-            if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) {
-                
-                // Get a handle to a Toolhelp snapshot of the systems
-                // processes.
-                HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;
-                if(INVALID_HANDLE_VALUE != hSnapShot) {
-                    // Get the first process' information.
-                    PROCESSENTRY32 procentry;
-                    procentry.dwSize = sizeof(PROCESSENTRY32) ;
-                    if(lpfProcess32First( hSnapShot, &procentry )){
-                        rc=true;
-                        do {
-                            PInfo p;
-                            p.PID=procentry.th32ProcessID;
-                            p.PPID=procentry.th32ParentProcessID;
-                            arPinfo.push_back(p);
-                        } while(lpfProcess32Next( hSnapShot, &procentry ));
-                    }
-                    CloseHandle(hSnapShot);
-                }
-            }
-        }
-        break;
-    default:
-        break;
-    }    
-    
-    SetParents(children);
-    
-    if(!rc){
-        wxMessageBox(_T("Couldn't get process information!\n"));
-    }
-    return rc;
-}
-#endif
-
-#endif
-
 #ifdef __WIN32__
 // This will be obsolete when we switch to using the version included
 // in wxWindows (from wxWin 2.3.1 onwards)
@@ -1438,3 +1237,363 @@ int ecKill(long pid, wxSignal sig)
 #endif
 }
 
+#ifdef _WIN32
+  #include <tlhelp32.h>
+
+  WXHINSTANCE wxProcessKiller::hInstLib1 = VER_PLATFORM_WIN32_NT==wxProcessKiller::GetPlatform()? (WXHINSTANCE) LoadLibrary(_T("PSAPI.DLL")) : (WXHINSTANCE) LoadLibrary(_T("Kernel32.DLL")) ;
+  WXHINSTANCE wxProcessKiller::hInstLib2 = VER_PLATFORM_WIN32_NT==wxProcessKiller::GetPlatform()? (WXHINSTANCE) LoadLibrary(_T("NTDLL.DLL")): (WXHINSTANCE) NULL;
+
+#endif
+
+const unsigned int wxProcessKiller::PROCESS_KILL_EXIT_CODE=0xCCFFCCFF;
+
+wxProcessKiller::wxProcessKiller(int pid):
+  m_bVerbose(false),
+  m_nExitCode(-1),
+  m_idProcess(pid)
+{
+#ifdef _WIN32
+      m_hProcess = (WXHANDLE) ::OpenProcess(SYNCHRONIZE |
+          PROCESS_TERMINATE |
+          PROCESS_QUERY_INFORMATION,
+          FALSE, // not inheritable
+          (DWORD) m_idProcess);
+#endif
+}
+
+wxProcessKiller::~wxProcessKiller()
+{
+#ifdef _WIN32
+    if (m_hProcess)
+    {
+        ::CloseHandle((HANDLE) m_hProcess);
+    }
+#endif
+}
+
+bool wxProcessKiller::Kill(bool bRecurse)
+{
+    wxPInfoArray arPinfo;
+    bool rc=false;
+    if(m_idProcess && -1!=m_idProcess){
+        // Start of with the easy one:
+        if(bRecurse) {
+            // Need to gather this information before we orphan our grandchildren:
+            PSExtract(arPinfo);
+        }
+        
+#ifdef _WIN32
+        
+        if(m_hProcess){
+            rc=(TRUE==::TerminateProcess((HANDLE) m_hProcess,PROCESS_KILL_EXIT_CODE));
+            // dtor's (or subsequent Run's) responsibility to close the handle
+        }
+        
+#else
+        rc=(0==kill(m_idProcess,SIGTERM));
+        int status;
+        waitpid(m_idProcess,&status,WNOHANG);
+#endif
+        
+        if(bRecurse) {
+            // kill process *and* its children
+            // FIXME: needs to be top-down
+            for(int i=0;i<(signed)arPinfo.size();i++){
+                if(arPinfo[i].IsChildOf(m_idProcess)){
+                    
+#ifdef _WIN32
+                    // begin hack
+                    // WHY NECESSARY??
+                    const wxString strName(Name(arPinfo[i].PID));
+                    if(_tcsstr(strName,_T("eCosTest")) || _tcsstr(strName,_T("cmd.EXE")) || _tcsstr(strName,_T("CMD.EXE")) || arPinfo[i].PID==(signed)GetCurrentProcessId()){
+                        continue;
+                    }
+                    // end hack
+                    HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,false,arPinfo[i].PID);
+                    if(hProcess){
+                        rc&=(TRUE==::TerminateProcess(hProcess,PROCESS_KILL_EXIT_CODE));
+                        CloseHandle(hProcess);
+                    } else {
+                        rc=false;
+                    }
+#else
+                    rc&=(0==kill(arPinfo[i].PID,SIGTERM));
+                    int status;
+                    waitpid(arPinfo[i].PID,&status,WNOHANG);
+#endif
+                }
+            }
+        }
+    }
+    return rc;
+}
+
+#ifdef _WIN32
+bool wxProcessKiller::PSExtract(wxProcessKiller::wxPInfoArray &arPinfo)
+{
+    bool rc=false;
+    arPinfo.clear();
+    // If Windows NT:
+    switch(GetPlatform()) {
+    case VER_PLATFORM_WIN32_NT:
+        if(hInstLib1) {
+            
+            // Get procedure addresses.
+            static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( (HINSTANCE) hInstLib1, "EnumProcesses" ) ;
+            if( lpfEnumProcesses) {
+                
+                if(hInstLib2) {
+                    
+                    static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) =
+                        (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( (HINSTANCE) hInstLib2,"NtQueryInformationProcess" ) ;
+                    
+                    if(lpfNtQueryInformationProcess){
+                        DWORD dwMaxPids=256;
+                        DWORD dwPidSize;
+                        DWORD *arPids = NULL ;
+                        do {
+                            delete [] arPids;
+                            arPids=new DWORD[dwMaxPids];
+                        } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ;
+                        
+                        if(dwPidSize/sizeof(DWORD)<dwMaxPids){
+                            rc=true;
+                            for( DWORD dwIndex = 0 ; (signed)dwIndex < dwPidSize/sizeof(DWORD); dwIndex++ ) {
+                                // Regardless of OpenProcess success or failure, we
+                                // still call the enum func with the ProcID.
+                                DWORD pid=arPids[dwIndex];
+                                HANDLE hProcess=::OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid ); 
+                                if (hProcess ) {
+                                    struct {
+                                        DWORD ExitStatus; // receives process termination status
+                                        DWORD PebBaseAddress; // receives process environment block address
+                                        DWORD AffinityMask; // receives process affinity mask
+                                        DWORD BasePriority; // receives process priority class
+                                        ULONG UniqueProcessId; // receives process identifier
+                                        ULONG InheritedFromUniqueProcessId; // receives parent process identifier
+                                    } pbi;
+                                    memset( &pbi, 0, sizeof(pbi)); 
+                                    DWORD retLen; 
+                                    __int64 ftCreation,ftExit,ftKernel,ftUser;
+                                    if(lpfNtQueryInformationProcess(hProcess, 0 /*ProcessBasicInformation*/, &pbi, sizeof(pbi), &retLen)>=0 &&
+                                        TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){
+                                        // The second test is important.  It excludes orphaned processes who appear to have been adopted by virtue of a new
+                                        // process having been created with the same ID as their original parent.
+                                        wxPInfo p;
+                                        p.PID=pid;
+                                        p.PPID=pbi.InheritedFromUniqueProcessId;
+                                        p.tCreation=ftCreation;
+                                        p.tCpu=Time((ftKernel+ftUser)/10000);
+                                        arPinfo.push_back(p);
+                                    }
+                                    
+                                    CloseHandle(hProcess); 
+                                    
+                                }
+                            }
+                        }
+                        delete [] arPids;
+                    }          
+                }
+            }      
+        }
+        break;
+    case VER_PLATFORM_WIN32_WINDOWS:
+        
+        if( hInstLib1) {
+            
+            static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)=
+                (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( (HINSTANCE) hInstLib1,"CreateToolhelp32Snapshot" ) ;
+            static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)=
+                (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( (HINSTANCE) hInstLib1, "Process32First" ) ;
+            static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)=
+                (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( (HINSTANCE) hInstLib1, "Process32Next" ) ;
+            if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) {
+                
+                // Get a handle to a Toolhelp snapshot of the systems
+                // processes.
+                HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;
+                if(INVALID_HANDLE_VALUE != hSnapShot) {
+                    // Get the first process' information.
+                    PROCESSENTRY32 procentry;
+                    procentry.dwSize = sizeof(PROCESSENTRY32) ;
+                    if(lpfProcess32First( hSnapShot, &procentry )){
+                        rc=true;
+                        do {
+                            wxPInfo p;
+                            p.PID=procentry.th32ProcessID;
+                            p.PPID=procentry.th32ParentProcessID;
+                            arPinfo.push_back(p);
+                        } while(lpfProcess32Next( hSnapShot, &procentry ));
+                    }
+                    CloseHandle(hSnapShot);
+                }
+            }
+        }
+        break;
+    default:
+        break;
+    }    
+    
+    SetParents(arPinfo);
+    
+    if(!rc){
+        wxLogError(_T("Couldn't get process information!\n"));
+    }
+    return rc;
+}
+
+#else // UNIX
+
+bool wxProcessKiller::PSExtract(wxProcessKiller::wxPInfoArray &arPinfo)
+{
+    arPinfo.clear();
+    int i;
+    FILE *f=popen("ps -l",_T("r") MODE_TEXT);
+    if(f){
+        char buf[100];
+        while(fgets(buf,sizeof(buf)-1,f)){
+            TCHAR discard[100];
+            wxPInfo p;
+            // Output is in the form
+            //  F S   UID   PID  PPID  C PRI  NI ADDR    SZ WCHAN  TTY          TIME CMD
+            //100 S   490   877   876  0  70   0    -   368 wait4  pts/0    00:00:00 bash
+            int F,UID,C,PRI,NI,SZ,HH,MM,SS; 
+            bool rc=(15==_stscanf(buf,_T("%d %s %d %d %d %d %d %d %s %d %s %s %d:%d:%d"),&F,discard,&UID,&p.PID,&p.PPID,&C,&PRI,&NI,discard,&SZ,discard,discard,&HH,&MM,&SS));
+            if(rc){
+                p.tCpu=1000*(SS+60*(60*HH+MM));
+                arPinfo.push_back(p);
+            }
+        }
+        pclose(f);
+        for(i=0;i<(signed)arPinfo.size();i++){
+            int pid=arPinfo[i].PPID;
+            arPinfo[i].pParent=0;
+            for(int j=0;j<(signed)arPinfo.size();j++){
+                if(i!=j && arPinfo[j].PID==pid){
+                    arPinfo[i].pParent=&arPinfo[j];
+                    break;
+                }
+            }
+        }
+    } else {
+        wxLogError(_T("Failed to run ps -l\n"));
+    }
+    return true; //FIXME
+}
+
+#endif
+
+void wxProcessKiller::SetParents(wxProcessKiller::wxPInfoArray &arPinfo)
+{
+    int i;
+    for(i=0;i<(signed)arPinfo.size();i++){
+        wxPInfo &p=arPinfo[i];
+        p.pParent=0;
+        for(int j=0;j<(signed)arPinfo.size();j++){
+            if(arPinfo[j].PID==p.PPID 
+#ifdef _WIN32
+                && arPinfo[j].tCreation<p.tCreation
+#endif
+                )
+            {
+                arPinfo[i].pParent=&arPinfo[j];
+                break;
+            }
+        }
+    }
+    
+    // Check for circularity
+    bool bCircularity=false;
+    for(i=0;i<(signed)arPinfo.size();i++){
+        wxPInfo *p=&arPinfo[i];
+        for(int j=0;j<(signed)arPinfo.size() && p;j++){
+            p=p->pParent;
+        }
+        // If all is well, p should be NULL here.  Otherwise we have a loop.
+        if(p){
+            // Make sure it can't foul things up:
+            arPinfo[i].pParent=0;
+            bCircularity=true;
+        }
+    }
+    
+    if(bCircularity){
+        wxLogError(_T("!!! Circularly linked process list at index %d\n"),i);
+        for(int k=0;k<(signed)arPinfo.size();k++){
+            const wxPInfo &p=arPinfo[k];
+            wxLogError(_T("%d: %s ppid=%4d\n"),k,(LPCTSTR)Name(p.PID),p.PPID);
+        }
+    }
+}
+
+bool wxProcessKiller::wxPInfo::IsChildOf(int pid) const
+{
+    for(wxPInfo *p=pParent;p && p!=this;p=p->pParent) { // guard against circular linkage
+        if(p->PID==pid){
+            return true;
+        }
+    }
+    return false;
+}
+
+const wxString wxProcessKiller::Name(int pid)
+{
+    wxString str;
+    str.Printf(_T("id=%d"),pid);
+#ifdef _DEBUG
+#ifdef _WIN32
+    if(VER_PLATFORM_WIN32_NT==GetPlatform() && hInstLib1){
+        static BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ) =
+            (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( (HINSTANCE) hInstLib1,"EnumProcessModules" ) ;
+        static DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE, LPTSTR, DWORD )=
+            (DWORD (WINAPI *)(HANDLE, HMODULE,LPTSTR, DWORD )) GetProcAddress( (HINSTANCE) hInstLib1,"GetModuleFileNameExA" ) ;
+        if( lpfEnumProcessModules &&  lpfGetModuleFileNameEx ) {
+            HANDLE hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,pid);
+            if(hProcess) {
+                HMODULE hMod;
+                DWORD dwSize;
+                if(lpfEnumProcessModules( hProcess, &hMod, sizeof(HMODULE), &dwSize ) ){
+                    // Get Full pathname:
+                    TCHAR buf[1+MAX_PATH];
+                    lpfGetModuleFileNameEx( hProcess, hMod, buf, MAX_PATH);
+                    str+=_TCHAR(' ');
+                    str+=buf;
+                }
+                CloseHandle(hProcess);
+            }
+        }
+    }
+#endif
+#endif
+    return str;
+}
+
+#ifdef _WIN32
+long wxProcessKiller::GetPlatform()
+{
+    OSVERSIONINFO  osver;
+    osver.dwOSVersionInfoSize = sizeof( osver ) ;
+    return GetVersionEx( &osver ) ? (long) osver.dwPlatformId : (long)-1;
+}
+#endif
+
+const wxString wxProcessKiller::ErrorString() const
+{
+#ifdef _WIN32
+    TCHAR *pszMsg;
+    FormatMessage(  
+        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+        NULL,
+        m_nErr,
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+        (LPTSTR)&pszMsg,
+        0,
+        NULL 
+        );
+    return pszMsg;
+#else 
+    return strerror(errno);
+#endif
+}
+
--- a/host/tools/configtool/standalone/wxwin/ecutils.h
+++ b/host/tools/configtool/standalone/wxwin/ecutils.h
@@ -213,6 +213,77 @@ wxOutputStream& operator <<(wxOutputStre
 wxOutputStream& operator <<(wxOutputStream&, long l);
 
 /*
+ * Class for recursively killing a process and its children.
+ * This has been taken from CSubprocess, but we can't use CSubprocess
+ * directly for killing a process because it assumes it's been used to create
+ * the process.
+ */
+
+class wxProcessKiller
+{
+
+public:
+    const wxString ErrorString() const;
+
+    wxProcessKiller(int pid);
+    ~wxProcessKiller();
+    
+    void SetVerbose   (bool b)         { m_bVerbose=b; }
+      
+    int Pid() const { return m_idProcess; } // returns process id (even when process is terminated)
+    
+    // Get the process exit code.  This can be:
+    //   exit code of process (if terminated)
+    //   0xffffffff (if process not yet run)
+    //   GetLastError result (if process could not be run)
+    int GetExitCode() { return m_nExitCode; }
+    
+    // Kill the process:
+    bool Kill(bool bRecurse = true);
+    
+    // Is the process running?
+    bool ProcessAlive();
+    
+protected:
+    static const wxString Name (int pid); // for debugging - only works under NT
+    
+    struct wxPInfo;
+    struct wxPInfo {
+        wxPInfo *pParent;
+#ifdef _WIN32
+        __int64 tCreation;
+#endif
+        long tCpu;
+        int PID;
+        int PPID;
+        bool IsChildOf(int pid) const;
+    };
+    
+    typedef std::vector<wxPInfo> wxPInfoArray;
+    
+    static bool PSExtract(wxPInfoArray &arPinfo);
+    static void SetParents(wxPInfoArray &arPinfo);
+    
+#ifdef _WIN32
+    static long GetPlatform();
+    WXHANDLE m_hrPipe;
+    WXHANDLE m_hwPipe;
+    WXHANDLE m_hProcess;     // This handle is "owned" by the ThreadFunc
+    static WXHINSTANCE hInstLib1, hInstLib2;
+    int m_nErr;
+#else
+    int m_tty;
+    wxString m_strCmd;
+#endif
+    
+    bool m_bVerbose;
+    int m_nExitCode;
+    int m_idProcess;
+    
+    static const unsigned int PROCESS_KILL_EXIT_CODE;
+};
+
+/*
  * ecDialog
  * Supports features we want to have for all dialogs in the application.
  * So far, this just allows dialogs to be resizeable under MSW by
--- a/host/tools/configtool/standalone/wxwin/mainwin.cpp
+++ b/host/tools/configtool/standalone/wxwin/mainwin.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/24
-// Version:     $Id: mainwin.cpp,v 1.48 2001/08/10 14:58:21 julians Exp $
+// Version:     $Id: mainwin.cpp,v 1.53 2001/09/03 17:18:18 julians Exp $
 // Purpose:
 // Description: Implementation file for the ConfigTool main window
 // Requires:
@@ -478,7 +478,7 @@ void ecMainFrame::CreateWindows()
         wxDefaultSize, wxNO_BORDER);
     m_splitter->SplitVertically(m_tree, m_valueWindow);
     //m_splitter->AdjustScrollbars();
-    m_splitter->SetSashPosition(200);
+    m_splitter->SetSashPosition(wxGetApp().GetSettings().m_configPaneWidth);
     m_scrolledWindow->SetTargetWindow(m_tree);  
     m_scrolledWindow->EnableScrolling(FALSE, FALSE);
     m_tree->SetHelpText(_("The configuration window is the principal window used to configure eCos.\nIt takes the form of a tree-based representation of the configuration items within the currently loaded eCos packages."));
@@ -928,6 +928,7 @@ void ecMainFrame::OnCloseWindow(wxCloseE
     wxGetApp().GetSettings().m_shortDescrSashSize = m_shortDescrSashWindow->GetSize();
     wxGetApp().GetSettings().m_memorySashSize = m_memorySashWindow->GetSize();
     wxGetApp().GetSettings().m_outputSashSize = m_outputSashWindow->GetSize();
+    wxGetApp().GetSettings().m_configPaneWidth = m_splitter->GetSashPosition();
     
     event.Skip();
 }
@@ -1047,6 +1048,8 @@ void ecMainFrame::OnHelpConfigtool(wxCom
 {
     //wxString strURL(wxT("redirect/the-ecos-configuration-tool.html"));
     wxString strURL(wxGetApp().GetFullAppPath(wxT("manual/user-guides.2.html")));
+    if (!wxFileExists(strURL))
+	strURL = wxT("guides/user-guides.2.html");
 
     if (wxGetApp().GetConfigToolDoc())
     {
@@ -1118,7 +1121,8 @@ void ecMainFrame::OnTemplates(wxCommandE
 	{
 #ifdef __WXMSW__
         // Ensure display gets updated
-        wxYield();
+        ::UpdateWindow((HWND) GetHWND());
+        //wxYield();
 #endif
         ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
 
@@ -1520,11 +1524,60 @@ void ecMainFrame::OnBuildLibrary(wxComma
     // TODO: possibly add wxT("clean build") to ensure library is
     // cleanly built. No, can't do that because it would clean
     // out any user code too :-(
+
+    bool regenerateBuildTree = FALSE;
+
+    if (wxGetApp().GetSettings().m_editSaveFileOnly)
+    {
+        int ans = wxMessageBox(wxT("Running in --edit-only mode so there may not be an up-to-date build tree.\nBuild the tree now?"), wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO|wxCANCEL);
+
+        if (ans == wxYES)
+        {
+            regenerateBuildTree = TRUE;
+        }
+        else if (ans == wxCANCEL)
+            return;
+    }
+
+    if (regenerateBuildTree)
+    {
+        ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc();
+        if (!pDoc)
+            return;
+
+        if (!pDoc->GenerateBuildTree())
+            return ;
+    }
+
     wxGetApp().Build();
 }
 
 void ecMainFrame::OnBuildTests(wxCommandEvent& event)
 {
+    bool regenerateBuildTree = FALSE;
+
+    if (wxGetApp().GetSettings().m_editSaveFileOnly)
+    {
+        int ans = wxMessageBox(wxT("Running in --edit-only mode so there may not be an up-to-date build tree.\nBuild the tree now?"), wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO|wxCANCEL);
+
+        if (ans == wxYES)
+        {
+            regenerateBuildTree = TRUE;
+        }
+        else if (ans == wxCANCEL)
+            return;
+    }
+
+    if (regenerateBuildTree)
+    {
+        ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc();
+        if (!pDoc)
+            return;
+
+        if (!pDoc->GenerateBuildTree())
+            return ;
+    }
+
     wxGetApp().Build(wxT("tests"));
 }
 
@@ -1534,7 +1587,9 @@ void ecMainFrame::OnStopBuild(wxCommandE
     {
         long pid = wxGetApp().m_pipedProcess->GetPid();
         wxGetApp().m_pipedProcess->Detach();
-        ecKill(pid, wxSIGKILL);
+
+        wxProcessKiller pKiller(pid);
+        pKiller.Kill(TRUE);
     }
 }
 
--- a/host/tools/configtool/standalone/wxwin/settingsdlg.cpp
+++ b/host/tools/configtool/standalone/wxwin/settingsdlg.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/11
-// Version:     $Id: settingsdlg.cpp,v 1.13 2001/07/05 10:42:16 julians Exp $
+// Version:     $Id: settingsdlg.cpp,v 1.14 2001/09/03 16:51:51 julians Exp $
 // Purpose:
 // Description: Implementation file for ecSettingsDialog
 // Requires:
@@ -568,7 +568,7 @@ void ecViewerOptionsDialog::CreateContro
     item0->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 
     // Disable this option because we don't yet have a built-in browser
-#if !ecUSE_EXPERIMENTAL_CODE
+#if 0 // !ecUSE_EXPERIMENTAL_CODE
     FindWindow(ecID_VIEWER_DIALOG_DOC_BUILTIN)->Enable(FALSE);
 #endif
 
--- a/host/tools/configtool/standalone/wxwin/setup/configtool.iss
+++ b/host/tools/configtool/standalone/wxwin/setup/configtool.iss
@@ -4,13 +4,13 @@
 
 [Setup]
     MinVersion=4.0,4.0
-    AppName=eCos Configuration Tool 2.04
+    AppName=eCos Configuration Tool 2.07
     AppId=eCos Configuration Tool
     CreateUninstallRegKey=1
     UsePreviousAppDir=1
     UsePreviousGroup=1
-    AppVersion=2.04
-    AppVerName=eCos Configuration Tool 2.04
+    AppVersion=2.07
+    AppVerName=eCos Configuration Tool 2.07
     AppCopyright=Copyright © Red Hat Inc., 2001
     BackColor=$FF0000
     BackColor2=$000000
@@ -42,12 +42,9 @@
   Name: {app}\manual\pix
 
 [Files]
-  Source: v:\deliver\configtool\about.htm; DestDir: {app}\
-  Source: v:\deliver\configtool\aboutlo.htm; DestDir: {app}\
   Source: v:\deliver\configtool\CHANGES.txt; DestDir: {app}\
+  Source: v:\deliver\configtool\configtool.bin; DestDir: {app}\
   Source: v:\deliver\configtool\configtool.exe; DestDir: {app}\
-  Source: v:\deliver\configtool\ecoslogo.png; DestDir: {app}\
-  Source: v:\deliver\configtool\ecoslogosmall.png; DestDir: {app}\
   Source: v:\deliver\configtool\license.txt; DestDir: {app}\
   Source: v:\deliver\configtool\manual\botclear.gif; DestDir: {app}\manual
   Source: v:\deliver\configtool\manual\cygnus.css; DestDir: {app}\manual
@@ -182,7 +179,6 @@
   Source: v:\deliver\configtool\manual\user-guides.f.html; DestDir: {app}\manual
   Source: v:\deliver\configtool\manual\user-guides.html; DestDir: {app}\manual
   Source: v:\deliver\configtool\README.txt; DestDir: {app}\
-  Source: v:\deliver\configtool\rhlogo.png; DestDir: {app}\
   Source: v:\deliver\configtool\TODO.txt; DestDir: {app}\
 
     Source: c:\winnt\system32\tcl82.dll; DestDir: {sys}\; DestName: tcl82.dll; CopyMode: onlyifdoesntexist; Flags: uninsneveruninstall
@@ -217,7 +213,7 @@
 ; DO NOT DELETE THEM or you may be unable to reload the script
 
 ;[ScriptSetup]
-;VerNum=2.04
+;VerNum=2.07
 ;InnoVer=1.3
 ;AddVerTo=AppVerName
 ;SetupFilename=setup.exe
--- a/host/tools/configtool/standalone/wxwin/setup/makesetup.sh
+++ b/host/tools/configtool/standalone/wxwin/setup/makesetup.sh
@@ -35,6 +35,7 @@ findversion()
 
 doinno()
 {
+    rm -f -r $DEST/configtool
     mkdir -p $DEST/configtool
     mkdir -p $DEST/configtool/manual
     mkdir -p $DEST/configtool/manual/pix
@@ -45,6 +46,9 @@ doinno()
     cp $SRC/CHANGES.txt .
     cp $SRC/TODO.txt .
     cp $SRC/*.png .
+    cp $SRC/bitmaps/splash16.png .
+    zip configtool.bin about.htm *.png
+    rm -f about.htm *.png
     cp "$ECOSDIR/ecc/release/eCos Install/Setup Files/Uncompressed Files/Disk1/license.txt" .
     cp $BINARYSRC/configtool.exe .
     cp $CONFIGTOOLDIR/manual/*.html $CONFIGTOOLDIR/manual/*.css $CONFIGTOOLDIR/manual/*.gif $DEST/configtool/manual
--- a/host/tools/configtool/standalone/wxwin/setup/maketarball.sh
+++ b/host/tools/configtool/standalone/wxwin/setup/maketarball.sh
@@ -29,6 +29,9 @@ dotar()
 
     cp $SRC/*.htm .
     cp $SRC/*.png .
+    cp $SRC/bitmaps/splash16.png .
+    zip configtool.bin *.htm *.png
+    rm -f *.htm *.png
     cp $SRC/setup/ecosplatforms.tar.gz .
     cp $SRC/README.txt .
     cp $SRC/CHANGES.txt .
--- a/host/tools/configtool/standalone/wxwin/symbols.h
+++ b/host/tools/configtool/standalone/wxwin/symbols.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2001/05/14
-// Version:     $Id: symbols.h,v 1.8 2001/08/10 14:58:21 julians Exp $
+// Version:     $Id: symbols.h,v 1.10 2001/09/05 14:35:53 julians Exp $
 // Purpose:
 // Description: Some important symbols, such as the version
 // Requires:
@@ -43,5 +43,5 @@
 //
 //===========================================================================
 
-#define ecCONFIGURATION_TOOL_VERSION        2.05
+#define ecCONFIGURATION_TOOL_VERSION        2.07
 
--- a/packages/ChangeLog
+++ b/packages/ChangeLog
@@ -105,6 +105,10 @@ 2001-04-03  Jonathan Larmour  <jlarmour@
 	* ecos.db:
 	Include flash driver in sa1100mm target.
 
+2001-04-03  Jesper Skov  <jskov@redhat.com>
+
+	* ecos.db: Added PCNet ethernet driver package.
+
 2001-03-29  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* ecos.db: Add Atlas flash and ethernet drivers to target description.
--- a/packages/NEWS
+++ b/packages/NEWS
@@ -1,3 +1,4 @@
+* AMD PCNet ethernet driver added.
 * Generic SMP support added.
 * RedBoot support added to AM33-STB port.
 * Add Atmel AT91/EB40 port, including flash and serial drivers.
--- a/packages/compat/posix/current/ChangeLog
+++ b/packages/compat/posix/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-09-06  Jesper Skov  <jskov@redhat.com>
+
+	* cdl/posix.cdl: Moved signal implements statements to the
+	CYGPKG_POSIX_SIGNALS component.
+
 2001-08-06  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/posix.cdl: Reorganize dependencies so that signals, timers
--- a/packages/compat/posix/current/cdl/posix.cdl
+++ b/packages/compat/posix/current/cdl/posix.cdl
@@ -53,18 +53,9 @@ cdl_package CYGPKG_POSIX {
     requires       CYGIMP_KERNEL_SCHED_SORTED_QUEUES
 
     implements     CYGINT_ISO_SCHED_IMPL
-    implements     CYGINT_ISO_SIGNAL_NUMBERS
-    implements     CYGINT_ISO_SIGNAL_IMPL
     implements     CYGINT_ISO_POSIX_LIMITS
-    implements     CYGINT_ISO_PMUTEXTYPES
-    requires       { CYGBLD_ISO_SIGNAL_NUMBERS_HEADER == \
-                         "<cyg/posix/signal.h>" }
-    requires       { CYGBLD_ISO_SIGNAL_IMPL_HEADER == \
-                         "<cyg/posix/signal.h>" }
     requires       { CYGBLD_ISO_POSIX_LIMITS_HEADER == \
                          "<cyg/posix/limits.h>" }
-    requires       { CYGBLD_ISO_PMUTEXTYPES_HEADER == \
-                         "<cyg/posix/muttypes.h>" }
     
     compile        mqueue.cxx mutex.cxx sem.cxx misc.cxx
     compile       -library=libextras.a startup.cxx
@@ -205,6 +196,12 @@ cdl_package CYGPKG_POSIX {
         implements       CYGINT_ISO_SIGSETJMP
         requires         { CYGBLD_ISO_SIGSETJMP_HEADER == \
                              "<cyg/posix/sigsetjmp.h>" }
+        implements       CYGINT_ISO_SIGNAL_NUMBERS
+        implements       CYGINT_ISO_SIGNAL_IMPL
+        requires         { CYGBLD_ISO_SIGNAL_NUMBERS_HEADER == \
+                             "<cyg/posix/signal.h>" }
+        requires         { CYGBLD_ISO_SIGNAL_IMPL_HEADER == \
+                             "<cyg/posix/signal.h>" }
 	description      "This component provides configuration controls for
 	                  the POSIX signals."
         compile          signal.cxx except.cxx 
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/amd/pcnet/current/ChangeLog
@@ -0,0 +1,123 @@
+2001-07-26  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c (amd_pcnet_init): Wait for init table loadup
+	completion. Removed ESA hack.
+
+2001-07-25  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: Be more careful with the use of STOP since it
+	clears interrupt request flags. Moved some code from _start to
+	_init. Don't double check RX int flag in RxEvent function.
+	(amd_pcnet_init): Move ID output below initialization.
+	Get rid of the last use of STOP, replace with SUSPEND. Minor
+	cleanups.
+	(amd_pcnet_init): Fix silly compile error.
+	(amd_pcnet_init): Check that the controller actually
+	starts. Appears that it needs to be kicked a couple of times under
+	certain conditions.
+
+	* src/amd_pcnet.h: Added TFC bits.
+
+2001-07-24  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: Mask off RDRA/TDRA pointers. Additional debug
+	info. Hack for broken ESA init. Don't clear TX interrupt flag in
+	send function (leave it to the event handler).
+	(pcnet_stop): Don't reset the controller, just stop it.
+	(pcnet_TxEvent): Only ack interrupt once.
+
+	* src/amd_pcnet.h: Added more registers.
+
+2001-07-18  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: Make controller recover after FIFO
+	underflow. Removed unnecessary stall checking. Signal stack on TX
+	errors.
+
+2001-07-16  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: Minor cleanups, avoid use of diag_printf unless
+	when debugging.
+
+2001-07-12  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: Use PCI_IO accessor macros instead of HAL IO
+	macros. Added a few more CPU->PCI address conversions. Print
+	controller data.
+	
+	* src/amd_pcnet.h: Added default PCI_IO accessor macros. Use
+	PCI_IO accessor macros instead of HAL IO macros.
+
+	* src/if_pcnet.c: Removed macros. Added new interrupt handling
+	code. Added code to find resources via PCI library. Change from
+	enaddr to esa. Use HAL_PCI_CPU_TO_BUS macros instead of phys
+	address macro. Fix esa setup code. Debug output tidied up.
+
+	* src/amd_pcnet.h: Moved macros here. Added definitions for 32 bit
+	RD/TD (unused). Changes for PCI configury.
+
+	* cdl/amd_pcnet_eth_drivers.cdl: Removed static esa option (now
+	per-device option). Added dev count option.
+
+	* src/if_pcnet.c: Get rid of within_send.
+	* src/amd_pcnet.h: Same.
+
+	* src/if_pcnet.c: Fix compile error.
+
+2001-04-09  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: More updates.
+
+	* src/amd_pcnet.h: A few more defs.
+
+	* cdl/amd_pcnet_eth_drivers.cdl: Removed write EEPROM option.
+
+	* src/if_pcnet.c: Fix link status check code. Change some C types
+	to cyg types.
+	* src/amd_pcnet.h (get_reg, put_reg): Also access ANR registers. 
+
+	* src/amd_pcnet.h: Macros for accessing structure elements.
+	* src/if_pcnet.c: Use those macros.	
+
+2001-04-04  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c: Keep local counter of where to expect RX
+	packets. Appears that the receive ring counter always points at
+	the first buffer.
+	(pcnet_poll): Handle RX events before TX events. 
+	Make sure to not accidently clear IENA flag.
+
+	* src/if_pcnet.c: Added RX code.
+	* src/amd_pcnet.h: A few more defs.
+
+2001-04-03  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c (amd_pcnet_init): Feed controller physical address.
+
+	* Cloned from LAN91Cxx driver.
+
+//===========================================================================
+//####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, 2001 Red Hat, Inc.
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl
@@ -0,0 +1,86 @@
+# ====================================================================
+#
+#      amd_pcnet_eth_drivers.cdl
+#
+#      Ethernet drivers - support for AMD PCNET ethernet controllers
+#
+# ====================================================================
+#####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, 2001 Red Hat, Inc.
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      gthomas
+# Contributors:   gthomas, jskov
+# Date:           2001-04-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_AMD_PCNET {
+    display       "AMD PCNET compatible ethernet driver"
+    description   "Ethernet driver for AMD PCNET compatible controllers."
+
+    parent        CYGPKG_IO_ETH_DRIVERS
+    active_if	  CYGPKG_IO_ETH_DRIVERS
+
+    active_if     CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED
+
+    include_dir   .
+    include_files ; # none _exported_ whatsoever
+    compile       -library=libextras.a if_pcnet.c
+
+    define_proc {
+        puts $::cdl_header "#include <pkgconf/system.h>";
+        puts $::cdl_header "#include CYGDAT_DEVS_ETH_AMD_PCNET_CFG";
+    }
+
+    cdl_option CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT {
+	display "Number of supported interfaces."
+	calculated    { CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED }
+        flavor        data
+	description   "
+	    This option selects the number of PCI ethernet interfaces to
+            be supported by the driver."
+    }
+
+    cdl_component CYGPKG_DEVS_ETH_AMD_PCNET_OPTIONS {
+        display "PCNET ethernet driver build options"
+        flavor  none
+	no_define
+
+        cdl_option CYGPKG_DEVS_ETH_AMD_PCNET_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "-D_KERNEL -D__ECOS" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the PCNET ethernet driver package.
+                These flags are used in addition
+                to the set of global flags."
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h
@@ -0,0 +1,528 @@
+#ifndef CYGONCE_DEVS_ETH_AMD_PCNET_H
+#define CYGONCE_DEVS_ETH_AMD_PCNET_H
+//==========================================================================
+//
+//      amd_pcnet.h
+//
+//      AMD PCNet Ethernet chip
+//
+//==========================================================================
+//####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, 2001 Red Hat, Inc.
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources,
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jskov
+// Contributors: jskov, hmt
+// Date:         2001-04-02
+// Purpose:      Hardware description of AMD PCnet series.
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+
+//------------------------------------------------------------------------
+// Get macros from platform header
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_AMD_PCNET_INL
+#undef  __WANT_CONFIG
+
+//------------------------------------------------------------------------
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0x0
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+# define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+# define INCR_STAT( _x_ )        (cpd->stats. _x_ ++)
+#else
+# define INCR_STAT( _x_ )        CYG_EMPTY_STATEMENT
+#endif
+
+//------------------------------------------------------------------------
+// Cache translation
+#ifndef CYGARC_UNCACHED_ADDRESS
+# define CYGARC_UNCACHED_ADDRESS(x) (x)
+#endif
+
+//------------------------------------------------------------------------
+// Address translation
+#ifndef HAL_PCI_CPU_TO_BUS
+# error "HAL PCI support must define translation macros"
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for accessing structure elements
+
+#define _SU8( _base_, _offset_) \
+        *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU16( _base_, _offset_) \
+        *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU32( _base_, _offset_) \
+        *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+#define _SI8( _base_, _offset_) \
+        *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI16( _base_, _offset_) \
+        *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI32( _base_, _offset_) \
+        *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+// ------------------------------------------------------------------------
+// Macros for accessing controller registers
+#ifndef HAL_PCI_IO_READ_UINT8
+# define HAL_PCI_IO_READ_UINT8(addr, datum)   HAL_READ_UINT8(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT8(addr, datum)  HAL_WRITE_UINT8(addr, datum)
+# define HAL_PCI_IO_READ_UINT16(addr, datum)  HAL_READ_UINT16(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum)
+# define HAL_PCI_IO_READ_UINT32(addr, datum)  HAL_READ_UINT32(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum)
+#endif
+
+// ------------------------------------------------------------------------
+// IO map registers
+#define PCNET_IO_EEPROM   0x00
+#define PCNET_IO_ID       0x0e
+#define PCNET_IO_RDP      0x10
+#define PCNET_IO_RAP      0x12
+#define PCNET_IO_RESET    0x14
+#define PCNET_IO_BDP      0x16
+
+// The ID of the 79C790 is 0x5757 - that may be different in other
+// (older) cards.
+#define PCNET_IO_ID_KEY   0x5757
+
+// ------------------------------------------------------------------------
+// Controller registers come in three sets: CSR, BCR and ANR. Use
+// high-bits do differentiate, make the put/get functions do the right
+// thing depending the state of these bits.
+#define PCNET_RAP_MASK    0x007f
+//#define PCNET_CSR_FLAG  0x0000        // implied
+#define PCNET_BCR_FLAG    0x0080
+#define PCNET_ANR_FLAG    0x0100
+
+
+// CSR registers
+#define PCNET_CSR_CSCR    0
+#define PCNET_CSR_IBA0    1
+#define PCNET_CSR_IBA1    2
+#define PCNET_CSR_IM      3
+#define PCNET_CSR_TFC     4
+#define PCNET_CSR_ECI     5
+#define PCNET_CSR_LAR0    8
+#define PCNET_CSR_LAR1    9
+#define PCNET_CSR_LAR2    10
+#define PCNET_CSR_LAR3    11
+#define PCNET_CSR_PAR0    12
+#define PCNET_CSR_PAR1    13
+#define PCNET_CSR_PAR2    14
+#define PCNET_CSR_MODE    15
+#define PCNET_CSR_BARRL   24
+#define PCNET_CSR_BARRU   25
+#define PCNET_CSR_BATRL   30
+#define PCNET_CSR_BATRU   31
+#define PCNET_CSR_RRC     72
+#define PCNET_CSR_TRC     74
+#define PCNET_CSR_RRLEN   76
+#define PCNET_CSR_TRLEN   78
+#define PCNET_CSR_ID_LO   88
+#define PCNET_CSR_ID_HI   89
+
+
+#define PCNET_CSR_CSCR_ERR       0x8000
+#define PCNET_CSR_CSCR_RES       0x4000
+#define PCNET_CSR_CSCR_CERR      0x2000
+#define PCNET_CSR_CSCR_MISS      0x1000
+#define PCNET_CSR_CSCR_MERR      0x0800
+#define PCNET_CSR_CSCR_RINT      0x0400
+#define PCNET_CSR_CSCR_TINT      0x0200
+#define PCNET_CSR_CSCR_IDON      0x0100
+#define PCNET_CSR_CSCR_INTR      0x0080
+#define PCNET_CSR_CSCR_IENA      0x0040
+#define PCNET_CSR_CSCR_RXON      0x0020
+#define PCNET_CSR_CSCR_TXON      0x0010
+#define PCNET_CSR_CSCR_TDMD      0x0008
+#define PCNET_CSR_CSCR_STOP      0x0004
+#define PCNET_CSR_CSCR_STRT      0x0002
+#define PCNET_CSR_CSCR_INIT      0x0001
+
+#define PCNET_CSR_CSCR_EV_MASK   0x007f
+
+#define PCNET_CSR_IM_MISSM       0x1000
+#define PCNET_CSR_IM_MERRM       0x0800
+#define PCNET_CSR_IM_RINTM       0x0400
+#define PCNET_CSR_IM_TINTM       0x0200
+#define PCNET_CSR_IM_IDONM       0x0100
+#define PCNET_CSR_IM_DXSUFLO     0x0040
+#define PCNET_CSR_IM_LAPPEN      0x0020
+#define PCNET_CSR_IM_DXMT2PD     0x0010
+#define PCNET_CSR_IM_EMBA        0x0008
+#define PCNET_CSR_IM_BSWP        0x0004
+
+#define PCNET_CSR_TFC_TXDPOLL    0x1000
+#define PCNET_CSR_TFC_APAD_XMT   0x0800
+#define PCNET_CSR_TFC_ASTRP_RCV  0x0400
+#define PCNET_CSR_TFC_MFCO       0x0200
+#define PCNET_CSR_TFC_MFCOM      0x0100
+#define PCNET_CSR_TFC_UINTCMD    0x0080
+#define PCNET_CSR_TFC_UINT       0x0040
+#define PCNET_CSR_TFC_RCVCCO     0x0020
+#define PCNET_CSR_TFC_RCVCCOM    0x0010
+#define PCNET_CSR_TFC_TXSTRT     0x0008
+#define PCNET_CSR_TFC_TXSTRTM    0x0004
+
+#define PCNET_CSR_ECI_TOKINTD      0x8000
+#define PCNET_CSR_ECI_LTINTEN      0x4000
+#define PCNET_CSR_ECI_SINT         0x0800
+#define PCNET_CSR_ECI_SINTE        0x0400
+#define PCNET_CSR_ECI_EXDINT       0x0080
+#define PCNET_CSR_ECI_EXDINTE      0x0040
+#define PCNET_CSR_ECI_MPPLBA       0x0020
+#define PCNET_CSR_ECI_MPINT        0x0010
+#define PCNET_CSR_ECI_MPINTE       0x0008
+#define PCNET_CSR_ECI_MPEN         0x0004
+#define PCNET_CSR_ECI_MPMODE       0x0002
+#define PCNET_CSR_ECI_SPND         0x0001
+
+#define PCNET_CSR_MODE_PROM        0x8000
+#define PCNET_CSR_MODE_DRCVBC      0x4000
+#define PCNET_CSR_MODE_DRCVPA      0x2000
+#define PCNET_CSR_MODE_PORTSEL     0x0180
+#define PCNET_CSR_MODE_INTL        0x0040
+#define PCNET_CSR_MODE_DRTY        0x0020
+#define PCNET_CSR_MODE_FCOLL       0x0010
+#define PCNET_CSR_MODE_DXMTFCS     0x0008
+#define PCNET_CSR_MODE_LOOP        0x0004
+#define PCNET_CSR_MODE_DTX         0x0002
+#define PCNET_CSR_MODE_DRX         0x0001
+
+// BCR registers
+#define PCNET_BCR_SWSTYLE (20 |PCNET_BCR_FLAG)
+#define PCNET_BCR_MIIADDR (33 |PCNET_BCR_FLAG)
+#define PCNET_BCR_MIIDATA (34 |PCNET_BCR_FLAG)
+
+#define PCNET_BCR_MIIADDR_PHYAD    0x03e0
+
+
+// ANR registers
+#define PCNET_ANR_PHYCTRL ( 0 |PCNET_ANR_FLAG)
+#define PCNET_ANR_PHYSTAT ( 1 |PCNET_ANR_FLAG)
+
+#define PCNET_ANR_PHYCTRL_100MBPS 0x2000
+#define PCNET_ANR_PHYCTRL_DUPLEX  0x0100
+
+#define PCNET_ANR_PHYSTAT_LINK    0x0004
+
+
+//----------------------------------------------------------------------------
+// Receive buffer Descriptor
+#if 1
+#define PCNET_RD_PTR       0x00        // 32 bit
+#define PCNET_RD_BLEN      0x04        // 16 bit (2's complement, negative)
+#define PCNET_RD_MLEN      0x06        // 16 bit
+#define PCNET_RD_SIZE      0x08
+
+#define PCNET_RD_PTR_OWN       0x80000000
+#define PCNET_RD_PTR_ERR       0x40000000
+#define PCNET_RD_PTR_FRAM      0x20000000
+#define PCNET_RD_PTR_OFLO      0x10000000
+#define PCNET_RD_PTR_CRC       0x08000000
+#define PCNET_RD_PTR_BUFF      0x04000000
+#define PCNET_RD_PTR_STP       0x02000000
+#define PCNET_RD_PTR_ENP       0x01000000
+#define PCNET_RD_PTR_MASK      0x00ffffff
+#else
+
+#define PCNET_RD_PTR       0x00
+#define PCNET_RD_BLEN      0x04
+#define PCNET_RD_MLEN      0x08
+#define PCNET_RD_USER      0x0c
+#define PCNET_RD_SIZE      0x10
+
+#define PCNET_RD_BLEN_OWN       0x80000000
+#define PCNET_RD_BLEN_ERR       0x40000000
+#define PCNET_RD_BLEN_FRAM      0x20000000
+#define PCNET_RD_BLEN_OFLO      0x10000000
+#define PCNET_RD_BLEN_CRC       0x08000000
+#define PCNET_RD_BLEN_BUFF      0x04000000
+#define PCNET_RD_BLEN_STP       0x02000000
+#define PCNET_RD_BLEN_ENP       0x01000000
+#define PCNET_RD_BLEN_BPE       0x00800000
+#define PCNET_RD_BLEN_PAM       0x00400000
+#define PCNET_RD_BLEN_LAFM      0x00200000
+#define PCNET_RD_BLEN_BAM       0x00100000
+#define PCNET_RD_BLEN_MASK      0x0000ffff
+#endif
+
+// Transmit buffer Descriptor
+#if 1
+#define PCNET_TD_PTR       0x00        // 32 bit
+#define PCNET_TD_LEN       0x04        // 16 bit (2's complement, negative)
+#define PCNET_TD_MISC      0x06        // 16 bit
+#define PCNET_TD_SIZE      0x08
+
+#define PCNET_TD_PTR_OWN       0x80000000
+#define PCNET_TD_PTR_ERR       0x40000000
+#define PCNET_TD_PTR_ADD_FCS   0x20000000
+#define PCNET_TD_PTR_MORE      0x10000000
+#define PCNET_TD_PTR_ONE       0x08000000
+#define PCNET_TD_PTR_DEF       0x04000000
+#define PCNET_TD_PTR_STP       0x02000000
+#define PCNET_TD_PTR_ENP       0x01000000
+#define PCNET_TD_PTR_MASK      0x00ffffff
+#else
+#define PCNET_TD_PTR       0x00
+#define PCNET_TD_LEN       0x04
+#define PCNET_TD_MISC      0x08
+#define PCNET_TD_USER      0x0c
+#define PCNET_TD_SIZE      0x10
+
+#define PCNET_TD_LEN_OWN       0x80000000
+#define PCNET_TD_LEN_ERR       0x40000000
+#define PCNET_TD_LEN_ADD_FCS   0x20000000
+#define PCNET_TD_LEN_MORE      0x10000000
+#define PCNET_TD_LEN_ONE       0x08000000
+#define PCNET_TD_LEN_DEF       0x04000000
+#define PCNET_TD_LEN_STP       0x02000000
+#define PCNET_TD_LEN_ENP       0x01000000
+#define PCNET_TD_LEN_BPE       0x00800000
+#define PCNET_TD_LEN_MASK      0x0000ffff
+
+#define PCNET_TD_FLAGS_BUFF     0x80000000
+#define PCNET_TD_FLAGS_UFLO     0x40000000
+#define PCNET_TD_FLAGS_EX_DEF   0x20000000
+#define PCNET_TD_FLAGS_LCOL     0x10000000
+#define PCNET_TD_FLAGS_LCAR     0x08000000
+#define PCNET_TD_FLAGS_RTRY     0x04000000
+#define PCNET_TD_FLAGS_TRC_MASK 0x0000000f
+#endif
+
+
+#define PCNET_TD_MISC_BUFF     0x8000
+#define PCNET_TD_MISC_UFLO     0x4000
+#define PCNET_TD_MISC_EXDEF    0x2000
+#define PCNET_TD_MISC_LCOL     0x1000
+#define PCNET_TD_MISC_LCAR     0x0800
+#define PCNET_TD_MISC_RTRY     0x0400
+#define PCNET_TD_MISC_TDR      0x03ff
+
+// Initialization Buffer
+#define PCNET_IB_MODE            0
+#define PCNET_IB_PADR0           2
+#define PCNET_IB_PADR1           4
+#define PCNET_IB_PADR2           6
+#define PCNET_IB_LADRF0          8
+#define PCNET_IB_LADRF1          10
+#define PCNET_IB_LADRF2          12
+#define PCNET_IB_LADRF3          14
+#define PCNET_IB_RDRA            16
+#define PCNET_IB_TDRA            20
+#define PCNET_IB_SIZE            24
+
+#define PCNET_IB_TDRA_CNT_shift  29
+#define PCNET_IB_TDRA_PTR_mask   0x00ffffff
+#define PCNET_IB_RDRA_CNT_shift  29
+#define PCNET_IB_RDRA_PTR_mask   0x00ffffff
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+struct amd_pcnet_stats {
+    unsigned int tx_good             ;
+    unsigned int tx_max_collisions   ;
+    unsigned int tx_late_collisions  ;
+    unsigned int tx_underrun         ;
+    unsigned int tx_carrier_loss     ;
+    unsigned int tx_deferred         ;
+    unsigned int tx_sqetesterrors    ;
+    unsigned int tx_single_collisions;
+    unsigned int tx_mult_collisions  ;
+    unsigned int tx_total_collisions ;
+    unsigned int rx_good             ;
+    unsigned int rx_crc_errors       ;
+    unsigned int rx_align_errors     ;
+    unsigned int rx_resource_errors  ;
+    unsigned int rx_overrun_errors   ;
+    unsigned int rx_collisions       ;
+    unsigned int rx_short_frames     ;
+    unsigned int rx_too_long_frames  ;
+    unsigned int rx_symbol_errors    ;
+    unsigned int interrupts          ;
+    unsigned int rx_count            ;
+    unsigned int rx_deliver          ;
+    unsigned int rx_resource         ;
+    unsigned int rx_restart          ;
+    unsigned int tx_count            ;
+    unsigned int tx_complete         ;
+    unsigned int tx_dropped          ;
+};
+#endif
+
+typedef struct pcnet_priv_data {
+    int index;
+    cyg_uint8                           // (split up for atomic byte access)
+        found:1,                        // was hardware discovered?
+        mac_addr_ok:1,                  // can we bring up?
+        active:1,                       // has this if been brung up?
+        hardwired_esa:1,                // set if ESA is hardwired via CDL
+        txbusy:1,                       // A packet has been sent
+        spare1:3; 
+
+    unsigned long txkey;                // Used to ack when packet sent
+    unsigned char* base;                // Base address of controller EPROM region
+    int interrupt;                      // Interrupt vector used by controller
+    unsigned char esa[6];            // Controller ESA
+    // Function to configure the ESA - may fetch ESA from EPROM or 
+    // RedBoot config option.
+    void (*config_esa)(struct pcnet_priv_data* cpd);
+    void *ndp;                          // Network Device Pointer
+
+    cyg_handle_t  interrupt_handle;
+    cyg_interrupt interrupt_object;
+    int devid;
+
+    cyg_uint8* rx_buffers;              // ptr to base of buffer mem
+    cyg_uint8* rx_ring;                 // ptr to base of rx ring memory
+    int rx_ring_cnt;                    // number of entries in ring
+    int rx_ring_log_cnt;                // log of above
+    int rx_ring_next;                   // index of next full ring entry
+
+    cyg_uint8* tx_buffers;
+    cyg_uint8* tx_ring;
+    int tx_ring_cnt;
+    int tx_ring_log_cnt;
+    int tx_ring_free;                   // index of next free ring entry
+    int tx_ring_alloc;                  // index of first controller owned ring
+    int tx_ring_owned;                  // number of controller owned ring entries
+
+    int rxpacket;
+#ifdef KEEP_STATISTICS
+    struct amd_pcnet_stats stats;
+#endif
+#if DEBUG & 1
+    cyg_uint32 txd;
+#endif
+} pcnet_priv_data;
+
+// ------------------------------------------------------------------------
+
+static __inline__ cyg_uint16
+get_reg(struct eth_drv_sc *sc, int regno)
+{
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+    cyg_uint16 val, addr;
+
+    if (regno & PCNET_ANR_FLAG) {
+        // We could do this with recursive calls to get/put reg
+        // functions, but might as well just do it directly.
+        // First set ANR address
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK);
+        HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr);
+        addr &= PCNET_BCR_MIIADDR_PHYAD;
+        addr |= (regno & PCNET_RAP_MASK);
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr);
+        // Then read ANR register data
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK);
+        HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val);
+    } else {
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK);
+        if (regno & PCNET_BCR_FLAG)
+            HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val);
+        else
+            HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RDP, val);
+    }
+#if DEBUG & 2
+    diag_printf("read %s reg %d val 0x%04x\n", 
+                (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr", 
+                regno & PCNET_RAP_MASK, val);
+#endif
+    return val;
+}
+
+static __inline__ void
+put_reg(struct eth_drv_sc *sc, int regno, cyg_uint16 val)
+{
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+    cyg_uint16 addr;
+
+    if (regno & PCNET_ANR_FLAG) {
+        // We could do this with recursive calls to get/put reg
+        // functions, but might as well just do it directly.
+        // First set ANR address
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK);
+        HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr);
+        addr &= PCNET_BCR_MIIADDR_PHYAD;
+        addr |= (regno & PCNET_RAP_MASK);
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr);
+        // Then write ANR register data
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK);
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val);
+    } else {
+        HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK);
+        if (regno & PCNET_BCR_FLAG)
+            HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val);
+        else
+            HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RDP, val);
+    }
+
+#if DEBUG & 2
+    diag_printf("write %s reg %d val 0x%04x\n", 
+                (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr", 
+                regno & PCNET_RAP_MASK, val);
+#endif
+}
+
+// ------------------------------------------------------------------------
+#endif CYGONCE_DEVS_ETH_AMD_PCNET_H
+// EOF amd_pcnet.h
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
@@ -0,0 +1,1244 @@
+//==========================================================================
+//
+//      dev/if_pcnet.c
+//
+//      Ethernet device driver for AMD PCNET compatible controllers
+//
+//==========================================================================
+//####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, 2001 Red Hat, Inc.
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources,
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jskov, based on lan91cxx driver by hmt & jskov
+// Contributors: gthomas, jskov, hmt
+// Date:         2001-04-02
+// Purpose:      
+// Description:  hardware driver for AMD PCNet (and possibly Lance) ethernet
+// Notes:        The controller is used in its 16bit mode. That means that
+//               all addresses are 24bit only - and that all controller
+//               accessed memory must be within the same 16MB region
+//               (starting at 0 on older controllers).
+//
+//               The KEEP_STATISTICS code is not implemented yet. Look
+//               for FIXME macro.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_amd_pcnet.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>             // delays
+#include <netdev.h>
+#include <eth_drv.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <net/if.h>  /* Needed for struct ifnet */
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+#else
+#error "Need PCI package here"
+#endif
+
+#define FIXME 0
+
+#define _BUF_SIZE 1544
+
+#ifdef CYGPKG_INFRA_DEBUG
+// Then we log, OOI, the number of times we get a bad packet number
+// from the tx done fifo.
+int pcnet_txfifo_good = 0;
+int pcnet_txfifo_bad = 0;
+#endif
+
+#include "amd_pcnet.h"
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_AMD_PCNET_INL
+#undef  __WANT_DEVS
+
+static void pcnet_poll(struct eth_drv_sc *sc);
+
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+pcnet_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+    struct pcnet_priv_data *cpd = (struct pcnet_priv_data *)data;
+
+    DEBUG_FUNCTION();
+
+    INCR_STAT( interrupts );
+
+    cyg_drv_interrupt_mask(cpd->interrupt);
+    cyg_drv_interrupt_acknowledge(cpd->interrupt);
+    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
+}
+
+static void
+pcnet_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    // This conditioning out is necessary because of explicit calls to this
+    // DSR - which would not ever be called in the case of a polled mode
+    // usage ie. in RedBoot.
+#ifdef CYGPKG_IO_ETH_DRIVERS_NET
+    struct pcnet_priv_data* cpd = (struct pcnet_priv_data *)data;
+    struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
+    struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+    // but here, it must be a *sc:
+    eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+#  error Empty PCnet ethernet DSR is compiled.  Is this what you want?
+# endif
+#endif
+}
+
+
+// The deliver function (ex-DSR)  handles the ethernet [logical] processing
+static void
+pcnet_deliver(struct eth_drv_sc *sc)
+{
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+
+    DEBUG_FUNCTION();
+
+    // Service the interrupt:
+    pcnet_poll(sc);
+    // Allow interrupts to happen again
+    cyg_drv_interrupt_unmask(cpd->interrupt);
+}
+
+static int
+pcnet_int_vector(struct eth_drv_sc *sc)
+{
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+
+    return (cpd->interrupt);
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+static cyg_uint32 pcnet_heap_size;
+static cyg_uint8 *pcnet_heap_base;
+static cyg_uint8 *pcnet_heap_free;
+
+static void*
+pciwindow_mem_alloc(int size)
+{
+    void *p_memory;
+    int _size = size;
+
+    CYG_ASSERT(
+        (CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE <= (int)pcnet_heap_free)
+        &&
+        ((CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE + 
+          CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE) > (int)pcnet_heap_free)
+        &&
+        (0 < pcnet_heap_size)
+        &&
+        (CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE >= pcnet_heap_size)
+        &&
+        (CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE == (int)pcnet_heap_base),
+        "Heap variables corrupted" );
+
+    p_memory = (void *)0;
+    size = (size + 3) & ~3;
+    if ( (pcnet_heap_free+size) < (pcnet_heap_base+pcnet_heap_size) ) {
+        cyg_uint32 *p;
+        p_memory = (void *)pcnet_heap_free;
+        pcnet_heap_free += size;
+        for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+            *p++ = 0;
+    }
+
+#if DEBUG & 9
+    diag_printf("Allocated %d bytes at 0x%08x\n", size, p_memory);
+#endif
+
+    return p_memory;
+}
+
+static cyg_pci_match_func find_pcnet_match_func;
+
+static cyg_bool
+find_pcnet_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+#if DEBUG & 9
+    diag_printf("PCI match vendor 0x%04x device 0x%04x\n", v, d);
+#endif
+    return (0x1022 == v) && (0x2000 == d);
+}
+
+static int
+pci_init_find_pcnet( void )
+{
+    cyg_pci_device_id devid;
+    cyg_pci_device dev_info;
+    cyg_uint16 cmd;
+    int device_index;
+    int found_devices = 0;
+
+    DEBUG_FUNCTION();
+
+#ifdef CYGARC_UNCACHED_ADDRESS
+    CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
+                CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE,
+      "PCI window configured does not match PCI memory section base" );
+#else
+    CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
+                CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE,
+      "PCI window configured does not match PCI memory section base" );
+#endif
+    CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
+                CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE,
+        "PCI window configured does not match PCI memory section size" );
+
+    if (
+#ifdef CYGARC_UNCACHED_ADDRESS
+         CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
+#else
+         (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
+#endif
+         CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE
+         ||
+         CYGMEM_SECTION_pci_window_SIZE !=
+         CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ) {
+#if DEBUG & 8
+        diag_printf("pci_init_find_pcnets(): PCI window misconfigured\n");
+#endif
+        return 0;
+    }
+
+    // First initialize the heap in PCI window'd memory
+    pcnet_heap_size = CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE;
+    pcnet_heap_base = (cyg_uint8 *)CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE;
+    pcnet_heap_free = pcnet_heap_base;
+#if DEBUG & 9
+    diag_printf("pcimem : 0x%08x size: 0x%08x\n", pcnet_heap_base, pcnet_heap_size);
+#endif
+
+    cyg_pci_init();
+#if DEBUG & 8
+    diag_printf("Finished cyg_pci_init();\n");
+#endif
+
+    devid = CYG_PCI_NULL_DEVID;
+
+    for (device_index = 0; 
+         device_index < CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT;
+         device_index++) {
+        struct pcnet_priv_data* cpd = pcnet_priv_array[device_index];
+
+        cpd->index = device_index;
+
+        // See above for find_pcnet_match_func - it selects any of several
+        // variants.  This is necessary in case we have multiple mixed-type
+        // devices on one board in arbitrary orders.
+        if (cyg_pci_find_matching( &find_pcnet_match_func, NULL, &devid )) {
+#if DEBUG & 8
+            diag_printf("eth%d = pcnet\n", device_index);
+#endif
+            cyg_pci_get_device_info(devid, &dev_info);
+
+            cpd->interrupt_handle = 0; // Flag not attached.
+            if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
+#if DEBUG & 8
+                diag_printf(" Wired to HAL vector %d\n", cpd->interrupt);
+#endif
+                cyg_drv_interrupt_create(
+                    cpd->interrupt,
+                    1,                  // Priority - unused
+                    (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
+                    pcnet_isr,          // ISR
+                    pcnet_dsr,          // DSR
+                    &cpd->interrupt_handle, // handle to intr obj
+                    &cpd->interrupt_object ); // space for int obj
+
+                cyg_drv_interrupt_attach(cpd->interrupt_handle);
+
+                // Don't unmask the interrupt yet, that could get us into a
+                // race.
+            }
+            else {
+                cpd->interrupt = 0;
+#if DEBUG & 8
+                diag_printf(" Does not generate interrupts.\n");
+#endif
+            }
+
+            if (cyg_pci_configure_device(&dev_info)) {
+#if DEBUG & 8
+                int i;
+                diag_printf("Found device on bus %d, devfn 0x%02x:\n",
+                          CYG_PCI_DEV_GET_BUS(devid),
+                          CYG_PCI_DEV_GET_DEVFN(devid));
+
+                if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+                    diag_printf(" Note that board is active. Probed"
+                              " sizes and CPU addresses invalid!\n");
+                }
+                diag_printf(" Vendor    0x%04x", dev_info.vendor);
+                diag_printf("\n Device    0x%04x", dev_info.device);
+                diag_printf("\n Command   0x%04x, Status 0x%04x\n",
+                          dev_info.command, dev_info.status);
+                
+                diag_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+                diag_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+                diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+                          dev_info.header.normal.sub_vendor, 
+                          dev_info.header.normal.sub_id);
+
+                for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+                    diag_printf(" BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
+                    diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+                              dev_info.base_size[i], dev_info.base_map[i]);
+                }
+                diag_printf(" eth%d configured\n", device_index);
+#endif
+                found_devices++;
+                cpd->found = 1;
+                cpd->active = 0;
+                cpd->devid = devid;
+                cpd->base = (unsigned char*) dev_info.base_map[0];
+#if DEBUG & 8
+                diag_printf(" I/O address = 0x%08x\n", cpd->base);
+#endif
+
+                // Don't use cyg_pci_set_device_info since it clears
+                // some of the fields we want to print out below.
+                cyg_pci_read_config_uint16(dev_info.devid,
+                                           CYG_PCI_CFG_COMMAND, &cmd);
+                cmd |= (CYG_PCI_CFG_COMMAND_IO         // enable I/O space
+                        | CYG_PCI_CFG_COMMAND_MEMORY   // enable memory space
+                        | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+                cyg_pci_write_config_uint16(dev_info.devid,
+                                            CYG_PCI_CFG_COMMAND, cmd);
+
+                // This is the indicator for "uses an interrupt"
+                if (cpd->interrupt_handle != 0) {
+                    cyg_drv_interrupt_acknowledge(cpd->interrupt);
+                    cyg_drv_interrupt_unmask(cpd->interrupt);
+#if DEBUG & 8
+                    diag_printf(" Enabled interrupt %d\n", cpd->interrupt);
+#endif
+                }
+#if DEBUG & 8
+                diag_printf(" **** Device enabled for I/O and Memory "
+                            "and Bus Master\n");
+#endif
+            }
+            else {
+                cpd->found = 0;
+                cpd->active = 0;
+#if DEBUG & 8
+                diag_printf("Failed to configure device %d\n", device_index);
+#endif
+            }
+        }
+        else {
+            cpd->found = 0;
+            cpd->active = 0;
+#if DEBUG & 8
+            diag_printf("eth%d not found\n", device_index);
+#endif
+        }
+    }
+
+    if (0 == found_devices)
+        return 0;
+
+    return 1;
+}
+
+
+static bool 
+amd_pcnet_init(struct cyg_netdevtab_entry *tab)
+{
+    static int initialized = 0; // only probe PCI et al *once*
+    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+    cyg_uint16 val;
+    cyg_uint32 b;
+    cyg_uint8* p;
+    cyg_uint8* d;
+    cyg_uint8* init_table;
+    int i;
+
+    DEBUG_FUNCTION();
+
+
+    if ( 0 == initialized++ ) {
+        // then this is the first time ever:
+        if ( ! pci_init_find_pcnet() ) {
+#if DEBUG & 8
+            diag_printf( "pci_init_find_pcnet failed" );
+#endif
+            return false;
+        }
+    }
+
+    // If this device is not present, exit
+    if (0 == cpd->found)
+        return 0;
+
+    cpd->txbusy = 0;
+
+#if DEBUG & 8
+    diag_printf("PCNet at base 0x%08x, EEPROM key 0x%04x\n",
+                cpd->base, _SU16(cpd->base, PCNET_IO_ID));
+#endif
+
+#if 0
+    // FIXME: Doesn't work with non-conforming EEPROMS
+    if (PCNET_IO_ID_KEY != _SU16(cpd->base, PCNET_IO_ID) ) {
+        diag_printf("PCNet EPROM key not found\n");
+        return false;
+    }
+#endif
+
+#if DEBUG & 9
+    diag_printf("pcimem : %08x size: %08x\n", pcnet_heap_base, pcnet_heap_size);
+#endif
+
+    // Prepare ESA
+    if (!cpd->hardwired_esa) {
+        // Use the address from the serial EEPROM
+        p = cpd->base + PCNET_IO_EEPROM;
+        for (i = 0; i < 6; i++)
+            cpd->esa[i] = *p++;
+    }
+#if DEBUG & 9
+    diag_printf("PCNET - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                (cpd->hardwired_esa) ? "static" : "eeprom",
+                cpd->esa[0], cpd->esa[1], cpd->esa[2],
+                cpd->esa[3], cpd->esa[4], cpd->esa[5] );
+#endif
+
+    // Prepare RX and TX rings
+    p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*PCNET_RD_SIZE));
+    d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
+    for (i = 0; i < cpd->rx_ring_cnt; i++) {
+        HAL_PCI_CPU_TO_BUS(d, b);
+        _SU32(p, PCNET_RD_PTR) = (b & PCNET_RD_PTR_MASK) | PCNET_RD_PTR_OWN;
+        _SU16(p, PCNET_RD_BLEN) = (-_BUF_SIZE);
+        p += PCNET_RD_SIZE;
+        d += _BUF_SIZE;
+    }
+    cpd->rx_ring_next = 0;
+
+    p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*PCNET_TD_SIZE));
+    d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
+    for (i = 0; i < cpd->tx_ring_cnt; i++) {
+        HAL_PCI_CPU_TO_BUS(d, b);
+        _SU32(p, PCNET_RD_PTR) = b & PCNET_TD_PTR_MASK;
+        p += PCNET_TD_SIZE;
+        d += _BUF_SIZE;
+    }
+    cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+
+    // Initialization table
+    init_table = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(PCNET_IB_SIZE));
+    _SU16(init_table, PCNET_IB_MODE) = 0x0000;
+    for (i = 0; i < 6; i++)
+        _SU8(init_table, PCNET_IB_PADR0+i) = cpd->esa[i];
+    for (i = 0; i < 8; i++)
+        _SU8(init_table, PCNET_IB_LADRF0+i) = 0;
+    
+    HAL_PCI_CPU_TO_BUS(cpd->rx_ring, b);
+    _SU32(init_table, PCNET_IB_RDRA) = ((b & PCNET_IB_RDRA_PTR_mask)
+                                        | (cpd->rx_ring_log_cnt << PCNET_IB_RDRA_CNT_shift));
+    HAL_PCI_CPU_TO_BUS(cpd->tx_ring, b);
+    _SU32(init_table, PCNET_IB_TDRA) = ((b & PCNET_IB_TDRA_PTR_mask)
+                                        | (cpd->tx_ring_log_cnt << PCNET_IB_TDRA_CNT_shift));
+
+#if DEBUG & 9
+    diag_printf("Loading up PCNet controller from table at 0x%08x\n", init_table);
+    diag_printf(" Mode 0x%04x\n", _SU16(init_table, PCNET_IB_MODE));
+    diag_printf(" PADR %02x:%02x:%02x:%02x:%02x:%02x ",
+                _SU8(init_table, PCNET_IB_PADR0+0), _SU8(init_table, PCNET_IB_PADR0+1),
+                _SU8(init_table, PCNET_IB_PADR0+2), _SU8(init_table, PCNET_IB_PADR0+3),
+                _SU8(init_table, PCNET_IB_PADR0+4), _SU8(init_table, PCNET_IB_PADR0+5));
+    diag_printf("LADR %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                _SU8(init_table, PCNET_IB_LADRF0+0), _SU8(init_table, PCNET_IB_LADRF0+1),
+                _SU8(init_table, PCNET_IB_LADRF0+2), _SU8(init_table, PCNET_IB_LADRF0+3),
+                _SU8(init_table, PCNET_IB_LADRF0+4), _SU8(init_table, PCNET_IB_LADRF0+5),
+                _SU8(init_table, PCNET_IB_LADRF0+5), _SU8(init_table, PCNET_IB_LADRF0+7));
+    diag_printf(" RX 0x%08x (len %d) TX 0x%08x (len %d)\n",
+                _SU32(init_table, PCNET_IB_RDRA) & 0x1fffffff,
+                (_SU32(init_table, PCNET_IB_RDRA) >> PCNET_IB_RDRA_CNT_shift) & 7,
+                _SU32(init_table, PCNET_IB_TDRA) & 0x1fffffff,
+                (_SU32(init_table, PCNET_IB_TDRA) >> PCNET_IB_TDRA_CNT_shift) & 7);
+#endif
+
+    // Reset chip
+    HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RESET, val);
+
+    // Load up chip with buffers.
+    // Note: There is a 16M limit on the addresses used by the driver
+    // since the top 8 bits of the init_table address is appended to
+    // all other addresses used by the controller.
+    HAL_PCI_CPU_TO_BUS(init_table, b);
+    put_reg(sc, PCNET_CSR_IBA0, (b >>  0) & 0xffff);
+    put_reg(sc, PCNET_CSR_IBA1, (b >> 16) & 0xffff);
+    // Disable automatic TX polling (_send will force a poll), pad
+    // XT frames to legal length, mask status interrupts.
+    put_reg(sc, PCNET_CSR_TFC, (PCNET_CSR_TFC_TXDPOLL | PCNET_CSR_TFC_APAD_XMT
+                                | PCNET_CSR_TFC_MFCOM | PCNET_CSR_TFC_RCVCCOM
+                                | PCNET_CSR_TFC_TXSTRTM));
+    // Recover after TX FIFO underflow
+    put_reg(sc, PCNET_CSR_IM, PCNET_CSR_IM_DXSUFLO);
+    // Initialize controller - load up init_table
+    put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_INIT);
+    while (0 == (get_reg(sc, PCNET_CSR_CSCR) & PCNET_CSR_CSCR_IDON));
+
+    // Stop controller
+    put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_STOP);
+
+#if DEBUG & 9
+    diag_printf("PCNet controller state is now:\n");
+    diag_printf(" Mode 0x%04x  TFC 0x%04x\n", _SU16(init_table, PCNET_IB_MODE), get_reg(sc, PCNET_CSR_TFC));
+    diag_printf(" PADR %04x:%04x:%04x ",
+                get_reg(sc, PCNET_CSR_PAR0),
+                get_reg(sc, PCNET_CSR_PAR1),
+                get_reg(sc, PCNET_CSR_PAR2));
+    diag_printf("LADR %04x:%04x:%04x:%04x\n",
+                get_reg(sc, PCNET_CSR_LAR0),
+                get_reg(sc, PCNET_CSR_LAR1),
+                get_reg(sc, PCNET_CSR_LAR2),
+                get_reg(sc, PCNET_CSR_LAR3));
+    diag_printf(" RX 0x%04x%04x (len 0x%04x) TX 0x%04x%04x (len 0x%04x)\n",
+                get_reg(sc, PCNET_CSR_BARRU), get_reg(sc, PCNET_CSR_BARRL), 
+                get_reg(sc, PCNET_CSR_RRLEN),
+                get_reg(sc, PCNET_CSR_BATRU), get_reg(sc, PCNET_CSR_BATRL), 
+                get_reg(sc, PCNET_CSR_TRLEN));
+
+    val = get_reg(sc, PCNET_CSR_ID_LO);
+    diag_printf("PCnet ID 0x%04x (%s) ",
+                val, 
+                (0x5003 == val) ? "Am79C973" : (0x7003 == val) ? "Am79C975" : "Unknown");
+    val = get_reg(sc, PCNET_CSR_ID_HI);
+    diag_printf("Part IDU 0x%03x Silicon rev %d\n",
+                val & 0x0fff, (val >> 12) & 0xf);
+#endif
+
+    // and record the net dev pointer
+    cpd->ndp = (void *)tab;
+
+    // Start controller, but put it in suspended mode
+    put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_STOP);
+    put_reg(sc, PCNET_CSR_CSCR, (PCNET_CSR_CSCR_IENA | PCNET_CSR_CSCR_STRT));
+    i = 0;
+    while (0 == (PCNET_CSR_CSCR_STRT & get_reg(sc, PCNET_CSR_CSCR))) {
+        CYGACC_CALL_IF_DELAY_US(1000);
+        put_reg(sc, PCNET_CSR_CSCR, (PCNET_CSR_CSCR_IENA | PCNET_CSR_CSCR_STRT));
+        if (i++ == 1000) {
+#if DEBUG & 9
+            diag_printf("Failed to start the controller\n");
+#endif
+            return false;
+        }
+    }
+
+    val = get_reg(sc, PCNET_CSR_ECI);
+    val |= PCNET_CSR_ECI_SPND;
+    put_reg(sc, PCNET_CSR_ECI, val);
+    // Wait for device to suspend
+    do {
+        val = get_reg(sc, PCNET_CSR_ECI);
+    } while (0 == (val & PCNET_CSR_ECI_SPND));
+    cpd->active = 0;
+
+    // Initialize upper level driver
+    (sc->funs->eth_drv->init)(sc, cpd->esa);
+
+#if DEBUG & 9
+    diag_printf("Done\n");
+#endif
+    return true;
+}
+
+static void
+pcnet_stop(struct eth_drv_sc *sc)
+{
+    cyg_uint16 reg;
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+
+    DEBUG_FUNCTION();
+    
+    reg = get_reg(sc, PCNET_CSR_ECI);
+    reg |= PCNET_CSR_ECI_SPND;
+    put_reg(sc, PCNET_CSR_ECI, reg);
+    // Wait for device to suspend
+    do {
+        reg = get_reg(sc, PCNET_CSR_ECI);
+    } while (0 == (reg & PCNET_CSR_ECI_SPND));
+    cpd->active = 0;
+}
+
+//
+// This function is called to "start up" the interface.  It may be called
+// multiple times, even when the hardware is already running.  It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+pcnet_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+    cyg_uint16 reg;
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+#ifdef CYGPKG_NET
+    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+    DEBUG_FUNCTION();
+
+    // If device is already active, suspend it
+    if (cpd->active) {
+        reg = get_reg(sc, PCNET_CSR_ECI);
+        reg |= PCNET_CSR_ECI_SPND;
+        put_reg(sc, PCNET_CSR_ECI, reg);
+        // Wait for device to suspend
+        do {
+            reg = get_reg(sc, PCNET_CSR_ECI);
+        } while (0 == (reg & PCNET_CSR_ECI_SPND));
+        cpd->active = 0;
+    }
+
+#ifdef CYGPKG_NET
+    if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+         != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+        ) || (ifp->if_flags & IFF_PROMISC)
+        ) {
+        // Then we select promiscuous mode.
+        cyg_uint16 rcr;
+        rcr = get_reg(sc, PCNET_CSR_MODE );
+        rcr |= PCNET_CSR_MODE_PROM;
+        put_reg(sc, PCNET_CSR_MODE, rcr );
+    }
+#endif
+
+    // Unsuspend the device
+    reg = get_reg(sc, PCNET_CSR_ECI);
+    reg &= ~PCNET_CSR_ECI_SPND;
+    put_reg(sc, PCNET_CSR_ECI, reg);
+    cpd->active = 1;
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+pcnet_control(struct eth_drv_sc *sc, unsigned long key,
+               void *data, int data_length)
+{
+    cyg_uint8 *esa = (cyg_uint8 *)data;
+    int i, res;
+    cyg_uint16 reg;
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+    cyg_bool was_active = cpd->active;
+
+    DEBUG_FUNCTION();
+
+    // If device is already active, suspend it
+    if (cpd->active) {
+        reg = get_reg(sc, PCNET_CSR_ECI);
+        reg |= PCNET_CSR_ECI_SPND;
+        put_reg(sc, PCNET_CSR_ECI, reg);
+        // Wait for device to suspend
+        do {
+            reg = get_reg(sc, PCNET_CSR_ECI);
+        } while (0 == (reg & PCNET_CSR_ECI_SPND));
+        cpd->active = 0;
+    }
+
+    res = 0;                            // expect success
+    switch (key) {
+    case ETH_DRV_SET_MAC_ADDRESS:
+#if 9 & DEBUG
+        diag_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] );
+#endif // DEBUG
+
+        for ( i = 0; i < sizeof(cpd->esa);  i++ )
+            cpd->esa[i] = esa[i];
+        for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
+            reg = cpd->esa[i] | (cpd->esa[i+1] << 8);
+            put_reg(sc, PCNET_CSR_PAR0+i/2, reg );
+        }
+        break;
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+    case ETH_DRV_GET_MAC_ADDRESS:
+        // Extract the MAC address that is in the chip, and tell the
+        // system about it.
+        for (i = 0;  i < sizeof(cpd->esa);  i += 2) {
+            cyg_uint16 z = get_reg(sc, PCNET_CSR_PAR0+i/2 );
+            esa[i] =   (cyg_uint8)(0xff & z);
+            esa[i+1] = (cyg_uint8)(0xff & (z >> 8));
+        }
+        break;
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+    case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+        // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+    case ETH_DRV_GET_IF_STATS:
+#endif
+
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+    {
+        cyg_uint16 anr;
+        struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+        // Chipset entry is no longer supported; RFC1573.
+        for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+            p->snmp_chipset[i] = 0;
+
+        // This perhaps should be a config opt, so you can make up your own
+        // description, or supply it from the instantiation.
+        strcpy( p->description, "AMD PCNet" );
+        // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+        anr = get_reg(sc, PCNET_ANR_PHYSTAT);
+        if ((anr & PCNET_ANR_PHYSTAT_LINK) == 0) {
+            p->operational = 2;         // LINK DOWN
+            p->duplex = 1;              // UNKNOWN
+            p->speed = 0;
+        }
+        else {
+            p->operational = 3;         // LINK UP
+            anr = get_reg(sc, PCNET_ANR_PHYCTRL);
+
+            if (anr & PCNET_ANR_PHYCTRL_DUPLEX)
+                p->duplex = 3;              // 3 = DUPLEX
+            else
+                p->duplex = 2;              // 2 = SIMPLEX
+            p->speed = (anr & PCNET_ANR_PHYCTRL_100MBPS) ? 100 * 1000000 : 10 * 1000000;
+        }
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+        {
+            struct amd_pcnet_stats *ps = &(cpd->stats);
+
+            // Admit to it...
+            p->supports_dot3        = true;
+
+            p->tx_good              = ps->tx_good             ;
+            p->tx_max_collisions    = ps->tx_max_collisions   ;
+            p->tx_late_collisions   = ps->tx_late_collisions  ;
+            p->tx_underrun          = ps->tx_underrun         ;
+            p->tx_carrier_loss      = ps->tx_carrier_loss     ;
+            p->tx_deferred          = ps->tx_deferred         ;
+            p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
+            p->tx_single_collisions = ps->tx_single_collisions;
+            p->tx_mult_collisions   = ps->tx_mult_collisions  ;
+            p->tx_total_collisions  = ps->tx_total_collisions ;
+            p->rx_good              = ps->rx_good             ;
+            p->rx_crc_errors        = ps->rx_crc_errors       ;
+            p->rx_align_errors      = ps->rx_align_errors     ;
+            p->rx_resource_errors   = ps->rx_resource_errors  ;
+            p->rx_overrun_errors    = ps->rx_overrun_errors   ;
+            p->rx_collisions        = ps->rx_collisions       ;
+            p->rx_short_frames      = ps->rx_short_frames     ;
+            p->rx_too_long_frames   = ps->rx_too_long_frames  ;
+            p->rx_symbol_errors     = ps->rx_symbol_errors    ;
+        
+            p->interrupts           = ps->interrupts          ;
+            p->rx_count             = ps->rx_count            ;
+            p->rx_deliver           = ps->rx_deliver          ;
+            p->rx_resource          = ps->rx_resource         ;
+            p->rx_restart           = ps->rx_restart          ;
+            p->tx_count             = ps->tx_count            ;
+            p->tx_complete          = ps->tx_complete         ;
+            p->tx_dropped           = ps->tx_dropped          ;
+        }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+        p->tx_queue_len = 1;
+        break;
+    }
+#endif
+    default:
+        res = 1;
+        break;
+    }
+
+    // Restore controller state
+    if (was_active) {
+        // Unsuspend the device
+        reg = get_reg(sc, PCNET_CSR_ECI);
+        reg &= ~PCNET_CSR_ECI_SPND;
+        put_reg(sc, PCNET_CSR_ECI, reg);
+    }
+
+    return res;
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+pcnet_can_send(struct eth_drv_sc *sc)
+{
+    struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+    cyg_uint16 stat;
+
+    DEBUG_FUNCTION();
+
+    stat = get_reg(sc, PCNET_ANR_PHYSTAT);
+    if ((stat & PCNET_ANR_PHYSTAT_LINK) == 0) {
+        return 0;                       // Link not connected
+    }
+
+    return (0 == cpd->txbusy);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void 
+pcnet_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, 
+            int total_len, unsigned long key)
+{
+    struct pcnet_priv_data *cpd = 
+        (struct pcnet_priv_data *)sc->driver_private;
+    int i, len, plen, ring_entry;
+
+    cyg_uint8* sdata = NULL;
+    cyg_uint8 *d, *buf, *txd;
+    cyg_uint16 ints;
+    cyg_uint32 b;
+
+    DEBUG_FUNCTION();
+
+    INCR_STAT( tx_count );
+
+    cpd->txbusy = 1;
+    cpd->txkey = key;
+
+    // Find packet length
+    plen = 0;
+    for (i = 0;  i < sg_len;  i++)
+        plen += sg_list[i].len;
+
+    CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+    
+    // Get next TX descriptor
+    ring_entry = cpd->tx_ring_free;
+    do {
+        if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
+            // Is this a dead end? Probably is.
+#if DEBUG & 1
+            diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+#endif
+            continue;
+        }
+
+        cpd->tx_ring_free++;
+        cpd->tx_ring_owned++;
+        if (cpd->tx_ring_free == cpd->tx_ring_cnt)
+            cpd->tx_ring_free = 0;
+    } while (0);
+
+    txd = cpd->tx_ring + ring_entry*PCNET_TD_SIZE;
+    buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
+    CYG_ASSERT(0 == (_SU32(txd, PCNET_TD_PTR) & PCNET_TD_PTR_OWN),
+               "TX descriptor not free");
+
+#if DEBUG & 4
+    diag_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
+                txd, buf);
+#endif
+
+    // Put data into buffer
+    d = buf;
+    for (i = 0;  i < sg_len;  i++) {
+        sdata = (cyg_uint8 *)sg_list[i].buf;
+        len = sg_list[i].len;
+
+        CYG_ASSERT( sdata, "No sg data pointer here" );
+        while(len--)
+            *d++ = *sdata++;
+    }
+    CYG_ASSERT( sdata, "No sg data pointer outside" );
+
+#if DEBUG & 1
+    diag_printf("CSCR %04x\n", get_reg(sc, PCNET_CSR_CSCR));
+#endif
+    _SU16(txd, PCNET_TD_LEN) = (-plen);
+    _SU16(txd, PCNET_TD_MISC) = 0;
+    HAL_PCI_CPU_TO_BUS(buf, b);
+    _SU32(txd, PCNET_TD_PTR) = ((b & PCNET_TD_PTR_MASK)
+                                | PCNET_TD_PTR_OWN | PCNET_TD_PTR_STP | PCNET_TD_PTR_ENP);
+
+#if DEBUG & 1
+    cpd->txd = txd;
+    diag_printf("Last TX: LEN %04x MISC %04x PTR %08x\n", 
+                _SU16(cpd->txd, PCNET_TD_LEN),
+                _SU16(cpd->txd, PCNET_TD_MISC),
+                _SU32(cpd->txd, PCNET_TD_PTR));
+#endif
+
+    // Set transmit demand
+    ints = get_reg(sc, PCNET_CSR_CSCR);
+    ints &= PCNET_CSR_CSCR_EV_MASK;
+    ints |= PCNET_CSR_CSCR_TDMD;
+    put_reg(sc, PCNET_CSR_CSCR, ints);
+
+#if DEBUG & 1
+    ints = get_reg(sc, PCNET_CSR_CSCR);
+    diag_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints);
+#endif
+}
+
+static void
+pcnet_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+     struct pcnet_priv_data *cpd =
+        (struct pcnet_priv_data *)sc->driver_private;
+    int success = 1;
+    cyg_uint8 *txd;
+    cyg_uint16 ints;
+    cyg_uint32 pkt_stat;
+
+    DEBUG_FUNCTION();
+
+    INCR_STAT( tx_complete );
+
+    txd = cpd->tx_ring + cpd->tx_ring_alloc*PCNET_TD_SIZE;
+    pkt_stat = _SU32(txd, PCNET_TD_PTR);
+    if (pkt_stat & PCNET_TD_PTR_OWN) {
+#if DEBUG & 1
+        diag_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
+#endif
+        // first dirty ring entry not freed - wtf?
+    }
+
+    if (pkt_stat & PCNET_TD_PTR_ERR) {
+        // We had an error. Tell the stack.
+        success = 0;
+#if DEBUG & 1
+        diag_printf("%s: TX failure, retrying...\n", __FUNCTION__);
+#endif
+    }
+
+    cpd->tx_ring_alloc++;
+    if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
+        cpd->tx_ring_alloc = 0;
+    cpd->tx_ring_owned--;
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+    {
+        cyg_uint16 reg;
+
+        reg = get_reg( sc, PCNET_CSR_CSCR );
+        
+        // Covering each bit in turn...
+        if ( reg & PCNET_STATUS_TX_UNRN   ) INCR_STAT( tx_underrun );
+        //if ( reg & PCNET_STATUS_LINK_OK ) INCR_STAT(  );
+        //if ( reg & PCNET_STATUS_CTR_ROL ) INCR_STAT(  );
+        //if ( reg & PCNET_STATUS_EXC_DEF ) INCR_STAT(  );
+        if ( reg & PCNET_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
+        if ( reg & PCNET_STATUS_LATCOL    ) INCR_STAT( tx_late_collisions );
+        //if ( reg & PCNET_STATUS_WAKEUP  ) INCR_STAT(  );
+        if ( reg & PCNET_STATUS_TX_DEFR   ) INCR_STAT( tx_deferred );
+        //if ( reg & PCNET_STATUS_LTX_BRD ) INCR_STAT(  );
+        if ( reg & PCNET_STATUS_SQET      ) INCR_STAT( tx_sqetesterrors );
+        if ( reg & PCNET_STATUS_16COL     ) INCR_STAT( tx_max_collisions );
+        //if ( reg & PCNET_STATUS_LTX_MULT) INCR_STAT(  );
+        if ( reg & PCNET_STATUS_MUL_COL   ) INCR_STAT( tx_mult_collisions );
+        if ( reg & PCNET_STATUS_SNGL_COL  ) INCR_STAT( tx_single_collisions );
+        if ( reg & PCNET_STATUS_TX_SUC    ) INCR_STAT( tx_good );
+
+        cpd->stats.tx_total_collisions = 
+            cpd->stats.tx_late_collisions + 
+            cpd->stats.tx_max_collisions + 
+            cpd->stats.tx_mult_collisions + 
+            cpd->stats.tx_single_collisions;
+
+        // We do not need to look in the Counter Register (PCNET_COUNTER)
+        // because it just mimics the info we already have above.
+    }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+    // Ack the TX int which clears the packet from the TX completion
+    // queue.
+    ints = get_reg(sc, PCNET_CSR_CSCR);
+    ints |= PCNET_CSR_CSCR_TINT;
+    put_reg(sc, PCNET_CSR_CSCR, ints);
+
+#if DEBUG & 4
+    diag_printf("#####Tx packet freed 0x%08x\n", txd );
+#endif
+
+    if ( cpd->txbusy ) {
+        cpd->txbusy = 0;
+        (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+    }
+}
+
+
+//
+// This function is called when a packet has been received.  Its job is
+// to prepare to unload the packet from the hardware.  Once the length of
+// the packet is known, the upper layer of the driver can be told.  When
+// the upper layer is ready to unload the packet, the internal function
+// 'pcnet_recv' will be called to actually fetch it from the hardware.
+//
+static void
+pcnet_RxEvent(struct eth_drv_sc *sc)
+{
+    struct pcnet_priv_data *cpd = 
+        (struct pcnet_priv_data *)sc->driver_private;
+    cyg_uint8 *rxd;
+    cyg_uint32 rstat;
+    cyg_uint16 ints, len;
+
+    DEBUG_FUNCTION();
+
+    ints = get_reg(sc, PCNET_CSR_CSCR);
+#if DEBUG & 1
+    diag_printf("RxEvent - CSR: 0x%04x\n", ints);
+#endif
+
+    while (1) {
+        // Get state of next (supposedly) full ring entry
+        cpd->rxpacket = cpd->rx_ring_next;
+        rxd = cpd->rx_ring + cpd->rxpacket*PCNET_RD_SIZE;
+        rstat = _SU32(rxd, PCNET_RD_PTR);
+
+        // Keep going until we hit an entry that is owned by the
+        // controller.
+        if (rstat & PCNET_RD_PTR_OWN) {
+#if DEBUG & 1
+            int i;
+            for (i = 0; i < cpd->rx_ring_cnt; i++) {
+                rxd = cpd->rx_ring + i*PCNET_RD_SIZE;
+                rstat = _SU32(rxd, PCNET_RD_PTR);
+
+                if (!(rstat & PCNET_RD_PTR_OWN)) {
+                    int i;
+                    cyg_uint32 rstat;
+                    cyg_uint16 mlen, blen;
+                    cyg_uint8* rxd;
+
+                    diag_printf("%s: Inconsistent RX state\n", __FUNCTION__);
+                    for (i = 0; i < cpd->rx_ring_cnt; i++) {
+                        rxd = cpd->rx_ring + i*PCNET_RD_SIZE;
+                
+                        rstat = _SU32(rxd, PCNET_RD_PTR);
+                        blen = _SU16(rxd, PCNET_RD_BLEN);
+                        mlen = _SU16(rxd, PCNET_RD_MLEN);
+                        diag_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+                    }
+                }
+            }
+#endif
+            break;
+        }
+
+#if DEBUG & 4
+        diag_printf("#####Rx packet at index %d\n", cpd->rxpacket);
+#endif
+
+        // Increment counts
+        INCR_STAT( rx_count );
+        cpd->rx_ring_next++;
+        if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
+
+        len = _SU16(rxd, PCNET_RD_MLEN);
+
+#ifdef KEEP_STATISTICS
+        //if ( rstat & PCNET_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors );
+        //if ( rstat & PCNET_RD_PTR_OFLO ) INCR_STAT(  );
+        if ( rstat & PCNET_RD_PTR_CRC ) INCR_STAT( rx_crc_errors );
+        //if ( rstat & PCNET_RD_PTR_BUFF ) INCR_STAT(  );
+#endif // KEEP_STATISTICS
+
+        if (0 == (rstat & PCNET_RD_PTR_ERR)) {
+            // It's OK
+            INCR_STAT( rx_good );
+
+#if DEBUG & 1
+            diag_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+#endif
+            // Check for bogusly short packets; can happen in promisc
+            // mode: Asserted against and checked by upper layer
+            // driver.
+#ifdef CYGPKG_NET
+            if ( len > sizeof( struct ether_header ) )
+                // then it is acceptable; offer the data to the network stack
+#endif
+                (sc->funs->eth_drv->recv)(sc, len);
+        } else {
+            // Not OK for one reason or another...
+#if DEBUG & 1
+            diag_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+                        rstat, len);
+#endif
+        }
+
+        // Free packet (clear all status flags, and set OWN)
+        _SU32(rxd, PCNET_RD_PTR) &= PCNET_RD_PTR_MASK;
+        _SU32(rxd, PCNET_RD_PTR) |= PCNET_RD_PTR_OWN;
+    }
+
+    // Ack RX interrupt set
+    ints = get_reg(sc, PCNET_CSR_CSCR);
+    ints &= PCNET_CSR_CSCR_EV_MASK;
+    ints |= PCNET_CSR_CSCR_RINT;
+    put_reg(sc, PCNET_CSR_CSCR, ints);
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// Its job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet.  Note that the buffers
+// may come in pieces, using a scatter-gather list.  This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+pcnet_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+    struct pcnet_priv_data *cpd = 
+        (struct pcnet_priv_data *)sc->driver_private;
+    int i, mlen=0, plen;
+    cyg_uint8 *data, *rxd, *buf;
+
+    DEBUG_FUNCTION();
+
+    rxd = cpd->rx_ring + cpd->rxpacket*PCNET_TD_SIZE;
+    buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+
+    INCR_STAT( rx_deliver );
+
+    plen = _SU16(rxd, PCNET_RD_MLEN);
+
+    for (i = 0;  i < sg_len;  i++) {
+        data = (cyg_uint8*)sg_list[i].buf;
+        mlen = sg_list[i].len;
+
+#if DEBUG & 1
+        diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+#endif
+        if (data) {
+            while (mlen > 0) {
+                *data++ = *buf++;
+                mlen--;
+                plen--;
+            }
+        }
+    }
+}
+
+static void
+pcnet_poll(struct eth_drv_sc *sc)
+{
+    cyg_uint16 event;
+
+//  DEBUG_FUNCTION();
+
+    while (1) {
+        // Get the (unmasked) requests
+        event = get_reg(sc, PCNET_CSR_CSCR);
+        if (!((PCNET_CSR_CSCR_ERR|PCNET_CSR_CSCR_INTR) & event))
+            break;
+
+        if (event & PCNET_CSR_CSCR_RINT) {
+            pcnet_RxEvent(sc);
+        }
+        else if (event & PCNET_CSR_CSCR_TINT) {
+            pcnet_TxEvent(sc, event);
+        } 
+        else if (event & PCNET_CSR_CSCR_MISS) {
+#if DEBUG & 1
+            int i;
+            cyg_uint32 rstat;
+            cyg_uint16 mlen, blen;
+            cyg_uint8* rxd;
+            struct pcnet_priv_data *cpd = 
+                (struct pcnet_priv_data *)sc->driver_private;
+
+            diag_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+            for (i = 0; i < cpd->rx_ring_cnt; i++) {
+                rxd = cpd->rx_ring + i*PCNET_TD_SIZE;
+                
+                rstat = _SU32(rxd, PCNET_RD_PTR);
+                blen = _SU16(rxd, PCNET_RD_BLEN);
+                mlen = _SU16(rxd, PCNET_RD_MLEN);
+                diag_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+            }
+#endif
+            event &= PCNET_CSR_CSCR_EV_MASK;
+            event |= PCNET_CSR_CSCR_MISS;
+            put_reg(sc, PCNET_CSR_CSCR, event);
+        }
+        else {
+#if DEBUG & 1
+            diag_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+#endif
+            put_reg(sc, PCNET_CSR_CSCR, event);
+        }
+    }
+}
+
+// EOF if_pcnet.c
--- a/packages/devs/eth/arm/ebsa285/current/ChangeLog
+++ b/packages/devs/eth/arm/ebsa285/current/ChangeLog
@@ -1,3 +1,17 @@
+2001-08-31  Hugo Tyson  <hmt@redhat.com>
+2001-08-31  Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+	* src/if_ebsa285.c (TxDone): Check from prev change is moved to
+	the logical driver.  Also, we zero the key in global state before
+	the callback - this should make no difference, but again it's good
+	practice, and ASCOM's tests indicate a benefit for CASE 106059.
+	
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_ebsa285.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-06-08  Gary Thomas  <gthomas@redhat.com>
 
 	* src/if_ebsa285.c (TxDone): Defensive programming: only call
--- a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
+++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c
@@ -70,7 +70,6 @@
 #include <net/if.h>  /* Needed for struct ifnet */
 #else
 #include <cyg/hal/hal_if.h>
-#define diag_printf printf
 #endif
 
 #ifdef CYGPKG_IO_PCI
@@ -1490,14 +1489,14 @@ static void TxDone(struct i82559* p_i825
              ( p_i82559->tx_queue_full &&
               (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->txstatus) ) ) {
         unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ];
+        // Zero the key in global state before the callback:
+        p_i82559->tx_keys[ tx_descriptor_remove ] = 0;
 #ifdef DEBUG_82559
         os_printf("TxDone %d %x: KEY %x\n",
                   p_i82559->index, (int)p_i82559, key );
 #endif
-        if (key) {
-            (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ ); 
-        }
-        p_i82559->tx_keys[ tx_descriptor_remove ] = 0;
+        // tx_done() can now cope with a NULL key, no guard needed here
+        (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ ); 
         
         if ( ++tx_descriptor_remove >= MAX_TX_DESCRIPTORS )
             tx_descriptor_remove = 0;
--- a/packages/devs/eth/arm/iq80310/current/ChangeLog
+++ b/packages/devs/eth/arm/iq80310/current/ChangeLog
@@ -1,3 +1,14 @@
+2001-08-24  Mark Salter  <msalter@redhat.com>
+
+	* src/if_iq80310.c (PacketRxReady): Break out of Rx loop after
+	one packet is delivered for RedBoot.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_iq80310.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-08-15  Mark Salter  <msalter@redhat.com>
 
 	* src/if_iq80310.c: Use 32-bit access to MDI. Problem discovered
@@ -39,7 +50,7 @@ 2000-11-06  Mark Salter  <msalter@redhat
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/devs/eth/arm/iq80310/current/src/if_iq80310.c
+++ b/packages/devs/eth/arm/iq80310/current/src/if_iq80310.c
@@ -72,7 +72,6 @@
 #include <net/if.h>  /* Needed for struct ifnet */
 #else
 #include <cyg/hal/hal_if.h>
-#define diag_printf printf
 #endif
 
 #ifdef CYGPKG_IO_PCI
@@ -1469,6 +1468,10 @@ static void PacketRxReady(struct i82559*
 
         CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
         CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
+#ifdef CYGPKG_REDBOOT
+	// Need to make this decision at runtime.
+	break;
+#endif
     }
 
     // See if the RU has gone idle (usually because of out of resource
--- a/packages/devs/eth/cf/current/ChangeLog
+++ b/packages/devs/eth/cf/current/ChangeLog
@@ -1,3 +1,13 @@
+2001-08-25  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_sc_lpe.c (sc_lpe_card_handler): Rework ESA discovery code.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_sc_lpe.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-06-16  Jesper Skov  <jskov@redhat.com>
 
 	* src/if_sc_lpe.c: Use generic DP83902A driver, only redefining
@@ -114,7 +124,7 @@ 2000-07-14  Gary Thomas  <gthomas@redhat
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/devs/eth/cf/current/src/if_sc_lpe.c
+++ b/packages/devs/eth/cf/current/src/if_sc_lpe.c
@@ -65,7 +65,6 @@
 #include <pkgconf/net.h>
 #else
 #include <cyg/hal/hal_if.h>
-#define diag_printf printf
 #endif
 
 #include <cyg/io/dp83902a.h>
@@ -159,7 +158,7 @@ sc_lpe_card_handler(cyg_addrword_t param
                 while (*cp++) ;  // Skip to nul
                 vers_date = cp;
 #ifndef CYGPKG_NET
-                if (tries != 0) printf("\n");
+                if (tries != 0) diag_printf("\n");
                 diag_printf("%s: %s %s %s\n", vers_manuf, vers_product, vers_revision, vers_date);
 #endif
             }
@@ -174,23 +173,6 @@ sc_lpe_card_handler(cyg_addrword_t param
                 continue;
             }
 
-            // Fetch hardware address from card - terrible, but not well defined
-            // Note: at least one card has been known to not have a valid ESA anywhere
-            if (!dp->hardwired_esa) {
-                if (slot->attr[0x1C0] != (unsigned char)0xFF) {
-                    for (i = 0;  i < ETHER_ADDR_LEN;  i++)
-                        dp->esa[i] = slot->attr[0x1C0+(i*2)];
-                } else {
-                    diag_printf("No valid ESA found in CIS! Hardwiring to 08:88:87:65:43:21\n");
-                    dp->esa[0] = 0x08;
-                    dp->esa[1] = 0x88;
-                    dp->esa[2] = 0x87;
-                    dp->esa[3] = 0x65;
-                    dp->esa[4] = 0x43;
-                    dp->esa[5] = 0x21;
-                }
-            }
-
             ptr = 0;
             if (cf_get_CIS(slot, CF_CISTPL_CFTABLE_ENTRY, buf, &len, &ptr)) {
                 if (cf_parse_cftable(buf, len, &cftable)) {
@@ -207,6 +189,53 @@ sc_lpe_card_handler(cyg_addrword_t param
                     do {
                         DP_IN(base, DP_ISR, tmp);
                     } while (0 == (tmp & DP_ISR_RESET));
+
+                    // Fetch hardware address from card - terrible, but not well defined
+                    // Patterned after what Linux drivers do
+                    if (!dp->hardwired_esa) {
+                        static unsigned char sc_lpe_addr[] = { 0x00, 0xC0, 0x1B, 0x00, 0x99, 0x9E};
+                        if ((slot->attr[0x1C0] == sc_lpe_addr[0]) &&
+                            (slot->attr[0x1C2] == sc_lpe_addr[1]) &&
+                            (slot->attr[0x1C4] == sc_lpe_addr[2])) {
+                            sc_lpe_addr[3] = slot->attr[0x1C6];
+                            sc_lpe_addr[4] = slot->attr[0x1C8];
+                            sc_lpe_addr[5] = slot->attr[0x1CA];
+                        } else {
+                            // Coudn't find it in the CIS (attribute) data
+                            unsigned char prom[32];
+
+                            // Tell device to give up ESA
+                            DP_OUT(base, DP_DCR, 0x48);  // Bytewide access
+                            DP_OUT(base, DP_RBCH, 0);    // Remote byte count
+                            DP_OUT(base, DP_RBCL, 0);
+                            DP_OUT(base, DP_ISR, 0xFF);  // Clear any pending interrupts
+                            DP_OUT(base, DP_IMR, 0x00);  // Mask all interrupts 
+                            DP_OUT(base, DP_RCR, 0x20);  // Monitor
+                            DP_OUT(base, DP_TCR, 0x02);  // loopback
+                            DP_OUT(base, DP_RBCH, 32);   // Remote byte count
+                            DP_OUT(base, DP_RBCL, 0);
+                            DP_OUT(base, DP_RSAL, 0);    // Remote address
+                            DP_OUT(base, DP_RSAH, 0);
+                            DP_OUT(base, DP_CR, DP_CR_START|DP_CR_RDMA);  // Read data
+                            for (i = 0;  i < 32;  i++) {
+                                HAL_READ_UINT8(base+DP_DATAPORT, prom[i]);
+                            }
+                            if ((prom[0] == sc_lpe_addr[0]) &&
+                                (prom[2] == sc_lpe_addr[1]) &&
+                                (prom[4] == sc_lpe_addr[2])) {
+                                diag_printf("Getting address from port\n");
+                                sc_lpe_addr[3] = prom[6];
+                                sc_lpe_addr[4] = prom[8];
+                                sc_lpe_addr[5] = prom[10];
+                            } else {
+                                diag_printf("No valid ESA found in CIS! Hardwiring to 00:C0:1B:00:99:9E\n");
+                            }
+                        }
+                        for (i = 0;  i < 6;  i++) {
+                            dp->esa[i] = sc_lpe_addr[i];
+                        }
+                    }
+
                     // Initialize upper level driver
                     (sc->funs->eth_drv->init)(sc, dp->esa);
                     // Tell system card is ready to talk
@@ -229,8 +258,8 @@ sc_lpe_card_handler(cyg_addrword_t param
             cyg_drv_dsr_unlock();
             do_delay(50);  // FIXME!
 #ifndef CYGPKG_NET
-            if (tries == 0) printf("... Waiting for network card: ");
-            printf(".");
+            if (tries == 0) diag_printf("... Waiting for network card: ");
+            diag_printf(".");
             if (++tries == 10) {
                 // 5 seconds have elapsed - give up
                 return false;
--- a/packages/devs/eth/intel/i82559/current/ChangeLog
+++ b/packages/devs/eth/intel/i82559/current/ChangeLog
@@ -1,3 +1,29 @@
+2001-08-29  Hugo Tyson  <hmt@redhat.com>
+
+	* cdl/intel_i82559_eth_drivers.cdl: New CDL options called 
+	CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD, .._PRIORITY and
+	.._DELAY to control the thread.  By default this is all disabled
+	because it is not needed for a real network application which
+	itself proactively tries to use the net - it's only needed when
+	the app is totally passive, so the driver otherwise does not get
+	CPU time at all.
+	
+	* src/if_i82559.c (starti82559ticklethread): New code to start a
+	thread (!) to catch lost interrupts and thus restart jammed
+	hardware.  It's only possible if KERNEL and NET - RedBoot is
+	unaffected, and it's not needed for RedBoot 'cos RedBoot polls.
+	(TxMachine): An assert about the CU idle status sometimes fired;
+	made the code more conservative wrt timing here.
+	(comments): more documentation on the possible external configury
+	by .inl file, described the two TIMEOUT macros that can be set,
+	and indeed must be to use the tickling thread meaningfully.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_i82559.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-06-22  Jesper Skov  <jskov@redhat.com>
 
 	* src/if_i82559.c (i82559_init): Handle EEPROMS without CRC.
@@ -629,7 +655,7 @@ 2000-02-08  Hugo Tyson  <hmt@cygnus.co.u
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl
+++ b/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl
@@ -136,5 +136,41 @@ cdl_package CYGPKG_DEVS_ETH_INTEL_I82559
                 global flags."
         }
     }
+
+    cdl_component CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD {
+        display "Create a thread to 'unstick' from lost interrupts"
+        active_if CYGPKG_KERNEL
+        active_if CYGPKG_NET
+        default_value 0
+        description "
+            If this is enabled, the driver creates a thread to tickle the
+            device(s) periodically, to unblock them when the hardware has
+            become wedged due to a lost interrupt or other hardware
+            race-condition type problem.
+            This is not necessary if a networked app is running, provided
+            that it tries to send packets itself from time to time - or
+            uses TCP, or amy similar protocol which exchanges keep-alive
+            packets periodically and often enough.
+            Trying to send a packet passes control into the driver; this is
+            sufficient to detect and unblock jammed hardware."
+
+        cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_PRIORITY {
+            display "Priority of i82559 tickle thread"
+            flavor data
+            default_value CYGPKG_NET_THREAD_PRIORITY + 2
+            description "
+                The default is two below the net thread, which is one below
+                the default prio of the DHCP thread."
+        }
+
+        cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_DELAY {
+            display "Delay in kernel clocks of i82559 tickle loop"
+            flavor data
+            default_value 50
+            description "
+                The default is 50, which will usually mean a delay between
+                tests for 'stuck' devices of 500mS, that is half a second."
+        }
+    }
 }
 # EOF intel_i82559_eth_drivers.cdl
--- a/packages/devs/eth/intel/i82559/current/src/if_i82559.c
+++ b/packages/devs/eth/intel/i82559/current/src/if_i82559.c
@@ -114,6 +114,13 @@
 //               allocated chunk who appears to contain such a break, and
 //               tries again.
 //
+//               CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT( int32 )
+//               CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED( int32 ) if
+//               both defined give the driver a means to detect that we
+//               have been fixated on the same transmit operation for too
+//               long - we missed an interrupt or the device crashed.  The
+//               int32 argument is used to hold a eg. the value of a
+//               fast-running hardware timer.
 //
 //        FIXME: replace -1/-2 return values with proper E-defines
 //        FIXME: For 82557/8 compatibility i82559_configure() function
@@ -143,8 +150,6 @@
 #ifdef CYGPKG_NET
 #include <pkgconf/net.h>
 #include <net/if.h>  /* Needed for struct ifnet */
-#else
-#define diag_printf printf
 #endif
 
 #ifdef CYGPKG_IO_PCI
@@ -214,7 +219,8 @@ static struct {
     int waitcmd_timeouts;
     int waitcmd_timeouts_cu;
     int lockup_timeouts;
-} missed_interrupt = { 0,0,0, 0,0, 0 };
+    int bad_cu_idles;
+} missed_interrupt = { 0,0,0, 0,0, 0, 0 };
 #endif
 
 #define os_printf diag_printf
@@ -853,6 +859,17 @@ static int
 write_enable_eeprom(long ioaddr,  int addr_len);
 #endif
 
+#ifdef CYGPKG_KERNEL
+#ifdef CYGPKG_NET
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD
+
+static void
+starti82559ticklethread( void );
+
+#endif // CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD
+#endif // CYGPKG_NET
+#endif // CYGPKG_KERNEL
+
 // debugging/logging only:
 void dump_txcb(TxCB* p_txcb);
 void DisplayStatistics(void);
@@ -1295,6 +1312,15 @@ i82559_init(struct cyg_netdevtab_entry *
 #endif
             return 0;
         }
+#ifdef CYGPKG_KERNEL
+#ifdef CYGPKG_NET
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD
+
+        starti82559ticklethread();
+
+#endif // CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD
+#endif // CYGPKG_NET
+#endif // CYGPKG_KERNEL
     }
 
     // If this device is not present, exit
@@ -2034,7 +2060,16 @@ TxMachine(struct i82559* p_i82559)
         // start Tx operation
         wait_for_cmd_done(ioaddr, WAIT_CU);
         status = INW(ioaddr + SCBStatus);
-
+        // The following assert sometimes fires here, apparantly harmless!
+        // So check a second time to let the cursed thing settle and not
+        // tell us lies.
+        if ( 0 != (status & CU_STATUS_MASK) ) {
+#ifdef CYGDBG_USE_ASSERTS
+            missed_interrupt.bad_cu_idles++;
+#endif
+            wait_for_cmd_done(ioaddr, WAIT_CU);
+            status = INW(ioaddr + SCBStatus);
+        }
         CYG_ASSERT( ( 0 == (status & CU_STATUS_MASK)), "CU not idle");
         CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
         CYG_ASSERT( (cyg_uint8 *)p_txcb <  i82559_heap_free, "txcb over" );
@@ -3547,4 +3582,90 @@ update_statistics(struct i82559* p_i8255
 
 // ------------------------------------------------------------------------
 
+#ifdef CYGPKG_KERNEL
+#ifdef CYGPKG_NET
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD
+
+// Then we create a thread to tickle the device(s) periodically
+// to unblock them when the hardware has become wedged.
+// 
+// This is not necessary if a networked app is running, provided that it
+// tries to "send stuff" itself from time to time - or uses TCP, or amy
+// similar protocol which exchanges "keep-alive" packets periodically and
+// often enough.
+
+#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL)
+static char i82559tickle_stack[STACK_SIZE];
+static cyg_thread i82559tickle_thread_data;
+static cyg_handle_t i82559tickle_thread_handle;
+
+static int
+Poll82559ForTxLockupTimeout( void )
+{
+    struct eth_drv_sc *sc;
+    struct cyg_netdevtab_entry *ndp;
+    struct i82559 *p_i82559;
+    int i;
+#ifdef CYGDBG_USE_ASSERTS
+    int lockto = missed_interrupt.lockup_timeouts;
+#endif
+    for ( i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++ ) {
+        p_i82559 = i82559_priv_array[i];
+        ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+        sc = (struct eth_drv_sc *)(ndp->device_instance);
+        if ( p_i82559->active )
+            (void)i82559_can_send( sc ); // This is a neat way to advance
+    }
+    return 
+#ifdef CYGDBG_USE_ASSERTS
+        (missed_interrupt.lockup_timeouts - lockto)
+#endif
+        +0;
+}
+
+static void
+i82559tickle( cyg_addrword_t param )
+{
+    int spl, to;
+
+    while( 1 ) {
+        cyg_thread_delay(CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_DELAY);
+
+        spl = splnet();
+        to = Poll82559ForTxLockupTimeout();
+        splx(spl);
+
+#ifdef DEBUG
+#ifdef CYGDBG_USE_ASSERTS
+        if ( to )
+            diag_printf( "###Lockup detected: %d this time, total %d\n",
+                         to, missed_interrupt.lockup_timeouts );
+#endif
+#endif
+    }
+}
+
+
+static void
+starti82559ticklethread( void )
+{
+    // Create background thread
+    cyg_thread_create(CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_PRIORITY,
+                      i82559tickle,                 // entry
+                      0,                            // entry parameter
+                      "i82559 ethernet tickle",     // Name
+                      &i82559tickle_stack[0],       // Stack
+                      STACK_SIZE,                   // Size
+                      &i82559tickle_thread_handle,  // Handle
+                      &i82559tickle_thread_data     // Thread data structure
+        );
+    cyg_thread_resume(i82559tickle_thread_handle);    // Start it
+}
+
+#endif // CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD
+#endif // CYGPKG_NET
+#endif // CYGPKG_KERNEL
+
+// ------------------------------------------------------------------------
+
 // EOF if_i82559.c
--- a/packages/devs/eth/ns/dp83902a/current/ChangeLog
+++ b/packages/devs/eth/ns/dp83902a/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-08-25  Gary Thomas  <gthomas@redhat.com>
+
+	* include/dp83902a.h (DP_DATAPORT): Add - used by ESA discovery
+	on SC/LPE card.
+
 2001-06-21  Jesper Skov  <jskov@redhat.com>
 
 	* src/if_dp83902a.c: Fix various build problems when net package
--- a/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h
+++ b/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h
@@ -228,6 +228,7 @@ static void dp83902a_poll(struct eth_drv
 #define DP_DCR         0x0e             // write
 #define DP_MISSED      0x0f
 #define DP_IMR         0x0f             // write
+#define DP_DATAPORT    0x10             // "eprom" data port
 
 #define DP_P1_CR       0x00
 #define DP_P1_PAR0     0x01
--- a/packages/devs/eth/powerpc/fec/current/ChangeLog
+++ b/packages/devs/eth/powerpc/fec/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_fec.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-06-26  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/if_fec.c (fec_eth_init): Use correct version register.
--- a/packages/devs/eth/powerpc/fec/current/src/if_fec.c
+++ b/packages/devs/eth/powerpc/fec/current/src/if_fec.c
@@ -89,11 +89,7 @@ RedBoot_config_option("Network hardware 
 #endif
 #endif
 
-#ifdef CYGPKG_REDBOOT
-#define os_printf printf
-#else
 #define os_printf diag_printf
-#endif
 
 // For fetching the ESA from RedBoot
 #include <cyg/hal/hal_if.h>
@@ -310,7 +306,7 @@ fec_eth_init(struct cyg_netdevtab_entry 
 #endif
     if (!esa_ok) {
         // Can't figure out ESA
-        diag_printf("FEC_ETH - Warning! ESA unknown\n");
+        os_printf("FEC_ETH - Warning! ESA unknown\n");
         memcpy(&enaddr, &_default_enaddr, sizeof(enaddr));
     }
     memcpy((void *)&fec->addr[0], &enaddr[0], sizeof(enaddr));
--- a/packages/devs/eth/powerpc/quicc/current/ChangeLog
+++ b/packages/devs/eth/powerpc/quicc/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/if_quicc.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-05-07  Gary Thomas  <gthomas@redhat.com>
 
 	* src/if_quicc.c (quicc_eth_init): Get ESA from RedBoot 'fconfig' data.
@@ -155,7 +161,7 @@ 2000-02-21  Gary Thomas  <gthomas@cygnus
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c
+++ b/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c
@@ -450,7 +450,7 @@ quicc_eth_send(struct eth_drv_sc *sc, st
 #ifdef CYGPKG_NET
             panic ("No free xmit buffers");
 #else
-            printf("QUICC Ethernet: No free xmit buffers\n");
+            diag_printf("QUICC Ethernet: No free xmit buffers\n");
 #endif
         }
     }
--- a/packages/devs/flash/intel/strata/current/ChangeLog
+++ b/packages/devs/flash/intel/strata/current/ChangeLog
@@ -1,3 +1,11 @@
+2001-08-25  Gary Thomas  <gthomas@redhat.com>
+
+	* src/flash_program_buf.c (flash_program_buf): Allow configuration
+	specific code sequence for actual writing of data.  Define by the
+	macro CYGHWR_FLASH_WRITE_ELEM.  Note: this is required on some
+	hardware, like the Intel SA185, which handles flash writes in
+	strange/obscure fashion.
+
 2001-07-17 Jeroen Dobbelaere  <jeroen.dobbelaere@acunia.com>
 
 	* src/flash_query.c (flash_query): Query needs to be done on even
--- a/packages/devs/flash/intel/strata/current/src/flash_program_buf.c
+++ b/packages/devs/flash/intel/strata/current/src/flash_program_buf.c
@@ -97,7 +97,11 @@ flash_program_buf(volatile flash_t *addr
         }
         *BA = FLASHWORD(wc-1);  // Count is 0..N-1
         for (i = 0;  i < wc;  i++) {
+#ifdef CYGHWR_FLASH_WRITE_ELEM
+            CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i);
+#else
             *(addr+i) = *(data+i);
+#endif
         }
         *BA = FLASH_Confirm;
     
@@ -125,7 +129,11 @@ flash_program_buf(volatile flash_t *addr
 
     while (len > 0) {
         ROM[0] = FLASH_Program;
+#ifdef CYGHWR_FLASH_WRITE_ELEM
+        CYGHWR_FLASH_WRITE_ELEM(addr, data);
+#else
         *addr = *data;
+#endif
         timeout = 5000000;
         while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
             if (--timeout == 0) {
--- a/packages/devs/kbd/arm/ipaq/current/ChangeLog
+++ b/packages/devs/kbd/arm/ipaq/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-29  Kenichi Nakamura  <nakamura@redhat.com>
+
+	* cdl/kbd_ipaq.cdl: Modified dependency on file I/O package.
+
 2001-04-24  Gary Thomas  <gthomas@redhat.com>
 
 	* cdl/kbd_ipaq.cdl: Add dependency on file I/O package.
--- a/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl
+++ b/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl
@@ -43,7 +43,7 @@ cdl_package CYGPKG_DEVS_KBD_IPAQ {
     display     "Keypad driver for iPAQ"
     include_dir cyg/io
 
-    active_if   CYGPKG_FILEIO
+    active_if   CYGPKG_IO_FILEIO
     requires    CYGPKG_IO
     requires    CYGFUN_KERNEL_API_C
     requires    CYGPKG_HAL_ARM_SA11X0_IPAQ
--- a/packages/devs/serial/arm/iq80310/current/ChangeLog
+++ b/packages/devs/serial/arm/iq80310/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-09-03  Jesper Skov  <jskov@redhat.com>
+
+	* include/arm_iq80310_ser.inl: Fix interrupt vector name typos.
+
 2000-10-25  Mark Salter  <msalter@redhat.com>
 
 	* include/arm_iq80310_ser.inl: Initial checkin.
--- a/packages/devs/serial/arm/iq80310/current/include/arm_iq80310_ser.inl
+++ b/packages/devs/serial/arm/iq80310/current/include/arm_iq80310_ser.inl
@@ -72,7 +72,7 @@ static unsigned short select_baud[] = {
 
 #ifdef CYGPKG_IO_SERIAL_ARM_IQ80310_SERIAL0
 static pc_serial_info iq80310_serial_info0 = {0xFE800000,
-                                          CYGNUM_HAL_INTERRUPT_SERIALA};
+                                          CYGNUM_HAL_INTERRUPT_SERIAL_A};
 #if CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL0_BUFSIZE > 0
 static unsigned char iq80310_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL0_BUFSIZE];
 static unsigned char iq80310_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL0_BUFSIZE];
@@ -112,7 +112,7 @@ DEVTAB_ENTRY(iq80310_serial_io0,
 
 #ifdef CYGPKG_IO_SERIAL_ARM_IQ80310_SERIAL1
 static pc_serial_info iq80310_serial_info1 = {0xFE810000,
-                                          CYGNUM_HAL_INTERRUPT_SERIALB};
+                                          CYGNUM_HAL_INTERRUPT_SERIAL_B};
 #if CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL1_BUFSIZE > 0
 static unsigned char iq80310_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL1_BUFSIZE];
 static unsigned char iq80310_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL1_BUFSIZE];
--- a/packages/devs/touch/arm/ipaq/current/ChangeLog
+++ b/packages/devs/touch/arm/ipaq/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-29  Kenichi Nakamura  <nakamura@redhat.com>
+
+        * cdl/touch_ipaq.cdl: Modified dependency on file I/O package.
+
 2001-04-24  Gary Thomas  <gthomas@redhat.com>
 
 	* cdl/touch_ipaq.cdl: Add dependency on file I/O package.
--- a/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl
+++ b/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl
@@ -43,7 +43,7 @@ cdl_package CYGPKG_DEVS_TOUCH_IPAQ {
     display     "Touch screen driver for iPAQ"
     include_dir cyg/io
 
-    active_if   CYGPKG_FILEIO
+    active_if   CYGPKG_IO_FILEIO
     requires    CYGPKG_IO
     requires    CYGFUN_KERNEL_API_C
     requires    CYGPKG_HAL_ARM_SA11X0_IPAQ
--- a/packages/ecos.db
+++ b/packages/ecos.db
@@ -657,6 +657,14 @@ package CYGPKG_DEVS_ETH_ARM_EDB7XXX {
         description     "Ethernet driver for Cirrus Logic EDB7xxx development boards."
 }
 
+package CYGPKG_DEVS_ETH_AMD_PCNET {
+	alias 		{ "AMD PCNET ethernet driver" pcnet_eth_driver }
+	hardware
+	directory	devs/eth/amd/pcnet
+	script		amd_pcnet_eth_drivers.cdl
+        description     "Ethernet driver for AMD PCNET controller."
+}
+
 package CYGPKG_DEVS_ETH_ARM_EBSA285 {
 	alias 		{ "Intel EBSA285 with PRO/100+ ethernet driver"
 			   devs_eth_arm_ebsa285 ebsa285_eth_driver }
--- a/packages/hal/arm/arch/current/ChangeLog
+++ b/packages/hal/arm/arch/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-24  Mark Salter  <msalter@redhat.com>
+
+	* src/arm_stub.c (target_thumb_ins): Add support for pop insn.
+
 2001-08-21  Hugo Tyson  <hmt@redhat.com>
 
 	* include/hal_intr.h: Only define HAL_CLOCK_LATENCY() if it's not
--- a/packages/hal/arm/arch/current/src/arm_stub.c
+++ b/packages/hal/arm/arch/current/src/arm_stub.c
@@ -440,7 +440,8 @@ target_thumb_ins(unsigned long pc, unsig
 {
     unsigned long new_pc = MAKE_THUMB_ADDR(pc+2); // default is fall-through 
                                         // to next thumb instruction
-    unsigned long offset, arm_ins;
+    unsigned long offset, arm_ins, sp;
+    int i;
 
     switch ((ins & 0xf000) >> 12) {
     case 0x4:
@@ -448,6 +449,20 @@ target_thumb_ins(unsigned long pc, unsig
         if ((ins & 0xff07) == 0x4700)
             new_pc = (unsigned long)get_register((ins & 0x00078) >> 3);
         break;
+    case 0xb:
+        // push/pop
+        // Look for "pop {...,pc}"
+        if ((ins & 0xf00) == 0xd00) {
+            // find PC
+            sp = (unsigned long)get_register(SP);
+
+            for (offset = i = 0; i < 8; i++)
+              if (ins & (1 << i))
+                  offset += 4;
+
+            new_pc = *(cyg_uint32 *)(sp + offset);
+        }
+        break;
     case 0xd:
         // Bcc
         // Use ARM function to check condition
--- a/packages/hal/arm/ebsa285/current/ChangeLog
+++ b/packages/hal/arm/ebsa285/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_cmds.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-06-21  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* images/*: Remove. Don't bloat repository with things already on
@@ -751,7 +757,7 @@ 1999-07-14  Hugo Tyson  <hmt@cygnus.co.u
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/hal/arm/ebsa285/current/src/redboot_cmds.c
+++ b/packages/hal/arm/ebsa285/current/src/redboot_cmds.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -118,15 +118,15 @@ do_exec(int argc, char *argv[])
         }
     }
     if (wait_time_set) {
-        printf("About to start execution at %p - abort with ^C within %d seconds\n",
-               (void *)entry, wait_time);
-        res = gets(line, sizeof(line), wait_time*1000);
+        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
+                    (void *)entry, wait_time);
+        res = _rb_gets(line, sizeof(line), wait_time*1000);
         if (res == _GETS_CTRLC) {
             return;
         }
     }
     if (base_addr_set && !length_set) {
-      printf("Length required for non-standard base address\n");
+      diag_printf("Length required for non-standard base address\n");
       return;
     }
     ip = (unsigned long *)&&lab1;
--- a/packages/hal/arm/iq80310/current/ChangeLog
+++ b/packages/hal/arm/iq80310/current/ChangeLog
@@ -1,3 +1,18 @@
+2001-08-27  Mark Salter  <msalter@redhat.com>
+
+	* cdl/hal_arm_iq80310.cdl (CYGSEM_HAL_ARM_IQ80310_BTB): New option.
+	(CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY) New option.
+	
+	* src/iq80310_pci.c (cyg_hal_plf_pci_init): Clear PCI retry based on
+	CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY.
+
+	* include/hal_platform_setup.h: Turn on BTB based on configure option.
+
+2001-08-24  Mark Salter  <msalter@redhat.com>
+
+	* src/iq80310_misc.c (iq80310_program_new_stack): Convert to inline
+	asm so that code generation differences won't break it.
+
 2001-08-15  Mark Salter  <msalter@redhat.com>
 
 	* include/hal_iq80310.h: Fix size of PATUSR, SATUSR, PSR, and SSR regs.
--- a/packages/hal/arm/iq80310/current/cdl/hal_arm_iq80310.cdl
+++ b/packages/hal/arm/iq80310/current/cdl/hal_arm_iq80310.cdl
@@ -253,6 +253,31 @@ cdl_package CYGPKG_HAL_ARM_IQ80310 {
 	    compiler flags used only in building this package,
 	    and details of which tests are built."
 
+	cdl_option CYGSEM_HAL_ARM_IQ80310_BTB {
+            display       "Enable Branch Target Buffer"
+            flavor        bool
+            default_value 0
+            description   "
+                Enable this option to turn on the IQ80200 Branch Target Buffer
+                which is used for branch prediction. This is turned off by
+                default because of CPU errata which may cause thumb branches
+                to execute improperly on A-step CPUs. Normal ARM programs are
+                not affected by this errata, so enabling this option for
+                ARM-only applications may improve program performance."
+        }
+
+	cdl_option CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY {
+            display       "Have RedBoot clear PCI Retry bit"
+            flavor        bool
+            default_value 1
+            description   "
+                This option controls whether or not RedBoot allows the host PC
+                to completely boot. In some cases, you may not want to allow
+                this if RedBoot is used to automatically launch an application
+                which needs to run some setup code before allowing the PC to
+                finish booting. In that case, the application code, not RedBoot
+                will clear the PCI retry bit."
+        }
 
         cdl_option CYGPKG_HAL_ARM_IQ80310_CFLAGS_ADD {
             display "Additional compiler flags"
--- a/packages/hal/arm/iq80310/current/include/hal_platform_setup.h
+++ b/packages/hal/arm/iq80310/current/include/hal_platform_setup.h
@@ -128,6 +128,16 @@
 	sub  pc,pc,#4
 	.endm
 
+	// Enable the BTB
+	.macro BTB_INIT reg
+#ifdef CYGSEM_HAL_ARM_IQ80310_BTB
+	mrc	p15, 0, \reg, c1, c0, 0
+	orr	\reg, \reg, #MMU_Control_BTB
+	mcr	p15, 0, \reg, c1, c0, 0
+	CPWAIT  \reg
+#endif
+	.endm
+
 	// form a first-level section entry
 	.macro FL_SECTION_ENTRY base,x,ap,p,d,c,b
 	.word (\base << 20) | (\x << 12) | (\ap << 10) | (\p << 9) |\
@@ -696,11 +706,8 @@ SDRAM_DRIVE_2_BANK_X8:
 	mcr	p15, 0, r0, c1, c0, 0
 	CPWAIT  r0
 
-	// Enable the BTB
-	mrc	p15, 0, r0, c1, c0, 0
-	orr	r0, r0, #MMU_Control_BTB
-	mcr	p15, 0, r0, c1, c0, 0
-	CPWAIT  r0
+        // Initialize branch target buffer
+        BTB_INIT r0
 
 	//  Battery Backup SDRAM Memory Test
         //  Move 4 byte Test Pattern into register prior to zeroing out
--- a/packages/hal/arm/iq80310/current/src/diag/cycduart.c
+++ b/packages/hal/arm/iq80310/current/src/diag/cycduart.c
@@ -44,7 +44,7 @@
 
 #define DFLTLOOPERMS 500
 
-extern int printf(char*,...);
+//extern int printf(char*,...);
 extern long hexIn();
 
 int break_flag = 0;
--- a/packages/hal/arm/iq80310/current/src/diag/ether_test.c
+++ b/packages/hal/arm/iq80310/current/src/diag/ether_test.c
@@ -58,7 +58,7 @@ static int waitForRxInt();
 static int get_ether_addr();
 
 /* Externals */
-void printf();
+//void printf();
 void bcopy();
 extern void sgets();
 extern int atod();
--- a/packages/hal/arm/iq80310/current/src/diag/pci_serv.c
+++ b/packages/hal/arm/iq80310/current/src/diag/pci_serv.c
@@ -107,8 +107,7 @@ typedef struct
 /* Table where the interrupt handler addresses are stored. */
 INT_HANDLER pci_int_handlers[4][MAX_PCI_HANDLERS];
 
-
-extern void printf();
+//extern void printf();
 extern void hexIn();
 
 extern int pci_config_cycle;
--- a/packages/hal/arm/iq80310/current/src/iq80310_misc.c
+++ b/packages/hal/arm/iq80310/current/src/iq80310_misc.c
@@ -129,17 +129,16 @@ void hal_hardware_init(void)
 }
 
 #include CYGHWR_MEMORY_LAYOUT_H
-typedef void code_fun(void);
-void iq80310_program_new_stack(void *func)
+void __attribute__ ((naked)) iq80310_program_new_stack(void *func)
 {
-    register CYG_ADDRESS stack_ptr asm("sp");
-    register CYG_ADDRESS old_stack asm("r4");
-    register code_fun *new_func asm("r0");
-    old_stack = stack_ptr;
-    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
-    new_func = (code_fun*)func;
-    new_func();
-    stack_ptr = old_stack;
+    asm volatile ("mov    r12,sp\n"
+                  "stmdb  sp!, {r4, r12, lr, pc}\n"
+                  "sub    r4,r12, #4\n"
+                  "mov    r12,#0xa0000000\n"
+                  "add    sp,r12,#0x1000000\n"
+                  "mov    lr,pc\n"
+                  "mov    pc,r0\n"
+                  "ldmdb  r4, {r4, sp, pc}\n");
     return;
 }
 
--- a/packages/hal/arm/iq80310/current/src/iq80310_pci.c
+++ b/packages/hal/arm/iq80310/current/src/iq80310_pci.c
@@ -113,8 +113,10 @@ void cyg_hal_plf_pci_init(void)
         *(cyg_uint32 *)POIOWVR_ADDR = PRIMARY_IO_BASE;	
     }
 
+#ifdef CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY
     // clear RETRY
     *(cyg_uint16 *)EBCR_ADDR = 0x0008;
+#endif
 
     // ******** Secondary Inbound ATU ***********
 
@@ -185,6 +187,7 @@ void cyg_hal_plf_pci_init(void)
 	// set the primary bus number to 0
 	*(cyg_uint8 *)PBNR_ADDR = PRIMARY_BUS_NUM;
     } else {
+#ifdef CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY
 	// Wait for PC BIOS to initialize bus number
 	int i;
 
@@ -193,7 +196,7 @@ void cyg_hal_plf_pci_init(void)
 		break;
 	    hal_delay_us(1000);  // 1msec
 	}
-
+#endif
 	if (*((volatile cyg_uint8 *)SBNR_ADDR) == 0)
 	    *(cyg_uint8 *)SBNR_ADDR = SECONDARY_BUS_NUM;
     }
@@ -220,9 +223,6 @@ void cyg_hal_plf_pci_init(void)
     cyg_pci_set_memory_base(SECONDARY_MEM_BASE);
     cyg_pci_set_io_base(SECONDARY_IO_BASE);
     cyg_pci_configure_bus(sbus_nr, &next_bus);
-
-    // clear RETRY
-    *(cyg_uint16 *)EBCR_ADDR = 0x0008;
 }
 
 void cyg_hal_plf_pci_config_setup( cyg_uint32 bus,
--- a/packages/hal/arm/sa11x0/ipaq/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/ipaq/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_cmds.c: 
+	* src/lcd_support.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-07-23  Gary Thomas  <gthomas@redhat.com>
 
 	* include/hal_platform_ints.h: 
--- a/packages/hal/arm/sa11x0/ipaq/current/src/lcd_support.c
+++ b/packages/hal/arm/sa11x0/ipaq/current/src/lcd_support.c
@@ -896,7 +896,7 @@ lcd_comm_getc_nonblock(void* __ch_data, 
 #ifdef KBD_DEBUG
                 {
                     int cur = start_console(0);
-                    printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
+                    diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
                     end_console(cur);
                     dump_info = !dump_info;
                 }
@@ -923,7 +923,7 @@ lcd_comm_getc_nonblock(void* __ch_data, 
 #ifdef KBD_DEBUG
                 if (dump_info) {
                     int cur = start_console(0);
-                    printf("start pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
+                    diag_printf("start pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
                     end_console(cur);
                 }
 #endif
@@ -955,7 +955,7 @@ lcd_comm_getc_nonblock(void* __ch_data, 
 #ifdef KBD_DEBUG
             if (dump_info) {
                 int cur = start_console(0);
-                printf("going idle\n");
+                diag_printf("going idle\n");
                 end_console(cur);
             }
 #endif
@@ -965,7 +965,7 @@ lcd_comm_getc_nonblock(void* __ch_data, 
 #ifdef KBD_DEBUG
     if (dump_info) {
         int cur = start_console(0);
-        printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
+        diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
         end_console(cur);
     }
 #endif
@@ -980,7 +980,7 @@ lcd_comm_getc_nonblock(void* __ch_data, 
 #ifdef KBD_DEBUG
         if (dump_info) {
             int cur = start_console(0);
-            printf("Pen[%d] at %d/%d\n", total_events, x, y);
+            diag_printf("Pen[%d] at %d/%d\n", total_events, x, y);
             end_console(cur);
         }
 #endif
@@ -995,7 +995,7 @@ lcd_comm_getc_nonblock(void* __ch_data, 
 #ifdef KBD_DEBUG
             if (dump_info) {
                 int cur = start_console(0);
-                printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch);
+                diag_printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch);
                 end_console(cur);
             }
 #endif
@@ -1390,13 +1390,13 @@ lcd_comm_init(void)
             lcd_kbd(LCD_KBD_NORM);
         }
 #if 0
-        printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n",
-               kbd_limits[CS_UL].x, kbd_limits[CS_UL].y,
-               kbd_limits[CS_UR].x, kbd_limits[CS_UR].y,
-               kbd_limits[CS_LL].x, kbd_limits[CS_LL].y,
-               kbd_limits[CS_LR].x, kbd_limits[CS_LR].y);
-        printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY);
-        printf("screen %d x %d\n", screen_height, screen_width);
+        diag_printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n",
+                    kbd_limits[CS_UL].x, kbd_limits[CS_UL].y,
+                    kbd_limits[CS_UR].x, kbd_limits[CS_UR].y,
+                    kbd_limits[CS_LL].x, kbd_limits[CS_LL].y,
+                    kbd_limits[CS_LR].x, kbd_limits[CS_LR].y);
+        diag_printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY);
+        diag_printf("screen %d x %d\n", screen_height, screen_width);
 #endif
     }
 }
--- a/packages/hal/arm/sa11x0/ipaq/current/src/redboot_cmds.c
+++ b/packages/hal/arm/sa11x0/ipaq/current/src/redboot_cmds.c
@@ -91,24 +91,24 @@ do_gpio(int argc,char *argv[]) {
     }
     if ( !set_bits_set && !clr_bits_set ) {
 	// display only
-	printf("  gpio = 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL);
-	printf("         0x%08lX are output\n", *SA11X0_GPIO_PIN_DIRECTION);
-	printf("         0x%08lX rising edge detect\n", *SA11X0_GPIO_RISING_EDGE_DETECT);
-	printf("         0x%08lX falling edge detect\n", *SA11X0_GPIO_FALLING_EDGE_DETECT);
-	printf("         0x%08lX edge detect status\n", *SA11X0_GPIO_EDGE_DETECT_STATUS);
-	printf("         0x%08lX alternate function\n", *SA11X0_GPIO_ALTERNATE_FUNCTION);
+	diag_printf("  gpio = 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL);
+	diag_printf("         0x%08lX are output\n", *SA11X0_GPIO_PIN_DIRECTION);
+	diag_printf("         0x%08lX rising edge detect\n", *SA11X0_GPIO_RISING_EDGE_DETECT);
+	diag_printf("         0x%08lX falling edge detect\n", *SA11X0_GPIO_FALLING_EDGE_DETECT);
+	diag_printf("         0x%08lX edge detect status\n", *SA11X0_GPIO_EDGE_DETECT_STATUS);
+	diag_printf("         0x%08lX alternate function\n", *SA11X0_GPIO_ALTERNATE_FUNCTION);
 	return;
     }
-    printf( "  gpio 0x%08lX, ", *SA11X0_GPIO_PIN_LEVEL);
+    diag_printf( "  gpio 0x%08lX, ", *SA11X0_GPIO_PIN_LEVEL);
     if ( set_bits_set ) {
-	printf("set(0x%08X) ",set_bits);
+	diag_printf("set(0x%08X) ",set_bits);
 	*SA11X0_GPIO_PIN_OUTPUT_SET = set_bits;
     }
     if ( clr_bits_set ) {
-	printf("clear(0x%08X) ",clr_bits);
+	diag_printf("clear(0x%08X) ",clr_bits);
 	*SA11X0_GPIO_PIN_OUTPUT_CLEAR = clr_bits;
     }
-    printf( "gives 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL);
+    diag_printf( "gives 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL);
 }
 
 static void
@@ -123,19 +123,19 @@ do_egpio(int argc,char *argv[]) {
     if (!scan_opts(argc, argv, 1, opts, 2, NULL, 0, NULL)) return;
     if ( !set_bits_set && !clr_bits_set ) {
 	// display only
-	printf("  egpio = 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff));
+	diag_printf("  egpio = 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff));
 	return;
     }
-    printf( "  egpio 0x%04X, ", (int)(_ipaq_EGPIO & 0xffff));
+    diag_printf( "  egpio 0x%04X, ", (int)(_ipaq_EGPIO & 0xffff));
     if ( set_bits_set ) {
-	printf("set(0x%08X) ",set_bits);
+	diag_printf("set(0x%08X) ",set_bits);
 	ipaq_EGPIO( set_bits, set_bits );
     }
     if ( clr_bits_set ) {
-	printf("clear(0x%08X) ",clr_bits);
+	diag_printf("clear(0x%08X) ",clr_bits);
 	ipaq_EGPIO( clr_bits, 0x0000 );
     }
-    printf( "gives 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff));
+    diag_printf( "gives 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff));
 }
 
 static void
@@ -153,23 +153,23 @@ do_mem(int argc, char *argv[]) {
     if (!scan_opts(argc, argv, 1, opts, 3, (void*)&value, OPTION_ARG_TYPE_NUM, "address to set"))
 	return;
     if ( mem_byte && mem_half_word ) {
-	printf("*ERR: Should not specify both byte and half-word access\n");
+	diag_printf("*ERR: Should not specify both byte and half-word access\n");
     } else if ( mem_byte ) {
 	*(cyg_uint8*)address = (cyg_uint8)(value & 255);
-	printf("  Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address );
+	diag_printf("  Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address );
     } else if ( mem_half_word ) {
 	if ( address & 1 ) {
-	    printf( "*ERR: Badly aligned address 0x%08X for half-word store\n", address );
+	    diag_printf( "*ERR: Badly aligned address 0x%08X for half-word store\n", address );
 	} else {
 	    *(cyg_uint16*)address = (cyg_uint16)(value & 0xffff);
-	    printf("  Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address );
+	    diag_printf("  Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address );
 	}
     } else {
 	if ( address & 3 ) {
-	    printf( "*ERR: Badly aligned address 0x%08X for word store\n", address );
+	    diag_printf( "*ERR: Badly aligned address 0x%08X for word store\n", address );
 	} else {
 	    *(cyg_uint32*)address = (cyg_uint32)value;
-	    printf("  Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value, (int)*(cyg_uint32*)address );
+	    diag_printf("  Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value, (int)*(cyg_uint32*)address );
 	}
     }
 }
@@ -181,7 +181,7 @@ do_physaddr(int argc, char *argv[]) {
     if ( !scan_opts(argc,argv,1,0,0,(void*)&virt_addr, OPTION_ARG_TYPE_NUM, "virtual address") )
 	return;
     phys_addr = hal_virt_to_phys_address(virt_addr);
-    printf("Virtual addr %p = physical addr %p\n", virt_addr, phys_addr);
+    diag_printf("Virtual addr %p = physical addr %p\n", virt_addr, phys_addr);
 }
 
 // Get here when RedBoot is idle.  If it's been long enough, then
--- a/packages/hal/arm/sa11x0/var/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/var/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_linux_exec.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-08-21  Hugo Tyson  <hmt@redhat.com>
 
 	* include/hal_var_ints.h (HAL_CLOCK_LATENCY()): Define this if
--- a/packages/hal/arm/sa11x0/var/current/src/redboot_linux_exec.c
+++ b/packages/hal/arm/sa11x0/var/current/src/redboot_linux_exec.c
@@ -282,10 +282,10 @@ do_exec(int argc, char *argv[])
         unsigned char *hold_script = script;
         script = (unsigned char *)0;
 #endif
-        printf("About to start execution at %p - abort with ^C within %d seconds\n",
-               (void *)entry, wait_time);
+        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
+                    (void *)entry, wait_time);
         while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
-            res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
+            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
             if (res == _GETS_CTRLC) {
 #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
                 script = hold_script;  // Re-enable script
@@ -296,7 +296,7 @@ do_exec(int argc, char *argv[])
         }
     }
     if (base_addr_set && !length_set) {
-      printf("Length required for non-standard base address\n");
+      diag_printf("Length required for non-standard base address\n");
       return;
     }
     ip = (unsigned long *)&&lab1;
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-08-24  Mark Salter  <msalter@redhat.com>
+
+	* src/generic-stub.c (__process_packet): Add support for 'D' packet.
+	(__process_packet): Check for impossible mem write length.
+
 2001-08-17  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/hal.cdl: Add CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
--- a/packages/hal/common/current/src/generic-stub.c
+++ b/packages/hal/common/current/src/generic-stub.c
@@ -1264,7 +1264,11 @@ int
             && __hexToInt (&ptr, &length)
             && *ptr++ == ':')
           {
-            if (is_binary)
+            /* GDB sometimes sends an impossible length */
+            if (length < 0 || length >= BUFMAX)
+              strcpy (remcomOutBuffer, "E01");
+                
+            else if (is_binary)
               {
                 while (length > 0)
                   {
@@ -1290,7 +1294,7 @@ int
                 else
                   strcpy (remcomOutBuffer, "E03");
               }
-              else
+            else
               {
                 if (__hex2mem_safe (ptr, addr, length) != NULL)
                   strcpy (remcomOutBuffer, "OK");
@@ -1389,8 +1393,10 @@ int
         return -1;
       }
 
-      /* kill the program */
-    case 'k' :
+    case 'D' :     /* detach */
+      __putpacket (remcomOutBuffer);
+      /* fall through */
+    case 'k' :      /* kill the program */
 #ifdef __ECOS__
       hal_flush_output();
 #endif
--- a/packages/hal/i386/arch/current/ChangeLog
+++ b/packages/hal/i386/arch/current/ChangeLog
@@ -1,3 +1,23 @@
+2001-09-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/vectors.S (__default_interrupt_vsr): Adjust saved stack pointer
+	for the hardware and trampoline saved data.
+	(__default_exception_vsr): Ditto.
+
+2001-08-31  Nick Garnett  <nickg@redhat.com>
+
+	* include/arch.inc: Clean up typo in stack switching macros.
+
+2001-08-22  Nick Garnett  <nickg@redhat.com>
+
+	* include/hal_io.h: Added some macros to do in-memory data
+	accesses for memory mapped devices.
+
+	* include/hal_arch.h: Attempted to make some sense out of the
+	stack size macros.
+
+	* include/hal_intr.h: Extended VSR table to its full 256 entries.
+
 2001-07-31  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/hal_misc.c: Fix "implicit decl of diag_printf" warning.
--- a/packages/hal/i386/arch/current/cdl/hal_i386.cdl
+++ b/packages/hal/i386/arch/current/cdl/hal_i386.cdl
@@ -72,6 +72,7 @@ cdl_package CYGPKG_HAL_I386 {
         @rm target.tmp
     }
 
+        
     cdl_option CYGBLD_BUILD_I386_ROMBOOT {
 	display       "Build ROM bootstrap code"
 	calculated    { CYG_HAL_STARTUP == "ROM" }
--- a/packages/hal/i386/arch/current/include/arch.inc
+++ b/packages/hal/i386/arch/current/include/arch.inc
@@ -78,7 +78,80 @@
 
 #endif
 
+#------------------------------------------------------------------------------
 
+	.macro	hal_smp_init
+	.endm
+
+	.macro hal_smp_cpu reg
+	movl	$0,\reg
+	.endm
+
+
+#------------------------------------------------------------------------------
+# Stack switching macros
+
+#ifndef CYG_HAL_PPC_INTSTACK_MACROS_DEFINED
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+	.macro	hal_init_istack reg,tr
+	movl	$__interrupt_stack,\reg		// Load interrupt stack
+	.endm
+
+	.macro	hal_load_istack reg
+	movl	$__interrupt_stack,\reg		// Load interrupt stack
+	.endm
+
+	.macro	hal_load_istack_base reg
+	movl	$__interrupt_stack_base,\reg	// Load interrupt stack base
+	.endm
+
+		
+	.macro	hal_to_intstack
+	hal_load_istack_base %ebx		// EBX = stack base
+	movl	%ebx,%eax
+	addl	$CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE,%eax
+	cmpl	%ebx,%ebp			# compare SP with istack base
+	jb	1f				# if sp < istack base, switch
+	cmpl	%eax,%ebp			# compare SP with istack top
+	jbe	2f				# if sp < istack top, dont switch
+1:	
+	movl	%eax,%esp			# move on to new stack
+2:		
+	pushl	%ebp				# Save old SP on new stack
+	.endm
+
+	.macro	hal_from_intstack
+	popl	%esp				# pop old SP from stack
+	.endm
+
+#define CYG_HAL_PPC_INTSTACK_MACROS_DEFINED
+
+
+#else // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+	.macro	hal_init_istack reg
+	.endm
+
+	.macro	hal_load_istack_base reg
+	.endm
+
+	.macro	hal_load_istack reg
+	.endm
+
+	.macro	hal_to_intstack
+	.endm
+
+	.macro	hal_from_intstack
+	.endm
+
+#define CYG_HAL_PPC_INTSTACK_MACROS_DEFINED
+
+#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+#endif // CYG_HAL_PPC_INTSTACK_MACROS_DEFINED
+	
 #------------------------------------------------------------------------------
 # FPU macros.
 	
@@ -127,10 +200,54 @@
 	# up.
 	subl	$i386reg_fpucontext_size,%esp
 	movl	$0,i386reg_fpucontext_valid(%esp)
-	movl	%esp,cyg_hal_fpustate_current
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	movl	%esp,0(%ecx,%ebx,4)		# save in table[cpu] entry
 #endif
 	.endm
 
+	.macro	hal_fpu_cpu_init
+	# Tell the CPU to use the math hardware.
+	movl	%cr0, %eax
+	orl	$0x32, %eax	# Set MP, ET, NE bits
+	andl	$~0x8, %eax	# And clear TS bit
+	movl	%eax, %cr0
+
+	finit			# and initialize...
+
+        ## Enable floating point exceptions. Bit mask:
+        ##  1 - invalid operation
+        ##  2 - denormalized operand
+        ##  4 - zero divide
+        ##  8 - overflow
+        ## 16 - underflow
+        ## 32 - precision
+	pushl	$0		# space for CW
+        fstcw   0(%esp)		# store FPCW to stack
+        movl	0(%esp),%eax	# get into EAX
+        andb	$(~0x04),%al	# allow only zero divide exceptions
+        movl	%eax,0(%esp)	# put back into memory
+        fldcw	0(%esp)		# reload
+	addl	$4,%esp		# pop value
+
+#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
+	# Tell the CPU to generate an FPU unavailable exception
+	# when the FPU is first used.
+	movl	%cr0, %eax
+	orl	$0x8, %eax
+	movl	%eax, %cr0
+	# Now create an FPU context on the stack so that we can take
+	# FPU-using interrupts and exceptions before the kernel starts
+	# up.
+	subl	$i386reg_fpucontext_size,%esp
+	movl	$0,i386reg_fpucontext_valid(%esp)
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	movl	%esp,0(%ecx,%ebx,4)		# save in table[cpu] entry
+#endif
+
+	.endm
+
 #ifndef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
 
 	# Non-lazy CPU state switching. We simply switch the entire
@@ -206,7 +323,9 @@ 2:
 	# threads FPU context save area.
 
 	.macro	hal_fpu_push_ctx
-	pushl	cyg_hal_fpustate_current		# push our FPU state ptr
+	hal_smp_cpu %ebx			# Get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	pushl	0(%ecx,%ebx,4)			# push table[cpu] entry
 	.endm
 
 	# We do nothing here but set the CR0:TS bit to force
@@ -217,7 +336,9 @@ 2:
 	movl	%cr0, %ecx			# get CR0
 	orl	$0x8, %ecx			# set TS bit
 	movl	%ecx, %cr0			# restore CR0
-	popl	cyg_hal_fpustate_current	# set current FPU state pointer
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	popl	0(%ecx,%ebx,4)			# pop table[cpu] entry
 	.endm
 
 	# ------------------------------------------------------------
@@ -228,7 +349,9 @@ 2:
 	# interrupt.
 
 	.macro	hal_fpu_push_int
-	pushl	cyg_hal_fpustate_current	# push current threads FPU state ptr
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	pushl	0(%ecx,%ebx,4)			# push table[cpu] entry
 	# ensure that CR0:TS bit is set
 	movl	%cr0, %ecx			# get CR0
 	orl	$0x8, %ecx			# set TS bit
@@ -242,7 +365,9 @@ 2:
 	.macro	hal_fpu_push_int_annex
 	subl	$i386reg_fpucontext_size,%esp
 	movl	$0,i386reg_fpucontext_valid(%esp)
-	movl	%esp,cyg_hal_fpustate_current
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	movl	%esp,0(%ecx,%ebx,4)		# save in table[cpu] entry
 	.endm
 
 	# This is invoked just before any transfer back to the thread stack.
@@ -251,9 +376,11 @@ 2:
 	# own state over the top of it.
 
 	.macro	hal_fpu_pop_int_annex
-	cmpl	cyg_hal_fpustate_owner,%esp	# are we FPU owner?
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_owner,%ecx	# current state table
+	cmpl	0(%ecx,%ebx,4),%esp		# are we FPU owner?
 	jne	1f				# if not, then just continue
-	movl	$0,cyg_hal_fpustate_owner	# no one owns FPU now
+	movl	$0,0(%ecx,%ebx,4)		# no one owns FPU now
 	# ensure that CR0:TS bit is set to force a reload of
 	# the previous FPU state
 	movl	%cr0, %ecx			# get CR0
@@ -266,7 +393,9 @@ 1:
 	# Final return from interrupt handling. Just pull the current
 	# FPU context off the stack.
 	.macro	hal_fpu_pop_int
-	popl	cyg_hal_fpustate_current	# set current FPU state pointer
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	popl	0(%ecx,%ebx,4)			# pop table[cpu] entry
 	.endm
 
 	# ------------------------------------------------------------
@@ -277,13 +406,16 @@ 1:
 	# whole machine state is saved in memory.
 
 	.macro	hal_fpu_push_exc
-	pushl	cyg_hal_fpustate_current	# push our FPU state ptr
-	movl	cyg_hal_fpustate_owner,%eax	# EAX = FPU state owner
+	hal_smp_cpu %ebx			# get CPU id
+	movl	$cyg_hal_fpustate_current,%ecx	# current state table
+	pushl	0(%ecx,%ebx,4)			# push table[cpu] entry
+	movl	$cyg_hal_fpustate_owner,%ecx	# current owner table
+	movl	0(%ecx,%ebx,4),%eax		# EAX = FPU state owner
 	cmpl	$0,%eax				# test it
 	je	1f				# skip if zero
 	fsave	i386reg_fpucontext_state(%eax)	# save state
 	movl	$1,i386reg_fpucontext_valid(%eax) # set valid
-	movl	$0,cyg_hal_fpustate_owner	# zero owner pointer
+	movl	$0,0(%ecx,%ebx,4)		# zero owner pointer
 1:
 	.endm
 
@@ -311,6 +443,9 @@ 1:
 	.macro	hal_fpu_init
 	.endm
 
+	.macro	hal_fpu_cpu_init
+	.endm
+
 	.macro	hal_fpu_push_ctx
 	.endm
 
--- a/packages/hal/i386/arch/current/include/hal_arch.h
+++ b/packages/hal/i386/arch/current/include/hal_arch.h
@@ -292,26 +292,31 @@ externC void hal_idle_thread_action(cyg_
 // This is not a config option because it should not be adjusted except
 // under "enough rope" sort of disclaimers.
  
-// Stack frame overhead per call. 3 local registers (edi, esi, ebx) and
-// return address.
-#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 4)
+// Stack frame overhead per call. Four arguments, 3 local registers
+// (edi, esi, ebx), four local variables and return address.
+#define CYGNUM_HAL_STACK_FRAME_SIZE (12 * 4)
 
-// Stack needed for a context switch (i386reg_context_size from i386.inc)
-#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 24)
+// Stack needed for a context switch ( sizeof(HAL_SavedRegisters) ).
+#ifdef CYGHWR_HAL_I386_FPU
+# ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
+#  define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 13)
+# else
+#  define CYGNUM_HAL_STACK_CONTEXT_SIZE ((4 * 12) + 108)
+# endif
+#else
+# define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 12)
+#endif
 
 // Interrupt + call to ISR, interrupt_end() and the DSR
 #define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
-    ((6*4*2 /* 2*sizeof(HAL_SavedRegisters) */) + 4 * CYGNUM_HAL_STACK_FRAME_SIZE)
-
-// We have lots of registers so no particular amount is added in for
-// typical local variable usage.
+    ((4*CYGNUM_HAL_STACK_CONTEXT_SIZE) + 4 * CYGNUM_HAL_STACK_FRAME_SIZE)
 
 // We define a minimum stack size as the minimum any thread could ever
 // legitimately get away with. We can throw asserts if users ask for less
 // than this. Allow enough for three interrupt sources - clock, serial and
 // one other
 
-#if 0 // defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
+#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
 
 // An interrupt stack which is large enough for all possible interrupt
 // conditions (and only used for that purpose) exists.  "User" stacks
--- a/packages/hal/i386/arch/current/include/hal_intr.h
+++ b/packages/hal/i386/arch/current/include/hal_intr.h
@@ -77,11 +77,11 @@
 #define CYGNUM_HAL_VECTOR_FPE                    16
 #define CYGNUM_HAL_VECTOR_ALIGNMENT              17
 
-// The default size of the VSR table is 64 entries.
+// The default size of the VSR table is 256 entries.
 #ifndef CYGNUM_HAL_VSR_MIN
 #define CYGNUM_HAL_VSR_MIN                        0
-#define CYGNUM_HAL_VSR_MAX                       63
-#define CYGNUM_HAL_VSR_COUNT                     64
+#define CYGNUM_HAL_VSR_MAX                       255
+#define CYGNUM_HAL_VSR_COUNT                     256
 #endif
 
 // Common exception vectors.
--- a/packages/hal/i386/arch/current/include/hal_io.h
+++ b/packages/hal/i386/arch/current/include/hal_io.h
@@ -167,5 +167,18 @@ CYG_MACRO_END
     CYG_MACRO_END
 
 //-----------------------------------------------------------------------------
+
+// Macros for acessing shared memory structures
+
+#define HAL_READMEM_UINT8(   _reg_, _val_ ) ((_val_) = *((volatile CYG_BYTE *)(_reg_)))
+#define HAL_WRITEMEM_UINT8(  _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (_val_))
+
+#define HAL_READMEM_UINT16(  _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD16 *)(_reg_)))
+#define HAL_WRITEMEM_UINT16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (_val_))
+
+#define HAL_READMEM_UINT32(  _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD32 *)(_reg_)))
+#define HAL_WRITEMEM_UINT32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (_val_))
+
+//-----------------------------------------------------------------------------
 #endif // ifndef CYGONCE_HAL_HAL_IO_H
 // End of hal_io.h
--- a/packages/hal/i386/arch/current/src/i386.ld
+++ b/packages/hal/i386/arch/current/src/i386.ld
@@ -144,10 +144,8 @@ GROUP(libtarget.a libgcc.a)
 // Standard tables at base of memory
 
 idtStart                 = 0x00001000;
-//idtEnd                   = 0x00001800;
 hal_vsr_table            = 0x00001800;
-hal_virtual_vector_table = 0x00001900;
+hal_virtual_vector_table = 0x00001c00;
 
 
 
-
--- a/packages/hal/i386/arch/current/src/vectors.S
+++ b/packages/hal/i386/arch/current/src/vectors.S
@@ -47,6 +47,7 @@
 
 #include <pkgconf/system.h>
 #include <pkgconf/hal.h>
+#include <pkgconf/hal_i386_pc.h>
 
 #ifdef CYGPKG_KERNEL
 #include <pkgconf/kernel.h>
@@ -67,6 +68,7 @@
 
 _start: 
 	hal_cpu_init
+	hal_smp_init
 	hal_diag_init
 	hal_mmu_init
 	hal_memc_init
@@ -74,7 +76,8 @@
 	hal_cache_init
 	hal_timer_init
 
-	# loading the stack pointer seems appropriate now.
+	# Loading the stack pointer seems appropriate now.
+	
 	movl	$__interrupt_stack, %esp
 
 #if defined(CYG_HAL_STARTUP_FLOPPY) || defined(CYG_HAL_STARTUP_ROM)
@@ -131,6 +134,7 @@
 	.extern cyg_hal_invoke_constructors
 	call	cyg_hal_invoke_constructors
 
+		
 	.extern cyg_start
 	call	cyg_start
 
@@ -153,13 +157,12 @@ 1:	hlt
 
 	pusha			# save all registers
 	hal_fpu_push_exc	# save FPU state
-	
+
 	mov	%esp,%edi	# save state pointer in EDI
+
+        # adjust ESP by 16 for the state stored before the pusha
+        add     $16,i386reg_esp(%edi)
 		
-#if 0 //def CYGSEM_HAL_ROM_MONITOR
-	# In a monitor, switch to interrupt stack to handle this
-	movl	$__interrupt_stack,%esp
-#endif			
 
 	hal_fpu_push_exc_annex
 	
@@ -171,18 +174,12 @@ 1:	hlt
 	
 	hal_fpu_pop_exc_annex
 		
-#if 0 //def CYGSEM_HAL_ROM_MONITOR 
-	
-	# If we switched to the interrupt stack, switch back here
-	# %edi will have been preserved across the call to
-	# cyg_hal_exception_handler()
-	
-	movl	%edi,%esp
-#endif	
 
 	hal_fpu_pop_exc		# restore FPU state
 	popa			# restore all our registers.
 	addl	$4, %esp	# skip the vector number
+                                # Note: we do not need to re-adjust ESP
+                                # back by 16 as popa does not pop ESP.
 	iret			# and return to the program.
 			
 #==============================================================================
@@ -203,7 +200,7 @@ 1:	hlt
 	
 	pusha			# save registers
 	hal_fpu_push_int	# save FPU state
-	
+
 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \
     defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
 	# Save the context just to be able to set a breakpoint
@@ -212,7 +209,8 @@ 1:	hlt
 	movl %esp,hal_saved_interrupt_state
 #endif
 
-#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+    !defined(CYGPKG_HAL_SMP_SUPPORT)
 	# Increment scheduler lock
 	.extern cyg_scheduler_sched_lock
 	incl	cyg_scheduler_sched_lock
@@ -220,21 +218,11 @@ 1:	hlt
 
 	movl	%esp,%ebp			# EBP = copy of ESP
 	
-#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK	
-
-	# Switch to interrupt stack if we are not already on it
-
-	movl	$__interrupt_stack,%eax		# eax = stack top
-	cmpl	$__interrupt_stack_base,%ebp	# compare SP with istack base
-	jb	1f				# if sp < istack base, switch
-	cmpl	%eax,%ebp			# compare SP with istack top
-	jbe	2f				# if sp < istack top, dont switch
-1:	
-	movl	%eax,%esp			# move on to new stack
-2:		
-	pushl	%ebp				# Save old SP on new stack
-#endif		
-
+        # adjust ESP by 16 for the state stored before the pusha
+        add     $16,i386reg_esp(%esp)
+		
+	hal_to_intstack
+		
 	hal_fpu_push_int_annex			# save extra FPU state
 	
 #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
@@ -285,17 +273,11 @@ 2:
 
 	hal_fpu_pop_int_annex		# Pop any saved interrupt state
 		
-#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK	
-
 	# If we are returning from the last nested interrupt, move back
 	# to the thread stack. interrupt_end() must be called on the
 	# thread stack since it potentially causes a context switch.
-	# Since we have arranged for the top of stack location to
-	# contain the sp we need to go back to here, just pop it off
-	# into ESP.
 	
-	popl	%esp
-#endif
+	hal_from_intstack	
 			
 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
 
@@ -323,7 +305,8 @@ 2:
 
 #==============================================================================
 ## Execute pending DSRs on the interrupt stack with interrupts enabled.
-## Note: this can only be called from code running on a thread stack
+## Note: this can only be called from code running on a thread stack so we 
+## can always just jump to the interrupt stack without looking.
 
 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
 
@@ -332,33 +315,34 @@ 2:
 	
 hal_interrupt_stack_call_pending_DSRs:	
 
-	pushl	%esi			# save a work register
+	pushl	%ebp			# save EBP
 	pushfl				# save flags
-	movl	%esp,%esi		# ESI = old stack
+	movl	%esp,%ebp		# EBP = saved SP
 
-	movl	$__interrupt_stack,%esp	# ESP = interrupt stack
+	hal_load_istack	%edx		# load new SP into EDX
+	movl	%edx,%esp		# move it to ESP
 	
 	sti				# Enable interrupts
 
 	# Call back to kernel to run DSRs
 	call	cyg_interrupt_call_pending_DSRs
 
-	# On return ESI will still contain the old ESP since
+	# On return EBP will still contain the old ESP since
 	# it is a callee saved register.
 	
-	movl	%esi,%esp		# restore original stack
+	movl	%ebp,%esp		# restore saved SP
 
 	# Now merge the original IF bit into the current
 	# EFLAGS. 
 	
-	popl	%esi			# ESI = saved flags
+	popl	%eax			# EAX = saved flags
 	pushfl				# 0(%esp) = current flags
 	btrl	$9,0(%esp)		# clear IF bit in current flags
-	andl	$0x00000200,%esi	# isolate saved IF bit
-	orl	%esi,0(%esp)		# OR it in to the saved flags
+	andl	$0x00000200,%eax	# isolate saved IF bit
+	orl	%eax,0(%esp)		# OR it in to the saved flags
 	popfl				# restore flags
 	
-	popl	%esi			# retrieve work register
+	popl	%ebp			# restore EBP
 	ret				# and return
 	
 #endif				
@@ -373,22 +357,41 @@ hal_interrupt_stack_call_pending_DSRs:
 	
 #ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY		
 
+#ifndef CYGPKG_HAL_SMP_CPU_MAX
+#define CYGPKG_HAL_SMP_CPU_MAX 1
+#endif
+				
 	.data
 	.global cyg_hal_fpustate_owner
-cyg_hal_fpustate_owner:	
+cyg_hal_fpustate_owner:
+	.rept	CYGPKG_HAL_SMP_CPU_MAX
 	.long	0				# pointer to FPU owning context
+	.endr
 	.global cyg_hal_fpustate_current	
 cyg_hal_fpustate_current:	
+	.rept	CYGPKG_HAL_SMP_CPU_MAX
 	.long	0				# pointer to current threads FPU context
-		
+	.endr
+			
 	.text	
 __fpu_switch_vsr:
 
+	## We enter here with the CPU state still in the registers and:
+	##  0(%esp)	vector number pushed by trampoline
+	##  4(%esp)	PC pushed by hardware
+	##  8(%esp)	CS pushed by hardware
+	## 12(%esp)	EFLAGS pushed by hardware
+	
 	clts					# clear CR0:TS bit
 	pusha					# save all regs
 
-	movl	cyg_hal_fpustate_owner,%eax	# EAX = FPU context owner
-	movl	cyg_hal_fpustate_current,%ebx	# EBX = current threads context
+	hal_smp_cpu %ecx			# ECX = CPU id
+	movl	$cyg_hal_fpustate_owner,%esi	# ESI = FPU context owner table
+	leal	0(%eax,%ecx,4),%esi		# ESI = address of owner pointer
+	movl	$cyg_hal_fpustate_current,%edi	# EDI = current threads context table
+	leal	0(%ebx,%ecx,4),%edi		# EDI = address of context pointer
+	movl	0(%esi),%eax			# EAX = Current FPU context owner
+	movl	0(%edi),%ebx			# EBX = Current threads FPU context
 	cmpl	%ebx,%eax			# current == owner ?
 	je	9f				# yes, nothing else to do
 	cmpl	$0,%eax				# is FPU even in use?
@@ -396,7 +399,7 @@ cyg_hal_fpustate_current:
 	fsave	i386reg_fpucontext_state(%eax)	# save FPU state
 	movl	$1,i386reg_fpucontext_valid(%eax) # mark valid
 1:
-	movl	%ebx,cyg_hal_fpustate_owner	# Set new owner
+	movl	%ebx,0(%esi)            	# Set new owner
 	btl	$0,i386reg_fpucontext_valid(%ebx) # Valid state?
 	jc	2f				# If yes, go to restore it
 	finit					# Otherwise init FPU
@@ -409,17 +412,8 @@ 9:
 	iret					# and return to the thread.
 		
 #endif
-		
-#==============================================================================	
-# hal_idle_thread_action(cyg_uint32 loop_count)
-	
-	.align	4
-	.globl	hal_idle_thread_action
-hal_idle_thread_action:
-	hlt
-	ret
-	
 
+#if 0			
 #==============================================================================
 # Assembler swap routines
 	
@@ -444,7 +438,8 @@ CPU_swap_u32:
 	movb	6(%esp), %ah
 	movb	7(%esp), %al
 	ret
-	
+#endif
+		
 #==============================================================================
 # Exception trampolines
 # IDT exception gates point to short code sequences that push the vector
@@ -561,7 +556,9 @@ default_vsr_iret:
 #ifndef CYG_HAL_PPC_INTERRUPT_STACK_DEFINED
 	        
 	.bss
+
 	
+	.balign 16
 	.global cyg_interrupt_stack_base
 cyg_interrupt_stack_base:
 __interrupt_stack_base:
@@ -572,8 +569,9 @@ cyg_interrupt_stack_base:
 	.global cyg_interrupt_stack
 cyg_interrupt_stack:
 __interrupt_stack:
-        
-        .long   0,0,0,0,0,0,0,0
+
+	.long	0,0,0,0,0,0,0,0	
+
 
 #endif	
 		
--- a/packages/hal/i386/pc/current/ChangeLog
+++ b/packages/hal/i386/pc/current/ChangeLog
@@ -1,3 +1,23 @@
+2001-09-07  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* misc/redboot_FLOPPY.ecm: Disable
+	CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS
+	* misc/redboot_ROM.ecm: Ditto.
+
+2001-09-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/plf_misc.c (hal_platform_init): If not RAM startup, install
+	exception VSRs.
+
+2001-08-22  Nick Garnett  <nickg@redhat.com>
+
+	* include/pkgconf/mlt_i386_pc_floppy.ldi:
+	* include/pkgconf/mlt_i386_pc_floppy.mlt:
+	Moved load base address from 0x2000 to 0x3000.
+
+	* include/platform.inc (hal_idt_init): Added entries to set up IDT
+	entries 48..67.
+
 2001-08-13  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/hal_i386_pc.cdl: Fix CYG_HAL_STARTUP description.
--- a/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.ldi
+++ b/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.ldi
@@ -12,7 +12,7 @@ MEMORY
 SECTIONS
 {
     SECTIONS_BEGIN
-    SECTION_vectors (ram, 0x2000, LMA_EQ_VMA)
+    SECTION_vectors (ram, 0x3000, LMA_EQ_VMA)
     SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
     SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
     SECTION_rodata1 (ram, ALIGN (0x8), LMA_EQ_VMA)
--- a/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.mlt
+++ b/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.mlt
@@ -1,6 +1,6 @@
 version 0
 region ram 0 a0000 0 !
-section vectors 0 1 0 1 1 1 1 1 2000 2000 text text !
+section vectors 0 1 0 1 1 1 1 1 3000 3000 text text !
 section text 0 4 0 1 0 1 0 1 fini fini !
 section fini 0 4 0 1 0 1 0 1 rodata1 rodata1 !
 section rodata1 0 8 0 1 0 1 0 1 rodata rodata !
--- a/packages/hal/i386/pc/current/misc/redboot_FLOPPY.ecm
+++ b/packages/hal/i386/pc/current/misc/redboot_FLOPPY.ecm
@@ -32,6 +32,10 @@ cdl_option CYGBLD_BUILD_REDBOOT {
     user_value 1
 };
 
+cdl_option CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS {
+    user_value 0
+};
+
 #cdl_option CYGSEM_REDBOOT_FLASH_CONFIG {
 #    user_value 1
 #};
--- a/packages/hal/i386/pc/current/misc/redboot_ROM.ecm
+++ b/packages/hal/i386/pc/current/misc/redboot_ROM.ecm
@@ -32,6 +32,10 @@ cdl_option CYGBLD_BUILD_REDBOOT {
     user_value 1
 };
 
+cdl_option CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS {
+    user_value 0
+};
+
 #cdl_option CYGSEM_REDBOOT_FLASH_CONFIG {
 #    user_value 1
 #};
--- a/packages/hal/i386/pc/current/src/plf_misc.c
+++ b/packages/hal/i386/pc/current/src/plf_misc.c
@@ -74,6 +74,7 @@ extern void patch_dbg_syscalls(void * ve
 
 extern void hal_pcmb_init(void);
 
+
 //----------------------------------------------------------------------------
 // ISR tables
 
@@ -114,9 +115,18 @@ void hal_platform_init(void)
         cyg_uint32 index;
         HAL_TRANSLATE_VECTOR( vector, index );
         hal_interrupt_handlers[index] = (CYG_ADDRESS) HAL_DEFAULT_ISR;
-        HAL_VSR_SET( vector, __default_interrupt_vsr, NULL );
+        HAL_VSR_SET( vector, &__default_interrupt_vsr, NULL );
     }
     
+#if !defined(CYG_HAL_STARTUP_RAM)
+    for (vector = CYGNUM_HAL_EXCEPTION_MIN;
+         vector <= CYGNUM_HAL_EXCEPTION_MAX;
+         vector++)        
+    {
+        HAL_VSR_SET( vector, &__default_exception_vsr, NULL );
+    }
+#endif
+    
 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)    
     {
         void hal_ctrlc_isr_init(void);
@@ -125,14 +135,6 @@ void hal_platform_init(void)
 
 #endif
         
-#if 0 // !defined(CYGSEM_HAL_ROM_MONITOR)
-    /* Connect to the floating point interrupt. */
-    cyg_interrupt_create(CYGNUM_HAL_VECTOR_NO_DEVICE, 1, 0,
-                         hal_pc_fpe_isr, hal_pc_fpe_dsr,
-                         &hal_pc_fpe_interrupt, &hal_pc_fpe_interrupt_object);
-    cyg_interrupt_attach(hal_pc_fpe_interrupt);
-#endif        
-
 #ifdef CYGPKG_REDBOOT
 
     // Start the timer device running if we are in a RedBoot
@@ -144,6 +146,7 @@ void hal_platform_init(void)
     
     hal_if_init();
 
+    
 }
 
 /*------------------------------------------------------------------------*/
--- a/packages/hal/i386/pcmb/current/ChangeLog
+++ b/packages/hal/i386/pcmb/current/ChangeLog
@@ -1,3 +1,11 @@
+2001-08-22  Nick Garnett  <nickg@redhat.com>
+
+	* src/pcmb_misc.c: Added spinlock to clock read operation.
+	
+	* include/pcmb_io.h (PC_WRITE_SCREEN_*): Added casts to make these
+	macros more universal.
+
+
 2001-07-31  Mark Salter  <msalter@redhat.com>
 
 	* include/pcmb_io.h: Add IDE I/O macros.
--- a/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl
+++ b/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl
@@ -87,6 +87,7 @@ cdl_package CYGPKG_HAL_I386_PCMB {
         }
     }
 
+    
     cdl_interface CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT {
 	display       "Enable PC screen support"
 	compile       pcmb_screen.c
--- a/packages/hal/i386/pcmb/current/include/pcmb_intr.h
+++ b/packages/hal/i386/pcmb/current/include/pcmb_intr.h
@@ -96,11 +96,12 @@
 #define CYGNUM_HAL_INTERRUPT_HDD                 46
 
 #define CYGNUM_HAL_ISR_MIN                       32
-#define CYGNUM_HAL_ISR_MAX                       47
+#define CYGNUM_HAL_ISR_MAX                       255
 #define CYGNUM_HAL_ISR_COUNT    (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
 
 #define CYGNUM_HAL_INTERRUPT_RTC                 CYGNUM_HAL_INTERRUPT_TIMER
 
+
 //--------------------------------------------------------------------------
 // Interrupt vector translation
 
@@ -111,6 +112,7 @@
 //--------------------------------------------------------------------------
 // PIC interrupt acknowledge
 
+
 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )   \
 CYG_MACRO_START                                 \
     int x;                                      \
@@ -121,9 +123,11 @@ CYG_MACRO_START                         
         HAL_WRITE_UINT8( 0x20, 0x20 );          \
 CYG_MACRO_END
 
+
 //--------------------------------------------------------------------------
 // PIC per-interrupt source masking
 
+
 #define HAL_INTERRUPT_MASK( _vector_ )                  \
 CYG_MACRO_START                                         \
     int x;                                              \
@@ -193,6 +197,7 @@ CYG_MACRO_END
 
 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )            
 
+
 //---------------------------------------------------------------------------
 // Clock support.
 
--- a/packages/hal/i386/pcmb/current/include/pcmb_io.h
+++ b/packages/hal/i386/pcmb/current/include/pcmb_io.h
@@ -180,17 +180,17 @@ CYG_MACRO_END
 #define PC_WRITE_SCREEN_8( __pos, __val )                       \
 {                                                               \
     char __hex[] = "0123456789ABCDEF";                          \
-    PC_WRITE_SCREEN( (__pos), __hex[((__val)>>4)&0xF] );        \
-    PC_WRITE_SCREEN( ((__pos)+1), __hex[(__val)&0xF] );         \
+    PC_WRITE_SCREEN( (__pos), __hex[((int)(__val)>>4)&0xF] );        \
+    PC_WRITE_SCREEN( ((__pos)+1), __hex[(int)(__val)&0xF] );         \
 }
 
 #define PC_WRITE_SCREEN_16( __pos, __val )      \
-    PC_WRITE_SCREEN_8( __pos, (__val)>>8 );     \
-    PC_WRITE_SCREEN_8( (__pos)+2, __val );
+    PC_WRITE_SCREEN_8( __pos, (int)(__val)>>8 );     \
+    PC_WRITE_SCREEN_8( (__pos)+2, (int)(__val) );
 
 #define PC_WRITE_SCREEN_32( __pos, __val )      \
-    PC_WRITE_SCREEN_16( __pos, (__val)>>16 );   \
-    PC_WRITE_SCREEN_16( (__pos)+4, __val );
+    PC_WRITE_SCREEN_16( __pos, (int)(__val)>>16 );   \
+    PC_WRITE_SCREEN_16( (__pos)+4, (int)(__val) );
 
 //-----------------------------------------------------------------------------
 // IDE interface macros
--- a/packages/hal/i386/pcmb/current/src/pcmb_misc.c
+++ b/packages/hal/i386/pcmb/current/src/pcmb_misc.c
@@ -43,6 +43,7 @@
 //========================================================================*/
 
 #include <pkgconf/hal.h>
+#include <pkgconf/hal_i386.h>
 #include <pkgconf/hal_i386_pcmb.h>
 
 #include <cyg/infra/cyg_type.h>         // Base types
@@ -88,6 +89,7 @@ void hal_pcmb_init(void)
 #endif
 
     cyg_hal_pcmb_memsize_extended = ((hi<<8)+lo)*1024;
+
 }
 
 /*------------------------------------------------------------------------*/
@@ -108,12 +110,17 @@ cyg_uint8 *hal_i386_mem_real_region_top(
 /*------------------------------------------------------------------------*/
 // Clock initialization and access
 
+#define HAL_SPINLOCK_SPIN( lock )
+#define HAL_SPINLOCK_CLEAR( lock )
+
 void hal_pc_clock_initialize(cyg_uint32 period)
 {
     /* Select mode 2: rate generator.  Then we'll load LSB, and finally MSB. */
     HAL_WRITE_UINT8( PC_PIT_CONTROL, 0x34 );
     HAL_WRITE_UINT8( PC_PIT_CLOCK_0, period & 0xFF );
     HAL_WRITE_UINT8( PC_PIT_CLOCK_0, period >> 8 );
+
+    HAL_SPINLOCK_CLEAR( pc_clock_lock );
 }
 
 
@@ -121,11 +128,13 @@ void hal_pc_clock_read(cyg_uint32 * coun
 {
     cyg_uint8 lo = 0,hi = 0;
     cyg_uint32 curr = 0;
-    cyg_uint32 interruptState ;
+    CYG_INTERRUPT_STATE interruptState ;
 
     /* Hold off on interrupts for a bit. */
     HAL_DISABLE_INTERRUPTS(interruptState) ;
 
+    HAL_SPINLOCK_SPIN( pc_clock_lock );    
+    
     /* Latch counter 0. */
     HAL_WRITE_UINT8(PC_PIT_CONTROL, 0x00);
 
@@ -134,6 +143,8 @@ void hal_pc_clock_read(cyg_uint32 * coun
     HAL_READ_UINT8( PC_PIT_CLOCK_0, hi );
 
     curr = (hi<<8) | lo;
+
+    HAL_SPINLOCK_CLEAR( pc_clock_lock );
     
     /* (Maybe) restore interrupts. */
     HAL_RESTORE_INTERRUPTS(interruptState) ;
@@ -143,11 +154,11 @@ void hal_pc_clock_read(cyg_uint32 * coun
 
 /*------------------------------------------------------------------------*/
 
-#if 0
 void hal_idle_thread_action(cyg_uint32 loop_count)
-{	asm("hlt") ;
+{
+    asm("hlt") ;
+
 }
-#endif
 
 /*------------------------------------------------------------------------*/
 /* End of pcmb_misc.c                                                      */
--- a/packages/hal/mips/arch/current/ChangeLog
+++ b/packages/hal/mips/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_linux_exec.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-08-01  Hugo Tyson  <hmt@redhat.com>
 
 	* src/vectors.S (restore_state): (see the change below 2001-07-03)
@@ -1459,7 +1465,7 @@ 1998-07-23  Nick Garnett  <nickg@cygnus.
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/hal/mips/arch/current/src/redboot_linux_exec.c
+++ b/packages/hal/mips/arch/current/src/redboot_linux_exec.c
@@ -107,14 +107,14 @@ do_exec(int argc, char *argv[])
     __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
     baud = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
 
-    printf("Now booting linux kernel:\n");
-    printf(" Base address 0x%08x Entry 0x%08x\n", base_addr, entry);
-    printf(" Cmdline : %s\n", cmd_line);
+    diag_printf("Now booting linux kernel:\n");
+    diag_printf(" Base address 0x%08x Entry 0x%08x\n", base_addr, entry);
+    diag_printf(" Cmdline : %s\n", cmd_line);
 
     if (wait_time_set) {
-        printf("About to start execution at %p - abort with ^C within %d seconds\n",
-               (void *)entry, wait_time);
-        res = gets(line, sizeof(line), wait_time*1000);
+        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
+                    (void *)entry, wait_time);
+        res = _rb_gets(line, sizeof(line), wait_time*1000);
         if (res == _GETS_CTRLC) {
             return;
         }
@@ -126,23 +126,23 @@ do_exec(int argc, char *argv[])
     pcmd = pb->text;
 
     pb->memsize.name = pcmd;
-    pcmd += sprintf(pcmd, "memsize");
+    pcmd += diag_sprintf(pcmd, "memsize");
     pb->memsize.val = ++pcmd;
-    pcmd += sprintf(pcmd, "0x%08x", (ram_end - ram_start + 0xFFFFF) & ~0xFFFFF);
+    pcmd += diag_sprintf(pcmd, "0x%08x", (ram_end - ram_start + 0xFFFFF) & ~0xFFFFF);
 
     pb->modetty0.name = ++pcmd;
-    pcmd += sprintf(pcmd, "modetty0");
+    pcmd += diag_sprintf(pcmd, "modetty0");
     pb->modetty0.val = ++pcmd;
-    pcmd += sprintf(pcmd, "%d,n,8,1,hw", baud);
+    pcmd += diag_sprintf(pcmd, "%d,n,8,1,hw", baud);
 
 #ifdef CYGPKG_REDBOOT_NETWORKING
     pb->ethaddr.name = ++pcmd;
-    pcmd += sprintf(pcmd, "ethaddr");
+    pcmd += diag_sprintf(pcmd, "ethaddr");
     pb->ethaddr.val = ++pcmd;
-    pcmd += sprintf(pcmd, "%02x.%02x.%02x.%02x.%02x.%02x",
-            __local_enet_addr[0], __local_enet_addr[1],
-            __local_enet_addr[2], __local_enet_addr[3],
-            __local_enet_addr[4], __local_enet_addr[5]);
+    pcmd += diag_sprintf(pcmd, "%02x.%02x.%02x.%02x.%02x.%02x",
+                         __local_enet_addr[0], __local_enet_addr[1],
+                         __local_enet_addr[2], __local_enet_addr[3],
+                         __local_enet_addr[4], __local_enet_addr[5]);
     pb->env_end.name = NULL;
     pb->env_end.val = NULL;
 #else
--- a/packages/hal/mips/rm7000/ocelot/current/ChangeLog
+++ b/packages/hal/mips/rm7000/ocelot/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-31  David Woodhouse  <dwmw2@redhat.com>
+
+	* cfl/hal_mips_rm7000_ocelot.cdl: Fix compiler options to use
+	-mips2 for BE build, and make the LE options match the BE options
+	in all but endianness.
+
 2001-08-09  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* include/plf_intr.h: Move HAL_INTERRUPT_ interrupt controller
--- a/packages/hal/mips/rm7000/ocelot/current/cdl/hal_mips_rm7000_ocelot.cdl
+++ b/packages/hal/mips/rm7000/ocelot/current/cdl/hal_mips_rm7000_ocelot.cdl
@@ -256,7 +256,7 @@ cdl_package CYGPKG_HAL_MIPS_RM7000_OCELO
             flavor  data
             no_define
 # -mabi=eabi -mips2
-            default_value { CYGPKG_HAL_MIPS_MSBFIRST ? "-G0 -mips32 -EB -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" : "-mips2 -EL -mabi=eabi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            default_value { CYGPKG_HAL_MIPS_MSBFIRST ? "-G0 -mips2 -EB -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" : "-G0 -mips2 -EL -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
             description   "
                 This option controls the global compiler flags which
                 are used to compile all packages by
--- a/packages/hal/mn10300/stb/current/ChangeLog
+++ b/packages/hal/mn10300/stb/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-09-05  David Howells  <dhowells@redhat.com>
+
+	* src/plf_misc.c: made inclusion here of hal_ctrlc_isr()
+	contingent on the lack of virtual vector support.
+
 2001-08-15  David Howells  <dhowells@redhat.com>
 
 	* src/hal_diag.c: included hal_misc.h.
--- a/packages/hal/mn10300/stb/current/src/plf_misc.c
+++ b/packages/hal/mn10300/stb/current/src/plf_misc.c
@@ -128,7 +128,8 @@ void hal_platform_init(void)
 /*------------------------------------------------------------------------*/
 /* Control C ISR support                                                  */
 
-#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) && \
+    !defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT)
 
 #if CYGHWR_HAL_MN10300_AM33_STB_GDB_PORT == 0
 
--- a/packages/hal/powerpc/mpc8xx/current/ChangeLog
+++ b/packages/hal/powerpc/mpc8xx/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/mpc8xxrev.c: Don't use printf(), but rather diag_printf().
+
 2001-06-29  Jesper Skov  <jskov@redhat.com>
 
 	* src/var_intr.c: Include new arbiter header.
@@ -164,7 +168,7 @@ 2000-02-07  Jesper Skov  <jskov@redhat.c
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/hal/powerpc/mpc8xx/current/src/mpc8xxrev.c
+++ b/packages/hal/powerpc/mpc8xx/current/src/mpc8xxrev.c
@@ -39,6 +39,7 @@
 #include <stdio.h>
 #include <cyg/hal/ppc_regs.h>
 #include <cyg/hal/hal_io.h>
+#include <cyg/infra/diag.h>
 
 int
 main( void )
@@ -49,17 +50,17 @@ main( void )
     CYG_TEST_INIT();
 
     asm volatile ("mfspr %0, 287;": "=r" (pvr));
-    printf ("Processor PVR:         0x%08x\n", pvr);
+    diag_printf("Processor PVR:         0x%08x\n", pvr);
 
     asm volatile ("mfspr %0, 638;": "=r" (part_mask));
-    printf ("Processor IMMR[16:31]: 0x%04x\n", (part_mask & 0xffff));
+    diag_printf("Processor IMMR[16:31]: 0x%04x\n", (part_mask & 0xffff));
 
     HAL_READ_UINT16(CYGARC_REG_REV_NUM, rev_num);
-    printf ("Processor REV_NUM:     0x%04x\n", rev_num);
+    diag_printf("Processor REV_NUM:     0x%04x\n", rev_num);
 
 
-    printf("\nSee http://www.motorola.com/SPS/RISC/netcomm/ for erratas.\n");
-    printf("Look for MPC8xx Versions and Masks in the Publications Library\n");
+    diag_printf("\nSee http://www.motorola.com/SPS/RISC/netcomm/ for erratas.\n");
+    diag_printf("Look for MPC8xx Versions and Masks in the Publications Library\n");
 
     CYG_TEST_PASS_FINISH("mpc8xx revision dump");
 }
--- a/packages/hal/sh/arch/current/ChangeLog
+++ b/packages/hal/sh/arch/current/ChangeLog
@@ -1,3 +1,13 @@
+2001-09-05  Jesper Skov  <jskov@redhat.com>
+
+	* src/sh_stub.c (__single_step): Changed type 2 handling.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_linux_exec.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-07-09  Jesper Skov  <jskov@redhat.com>
 
 	* src/sh_stub.c: Fixed potential SH4 problem in UBC handling.
@@ -833,7 +843,7 @@ 1999-04-22  Jesper Skov  <jskov@lassi.cy
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/hal/sh/arch/current/src/sh_stub.c
+++ b/packages/hal/sh/arch/current/src/sh_stub.c
@@ -133,19 +133,27 @@ void __single_step (void)
     // Match entire address.
 #if (CYGARC_SH_MOD_UBC == 1)
     HAL_WRITE_UINT8(CYGARC_REG_BAMRA, CYGARC_REG_BAMRA_BARA_UNMASKED);
-#else
-    HAL_WRITE_UINT32(CYGARC_REG_BAMRA, 0xffffffff);
+#elif (CYGARC_SH_MOD_UBC == 2)
+    // For some reason, matching all bits causes the system to hang
+    // (not just run amok - it appears to stop execution).
+    //HAL_WRITE_UINT32(CYGARC_REG_BAMRA, 0xffffffff);
+    HAL_WRITE_UINT32(CYGARC_REG_BAMRA, 0);
 #endif
+
     // Stop after instruction at matching address has executed.
-    HAL_WRITE_UINT16(CYGARC_REG_BRCR, CYGARC_REG_BRCR_PCBA);
+#if (CYGARC_SH_MOD_UBC == 1)
+    HAL_WRITE_UINT16(CYGARC_REG_BRCR, CYGARC_REG_BRCR_ONE_STEP);
+#else
+    HAL_WRITE_UINT32(CYGARC_REG_BRCR, CYGARC_REG_BRCR_ONE_STEP);
+#endif
 
     // Stop on IFETCH/READ
-#if (CYGARC_SH_MOD_UBC == 3)
+#if (CYGARC_SH_MOD_UBC == 1)
+    HAL_WRITE_UINT16(CYGARC_REG_BBRA, 
+                     CYGARC_REG_BBRA_IFETCH|CYGARC_REG_BBRA_READ);
+#else
     HAL_WRITE_UINT16(CYGARC_REG_BBRA, 
                      CYGARC_REG_BBRA_CPU|CYGARC_REG_BBRA_IFETCH|CYGARC_REG_BBRA_READ);
-#else
-    HAL_WRITE_UINT16(CYGARC_REG_BBRA, 
-                     CYGARC_REG_BBRA_IFETCH|CYGARC_REG_BBRA_READ);
 #endif
 
 #ifdef CYGPKG_HAL_SH_SH4
--- a/packages/hal/sh/sh3/current/ChangeLog
+++ b/packages/hal/sh/sh3/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-09-05  Jesper Skov  <jskov@redhat.com>
+
+	* include/mod_regs_ubc.h: Type 2 BRCR definitions.
+
+	* include/mod_7729.h (CYGARC_SH_MOD_UBC): Changed to type 2.
+
 2001-07-26  Jesper Skov  <jskov@redhat.com>
 
 	* include/var_cache.h: Fix cache query function.
--- a/packages/hal/sh/sh3/current/include/mod_7729.h
+++ b/packages/hal/sh/sh3/current/include/mod_7729.h
@@ -55,7 +55,7 @@
 #define CYGARC_SH_MOD_PFC  1
 #define CYGARC_SH_MOD_SCI  1
 #define CYGARC_SH_MOD_SCIF 1
-//#define CYGARC_SH_MOD_UBC  3
+#define CYGARC_SH_MOD_UBC  2
 
 
 //-----------------------------------------------------------------------------
--- a/packages/hal/sh/sh3/current/include/mod_regs_ubc.h
+++ b/packages/hal/sh/sh3/current/include/mod_regs_ubc.h
@@ -41,7 +41,7 @@
 
 //--------------------------------------------------------------------------
 // User Break Control
-#define CYGARC_REG_BRCR                 0xffffff98 // 16 bit
+#define CYGARC_REG_BRCR                 0xffffff98 // 16 bit (v1) / 32 bit
 
 #define CYGARC_REG_BARA                 0xffffffb0 // 32 bit
 #define CYGARC_REG_BAMRA                0xffffffb4 // 8 bit (v1) / 32 bit
@@ -55,20 +55,39 @@
 #define CYGARC_REG_BDRB                 0xffffff90 // 32 bit
 #define CYGARC_REG_BDMRB                0xffffff94 // 32 bit
 
+#ifdef CYGARC_SH_MOD_UBC
 
-#define CYGARC_REG_BRCR_CMFA            0x8000 // condition match flag A
-#define CYGARC_REG_BRCR_CMFB            0x4000 // condition match flag B
-#define CYGARC_REG_BRCR_PCBA            0x0400 // post execute channel A
-#define CYGARC_REG_BRCR_DBEB            0x0080 // data break enable B
-#define CYGARC_REG_BRCR_PCBB            0x0040 // post execute channel B
-#define CYGARC_REG_BRCR_SEQ             0x0008 // sequence condition select
+#if (CYGARC_SH_MOD_UBC == 1)
+# define CYGARC_REG_BRCR_CMFA           0x8000 // condition match flag A
+# define CYGARC_REG_BRCR_CMFB           0x4000 // condition match flag B
+# define CYGARC_REG_BRCR_PCBA           0x0400 // post execute channel A
+# define CYGARC_REG_BRCR_DBEB           0x0080 // data break enable B
+# define CYGARC_REG_BRCR_PCBB           0x0040 // post execute channel B
+# define CYGARC_REG_BRCR_SEQ            0x0008 // sequence condition select
+# define CYGARC_REG_BRCR_ONE_STEP       (CYGARC_REG_BRCR_PCBA)
+#else
+# define CYGARC_REG_BRCR_BASMA          0x00200000 // asid not checked
+# define CYGARC_REG_BRCR_BASMB          0x00100000
+# define CYGARC_REG_BRCR_SCMFCA         0x00008000
+# define CYGARC_REG_BRCR_SCMFCB         0x00004000
+# define CYGARC_REG_BRCR_SCMFDA         0x00002000
+# define CYGARC_REG_BRCR_SCMFDB         0x00001000
+# define CYGARC_REG_BRCR_PCTE           0x00000800 // PC trace enable
+# define CYGARC_REG_BRCR_PCBA           0x00000400 // post execute
+# define CYGARC_REG_BRCR_DBEB           0x00000080 // data break
+# define CYGARC_REG_BRCR_PCBB           0x00000040
+# define CYGARC_REG_BRCR_SEQ            0x00000008 // A and B channel in sequence
+# define CYGARC_REG_BRCR_ETBE           0x00000001 // execution count on B matches
+# define CYGARC_REG_BRCR_ONE_STEP       (CYGARC_REG_BRCR_BASMA | CYGARC_REG_BRCR_PCBA)
+#endif
 
-#if defined(CYGARC_SH_MOD_UBC) && (CYGARC_SH_MOD_UBC == 1)
-#define CYGARC_REG_BAMRA_BASMA          0x04   // BASRA masked
-#define CYGARC_REG_BAMRA_BARA_UNMASKED  0x00   // BARA not masked
-#define CYGARC_REG_BAMRA_BARA_10BIT     0x01   // Lowest 10 bit masked
-#define CYGARC_REG_BAMRA_BARA_12BIT     0x02   // Lowest 12 bit masked
-#define CYGARC_REG_BAMRA_BARA_MASKED    0x03   // All bits masked
+
+#if (CYGARC_SH_MOD_UBC == 1)
+# define CYGARC_REG_BAMRA_BASMA          0x04   // BASRA masked
+# define CYGARC_REG_BAMRA_BARA_UNMASKED  0x00   // BARA not masked
+# define CYGARC_REG_BAMRA_BARA_10BIT     0x01   // Lowest 10 bit masked
+# define CYGARC_REG_BAMRA_BARA_12BIT     0x02   // Lowest 12 bit masked
+# define CYGARC_REG_BAMRA_BARA_MASKED    0x03   // All bits masked
 #else
 // mask is fully configurable in other versions of the UBC
 #endif
@@ -85,7 +104,7 @@
 
 //----------------------------------------------------------------------------
 // Other types
-#if defined(CYGARC_SH_MOD_UBC) && (CYGARC_SH_MOD_UBC >= 3)
+#if (CYGARC_SH_MOD_UBC == 2)
 #define CYGARC_REG_BETR                 0xffffff9c // 16 bit
 #define CYGARC_REG_BRSR                 0xffffffac // 32 bit
 #define CYGARC_REG_BRDR                 0xffffffbc // 32 bit
@@ -93,3 +112,5 @@
 #define CYGARC_REG_BBRA_DMA             0x0080 // Break on DMAC cycle
 #define CYGARC_REG_BBRA_CPU             0x0040 // Break on CPU cycle
 #endif
+
+#endif // CYGARC_SH_MOD_UBC
--- a/packages/infra/current/ChangeLog
+++ b/packages/infra/current/ChangeLog
@@ -1,3 +1,43 @@
+2001-08-25  Gary Thomas  <gthomas@redhat.com>
+
+	* src/diag.cxx (_vprintf): Fix confusion between signed and unsigned
+	descriptors (only %d is signed).
+
+2001-08-24  Gary Thomas  <gthomas@redhat.com>
+
+	* include/diag.h: Export diag_dump_buf_with_offset.
+
+	* src/diag.cxx (_vprintf): Fix problems with signed/unsigned prints.
+	(diag_dump_buf_with_offset): Export.
+
+2001-08-23  Gary Thomas  <gthomas@redhat.com>
+
+	* src/diag.cxx (_vprintf): Restore functionality of %D,%U,%X,%B,%S,%C
+	which were present in old code.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/diag.cxx: 
+	* include/diag.h: 
+	* cdl/infra.cdl: Restructuring to support more flexible versions
+	of diag_printf() and related functions.  Remove old cruft which
+	was workaround for possibly failing compilers [K&R support].
+	These versions of printf(), etc, were part of the RedBoot package
+	and have been moved here (and renamed) to reduce code duplication.
+
+2001-08-22  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/eprintf.c: New file to implement __eprintf called from libgcc.
+	* cdl/infra.cdl: Build it.
+	* include/cyg_type.h: Provide __THROW default empty throw specifier.
+	* include/cyg_ass.h (cyg_assert_fail): Add __THROW.
+	(cyg_assert_msg): Ditto.
+	* src/buffer.cxx (cyg_assert_fail): Ditto.
+	* src/fancy.cxx (cyg_assert_fail): Ditto.
+	* src/null.cxx (cyg_assert_fail): Ditto (twice).
+	* src/simple.cxx (cyg_assert_fail): Ditto.
+	* src/tcdiag.cxx (cyg_assert_msg): Ditto.
+
 2001-08-03  Nick Garnett  <nickg@cygnus.co.uk>
 
 	Imported from a development branch:
@@ -731,7 +771,7 @@ 1998-08-20  Nick Garnett  <nickg@cygnus.
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/infra/current/cdl/infra.cdl
+++ b/packages/infra/current/cdl/infra.cdl
@@ -23,7 +23,7 @@
 #                                                                          
 # The Initial Developer of the Original Code is Red Hat.                   
 # Portions created by Red Hat are                                          
-# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 # All Rights Reserved.                                                     
 # -------------------------------------------                              
 #                                                                          
@@ -50,7 +50,7 @@ cdl_package CYGPKG_INFRA {
 
     compile startup.cxx prestart.cxx pkgstart.cxx userstart.cxx      \
             dummyxxmain.cxx null.cxx simple.cxx fancy.cxx buffer.cxx \
-            diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx
+            diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx eprintf.c
 
 
     # ====================================================================
@@ -65,19 +65,6 @@ cdl_package CYGPKG_INFRA {
 #            set up according to the selected HAL."
 #    }
 
-    cdl_option CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG {
-        display       "Use varargs in diag_printf()"
-        default_value 1 
-        description   "
-            The diagnostic routine diag_printf() can be defined
-            using either variadic arguments or a K&R style definition.
-            The former will work in most circumstances, but if variable
-            argument handling is broken or missing then the K&R variant
-            may be used. This will also generate warnings about the
-            declaration of diag_printf() not being a prototype.
-            These may safely be ignored."
-    }
-
     # ====================================================================
     cdl_component CYGPKG_INFRA_DEBUG {
         display       "Asserts & Tracing"
@@ -182,14 +169,6 @@ cdl_package CYGPKG_INFRA {
 
     # ========================================================================
     # Debugging-related miscellania.
-    #
-    # NOTE: this is not yet fully supported, by CDL nor by having a proper
-    # symbol name.
-    #
-    # Define how diag data is directed off of the board. If using an actual
-    # device then a device must be configured to support diag.
-    #
-    #undef CYGDBG_INFRA_DIAG_USE_DEVICE
 
     define_proc {
         puts $::cdl_header "/***** proc output start *****/"
--- a/packages/infra/current/include/cyg_ass.h
+++ b/packages/infra/current/include/cyg_ass.h
@@ -75,7 +75,7 @@
 
 externC void
 cyg_assert_fail( const char* /* psz_func */, const char* /* psz_file */,
-                 cyg_uint32 /* linenum */, const char* /* psz_msg */ )
+                 cyg_uint32 /* linenum */, const char* /* psz_msg */ )  __THROW
     CYGBLD_ATTRIB_NORET CYGBLD_ATTRIB_WEAK;
 
 
--- a/packages/infra/current/include/cyg_type.h
+++ b/packages/infra/current/include/cyg_type.h
@@ -362,6 +362,12 @@ typedef cyg_haladdrword CYG_ADDRWORD;
 # define CYGBLD_ATTRIB_WEAK_ALIAS(__symbol__) \
         CYGBLD_ATTRIB_WEAK CYGBLD_ATTRIB_ALIAS(__symbol__)
 
+#ifdef __cplusplus
+# define __THROW throw()
+#else
+# define __THROW
+#endif
+
 // -------------------------------------------------------------------------
 // Variable annotations
 // These annotations may be added to various static variables in the
--- a/packages/infra/current/include/diag.h
+++ b/packages/infra/current/include/diag.h
@@ -26,7 +26,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -35,7 +35,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):   nickg
-// Contributors:        nickg
+// Contributors:        nickg, gthomas
 // Date:        1998-03-02
 // Purpose:     Diagnostic Routines for Infra Development
 // Description: Diagnostic routines for use during infra development.
@@ -47,14 +47,7 @@
 
 #include <pkgconf/infra.h>
 #include <cyg/infra/cyg_type.h>
-
-#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG
 #include <stdarg.h>
-#endif
-
-#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE
-#include <cyg/io/io_diag.h>
-#endif
 
 /*---------------------------------------------------------------------------*/
 /* Diagnostic routines                                                       */
@@ -70,35 +63,23 @@ externC void diag_write_dec( cyg_int32 n
 externC void diag_write_hex( cyg_uint32 n);   /* Write hexadecimal value   */
 
 externC void diag_dump_buf(void *buf, CYG_ADDRWORD len);
-
-#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG
+externC void diag_dump_buf_with_offset(cyg_uint8     *p, 
+                                       CYG_ADDRWORD   s, 
+                                       cyg_uint8     *base);
 
-externC void diag_printf( const char *fmt, ... );  /* Formatted print      */
-
-#else
+externC int  diag_printf( const char *fmt, ... );  /* Formatted print      */
 
-// This function deliberately has a K&R prototype to avoid having to use
-// varargs, or pad arglists or anything grody like that.
-
-#warning CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG not enabled
-#warning Expect a "function declaration isn't a prototype" warning
+externC void diag_init_putc(void (*putc)(char c, void **param));
+externC int  diag_sprintf(char *buf, const char *fmt, ...);
+externC int  diag_vsprintf(char *buf, const char *fmt, va_list ap);
+externC int  diag_vprintf(const char *fmt, va_list ap);
 
-externC void diag_printf(/* const char *fmt, CYG_ADDRWORD, CYG_ADDRWORD,
-                         CYG_ADDRWORD, CYG_ADDRWORD, CYG_ADDRWORD,
-                         CYG_ADDRWORD, CYG_ADDRWORD, CYG_ADDRWORD */);
-
-#endif
 
 /*---------------------------------------------------------------------------*/
 /* Internal Diagnostic MACROS                                                */
 
-#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE
-#define DIAG_DEVICE_START_SYNC()        diag_device_start_sync()
-#define DIAG_DEVICE_END_SYNC()          diag_device_end_sync()
-#else
 #define DIAG_DEVICE_START_SYNC()
 #define DIAG_DEVICE_END_SYNC()
-#endif
 
 /*---------------------------------------------------------------------------*/
 #endif /* CYGONCE_INFRA_DIAG_H */
--- a/packages/infra/current/src/buffer.cxx
+++ b/packages/infra/current/src/buffer.cxx
@@ -711,7 +711,7 @@ cyg_trace_dump(void)
 
 externC void
 cyg_assert_fail( const char *psz_func, const char *psz_file,
-                 cyg_uint32 linenum, const char *psz_msg )
+                 cyg_uint32 linenum, const char *psz_msg ) __THROW
 {
     cyg_uint32 old_ints;
 
--- a/packages/infra/current/src/diag.cxx
+++ b/packages/infra/current/src/diag.cxx
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.  
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -31,8 +31,8 @@
 //========================================================================
 //#####DESCRIPTIONBEGIN####
 //
-// Author(s):    nickg
-// Contributors: nickg
+// Author(s):    nickg,gthomas,jlarmour
+// Contributors: 
 // Date:         1999-02-22
 // Purpose:      Infrastructure diagnostic output
 // Description:  Implementations of infrastructure diagnostic routines.
@@ -46,26 +46,18 @@
 #include <pkgconf/infra.h>
 
 #include <cyg/infra/cyg_type.h>         // base types
-
+  
 #include <cyg/infra/diag.h>             // HAL polled output
 #include <cyg/hal/hal_arch.h>           // architectural stuff for...
 #include <cyg/hal/hal_intr.h>           // interrupt control
 #include <cyg/hal/hal_diag.h>           // diagnostic output routines
-
-#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG
-
 #include <stdarg.h>
-
-#endif
-
-#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE
-#include <cyg/io/io_diag.h>
-#endif
-
+#include <limits.h>
+  
 #ifdef CYG_HAL_DIAG_LOCK_DATA_DEFN
 CYG_HAL_DIAG_LOCK_DATA_DEFN;
 #endif
-
+  
 /*----------------------------------------------------------------------*/
 
 externC void diag_write_num(
@@ -79,30 +71,10 @@ externC void diag_write_num(
 class Cyg_dummy_diag_init_class {
 public:
     Cyg_dummy_diag_init_class() {
-#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE
-        diag_device_init(); 
-#else
         HAL_DIAG_INIT();
-#endif
     }
 };
 
-#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE
-
-// Initialize after IO devices.
-static Cyg_dummy_diag_init_class cyg_dummy_diag_init_obj 
-                                      CYGBLD_ATTRIB_INIT_AFTER(CYG_INIT_IO);
-
-/*----------------------------------------------------------------------*/
-/* Write single char to output                                          */
-
-externC void diag_write_char(char c)
-{
-    diag_device_write_char(c);
-}
-
-#else
-
 // Initialize after HAL.
 static Cyg_dummy_diag_init_class cyg_dummy_diag_init_obj 
                                       CYGBLD_ATTRIB_INIT_AFTER(CYG_INIT_HAL);
@@ -110,23 +82,24 @@ static Cyg_dummy_diag_init_class cyg_dum
 /*----------------------------------------------------------------------*/
 /* Write single char to output                                          */
 
-#define PREFIX()
-//#define PREFIX() HAL_DIAG_WRITE_CHAR(0x0F)
-
 externC void diag_write_char(char c)
 {    
     /* Translate LF into CRLF */
     
     if( c == '\n' )
     {
-        PREFIX();
         HAL_DIAG_WRITE_CHAR('\r');        
     }
 
-    PREFIX();
     HAL_DIAG_WRITE_CHAR(c);
 }
-#endif
+
+// Default wrapper function used by diag_printf
+static void
+_diag_write_char(char c, void **param)
+{
+    diag_write_char(c);
+}
 
 /*----------------------------------------------------------------------*/
 /* Initialize. Call to pull in diag initializing constructor            */
@@ -135,6 +108,18 @@ externC void diag_init(void)
 {
 }
 
+//
+// This routine is used to send characters during 'printf()' functions.
+// It can be replaced by providing a replacement via diag_init_putc().
+//
+static void (*_putc)(char c, void **param) = _diag_write_char;
+
+void
+diag_init_putc(void (*putc)(char c, void **param))
+{
+    _putc = putc;
+}
+
 /*----------------------------------------------------------------------*/
 /* Write zero terminated string                                         */
   
@@ -264,256 +249,310 @@ static cyg_bool diag_check_string( const
 
 /*----------------------------------------------------------------------*/
 
-externC void diag_vprintf( const char *fmt, CYG_ADDRWORD *args)
+static int
+_cvt(unsigned long long val, char *buf, long radix, char *digits)
 {
+    char temp[80];
+    char *cp = temp;
+    int length = 0;
 
-    cyg_bool pad = true;
+    if (val == 0) {
+        /* Special case */
+        *cp++ = '0';
+    } else {
+        while (val) {
+            *cp++ = digits[val % radix];
+            val /= radix;
+        }
+    }
+    while (cp != temp) {
+        *buf++ = *--cp;
+        length++;
+    }
+    *buf = '\0';
+    return (length);
+}
 
-    if( !diag_check_string(fmt) )
-    {
-        int i;
+#define is_digit(c) ((c >= '0') && (c <= '9'))
+
+static int
+_vprintf(void (*putc)(char c, void **param), void **param, const char *fmt, va_list ap)
+{
+    char buf[sizeof(long long)*8];
+    char c, sign, *cp=buf;
+    int left_prec, right_prec, zero_fill, pad, pad_on_right, 
+        i, islong, islonglong;
+    long long val = 0;
+    int res = 0, length = 0;
+
+    if (!diag_check_string(fmt)) {
         diag_write_string("<Bad format string: ");
         diag_write_hex((cyg_uint32)fmt);
         diag_write_string(" :");
-        for( i = 0; i < 8; i++ )
-        {
+        for( i = 0; i < 8; i++ ) {
             diag_write_char(' ');
-            diag_write_hex(args[i]);
+            val = va_arg(ap, unsigned long);
+            diag_write_hex(val);
         }
         diag_write_string(">\n");
-        return;
+        return 0;
     }
-    
-    while( *fmt != '\0' )
-    {
-        char c = *fmt;
-
-        if( c != '%' ) diag_write_char( c );
-        else
-        {
-            cyg_bool pfzero = false;
-            cyg_count8 width = 0;
-            char sign = '+';
-            cyg_bool long_op = false;
-                        
-            c = *++fmt;
-                        
-            if( c == '0' ) pfzero = true;
-
-            while( '0' <= c && c <= '9' )
-            {
-                width = width*10 + c - '0';
-                c = *++fmt;
+    while ((c = *fmt++) != '\0') {
+        if (c == '%') {
+            c = *fmt++;
+            left_prec = right_prec = pad_on_right = islong = islonglong = 0;
+            if (c == '-') {
+                c = *fmt++;
+                pad_on_right++;
+            }
+            if (c == '0') {
+                zero_fill = true;
+                c = *fmt++;
+            } else {
+                zero_fill = false;
+            }
+            while (is_digit(c)) {
+                left_prec = (left_prec * 10) + (c - '0');
+                c = *fmt++;
             }
-
+            if (c == '.') {
+                c = *fmt++;
+                zero_fill++;
+                while (is_digit(c)) {
+                    right_prec = (right_prec * 10) + (c - '0');
+                    c = *fmt++;
+                }
+            } else {
+                right_prec = left_prec;
+            }
+            sign = '\0';
             if (c == 'l') {
-                // %lx and %ld are equivalent to %x/%d
-                c = *++fmt;
-                // %llx or %lld used to indicate (long long) operand
+                // 'long' qualifier
+                c = *fmt++;
+		islong = 1;
                 if (c == 'l') {
-                    long_op = true;
-                    c = *++fmt;
+                    // long long qualifier
+                    c = *fmt++;
+                    islonglong = 1;
                 }
             }
-
-            if (long_op) {
-                    if(pad) args++;
-                    pad=false;
-            } else {
-                    pad=!pad;
-            }
-               
-            switch( c )
-            {
+            // Fetch value [numeric descriptors only]
+            switch (c) {
+            case 'p':
+		islong = 1;
             case 'd':
             case 'D':
-            {
-                if (long_op) {
-                    long long *lp = (long long *)args;
-                    long long val = *lp++;
-                    args = (CYG_ADDRWORD *)lp;
-                    if( val < 0 ) val = -val, sign = '-';
-                    diag_write_long_num(val, 10, sign, pfzero, width);
+            case 'x':
+            case 'X':
+            case 'u':
+            case 'U':
+            case 'b':
+            case 'B':
+                if (islonglong) {
+                    val = va_arg(ap, long long);
+	        } else if (islong) {
+                    val = (long long)va_arg(ap, long);
+		} else{
+                    val = (long long)va_arg(ap, int);
+                }
+                if ((c == 'd') || (c == 'D')) {
+                    if (val < 0) {
+                        sign = '-';
+                        val = -val;
+                    }
                 } else {
-                    long val = (long)(*args++);
-                    if( val < 0 ) val = -val, sign = '-';
-                    diag_write_num(val, 10, sign, pfzero, width);
+                    // Mask to unsigned, sized quantity
+                    if (islong) {
+                        val &= ((long long)1 << (sizeof(long) * 8)) - 1;
+                    } else{
+                        val &= ((long long)1 << (sizeof(int) * 8)) - 1;
+                    }
                 }
                 break;
+            default:
+                break;
             }
-
+            // Process output
+            switch (c) {
+            case 'p':  // Pointer
+                (*putc)('0', param);
+                (*putc)('x', param);
+                zero_fill = true;
+                left_prec = sizeof(unsigned long)*2;
+            case 'd':
+            case 'D':
+            case 'u':
+            case 'U':
             case 'x':
             case 'X':
-            {
-                if (long_op) {
-                    long long *lp = (long long *)args;
-                    long long val = *lp++;
-                    args = (CYG_ADDRWORD *)lp;
-                    diag_write_long_num(val, 16, sign, pfzero, width);
-                } else {
-                    unsigned long val = (long)(*args++);
-                    diag_write_num(val, 16, sign, pfzero, width);
+                switch (c) {
+                case 'd':
+                case 'D':
+                case 'u':
+                case 'U':
+                    length = _cvt(val, buf, 10, "0123456789");
+                    break;
+                case 'p':
+                case 'x':
+                    length = _cvt(val, buf, 16, "0123456789abcdef");
+                    break;
+                case 'X':
+                    length = _cvt(val, buf, 16, "0123456789ABCDEF");
+                    break;
                 }
+                cp = buf;
                 break;
-            }
-
-            case 'c':
-            case 'C':
-            {
-                char ch = (char)(*args++);
-                diag_write_char(ch);
-                break;
-            }
-
             case 's':
             case 'S':
-            {
-                char *s = (char *)(*args++);
-                cyg_count32 len = 0;
-                cyg_count32 pre = 0, post = 0;
-
-                if( s == NULL ) s = "<null>";
-                else if( !diag_check_string(s) )
-                {
+                cp = va_arg(ap, char *);
+                if (cp == NULL) 
+                    cp = "<null>";
+                else if (!diag_check_string(cp)) {
                     diag_write_string("<Not a string: 0x");
-                    diag_write_hex((cyg_uint32)s);
-                    s = ">";
-                    if( width > 25 ) width -= 25;
-                    pfzero = false;
-                    /* Drop through to print the closing ">" */
-                    /* and pad to the required length.       */
+                    diag_write_hex((cyg_uint32)cp);
+                    cp = ">";
                 }
-                
-                while( s[len] != 0 ) len++;
-                
-                if( width && len > width ) len = width;
-
-                if( pfzero ) pre = width-len;
-                else post = width-len;
-
-                while( pre-- > 0 ) diag_write_char(' ');
-
-                while( *s != '\0' && len-- != 0)
-                    diag_write_char(*s++);
-
-                while( post-- > 0 ) diag_write_char(' ');
-                                
+                length = 0;
+                while (cp[length] != '\0') length++;
                 break;
-            }
-
+            case 'c':
+            case 'C':
+                c = va_arg(ap, int /*char*/);
+                (*putc)(c, param);
+                res++;
+                continue;
             case 'b':
             case 'B':
-            {
-                unsigned long val = (unsigned long)(*args++);
-                cyg_uint32 i;
-                if( width == 0 ) width = 32;
-
-                for( i = width-1; i >= 0; i-- )
-                    diag_write_char( (val&(1<<i))?'1':'.' );
-                                
+                length = left_prec;
+                if (left_prec == 0) {
+                    if (islonglong)
+                        length = sizeof(long long)*8;
+                    else if (islong)
+                        length = sizeof(long)*8;
+                    else
+                        length = sizeof(int)*8;
+                }
+                for (i = 0;  i < length-1;  i++) {
+                    buf[i] = ((val & ((long long)1<<i)) ? '1' : '.');
+                }
+                cp = buf;
                 break;
-            }
-
             case '%':
-                diag_write_char('%');
-                break;
-
-            default:
-                diag_write_char('%');
-                diag_write_char(c);
+                (*putc)('%', param);
                 break;
+            default:
+                (*putc)('%', param);
+                (*putc)(c, param);
+                res += 2;
             }
+            pad = left_prec - length;
+            if (sign != '\0') {
+                pad--;
+            }
+            if (zero_fill) {
+                c = '0';
+                if (sign != '\0') {
+                    (*putc)(sign, param);
+                    res++;
+                    sign = '\0';
+                }
+            } else {
+                c = ' ';
+            }
+            if (!pad_on_right) {
+                while (pad-- > 0) {
+                    (*putc)(c, param);
+                    res++;
+                }
+            }
+            if (sign != '\0') {
+                (*putc)(sign, param);
+                res++;
+            }
+            while (length-- > 0) {
+                c = *cp++;
+                if (c == '\n') {
+                    (*putc)('\r', param);
+                    res++;
+                }
+                (*putc)(c, param);
+                res++;
+            }
+            if (pad_on_right) {
+                while (pad-- > 0) {
+                    (*putc)(' ', param);
+                    res++;
+                }
+            }
+        } else {
+            if (c == '\n') {
+                (*putc)('\r', param);
+                res++;
+            }
+            (*putc)(c, param);
+            res++;
         }
-
-        fmt++;
-    }   
-    
+    }
+    return (res);
 }
 
-/*-----------------------------------------------------------------------*/
-/* Formatted diagnostic output.                                          */
-
-#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG
-
-externC void diag_printf(const char *fmt, ... )
+static void 
+_sputc(char c, void **param)
 {
-    
-    CYG_ADDRWORD args[8];
+    char *_sprintf_ptr = (char *)*param;
 
-    va_list a;
-
-    va_start(a, fmt);
+    *_sprintf_ptr++ = c;
+    *_sprintf_ptr = '\0';
+    *param = _sprintf_ptr;
+}
 
-    /* Move all of the arguments into simple scalars. This avoids
-     * having to use varargs to define diag_vprintf().
-     */
-    
-    args[0] = va_arg(a,CYG_ADDRWORD);
-    args[1] = va_arg(a,CYG_ADDRWORD);
-    args[2] = va_arg(a,CYG_ADDRWORD);
-    args[3] = va_arg(a,CYG_ADDRWORD);
-    args[4] = va_arg(a,CYG_ADDRWORD);
-    args[5] = va_arg(a,CYG_ADDRWORD);
-    args[6] = va_arg(a,CYG_ADDRWORD);
-    args[7] = va_arg(a,CYG_ADDRWORD);
+int
+diag_sprintf(char *buf, const char *fmt, ...)
+{        
+    int ret;
+    va_list ap;
+    char *_sprintf_ptr;
 
-    va_end(a);
-
-#ifdef CYG_HAL_DIAG_LOCK
-    CYG_HAL_DIAG_LOCK();
-#endif    
-    
-    diag_vprintf( fmt, args);
-
-#ifdef CYG_HAL_DIAG_UNLOCK
-    CYG_HAL_DIAG_UNLOCK();
-#endif    
-    
+    va_start(ap, fmt);
+    _sprintf_ptr = buf;
+    ret = _vprintf(_sputc, (void **)&_sprintf_ptr, fmt, ap);
+    va_end(ap);
+    return (ret);
 }
 
-#else
-
-/* The prototype for diag_printf in diag.h is defined using K&R syntax   */
-/* to allow us to use a variable number of arguments in the call without */
-/* using ellipses, which would require use of varargs stuff. If we ever  */
-/* need to support arguments that are not simple words, we may need to   */
-/* use varargs.                                                          */
-/* For the actual implementation, a normal ANSI C prototype is           */
-/* acceptable.                                                            */
-
-externC void diag_printf(const char *fmt, CYG_ADDRWORD a1, CYG_ADDRWORD a2,
-                         CYG_ADDRWORD a3, CYG_ADDRWORD a4,
-                         CYG_ADDRWORD a5, CYG_ADDRWORD a6,
-                         CYG_ADDRWORD a7, CYG_ADDRWORD a8)
+int 
+diag_vsprintf(char *buf, const char *fmt, va_list ap)
 {
-    
-    CYG_ADDRWORD args[8];
+    int ret;
+    char *_sprintf_ptr;
 
-    args[0] = a1;
-    args[1] = a2;
-    args[2] = a3;
-    args[3] = a4;
-    args[4] = a5;
-    args[5] = a6;
-    args[6] = a7;
-    args[7] = a8;
-
-
-#ifdef CYG_HAL_DIAG_LOCK
-    CYG_HAL_DIAG_LOCK();
-#endif    
-    
-    diag_vprintf( fmt, args);
-
-#ifdef CYG_HAL_DIAG_UNLOCK
-    CYG_HAL_DIAG_UNLOCK();
-#endif    
-
+    _sprintf_ptr = buf;
+    ret = _vprintf(_sputc, (void **)&_sprintf_ptr, fmt, ap);
+    return (ret);
 }
 
-#endif
+int
+diag_printf(const char *fmt, ...)
+{
+    va_list ap;
+    int ret;
 
-static void
+    va_start(ap, fmt);
+    ret = _vprintf(_putc, (void **)0, fmt, ap);
+    va_end(ap);
+    return (ret);
+}
+
+int
+diag_vprintf(const char *fmt, va_list ap)
+{
+    int ret;
+
+    ret = _vprintf(_putc, (void **)0, fmt, ap);
+    return (ret);
+}
+
+void
 diag_dump_buf_with_offset(cyg_uint8     *p, 
                           CYG_ADDRWORD   s, 
                           cyg_uint8     *base)
new file mode 100644
--- /dev/null
+++ b/packages/infra/current/src/eprintf.c
@@ -0,0 +1,83 @@
+//========================================================================
+//
+//      eprintf.c
+//
+//      __eprintf() used by libgcc
+//
+//========================================================================
+//####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) 2001 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jlarmour
+// Contributors:  
+// Date:          2001-08-21
+// Purpose:       Provide __eprintf() as used by libgcc.
+// Description:   libgcc calls __eprintf() to display errors and abort.
+// Usage:       
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/system.h>
+/* We can't do anything without the isoinfra package */
+#ifdef CYGPKG_ISOINFRA 
+#include <pkgconf/isoinfra.h>   // Configuration header
+
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h>    // Common type definitions and support
+#include <cyg/infra/cyg_ass.h>     // Default assertion
+#include <stdio.h>
+#include <stdlib.h>
+
+// FUNCTIONS
+
+__externC void
+__eprintf (const char *string, const char *expression,
+           unsigned int line, const char *filename)
+{
+#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
+    fprintf(stderr, string, expression, line, filename);
+#else
+    diag_printf(string, expression, line, filename);
+#endif
+#ifdef CYGINT_ISO_STDIO_FILEACCESS
+    fflush (stderr);
+#endif
+#if CYGINT_ISO_EXIT
+    abort();
+#else
+    CYG_FAIL( "Aborting" );
+    for (;;);
+#endif
+} // __eprintf()
+
+#endif // ifdef CYGPKG_ISOINFRA 
+
+// EOF eprintf.c
--- a/packages/infra/current/src/fancy.cxx
+++ b/packages/infra/current/src/fancy.cxx
@@ -589,7 +589,7 @@ cyg_trace_dump(void)
 
 externC void
 cyg_assert_fail( const char *psz_func, const char *psz_file,
-                 cyg_uint32 linenum, const char *psz_msg )
+                 cyg_uint32 linenum, const char *psz_msg ) __THROW
 {
     cyg_uint32 old_ints;
 
--- a/packages/infra/current/src/null.cxx
+++ b/packages/infra/current/src/null.cxx
@@ -57,7 +57,7 @@
 
 externC void
 cyg_assert_fail( const char *psz_func, const char *psz_file,
-                 cyg_uint32 linenum, const char *psz_msg )
+                 cyg_uint32 linenum, const char *psz_msg ) __THROW
 {
     for(;;);
 };
@@ -132,7 +132,7 @@ cyg_trace_dump(void)
 
 externC void
 cyg_assert_fail( const char *psz_func, const char *psz_file,
-                 cyg_uint32 linenum, const char *psz_msg )
+                 cyg_uint32 linenum, const char *psz_msg ) __THROW
 {
     for(;;);
 };
--- a/packages/infra/current/src/simple.cxx
+++ b/packages/infra/current/src/simple.cxx
@@ -490,7 +490,7 @@ cyg_trace_dump(void)
 
 externC void
 cyg_assert_fail( const char *psz_func, const char *psz_file,
-                 cyg_uint32 linenum, const char *psz_msg )
+                 cyg_uint32 linenum, const char *psz_msg ) __THROW
 {
     cyg_uint32 old_ints;
 
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,28 @@
+2001-09-05  Gary Thomas  <gthomas@redhat.com>
+
+	* src/stand_alone/eth_drv.c (eth_drv_init): Don't initialize
+	structures if ESA is zero.  This is used by low level drivers
+	to indicate that a device is present, but can't currently be
+	used.  The eCos driver handles this case as well.
+
+2001-08-31  Hugo Tyson  <hmt@redhat.com>
+2001-08-31  Andrew Lunn <Andrew.Lunn@ascom.ch>
+
+	* src/net/eth_drv.c (eth_drv_tx_done): Guard against a NULL key
+	return - which can be caused by race conditions in the driver,
+	this is the neatest fixup.  It's good defensive programming
+	anyway and ASCOM's tests indicate a benefit for CASE 106059.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/stand_alone/eth_drv.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
+	* cdl/eth_drivers.cdl: Only enable warning/debug modes if RedBoot
+	is present as the debug environment (since there are implicit
+	dependencies on RedBoot functions).
+
 2001-08-20  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/net/eth_drv.c (eth_drv_send): Move endif location to fix build
@@ -356,7 +381,7 @@ 2000-02-08  John Dallaway  <jld@cygnus.c
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/io/eth/current/cdl/eth_drivers.cdl
+++ b/packages/io/eth/current/cdl/eth_drivers.cdl
@@ -23,7 +23,7 @@
 #                                                                          
 # The Initial Developer of the Original Code is Red Hat.                   
 # Portions created by Red Hat are                                          
-# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 # All Rights Reserved.                                                     
 # -------------------------------------------                              
 #                                                                          
@@ -145,6 +145,7 @@ cdl_package CYGPKG_IO_ETH_DRIVERS {
 
         cdl_option CYGSEM_IO_ETH_DRIVERS_WARN {
             display          "Show driver warnings"
+            active_if        CYGPKG_REDBOOT
             flavor           bool
             default_value    0
             description      "
@@ -155,6 +156,7 @@ cdl_package CYGPKG_IO_ETH_DRIVERS {
 
         cdl_option CYGSEM_IO_ETH_DRIVERS_DEBUG {
             display          "Print driver debug information"
+            active_if        CYGPKG_REDBOOT
             flavor           booldata
             default_value    { 0 != CYGPKG_REDBOOT ? 1 : 0}
             description      "
--- a/packages/io/eth/current/src/net/eth_drv.c
+++ b/packages/io/eth/current/src/net/eth_drv.c
@@ -626,8 +626,13 @@ eth_drv_tx_done(struct eth_drv_sc *sc, C
     // Check for errors here (via 'status')
     ifp->if_opackets++;
     // Done with packet
-    mbuf_key = m0;
-    m_freem(m0);
+
+    // Guard against a NULL return - can be caused by race conditions in
+    // the driver, this is the neatest fixup:
+    if (m0) { 
+        mbuf_key = m0;
+        m_freem(m0);
+    }
     // Start another if possible
     eth_drv_send(ifp);
     CYGARC_HAL_RESTORE_GP();
--- a/packages/io/eth/current/src/stand_alone/eth_drv.c
+++ b/packages/io/eth/current/src/stand_alone/eth_drv.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -114,10 +114,10 @@ static struct eth_msg eth_msgs[NUM_ETH_M
 // Prototypes for functions used in this module
 static void eth_drv_start(struct eth_drv_sc *sc);
 
+// These functions are defined in RedBoot and control access to
+// the "default" console.
 extern int  start_console(void);
 extern void end_console(int);
-extern void printf(char *fmt, ...);
-extern void dump_buf(CYG_ADDRWORD, int);
 
 // Simple queue management functions
 
@@ -170,11 +170,14 @@ eth_drv_buffers_init(void)
 static void
 eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
 {
-    // Set up hardware address
-    memcpy(&sc->sc_arpcom.esa, enaddr, ETHER_ADDR_LEN);
-    memcpy(__local_enet_addr, enaddr, ETHER_ADDR_LEN);
-    __local_enet_sc = sc;
-    eth_drv_start(sc);
+    // enaddr == 0 -> hardware init was incomplete (no ESA)
+    if (enaddr != 0) {
+        // Set up hardware address
+        memcpy(&sc->sc_arpcom.esa, enaddr, ETHER_ADDR_LEN);
+        memcpy(__local_enet_addr, enaddr, ETHER_ADDR_LEN);
+        __local_enet_sc = sc;
+        eth_drv_start(sc);
+    }
 }
 
 #if 0 // Not currently used.  Left in case it's needed in the future
@@ -246,9 +249,9 @@ eth_drv_write(char *eth_hdr, char *buf, 
     if (net_debug) {
         int old_console;
         old_console = start_console();
-        printf("Ethernet send:\n");
-        dump_buf((CYG_ADDRWORD)eth_hdr, 14);
-        dump_buf((CYG_ADDRWORD)buf, len);
+        diag_printf("Ethernet send:\n");
+        diag_dump_buf((CYG_ADDRWORD)eth_hdr, 14);
+        diag_dump_buf((CYG_ADDRWORD)buf, len);
         end_console(old_console);
     }
 #endif
@@ -297,7 +300,7 @@ eth_drv_tx_done(struct eth_drv_sc *sc, C
         if (net_debug) {
             int old_console;
             old_console = start_console();
-            printf("tx_done for other key: %x\n", key);
+            diag_printf("tx_done for other key: %x\n", key);
             end_console(old_console);
         }
 #endif
@@ -405,7 +408,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
 #ifdef CYGSEM_IO_ETH_DRIVERS_WARN
         int old_console;
         old_console = start_console();
-        printf("%s: packet of %d bytes dropped\n", __FUNCTION__, total_len);
+        diag_printf("%s: packet of %d bytes dropped\n", __FUNCTION__, total_len);
         end_console(old_console);
 #endif
         buf = (char *)0;  // Drivers know this means "the bit bucket"
@@ -419,9 +422,9 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
     if (net_debug) {
         int old_console;
         old_console = start_console();
-        printf("Ethernet recv:\n");
-        dump_buf((CYG_ADDRWORD)buf, 14);
-        dump_buf((CYG_ADDRWORD)buf+14, total_len-14);
+        diag_printf("Ethernet recv:\n");
+        diag_dump_buf((CYG_ADDRWORD)buf, 14);
+        diag_dump_buf((CYG_ADDRWORD)buf+14, total_len-14);
         end_console(old_console);
     }
 #endif
@@ -448,7 +451,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
         eth_drv_msg_put(&eth_msg_full, msg);
 #ifdef CYGSEM_IO_ETH_DRIVERS_WARN
     } else {
-        dump_buf(sg_list[0].buf, sg_list[0].len);
+        diag_dump_buf(sg_list[0].buf, sg_list[0].len);
 #endif
     }
     CYGARC_HAL_RESTORE_GP();
@@ -469,8 +472,8 @@ void eth_drv_dsr(cyg_vector_t vector,
                  cyg_ucount32 count,
                  cyg_addrword_t data)
 {
-    printf( "eth_drv_dsr should not be called: vector %d, data %x\n",
-            vector, data );
+    diag_printf("eth_drv_dsr should not be called: vector %d, data %x\n",
+                vector, data );
 }
 
 
--- a/packages/io/pci/current/ChangeLog
+++ b/packages/io/pci/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/pci.c: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.
+
 2001-02-28  Hugo Tyson  <hmt@redhat.com>
 
 	* tests/pci1.c (pci_scan): Added a new function to re-scan the
@@ -262,7 +268,7 @@ 1999-08-12  Jesper Skov  <jskov@cygnus.c
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/io/pci/current/src/pci.c
+++ b/packages/io/pci/current/src/pci.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -416,7 +416,7 @@ cyg_pci_find_next( cyg_pci_device_id cur
     cyg_uint8 fn = CYG_PCI_DEV_GET_FN(devfn);
 
 #ifdef CYGPKG_IO_PCI_DEBUG
-    printf("cyg_pci_find_next: start[%x] ...\n",(unsigned)cur_devid);
+    diag_printf("cyg_pci_find_next: start[%x] ...\n",(unsigned)cur_devid);
 #endif
 
     // If this is the initializer, start with 0/0/0
@@ -459,7 +459,7 @@ cyg_pci_find_next( cyg_pci_device_id cur
                                              CYG_PCI_CFG_VENDOR, &vendor);
                 if (CYG_PCI_VENDOR_UNDEFINED != vendor) {
 #ifdef CYGPKG_IO_PCI_DEBUG
-                printf("   Bus: %d, Dev: %d, Fn: %d, Vendor: %x\n", bus, dev, fn, vendor);
+                diag_printf("   Bus: %d, Dev: %d, Fn: %d, Vendor: %x\n", bus, dev, fn, vendor);
 #endif
                     *next_devid = CYG_PCI_DEV_MAKE_ID(bus, devfn);
                     return true;
@@ -469,7 +469,7 @@ cyg_pci_find_next( cyg_pci_device_id cur
     }
 
 #ifdef CYGPKG_IO_PCI_DEBUG
-    printf("nothing.\n");
+    diag_printf("nothing.\n");
 #endif
 
     return false;
@@ -486,7 +486,7 @@ cyg_pci_find_device( cyg_uint16 vendor, 
     cyg_pci_device_id new_devid = *devid;
 
 #ifdef CYGPKG_IO_PCI_DEBUG
-    printf("cyg_pci_find_device - vendor: %x, device: %x\n", vendor, device);
+    diag_printf("cyg_pci_find_device - vendor: %x, device: %x\n", vendor, device);
 #endif
     // Scan entire bus, check for matches on valid devices.
     while (cyg_pci_find_next(new_devid, &new_devid)) {
@@ -500,7 +500,7 @@ cyg_pci_find_device( cyg_uint16 vendor, 
         cyg_pcihw_read_config_uint16(bus, devfn,
                                      CYG_PCI_CFG_DEVICE, &d);
 #ifdef CYGPKG_IO_PCI_DEBUG
-        printf("... PCI vendor = %x, device = %x\n", v, d);
+        diag_printf("... PCI vendor = %x, device = %x\n", v, d);
 #endif
         if (v != vendor) continue;
 
@@ -542,7 +542,7 @@ cyg_pci_find_matching( cyg_pci_match_fun
     cyg_pci_device_id new_devid = *devid;
 
 #ifdef CYGPKG_IO_PCI_DEBUG
-    printf("cyg_pci_find_matching - func is at %x\n", (unsigned int)matchp);
+    diag_printf("cyg_pci_find_matching - func is at %x\n", (unsigned int)matchp);
 #endif
     // Scan entire bus, check for matches on valid devices.
     while (cyg_pci_find_next(new_devid, &new_devid)) {
@@ -560,7 +560,7 @@ cyg_pci_find_matching( cyg_pci_match_fun
                                      CYG_PCI_CFG_CLASS_REV, &c);
         c >>= 8;
 #ifdef CYGPKG_IO_PCI_DEBUG
-        printf("... PCI vendor = %x, device = %x, class %x\n", v, d, c);
+        diag_printf("... PCI vendor = %x, device = %x, class %x\n", v, d, c);
 #endif
         // Check that device matches as the caller desires:
         if ( (*matchp)(v, d, c, match_callback_data) ) {
@@ -819,7 +819,7 @@ cyg_pci_configure_bus( cyg_uint8 bus,
     devid = CYG_PCI_DEV_MAKE_ID(bus, 0) | CYG_PCI_NULL_DEVFN;
 
 #ifdef CYGPKG_IO_PCI_DEBUG
-    printf("Configuring bus %d.\n", bus);
+    diag_printf("Configuring bus %d.\n", bus);
 #endif
 
     while (cyg_pci_find_next(devid, &devid) && bus == CYG_PCI_DEV_GET_BUS(devid)) {
@@ -830,12 +830,12 @@ cyg_pci_configure_bus( cyg_uint8 bus,
 	cyg_pci_get_device_info(devid, &dev_info);
 
 #ifdef CYGPKG_IO_PCI_DEBUG
-	printf("\n");
-	printf("Configuring PCI Bus   : %d\n", bus);
-	printf("            PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));
-	printf("            PCI Func  : %d\n", CYG_PCI_DEV_GET_FN(devfn));
-	printf("            Vendor Id : 0x%08X\n", dev_info.vendor);
-	printf("            Device Id : 0x%08X\n", dev_info.device);
+	diag_printf("\n");
+	diag_printf("Configuring PCI Bus   : %d\n", bus);
+	diag_printf("            PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));
+	diag_printf("            PCI Func  : %d\n", CYG_PCI_DEV_GET_FN(devfn));
+	diag_printf("            Vendor Id : 0x%08X\n", dev_info.vendor);
+	diag_printf("            Device Id : 0x%08X\n", dev_info.device);
 #endif
 
 	header_type = dev_info.header_type & CYG_PCI_CFG_HEADER_TYPE_MASK;
@@ -1012,7 +1012,7 @@ cyg_pci_configure_bus( cyg_uint8 bus,
 	}
     }
 #ifdef CYGPKG_IO_PCI_DEBUG
-    printf("Finished configuring bus %d.\n", bus);
+    diag_printf("Finished configuring bus %d.\n", bus);
 #endif
 
     return true;
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,8 +1,134 @@
+2001-09-05  Jesper Skov  <jskov@redhat.com>
+
+	* include/mqueue.inl (Cyg_Mqueue): Initialize busy flag of last
+	entry in the list.
+
+2001-09-04  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/instrument.cdl (CYGDBG_KERNEL_INSTRUMENT_BUILD_HOST_DUMP): 
+	Remove redundant requires, and adjust make rule to be more portable
+	across hosts.
+	(CYGDBG_KERNEL_INSTRUMENT_MSGS_BUILD_HEADERFILE):
+	Invoke script with sh directly rather than rely on executable attribute.
+
+	* host/instr/readme.txt: Update build of host dump as per the changed
+	CDL.
+
+	* cdl/kernel.cdl: Don't build nullinst.cxx any more.
+	Build meminst.cxx only in CYGPKG_KERNEL_INSTRUMENT.
+	* src/instrmnt/nullinst.cxx: Delete. It causes confusion in the
+	library as it declares cyg_instrument like meminst.cxx does.
+
+2001-08-31  Nick Garnett  <nickg@redhat.com>
+
+	* src/intr/intr.cxx: Clean up typo in DSR table
+	case. dsr_table_tail and dsr_table_head were not being subscripted
+	in a couple of places.
+
+2001-08-23  Hugo Tyson  <hmt@redhat.com>
+2001-08-20  Andrew Lunn <andrew.lunn@ascom.ch>
+
+	* include/instrument_desc.h: New file.  This contains the table of
+	events used to print the nice information.  It should be
+	regenerated when the instrumentation numbers change.
+
+	* src/instrmnt/meminst.cxx (cyg_instrument_msg):
+	returns an ASCII string describing the type of event the
+	instrumentation code logged.
+
+	* include/instrmnt.h: Added function prototype.
+
+	* cdl/instrument.cdl: Configury for enabling the new function, and
+	optionally rebuilding its header file and building a host tool.
+
+	* host/instr/dump_instr.c: New file.  A host program to print the
+	instrumentation information in a human readable form.
+
+	* host/instr/instrument.sh: New file.  Script to generate table of
+	events with textual representation.
+
+	* host/instr/readme.txt: New file.  Helpful information.
+
+2001-08-23  Nick Garnett  <nickg@redhat.com>
+
+	* include/kapidata.h (CYG_THREADTIMER_MEMBERS):
+	Substituted an expicit cyg_alarm object for CYG_ALARM_MEMBERS in
+	this definition. In some architectures (MIPS in particular) the
+	structures need to be padded to a multiple of 64 bits. This was
+	not happening with the macro substituted versions.
+	This is just a temporary fix, I'll leave it to Jifl to sort out a
+	real patch when he returns.
+
+2001-08-23  Hugo Tyson  <hmt@redhat.com>
+
+	* src/common/thread.cxx: Properly qualify Cyg_Thread::destructors
+	array so that it builds when destructors are not used.
+
+2001-08-23  Nick Garnett  <nickg@redhat.com>
+
+	* src/sched/mlqueue.cxx: Added code to
+	Cyg_SchedThread_Implementation::to_queue_head() to handle a NULL
+	thread queue pointer. This compensates for a minor change in
+	behaviour of the scheduler.
+
+2001-08-22  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/thread.cdl: Add kernel thread destructor options.
+	* include/kapidata.h: Add thread destructor entries to cyg_thread
+	* include/thread.hxx (Cyg_Thread): Give per-thread data indexes
+	their own type, cyg_data_index.
+	Include new thread destructor data members, and new add_destructor
+	and rem_destructor member functions.
+	* include/thread.inl: Use a cyg_data_index for per-thread data handle.
+	(add_destructor): New Cyg_Thread member function.
+	(rem_destructor): Ditto.
+	* src/common/kapi.cxx: Use cyg_data_index type for per-thread data
+	functions.
+	* src/common/thread.cxx (Cyg_Thread): initialise per-thread
+	destructors if needed.
+	Define static destructors if needed.
+	(exit): Call destructors.
+	(new_data_index): Use cyg_data_index type.
+	(free_data_index): Ditto.
+
+2001-08-22  Hugo Tyson  <hmt@redhat.com>
+  
+	* src/sync/mutex.cxx (Cyg_Mutex): Add initialization of the
+	priority ceiling value in the non-dynamic protocol case.
+
+2001-08-22  Nick Garnett  <nickg@redhat.com>
+
+	* tests/intr0.c: 
+	* tests/kintr0.c:
+	Swapped order of interrupt enable/disable calls to keep kernel
+	happy when assertions are enabled. Otherwise the enable call
+	complains that interrupts have not been disabled.
+
+	* src/sched/mlqueue.cxx:
+	Simplified algorithm in set_need_reschedule().
+
+	* include/smp.hxx: 
+	* include/kapidata.h: Change spinlock to be a cyg_uint32, rather
+	than a cyg_atomic.
+
+	* src/intr/intr.cxx: 
+	* include/intr.hxx:
+	Now arrange for DSRs to be called on the same CPU as the ISR. This
+	is necessary if the DSR needs to access per-CPU hardware (such as
+	interrupt controllers). This is achieved by keeping a separate DSR
+	list/table for each CPU.
+
+	* tests/smp.cxx: Some modifications to make this test work in a
+	real SMP environment.
+
+	* tests/timeslice.c: 
+	* cdl/kernel.cdl: Added timeslice test.
+
 2001-08-21  Hugo Tyson  <hmt@redhat.com>
 
 	* src/sync/mutex.cxx (lock): Bugfix: a ceiling priority mutex
 	wasn't elevated until after it had acquired the mutex.  This meant
-	is slept with a low priority, and so did not run when awakened by
+	it slept with a low priority, and so did not run when awakened by
 	the release of the mutex.  The fix is to elevate the potential
 	claimant before it sleeps in contention. 
 
--- a/packages/kernel/current/cdl/instrument.cdl
+++ b/packages/kernel/current/cdl/instrument.cdl
@@ -248,3 +248,56 @@ cdl_option CYGDBG_KERNEL_INSTRUMENT_USER
         whether or not application-level instrumentation gets
         compiled in."
 }
+
+cdl_component CYGDBG_KERNEL_INSTRUMENT_MSGS {
+    display       "Print user friendly instrument messages"
+    default_value 1
+    description   "
+        Include code which will convert the instrument type field 
+        into a more human understandable string"
+        
+    cdl_option  CYGDBG_KERNEL_INSTRUMENT_MSGS_BUILD_HEADERFILE {
+	display   "Rebuild the header file"
+	default_value 0
+	description "
+
+	Make (using a shell script) include/cyg/kernel/instrument_desc.h in
+	your build tree; this is normally simply copied from the repository.
+	If you make a permanent change to include/instrmnt.h, such that
+	instrument_desc.h needs updating, it's up to you to first delete the
+	master file
+	ECOS_REPOSITORY/kernel/VERSION/include/instrument_desc.h
+	in your source repository, make the new version by enabling this
+	option then copy the new file
+        back from your build place to its source in
+	ECOS_REPOSITORY/kernel/VERSION/include/instrument_desc.h
+	and/or commit this to any version control system that you use."
+
+	make -priority 50 {
+	    <PREFIX>/include/cyg/kernel/instrument_desc.h: <PACKAGE>/include/instrmnt.h <PACKAGE>/cdl/instrument.cdl
+	    sh $(REPOSITORY)/$(PACKAGE)/host/instr/instrument.sh $< > $@
+	}
+    }
+
+    cdl_component CYGDBG_KERNEL_INSTRUMENT_BUILD_HOST_DUMP {
+	display       "Build the host tool to print out a dump"
+	default_value 0
+	description   "
+        Generate a host program which can dump the instrumentation
+        data in a human readable format. You have to somehow get the
+        instrumentation buffer into a file on the host. 'Exercise for
+        the reader' as university lecturers tend to say."
+
+	make -priority 51 {
+	    <PREFIX>/bin/dump_instr: <PREFIX>/include/cyg/kernel/instrument_desc.h <PACKAGE>/cdl/instrument.cdl
+	    @mkdir -p $(dir $@)
+            @mkdir -p tempinc
+            @cp -r $(PREFIX)/include/cyg tempinc
+            @cp -r $(PREFIX)/include/pkgconf tempinc
+	    cc -I./tempinc $(REPOSITORY)/$(PACKAGE)/host/instr/dump_instr.c -o $(PREFIX)/bin/dump_instr
+            @rm -rf tempinc
+	}
+    }
+}
+
+# EOF instrument.cdl
--- a/packages/kernel/current/cdl/kernel.cdl
+++ b/packages/kernel/current/cdl/kernel.cdl
@@ -55,7 +55,6 @@ cdl_package CYGPKG_KERNEL {
     #        will actually be used.
     compile       common/clock.cxx     common/timer.cxx  common/kapi.cxx   \
                   common/thread.cxx    common/except.cxx                   \
-                  instrmnt/meminst.cxx instrmnt/nullinst.cxx               \
                   intr/intr.cxx                                            \
                   sched/bitmap.cxx     sched/lottery.cxx sched/mlqueue.cxx \
                   sched/sched.cxx                                          \
@@ -208,6 +207,7 @@ cdl_package CYGPKG_KERNEL {
             events occur, and these will be stored in a circular buffer
             for later reference."
 
+        compile       instrmnt/meminst.cxx
         script        instrument.cdl
     }
 
@@ -318,14 +318,14 @@ cdl_package CYGPKG_KERNEL {
             flavor  data
             no_define
             calculated { 
-                CYGPKG_HAL_ARM_AEB ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \
-                CYGPKG_HAL_ARM_EBSA285 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
-                CYGPKG_HAL_ARM_SA11X0 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
-                CYGPKG_HAL_ARM_EDB7XXX ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
-                CYGPKG_HAL_ARM_CMA230 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \
-                CYGPKG_HAL_ARM_E7T ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
-                CYGPKG_HAL_ARM ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \
-                "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/smp" 
+                CYGPKG_HAL_ARM_AEB ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/timeslice" : \
+                CYGPKG_HAL_ARM_EBSA285 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \
+                CYGPKG_HAL_ARM_SA11X0 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \
+                CYGPKG_HAL_ARM_EDB7XXX ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \
+                CYGPKG_HAL_ARM_CMA230 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/timeslice" : \
+                CYGPKG_HAL_ARM_E7T ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \
+                CYGPKG_HAL_ARM ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/timeslice" : \
+                "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/smp tests/timeslice" 
             }
             description   "
                 This option specifies the set of tests for the eCos kernel."
--- a/packages/kernel/current/cdl/thread.cdl
+++ b/packages/kernel/current/cdl/thread.cdl
@@ -220,6 +220,38 @@ cdl_component CYGVAR_KERNEL_THREADS_DATA
     }
 }
 
+cdl_component CYGPKG_KERNEL_THREADS_DESTRUCTORS {
+    display       "Thread destructors"
+    default_value 0
+    description   "
+        This option enables support for registered destructor functions to
+        be called on thread exit."
+    
+
+    cdl_option CYGNUM_KERNEL_THREADS_DESTRUCTORS {
+        display        "Number of possible destructors"
+        flavor         data
+        legal_values   1 to 65535
+        default_value  8
+        description    "
+                This option gives the number of possible destructors allowed.
+                Increasing this will increase the size of every
+                thread control structure if per-thread destructors are
+                enabled."
+    }
+    
+    cdl_option CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD {
+        display        "Per-thread destructors"
+        default_value  1
+        description    "
+                Enabling this option makes the thread destructors a per-thread
+                property, with each thread having its own list of destructors.
+                Disabling this option makes the thread destructor list
+                global so all threads have the same destructors."
+    }
+    
+}
+
 cdl_option CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE {
     display       "Stack size for the idle thread"
     flavor        data
new file mode 100644
--- /dev/null
+++ b/packages/kernel/current/host/instr/dump_instr.c
@@ -0,0 +1,105 @@
+
+#include <pkgconf/kernel.h>
+#include <cyg/kernel/ktypes.h>         // base kernel types
+#include <cyg/kernel/instrmnt.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// -------------------------------------------------------------------------
+// Instrumentation record.
+
+struct Instrument_Record
+{
+    CYG_WORD16  type;                   // record type
+    CYG_WORD16  thread;                 // current thread id
+    CYG_WORD    timestamp;              // 32 bit timestamp
+    CYG_WORD    arg1;                   // first arg
+    CYG_WORD    arg2;                   // second arg
+};
+
+// -------------------------------------------------------------------------
+
+#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS
+#include <cyg/kernel/instrument_desc.h>
+#define NELEM(x) (sizeof(x)/sizeof*(x))
+externC char * cyg_instrument_msg(CYG_WORD16 type) {
+
+  struct instrument_desc_s *record;
+  struct instrument_desc_s *end_record;
+  CYG_WORD cl, event;
+
+  record = instrument_desc;
+  end_record = &instrument_desc[NELEM(instrument_desc)];
+  cl = type & 0xff00;
+  event = type & 0x00ff;
+
+  while ((record != end_record) && (record->num != cl)) {
+    record++;
+  }
+
+  if (record->num == cl) {
+    record++;
+    while ((record != end_record) && (record->num != event) &&
+           (record->num < 0xff)) {
+      record++;
+    }
+
+    if (record->num == event) {
+      return (record->msg);
+    }
+  }
+  return("Unknown event");
+}
+#endif // CYGDBG_KERNEL_INSTRUMENT_MSGS
+
+void usage(char *myname) 
+{
+  fprintf(stderr,"Usage: %s <filename>\n",myname);
+  fprintf(stderr,"where filename is that of the instrumentation data");
+}
+
+int main(int argc, char * argv[]) 
+{
+  
+  FILE * file;
+  char * filename;
+  struct Instrument_Record record;
+  int cnt=0;
+
+  if (argc != 1) {
+    usage(argv[0]);
+    exit(1);
+  }
+
+  filename = argv[1];
+
+  file = fopen(filename, "r");
+  if (!file) {
+    fprintf(stderr,"Error opening file %s: ",filename);
+    perror("");
+    exit(1);
+  }
+  
+  while (!feof(file)) {
+    fread(&record,sizeof(record),1,file);
+    if (record.type == 0) {
+      break;
+    }
+
+#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS 
+    printf("%4d Record type (0x%04x): %-20s thread %2d, ",
+           cnt++,record.type,cyg_instrument_msg(record.type), 
+           record.thread);
+#else
+    printf("%4d Record type 0x%04x, thread %2d, ",
+           cnt++,record.type, record.thread);
+#endif
+    printf("time %5d, arg1 0x%08x, arg2 0x%08x\n",
+           record.timestamp, record.arg1,
+           record.arg2);
+  }
+
+  fclose(file);
+  return (0);
+}
new file mode 100644
--- /dev/null
+++ b/packages/kernel/current/host/instr/instrument.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+echo "/* This is an automatically generated file. Do not edit.               */"
+echo "/* Repository name: PACKAGES/kernel/VERSION/include/instrument_desc.h  */"
+echo "/* Install tree   : INSTALL/include/cyg/kernel/instrument_desc.h       */"
+echo
+echo "struct instrument_desc_s {                                "
+echo "    char *   msg;                                         "
+echo "    CYG_WORD num;                                         "
+echo "};                                                        "
+echo
+echo struct instrument_desc_s instrument_desc[] = {
+
+grep -e \#define.CYG_INSTRUMENT_EVENT -e \#define.CYG_INSTRUMENT_CLASS $1 | grep -v MAX | cut -d " " -f 2- | cut -d "_" -f 4- | sort | awk '{ print("{\""$1"\",   " $2 "},") }'
+
+echo }\;
+echo
+echo "/* EOF instrument_desc.h */"
+
new file mode 100644
--- /dev/null
+++ b/packages/kernel/current/host/instr/readme.txt
@@ -0,0 +1,80 @@
+
+README for User Friendly Instrumentation Messages
+=================================================
+
+The CDL option CYGDBG_KERNEL_INSTRUMENT_MSGS controls whether the
+system is capable of displaying user friendly instrumentation
+messages.  To do this it needs to know what event numbers mean
+what events - as a text string to print for you.
+
+It gets the information from a table created by the header file
+instrument_desc.h in the kernel.  If the instrumentation numbers
+change, you must rebuild that header to match.
+
+A further CDL option is provided to help you with that.  The
+procedure is as follows:
+
+1) Remove kernel/VERSION/include/instrument_desc.h from your
+   repository.  Is is probably a good idea to move it away rather
+   than deleting it in case the next stages fail.
+
+2) Make a build configuration, enabling options
+   CYGDBG_KERNEL_INSTRUMENT, CYGDBG_KERNEL_INSTRUMENT_MSGS and
+   CYGDBG_KERNEL_INSTRUMENT_MSGS_BUILD_HEADERFILE in the kernel.
+   Viewed in the GUI configtool, "Kernel instrumentation", "Print
+   user friendly instrument messages" and "Rebuild the header
+   file" respectively.
+
+3) Make eCos within this build configuration.  It should create
+   install/include/cyg/kernel/instrument_desc.h
+
+4) Copy that new file back to your repository, to
+   kernel/VERSION/include/instrument_desc.h replacing the file
+   you moved aside in step 1.
+
+5) Commit the new file to your version control system or whatever
+   you use.
+
+If you wish to rebuild the file "by hand" the command to use, in
+a suitable shell, is this:
+
+   $ECOS_REPOSITORY/kernel/$ECOS_VERSION/host/instr/instrument.sh 
+        $ECOS_REPOSITORY/kernel/$ECOS_VERSION/include/instrmnt.h
+        > $ECOS_BUILD_PREFIX/include/cyg/kernel/instrument_desc.h
+
+(all on one line of course) or to rebuild it directly into the
+kernel source repository:
+
+   $ECOS_REPOSITORY/kernel/$ECOS_VERSION/host/instr/instrument.sh 
+        $ECOS_REPOSITORY/kernel/$ECOS_VERSION/include/instrmnt.h
+        > $ECOS_REPOSITORY/kernel/$ECOS_VERSION/include/instrument_desc.h
+
+It's up to you to sort out file permissions for this to work, and
+to set environment variables as required or edit these lines as
+you type them.
+
+
+There is also a host-based program which can print a buffer
+nicely for you - if you can get the data into your host.
+Enabling CDL option CYGDBG_KERNEL_INSTRUMENT_BUILD_HOST_DUMP or
+"Build the host tool to print out a dump" will build it for you
+in install/bin.  To build it instead "by hand", use
+
+    mkdir -p tempinc
+    cp -r $(ECOS_BUILD_PREFIX)/include/cyg tempinc
+    cp -r $(ECOS_BUILD_PREFIX)/include/pkgconf tempinc
+    cc -I./tempinc
+    $(ECOS_REPOSITORY)/kernel/${ECOS_VERSION}/host/instr/dump_instr.c
+    -o $(PREFIX)/bin/dump_instr
+
+again with environment variables as required, or type in whatever
+is appropriate.  You still have to somehow get the
+instrumentation buffer into a file on the host. 'Exercise for the
+reader' as university lecturers tend to say.
+
+One possibility is to set up a tftp *server* in the target which
+will serve the instrumentation buffer.  This hint is as far as
+support for this goes.
+
+
+
--- a/packages/kernel/current/include/instrmnt.h
+++ b/packages/kernel/current/include/instrmnt.h
@@ -26,7 +26,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -35,7 +35,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    nickg
-// Contributors: nickg
+// Contributors: nickg, andrew.lunn@ascom.ch
 // Date:         2000-05-04
 // Purpose:      Define kernel instrumentation
 // Description:  A set of definitions and macros used to implement an
@@ -73,6 +73,9 @@ externC void cyg_instrument_enable( cyg_
 
 externC void cyg_instrument_disable( cyg_uint32 cl, cyg_uint32 event );
 
+#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS
+externC char * cyg_instrument_msg(CYG_WORD16 type);
+#endif 
 #endif
 
 // -------------------------------------------------------------------------
@@ -446,4 +449,4 @@ externC void cyg_instrument_disable( cyg
 
 // -------------------------------------------------------------------------
 #endif // ifndef CYGONCE_KERNEL_INSTRMNT_HXX
-// EOF instrmnt.hxx
+// EOF instrmnt.h
new file mode 100644
--- /dev/null
+++ b/packages/kernel/current/include/instrument_desc.h
@@ -0,0 +1,138 @@
+/* This is an automatically generated file. Do not edit.               */
+/* Repository name: PACKAGES/kernel/VERSION/include/instrument_desc.h  */
+/* Install tree   : INSTALL/include/cyg/kernel/instrument_desc.h       */
+
+struct instrument_desc_s {                                
+    char *   msg;                                         
+    CYG_WORD num;                                         
+};                                                        
+
+struct instrument_desc_s instrument_desc[] = {
+{"ALARM",   0x0900},
+{"ALARM_ADD",   1},
+{"ALARM_CALL",   3},
+{"ALARM_INIT",   4},
+{"ALARM_INTERVAL",   6},
+{"ALARM_REM",   2},
+{"ALARM_TRIGGER",   5},
+{"BINSEM",   0x0600},
+{"BINSEM_CLAIM",   1},
+{"BINSEM_POST",   5},
+{"BINSEM_TRY",   4},
+{"BINSEM_WAIT",   2},
+{"BINSEM_WAKE",   6},
+{"BINSEM_WOKE",   3},
+{"CLOCK",   0x0800},
+{"CLOCK_ISR",   3},
+{"CLOCK_TICK_END",   2},
+{"CLOCK_TICK_START",   1},
+{"CNTSEM",   0x0700},
+{"CNTSEM_CLAIM",   1},
+{"CNTSEM_POST",   5},
+{"CNTSEM_TIMEOUT",   7},
+{"CNTSEM_TRY",   4},
+{"CNTSEM_WAIT",   2},
+{"CNTSEM_WAKE",   6},
+{"CNTSEM_WOKE",   3},
+{"CONDVAR",   0x0500},
+{"CONDVAR_BROADCAST",   5},
+{"CONDVAR_SIGNAL",   3},
+{"CONDVAR_TIMED_WAIT",   6},
+{"CONDVAR_WAIT",   1},
+{"CONDVAR_WAKE",   4},
+{"CONDVAR_WOKE",   2},
+{"INTR",   0x0300},
+{"INTR_ACK",   14},
+{"INTR_ATTACH",   6},
+{"INTR_CALL_DSR",   5},
+{"INTR_CHAIN_ISR",   15},
+{"INTR_CONFIGURE",   13},
+{"INTR_DETACH",   7},
+{"INTR_DISABLE",   9},
+{"INTR_ENABLE",   10},
+{"INTR_END",   2},
+{"INTR_GET_CPU",   17},
+{"INTR_MASK",   11},
+{"INTR_POST_DSR",   4},
+{"INTR_RAISE",   1},
+{"INTR_RESTORE",   3},
+{"INTR_SET_CPU",   16},
+{"INTR_SET_VSR",   8},
+{"INTR_UNMASK",   12},
+{"MBOXT",   0x0a00},
+{"MBOXT_GET",   2},
+{"MBOXT_GOT",   3},
+{"MBOXT_PUT",   7},
+{"MBOXT_TIMEOUT",   4},
+{"MBOXT_TRY",   6},
+{"MBOXT_WAIT",   1},
+{"MBOXT_WAKE",   5},
+{"MLQ",   0x0c00},
+{"MLQ_ADD",   3},
+{"MLQ_DEQUEUE",   8},
+{"MLQ_ENQUEUE",   7},
+{"MLQ_REM",   4},
+{"MLQ_REMOVE",   9},
+{"MLQ_RESCHEDULE",   2},
+{"MLQ_SCHEDULE",   1},
+{"MLQ_TIMESLICE",   5},
+{"MLQ_YIELD",   6},
+{"MUTEX",   0x0400},
+{"MUTEX_LOCK",   1},
+{"MUTEX_LOCKED",   3},
+{"MUTEX_RELEASE",   7},
+{"MUTEX_RELEASED",   8},
+{"MUTEX_TRY",   4},
+{"MUTEX_UNLOCK",   5},
+{"MUTEX_WAIT",   2},
+{"MUTEX_WAKE",   6},
+{"SCHED",   0x0100},
+{"SCHED_LOCK",   1},
+{"SCHED_RESCHEDULE",   3},
+{"SCHED_TIMESLICE",   4},
+{"SCHED_UNLOCK",   2},
+{"SMP",   0x0b00},
+{"SMP_CPU_START",   4},
+{"SMP_LOCK_GOT",   6},
+{"SMP_LOCK_INC",   1},
+{"SMP_LOCK_SET",   3},
+{"SMP_LOCK_WAIT",   5},
+{"SMP_LOCK_ZERO",   2},
+{"SMP_RESCHED_RECV",   9},
+{"SMP_RESCHED_SEND",   8},
+{"THREAD",   0x0200},
+{"THREAD_ALARM",   8},
+{"THREAD_ATTACH_STACK",   11},
+{"THREAD_CHECK_STACK",   10},
+{"THREAD_CREATE",   12},
+{"THREAD_DELAY",   7},
+{"THREAD_ENTER",   9},
+{"THREAD_PRIORITY",   6},
+{"THREAD_RESUME",   5},
+{"THREAD_SLEEP",   2},
+{"THREAD_SUSPEND",   4},
+{"THREAD_SWITCH",   1},
+{"THREAD_WAKE",   3},
+{"USER",   0x0f00},
+{"USER_10",   10},
+{"USER_1",   1},
+{"USER_11",   11},
+{"USER_12",   12},
+{"USER_13",   13},
+{"USER_14",   14},
+{"USER_15",   15},
+{"USER_16",   16},
+{"USER_17",   17},
+{"USER_18",   18},
+{"USER_19",   19},
+{"USER_2",   2},
+{"USER_3",   3},
+{"USER_4",   4},
+{"USER_5",   5},
+{"USER_6",   6},
+{"USER_7",   7},
+{"USER_8",   8},
+{"USER_9",   9},
+};
+
+/* EOF instrument_desc.h */
--- a/packages/kernel/current/include/intr.hxx
+++ b/packages/kernel/current/include/intr.hxx
@@ -167,12 +167,15 @@ class Cyg_Interrupt
 
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
     
-    static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]
-                                    CYGBLD_ANNOTATE_VARIABLE_INTR;
+    static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_CPU_MAX]
+                                   [CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]
+                                   CYGBLD_ANNOTATE_VARIABLE_INTR;
 
-    static cyg_ucount32 dsr_table_head CYGBLD_ANNOTATE_VARIABLE_INTR;
+    static cyg_ucount32 dsr_table_head[CYGNUM_KERNEL_CPU_MAX]
+                                      CYGBLD_ANNOTATE_VARIABLE_INTR;
 
-    static volatile cyg_ucount32 dsr_table_tail CYGBLD_ANNOTATE_VARIABLE_INTR;
+    static volatile cyg_ucount32 dsr_table_tail[CYGNUM_KERNEL_CPU_MAX]
+                                               CYGBLD_ANNOTATE_VARIABLE_INTR;
 
 #endif
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
@@ -184,7 +187,8 @@ class Cyg_Interrupt
     Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; 
 
     // static list of pending DSRs
-    static Cyg_Interrupt* volatile dsr_list CYGBLD_ANNOTATE_VARIABLE_INTR;
+    static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX]
+                                           CYGBLD_ANNOTATE_VARIABLE_INTR;
     
 #endif
 
@@ -335,14 +339,15 @@ public:
 
 inline cyg_bool Cyg_Interrupt::DSRs_pending()
 {
+    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
     
-    return dsr_table_head != dsr_table_tail;
+    return dsr_table_head[cpu] != dsr_table_tail[cpu];
 
 #endif
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
     
-    return dsr_list != NULL;
+    return dsr_list[cpu] != NULL;
 
 #endif
 };
--- a/packages/kernel/current/include/kapidata.h
+++ b/packages/kernel/current/include/kapidata.h
@@ -327,7 +327,7 @@ typedef struct
 } cyg_schedthread;
 
 #define CYG_THREADTIMER_MEMBERS \
-    CYG_ALARM_MEMBERS           \
+    cyg_alarm           alarm;  \
     cyg_thread          *thread;
 
 /*---------------------------------------------------------------------------*/
@@ -376,6 +376,22 @@ typedef int cyg_reason_t; /* cyg_reason 
 # define CYG_THREAD_LIST_NEXT_MEMBER
 #endif
 
+
+
+#ifdef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
+typedef void (*cyg_thread_destructor_fn)(CYG_ADDRWORD);
+
+struct Cyg_Destructor_Entry {
+    cyg_thread_destructor_fn fn;
+    CYG_ADDRWORD data;
+};
+# define CYG_THREAD_DESTRUCTORS_MEMBER \
+   struct Cyg_Destructor_Entry destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ];
+#else
+# define CYG_THREAD_DESTRUCTORS_MEMBER
+#endif
+
+
 #define CYG_THREAD_MEMBERS                        \
     CYG_HARDWARETHREAD_MEMBERS                    \
     CYG_SCHEDTHREAD_MEMBERS                       \
@@ -393,6 +409,7 @@ typedef int cyg_reason_t; /* cyg_reason 
     cyg_reason_t        wake_reason;              \
                                                   \
     CYG_THREAD_THREAD_DATA_MEMBER                 \
+    CYG_THREAD_DESTRUCTORS_MEMBER                 \
     CYG_THREAD_NAME_MEMBER                        \
     CYG_THREAD_LIST_NEXT_MEMBER                   
 
@@ -460,7 +477,7 @@ struct cyg_cond_t
 
 struct cyg_spinlock_t
 {
-    cyg_atomic          lock;           /* lock word                     */
+    cyg_uint32          lock;           /* lock word                     */
 };
 
 /*------------------------------------------------------------------------*/
--- a/packages/kernel/current/include/mqueue.inl
+++ b/packages/kernel/current/include/mqueue.inl
@@ -163,7 +163,7 @@ Cyg_Mqueue::check_this( cyg_assert_class
         if ( qlen != (msgs+freemsgs+busymsgs) )
             goto fail;
 #endif
-        
+
         Cyg_Scheduler::unlock();
 
     }
@@ -218,6 +218,7 @@ Cyg_Mqueue::Cyg_Mqueue( long maxmsgs, lo
 
     // set the last entry in the chain to the start to make the list circular
     qtmp->next = NULL;
+    qtmp->busy = false;
     callback   = NULL;
     q          = NULL;
     free_fn    = qfree;
--- a/packages/kernel/current/include/smp.hxx
+++ b/packages/kernel/current/include/smp.hxx
@@ -338,7 +338,7 @@ HAL_SMP_SCHEDLOCK_DATA_TYPE Cyg_Schedule
 
 class Cyg_SpinLock
 {
-    cyg_atomic          lock;
+    volatile cyg_uint32 lock;
 
 public:
 
--- a/packages/kernel/current/include/thread.hxx
+++ b/packages/kernel/current/include/thread.hxx
@@ -427,16 +427,39 @@ private:
 
 public:
     
-    static CYG_ADDRWORD get_data( cyg_ucount32 index );
+    typedef cyg_count32 cyg_data_index;
+
+    static CYG_ADDRWORD get_data( cyg_data_index index );
+
+    static CYG_ADDRWORD *get_data_ptr( cyg_data_index index );
+
+    void                set_data( cyg_data_index index, CYG_ADDRWORD data );
 
-    static CYG_ADDRWORD *get_data_ptr( cyg_ucount32 index );
+    // returns -1 if no more indexes available
+    static cyg_data_index new_data_index();
+
+    static void         free_data_index( cyg_data_index index );
+
+#endif
+
+#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
 
-    void                set_data( cyg_ucount32 index, CYG_ADDRWORD data );
-
-    static cyg_ucount32 new_data_index();
-
-    static void         free_data_index( cyg_ucount32 index );
-
+    // thread destructors, called on thread exit.
+private:
+    typedef void (*destructor_fn)(CYG_ADDRWORD);
+    struct Cyg_Destructor_Entry {
+        destructor_fn fn;
+        CYG_ADDRWORD data;
+    };
+#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
+    static 
+#endif
+    Cyg_Destructor_Entry destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ];
+public:
+ 
+    // Add and remove destructors. Returns true on success, false on failure.
+    static cyg_bool     add_destructor( destructor_fn fn, CYG_ADDRWORD data );
+    static cyg_bool     rem_destructor( destructor_fn fn, CYG_ADDRWORD data );
 #endif
 
 #ifdef CYGVAR_KERNEL_THREADS_NAME
--- a/packages/kernel/current/include/thread.inl
+++ b/packages/kernel/current/include/thread.inl
@@ -453,7 +453,7 @@ inline void Cyg_Thread::clear_timer()
 
 #ifdef CYGVAR_KERNEL_THREADS_DATA
 
-inline CYG_ADDRWORD Cyg_Thread::get_data( cyg_ucount32 index )
+inline CYG_ADDRWORD Cyg_Thread::get_data( Cyg_Thread::cyg_data_index index )
 {
     CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX,
                 "Per thread data index out of bounds");
@@ -463,7 +463,7 @@ inline CYG_ADDRWORD Cyg_Thread::get_data
     return self()->thread_data[index];
 }
 
-inline CYG_ADDRWORD *Cyg_Thread::get_data_ptr( cyg_ucount32 index )
+inline CYG_ADDRWORD *Cyg_Thread::get_data_ptr( Cyg_Thread::cyg_data_index index )
 {
     CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX,
                 "Per thread data index out of bounds");
@@ -473,7 +473,8 @@ inline CYG_ADDRWORD *Cyg_Thread::get_dat
     return &(self()->thread_data[index]);
 }
 
-inline void Cyg_Thread::set_data( cyg_ucount32 index, CYG_ADDRWORD data )
+inline void Cyg_Thread::set_data( Cyg_Thread::cyg_data_index index,
+                                  CYG_ADDRWORD data )
 {
     CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX,
                 "Per thread data index out of bounds");
@@ -487,6 +488,46 @@ inline void Cyg_Thread::set_data( cyg_uc
 
 // -------------------------------------------------------------------------
 
+#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
+
+    // Add and remove destructors. Returns true on success, false on failure.
+inline cyg_bool
+Cyg_Thread::add_destructor( destructor_fn fn, CYG_ADDRWORD data )
+{
+    cyg_ucount16 i;
+    Cyg_Scheduler::lock();
+    for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) {
+        if (NULL == destructors[i].fn) {
+            destructors[i].data = data;
+            destructors[i].fn = fn;
+            Cyg_Scheduler::unlock();
+            return true;
+        }
+    }
+    Cyg_Scheduler::unlock();
+    return false;
+}
+
+inline cyg_bool
+Cyg_Thread::rem_destructor( destructor_fn fn, CYG_ADDRWORD data )
+{
+    cyg_ucount16 i;
+    Cyg_Scheduler::lock();
+    for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) {
+        if (destructors[i].fn == fn && destructors[i].data == data) {
+            destructors[i].fn = NULL;
+            Cyg_Scheduler::unlock();
+            return true;
+        }
+    }
+    Cyg_Scheduler::unlock();
+    return false;
+}
+
+#endif
+
+// -------------------------------------------------------------------------
+
 #ifdef CYGVAR_KERNEL_THREADS_NAME
 
 inline char *Cyg_Thread::get_name()
--- a/packages/kernel/current/src/common/kapi.cxx
+++ b/packages/kernel/current/src/common/kapi.cxx
@@ -306,28 +306,30 @@ externC cyg_uint32 cyg_thread_measure_st
 
 externC cyg_ucount32 cyg_thread_new_data_index()
 {
-        return Cyg_Thread::new_data_index();
+    Cyg_Thread::cyg_data_index index = Cyg_Thread::new_data_index();
+    CYG_ASSERT(index >= 0, "failed to allocate data index" );
+    return index;
 }
 
 externC void cyg_thread_free_data_index(cyg_ucount32 index)
 {
-        Cyg_Thread::free_data_index(index);
+    Cyg_Thread::free_data_index(index);
 }
 
 externC CYG_ADDRWORD cyg_thread_get_data(cyg_ucount32 index)
 {
-        return Cyg_Thread::get_data(index);
+    return Cyg_Thread::get_data(index);
 }
 
 externC CYG_ADDRWORD *cyg_thread_get_data_ptr(cyg_ucount32 index)
 {
-        return Cyg_Thread::get_data_ptr(index);
+    return Cyg_Thread::get_data_ptr(index);
 }
 
 externC void cyg_thread_set_data(cyg_ucount32 index, CYG_ADDRWORD 
 data)
 {
-        Cyg_Thread::self()->set_data(index, data);
+    Cyg_Thread::self()->set_data(index, data);
 }
 #endif
 
--- a/packages/kernel/current/src/common/thread.cxx
+++ b/packages/kernel/current/src/common/thread.cxx
@@ -209,6 +209,11 @@ Cyg_Thread::Cyg_Thread(
     for( int i = 0; i < CYGNUM_KERNEL_THREADS_DATA_MAX; i++ )
         thread_data[i] = 0;
 #endif
+#ifdef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
+    for (int j=0; j<CYGNUM_KERNEL_THREADS_DESTRUCTORS; j++) {
+        destructors[j].fn = NULL;
+    }
+#endif
 #ifdef CYGVAR_KERNEL_THREADS_NAME
     name = name_arg;
 #endif
@@ -720,6 +725,13 @@ Cyg_Thread::release()
 // -------------------------------------------------------------------------
 // Exit thread. This puts the thread into EXITED state.
 
+#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
+#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
+Cyg_Thread::Cyg_Destructor_Entry
+Cyg_Thread::destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ];
+#endif
+#endif
+
 void
 Cyg_Thread::exit()
 {
@@ -729,6 +741,20 @@ Cyg_Thread::exit()
 
     Cyg_Thread *self = Cyg_Thread::self();
 
+#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
+    cyg_ucount16 i;
+    Cyg_Scheduler::lock();
+    for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) {
+        if (NULL != self->destructors[i].fn) {
+            destructor_fn fn = self->destructors[i].fn;
+            CYG_ADDRWORD data = self->destructors[i].data;
+            Cyg_Scheduler::unlock();
+            fn(data);
+            Cyg_Scheduler::lock();
+        }        
+    }
+    Cyg_Scheduler::unlock();
+#endif
 #ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT
     diag_printf( "Stack usage for thread %08x: %d\n", self,
 		 self->measure_stack_usage() );
@@ -1023,14 +1049,15 @@ Cyg_Thread::deliver_exception(
 cyg_ucount32 Cyg_Thread::thread_data_map = (~CYGNUM_KERNEL_THREADS_DATA_ALL) &
                                            ((1<<CYGNUM_KERNEL_THREADS_DATA_MAX)-1);
 
-cyg_ucount32
+Cyg_Thread::cyg_data_index
 Cyg_Thread::new_data_index()
 {
     Cyg_Scheduler::lock();
 
-    cyg_ucount32 index;
+    Cyg_Thread::cyg_data_index index;
 
-    CYG_ASSERT( thread_data_map != 0 , "No more thread data indexes");
+    if (0 == thread_data_map)
+        return -1;
     
     // find ls set bit
     HAL_LSBIT_INDEX( index, thread_data_map );
@@ -1043,7 +1070,7 @@ Cyg_Thread::new_data_index()
     return index;
 }
 
-void Cyg_Thread::free_data_index( cyg_ucount32 index )
+void Cyg_Thread::free_data_index( Cyg_Thread::cyg_data_index index )
 {
     Cyg_Scheduler::lock();
 
--- a/packages/kernel/current/src/instrmnt/meminst.cxx
+++ b/packages/kernel/current/src/instrmnt/meminst.cxx
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):   nickg
-// Contributors:        nickg
+// Contributors: nickg, andrew.lunn@ascom.ch
 // Date:        1997-10-27
 // Purpose:     Instrumentation functions
 // Description: The functions in this file are implementations of the
@@ -209,6 +209,38 @@ externC void cyg_instrument_disable( cyg
 
 // -------------------------------------------------------------------------
 
+#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS
+#include <cyg/kernel/instrument_desc.h>
+#define NELEM(x) (sizeof(x)/sizeof*(x))
+externC char * cyg_instrument_msg(CYG_WORD16 type) {
+
+  struct instrument_desc_s *record;
+  struct instrument_desc_s *end_record;
+  CYG_WORD cl, event;
+
+  record = instrument_desc;
+  end_record = &instrument_desc[NELEM(instrument_desc)];
+  cl = type & 0xff00;
+  event = type & 0x00ff;
+
+  while ((record != end_record) && (record->num != cl)) {
+    record++;
+  }
+
+  if (record->num == cl) {
+    record++;
+    while ((record != end_record) && (record->num != event) &&
+           (record->num < 0xff)) {
+      record++;
+    }
+
+    if (record->num == event) {
+      return (record->msg);
+    }
+  }
+  return("Unknown event");
+}
+#endif // CYGDBG_KERNEL_INSTRUMENT_MSGS
 #endif // CYGPKG_KERNEL_INSTRUMENT
 
-// EOF instrmnt/null.cxx
+// EOF instrmnt/meminst.cxx
deleted file mode 100644
--- a/packages/kernel/current/src/instrmnt/nullinst.cxx
+++ /dev/null
@@ -1,66 +0,0 @@
-//==========================================================================
-//
-//      instrmnt/null.cxx
-//
-//      Null instrumentation functions
-//
-//==========================================================================
-//####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):   nickg
-// Contributors:        nickg
-// Date:        1997-10-24
-// Purpose:     Instrumentation functions
-// Description: The functions in this file are null implementations of the
-//              standard instrumentation functions. These can be used to
-//              eliminate all instrumentation without recompiling.
-//
-//####DESCRIPTIONEND####
-//
-//==========================================================================
-
-#include <pkgconf/kernel.h>
-
-#include <cyg/kernel/ktypes.h>             // base kernel types
-#include <cyg/infra/cyg_trac.h>            // tracing macros
-#include <cyg/infra/cyg_ass.h>             // assertion macros
-#include <cyg/kernel/instrmnt.h>           // instrumentation
-
-#ifdef CYGPKG_KERNEL_INSTRUMENT
-
-// -------------------------------------------------------------------------
-
-void cyg_instrument( cyg_uint32 type, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2 )
-{
-    return;
-}
-
-// -------------------------------------------------------------------------
-
-#endif //CYGPKG_KERNEL_INSTRUMENT
-
-// EOF instrmnt/null.cxx
--- a/packages/kernel/current/src/intr/intr.cxx
+++ b/packages/kernel/current/src/intr/intr.cxx
@@ -85,7 +85,7 @@ Cyg_Interrupt::Cyg_Interrupt(
     data        = d;
 
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
-    
+
     dsr_count   = 0;
     next_dsr    = NULL;
 
@@ -116,17 +116,17 @@ Cyg_Interrupt::~Cyg_Interrupt()
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
 
 Cyg_Interrupt *
-Cyg_Interrupt::dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE];
+Cyg_Interrupt::dsr_table[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE];
 
-cyg_ucount32 Cyg_Interrupt::dsr_table_head = 0;
+cyg_ucount32 Cyg_Interrupt::dsr_table_head[CYGNUM_KERNEL_CPU_MAX];
 
-volatile cyg_ucount32 Cyg_Interrupt::dsr_table_tail = 0;
+volatile cyg_ucount32 Cyg_Interrupt::dsr_table_tail[CYGNUM_KERNEL_CPU_MAX];
 
 #endif
 
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
 
-Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list = NULL;
+Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list[CYGNUM_KERNEL_CPU_MAX];
 
 #endif
 
@@ -138,15 +138,17 @@ Cyg_Interrupt::call_pending_DSRs_inner(v
 {
 //    CYG_REPORT_FUNCTION();
 
+    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();
+    
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE    
 
-    while( dsr_table_head != dsr_table_tail )
+    while( dsr_table_head[cpu] != dsr_table_tail[cpu] )
     {
-        Cyg_Interrupt *intr = dsr_table[dsr_table_head];
+        Cyg_Interrupt *intr = dsr_table[cpu][dsr_table_head[cpu]];
 
-        dsr_table_head++;
-        if( dsr_table_head >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )
-            dsr_table_head = 0;
+        dsr_table_head[cpu]++;
+        if( dsr_table_head[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )
+            dsr_table_head[cpu] = 0;
 
         CYG_INSTRUMENT_INTR(CALL_DSR, intr->vector, 0);
         
@@ -159,7 +161,7 @@ Cyg_Interrupt::call_pending_DSRs_inner(v
 
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
 
-    while( dsr_list != NULL )
+    while( dsr_list[cpu] != NULL )
     {
         Cyg_Interrupt* intr;
         cyg_uint32 old_intr;
@@ -167,8 +169,8 @@ Cyg_Interrupt::call_pending_DSRs_inner(v
         
         HAL_DISABLE_INTERRUPTS(old_intr);
         
-        intr = dsr_list;
-        dsr_list = intr->next_dsr;
+        intr = dsr_list[cpu];
+        dsr_list[cpu] = intr->next_dsr;
         count = intr->dsr_count;
         intr->dsr_count = 0;
         
@@ -211,7 +213,8 @@ void
 Cyg_Interrupt::post_dsr(void)
 {
 //    CYG_REPORT_FUNCTION();
-
+    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();
+    
     CYG_INSTRUMENT_INTR(POST_DSR, vector, 0);
 
     cyg_uint32 old_intr;
@@ -223,9 +226,9 @@ Cyg_Interrupt::post_dsr(void)
 
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
     
-    dsr_table[dsr_table_tail++] = this;
-    if( dsr_table_tail >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )
-        dsr_table_tail = 0;
+    dsr_table[cpu][dsr_table_tail[cpu]++] = this;
+    if( dsr_table_tail[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )
+        dsr_table_tail[cpu] = 0;
 
 #endif
 
@@ -239,8 +242,8 @@ Cyg_Interrupt::post_dsr(void)
     
     if( dsr_count++ == 0 )
     {
-        next_dsr = dsr_list;
-        dsr_list = this;
+        next_dsr = dsr_list[cpu];
+        dsr_list[cpu] = this;
     }
     
 #endif
@@ -271,7 +274,7 @@ interrupt_end(
 {
 //    CYG_REPORT_FUNCTION();
 
-#ifdef CYGPKG_KERNEL_SMP_SUPPORT    
+#ifdef CYGPKG_KERNEL_SMP_SUPPORT
     Cyg_Scheduler::lock();
 #endif
     
@@ -708,7 +711,7 @@ Cyg_Interrupt::get_cpu(
     CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    
     CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
 
-    HAL_SMP_CPU_TYPE cpu;
+    HAL_SMP_CPU_TYPE cpu = 0;
     
     HAL_INTERRUPT_GET_CPU( vector, cpu );
 
--- a/packages/kernel/current/src/sched/mlqueue.cxx
+++ b/packages/kernel/current/src/sched/mlqueue.cxx
@@ -106,7 +106,9 @@ Cyg_Scheduler_Implementation::Cyg_Schedu
     
     for( int i = 0; i < CYGNUM_KERNEL_CPU_MAX; i++ )
     {
+#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE        
         timeslice_count[i] = CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS;
+#endif        
         need_reschedule[i] = true;
     }
     
@@ -350,20 +352,18 @@ void Cyg_Scheduler_Implementation::set_n
     // Start with current CPU. If we can do the job locally then
     // that is most efficient. Only go on to other CPUs if that is
     // not possible.
-        
-    HAL_SMP_CPU_TYPE cpu = cpu_this;
-    HAL_SMP_CPU_TYPE cpu_last = (cpu + cpu_count - 1) % cpu_count;
 
-    for(;;)
+    for(int i = 0; i < cpu_count; i++)
     {
-        
+        HAL_SMP_CPU_TYPE cpu = (i + cpu_this) % cpu_count;
+       
         // If a CPU is not already marked for rescheduling, and its
         // current thread is of lower priority than _thread_, then
         // set its need_reschedule flag.
 
         Cyg_Thread *cur = current_thread[cpu];
-        
-        if( !need_reschedule[cpu] &&
+
+        if( (!need_reschedule[cpu]) &&
             (cur->priority > thread->priority)
           )
         {
@@ -371,6 +371,9 @@ void Cyg_Scheduler_Implementation::set_n
 
             if( cpu != cpu_this )
             {
+                // All processors other than this one need to be sent
+                // a reschedule interrupt.
+                
                 CYG_INSTRUMENT_SMP( RESCHED_SEND, cpu, 0 );
                 CYG_KERNEL_CPU_RESCHEDULE_INTERRUPT( cpu, 0 );
             }
@@ -380,17 +383,7 @@ void Cyg_Scheduler_Implementation::set_n
             // that CPU onto another.
             
             thread = cur;
-            cpu = (cpu + 1) % cpu_count;
-            cpu_last = (cpu + cpu_count - 1) % cpu_count;
-            continue;
         }
-
-        // If that was the last CPU in the circle, stop here.
-        if( cpu == cpu_last )
-            break;
-
-        // Otherwise go on to the next.
-        cpu = (cpu + 1) % cpu_count;
     } 
 
 #endif  
@@ -723,7 +716,18 @@ Cyg_SchedThread_Implementation::to_queue
     CYG_ASSERTCLASS( thread, "Bad current thread");
     
     Cyg_ThreadQueue *q = thread->get_current_queue();
-    q->to_head( thread );
+    if( q != NULL )
+        q->to_head( thread );
+    else if( thread->in_list() )
+    {
+        // If the queue pointer is NULL then it is on a run
+        // queue. Move the thread to the head of it's priority list
+        // and force a reschedule.
+        
+        Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;
+        sched->run_queue[thread->priority].to_head( thread );
+        sched->set_need_reschedule( thread );
+    }
 
     // Unlock the scheduler and switch threads
     Cyg_Scheduler::unlock();
--- a/packages/kernel/current/src/sync/mutex.cxx
+++ b/packages/kernel/current/src/sync/mutex.cxx
@@ -95,9 +95,26 @@ Cyg_Mutex::Cyg_Mutex()
 #endif    
 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_NONE
     protocol    = NONE;
-#endif    
+#endif
+
+#else // not (DYNAMIC and DEFAULT defined)
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING    
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY
 
+    // if there is a default priority ceiling defined, use that to initialize
+    // the ceiling.
+    ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY;    
+
+#else
+
+    // Otherwise set it to zero.
+    ceiling = 0;
+    
 #endif    
+#endif
+
+#endif // DYNAMIC and DEFAULT defined
     
     CYG_REPORT_RETURN();
 }
--- a/packages/kernel/current/tests/intr0.cxx
+++ b/packages/kernel/current/tests/intr0.cxx
@@ -133,8 +133,8 @@ void intr0_main( void )
         intr1 = new((void *)&intr1_obj[0]) Cyg_Interrupt( lvl2, 1, 888, isr1, dsr1 );
 
     // Check these functions at least exist
+    Cyg_Interrupt::disable_interrupts();
     Cyg_Interrupt::enable_interrupts();
-    Cyg_Interrupt::disable_interrupts();
 
     if (intr0)
         intr0->attach();
--- a/packages/kernel/current/tests/kintr0.c
+++ b/packages/kernel/current/tests/kintr0.c
@@ -156,8 +156,8 @@ void kintr0_main( void )
 
     // Check these functions at least exist
 
+    cyg_interrupt_disable();
     cyg_interrupt_enable();
-    cyg_interrupt_disable();
 
     if (intr0)
         cyg_interrupt_attach(intr0);
--- a/packages/kernel/current/tests/smp.cxx
+++ b/packages/kernel/current/tests/smp.cxx
@@ -86,7 +86,7 @@ static cyg_handle_t threads[NTHREADS_MAX
 
 static volatile cyg_uint32 cpu_run[CYGNUM_KERNEL_CPU_MAX];
 static volatile int failed = false;
-static volatile cyg_handle_t cpu_thread[CYGNUM_KERNEL_CPU_MAX];
+static volatile cyg_uint32 cpu_thread[CYGNUM_KERNEL_CPU_MAX];
 
 static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX];
 
@@ -141,7 +141,7 @@ void run_smp_test_cpus()
     }
 
     // Just wait a while, until the threads have all run for a bit.
-    cyg_thread_delay( 1 );
+    cyg_thread_delay( 10 );
 
     // Delete all the threads
     for (i = 0;  i < ncpus;  i++) {
@@ -150,9 +150,12 @@ void run_smp_test_cpus()
 
     // And check that a thread ran on each CPU
     for (i = 0;  i < ncpus;  i++) {
-        CYG_TEST_CHECK( cpu_run[i], "CPU didn't run");
+//        CYG_TEST_CHECK( cpu_run[i], "CPU didn't run");
         if( !cpu_run[i] )
+        {
+            CYG_TEST_INFO( "CPU didn't run" );
             failed++;
+        }
     }
 
     CYG_TEST_INFO( "CPU Test: done");
@@ -166,7 +169,7 @@ test_thread_pri(CYG_ADDRESS id)
 {
     for(;;)
     {
-        cpu_thread[CYG_KERNEL_CPU_THIS()] = cyg_thread_self();
+        cpu_thread[CYG_KERNEL_CPU_THIS()] = id;
     }
 }
 
@@ -174,6 +177,7 @@ test_thread_pri(CYG_ADDRESS id)
 // Second test: Run a thread on each CPU and then by manipulating the
 // priorities, get the current thread to migrate to each CPU in turn.
 
+
 void run_smp_test_pri()
 {
     int i;
@@ -183,7 +187,7 @@ void run_smp_test_pri()
     // Init flags.
     for (i = 0;  i < ncpus;  i++)
         cpu_run[i] = false;
-    
+
     // Set my priority higher than any I plan to creat
     cyg_thread_set_priority(cyg_thread_self(), 2);
 
@@ -200,13 +204,15 @@ void run_smp_test_pri()
         cyg_thread_resume( threads[i]);
     }
 
+    cyg_thread_delay( 2 );
+    
     cyg_handle_t cthread = threads[0];
     cyg_thread_set_priority(cthread, 25);
     
     // Just wait a while, until the threads have all run for a bit.
-    cyg_thread_delay( 1 );
+    cyg_thread_delay( 2 );
 
-    for (i = 0;  i < ncpus*5;  i++)
+    for (i = 0;  i < ncpus*500;  i++)
     {
         HAL_SMP_CPU_TYPE cpu = i % CYG_KERNEL_CPU_COUNT();
         
@@ -218,12 +224,17 @@ void run_smp_test_pri()
             // priority 25.
             
             // Pick a thread on a different CPU
-            cyg_handle_t dthread = cpu_thread[cpu];
+            cyg_handle_t dthread;
+
+            do
+            {
+                dthread = threads[cpu_thread[cpu]];
+            } while( dthread == cthread );
 
             // Change the priority of the victim thread to 20. It is
             // still higher priority than cthread so it will continue
             // running.
-            
+
             cyg_thread_set_priority(dthread, 20);
 
             // Now change our priority to 15. We are still higher
@@ -248,7 +259,7 @@ void run_smp_test_pri()
 
             // Spin here a while until the scheduler sorts itself out.
             
-            for( int j = 0; j < 1000; j++ );
+            for( int j = 0; j < 100000; j++ );
 
             // Indicate that we have run on this CPU
             cpu_run[CYG_KERNEL_CPU_THIS()]++;
@@ -270,9 +281,12 @@ void run_smp_test_pri()
 
     // And check that a thread ran on each CPU
     for (i = 0;  i < ncpus;  i++) {
-        CYG_TEST_CHECK( cpu_run[i], "CPU didn't run");
+//        CYG_TEST_CHECK( cpu_run[i], "CPU didn't run");
         if( !cpu_run[i] )
+        {
+            CYG_TEST_INFO( "CPU didn't run" );            
             failed++;
+        }
     }
 
     CYG_TEST_INFO( "PRI Test: done");
@@ -319,7 +333,7 @@ void run_smp_test_timeslice()
     }
 
     // Just wait a while, until the threads have all run for a bit.
-    cyg_thread_delay( 20 );
+    cyg_thread_delay( 200 );
 
     // Delete all the threads
     for (i = 0;  i < nthread;  i++) {
@@ -384,7 +398,7 @@ run_smp_tests(CYG_ADDRESS id)
 {
     cyg_mutex_init( &mx );
 
-    for( int i = 0; i < 10; i++ )
+    for( int i = 0; i < 100; i++ )
     {
         run_smp_test_cpus();
         run_smp_test_pri();
new file mode 100644
--- /dev/null
+++ b/packages/kernel/current/tests/timeslice.c
@@ -0,0 +1,272 @@
+//==========================================================================
+//
+//        timeslice.c
+//
+//        Timeslice test
+//
+//==========================================================================
+//####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, 2001 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2001-06-18
+// Description:   A basic timeslicing test.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/kernel/smp.hxx>
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+//==========================================================================
+
+#if defined(CYGSEM_KERNEL_SCHED_TIMESLICE) &&   \
+    defined(CYGFUN_KERNEL_API_C) &&             \
+    defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&     \
+    defined(CYGVAR_KERNEL_COUNTERS_CLOCK) &&    \
+    !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) &&   \
+    (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+//==========================================================================
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL*5
+
+#define NTHREADS_MAX (CYGNUM_KERNEL_CPU_MAX*6)
+
+static int ncpus = CYGNUM_KERNEL_CPU_MAX;
+
+static char test_stack[STACK_SIZE];
+static cyg_thread test_thread;
+static cyg_handle_t main_thread;
+
+static char stacks[NTHREADS_MAX][STACK_SIZE];
+static cyg_thread test_threads[NTHREADS_MAX];
+static cyg_handle_t threads[NTHREADS_MAX];
+
+static volatile int failed = false;
+
+static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX];
+
+//==========================================================================
+
+void 
+test_thread_timeslice(CYG_ADDRESS id)
+{
+    for(;;)
+        slicerun[id][CYG_KERNEL_CPU_THIS()]++;
+}
+
+//==========================================================================
+
+void run_test_timeslice(int nthread)
+{
+    int i,j;
+    cyg_uint32 cpu_total[CYGNUM_KERNEL_CPU_MAX];
+    cyg_uint32 cpu_threads[CYGNUM_KERNEL_CPU_MAX];
+    cyg_uint32 thread_total[NTHREADS_MAX];
+
+    CYG_TEST_INFO( "Timeslice Test: Check timeslicing works");
+    
+    // Init flags.
+    for (i = 0;  i < nthread;  i++)
+        for( j = 0; j < ncpus; j++ )
+            slicerun[i][j] = 0;
+    
+    // Set my priority higher than any I plan to create
+    cyg_thread_set_priority(cyg_thread_self(), 2);
+
+    for (i = 0;  i < nthread;  i++) {
+        cyg_thread_create(10,              // Priority - just a number
+                          test_thread_timeslice, // entry
+                          i,               // index
+                          "test_thread",     // Name
+                          &stacks[i][0],   // Stack
+                          STACK_SIZE,      // Size
+                          &threads[i],     // Handle
+                          &test_threads[i] // Thread data structure
+            );
+        cyg_thread_resume( threads[i]);
+    }
+
+    // Just wait a while, until the threads have all run for a bit.
+    cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS*100 );
+
+    // Suspend all the threads
+    for (i = 0;  i < nthread;  i++) {
+        cyg_thread_suspend(threads[i]);
+    }
+
+    
+    // And check that a thread ran on each CPU, and that each thread
+    // ran.
+    
+    
+    diag_printf(" Thread ");
+    for( j = 0; j < ncpus; j++ )
+    {
+        cpu_total[j] = 0;
+        cpu_threads[j] = 0;
+        // "  %11d"  __123456789ab"
+        diag_printf("       CPU %2d",j);
+    }
+    // "  %11d"  __123456789ab"
+    diag_printf("        Total\n");
+    for (i = 0;  i < nthread;  i++)
+    {
+        thread_total[i] = 0;
+        diag_printf("     %2d ",i);
+        for( j = 0; j < ncpus; j++ )
+        {
+            thread_total[i] += slicerun[i][j];
+            cpu_total[j] += slicerun[i][j];
+            if( slicerun[i][j] > 0 )
+                cpu_threads[j]++;
+            diag_printf("  %11d",slicerun[i][j]);
+        }
+        diag_printf("  %11d\n",thread_total[i]);
+        if( thread_total[i] == 0 )
+            failed++;
+    }
+    
+    diag_printf(" Total  ");
+    for( j = 0; j < ncpus; j++ )
+        diag_printf("  %11d",cpu_total[j]);
+    diag_printf("\n");
+    diag_printf("Threads ");
+    for( j = 0; j < ncpus; j++ )
+    {
+        diag_printf("  %11d",cpu_threads[j]);
+        if( cpu_threads[j] < 2 )
+            failed++;
+    }
+    diag_printf("\n");
+
+    // Delete all the threads
+    for (i = 0;  i < nthread;  i++) {
+        cyg_thread_delete(threads[i]);
+    }
+
+    CYG_TEST_INFO( "Timeslice Test: done");
+}
+
+
+//==========================================================================
+
+void 
+run_tests(CYG_ADDRESS id)
+{
+    int step;
+    int nthread;
+    
+    // Try to run about 10 times in total, with varying numbers of threads
+    // from only one extra up to the full set:
+
+    step = (NTHREADS_MAX - (1 + CYG_KERNEL_CPU_COUNT()))/10;
+    if( step == 0 ) step = 1;
+    
+    for( nthread = 1 + CYG_KERNEL_CPU_COUNT() ;
+         nthread <= NTHREADS_MAX ;
+         nthread += step )
+            run_test_timeslice(nthread);
+
+    if( failed )
+        CYG_TEST_FAIL_FINISH("Timeslice test failed\n");
+    
+    CYG_TEST_PASS_FINISH("Timeslice test OK");    
+}
+
+//==========================================================================
+
+void timeslice_main( void )
+{
+    CYG_TEST_INIT();
+
+    // Work out how many CPUs we actually have.
+    ncpus = CYG_KERNEL_CPU_COUNT();
+
+    cyg_thread_create(0,              // Priority - just a number
+                      run_tests, // entry
+                      0,               // index
+                      "run_tests",     // Name
+                      test_stack,   // Stack
+                      STACK_SIZE,      // Size
+                      &main_thread,     // Handle
+                      &test_thread // Thread data structure
+        );
+    cyg_thread_resume( main_thread);
+    
+    cyg_scheduler_start();
+}
+
+//==========================================================================
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+    cyg_hal_invoke_constructors();
+#endif
+    timeslice_main();
+}   
+
+//==========================================================================
+
+#else // CYGSEM_KERNEL_SCHED_TIMESLICE etc
+
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA("SMP test requires:\n"
+                "CYGSEM_KERNEL_SCHED_TIMESLICE &&\n"
+                "CYGPKG_KERNEL_SMP_SUPPORT &&\n"
+                "CYGFUN_KERNEL_API_C && \n"
+                "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
+                "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+                "!CYGPKG_HAL_I386_LINUX &&\n"
+                "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
+                "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+}
+
+#endif // CYGSEM_KERNEL_SCHED_TIMESLICE etc.
+
+//==========================================================================
+// EOF timeslice.c
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,68 @@
+2001-09-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* include/redboot.h: Include string function prototype header.
+
+2001-09-06  Jesper Skov  <jskov@redhat.com>
+
+	* src/fs/ide.c (ide_read_sectors): Use diag_(s)printf.
+	* src/fs/disk.c (do_disks): Same.
+
+2001-08-27  Mark Salter  <msalter@redhat.com>
+
+	* src/syscall.c (HZ): Should be 60 for ARM, also.
+
+2001-08-24  Tim Smith  <tsmith@redhat.com>
+	* src/xyzModem.c
+	* src/xyzModem.h
+	Provide xyzModem_stream_terminate() function to abort/clean up
+	XYZmodem download on normal termination or after errors.
+
+	* src/load.c
+	Use aforementioned function to abort downloads on SREC errors,
+	stop load_srec_image() from injecting stuff into the XYZmodem
+	stream and confusing things.
+
+2001-08-24  Mark Salter  <msalter@redhat.com>
+
+	* src/net/net_io.c: Don't close connections if there is
+	data left to read or write.
+
+	* src/syscall.c: Add support for utimes syscall.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* src/net/udp.c: 
+
+	* src/net/pktbuf.c: 
+
+	* src/net/ping.c: 
+
+	* src/net/net_io.c: 
+
+	* src/net/inet_addr.c: 
+
+	* src/net/enet.c: 
+
+	* src/fs/e2fs.c: 
+
+	* src/xyzModem.c: 
+	* src/parse.c: 
+	* src/misc_funs.c: 
+	* src/main.c: 
+	* src/load.c: 
+	* src/io.c: 
+	* src/flash.c: 
+	* include/net/net.h: 
+	* include/redboot.h: 
+	printf() is no longer a part of RedBoot.  Thus all programs
+	must use diag_printf() and related functions instead.  Also
+	renamed the non-standard function gets() to be _rb_gets()
+	since there was some confusion about it because of it's
+	rather standard name.
+
+	* cdl/redboot.cdl: Lots of changes based on moving all printf()
+	functionality into "infra" and only using it as diag_XXX().
+
 2001-08-17  Gary Thomas  <gthomas@redhat.com>
 
 	* src/version.c: Augment version information with startup mode.
--- a/packages/redboot/current/cdl/redboot.cdl
+++ b/packages/redboot/current/cdl/redboot.cdl
@@ -68,6 +68,9 @@ cdl_package CYGPKG_REDBOOT {
         requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
         requires CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 
+        requires CYGINT_ISO_STRING_MEMFUNCS 
+        requires CYGINT_ISO_STRING_STRFUNCS
+
         cdl_option CYGBLD_BUILD_REDBOOT_WITH_THREADS {
             display "Threads debugging support"
             no_define
@@ -98,7 +101,7 @@ cdl_package CYGPKG_REDBOOT {
                      This is handled by a rule in the target CDL."
 
         compile main.c crc.c
-        compile printf.c misc_funs.c io.c parse.c ticks.c xyzModem.c syscall.c
+        compile misc_funs.c io.c parse.c ticks.c xyzModem.c syscall.c
         compile decompress.c
         compile -library=libextras.a load.c
 
--- a/packages/redboot/current/include/net/net.h
+++ b/packages/redboot/current/include/net/net.h
@@ -578,7 +578,7 @@ extern char *inet_ntoa(in_addr_t *);
 
 #ifdef BSP_LOG
 #define BSPLOG(x) { int old_console = start_console(); x; end_console(old_console); }
-#define bsp_log printf
+#define bsp_log diag_printf
 #else
 #define BSPLOG(x)
 #endif
--- a/packages/redboot/current/include/redboot.h
+++ b/packages/redboot/current/include/redboot.h
@@ -50,6 +50,8 @@
 #include <pkgconf/hal.h>
 #include <cyg/hal/hal_if.h>
 #include <cyg/hal/hal_tables.h>
+#include <cyg/infra/diag.h>
+#include <string.h>
 
 #ifdef CYGPKG_REDBOOT_NETWORKING
 #include <net/net.h>
@@ -96,27 +98,18 @@ EXTERN int console_baud_rate;
 #endif
 
 // Prototypes
-typedef int _printf_fun(char *fmt, ...);
-_printf_fun printf;
-int  vprintf(char *fmt, va_list ap);
-int  sprintf(char *buf, char *fmt, ...);
-int  vsprintf(char *buf, char *fmt, va_list ap);
-int  strlen(const char *str);
-int  strcmp(const char *s1, const char *s2);
-int  strncmp(const char *s1, const char *s2, int len);
-int  strcmpci(const char *s1, const char *s2);
-int  strncmpci(const char *s1, const char *s2, int len);
-char *strcpy(char *s1, const char *s2);
-char *strncpy(char *s1, const char *s2, unsigned long n);
+typedef int _printf_fun(const char *fmt, ...);
+externC int  strcasecmp(const char *s1, const char *s2);
+externC int  strncasecmp(const char *s1, const char *s2, size_t len);
 
-void mon_write_char(char c);
-bool verify_action(char *fmt, ...);
-void dump_buf(void *, CYG_ADDRWORD);
-void dump_buf_with_offset(void *, CYG_ADDRWORD, void *);
-void vdump_buf_with_offset(_printf_fun *pf, void *, CYG_ADDRWORD, void *);
+externC void mon_write_char(char c);
+externC bool verify_action(char *fmt, ...);
+//void dump_buf(void *, CYG_ADDRWORD);
+//void dump_buf_with_offset(void *, CYG_ADDRWORD, void *);
+//void vdump_buf_with_offset(_printf_fun *pf, void *, CYG_ADDRWORD, void *);
 
 // Read a single line of input from the console, possibly with timeout
-int  gets(char *line, int len, int timeout);
+externC int  _rb_gets(char *line, int len, int timeout);
 // Result codes from 'gets()'
 #define _GETS_TIMEOUT -1
 #define _GETS_CTRLC   -2
@@ -124,8 +117,8 @@ int  gets(char *line, int len, int timeo
 #define _GETS_OK       1
 
 // "console" selection
-int  start_console(void);
-void end_console(int old_console);
+externC int  start_console(void);
+externC void end_console(int old_console);
 
 // CRC support
 unsigned short crc16(unsigned char *buf, int len);
@@ -152,8 +145,8 @@ externC _decompress_fun_close* _dc_close
 #endif // CYGPKG_COMPRESS_ZLIB
 
 // CLI support functions
-bool parse_num(char *s, unsigned long *val, char **es, char *delim);
-bool parse_bool(char *s, bool *val);
+externC bool parse_num(char *s, unsigned long *val, char **es, char *delim);
+externC bool parse_bool(char *s, bool *val);
 
 typedef void cmd_fun(int argc, char *argv[]);
 struct cmd {
@@ -162,8 +155,8 @@ struct cmd {
     char    *usage;
     cmd_fun *fun;
 } CYG_HAL_TABLE_TYPE;
-extern struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg);
-extern void        cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix);
+externC struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg);
+externC void        cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix);
 #define RedBoot_cmd(_s_,_h_,_u_,_f_) cmd_entry(_s_,_h_,_u_,_f_,RedBoot_commands)
 #define _cmd_entry(_s_,_h_,_u_,_f_,_n_)                                   \
 cmd_fun _f_;                                                      \
@@ -224,17 +217,17 @@ struct option_info {
 #define OPTION_ARG_TYPE_FLG 2    // Flag only
 
 // Command line parsing
-struct cmd *parse(char *line, int *argc, char **argv);
+externC struct cmd *parse(char *line, int *argc, char **argv);
 
-extern void init_opts(struct option_info *opts, char flag, bool takes_arg, 
-                      int arg_type, void **arg, bool *arg_set, char *name);
-extern bool scan_opts(int argc, char *argv[], int first, 
-                      struct option_info *opts, int num_opts, 
-                      void **def_arg, int def_arg_type, char *def_descr);
+externC void init_opts(struct option_info *opts, char flag, bool takes_arg, 
+                       int arg_type, void **arg, bool *arg_set, char *name);
+externC bool scan_opts(int argc, char *argv[], int first, 
+                       struct option_info *opts, int num_opts, 
+                       void **def_arg, int def_arg_type, char *def_descr);
 
-extern int redboot_getc(void);
-extern void redboot_getc_init(int (*fun)(char *, int, int *), int verbose);
-extern void redboot_getc_rewind(void);
+externC int redboot_getc(void);
+externC void redboot_getc_init(int (*fun)(char *, int, int *), int verbose);
+externC void redboot_getc_rewind(void);
 
 #define BUF_SIZE 256
 typedef struct {
@@ -283,11 +276,12 @@ typedef struct {
     return ret;
 }
 
+
 //
 // Convert a character to lower case
 //
 __inline__ static char
-tolower(char c)
+_tolower(char c)
 {
     if ((c >= 'A') && (c <= 'Z')) {
         c = (c - 'A') + 'a';
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -155,7 +155,7 @@ static int   cfg_size;   // Length of co
 static void
 fis_usage(char *why)
 {
-    printf("*** invalid 'fis' command: %s\n", why);
+    diag_printf("*** invalid 'fis' command: %s\n", why);
     cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis ");
 }
 
@@ -196,10 +196,10 @@ fis_init(int argc, char *argv[])
     }
 
     if (!verify_action("About to initialize [format] FLASH image system")) {
-        printf("** Aborted\n");
+        diag_printf("** Aborted\n");
         return;
     }
-    printf("*** Initialize FLASH Image System\n");
+    diag_printf("*** Initialize FLASH Image System\n");
 
 #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE
     redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE;
@@ -280,8 +280,8 @@ fis_init(int argc, char *argv[])
             erase_size -= erase_start;
             if ((stat = flash_erase((void *)erase_start, erase_size,
                                     (void **)&err_addr)) != 0) {
-                printf("   initialization failed at %p: %s\n",
-                       err_addr, flash_errmsg(stat));
+                diag_printf("   initialization failed at %p: %s\n",
+                            err_addr, flash_errmsg(stat));
             }
         }
         // second deal with the larger part in the main:
@@ -293,11 +293,11 @@ fis_init(int argc, char *argv[])
 #endif
         if ((stat = flash_erase((void *)erase_start, erase_size,
                                 (void **)&err_addr)) != 0) {
-            printf("   initialization failed at %p: %s\n",
-                   err_addr, flash_errmsg(stat));
+            diag_printf("   initialization failed at %p: %s\n",
+                        err_addr, flash_errmsg(stat));
         }
     } else {
-        printf("    Warning: device contents not erased, some blocks may not be usable\n");
+        diag_printf("    Warning: device contents not erased, some blocks may not be usable\n");
     }
 
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -305,13 +305,13 @@ fis_init(int argc, char *argv[])
     flash_unlock((void *)fis_base, block_size, (void **)&err_addr);
 #endif
     if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) {
-            printf("   initialization failed at %p: %s\n", err_addr, flash_errmsg(stat));
+        diag_printf("   initialization failed at %p: %s\n", err_addr, flash_errmsg(stat));
     } else {
         if ((stat = flash_program(fis_base, fis_work_block, 
                                   (unsigned long)img - (unsigned long)fis_work_block,
                                   (void **)&err_addr)) != 0) {
-            printf("Error writing image descriptors at %p: %s\n", 
-                   err_addr, flash_errmsg(stat));
+            diag_printf("Error writing image descriptors at %p: %s\n", 
+                        err_addr, flash_errmsg(stat));
         }
     }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -344,25 +344,25 @@ fis_list(int argc, char *argv[])
     }
 
     img = (struct fis_image_desc *)((unsigned long)flash_end - block_size);
-    // Let printf do the formatting in both cases, rather than cnouting
+    // Let diag_printf do the formatting in both cases, rather than cnouting
     // cols by hand....
-    printf("%-16s  %-10s  %-10s  %-10s  %-s\n",
-           "Name","FLASH addr",
-           show_cksums ? "Checksum" : "Mem addr",
-           show_datalen ? "Datalen" : "Length",
-           "Entry point" );
+    diag_printf("%-16s  %-10s  %-10s  %-10s  %-s\n",
+                "Name","FLASH addr",
+                show_cksums ? "Checksum" : "Mem addr",
+                show_datalen ? "Datalen" : "Length",
+                "Entry point" );
     for (i = 0;  i < block_size/sizeof(*img);  i++, img++) {
         if (img->name[0] != (unsigned char)0xFF) {
-            printf("%-16s  0x%08lX  0x%08lX  0x%08lX  0x%08lX\n", img->name, 
-                   img->flash_base, 
+            diag_printf("%-16s  0x%08lX  0x%08lX  0x%08lX  0x%08lX\n", img->name, 
+                        img->flash_base, 
 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
-                   show_cksums ? img->file_cksum : img->mem_base, 
-                   show_datalen ? img->data_length : img->size, 
+                        show_cksums ? img->file_cksum : img->mem_base, 
+                        show_datalen ? img->data_length : img->size, 
 #else
-                   img->mem_base, 
-                   img->size, 
+                        img->mem_base, 
+                        img->size, 
 #endif
-                   img->entry_point);
+                        img->entry_point);
         }
     }
 }
@@ -381,8 +381,8 @@ fis_free(int argc, char *argv[])
         if (*fis_ptr != (unsigned long)0xFFFFFFFF) {
             if (area_start != fis_ptr) {
                 // Assume that this is something
-                printf("  0x%08lX .. 0x%08lX\n",
-                       (unsigned long)area_start, (unsigned long)fis_ptr);
+                diag_printf("  0x%08lX .. 0x%08lX\n",
+                            (unsigned long)area_start, (unsigned long)fis_ptr);
             }
             // Find next blank block
             area_start = fis_ptr;
@@ -398,8 +398,8 @@ fis_free(int argc, char *argv[])
         }
     }
     if (area_start != fis_ptr) {
-        printf("  0x%08lX .. 0x%08lX\n", 
-               (unsigned long)area_start, (unsigned long)fis_ptr);
+        diag_printf("  0x%08lX .. 0x%08lX\n", 
+                    (unsigned long)area_start, (unsigned long)fis_ptr);
     }
 }
 
@@ -526,34 +526,34 @@ fis_create(int argc, char *argv[])
 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken
     length = ((length + block_size - 1) / block_size) * block_size;
     if (length < img_size) {
-        printf("Invalid FLASH image size/length combination\n");
+        diag_printf("Invalid FLASH image size/length combination\n");
         return;
     }
 #endif
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) {
-        printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
-        printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
+        diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
+        diag_printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
         return;
     }
     if (flash_addr_set && flash_addr & (block_size-1)) {
-        printf("Invalid FLASH address: %p\n", (void *)flash_addr);
-        printf("   must be 0x%x aligned\n", block_size);
+        diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
+        diag_printf("   must be 0x%x aligned\n", block_size);
         return;
     }
     if (strlen(name) >= sizeof(img->name)) {
-        printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name));
+        diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name));
         return;
     }
     if (!no_copy) {
         if ((mem_addr < (unsigned long)ram_start) ||
             ((mem_addr+img_size) >= (unsigned long)ram_end)) {
-            printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
-            printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
+            diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
+            diag_printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
         }
         if (!flash_addr_set && !fis_find_free(&flash_addr, length)) {
-            printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length);
+            diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length);
             return;
         }
     }
@@ -566,11 +566,11 @@ fis_create(int argc, char *argv[])
     for (i = 0;  i < block_size/sizeof(*img);  i++, img++) {
         if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
             if (flash_addr_set && (img->flash_base != flash_addr)) {
-                printf("Image found, but FLASH address incorrect\n");
+                diag_printf("Image found, but FLASH address incorrect\n");
                 return;
             }
             if (img->size != length) {
-                printf("Image found, but LENGTH is incorrect (0x%lx != 0x%lx)\n", img->size, length);
+                diag_printf("Image found, but LENGTH is incorrect (0x%lx != 0x%lx)\n", img->size, length);
                 return;
             }
             if (!verify_action("An image named '%s' exists", name)) {
@@ -601,21 +601,21 @@ fis_create(int argc, char *argv[])
     if (!no_copy) {
         // Safety check - make sure the address range is not within the code we're running
         if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) {
-            printf("Can't program this region - contains code in use!\n");
+            diag_printf("Can't program this region - contains code in use!\n");
             return;
         }
         prog_ok = true;
         if (prog_ok) {
             // Erase area to be programmed
             if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-                printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
+                diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
                 prog_ok = false;
             }
         }
         if (prog_ok) {
             // Now program it
             if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) {
-                printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
+                diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
                 prog_ok = false;
             }
         }
@@ -637,12 +637,12 @@ fis_create(int argc, char *argv[])
         flash_unlock((void *)fis_addr, block_size, (void **)&err_addr);
 #endif
         if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) {
-            printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
+            diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
             // Don't try to program if the erase failed
         } else {
             // Now program it
             if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) {
-                printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat));
+                diag_printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat));
             }
         }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -703,12 +703,12 @@ fis_delete(int argc, char *argv[])
         }
     }
     if (!slot_found) {
-        printf("No image '%s' found\n", name);
+        diag_printf("No image '%s' found\n", name);
         return;
     }
     // Erase Data blocks (free space)
     if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) {
-        printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
+        diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
     } else {
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
         // Insure [quietly] that the directory is unlocked before trying to update
@@ -717,12 +717,12 @@ fis_delete(int argc, char *argv[])
         // Update directory
         memset(img, 0xFF, sizeof(*img));
         if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) {
-            printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
+            diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
             // Don't try to program if the erase failed
         } else {
             // Now program it
             if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) {
-                printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat));
+                diag_printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat));
             }
         }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -766,7 +766,7 @@ fis_load(int argc, char *argv[])
         return;
     }
     if ((img = fis_lookup(name)) == (struct fis_image_desc *)0) {
-        printf("No image '%s' found\n", name);
+        diag_printf("No image '%s' found\n", name);
         return;
     }
     if (!mem_addr_set) {
@@ -775,7 +775,7 @@ fis_load(int argc, char *argv[])
     // Load image from FLASH into RAM
     if ((mem_addr < (unsigned long)user_ram_start) ||
         ((mem_addr+img->size) >= (unsigned long)user_ram_end)) {
-        printf("Not a loadable image\n");
+        diag_printf("Not a loadable image\n");
         return;
     }
 #ifdef CYGPKG_COMPRESS_ZLIB
@@ -798,9 +798,9 @@ fis_load(int argc, char *argv[])
         err = (*_dc_close)(p, err);
 
         if (0 != err && p->msg) {
-            printf("decompression error: %s\n", p->msg);
+            diag_printf("decompression error: %s\n", p->msg);
         } else {
-            printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf);
+            diag_printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf);
         }
 
     } else // dangling block
@@ -812,13 +812,13 @@ fis_load(int argc, char *argv[])
 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK
     cksum = crc32((unsigned char *)mem_addr, img->data_length);
     if (show_cksum) {
-        printf("Checksum: 0x%08lx\n", cksum);
+        diag_printf("Checksum: 0x%08lx\n", cksum);
     }
     // When decompressing, leave CRC checking to decompressor
     if (!decompress && img->file_cksum) {
         if (cksum != img->file_cksum) {
-            printf("** Warning - checksum failure.  stored: 0x%08lx, computed: 0x%08lx\n",
-                   img->file_cksum, cksum);
+            diag_printf("** Warning - checksum failure.  stored: 0x%08lx, computed: 0x%08lx\n",
+                        img->file_cksum, cksum);
         }
     }
 #endif
@@ -861,23 +861,23 @@ fis_write(int argc, char *argv[])
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
-        printf("Invalid FLASH address %p: (%s)\n", (void *)flash_addr, flash_errmsg(stat));
-        printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
+        diag_printf("Invalid FLASH address %p: (%s)\n", (void *)flash_addr, flash_errmsg(stat));
+        diag_printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
         return;
     }
     if (flash_addr_set && flash_addr & (block_size-1)) {
-        printf("Invalid FLASH address: %p\n", (void *)flash_addr);
-        printf("   must be 0x%x aligned\n", block_size);
+        diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
+        diag_printf("   must be 0x%x aligned\n", block_size);
         return;
     }
     if ((mem_addr < (unsigned long)ram_start) ||
         ((mem_addr+length) >= (unsigned long)ram_end)) {
-        printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
-        printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
+        diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
+        diag_printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
     }
     // Safety check - make sure the address range is not within the code we're running
     if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) {
-        printf("Can't program this region - contains code in use!\n");
+        diag_printf("Can't program this region - contains code in use!\n");
         return;
     }
     if (!verify_action("* CAUTION * about to program FLASH\n            at %p..%p from %p", 
@@ -889,14 +889,14 @@ fis_write(int argc, char *argv[])
     if (prog_ok) {
         // Erase area to be programmed
         if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-            printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
+            diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
             prog_ok = false;
         }
     }
     if (prog_ok) {
         // Now program it
         if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) {
-            printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
+            diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
             prog_ok = false;
         }
     }
@@ -929,22 +929,22 @@ fis_erase(int argc, char *argv[])
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
-        printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
-        printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
+        diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
+        diag_printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
         return;
     }
     if (flash_addr_set && flash_addr & (block_size-1)) {
-        printf("Invalid FLASH address: %p\n", (void *)flash_addr);
-        printf("   must be 0x%x aligned\n", block_size);
+        diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr);
+        diag_printf("   must be 0x%x aligned\n", block_size);
         return;
     }
     // Safety check - make sure the address range is not within the code we're running
     if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) {
-        printf("Can't erase this region - contains code in use!\n");
+        diag_printf("Can't erase this region - contains code in use!\n");
         return;
     }
     if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
+        diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat));
     }
 }
 
@@ -977,12 +977,12 @@ fis_lock(int argc, char *argv[])
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
-        printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
-        printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
+        diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
+        diag_printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
         return;
     }
     if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat));
+        diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat));
     }
 }
 
@@ -1013,12 +1013,12 @@ fis_unlock(int argc, char *argv[])
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+length-1))))) {
-        printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
-        printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
+        diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat));
+        diag_printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
         return;
     }
     if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat));
+        diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat));
     }
 }
 #endif
@@ -1029,7 +1029,7 @@ void
 _flash_info(void)
 {
     if (!__flash_init) return;
-    printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", 
+    diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", 
            flash_start, flash_end, blocks, (void *)block_size);
 }
 
@@ -1041,8 +1041,8 @@ do_flash_init(void)
     if (!__flash_init) {
         __flash_init = 1;
         if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE), 
-                               FLASH_MIN_WORKSPACE, printf)) != 0) {
-            printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
+                               FLASH_MIN_WORKSPACE, diag_printf)) != 0) {
+            diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat));
             return false;
         }
         flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end);
@@ -1198,52 +1198,52 @@ get_config(unsigned char *dp, char *titl
     }
     val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);
     if (LIST_OPT_NICKNAMES & list_opt)
-        printf("%s: ", CONFIG_OBJECT_KEY(dp));
+        diag_printf("%s: ", CONFIG_OBJECT_KEY(dp));
     if (LIST_OPT_FULLNAMES & list_opt) {
         if (title != (char *)NULL) {
-            printf("%s: ", title);
+            diag_printf("%s: ", title);
         } else {
-            printf("%s: ", CONFIG_OBJECT_KEY(dp));
+            diag_printf("%s: ", CONFIG_OBJECT_KEY(dp));
         }
     }
     switch (type = CONFIG_OBJECT_TYPE(dp)) {
     case CONFIG_BOOL:
         memcpy(&hold_bool_val, val_ptr, sizeof(bool));
-        printf("%s ", hold_bool_val ? "true" : "false");
+        diag_printf("%s ", hold_bool_val ? "true" : "false");
         break;
     case CONFIG_INT:
         memcpy(&hold_int_val, val_ptr, sizeof(unsigned long));
-        printf("%ld ", hold_int_val);
+        diag_printf("%ld ", hold_int_val);
         break;
 #ifdef CYGPKG_REDBOOT_NETWORKING
     case CONFIG_IP:
-        printf("%s ", inet_ntoa((in_addr_t *)val_ptr));
+        diag_printf("%s ", inet_ntoa((in_addr_t *)val_ptr));
         break;
     case CONFIG_ESA:
         for (esa_ptr = 0;  esa_ptr < sizeof(enet_addr_t);  esa_ptr++) {
-            printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]);
-            if (esa_ptr < (sizeof(enet_addr_t)-1)) printf(":");
+            diag_printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]);
+            if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":");
         }
-        printf(" ");
+        diag_printf(" ");
         break;
 #endif
     case CONFIG_STRING:
-        printf("%s ", (unsigned char *)val_ptr);
+        diag_printf("%s ", (unsigned char *)val_ptr);
         break;
     case CONFIG_SCRIPT:
-        printf("\n");
+        diag_printf("\n");
         sp = lp = (unsigned char *)val_ptr;
         while (*sp) {
             while (*lp != '\n') lp++;
             *lp = '\0';
-            printf(".. %s\n", sp);
+            diag_printf(".. %s\n", sp);
             *lp++ = '\n';
             sp = lp;
         }
         break;
     }
     if (LIST_OPT_LIST_ONLY & list_opt) {
-        printf("\n");
+        diag_printf("\n");
         return CONFIG_OK;
     }
     if (type != CONFIG_SCRIPT) {
@@ -1252,10 +1252,10 @@ get_config(unsigned char *dp, char *titl
             if (ret > sizeof(line))
                 return CONFIG_BAD;
             strcpy(line, newvalue);
-            printf("Setting to %s\n", newvalue);
+            diag_printf("Setting to %s\n", newvalue);
         }
         else // read from terminal
-            ret = gets(line, sizeof(line), 0);
+            ret = _rb_gets(line, sizeof(line), 0);
         if (ret < 0) return CONFIG_ABORT;
         if (strlen(line) == 0) return CONFIG_OK;  // Just a CR - leave value untouched
         if (line[0] == '.') return CONFIG_DONE;
@@ -1316,11 +1316,11 @@ get_config(unsigned char *dp, char *titl
     case CONFIG_SCRIPT:
         // Assume it always changes
         sp = (unsigned char *)val_ptr;
-        printf("Enter script, terminate with empty line\n");
+        diag_printf("Enter script, terminate with empty line\n");
         while (true) {
             *sp = '\0';
-            printf(">> ");
-            ret = gets(line, sizeof(line), 0);
+            diag_printf(">> ");
+            ret = _rb_gets(line, sizeof(line), 0);
             if (ret < 0) return CONFIG_ABORT;
             if (strlen(line) == 0) break;
             lp = line;
@@ -1332,7 +1332,7 @@ get_config(unsigned char *dp, char *titl
         break;
     case CONFIG_STRING:
         if (strlen(line) >= MAX_STRING_LENGTH) {
-            printf("Sorry, value is too long\n");
+            diag_printf("Sorry, value is too long\n");
             return CONFIG_BAD;
         }
         strcpy((unsigned char *)val_ptr, line);
@@ -1470,7 +1470,7 @@ do_flash_config(int argc, char *argv[])
             continue;
         case CONFIG_BAD:
             // Nothing - make him do it again
-            printf ("** invalid entry\n");
+            diag_printf ("** invalid entry\n");
         }
     }
 
@@ -1479,10 +1479,10 @@ do_flash_config(int argc, char *argv[])
 #ifdef CYGSEM_REDBOOT_ALLOW_DYNAMIC_FLASH_CONFIG_DATA
         if (verify_action("** entry '%s' not found - add", onlyone)) {
             struct config_option opt;
-            printf("Trying to add value\n");
+            diag_printf("Trying to add value\n");
         }
 #else
-        printf("** entry '%s' not found", onlyone);
+        diag_printf("** entry '%s' not found", onlyone);
 #endif
     }
     if (!need_update)
@@ -1502,7 +1502,7 @@ RedBoot_cmd("alias",
 static void
 make_alias(char *alias, char *name)
 {
-    sprintf(alias, "alias/%s", name);
+    diag_sprintf(alias, "alias/%s", name);
 }
 
 static void
@@ -1516,14 +1516,14 @@ do_alias(int argc, char *argv[])
     case 2:
         make_alias(name, argv[1]);
         if (flash_get_config(name, &val, CONFIG_STRING)) {
-            printf("'%s' = '%s'\n", argv[1], val);
+            diag_printf("'%s' = '%s'\n", argv[1], val);
         } else {
-            printf("'%s' not found\n", argv[1]);
+            diag_printf("'%s' not found\n", argv[1]);
         }
         break;
     case 3:
         if (strlen(argv[2]) >= MAX_STRING_LENGTH) {
-            printf("Sorry, value is too long\n");
+            diag_printf("Sorry, value is too long\n");
             break;
         }
         make_alias(name, argv[1]);
@@ -1535,7 +1535,7 @@ do_alias(int argc, char *argv[])
         flash_add_config(&opt, true);
         break;
     default:
-        printf("usage: alias name [value]\n");
+        diag_printf("usage: alias name [value]\n");
     }
 }
 
@@ -1572,7 +1572,7 @@ bool
                 lp += 2;
                 while (*lp && (*lp != '}')) lp++;
                 if (!*lp) {
-                    printf("Invalid macro/alias '%s'\n", ms);
+                    diag_printf("Invalid macro/alias '%s'\n", ms);
                     line[0] = '\0';  // Destroy line
                     return false;
                 }
@@ -1599,12 +1599,12 @@ bool
                         }
                         line_len = strlen(line);
                     } else {
-                        printf("No room to expand '%s'\n", ms);
+                        diag_printf("No room to expand '%s'\n", ms);
                         line[0] = '\0';  // Destroy line
                         return false;
                     }
                 } else {
-                    printf("Alias '%s' not defined\n", ms);
+                    diag_printf("Alias '%s' not defined\n", ms);
                     *me = '|';
                 }
             } else if (c == '"') {
@@ -1642,12 +1642,12 @@ flash_write_config(void)
         flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr);
 #endif
         if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) {
-            printf("   initialization failed at %p: %s\n", err_addr, flash_errmsg(stat));
+            diag_printf("   initialization failed at %p: %s\n", err_addr, flash_errmsg(stat));
         } else {
             if ((stat = flash_program(cfg_base, (void *)&config, 
                                       sizeof(config), (void **)&err_addr)) != 0) {
-                printf("Error writing config data at %p: %s\n", 
-                       err_addr, flash_errmsg(stat));
+                diag_printf("Error writing config data at %p: %s\n", 
+                            err_addr, flash_errmsg(stat));
             }
         }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -1677,7 +1677,7 @@ flash_lookup_config(char *key)
         }
         dp += len;
     }
-//    printf("Can't find config data for '%s'\n", key);
+//    diag_printf("Can't find config data for '%s'\n", key);
     return false;
 }
 
@@ -1718,7 +1718,7 @@ flash_get_config(char *key, void *val, i
                 break;
             }
         } else {
-            printf("Request for config value '%s' - wrong type\n", key);
+            diag_printf("Request for config value '%s' - wrong type\n", key);
         }
         return true;
     }
@@ -1814,7 +1814,7 @@ flash_add_config(struct config_option *o
             size += len;
         }
     }
-    printf("No space to add '%s'\n", opt->key);
+    diag_printf("No space to add '%s'\n", opt->key);
     return false;
 }
 
@@ -1858,7 +1858,7 @@ load_flash_config(void)
     memcpy(&config, cfg_base, sizeof(config));
     if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) ||
         (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) {
-        printf("FLASH configuration checksum error or invalid key\n");
+        diag_printf("FLASH configuration checksum error or invalid key\n");
         config_init();
         return;
     }
--- a/packages/redboot/current/src/fs/disk.c
+++ b/packages/redboot/current/src/fs/disk.c
@@ -310,20 +310,22 @@ do_disks(int argc, char *argv[])
     char name[16];
 
     for (i = 0, d = disk_table;  i < disk_count;  i++, d++) {
-	switch (d->kind) {
-	  case DISK_IDE_HD:
-	    for (j = 0, p = d->partitions; j < CYGNUM_REDBOOT_MAX_PARTITIONS; j++, p++) {
-		if (p->systype) {
-		    sprintf(name, "hd%c%d", 'a' + d->index, j+1);
-		    printf("%-8s %s\n", name, systype_name(p->systype));
-		}
-	    }
-	    break;
-	  case DISK_IDE_CDROM:
-	    sprintf(name, "cd%d", d->index);
-	    printf("%-8s ISO9660\n", name);
-	    break;
-	}
+        switch (d->kind) {
+          case DISK_IDE_HD:
+            for (j = 0, p = d->partitions;
+                 j < CYGNUM_REDBOOT_MAX_PARTITIONS;
+                 j++, p++) {
+                if (p->systype) {
+                    diag_sprintf(name, "hd%c%d", 'a' + d->index, j+1);
+                    diag_printf("%-8s %s\n", name, systype_name(p->systype));
+                }
+            }
+            break;
+          case DISK_IDE_CDROM:
+            diag_sprintf(name, "cd%d", d->index);
+            diag_printf("%-8s ISO9660\n", name);
+            break;
+        }
     }
 }
 
--- a/packages/redboot/current/src/fs/e2fs.c
+++ b/packages/redboot/current/src/fs/e2fs.c
@@ -88,8 +88,8 @@ e2fs_get_gdesc(e2fs_desc_t *e2fs, cyg_ui
 	sec_nr += (group_nr / E2FS_GDESC_PER_SECTOR);
 
 #if DEBUG_E2FS > 2
-	printf("%s: group[%d] cache miss, sec_nr[%d]\n",
-	       __FUNCTION__, group_nr, sec_nr);
+	diag_printf("%s: group[%d] cache miss, sec_nr[%d]\n",
+                    __FUNCTION__, group_nr, sec_nr);
 #endif
 	if (!PARTITION_READ(e2fs->part, sec_nr, (cyg_uint32 *)e2fs->gdesc_cache,
 			    sizeof(e2fs->gdesc_cache)/SECTOR_SIZE))
@@ -125,8 +125,8 @@ e2fs_get_inode(e2fs_desc_t *e2fs, int in
     offset %= SECTOR_SIZE;
 
 #if DEBUG_E2FS > 0
-    printf("%s: ino[%d], sec_nr[%d] offset[%d]\n", __FUNCTION__,
-	   ino, sec_nr, offset);
+    diag_printf("%s: ino[%d], sec_nr[%d] offset[%d]\n", __FUNCTION__,
+                ino, sec_nr, offset);
 #endif
 
     if (!PARTITION_READ(e2fs->part, sec_nr, buf, 1))
@@ -135,7 +135,7 @@ e2fs_get_inode(e2fs_desc_t *e2fs, int in
     *ip = *(e2fs_inode_t *)((char *)buf + offset);
 
 #if DEBUG_E2FS > 0
-    printf("%s: inode size[%d]\n", __FUNCTION__, SWAB_LE32(ip->size));
+    diag_printf("%s: inode size[%d]\n", __FUNCTION__, SWAB_LE32(ip->size));
 #endif
 
     return 1;
@@ -158,7 +158,7 @@ e2fs_mount(partition_t *part, e2fs_desc_
 	return -1;
 
     if (SWAB_LE16(sb->magic) != E2FS_SUPER_MAGIC) {
-	printf("ext2_mount: bad magic 0x%x\n", SWAB_LE16(sb->magic));
+	diag_printf("ext2_mount: bad magic 0x%x\n", SWAB_LE16(sb->magic));
 	return -1;
     }
 
@@ -181,12 +181,12 @@ e2fs_mount(partition_t *part, e2fs_desc_
 	return -1;
 
 #if DEBUG_E2FS > 1
-    printf("E2FS superblock:\n");
-    printf("   [%d] inodes\n", SWAB_LE32(sb->inodes_count));
-    printf("   [%d] blocks\n", SWAB_LE32(sb->blocks_count));
-    printf("   [%d] blocksize\n", e2fs->blocksize);
-    printf("   [%d] blocks per group\n", e2fs->blocks_per_group);
-    printf("   [%d] ngroups\n", e2fs->ngroups);
+    diag_printf("E2FS superblock:\n");
+    diag_printf("   [%d] inodes\n", SWAB_LE32(sb->inodes_count));
+    diag_printf("   [%d] blocks\n", SWAB_LE32(sb->blocks_count));
+    diag_printf("   [%d] blocksize\n", e2fs->blocksize);
+    diag_printf("   [%d] blocks per group\n", e2fs->blocks_per_group);
+    diag_printf("   [%d] ngroups\n", e2fs->ngroups);
 #endif
 
 #if DEBUG_E2FS > 4
@@ -289,13 +289,13 @@ e2fs_dir_lookup(e2fs_desc_t *e2fs, cyg_u
     cyg_uint32 nblocks, last_block_size, i, block_nr, nbytes;
 
 #if DEBUG_E2FS > 0
-    printf("%s: looking for %s [%d] in ino[%d]\n",
-	   __FUNCTION__, name, namelen, dir_ino);
+    diag_printf("%s: looking for %s [%d] in ino[%d]\n",
+                __FUNCTION__, name, namelen, dir_ino);
 #endif
 
     if (!e2fs_get_inode(e2fs, dir_ino, &inode)) {
 #if DEBUG_E2FS > 0
-	printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, dir_ino);
+	diag_printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, dir_ino);
 #endif
 	return NULL;
     }
@@ -349,7 +349,7 @@ e2fs_follow_symlink(e2fs_desc_t *e2fs, c
 
     if (!e2fs_get_inode(e2fs, sym_ino, &inode)) {
 #if DEBUG_E2FS > 0
-	printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, *ino);
+	diag_printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, *ino);
 #endif
 	return 0;
     }
@@ -472,19 +472,19 @@ e2fs_open(partition_t *p, const char *fi
 
     // mount partition
     if (e2fs_mount(p, &rinfo.e2fs_desc) != 0) {
-	printf("mount failed.\n");
+	diag_printf("mount failed.\n");
 	return NULL;
     }
 
     // find file inode
     if (!e2fs_inode_lookup(&rinfo.e2fs_desc, E2FS_ROOT_INO, filepath, &ino_info)) {
-	printf("%s: e2fs_inode_lookup failed\n", __FUNCTION__);
+	diag_printf("%s: e2fs_inode_lookup failed\n", __FUNCTION__);
 	return NULL;
     }
 
     // read inode
     if (!e2fs_get_inode(&rinfo.e2fs_desc, ino_info.ino, &rinfo.inode)) {
-	printf("%s: e2fs_get_inode failed for ino[%d]\n", __FUNCTION__, ino_info.ino);
+	diag_printf("%s: e2fs_get_inode failed for ino[%d]\n", __FUNCTION__, ino_info.ino);
 	return NULL;
     }
 
@@ -552,46 +552,46 @@ e2fs_read(void *fp, char *buf, cyg_uint3
 #if DEBUG_E2FS > 4
 static void dump_sb(struct e2fs_super_block *s)
 {
-    printf("inode_count: %d\n", SWAB_LE32(s->inodes_count));
-    printf("blocks_count: %d\n", SWAB_LE32(s->blocks_count));
-    printf("r_blocks_count: %d\n", SWAB_LE32(s->r_blocks_count));
-    printf("free_blocks_count: %d\n", SWAB_LE32(s->free_blocks_count));
-    printf("free_inodes_count: %d\n", SWAB_LE32(s->free_inodes_count));
-    printf("first_data_block: %d\n", SWAB_LE32(s->first_data_block));
-    printf("log_block_size: %d\n", SWAB_LE32(s->log_block_size));
-    printf("log_frag_size: %d\n", SWAB_LE32(s->log_frag_size));
-    printf("blocks_per_group: %d\n", SWAB_LE32(s->blocks_per_group));
-    printf("frags_per_group: %d\n", SWAB_LE32(s->frags_per_group));
-    printf("inodes_per_group: %d\n", SWAB_LE32(s->inodes_per_group));
-    printf("mnt_count: %d\n", SWAB_LE16(s->mnt_count));
-    printf("max_mnt_count: %d\n", SWAB_LE16(s->max_mnt_count));
-    printf("magic: %d\n", SWAB_LE16(s->magic));
-    printf("state: %d\n", SWAB_LE16(s->state));
-    printf("errors: %d\n", SWAB_LE16(s->errors));
-    printf("minor_rev_level: %d\n", SWAB_LE16(s->minor_rev_level));
-    printf("lastcheck: %d\n", SWAB_LE32(s->lastcheck));
-    printf("checkinterval: %d\n", SWAB_LE32(s->checkinterval));
-    printf("creator_os: %d\n", SWAB_LE32(s->creator_os));
-    printf("rev_level: %d\n", SWAB_LE32(s->rev_level));
+    diag_printf("inode_count: %d\n", SWAB_LE32(s->inodes_count));
+    diag_printf("blocks_count: %d\n", SWAB_LE32(s->blocks_count));
+    diag_printf("r_blocks_count: %d\n", SWAB_LE32(s->r_blocks_count));
+    diag_printf("free_blocks_count: %d\n", SWAB_LE32(s->free_blocks_count));
+    diag_printf("free_inodes_count: %d\n", SWAB_LE32(s->free_inodes_count));
+    diag_printf("first_data_block: %d\n", SWAB_LE32(s->first_data_block));
+    diag_printf("log_block_size: %d\n", SWAB_LE32(s->log_block_size));
+    diag_printf("log_frag_size: %d\n", SWAB_LE32(s->log_frag_size));
+    diag_printf("blocks_per_group: %d\n", SWAB_LE32(s->blocks_per_group));
+    diag_printf("frags_per_group: %d\n", SWAB_LE32(s->frags_per_group));
+    diag_printf("inodes_per_group: %d\n", SWAB_LE32(s->inodes_per_group));
+    diag_printf("mnt_count: %d\n", SWAB_LE16(s->mnt_count));
+    diag_printf("max_mnt_count: %d\n", SWAB_LE16(s->max_mnt_count));
+    diag_printf("magic: %d\n", SWAB_LE16(s->magic));
+    diag_printf("state: %d\n", SWAB_LE16(s->state));
+    diag_printf("errors: %d\n", SWAB_LE16(s->errors));
+    diag_printf("minor_rev_level: %d\n", SWAB_LE16(s->minor_rev_level));
+    diag_printf("lastcheck: %d\n", SWAB_LE32(s->lastcheck));
+    diag_printf("checkinterval: %d\n", SWAB_LE32(s->checkinterval));
+    diag_printf("creator_os: %d\n", SWAB_LE32(s->creator_os));
+    diag_printf("rev_level: %d\n", SWAB_LE32(s->rev_level));
 }
 
 static void dump_inode(struct e2fs_inode *i)
 {
     int j, n;
 
-    printf("mode: %o\n", SWAB_LE16(i->mode));
-    printf("uid: %o\n", SWAB_LE16(i->uid));
-    printf("size: %d\n", SWAB_LE32(i->size));
-    printf("gid: %o\n", SWAB_LE16(i->gid));
-    printf("links: %d\n", SWAB_LE16(i->links_count));
-    printf("blocks: %d\n", SWAB_LE32(i->blocks));
+    diag_printf("mode: %o\n", SWAB_LE16(i->mode));
+    diag_printf("uid: %o\n", SWAB_LE16(i->uid));
+    diag_printf("size: %d\n", SWAB_LE32(i->size));
+    diag_printf("gid: %o\n", SWAB_LE16(i->gid));
+    diag_printf("links: %d\n", SWAB_LE16(i->links_count));
+    diag_printf("blocks: %d\n", SWAB_LE32(i->blocks));
 
     n = i->blocks;
     if (n > E2FS_N_BLOCKS)
 	n = E2FS_N_BLOCKS;
 
     for (j = 0; j < n; j++)
-	printf("  block: %d\n", SWAB_LE32(i->block[j]));
+	diag_printf("  block: %d\n", SWAB_LE32(i->block[j]));
 }
 #endif
 
--- a/packages/redboot/current/src/fs/ide.c
+++ b/packages/redboot/current/src/fs/ide.c
@@ -139,14 +139,14 @@ ide_read_sectors(int ctlr, int dev, cyg_
 
     for(p = buf, i = 0; i < count; i++) {
 
-	if (!__wait_for_drq(ctlr)) {
-	    printf("%s: NO DRQ for ide%d, device %d.\n",
-		   __FUNCTION__, ctlr, dev);
-	    return 0;
-	}
+        if (!__wait_for_drq(ctlr)) {
+            diag_printf("%s: NO DRQ for ide%d, device %d.\n",
+                        __FUNCTION__, ctlr, dev);
+            return 0;
+        }
 
-	for (j = 0; j < (SECTOR_SIZE / sizeof(cyg_uint16)); j++, p++)
-	    HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *p);
+        for (j = 0; j < (SECTOR_SIZE / sizeof(cyg_uint16)); j++, p++)
+            HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *p);
     }
     return 1;
 }
--- a/packages/redboot/current/src/io.c
+++ b/packages/redboot/current/src/io.c
@@ -82,7 +82,7 @@ do_channel(int argc, char *argv[])
         {
             unsigned long chan;
             if ( !parse_num( argv[1], &chan, NULL, NULL) ) {
-                printf("** Error: invalid channel '%s'\n", argv[1]);
+                diag_printf("** Error: invalid channel '%s'\n", argv[1]);
             } else {
                 if (chan < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) {
                     CYGACC_CALL_IF_SET_CONSOLE_COMM(chan);
@@ -91,20 +91,20 @@ do_channel(int argc, char *argv[])
                         console_echo = true;
                 }
                 else {
-                    printf("**Error: bad channel number '%s'\n", argv[1]);
+                    diag_printf("**Error: bad channel number '%s'\n", argv[1]);
                 }
             }
         }
     }
     /* else display */ 
     else {
-        printf("Current console channel id: ");
+        diag_printf("Current console channel id: ");
 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
         if (!console_selected)
-            printf("-1\n");
+            diag_printf("-1\n");
         else
 #endif
-            printf("%d\n", cur);
+            diag_printf("%d\n", cur);
     }
 }
 
@@ -283,7 +283,7 @@ getc_script(char *cp)
 //   -2: ^C typed
 //
 int
-gets(char *buf, int buflen, int timeout)
+_rb_gets(char *buf, int buflen, int timeout)
 {
     char *ptr = buf;
     char c;
@@ -318,7 +318,7 @@ gets(char *buf, int buflen, int timeout)
         switch (c) {
         case 0x03: // ^C
             if (ptr == buf) {
-                printf("^C\n");
+                diag_printf("^C\n");
                 return _GETS_CTRLC;
             }
             *ptr++ = c;
@@ -349,7 +349,6 @@ gets(char *buf, int buflen, int timeout)
                 ptr--;
             }
             break;
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
         case '\\':                 // escape character
             if (console_echo) {
                 mon_write_char(c);
@@ -359,6 +358,7 @@ gets(char *buf, int buflen, int timeout)
             *ptr++ = c;
             c = '\0';    // cheat so that the "shift" state resets
             break;
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
         case '+': // fall through
         case '$':
             if (ptr == buf || last_ch != '\\')
@@ -381,59 +381,6 @@ gets(char *buf, int buflen, int timeout)
     }
 }
 
-void
-vdump_buf_with_offset(_printf_fun *pf, void *_p, CYG_ADDRWORD s, void *_base)
-{
-    int i, c;
-    cyg_uint8 *p = (cyg_uint8 *)_p;
-    cyg_uint8 *base = (cyg_uint8 *)_base;
-
-    if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) {
-        s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p;
-    }
-    while ((int)s > 0) {
-        if (base) {
-            (*pf)("0x%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
-        } else {
-            (*pf)("0x%08X: ", (CYG_ADDRWORD)p);
-        }
-        for (i = 0;  i < 16;  i++) {
-            if (i < (int)s) {
-                (*pf)("%02X", p[i] & 0xFF);
-            } else {
-                (*pf)("  ");
-            }
-            if ((i % 2) == 1) (*pf)(" ");
-            if ((i % 8) == 7) (*pf)(" ");
-        }
-        (*pf)(" |");
-        for (i = 0;  i < 16;  i++) {
-            if (i < (int)s) {
-                c = p[i] & 0xFF;
-                if ((c < 0x20) || (c >= 0x7F)) c = '.';
-            } else {
-                c = ' ';
-            }
-            (*pf)("%c", c);
-        }
-        (*pf)("|\n");
-        s -= 16;
-        p += 16;
-    }
-}
-
-void
-dump_buf_with_offset(void *p, CYG_ADDRWORD s, void *base)
-{
-    vdump_buf_with_offset(printf, p, s, base);
-}
-
-void
-dump_buf(void *p, CYG_ADDRWORD s)
-{
-   dump_buf_with_offset((cyg_uint8 *)p, s, 0);
-}
-
 bool
 verify_action(char *fmt, ...)
 {
@@ -446,8 +393,8 @@ verify_action(char *fmt, ...)
 #endif
 
     va_start(ap, fmt);
-    vprintf(fmt, ap);
-    printf(" - are you sure (y/n)? ");
-    gets(ans, sizeof(ans), 0);
+    diag_vprintf(fmt, ap);
+    diag_printf(" - are you sure (y/n)? ");
+    _rb_gets(ans, sizeof(ans), 0);
     return ((ans[0] == 'y') || (ans[0] == 'Y'));
 }
--- a/packages/redboot/current/src/load.c
+++ b/packages/redboot/current/src/load.c
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas
+// Contributors: gthomas, tsmith
 // Date:         2000-07-14
 // Purpose:      
 // Description:  
@@ -49,6 +49,7 @@
 #include <fs/disk.h>
 #endif
 
+
 // Buffer used by redboot_getc
 getc_info_t getc_info;
 
@@ -72,7 +73,7 @@ RedBoot_cmd("load",
 static unsigned long
 load_elf_image(int (*getc)(void))
 {
-    printf("ELF images not supported\n");
+    diag_printf("ELF images not supported\n");
     return 0;
 }
 
@@ -114,7 +115,7 @@ static long
 //
 #define MAX_LINE 80
 static unsigned long
-load_srec_image(int (*getc)(void), unsigned long base)
+load_srec_image(int (*getc)(void), void (*terminate)(int method,int (*getc)(void)), unsigned long base)
 {
     char line[MAX_LINE];
     char *lp;
@@ -131,7 +132,8 @@ load_srec_image(int (*getc)(void), unsig
         lp = line;  len = 0;
         // Start of line
         if (c != 'S') {
-            printf("Invalid S-record at offset %p, input: %c\n", 
+	    if (terminate) (*terminate)(xyzModem_abort, getc);
+            diag_printf("Invalid S-record at offset %p, input: %c\n", 
                    (void *)offset, c);
             return 0;
         }
@@ -139,7 +141,8 @@ load_srec_image(int (*getc)(void), unsig
         offset += 2;
         sum = 0;
         if ((count = _hex2(getc, 1, &sum)) < 0) {
-            printf("Bad S-record count at offset %p\n", (void *)offset);
+	    if (terminate) (*terminate)(xyzModem_abort, getc);
+            diag_printf("Bad S-record count at offset %p\n", (void *)offset);
             return 0;
         }
         offset += 1;
@@ -154,7 +157,6 @@ load_srec_image(int (*getc)(void), unsig
             if (first_addr) {
                 if (base) {
                     addr_offset = (unsigned long)base - (unsigned long)addr;
-                    printf("Address offset = %p\n", (void *)addr_offset);
                 } else {
                     addr_offset = 0;                    
                 }
@@ -166,9 +168,16 @@ load_srec_image(int (*getc)(void), unsig
             }
 #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS
             if ((addr < user_ram_start) || (addr > user_ram_end)) {
+	      // Only if there is no need to stop the download before printing
+	      // output can we ask confirmation questions.
+	      if (terminate) {
+		(*terminate)(xyzModem_abort, getc);
+		diag_printf("*** Warning! Attempt to load S-record to address: %p\nRedBoot does not believe this is in RAM\nUse TFTP for a chance to override this.\n",(void*)addr);
+	      } else {
                 if (!verify_action("Attempt to load S-record data to address: %p\n"
                                    "RedBoot does not believe this is in RAM", (void*)addr))
                     return 0;
+	      }
             }
 #endif
             count -= ((type-'1'+2)+1);
@@ -182,7 +191,8 @@ load_srec_image(int (*getc)(void), unsig
             sum = sum & 0xFF;
             cksum = (~cksum & 0xFF);
             if (cksum != sum) {
-                printf("*** Warning! Checksum failure - Addr: %lx, %02lX <> %02lX\n", 
+		if (terminate) (*terminate)(xyzModem_abort, getc);
+                diag_printf("*** Warning! Checksum failure - Addr: %lx, %02lX <> %02lX\n", 
                        (unsigned long)base_addr, sum, cksum);
                 return 0;
             }
@@ -196,12 +206,14 @@ load_srec_image(int (*getc)(void), unsig
             addr = (unsigned char *)_hex2(getc, ('9'-type+2), &sum);
             offset += ('9'-type+2);
             entry_address = (unsigned long *)addr;
-            printf("Entry point: %p, address range: %p-%p\n", 
+	    if (terminate) (*terminate)(xyzModem_close, getc);
+            if (addr_offset) diag_printf("Address offset = %p\n", (void *)addr_offset);
+            diag_printf("Entry point: %p, address range: %p-%p\n", 
                    (void*)entry_address, (void *)lowest_address, (void *)highest_address);
-            while ((c = (*getc)()) > 0) ;  // Swallow rest of data
             return highest_address;
         default:
-            printf("Invalid S-record at offset 0x%lx, type: %x\n", 
+	    if (terminate) (*terminate)(xyzModem_abort, getc);
+            diag_printf("Invalid S-record at offset 0x%lx, type: %x\n", 
                    (unsigned long)offset, type);
             return 0;
         }
@@ -220,20 +232,20 @@ redboot_getc(void)
     }
     if (getc_info.avail == 0) {
         if (getc_info.verbose) {
-            printf("%c\b", spin[getc_info.tick++]);
+            diag_printf("%c\b", spin[getc_info.tick++]);
             if (getc_info.tick >= sizeof(spin)) {
                 getc_info.tick = 0;
             }
         }
         if (getc_info.len < BUF_SIZE) {
             // No more data available
-            if (getc_info.verbose) printf("\n");
+            if (getc_info.verbose) diag_printf("\n");
             return -1;
         }
         getc_info.bufp = getc_info.buf;
         getc_info.len = (*getc_info.fun)(getc_info.bufp, BUF_SIZE, &getc_info.err);
         if ((getc_info.avail = getc_info.len) <= 0) {
-            if (getc_info.verbose) printf("\n");
+            if (getc_info.verbose) diag_printf("\n");
             return -1;
         }
     }
@@ -326,14 +338,14 @@ do_load(int argc, char *argv[])
 #ifdef CYGPKG_REDBOOT_NETWORKING
     if (hostname_set) {
         if (!inet_aton(hostname, (in_addr_t *)&host)) {
-            printf("Invalid IP address: %s\n", hostname);
+            diag_printf("Invalid IP address: %s\n", hostname);
             return;
         }
     }
 #endif
     if (mode_str_set) {
-        if (strncmpci(&mode_str[1], "modem", strlen(&mode_str[1])) == 0) {
-            switch (tolower(mode_str[0])) {
+        if (strncasecmp(&mode_str[1], "modem", strlen(&mode_str[1])) == 0) {
+            switch (_tolower(mode_str[0])) {
             case 'x':
                 mode = MODE_XMODEM;
                 break;
@@ -344,33 +356,33 @@ do_load(int argc, char *argv[])
                 mode = MODE_ZMODEM;
                 break;
             default:
-                printf("Invalid 'mode': %s\n", mode_str);
+                diag_printf("Invalid 'mode': %s\n", mode_str);
                 return;
             }
             // When using a serial download type, override verbose
             // setting: spinner interferes with the protocol.
             verbose = false;
 #ifdef CYGPKG_REDBOOT_DISK
-	} else if (strcmpci(mode_str, "disk") == 0) {
+	} else if (strcasecmp(mode_str, "disk") == 0) {
             mode = MODE_DISK;
 #endif
 #ifdef CYGPKG_REDBOOT_NETWORKING
-        } else if (strcmpci(mode_str, "tftp") == 0) {
+        } else if (strcasecmp(mode_str, "tftp") == 0) {
             mode = MODE_TFTP;
             if (!have_net) {
-                printf("TFTP mode requires a working network\n");
+                diag_printf("TFTP mode requires a working network\n");
                 return;
             }
 #endif
         } else {
-            printf("Invalid 'mode': %s\n", mode_str);
+            diag_printf("Invalid 'mode': %s\n", mode_str);
             return;
         }
     }
 #if defined(CYGPKG_REDBOOT_NETWORKING) || defined(CYGPKG_REDBOOT_DISK)
     if ((mode == MODE_TFTP || mode == MODE_DISK) && !filename) {
-        printf("File name missing\n");
-        printf("usage: load %s\n", usage);
+        diag_printf("File name missing\n");
+        diag_printf("usage: load %s\n", usage);
         return;
     }
 #endif
@@ -383,14 +395,14 @@ do_load(int argc, char *argv[])
     }
 #endif
     if (raw && !base_addr_set) {
-        printf("Raw load requires a memory address\n");
+        diag_printf("Raw load requires a memory address\n");
         return;
     }
 #ifdef CYGPKG_REDBOOT_NETWORKING
     if (mode == MODE_TFTP) {
         res = tftp_stream_open(filename, &host, TFTP_OCTET, &err);    
         if (res < 0) {
-            printf("Can't load '%s': %s\n", filename, tftp_error(err));
+            diag_printf("Can't load '%s': %s\n", filename, tftp_error(err));
             return;
         }
         redboot_getc_init(tftp_stream_read, verbose);
@@ -400,7 +412,7 @@ do_load(int argc, char *argv[])
     else if (mode == MODE_DISK) {
         res = disk_stream_open(filename, &err);
         if (res < 0) {
-            printf("Can't load '%s': %s\n", filename, disk_error(err));
+            diag_printf("Can't load '%s': %s\n", filename, disk_error(err));
             return;
         }
         redboot_getc_init(disk_stream_read, verbose);
@@ -409,7 +421,7 @@ do_load(int argc, char *argv[])
     else {
         res = xyzModem_stream_open(filename, mode, &err);
         if (res < 0) {
-            printf("Can't load '%s': %s\n", filename, xyzModem_error(err));
+            diag_printf("Can't load '%s': %s\n", filename, xyzModem_error(err));
             return;
         }
         // Suppress verbosity when using xyz modem download
@@ -445,7 +457,7 @@ do_load(int argc, char *argv[])
             err = (*_dc_close)(p, err);
 
             if (0 != err && p->msg) {
-                printf("decompression error: %s\n", p->msg);
+                diag_printf("decompression error: %s\n", p->msg);
             }
 
             end = (unsigned long) base + p->out_size;
@@ -460,7 +472,7 @@ do_load(int argc, char *argv[])
             end = (unsigned long) mp;
         }
         if (0 == err)
-            printf("Raw file loaded %p-%p\n", (void *)base, (void *)end);
+            diag_printf("Raw file loaded %p-%p\n", (void *)base, (void *)end);
     } else {
         // Read initial header - to determine file [image] type
         for (i = 0;  i < sizeof(type);  i++) {
@@ -477,9 +489,18 @@ do_load(int argc, char *argv[])
                 end = load_elf_image(redboot_getc);
             } else if ((type[0] == 'S') &&
                        ((type[1] >= '0') && (type[1] <= '9'))) {
-                end = load_srec_image(redboot_getc, base);
+		switch (mode) {
+		  case MODE_XMODEM:
+		  case MODE_YMODEM:
+		  case MODE_ZMODEM:
+                    end = load_srec_image(redboot_getc, xyzModem_stream_terminate, base);
+		    break;
+		  default:
+                    end = load_srec_image(redboot_getc, NULL, base);
+		    break;
+		}
             } else {
-                printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type);
+                diag_printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type);
             }
         }
     }
--- a/packages/redboot/current/src/main.c
+++ b/packages/redboot/current/src/main.c
@@ -144,14 +144,14 @@ do_version(int argc, char *argv[])
     externC void _flash_info(void);
 #endif
 
-    printf(RedBoot_version);
+    diag_printf(RedBoot_version);
 #ifdef HAL_PLATFORM_CPU
-    printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
+    diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
 #endif
-    printf("Copyright (C) 2000, 2001, Red Hat, Inc.\n\n");
-    printf("RAM: %p-%p, %p-%p available\n", 
-           (void*)ram_start, (void*)ram_end,
-           (void*)user_ram_start, (void *)user_ram_end);
+    diag_printf("Copyright (C) 2000, 2001, Red Hat, Inc.\n\n");
+    diag_printf("RAM: %p-%p, %p-%p available\n", 
+                (void*)ram_start, (void*)ram_end,
+                (void*)user_ram_start, (void *)user_ram_end);
 #ifdef CYGPKG_IO_FLASH
     _flash_info();
 #endif
@@ -168,6 +168,13 @@ do_idle(bool is_idle)
     }
 }
 
+// Wrapper used by diag_printf()
+static void
+_mon_write_char(char c, void **param)
+{
+    mon_write_char(c);
+}
+
 //
 // This is the main entry point for RedBoot
 //
@@ -182,6 +189,7 @@ cyg_start(void)
     struct init_tab_entry *init_entry;
 
     // Make sure the channels are properly initialized.
+    diag_init_putc(_mon_write_char);
     hal_if_diag_init();
 
     // Force console to output raw text - but remember the old setting
@@ -248,15 +256,15 @@ cyg_start(void)
         // Give the guy a chance to abort any boot script
         unsigned char *hold_script = script;
         int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
-        printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
-               script_timeout_ms/1000, script_timeout_ms%1000);
+        diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
+                    script_timeout_ms/1000, script_timeout_ms%1000);
         script = (unsigned char *)0;
         res = _GETS_CTRLC;  // Treat 0 timeout as ^C
         while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
-            res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
+            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
             if (res >= _GETS_OK) {
-                printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
-                       script_timeout_ms/1000, script_timeout_ms%1000);
+                diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
+                            script_timeout_ms/1000, script_timeout_ms%1000);
                 continue;  // Ignore anything but ^C
             }
             if (res != _GETS_TIMEOUT) break;
@@ -272,10 +280,10 @@ cyg_start(void)
 
     while (true) {
         if (prompt) {
-            printf("RedBoot> ");
+            diag_printf("RedBoot> ");
             prompt = false;
         }
-        res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
+        res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
         if (res == _GETS_TIMEOUT) {
             // No input arrived
         } else {
@@ -311,7 +319,7 @@ cyg_start(void)
                     if ((cmd = parse(line, &argc, &argv[0])) != (struct cmd *)0) {
                         (cmd->fun)(argc, argv);
                     } else {
-                        printf("** Error: Illegal command: \"%s\"\n", argv[0]);
+                        diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
                     }
                 }
                 prompt = true;
@@ -327,12 +335,12 @@ do_caches(int argc, char *argv[])
     int dcache_on=0, icache_on=0;
 
     if (argc == 2) {
-        if (strcmpci(argv[1], "on") == 0) {
+        if (strcasecmp(argv[1], "on") == 0) {
             HAL_DISABLE_INTERRUPTS(oldints);
             HAL_ICACHE_ENABLE();
             HAL_DCACHE_ENABLE();
             HAL_RESTORE_INTERRUPTS(oldints);
-        } else if (strcmpci(argv[1], "off") == 0) {
+        } else if (strcasecmp(argv[1], "off") == 0) {
             HAL_DISABLE_INTERRUPTS(oldints);
             HAL_DCACHE_SYNC();
             HAL_ICACHE_DISABLE();
@@ -342,7 +350,7 @@ do_caches(int argc, char *argv[])
             HAL_DCACHE_INVALIDATE_ALL();
             HAL_RESTORE_INTERRUPTS(oldints);
         } else {
-            printf("Invalid cache mode: %s\n", argv[1]);
+            diag_printf("Invalid cache mode: %s\n", argv[1]);
         }
     } else {
 #ifdef HAL_DCACHE_IS_ENABLED
@@ -351,7 +359,8 @@ do_caches(int argc, char *argv[])
 #ifdef HAL_ICACHE_IS_ENABLED
         HAL_ICACHE_IS_ENABLED(icache_on);
 #endif
-        printf("Data cache: %s, Instruction cache: %s\n", dcache_on?"On":"Off", icache_on?"On":"Off");
+        diag_printf("Data cache: %s, Instruction cache: %s\n", 
+                    dcache_on?"On":"Off", icache_on?"On":"Off");
     }
 }
 
@@ -365,7 +374,7 @@ do_help(int argc, char *argv[])
     int len = 0;
 
     if (!scan_opts(argc, argv, 1, 0, 0, (void **)&which, OPTION_ARG_TYPE_STR, "<topic>")) {
-        printf("Invalid argument\n");
+        diag_printf("Invalid argument\n");
         return;
     }
     if (which) {
@@ -374,11 +383,11 @@ do_help(int argc, char *argv[])
     cmd = __RedBoot_CMD_TAB__;
     while (cmd != &__RedBoot_CMD_TAB_END__) {
         show = true;
-        if (which && (strncmpci(which, cmd->str, len) != 0)) {
+        if (which && (strncasecmp(which, cmd->str, len) != 0)) {
             show = false;
         }
         if (show) {
-            printf("%s\n   %s %s\n", cmd->help, cmd->str, cmd->usage);
+            diag_printf("%s\n   %s %s\n", cmd->help, cmd->str, cmd->usage);
         }
         cmd++;
     }
@@ -402,7 +411,7 @@ do_dump(int argc, char *argv[])
     }
     if (!base_set) {
         if (_base == 0) {
-            printf("Dump what [location]?\n");
+            diag_printf("Dump what [location]?\n");
             return;
         }
         base = _base;
@@ -414,7 +423,7 @@ do_dump(int argc, char *argv[])
     if (!len_set) {
         len = 32;
     }
-    dump_buf((void *)base, len);
+    diag_dump_buf((void *)base, len);
     _base = base + len;
     _len = len;
 }
@@ -438,11 +447,11 @@ do_cksum(int argc, char *argv[])
         return;
     }
     if (!base_set || !len_set) {
-        printf("usage: cksum -b <addr> -l <length>\n");
+        diag_printf("usage: cksum -b <addr> -l <length>\n");
         return;
     }
     crc = posix_crc32((unsigned char *)base, len);
-    printf("POSIX cksum = 0x%08lx (%lu)\n", crc, crc);
+    diag_printf("POSIX cksum = 0x%08lx (%lu)\n", crc, crc);
 }
 
 void
@@ -470,10 +479,10 @@ do_go(int argc, char *argv[])
         unsigned char *hold_script = script;
         script = (unsigned char *)0;
 #endif
-        printf("About to start execution at %p - abort with ^C within %d seconds\n",
-               (void *)entry, wait_time);
+        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
+                    (void *)entry, wait_time);
         while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
-            res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
+            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
             if (res == _GETS_CTRLC) {
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
                 script = hold_script;  // Re-enable script
@@ -502,11 +511,11 @@ do_go(int argc, char *argv[])
 void
 do_reset(int argc, char *argv[])
 {
-    printf("... Resetting.");
+    diag_printf("... Resetting.");
     CYGACC_CALL_IF_DELAY_US(2*100000);
-    printf("\n");
+    diag_printf("\n");
     CYGACC_CALL_IF_RESET();
-    printf("!! oops, RESET not working on this platform\n");
+    diag_printf("!! oops, RESET not working on this platform\n");
 }
 #endif
 
@@ -526,7 +535,7 @@ set_console_baud_rate(int rate)
         __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
         ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SETBAUD, rate);
         if (ret <= 0) {
-            printf("Failed\n");
+            diag_printf("Failed\n");
         }
         current_rate = rate;
     }
@@ -561,11 +570,11 @@ do_baud_rate(int argc, char *argv[])
         set_console_baud_rate(new_rate);
     } else {
         ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
-        printf("Baud rate = ");
+        diag_printf("Baud rate = ");
         if (ret <= 0) {
-            printf("unknown\n");
+            diag_printf("unknown\n");
         } else {
-            printf("%d\n", ret);
+            diag_printf("%d\n", ret);
         }
     }
 }
--- a/packages/redboot/current/src/misc_funs.c
+++ b/packages/redboot/current/src/misc_funs.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -46,109 +46,27 @@
 #include <redboot.h>
 
 int
-strlen(const char *s)
-{
-    int len = 0;
-    if (s)
-        while (*s++) len++;
-    return len;
-}
-
-int
-strcmp(const char *s1, const char *s2)
+strcasecmp(const char *s1, const char *s2)
 {
     char c1, c2;
-
-    while ((c1 = *s1++) == (c2 = *s2++))
-        if (c1 == 0)
-            return (0);
-    return ((unsigned char)c1 - (unsigned char)c2);
-}
-
-char *
-strncpy(char *s1, const char *s2, unsigned long n)
-{
-    char c;
-    char *_s1 = s1;
-
-    if (n) {
-        n--;                            // leave space for terminator
-        while (n != 0 && (c = *s2++) != '\0') {
-            *s1++ = c;
-            n--;
-        }
-        *s1 = '\0';
-        while (n != 0) {                // fill remainder with zero
-            *s1++ = 0;
-            n--;
-        }
-    }
-    return _s1;
-}
-
-char *
-strcpy(char *s1, const char *s2)
-{
-    char c;
-    char *_s1 = s1;
-
-    while ((c = *s2++) != '\0')
-        *s1++ = c;
-    *s1 = '\0';
-    return _s1;
-}
-
-int
-strcmpci(const char *s1, const char *s2)
-{
-    char c1, c2;
-    while ((c1 = tolower(*s1++)) == (c2 = tolower(*s2++)))
+    while ((c1 = _tolower(*s1++)) == (c2 = _tolower(*s2++)))
         if (c1 == 0)
             return (0);
     return ((unsigned char)c1 - (unsigned char)c2);
 }
 
 int
-strncmp(const char *s1, const char *s2, int len)
+strncasecmp(const char *s1, const char *s2, size_t len)
 {
     char c1, c2;
 
     if (len == 0)
         return 0;
     do {
-        if ((c1 = *s1++) != (c2 = *s2++))
+        if ((c1 = _tolower(*s1++)) != (c2 = _tolower(*s2++)))
             return ((unsigned char)c1 - (unsigned char)c2);
         if (c1 == 0)
             break;
     } while (--len != 0);
     return 0;
 }
-
-int
-strncmpci(const char *s1, const char *s2, int len)
-{
-    char c1, c2;
-
-    if (len == 0)
-        return 0;
-    do {
-        if ((c1 = tolower(*s1++)) != (c2 = tolower(*s2++)))
-            return ((unsigned char)c1 - (unsigned char)c2);
-        if (c1 == 0)
-            break;
-    } while (--len != 0);
-    return 0;
-}
-
-int
-memcmp(const void *_dst, const void *_src, size_t len)
-{
-    unsigned char *dst = (unsigned char *)_dst;
-    unsigned char *src = (unsigned char *)_src;
-    while (len-- > 0) {
-        if (*dst++ != *src++) {
-            return (*--dst - *--src);
-        }
-    }
-    return 0;
-}
--- a/packages/redboot/current/src/net/enet.c
+++ b/packages/redboot/current/src/net/enet.c
@@ -95,7 +95,7 @@ pkt_handler_t
 	    return (pkt_handler_t)0;
 	}
     }
-    printf("** Warning: can't install listener for ethernet type 0x%02x\n", eth_type);
+    diag_printf("** Warning: can't install listener for ethernet type 0x%02x\n", eth_type);
     return (pkt_handler_t)0;
 }
 
@@ -131,7 +131,7 @@ void
         if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) {
             if (!was_exhausted) {
                 int old = start_console();  // Force output to standard port
-                printf("__enet_poll: no more buffers\n");
+                diag_printf("__enet_poll: no more buffers\n");
                 __pktbuf_dump();
                 was_exhausted = true;
                 end_console(old);
--- a/packages/redboot/current/src/net/inet_addr.c
+++ b/packages/redboot/current/src/net/inet_addr.c
@@ -60,7 +60,7 @@ inet_aton(char *s, in_addr_t *addr)
         val = 0;
         radix = 10;
         while ((c = *s++) != '\0') {
-            if (first && (c == '0') && (tolower(*s) == 'x')) {
+            if (first && (c == '0') && (_tolower(*s) == 'x')) {
                 radix = 16;
                 s++;  // Skip over 0x
                 c = *s++;
@@ -94,6 +94,6 @@ inet_ntoa(in_addr_t *addr)
     unsigned char *ap;
 
     ap = (unsigned char *)addr;
-    sprintf(str, "%d.%d.%d.%d", ap[0], ap[1], ap[2], ap[3]);
+    diag_sprintf(str, "%d.%d.%d.%d", ap[0], ap[1], ap[2], ap[3]);
     return str;
 }
--- a/packages/redboot/current/src/net/net_io.c
+++ b/packages/redboot/current/src/net/net_io.c
@@ -130,10 +130,10 @@ static cyg_bool
         __tcp_poll();
         if (tcp_sock.state == _CLOSE_WAIT) {
             // This connection is breaking
-            if (tcp_sock.data_bytes == 0) {
+            if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) {
                 __tcp_close(&tcp_sock);
+                return false;
             }
-            return false;
         }
         if (tcp_sock.state == _CLOSED) {
             // The connection is gone
@@ -147,8 +147,8 @@ static cyg_bool
         if (show_tcp && (in_buflen > 0)) {
             int old_console;
             old_console = start_console();  
-            printf("%s:%d\n", __FUNCTION__, __LINE__);  
-            dump_buf(in_buf, in_buflen);  
+            diag_printf("%s:%d\n", __FUNCTION__, __LINE__);  
+            diag_dump_buf(in_buf, in_buflen);  
             end_console(old_console);
         }
 #endif // DEBUG_TCP
@@ -231,7 +231,9 @@ net_io_flush(void)
     while (out_buflen) {
         if (tcp_sock.state == _CLOSE_WAIT) {
             // This connection is tring to close
-            __tcp_close(&tcp_sock);
+            // This connection is breaking
+            if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0)
+                __tcp_close(&tcp_sock);
         }
         if (tcp_sock.state == _CLOSED) {
             // The connection is gone!
@@ -242,8 +244,8 @@ net_io_flush(void)
         if (show_tcp) {
             int old_console;
             old_console = start_console();  
-            printf("%s.%d\n", __FUNCTION__, __LINE__);
-            dump_buf(out_buf, out_buflen);  
+            diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
+            diag_dump_buf(out_buf, out_buflen);  
             end_console(old_console);
         }
 #endif // SHOW_TCP
@@ -290,7 +292,7 @@ net_io_write(void* __ch_data, const cyg_
     int old_console;
 
     old_console = start_console();
-    printf("%s.%d\n", __FUNCTION__, __LINE__);
+    diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
     end_console(old_console);
 #if 0
     CYGARC_HAL_SAVE_GP();
@@ -308,7 +310,7 @@ net_io_read(void* __ch_data, cyg_uint8* 
     int old_console;
 
     old_console = start_console();
-    printf("%s.%d\n", __FUNCTION__, __LINE__);
+    diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
     end_console(old_console);
 #if 0
     CYGARC_HAL_SAVE_GP();
@@ -380,11 +382,11 @@ net_io_control(void *__ch_data, __comm_c
         _timeout = va_arg(ap, cyg_uint32);
 
         va_end(ap);
-	break;
+        break;
     }
     case __COMMCTL_FLUSH_OUTPUT:
         net_io_flush();
-	break;
+        break;
     default:
         break;
     }
@@ -485,7 +487,7 @@ net_io_init(void)
     __tcp_listen(&tcp_sock, gdb_port);
     state = tcp_sock.state; 
 #ifdef DEBUG_TCP
-    printf("show tcp = %p\n", (void *)&show_tcp);
+    diag_printf("show tcp = %p\n", (void *)&show_tcp);
 #endif
 }
 
@@ -546,7 +548,7 @@ net_init(void)
     if (!use_bootp)
     {
         ip_addr_t bootp_my_ip;
-        char i;
+        int i;
         flash_get_config("bootp_my_ip", &bootp_my_ip, CONFIG_IP);
         if (bootp_my_ip[0] != 0 || bootp_my_ip[1] != 0 ||
             bootp_my_ip[2] != 0 || bootp_my_ip[3] != 0) {
@@ -572,7 +574,7 @@ net_init(void)
         }
     }
     if (!__local_enet_sc) {
-        printf("No network interfaces found\n");
+        diag_printf("No network interfaces found\n");
         return;
     }    
     // Initialize the network [if present]
@@ -583,9 +585,9 @@ net_init(void)
             // Is it an unset address, or has it been set to a static addr
             if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
                 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
-                printf("Can't get BOOTP info - network disabled!\n");
+                diag_printf("Can't get BOOTP info - network disabled!\n");
             } else {
-                printf("Can't get BOOTP info, using default IP address\n");
+                diag_printf("Can't get BOOTP info, using default IP address\n");
                 have_net = true;
             }
         }
@@ -593,17 +595,17 @@ net_init(void)
         have_net = true;  // Assume values in FLASH were OK
     }
     if (have_net) {
-        printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
-               __local_enet_sc->dev_name,
-               __local_enet_addr[0],
-               __local_enet_addr[1],
-               __local_enet_addr[2],
-               __local_enet_addr[3],
-               __local_enet_addr[4],
-               __local_enet_addr[5]);
+        diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
+                    __local_enet_sc->dev_name,
+                    __local_enet_addr[0],
+                    __local_enet_addr[1],
+                    __local_enet_addr[2],
+                    __local_enet_addr[3],
+                    __local_enet_addr[4],
+                    __local_enet_addr[5]);
 
-        printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr));
-        printf(", Default server: %s\n", inet_ntoa(&my_bootp_info.bp_siaddr));
+        diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr));
+        diag_printf(", Default server: %s\n", inet_ntoa(&my_bootp_info.bp_siaddr));
         net_io_init();
     }
 }
--- a/packages/redboot/current/src/net/ping.c
+++ b/packages/redboot/current/src/net/ping.c
@@ -102,14 +102,14 @@ do_ping(int argc, char *argv[])
     init_opts(&opts[6], 'r', true, OPTION_ARG_TYPE_NUM, 
               (void **)&rate, (bool *)&rate_set, "<rate> - time between packets");
     if (!scan_opts(argc, argv, 1, opts, 7, (void **)0, 0, "")) {
-        printf("PING - Invalid option specified\n");
+        diag_printf("PING - Invalid option specified\n");
         return;
     }   
     // Set defaults; this has to be done _after_ the scan, since it will
     // have destroyed all values not explicitly set.
     if (local_ip_addr_set) {
         if (!inet_aton(local_ip_addr, (in_addr_t *)&local_addr)) {
-            printf("PING - Invalid IP address: %s\n", local_ip_addr);
+            diag_printf("PING - Invalid IP address: %s\n", local_ip_addr);
             return;
         }
     } else {
@@ -117,15 +117,15 @@ do_ping(int argc, char *argv[])
     }
     if (host_ip_addr_set) {
         if (!inet_aton(host_ip_addr, (in_addr_t *)&host_addr)) {
-            printf("PING - Invalid IP address: %s\n", host_ip_addr);
+            diag_printf("PING - Invalid IP address: %s\n", host_ip_addr);
             return;
         }
         if (__arp_lookup((ip_addr_t *)&host_addr.sin_addr, &dest_ip) < 0) {
-            printf("PING: Can't find address of server '%s'\n", host_ip_addr);
+            diag_printf("PING: Can't find address of server '%s'\n", host_ip_addr);
             return;
         }
     } else {
-        printf("PING - host IP address required\n");
+        diag_printf("PING - host IP address required\n");
         return;
     }
 #define DEFAULT_LENGTH   64
@@ -139,7 +139,7 @@ do_ping(int argc, char *argv[])
         length = DEFAULT_LENGTH;
     }
     if ((length < 64) || (length > 1400)) {
-        printf("Invalid length specified: %ld\n", length);
+        diag_printf("Invalid length specified: %ld\n", length);
         return;
     }
     if (!count_set) {
@@ -149,10 +149,10 @@ do_ping(int argc, char *argv[])
         timeout = DEFAULT_TIMEOUT;
     }
     // Note: two prints here because 'inet_ntoa' returns a static pointer
-    printf("Network PING - from %s",
-           inet_ntoa((in_addr_t *)&local_addr));
-    printf(" to %s\n",
-           inet_ntoa((in_addr_t *)&host_addr));
+    diag_printf("Network PING - from %s",
+                inet_ntoa((in_addr_t *)&local_addr));
+    diag_printf(" to %s\n",
+                inet_ntoa((in_addr_t *)&host_addr));
     received = 0;    
     __icmp_install_listener(handle_icmp);
     for (tries = 0;  tries < count;  tries++) {
@@ -203,14 +203,14 @@ do_ping(int argc, char *argv[])
         if (icmp_received) {
             received++;
             if (verbose) {
-                printf(" seq: %ld, time: %ld (ticks)\n",
-                       ntohs(hold_hdr.seqnum), end_time-start_time);
+                diag_printf(" seq: %ld, time: %ld (ticks)\n",
+                            ntohs(hold_hdr.seqnum), end_time-start_time);
             }
         }
     }
     __icmp_remove_listener();
     // Report
-    printf("PING - received %ld of %ld expected\n", received, count);
+    diag_printf("PING - received %ld of %ld expected\n", received, count);
 }
 
 #endif //CYGPKG_REDBOOT_NETWORKING
--- a/packages/redboot/current/src/net/pktbuf.c
+++ b/packages/redboot/current/src/net/pktbuf.c
@@ -90,15 +90,15 @@ void
 {
     int i;
     for (i = 0; i < MAX_PKTBUF; i++) {
-        printf("Buf[%d]/%p: buf: %p, len: %d/%d, next: %p\n", 
-               i,
-               (void*)&pktbuf_list[i],
-               (void*)pktbuf_list[i].buf,
-               pktbuf_list[i].bufsize,
-               pktbuf_list[i].pkt_bytes,
-               (void*)pktbuf_list[i].next);
+        diag_printf("Buf[%d]/%p: buf: %p, len: %d/%d, next: %p\n", 
+                    i,
+                    (void*)&pktbuf_list[i],
+                    (void*)pktbuf_list[i].buf,
+                    pktbuf_list[i].bufsize,
+                    pktbuf_list[i].pkt_bytes,
+                    (void*)pktbuf_list[i].next);
     }
-    printf("Free list = %p\n", (void*)free_list);
+    diag_printf("Free list = %p\n", (void*)free_list);
 }
 
 /*
--- a/packages/redboot/current/src/net/udp.c
+++ b/packages/redboot/current/src/net/udp.c
@@ -193,7 +193,7 @@ int
     ip_route_t rt;
 
     if (__arp_lookup((ip_addr_t *)&server->sin_addr, &rt) < 0) {
-        printf("%s: Can't find address of server\n", __FUNCTION__);
+        diag_printf("%s: Can't find address of server\n", __FUNCTION__);
         return -1;
     } else {
 	__udp_send(data, len, &rt, ntohs(server->sin_port), ntohs(local->sin_port));
@@ -223,7 +223,7 @@ static void
         memcpy(&recvfrom_server->sin_addr, &src_route->ip_addr, sizeof(src_route->ip_addr));
         recvfrom_buf = (char *)0;  // Tell reader we got a packet
     } else {
-        printf("udp_recvfrom - dropped packet of %d bytes\n", len);
+        diag_printf("udp_recvfrom - dropped packet of %d bytes\n", len);
     }
 }
 
--- a/packages/redboot/current/src/parse.c
+++ b/packages/redboot/current/src/parse.c
@@ -76,7 +76,7 @@ parse(char *line, int *argc, char **argv
         if (indx < MAX_ARGV) {
             argv[indx++] = cp;
         } else {
-            printf("Too many arguments - stopped at: '%s'\n", cp);
+            diag_printf("Too many arguments - stopped at: '%s'\n", cp);
         }
         while (*cp) {
             if (*cp == ' ') {
@@ -97,7 +97,7 @@ parse(char *line, int *argc, char **argv
                     *pp++ = *cp++;
                 }
                 if (!*cp) {
-                    printf("Unbalanced string!\n");
+                    diag_printf("Unbalanced string!\n");
                 } else {
                     if (pp != cp) *pp = '\0';
                     *cp++ = '\0';
@@ -124,7 +124,7 @@ cmd_search(struct cmd *tab, struct cmd *
     cmd_len = strlen(arg);
     cmd = tab;
     while (cmd != tabend) {
-        if (strncmpci(arg, cmd->str, cmd_len) == 0) {
+        if (strncasecmp(arg, cmd->str, cmd_len) == 0) {
             if (strlen(cmd->str) > cmd_len) {
                 // Check for ambiguous commands here
                 // Note: If there are commands which are not length-unique
@@ -133,18 +133,19 @@ cmd_search(struct cmd *tab, struct cmd *
                 cmd2 = tab;
                 while (cmd2 != tabend) {
                     if ((cmd != cmd2) && 
-                        (strncmpci(arg, cmd2->str, cmd_len) == 0)) {
+                        (strncasecmp(arg, cmd2->str, cmd_len) == 0)) {
                         if (first) {
-                            printf("Ambiguous command '%s', choices are: %s", arg, cmd->str);
+                            diag_printf("Ambiguous command '%s', choices are: %s", 
+                                        arg, cmd->str);
                             first = false;
                         }
-                        printf(" %s", cmd2->str);
+                        diag_printf(" %s", cmd2->str);
                     }
                     cmd2++;
                 }
                 if (!first) {
                     // At least one ambiguity found - fail the lookup
-                    printf("\n");
+                    diag_printf("\n");
                     return (struct cmd *)0;
                 }
             }
@@ -159,8 +160,10 @@ void
 cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix)
 {
     struct cmd *cmd;
-    printf("Usage:\n"); for (cmd = tab;  cmd != tabend;  cmd++) {
-        printf("  %s%s %s\n", prefix, cmd->str, cmd->usage);
+
+    diag_printf("Usage:\n"); 
+    for (cmd = tab;  cmd != tabend;  cmd++) {
+        diag_printf("  %s%s %s\n", prefix, cmd->str, cmd->usage);
     }
 }
 
@@ -223,7 +226,7 @@ scan_opts(int argc, char *argv[], int fi
             for (j = 0;  j < num_opts;  j++, opt++) {
                 if (c == opt->flag) {
                     if (opt->arg_set && *opt->arg_set) {
-                        printf("** Error: %s already specified\n", opt->name);
+                        diag_printf("** Error: %s already specified\n", opt->name);
                         ret = false;
                     }
                     if (opt->takes_arg) {
@@ -236,7 +239,8 @@ scan_opts(int argc, char *argv[], int fi
                         switch (opt->arg_type) {
                         case OPTION_ARG_TYPE_NUM:
                             if (!parse_num(s, (unsigned long *)opt->arg, 0, 0)) {
-                                printf("** Error: invalid number '%s' for %s\n", s, opt->name);
+                                diag_printf("** Error: invalid number '%s' for %s\n", 
+                                            s, opt->name);
                                 ret = false;
                             }
                             break;
@@ -260,19 +264,20 @@ scan_opts(int argc, char *argv[], int fi
                 }
             }
             if (!flag_ok) {
-                printf("** Error: invalid flag '%c'\n", c);
+                diag_printf("** Error: invalid flag '%c'\n", c);
                 ret = false;
             }
         } else {
             if (def_arg) {
                 if (def_arg_set) {
-                    printf("** Error: %s already specified\n", def_descr);
+                    diag_printf("** Error: %s already specified\n", def_descr);
                     ret = false;
                 }
                 switch (def_arg_type) {
                 case OPTION_ARG_TYPE_NUM:
                     if (!parse_num(argv[i], (unsigned long *)def_arg, 0, 0)) {
-                        printf("** Error: invalid number '%s' for %s\n", argv[i], def_descr);
+                        diag_printf("** Error: invalid number '%s' for %s\n", 
+                                    argv[i], def_descr);
                         ret = false;
                     }
                     break;
@@ -282,7 +287,7 @@ scan_opts(int argc, char *argv[], int fi
                 }
                 def_arg_set = true;
             } else {
-                printf("** Error: no default/non-flag arguments supported\n");
+                diag_printf("** Error: no default/non-flag arguments supported\n");
                 ret = false;
             }
         }
@@ -304,7 +309,7 @@ parse_num(char *s, unsigned long *val, c
 
     while (*s == ' ') s++;
     while (*s) {
-        if (first && (s[0] == '0') && (tolower(s[1]) == 'x')) {
+        if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) {
             radix = 16;
             s += 2;
         }
deleted file mode 100644
--- a/packages/redboot/current/src/printf.c
+++ /dev/null
@@ -1,277 +0,0 @@
-//==========================================================================
-//
-//      printf.c
-//
-//      Stand-alone minimal printf support for RedBoot
-//
-//==========================================================================
-//####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, 2001 Red Hat, Inc.                             
-// All Rights Reserved.                                                     
-// -------------------------------------------                              
-//                                                                          
-//####COPYRIGHTEND####
-//==========================================================================
-//#####DESCRIPTIONBEGIN####
-//
-// Author(s):    gthomas
-// Contributors: gthomas
-// Date:         2000-07-14
-// Purpose:      
-// Description:  
-//              
-// This code is part of RedBoot (tm).
-//
-//####DESCRIPTIONEND####
-//
-//==========================================================================
-
-#include <stdarg.h>
-#include <limits.h>
-#include <redboot.h>
-
-static int
-_cvt(unsigned long val, char *buf, long radix, char *digits)
-{
-    char temp[80];
-    char *cp = temp;
-    int length = 0;
-    if (val == 0) {
-        /* Special case */
-        *cp++ = '0';
-    } else {
-        while (val) {
-            *cp++ = digits[val % radix];
-            val /= radix;
-        }
-    }
-    while (cp != temp) {
-        *buf++ = *--cp;
-        length++;
-    }
-    *buf = '\0';
-    return (length);
-}
-
-#define is_digit(c) ((c >= '0') && (c <= '9'))
-
-static int
-_vprintf(void (*putc)(char c), char *fmt0, va_list ap)
-{
-    char buf[32];
-    char c, sign, *cp=buf;
-    int left_prec, right_prec, zero_fill, pad, pad_on_right, islong;
-    long val;
-    int res = 0, length = 0;
-    while ((c = *fmt0++) != '\0') {
-        if (c == '%') {
-            c = *fmt0++;
-            left_prec = right_prec = pad_on_right = islong = 0;
-            if (c == '-') {
-                c = *fmt0++;
-                pad_on_right++;
-            }
-            if (c == '0') {
-                zero_fill = true;
-                c = *fmt0++;
-            } else {
-                zero_fill = false;
-            }
-            while (is_digit(c)) {
-                left_prec = (left_prec * 10) + (c - '0');
-                c = *fmt0++;
-            }
-            if (c == '.') {
-                c = *fmt0++;
-                zero_fill++;
-                while (is_digit(c)) {
-                    right_prec = (right_prec * 10) + (c - '0');
-                    c = *fmt0++;
-                }
-            } else {
-                right_prec = left_prec;
-            }
-            sign = '\0';
-            if (c == 'l') {
-                // 'long' qualifier
-                c = *fmt0++;
-		islong = 1;
-            }
-            switch (c) {
-            case 'p':  // Pointer
-		islong = 1;
-                (*putc)('0');
-                (*putc)('x');
-                zero_fill = true;
-                left_prec = sizeof(unsigned long)*2;
-            case 'd':
-            case 'u':
-            case 'x':
-            case 'X':
-	        if (islong)
-                  val = va_arg(ap, long);
-		else
-		  val = va_arg(ap, int);
-                switch (c) {
-                case 'd':
-                    if (val < 0) {
-                        sign = '-';
-                        val = -val;
-                    }
-                case 'u':
-                    length = _cvt(val, buf, 10, "0123456789");
-                    break;
-                case 'p':
-                case 'x':
-#if INT_MAX < LONG_MAX
-		    if (!islong)
-			val &= (1L << (sizeof(int) * 8)) - 1;
-#endif
-                    length = _cvt(val, buf, 16, "0123456789abcdef");
-                    break;
-                case 'X':
-#if INT_MAX < LONG_MAX
-		    if (!islong)
-			val &= (1L << (sizeof(int) * 8)) - 1;
-#endif
-                    length = _cvt(val, buf, 16, "0123456789ABCDEF");
-                    break;
-                }
-                cp = buf;
-                break;
-            case 's':
-                cp = va_arg(ap, char *);
-                length = strlen(cp);
-                break;
-            case 'c':
-                c = va_arg(ap, int /*char*/);
-                (*putc)(c);
-                res++;
-                continue;
-            default:
-                (*putc)('?');
-                res++;
-            }
-            pad = left_prec - length;
-            if (sign != '\0') {
-                pad--;
-            }
-            if (zero_fill) {
-                c = '0';
-                if (sign != '\0') {
-                    (*putc)(sign);
-                    res++;
-                    sign = '\0';
-                }
-            } else {
-                c = ' ';
-            }
-            if (!pad_on_right) {
-                while (pad-- > 0) {
-                    (*putc)(c);
-                    res++;
-                }
-            }
-            if (sign != '\0') {
-                (*putc)(sign);
-                res++;
-            }
-            while (length-- > 0) {
-                c = *cp++;
-                if (c == '\n') {
-                    (*putc)('\r');
-                    res++;
-                }
-                (*putc)(c);
-                res++;
-            }
-            if (pad_on_right) {
-                while (pad-- > 0) {
-                    (*putc)(' ');
-                    res++;
-                }
-            }
-        } else {
-            if (c == '\n') {
-                (*putc)('\r');
-                res++;
-            }
-            (*putc)(c);
-            res++;
-        }
-    }
-    return (res);
-}
-
-static char *_sprintf_ptr;
-
-static void 
-_sputc(char c)
-{
-   *_sprintf_ptr++ = c;
-   *_sprintf_ptr = '\0';
-}
-
-int
-sprintf(char *buf, char *fmt, ...)
-{
-    int ret;
-    va_list ap;
-
-    va_start(ap, fmt);
-    _sprintf_ptr = buf;
-    ret = _vprintf(_sputc, fmt, ap);
-    va_end(ap);
-    return (ret);
-}
-
-int 
-vsprintf(char *buf, char *fmt, va_list ap)
-{
-    int ret;
-
-    _sprintf_ptr = buf;
-    ret = _vprintf(_sputc, fmt, ap);
-    return (ret);
-}
-
-extern void mon_write_char(char);
-
-int
-printf(char *fmt, ...)
-{
-    va_list ap;
-    int ret;
-
-    va_start(ap, fmt);
-    ret = _vprintf(mon_write_char, fmt, ap);
-    va_end(ap);
-    return (ret);
-}
-
-int
-vprintf(char *fmt, va_list ap)
-{
-    int ret;
-
-    ret = _vprintf(mon_write_char, fmt, ap);
-    return (ret);
-}
-
--- a/packages/redboot/current/src/syscall.c
+++ b/packages/redboot/current/src/syscall.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 2000 Red Hat, Inc.                             
+// Copyright (C) 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -41,35 +41,37 @@
 //=========================================================================*/
 
 #include <redboot.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
 
 #ifdef CYGSEM_REDBOOT_BSP_SYSCALLS
 
-#define	EIO 5		/* I/O error */
+#define EIO 5           /* I/O error */
 
 // These are required by the ANSI C part of newlib (excluding system() of
 // course).
-#define	SYS_exit	1
-#define	SYS_open	2
-#define	SYS_close	3
-#define	SYS_read	4
-#define	SYS_write	5
-#define	SYS_lseek	6
-#define	SYS_unlink	7
-#define	SYS_getpid	8
-#define	SYS_kill	9
+#define SYS_exit        1
+#define SYS_open        2
+#define SYS_close       3
+#define SYS_read        4
+#define SYS_write       5
+#define SYS_lseek       6
+#define SYS_unlink      7
+#define SYS_getpid      8
+#define SYS_kill        9
 #define SYS_fstat       10
-//#define SYS_sbrk	11 - not currently a system call, but reserved.
+//#define SYS_sbrk      11 - not currently a system call, but reserved.
 
 // ARGV support.
-#define SYS_argvlen	12
-#define SYS_argv	13
+#define SYS_argvlen     12
+#define SYS_argv        13
 
 // These are extras added for one reason or another.
-#define SYS_chdir	14
-#define SYS_stat	15
-#define SYS_chmod 	16
-#define SYS_utime 	17
-#define SYS_time 	18
+#define SYS_chdir       14
+#define SYS_stat        15
+#define SYS_chmod       16
+#define SYS_utime       17
+#define SYS_time        18
 
 #define SYS_interrupt   1000
 #define SYS_meminfo     1001
@@ -84,7 +86,7 @@
  * is made automatically from within the crt0.o file.
  */
 typedef struct {
-    int		version;	/* version number for future expansion */
+    int         version;        /* version number for future expansion */
     const void **__ictrl_table;
     void **__exc_table;
     void *__dbg_vector;
@@ -96,8 +98,8 @@ typedef struct {
     void *__cpu_data;
     void *__board_data;
     void *__sysinfo;
-    int	 (*__set_debug_comm)(int __comm_id);
-    int	 (*__set_console_comm)(int __comm_id);
+    int  (*__set_debug_comm)(int __comm_id);
+    int  (*__set_console_comm)(int __comm_id);
     int  (*__set_serial_baud)(int __comm_id, int baud);
     void *__dbg_data;
     void (*__reset)(void);
@@ -124,14 +126,59 @@ static inline void __putc(char c)
 {
     hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
     if (__chan)
-	CYGACC_COMM_IF_PUTC(*__chan, c);
+        CYGACC_COMM_IF_PUTC(*__chan, c);
     else {
-	__chan = CYGACC_CALL_IF_DEBUG_PROCS();
-	CYGACC_COMM_IF_PUTC(*__chan, c);
+        __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+        CYGACC_COMM_IF_PUTC(*__chan, c);
     }
 }
 
 
+// Timer support
+
+static cyg_handle_t  sys_timer_handle;
+static cyg_interrupt sys_timer_interrupt;
+static cyg_uint32    sys_timer_ticks;
+
+static void
+sys_timer_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    // do nothing
+}
+
+
+static cyg_uint32
+sys_timer_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+    ++sys_timer_ticks;
+
+    HAL_CLOCK_RESET(CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_HAL_RTC_PERIOD);
+
+    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_RTC);
+
+    return 0;
+}
+
+
+static void sys_timer_init(void)
+{
+    HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD);
+    
+    cyg_drv_interrupt_create(
+        CYGNUM_HAL_INTERRUPT_RTC,
+        0,                      // Priority - unused
+        (CYG_ADDRWORD)0,        // Data item passed to ISR & DSR
+        sys_timer_isr,          // ISR
+        sys_timer_dsr,          // DSR
+        &sys_timer_handle,      // handle to intr obj
+        &sys_timer_interrupt ); // space for int obj
+
+    cyg_drv_interrupt_attach(sys_timer_handle);
+
+    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);
+}
+
+
 //
 // read  -- read bytes from the serial port. Ignore fd, since
 //          we only have stdin.
@@ -141,11 +188,11 @@ sys_read(int fd, char *buf, int nbytes)
     int i = 0;
 
     for (i = 0; i < nbytes; i++) {
-	*(buf + i) = __getc();
-	if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
-	    (*(buf + i + 1)) = 0;
-	    break;
-	}
+        *(buf + i) = __getc();
+        if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
+            (*(buf + i + 1)) = 0;
+            break;
+        }
     }
     return (i);
 }
@@ -165,10 +212,10 @@ sys_write(int fd, char *buf, int nbytes)
     tosend = nbytes;
 
     while (tosend > 0) {
-	if (*buf == '\n')
-	    __putc('\r');
-	__putc(*buf++);
-	tosend--;
+        if (*buf == '\n')
+            __putc('\r');
+        __putc(*buf++);
+        tosend--;
     }
 
     return (nbytes);
@@ -205,24 +252,29 @@ sys_lseek(int fd,  int offset, int whenc
     return (-EIO);
 }
 
+#define NS_PER_TICK    (CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR)
+#define TICKS_PER_SEC  (1000000000L / NS_PER_TICK)
+
+// This needs to match newlib HZ which is normally 60.
+#define HZ 60
 
 static int
 sys_utime(unsigned long *p)
 {
-#ifdef HAVE_SYS_CLOCK
-    extern unsigned long __clock;
+    static int inited = 0;
+
+    if (!inited) {
+        inited = 1;
+        sys_timer_init();
+    }
 
     /* target clock runs at CLOCKS_PER_SEC. Convert to HZ */
     if (p)
-	*p = (__clock * HZ) / CLOCKS_PER_SEC;
-#else
-    if (p)
-	*p = 0;
-#endif
+        *p = (sys_timer_ticks * HZ) / TICKS_PER_SEC;
+
     return 0;
 }
 
-
 //
 //  Generic syscall handler.
 //
@@ -231,38 +283,38 @@ sys_utime(unsigned long *p)
 //  extend the syscall handler by using exception chaining.
 //
 CYG_ADDRWORD
-__do_syscall(CYG_ADDRWORD func,			// syscall function number
-	     CYG_ADDRWORD arg1, CYG_ADDRWORD arg2,	// up to four args.
-	     CYG_ADDRWORD arg3, CYG_ADDRWORD arg4,
-	     CYG_ADDRWORD *retval)		// syscall return value
+__do_syscall(CYG_ADDRWORD func,                 // syscall function number
+             CYG_ADDRWORD arg1, CYG_ADDRWORD arg2,      // up to four args.
+             CYG_ADDRWORD arg3, CYG_ADDRWORD arg4,
+             CYG_ADDRWORD *retval)              // syscall return value
 {
     int err = 0;
 
     switch (func) {
 
       case SYS_read:
-	err = sys_read((int)arg1, (char *)arg2, (int)arg3);
-	break;
+        err = sys_read((int)arg1, (char *)arg2, (int)arg3);
+        break;
 
       case SYS_write:
-	err = sys_write((int)arg1, (char *)arg2, (int)arg3);
-	break;
+        err = sys_write((int)arg1, (char *)arg2, (int)arg3);
+        break;
 
       case SYS_open:
-	err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
-	break;
+        err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
+        break;
 
       case SYS_close:
-	err = sys_close((int)arg1);
-	break;
+        err = sys_close((int)arg1);
+        break;
 
       case SYS_lseek:
-	err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
-	break;
+        err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
+        break;
 
       case SYS_utime:
-	err = sys_utime((unsigned long *)arg1);
-	break;
+        err = sys_utime((unsigned long *)arg1);
+        break;
 
       case SYS_meminfo:
         err = 1;
@@ -271,11 +323,11 @@ CYG_ADDRWORD
         break;
         
       case __GET_SHARED:
-	*(__shared_t **)arg1 = &__shared_data;
-	break;
+        *(__shared_t **)arg1 = &__shared_data;
+        break;
 
       default:
-	return 0;
+        return 0;
     }    
 
     *retval = err;
--- a/packages/redboot/current/src/xyzModem.c
+++ b/packages/redboot/current/src/xyzModem.c
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas
+// Contributors: gthomas, tsmith
 // Date:         2000-07-14
 // Purpose:      
 // Description:  
@@ -53,6 +53,7 @@
 #define STX 0x02
 #define EOT 0x04
 #define ACK 0x06
+#define BSP 0x08
 #define NAK 0x15
 #define CAN 0x18
 
@@ -88,7 +89,7 @@ zm_dprintf(char *fmt, ...)
     va_start(args, fmt);
     cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
     CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
-    vprintf(fmt, args);
+    diag_vprintf(fmt, args);
     CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console);
 }
 
@@ -111,7 +112,7 @@ zm_dprintf(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    len = vsprintf(zm_out, fmt, args);
+    len = diag_vsprintf(zm_out, fmt, args);
     zm_out += len;
     return len;
 }
@@ -300,7 +301,7 @@ xyzModem_stream_open(char *filename, int
     int retries = xyzModem_MAX_RETRIES;
     int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;
 
-    ZM_DEBUG(zm_out = zm_out_start);
+//    ZM_DEBUG(zm_out = zm_out_start);
     if (mode == xyzModem_zmodem) {
         *err = xyzModem_noZmodem;
         return -1;
@@ -385,9 +386,10 @@ xyzModem_stream_read(char *buf, int size
                     if (xyz.mode == xyzModem_ymodem) {
                         CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
                         xyz.total_retries++;
+                        ZM_DEBUG(zm_dprintf("Reading Final Header\n"));
                         stat = xyzModem_get_hdr();                        
                         CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
-                        ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__));
+                        ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__));
                     }
                     xyz.at_eof = true;
                     break;
@@ -417,13 +419,61 @@ xyzModem_stream_read(char *buf, int size
 void
 xyzModem_stream_close(int *err)
 {
-    printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", 
-           xyz.crc_mode ? "CRC" : "Cksum",
-           xyz.total_SOH, xyz.total_STX, xyz.total_CAN,
-           xyz.total_retries);
+    diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", 
+                xyz.crc_mode ? "CRC" : "Cksum",
+                xyz.total_SOH, xyz.total_STX, xyz.total_CAN,
+                xyz.total_retries);
 //    ZM_DEBUG(zm_flush());
 }
 
+// Need to be able to clean out the input buffer, so have to take the
+// getc
+void xyzModem_stream_terminate(int method, int (*getc)(void))
+{
+  int c;
+
+  switch (method) {
+    case xyzModem_abort:
+      ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n"));
+      switch (xyz.mode) {
+	case xyzModem_xmodem:
+	case xyzModem_ymodem:
+	  // The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal
+	  // number of Backspaces is a friendly way to get the other end to abort.
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+	  CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
+	  // Now consume the rest of what's waiting on the line.
+	  ZM_DEBUG(zm_dprintf("Flushing serial line.\n"));
+	  xyzModem_flush();
+          xyz.at_eof = true;
+	break;
+	case xyzModem_zmodem:
+	  // Might support it some day I suppose.
+	break;
+      }
+    default:
+      ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n"));
+      // Consume any trailing crap left in the inbuffer from
+      // previous recieved blocks. Since very few files are an exact multiple
+      // of the transfer block size, there will almost always be some gunk here.
+      // If we don't eat it now, RedBoot will think the user typed it.
+      ZM_DEBUG(zm_dprintf("Trailing gunk:\n"));
+      while ((c = (*getc)()) > -1) ;
+      ZM_DEBUG(zm_dprintf("\n"));
+      // Make a small delay to give terminal programs like minicom
+      // time to get control again after their file transfer program
+      // exits.
+      CYGACC_CALL_IF_DELAY_US((cyg_int32)100000);
+      break;
+  }
+}
+
 char *
 xyzModem_error(int err)
 {
--- a/packages/redboot/current/src/xyzModem.h
+++ b/packages/redboot/current/src/xyzModem.h
@@ -59,8 +59,12 @@
 #define xyzModem_cksum    -7
 #define xyzModem_sequence -8
 
+#define xyzModem_close 1
+#define xyzModem_abort 2
+
 int   xyzModem_stream_open(char *filename, int mode, int *err);    
 void  xyzModem_stream_close(int *err);    
+void  xyzModem_stream_terminate(int method, int (*getc)(void));    
 int   xyzModem_stream_read(char *buf, int size, int *err);    
 char *xyzModem_error(int err);
 
--- a/packages/templates/redboot/ChangeLog
+++ b/packages/templates/redboot/ChangeLog
@@ -1,3 +1,11 @@
+2001-09-04  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* current.ect: Silence warnings when selecting redboot template.
+
+2001-08-22  Gary Thomas  <gthomas@redhat.com>
+
+	* current.ect: Include STDC string functions.
+
 2001-06-25  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* current.ect: Increase default interrupt stack size up to 6K
@@ -43,7 +51,7 @@ 2000-07-12  Gary Thomas  <gthomas@redhat
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
--- a/packages/templates/redboot/current.ect
+++ b/packages/templates/redboot/current.ect
@@ -13,6 +13,8 @@ This is the RedBoot configuration, used 
     package     CYGPKG_HAL current ;
     package     CYGPKG_INFRA current ;
     package     CYGPKG_REDBOOT current ;
+    package     CYGPKG_ISOINFRA current ;
+    package     CYGPKG_LIBC_STRING current ;
 };
 
 cdl_option CYGBLD_BUILD_REDBOOT {
@@ -26,3 +28,20 @@ cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_
 cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
     user_value 6144
 };
+
+cdl_option CYGBLD_ISO_STRTOK_R_HEADER {
+    inferred_value 1 <cyg/libc/string/string.h>
+};
+
+cdl_option CYGBLD_ISO_STRING_LOCALE_FUNCS_HEADER {
+    inferred_value 1 <cyg/libc/string/string.h>
+};
+
+cdl_option CYGBLD_ISO_STRING_MEMFUNCS_HEADER {
+    inferred_value 1 <cyg/libc/string/string.h>
+};
+
+cdl_option CYGBLD_ISO_STRING_STRFUNCS_HEADER {
+    inferred_value 1 <cyg/libc/string/string.h>
+};
+