changeset 198:ea3f0bd33a73

Merge from eCos master repository on 2001-12-07-11:40:47-GMT
author jlarmour
date Fri, 07 Dec 2001 14:15:03 +0000
parents 51b34619b677
children 920b9b754b53
files host/libcdl/ChangeLog host/libcdl/build.cxx host/libcdl/cdlcore.hxx host/libcdl/infer.cxx host/libcdl/interp.cxx host/tools/configtool/ChangeLog host/tools/configtool/standalone/common/ChangeLog host/tools/configtool/standalone/common/cdl_exec.cxx host/tools/configtool/standalone/wxwin/CHANGES.txt host/tools/configtool/standalone/wxwin/TODO.txt host/tools/configtool/standalone/wxwin/symbols.h host/tools/configtool/standalone/wxwin/templatesdlg.cpp packages/devs/eth/amd/pcnet/current/ChangeLog packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h packages/devs/eth/amd/pcnet/current/src/if_pcnet.c packages/devs/serial/powerpc/quicc/current/ChangeLog packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c packages/hal/arm/edb7xxx/current/ChangeLog packages/hal/arm/edb7xxx/current/misc/edb7212_redboot.ecm packages/hal/arm/edb7xxx/current/misc/edb7212_redboot_ROM.ecm packages/hal/arm/pid/current/ChangeLog packages/hal/arm/pid/current/cdl/hal_arm_pid.cdl packages/hal/common/current/ChangeLog packages/hal/common/current/cdl/hal.cdl packages/hal/common/current/src/dbg-threads-syscall.c packages/hal/common/current/src/generic-stub.c packages/hal/i386/arch/current/ChangeLog packages/hal/i386/arch/current/src/i386.ld packages/hal/i386/pc/current/misc/redboot_FLOPPY_D850GB.ecm packages/hal/i386/pcmb/current/ChangeLog packages/hal/i386/pcmb/current/include/pcmb_serial.h packages/hal/i386/pcmb/current/src/pcmb_serial.c packages/hal/mips/arch/current/ChangeLog packages/hal/mips/arch/current/cdl/hal_mips.cdl packages/hal/mips/arch/current/include/hal_arch.h packages/hal/mips/arch/current/include/mips-regs.h packages/hal/mips/arch/current/include/mips-stub.h packages/hal/mips/arch/current/src/hal_misc.c packages/hal/mips/arch/current/src/vectors.S packages/hal/mips/mips32/current/ChangeLog packages/hal/mips/mips32/current/cdl/hal_mips_mips32.cdl packages/hal/mips/mips32/current/include/var_arch.h packages/hal/mips/mips64/current/ChangeLog packages/hal/mips/mips64/current/cdl/hal_mips_mips64.cdl packages/hal/mips/mips64/current/include/var_arch.h packages/hal/mips/vr4300/current/ChangeLog packages/hal/mips/vr4300/current/include/variant.inc packages/infra/current/ChangeLog packages/infra/current/include/diag.h packages/infra/current/src/diag.cxx packages/io/eth/current/ChangeLog packages/io/eth/current/src/stand_alone/eth_drv.c packages/isoinfra/current/ChangeLog packages/isoinfra/current/include/netdb.h packages/language/c/libc/stdio/current/ChangeLog packages/language/c/libc/stdio/current/src/common/fflush.cxx packages/net/ftpclient/current/ChangeLog packages/net/ftpclient/current/src/ftpclient.c packages/net/snmp/agent/current/ChangeLog packages/net/snmp/agent/current/src/snmpd.c packages/net/snmp/agent/current/src/snmptask.c packages/net/tcpip/current/ChangeLog packages/net/tcpip/current/include/bootp.h packages/net/tcpip/current/src/lib/bootp_support.c packages/net/tcpip/current/src/lib/dhcp_prot.c packages/net/tcpip/current/src/lib/dhcp_support.c packages/redboot/current/ChangeLog packages/redboot/current/include/net/net.h packages/redboot/current/src/flash.c packages/redboot/current/src/load.c packages/redboot/current/src/main.c packages/redboot/current/src/net/inet_addr.c packages/redboot/current/src/net/net_io.c packages/redboot/current/src/net/tcp.c packages/redboot/current/src/parse.c
diffstat 75 files changed, 1172 insertions(+), 270 deletions(-) [+]
line wrap: on
line diff
--- a/host/libcdl/ChangeLog
+++ b/host/libcdl/ChangeLog
@@ -1,3 +1,15 @@
+2001-12-06  Bart Veer  <bartv@redhat.com>
+
+	* cdlcore.hxx, build.cxx, interp.cxx:
+	Move #include of <cctype> to common header rather than to
+	individual source files, avoiding build problems with
+	newer compilers. Reported by Jeff Law.
+
+	* infer.cxx (inner_resolve):
+	CdlTransaction::is_preferable_to() is not symmetric. Rearrange
+	some expressions so that disabling options or making them
+	inactive is subtly discouraged rather than encouraged.
+
 2001-07-20  Bart Veer  <bartv@redhat.com>
 
 	* value.cxx (save):
--- a/host/libcdl/build.cxx
+++ b/host/libcdl/build.cxx
@@ -10,7 +10,7 @@
 //####COPYRIGHTBEGIN####
 //                                                                          
 // ----------------------------------------------------------------------------
-// Copyright (C) 1999, 2000 Red Hat, Inc.
+// Copyright (C) 1999, 2000, 2001 Red Hat, Inc.
 //
 // This file is part of the eCos host tools.
 //
@@ -57,9 +57,6 @@
 // the class definitions rely on these headers.
 #include <cdlcore.hxx>
 
-// split_custom_build_step() needs access to isspace() etc.
-#include <cctype>
-
 //}}}
 
 //{{{  Statics                          
--- a/host/libcdl/cdlcore.hxx
+++ b/host/libcdl/cdlcore.hxx
@@ -79,6 +79,11 @@
 #include <functional>
 #include <algorithm>
 
+// <cctype> is needed in various places in the implementation.
+// This #include should be moved to an implementation-specific
+// header.
+#include <cctype>
+
 // Now for some eCos host-side infrastructure headers.
 //
 // Get the cyg_int64 data type and CYG_UNUSED_PARAM() macro.
--- a/host/libcdl/infer.cxx
+++ b/host/libcdl/infer.cxx
@@ -1591,7 +1591,7 @@ CdlConflict_RequiresBody::inner_resolve(
                 return result;
             } else if (0 == preferred_transaction) {
                 preferred_transaction = disable_transaction;
-            } else if (disable_transaction->is_preferable_to(preferred_transaction)) {
+            } else if (!preferred_transaction->is_preferable_to(disable_transaction)) {
                 preferred_transaction->cancel(); 
                 delete preferred_transaction;
                 preferred_transaction = disable_transaction;
@@ -1626,7 +1626,7 @@ CdlConflict_RequiresBody::inner_resolve(
             return result;
         } else if (0 == preferred_transaction) {
             preferred_transaction = inactive_transaction;
-        } else if (inactive_transaction->is_preferable_to(preferred_transaction)) {
+        } else if (!preferred_transaction->is_preferable_to(inactive_transaction)) {
             preferred_transaction->cancel(); 
             delete preferred_transaction;
             preferred_transaction = inactive_transaction;
--- a/host/libcdl/interp.cxx
+++ b/host/libcdl/interp.cxx
@@ -59,9 +59,6 @@
 // in <tcl.h>
 #include <cdlcore.hxx>
 
-// quote() needs access to isspace()
-#include <cctype>
-
 //}}}
 
 //{{{  Statics                                                  
--- a/host/tools/configtool/ChangeLog
+++ b/host/tools/configtool/ChangeLog
@@ -1,3 +1,8 @@
+2001-12-03  Julian Smart <julians@redhat.com>
+
+    * standalone/wxwin/templatesdlg.cpp: hardware is now sorted alphabetically
+    on UNIX.
+
 2001-10-25  Julian Smart <julians@redhat.com>
 
     * common/common/build.cxx: now generates /ecos-x names under Windows
--- a/host/tools/configtool/standalone/common/ChangeLog
+++ b/host/tools/configtool/standalone/common/ChangeLog
@@ -1,3 +1,8 @@
+2001-12-06  Bart Veer  <bartv@redhat.com>
+
+	* cdl_exec.cxx (report_conflicts):
+	Report possible solutions correctly (bug 56232).
+
 2001-10-25  Julian Smart  <julians@redhat.com>
 
 	* cdl_exec.cxx: added calls to mount -f /ecos-x under Cygwin,
--- a/host/tools/configtool/standalone/common/cdl_exec.cxx
+++ b/host/tools/configtool/standalone/common/cdl_exec.cxx
@@ -748,8 +748,36 @@ cdl_exec::report_conflicts()
                 const std::vector<std::pair<CdlValuable, CdlValue> > & soln = (*conf_i)->get_solution();
                 unsigned int i;
                 for (i = 0; i < soln.size(); i++) {
-                    soln_msg += soln[i].first->get_name() + " -> " + soln[i].second.get_value() + "\n";
+                    CdlValuable valuable = soln[i].first;
+                    soln_msg += valuable->get_name();
+                    soln_msg += " -> ";
+                    switch(valuable->get_flavor()) {
+                      case CdlValueFlavor_Bool :
+                        if (!soln[i].second.is_enabled()) {
+                            soln_msg += "0 (disabled)";
+                        } else {
+                            soln_msg += "1 (enabled)";
+                        }
+                        break;
+                      case CdlValueFlavor_Data:
+                        soln_msg += soln[i].second.get_value();
+                        break;
+                      case CdlValueFlavor_BoolData:
+                        if (!soln[i].second.is_enabled()) {
+                            soln_msg += "0 " + soln[i].second.get_value();
+                        } else {
+                            soln_msg += "1 " + soln[i].second.get_value();
+                        }
+                        break;
+                        // An option with flavor none cannot be involved
+                        // in a solution.
+                      default:
+                        soln_msg += "<internal error>";
+                        break;
+                    }
+                    soln_msg += "\n";
                 }
+                
 #if 0
                 // FIXME: currently this member only works for nested sub-transactions.
                 if (transact->user_confirmation_required()) {
--- a/host/tools/configtool/standalone/wxwin/CHANGES.txt
+++ b/host/tools/configtool/standalone/wxwin/CHANGES.txt
@@ -1,6 +1,11 @@
 Release History for eCos Configuration Tool 2
 =============================================
 
+*** Version 2.09, December 3rd 2001
+
+- Hardware is now sorted alphabetically on UNIX.
+
+
 *** Version 2.08, October 25th 2001
 
 - Looks in PATH for gcc locations on UNIX.
--- a/host/tools/configtool/standalone/wxwin/TODO.txt
+++ b/host/tools/configtool/standalone/wxwin/TODO.txt
@@ -5,10 +5,6 @@ To-Do List for Configuration Tool 2.x
 
 - Verify Run Tests Dialog works for TCP/IP mode on Linux.
 
-- List templates in alphabetical order under Linux. Unfortunately
-  wxComboBox in wxGTK doesn't support wxCB_SORT at this time
-  (but wxChoice does).
-
 - Importing more than one package at a time can cause conflicts
   whereas importing one at a time causes no conflicts.
 
@@ -30,3 +26,6 @@ To-Do List for Configuration Tool 2.x
 - 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.
+
+- Should look for a .ecc file in the current directory if no save file is
+  passed on the command line.
\ No newline at end of file
--- 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.12 2001/10/11 12:31:42 julians Exp $
+// Version:     $Id: symbols.h,v 1.13 2001/12/03 16:05:40 julians Exp $
 // Purpose:
 // Description: Some important symbols, such as the version
 // Requires:
@@ -43,7 +43,7 @@
 //
 //===========================================================================
 
-#define ecCONFIGURATION_TOOL_VERSION        2.08
+#define ecCONFIGURATION_TOOL_VERSION        2.09
 
 // Use /ecos-x notation for drive specification
 #define ecUSE_ECOS_X_NOTATION               1
--- a/host/tools/configtool/standalone/wxwin/templatesdlg.cpp
+++ b/host/tools/configtool/standalone/wxwin/templatesdlg.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/27
-// Version:     $Id: templatesdlg.cpp,v 1.8 2001/07/13 15:17:43 julians Exp $
+// Version:     $Id: templatesdlg.cpp,v 1.10 2001/12/03 16:05:40 julians Exp $
 // Purpose:
 // Description: Implementation file for ecTemplatesDialog
 // Requires:
@@ -198,6 +198,15 @@ void ecTemplatesDialog::CreateControls(w
     PopulateControls();
 }
 
+// function which is called by quick sort
+static int wxStringCompareFunction(const void *first, const void *second)
+{
+  wxString *strFirst = (wxString *)first;
+  wxString *strSecond = (wxString *)second;
+
+  return wxStricmp(strFirst->c_str(), strSecond->c_str());
+}
+
 void ecTemplatesDialog::PopulateControls()
 {
     ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
@@ -211,6 +220,8 @@ void ecTemplatesDialog::PopulateControls
 	const std::vector<std::string> & targets = doc->GetCdlPkgData ()->get_targets ();
 	std::vector<std::string>::const_iterator target_i;
 
+    // Old code: let the combo box do the sorting. But not all platforms implement this.
+#if 0
     // populate the hardware combo box
     int nIndex = 0;
 	for (target_i = targets.begin (); target_i != targets.end (); target_i++)
@@ -232,6 +243,49 @@ void ecTemplatesDialog::PopulateControls
         }
         nIndex ++;
 	}
+#else
+    // New code: sort, then add to combobox. How do we keep track of the target iterators?
+    // could use hash table, assuming that each string is unique
+    wxHashTable ht(wxKEY_STRING);
+    wxArrayString ar;
+
+	for (target_i = targets.begin (); target_i != targets.end (); target_i++)
+	{
+		const std::vector<std::string> & aliases = doc->GetCdlPkgData ()->get_target_aliases (* target_i);
+
+		// use the first alias (if any) as the description
+		wxString strTargetDescription = aliases.size () ? aliases [0].c_str () : target_i->c_str ();
+
+        ar.Add(strTargetDescription);
+        ht.Put(strTargetDescription, (wxObject*) (void*) &(*target_i));
+    }
+
+    ar.Sort((wxArrayString::CompareFunction) & wxStringCompareFunction);
+
+    int nIndex = 0;
+
+    unsigned int i;
+    for (i = 0; i < ar.GetCount(); i ++)
+    {
+        wxString strTargetDescription = ar[i];
+
+        std::string *t_i = (std::string*) (void*) ht.Get(strTargetDescription);
+
+		cdlHardwareCtrl->Append(strTargetDescription, (void*) t_i); // store the target iterator
+        std::string str(* (t_i));
+		if (m_hardware == str.c_str())            // if current target...
+        {
+            int sel = 0;
+            int i;
+            for (i = 0; i <= nIndex; i++)
+                if (cdlHardwareCtrl->GetClientData(i) == (void*) &(*t_i))
+                    sel = i;
+			cdlHardwareCtrl->SetSelection (sel); // ...select the string
+        }
+        nIndex ++;
+	}
+
+#endif
 
 	if (-1 == cdlHardwareCtrl->GetSelection ()) // if no target selected...
 		cdlHardwareCtrl->SetSelection (0);          // ...select the first one
--- a/packages/devs/eth/amd/pcnet/current/ChangeLog
+++ b/packages/devs/eth/amd/pcnet/current/ChangeLog
@@ -1,3 +1,15 @@
+2001-12-04  Nick Garnett  <nickg@redhat.com>
+
+	* src/if_pcnet.c:
+	Added a couple of 100us delays in transmit code. These appear to
+	be necessary to meet timing constraints on some platforms. These
+	are not a very satisfying fix, but they will have to do for now.
+	Also changed all references to diag_printf to db_printf, and added
+	a static implementation of db_printf() that will gnerate
+	diagnostic output properly on RedBoot.
+
+	* src/amd_pcnet.h: diag_printf -> db_printf
+	
 2001-10-16  David Howells  <dhowells@redhat.com>
 
 	* src/if_pcnet.c: don't invert the logic of the auto-negotiation
--- a/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h
+++ b/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h
@@ -71,7 +71,7 @@
 #define DEBUG 0x0
 
 #if DEBUG & 1
-#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
+#define DEBUG_FUNCTION() do { os_printf("%s\n", __FUNCTION__); } while (0)
 #else
 #define DEBUG_FUNCTION() do {} while(0)
 #endif
@@ -491,7 +491,7 @@ get_reg(struct eth_drv_sc *sc, int regno
             HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RDP, val);
     }
 #if DEBUG & 2
-    diag_printf("read %s reg %d val 0x%04x\n", 
+    os_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
@@ -526,7 +526,7 @@ put_reg(struct eth_drv_sc *sc, int regno
     }
 
 #if DEBUG & 2
-    diag_printf("write %s reg %d val 0x%04x\n", 
+    os_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
--- a/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
+++ b/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
@@ -100,6 +100,27 @@ int pcnet_txfifo_bad = 0;
 #include CYGDAT_DEVS_ETH_AMD_PCNET_INL
 #undef  __WANT_DEVS
 
+#ifdef CYGPKG_REDBOOT
+
+static void db_printf( char *fmt, ... )
+{
+    extern int start_console(void);
+    extern void end_console(int);
+    va_list a;
+    int old_console;
+    va_start( a, fmt );
+    old_console = start_console();  
+    diag_vprintf( fmt, a );
+    end_console(old_console);
+    va_end( a );
+}
+
+#else
+
+#define db_printf diag_printf
+
+#endif
+
 static void pcnet_poll(struct eth_drv_sc *sc);
 
 // This ISR is called when the ethernet interrupt occurs
@@ -200,7 +221,7 @@ pciwindow_mem_alloc(int size)
     }
 
 #if DEBUG & 9
-    diag_printf("Allocated %d bytes at 0x%08x\n", size, p_memory);
+    db_printf("Allocated %d bytes at 0x%08x\n", size, p_memory);
 #endif
 
     return p_memory;
@@ -212,7 +233,7 @@ 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);
+    db_printf("PCI match vendor 0x%04x device 0x%04x\n", v, d);
 #endif
     return (0x1022 == v) && (0x2000 == d);
 }
@@ -252,7 +273,7 @@ pci_init_find_pcnet( void )
          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");
+        db_printf("pci_init_find_pcnets(): PCI window misconfigured\n");
 #endif
         return 0;
     }
@@ -262,12 +283,12 @@ pci_init_find_pcnet( void )
     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);
+    db_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");
+    db_printf("Finished cyg_pci_init();\n");
 #endif
 
     devid = CYG_PCI_NULL_DEVID;
@@ -284,14 +305,14 @@ pci_init_find_pcnet( void )
         // 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);
+            db_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);
+                db_printf(" Wired to HAL vector %d\n", cpd->interrupt);
 #endif
                 cyg_drv_interrupt_create(
                     cpd->interrupt,
@@ -310,39 +331,39 @@ pci_init_find_pcnet( void )
             else {
                 cpd->interrupt = 0;
 #if DEBUG & 8
-                diag_printf(" Does not generate interrupts.\n");
+                db_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",
+                db_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"
+                    db_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",
+                db_printf(" Vendor    0x%04x", dev_info.vendor);
+                db_printf("\n Device    0x%04x", dev_info.device);
+                db_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);
+                db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+                db_printf("\n Header 0x%02x\n", dev_info.header_type);
 
-                diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+                db_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",
+                    db_printf(" BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
+                    db_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);
+                db_printf(" eth%d configured\n", device_index);
 #endif
                 found_devices++;
                 cpd->found = 1;
@@ -350,7 +371,7 @@ pci_init_find_pcnet( void )
                 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);
+                db_printf(" I/O address = 0x%08x\n", cpd->base);
 #endif
 
                 // Don't use cyg_pci_set_device_info since it clears
@@ -368,11 +389,11 @@ pci_init_find_pcnet( void )
                     cyg_drv_interrupt_acknowledge(cpd->interrupt);
                     cyg_drv_interrupt_unmask(cpd->interrupt);
 #if DEBUG & 8
-                    diag_printf(" Enabled interrupt %d\n", cpd->interrupt);
+                    db_printf(" Enabled interrupt %d\n", cpd->interrupt);
 #endif
                 }
 #if DEBUG & 8
-                diag_printf(" **** Device enabled for I/O and Memory "
+                db_printf(" **** Device enabled for I/O and Memory "
                             "and Bus Master\n");
 #endif
             }
@@ -380,7 +401,7 @@ pci_init_find_pcnet( void )
                 cpd->found = 0;
                 cpd->active = 0;
 #if DEBUG & 8
-                diag_printf("Failed to configure device %d\n", device_index);
+                db_printf("Failed to configure device %d\n", device_index);
 #endif
             }
         }
@@ -388,7 +409,7 @@ pci_init_find_pcnet( void )
             cpd->found = 0;
             cpd->active = 0;
 #if DEBUG & 8
-            diag_printf("eth%d not found\n", device_index);
+            db_printf("eth%d not found\n", device_index);
 #endif
         }
     }
@@ -421,7 +442,7 @@ amd_pcnet_init(struct cyg_netdevtab_entr
         // then this is the first time ever:
         if ( ! pci_init_find_pcnet() ) {
 #if DEBUG & 8
-            diag_printf( "pci_init_find_pcnet failed" );
+            db_printf( "pci_init_find_pcnet failed" );
 #endif
             return false;
         }
@@ -434,20 +455,20 @@ amd_pcnet_init(struct cyg_netdevtab_entr
     cpd->txbusy = 0;
 
 #if DEBUG & 8
-    diag_printf("PCNet at base 0x%08x, EEPROM key 0x%04x\n",
+    db_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");
+        db_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);
+    db_printf("pcimem : %08x size: %08x\n", pcnet_heap_base, pcnet_heap_size);
 #endif
 
     // Prepare ESA
@@ -458,7 +479,7 @@ amd_pcnet_init(struct cyg_netdevtab_entr
             cpd->esa[i] = *p++;
     }
 #if DEBUG & 9
-    diag_printf("PCNET - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+    db_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] );
@@ -470,7 +491,7 @@ amd_pcnet_init(struct cyg_netdevtab_entr
 	int loop;
 
 #if DEBUG & 9
-	diag_printf("%s: Forcing 10Mbps negotiation\n", __FUNCTION__);
+	db_printf("%s: Forcing 10Mbps negotiation\n", __FUNCTION__);
 #endif
 	// adjust speed/duplex auto-negotiation mask to clear 100Mbps bits
 	anr = get_reg(sc,PCNET_ANR_AAR);
@@ -484,9 +505,9 @@ amd_pcnet_init(struct cyg_netdevtab_entr
 	while (loop>0 && !(get_reg(sc,PCNET_ANR_PHYSTAT) & PCNET_ANR_PHYSTAT_AUTONEG_COMP))
 		loop--;
 #if DEBUG & 9
-	diag_printf("ANR0: %04x\n",get_reg(sc,PCNET_ANR_PHYCTRL));
-	diag_printf("ANR1: %04x\n",get_reg(sc,PCNET_ANR_PHYSTAT));
-	diag_printf("ANR4: %04x\n",get_reg(sc,PCNET_ANR_AAR));
+	db_printf("ANR0: %04x\n",get_reg(sc,PCNET_ANR_PHYCTRL));
+	db_printf("ANR1: %04x\n",get_reg(sc,PCNET_ANR_PHYSTAT));
+	db_printf("ANR4: %04x\n",get_reg(sc,PCNET_ANR_AAR));
 #endif
     }
 #endif
@@ -535,18 +556,18 @@ amd_pcnet_init(struct cyg_netdevtab_entr
                                         | (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 ",
+    db_printf("Loading up PCNet controller from table at 0x%08x\n", init_table);
+    db_printf(" Mode 0x%04x\n", _SU16(init_table, PCNET_IB_MODE));
+    db_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",
+    db_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",
+    db_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,
@@ -578,29 +599,29 @@ amd_pcnet_init(struct cyg_netdevtab_entr
     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 ",
+    db_printf("PCNet controller state is now:\n");
+    db_printf(" Mode 0x%04x  TFC 0x%04x\n", _SU16(init_table, PCNET_IB_MODE), get_reg(sc, PCNET_CSR_TFC));
+    db_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",
+    db_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",
+    db_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) ",
+    db_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",
+    db_printf("Part IDU 0x%03x Silicon rev %d\n",
                 val & 0x0fff, (val >> 12) & 0xf);
 #endif
 
@@ -616,7 +637,7 @@ amd_pcnet_init(struct cyg_netdevtab_entr
         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");
+            db_printf("Failed to start the controller\n");
 #endif
             return false;
         }
@@ -635,7 +656,7 @@ amd_pcnet_init(struct cyg_netdevtab_entr
     (sc->funs->eth_drv->init)(sc, cpd->esa);
 
 #if DEBUG & 9
-    diag_printf("Done\n");
+    db_printf("Done\n");
 #endif
     return true;
 }
@@ -742,7 +763,7 @@ pcnet_control(struct eth_drv_sc *sc, uns
     switch (key) {
     case ETH_DRV_SET_MAC_ADDRESS:
 #if 9 & DEBUG
-        diag_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+        db_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
 
@@ -920,7 +941,7 @@ pcnet_send(struct eth_drv_sc *sc, struct
         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__ );
+            db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
 #endif
             continue;
         }
@@ -937,7 +958,7 @@ pcnet_send(struct eth_drv_sc *sc, struct
                "TX descriptor not free");
 
 #if DEBUG & 4
-    diag_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
+    db_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
                 txd, buf);
 #endif
 
@@ -954,7 +975,7 @@ pcnet_send(struct eth_drv_sc *sc, struct
     CYG_ASSERT( sdata, "No sg data pointer outside" );
 
 #if DEBUG & 1
-    diag_printf("CSCR %04x\n", get_reg(sc, PCNET_CSR_CSCR));
+    db_printf("CSCR %04x\n", get_reg(sc, PCNET_CSR_CSCR));
 #endif
     _SU16(txd, PCNET_TD_LEN) = (-plen);
     _SU16(txd, PCNET_TD_MISC) = 0;
@@ -964,12 +985,18 @@ pcnet_send(struct eth_drv_sc *sc, struct
 
 #if DEBUG & 1
     cpd->txd = txd;
-    diag_printf("Last TX: LEN %04x MISC %04x PTR %08x\n", 
+    db_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
 
+    // This delay seems to be necessary on some platforms
+    // Why it is needed is not clear, but removing it or
+    // reducing it cause transmission failures in RedBoot (at least).
+    CYGACC_CALL_IF_DELAY_US(100);
+    
+
     // Set transmit demand
     ints = get_reg(sc, PCNET_CSR_CSCR);
     ints &= PCNET_CSR_CSCR_EV_MASK;
@@ -978,8 +1005,13 @@ pcnet_send(struct eth_drv_sc *sc, struct
 
 #if DEBUG & 1
     ints = get_reg(sc, PCNET_CSR_CSCR);
-    diag_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints);
+    db_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints);
 #endif
+
+    // This is another mystery delay like the one above. This one is
+    // even stranger, since waiting here at the _end_ of the function
+    // should have no effect.
+    CYGACC_CALL_IF_DELAY_US(200);
 }
 
 static void
@@ -1000,7 +1032,7 @@ pcnet_TxEvent(struct eth_drv_sc *sc, int
     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__);
+        db_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
 #endif
         // first dirty ring entry not freed - wtf?
     }
@@ -1009,7 +1041,7 @@ pcnet_TxEvent(struct eth_drv_sc *sc, int
         // We had an error. Tell the stack.
         success = 0;
 #if DEBUG & 1
-        diag_printf("%s: TX failure, retrying...\n", __FUNCTION__);
+        db_printf("%s: TX failure, retrying...\n", __FUNCTION__);
 #endif
     }
 
@@ -1061,7 +1093,7 @@ pcnet_TxEvent(struct eth_drv_sc *sc, int
     put_reg(sc, PCNET_CSR_CSCR, ints);
 
 #if DEBUG & 4
-    diag_printf("#####Tx packet freed 0x%08x\n", txd );
+    db_printf("#####Tx packet freed 0x%08x\n", txd );
 #endif
 
     if ( cpd->txbusy ) {
@@ -1091,7 +1123,7 @@ pcnet_RxEvent(struct eth_drv_sc *sc)
 
     ints = get_reg(sc, PCNET_CSR_CSCR);
 #if DEBUG & 1
-    diag_printf("RxEvent - CSR: 0x%04x\n", ints);
+    db_printf("RxEvent - CSR: 0x%04x\n", ints);
 #endif
 
     while (1) {
@@ -1115,14 +1147,14 @@ pcnet_RxEvent(struct eth_drv_sc *sc)
                     cyg_uint16 mlen, blen;
                     cyg_uint8* rxd;
 
-                    diag_printf("%s: Inconsistent RX state\n", __FUNCTION__);
+                    db_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);
+                        db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
                     }
                 }
             }
@@ -1131,7 +1163,7 @@ pcnet_RxEvent(struct eth_drv_sc *sc)
         }
 
 #if DEBUG & 4
-        diag_printf("#####Rx packet at index %d\n", cpd->rxpacket);
+        db_printf("#####Rx packet at index %d\n", cpd->rxpacket);
 #endif
 
         // Increment counts
@@ -1153,7 +1185,7 @@ pcnet_RxEvent(struct eth_drv_sc *sc)
             INCR_STAT( rx_good );
 
 #if DEBUG & 1
-            diag_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+            db_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
@@ -1166,7 +1198,7 @@ pcnet_RxEvent(struct eth_drv_sc *sc)
         } else {
             // Not OK for one reason or another...
 #if DEBUG & 1
-            diag_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+            db_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
                         rstat, len);
 #endif
         }
@@ -1212,7 +1244,7 @@ pcnet_recv(struct eth_drv_sc *sc, struct
         mlen = sg_list[i].len;
 
 #if DEBUG & 1
-        diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+        db_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
 #endif
         if (data) {
             while (mlen > 0) {
@@ -1252,14 +1284,14 @@ pcnet_poll(struct eth_drv_sc *sc)
             struct pcnet_priv_data *cpd = 
                 (struct pcnet_priv_data *)sc->driver_private;
 
-            diag_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+            db_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);
+                db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
             }
 #endif
             event &= PCNET_CSR_CSCR_EV_MASK;
@@ -1268,7 +1300,7 @@ pcnet_poll(struct eth_drv_sc *sc)
         }
         else {
 #if DEBUG & 1
-            diag_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+            db_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
 #endif
             put_reg(sc, PCNET_CSR_CSCR, event);
         }
--- a/packages/devs/serial/powerpc/quicc/current/ChangeLog
+++ b/packages/devs/serial/powerpc/quicc/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-11-30  Jonathan Larmour  <jlarmour@redhat.com>
+2001-11-29  Christoph Csebits  <christoph.csebits@frequentis.com>
+
+	* src/quicc_smc_serial.c:
+        aligning buffer to cache lines,
+        flushing buffer in cache before flushing the device.
+
 2001-09-10  Jonathan Larmour  <jlarmour@redhat.com>
 
         * cdl/ser_quicc_smc.cdl:        
--- a/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
+++ b/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
@@ -54,6 +54,9 @@
 
 #ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC
 
+// macro for aligning buffers to cache lines
+#define ALIGN_TO_CACHELINES(b) ((cyg_uint8 *)(((CYG_ADDRESS)(b) + (HAL_DCACHE_LINE_SIZE-1)) & ~(HAL_DCACHE_LINE_SIZE-1)))
+
 // Buffer descriptor control bits
 #define QUICC_BD_CTL_Ready 0x8000  // Buffer contains data (tx) or is empty (rx)
 #define QUICC_BD_CTL_Wrap  0x2000  // Last buffer in list
@@ -154,8 +157,8 @@ static SERIAL_CHANNEL(quicc_smc_serial_c
     );
 #endif
 
-static unsigned char quicc_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE];
-static unsigned char quicc_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE];
+static unsigned char quicc_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE + HAL_DCACHE_LINE_SIZE-1];
+static unsigned char quicc_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE + HAL_DCACHE_LINE_SIZE-1];
 
 DEVTAB_ENTRY(quicc_smc_serial_io1, 
              CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME,
@@ -198,8 +201,8 @@ static SERIAL_CHANNEL(quicc_smc_serial_c
                       CYG_SERIAL_FLAGS_DEFAULT
     );
 #endif
-static unsigned char quicc_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE];
-static unsigned char quicc_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE];
+static unsigned char quicc_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE + HAL_DCACHE_LINE_SIZE-1];
+static unsigned char quicc_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE + HAL_DCACHE_LINE_SIZE-1];
 
 DEVTAB_ENTRY(quicc_smc_serial_io2, 
              CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME,
@@ -398,11 +401,11 @@ quicc_smc_serial_init(struct cyg_devtab_
                                    TxBD, 
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM,
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE,
-                                   &quicc_smc1_txbuf[0][0],
+                                   ALIGN_TO_CACHELINES(&quicc_smc1_txbuf[0][0]),
                                    RxBD, 
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM,
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE,
-                                   &quicc_smc1_rxbuf[0][0],
+                                   ALIGN_TO_CACHELINES(&quicc_smc1_rxbuf[0][0]),
                                    0xC0, // PortB mask
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BRG,
                                    12  // SI mask position
@@ -430,11 +433,11 @@ quicc_smc_serial_init(struct cyg_devtab_
                                    TxBD, 
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM,
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE,
-                                   &quicc_smc2_txbuf[0][0],
+                                   ALIGN_TO_CACHELINES(&quicc_smc2_txbuf[0][0]),
                                    RxBD, 
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM,
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE,
-                                   &quicc_smc2_rxbuf[0][0],
+                                   ALIGN_TO_CACHELINES(&quicc_smc2_rxbuf[0][0]),
                                    0xC00, // PortB mask
                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BRG,
                                    28  // SI mask position
@@ -475,6 +478,13 @@ static void
 quicc_smc_serial_flush(quicc_smc_serial_info *smc_chan)
 {
     volatile struct cp_bufdesc *txbd = smc_chan->txbd;
+    int cache_state;
+                                       
+    HAL_DCACHE_IS_ENABLED(cache_state);
+    if (cache_state) {
+      HAL_DCACHE_FLUSH(txbd->buffer, smc_chan->txsize);
+    }
+
     if ((txbd->length > 0) && 
         ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0)) {
         txbd->ctrl |= QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int;  // Signal buffer ready
--- a/packages/hal/arm/edb7xxx/current/ChangeLog
+++ b/packages/hal/arm/edb7xxx/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* misc/edb7212_redboot.ecm:
+	* misc/edb7212_redboot_ROM.ecm:
+	Fix target descriptions to be edb7xxx.
+
 2001-10-12  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/hal_arm_edb7xxx.cdl: Clarify package description strings.
--- a/packages/hal/arm/edb7xxx/current/misc/edb7212_redboot.ecm
+++ b/packages/hal/arm/edb7xxx/current/misc/edb7212_redboot.ecm
@@ -9,7 +9,7 @@ cdl_savefile_command cdl_interface { val
 
 cdl_configuration eCos {
     description "" ;
-    hardware    edb7212 ;
+    hardware    edb7xxx ;
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_EDB7XXX current ;
--- a/packages/hal/arm/edb7xxx/current/misc/edb7212_redboot_ROM.ecm
+++ b/packages/hal/arm/edb7xxx/current/misc/edb7212_redboot_ROM.ecm
@@ -9,7 +9,7 @@ cdl_savefile_command cdl_interface { val
 
 cdl_configuration eCos {
     description "" ;
-    hardware    edb7212 ;
+    hardware    edb7xxx ;
     template    redboot ;
     package -hardware CYGPKG_HAL_ARM current ;
     package -hardware CYGPKG_HAL_ARM_EDB7XXX current ;
--- a/packages/hal/arm/pid/current/ChangeLog
+++ b/packages/hal/arm/pid/current/ChangeLog
@@ -316,6 +316,10 @@ 1999-12-09  John Dallaway  <jld@cygnus.c
 	Modify testing parameters according to
 	CYGHWR_HAL_ARM_BIGENDIAN.
 
+1999-12-09  John Dallaway  <jld@cygnus.co.uk>
+
+	* cdl/hal_arm_pid.cdl: Add SID execution flags option.
+
 1999-12-07  Gary Thomas  <gthomas@cygnus.co.uk>
 
 	* cdl/hal_arm_pid.cdl: Add descriptive strings used by CygMon.
--- a/packages/hal/arm/pid/current/cdl/hal_arm_pid.cdl
+++ b/packages/hal/arm/pid/current/cdl/hal_arm_pid.cdl
@@ -404,6 +404,19 @@ cdl_package CYGPKG_HAL_ARM_PID {
              the ROM monitor or boot ROM."
      }
 
+    # custom rule to create a shell script to execute SID
+    make {
+        <PREFIX>/runsid : <PREFIX>/include/pkgconf/hal_arm_pid.h
+	@echo "arm-elf-sid CYGTST_SID_FLAGS \$$@" > $(notdir $@).tmp
+	$(CC) -E -P -c -xc -undef -imacros $< -o $@ $(notdir $@).tmp
+	@rm $(notdir $@).tmp
+    }
+
+    cdl_option CYGTST_SID_FLAGS {
+        display "SID execution flags"
+        flavor data
+        default_value { CYGHWR_HAL_ARM_BIGENDIAN ? "--board=pid7t -EB" : "--board=pid7t -EL" }
+    }
 
     cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
         display       "Redboot HAL options"
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,20 @@
+2001-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/dbg-threads-syscall.c (dbg_thread_syscall): Don't bother to
+	deref a func ptr. The opcode could theoretically be 0x0!
+
+2001-12-04  Richard Sandiford  <rsandifo@redhat.com>
+
+	* src/generic-stub.c (__add_char_to_packet): Reverse check for
+	end of buffer and end of packet to fix potential buffer overrun.
+
+2001-12-01  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/dbg-threads-syscall.c (dbg_thread_syscall): check for
+	NULL dbg_syscall_ptr.
+
+	* cdl/hal.cdl: require CYGPKG_INFRA since all HALs do!
+
 2001-11-29  Hugo Tyson  <hmt@redhat.com>
 
 	* src/hal_stub.c: Enable HAL_STUB_HW_SEND_STOP_REASON_TEXT for
--- a/packages/hal/common/current/cdl/hal.cdl
+++ b/packages/hal/common/current/cdl/hal.cdl
@@ -57,6 +57,8 @@ cdl_package CYGPKG_HAL {
     compile       drv_api.c
     compile       -library=libextras.a dummy.c
 
+    requires      CYGPKG_INFRA
+
     make -priority 250 {
         <PREFIX>/lib/extras.o: <PREFIX>/lib/libextras.a
         $(CC) $(CFLAGS) -nostdlib -Wl,-r -Wl,--whole-archive -o $@ $<
--- a/packages/hal/common/current/src/dbg-threads-syscall.c
+++ b/packages/hal/common/current/src/dbg-threads-syscall.c
@@ -82,8 +82,8 @@ static __inline__ int dbg_thread_syscall
 				     enum dbg_syscall_ids id)
 {
   dbg_syscall_func f ; /* double indirect via */
-  if (0 ==(f = *dbg_syscall_ptr)) return 0 ; /* no pointer to vector */
-  if (0 == *f) return 0 ; /* vector not initialized */
+  if (0 == dbg_syscall_ptr) return 0; /* dbg_syscall_ptr never init'd */
+  if (0 ==(f = *dbg_syscall_ptr)) return 0 ;  /* vector not initialized */
   return (*f)(id,&tcall);
 }
 
--- a/packages/hal/common/current/src/generic-stub.c
+++ b/packages/hal/common/current/src/generic-stub.c
@@ -259,20 +259,20 @@ int
   
   if (packet->state == 1)
     {
-      if (ch == '#')
+      if (packet->length == BUFMAX)
+        {
+          packet->state = 0;
+          packet->err = 1;
+        }
+      else if (ch == '#')
         {
           packet->contents[packet->length] = 0;
           packet->state = 2;
         }
-      else
+      else 
         {
-          if (packet->length == BUFMAX) {
-              packet->state = 0;
-              packet->err = 1;
-          } else {
-              packet->checksum += ch;
-              packet->contents[packet->length++] = ch;
-          }
+          packet->checksum += ch;
+          packet->contents[packet->length++] = ch;
         }
       return 0;
     }
--- a/packages/hal/i386/arch/current/ChangeLog
+++ b/packages/hal/i386/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/i386.ld: Add .rel.text and .rel.data sections to avoid
+	linker warnings, which can cause the linker to then get confused.
+	(From nickc)
+
 2001-11-21  Mark Salter  <msalter@redhat.com>
 
 	* src/i386_stub.c (__do_read_msr): Add mem_fault handling.
--- a/packages/hal/i386/arch/current/src/i386.ld
+++ b/packages/hal/i386/arch/current/src/i386.ld
@@ -94,6 +94,8 @@ GROUP(libtarget.a libgcc.a)
 
 // Note: The __ in the name is an encoding of the .
 #define SECTION_rel__got(_region_, _vma_, _lma_)        \
+    .rel.text _vma_ : _lma_ { *(.rel.text*) } > _region_      \
+    .rel.data _vma_ : _lma_ { *(.rel.data*) } > _region_      \
     .rel.got _vma_ : _lma_                                            \
     { *(.rel.got)      }                                        \
     > _region_
--- a/packages/hal/i386/pc/current/misc/redboot_FLOPPY_D850GB.ecm
+++ b/packages/hal/i386/pc/current/misc/redboot_FLOPPY_D850GB.ecm
@@ -52,10 +52,6 @@ cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COM
     user_value 2
 };
 
-cdl_component CYGPKG_HAL_SMP_SUPPORT {
-    user_value 0
-};
-
 cdl_component CYGHWR_HAL_I386_PENTIUM {
     user_value 1
 };
--- a/packages/hal/i386/pcmb/current/ChangeLog
+++ b/packages/hal/i386/pcmb/current/ChangeLog
@@ -1,3 +1,13 @@
+2001-12-06  Nick Garnett  <nickg@redhat.com>
+
+	* include/pcmb_serial.h: 
+	* src/pcmb_serial.c:
+	Added a simple validation test for serial devices. If the status
+	register reads back all ones we decide that the device is absent
+	and mark it invalid. We test this elsewhere to avoid touching the
+	device again. This should help to cope with various problems with
+	PCs that come with only one serial port.
+
 2001-11-29  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/pcmb_screen.c: Restore sensible num lock behaviour after the
--- a/packages/hal/i386/pcmb/current/include/pcmb_serial.h
+++ b/packages/hal/i386/pcmb/current/include/pcmb_serial.h
@@ -65,6 +65,7 @@
 
 typedef struct {
     cyg_uint16  base;
+    cyg_uint16  valid;
     cyg_int32   msec_timeout;
     cyg_int32   isr_vector;
 } channel_data_t;
--- a/packages/hal/i386/pcmb/current/src/pcmb_serial.c
+++ b/packages/hal/i386/pcmb/current/src/pcmb_serial.c
@@ -143,7 +143,8 @@ static void
 cyg_hal_plf_serial_init_channel(void* __ch_data)
 {
     cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
-
+    cyg_uint8 lsr;
+    
     HAL_WRITE_UINT8(base+CYG_DEV_IER, 0);	
     HAL_WRITE_UINT8(base+CYG_DEV_IER, 0);
     HAL_WRITE_UINT8(base+CYG_DEV_MCR, 0);    
@@ -154,6 +155,12 @@ cyg_hal_plf_serial_init_channel(void* __
     // 8-1-no parity.
     HAL_WRITE_UINT8(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
 
+    // Test whether the channel is valid or not. If the status
+    // register reads back all ones, its a fair bet that it is not
+    // actually there!
+    HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
+    ((channel_data_t*)__ch_data)->valid = (lsr != 0xFF);
+    
 //    HAL_WRITE_UINT8(base+CYG_DEV_FCR, 0x07);  // Enable & clear FIFO
 }
 
@@ -164,6 +171,10 @@ cyg_hal_plf_serial_putc(void *__ch_data,
 {
     cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
     cyg_uint8 lsr;
+
+    if( !((channel_data_t*)__ch_data)->valid )
+            return;
+    
     CYGARC_HAL_SAVE_GP();
     do {
         HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
@@ -182,6 +193,9 @@ cyg_hal_plf_serial_getc_nonblock(void* _
     cyg_uint16 base = ((channel_data_t*)__ch_data)->base;
     cyg_uint8 lsr;
 
+    if( !((channel_data_t*)__ch_data)->valid )
+            return false;
+    
     HAL_READ_UINT8(base+CYG_DEV_LSR, lsr);
     if ((lsr & SIO_LSR_DR) == 0)
         return false;
@@ -197,6 +211,10 @@ cyg_uint8
 cyg_hal_plf_serial_getc(void* __ch_data)
 {
     cyg_uint8 ch;
+
+    if( !((channel_data_t*)__ch_data)->valid )
+            return '\n';
+    
     CYGARC_HAL_SAVE_GP();
 
     while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
--- a/packages/hal/mips/arch/current/ChangeLog
+++ b/packages/hal/mips/arch/current/ChangeLog
@@ -1,3 +1,23 @@
+2001-12-04  Nick Garnett  <nickg@redhat.com>
+
+	* src/hal_misc.c: Added hal_arch_program_new_stack() to support
+	running user programs on a new stack placed at the top of RAM.
+
+	* src/vectors.S: Added hal_program_new_stack function to support
+	hal_arch_program_new_stack(). This does the actual stack
+	switching.
+
+	* include/mips-stub.h (NUMREGS): 
+	* include/mips-regs.h (NUM_REGS):
+	Added test to correctly define these when the target expects the
+	CP0 registers to be reported to GDB
+
+	* include/hal_arch.h: Added support for fetching CP0 registers in
+	MIPS64 platforms for GDB. Reorganized the code slightly.
+
+	* cdl/hal_mips.cdl:
+	Added define_proc to define HAL_ARCH_PROGRAM_NEW_STACK.
+
 2001-11-16  Nick Garnett  <nickg@redhat.com>
 
 	* src/hal_misc.c (hal_msbit_index): Fixed this function so that it
--- a/packages/hal/mips/arch/current/cdl/hal_mips.cdl
+++ b/packages/hal/mips/arch/current/cdl/hal_mips.cdl
@@ -69,6 +69,10 @@ cdl_package CYGPKG_HAL_MIPS {
         @rm vectors.tmp
     }
 
+    define_proc {
+	puts $::cdl_header "#define HAL_ARCH_PROGRAM_NEW_STACK hal_arch_program_new_stack"
+    }
+
     cdl_option CYGHWR_HAL_MIPS_CPU_FREQ {
         display "CPU frequency"
         flavor  data
--- a/packages/hal/mips/arch/current/include/hal_arch.h
+++ b/packages/hal/mips/arch/current/include/hal_arch.h
@@ -247,70 +247,73 @@ CYG_MACRO_END
 #define HAL_SET_GDB_FPU_REGISTERS( _regs_ , _regval_ )
 #endif
 
-// Some variants support CP0 regs in GDB
-#if defined(CYGPKG_HAL_MIPS_MIPS32)
-#define HAL_GET_CP0_REGISTER( _regval_, _cp0_regno_, _cp0_regsel_ ) \
-{                                                                   \
-    cyg_uint32 tmp;                                                 \
-    asm volatile ("mfc0   %0,$%1,%2\nnop\n"                         \
-	           : "=r" (tmp)                                     \
-	           : "i"  (_cp0_regno_), "i"  (_cp0_regsel_)  );    \
-    _regval_ = tmp;                                                 \
-}
+// Some targets also report the state of all the coprocessor 0
+// registers to GDB. If that is the case then
+// CYGPKG_HAL_MIPS_GDB_REPORT_CP0 will be defined and the
+// HAL_[G|S]ET_CP0_REGISTER_*() macros will be defined.
 
-#define HAL_SET_CP0_REGISTER( _regval_, _cp0_regno_, _cp0_regsel_ )       \
-{                                                                         \
-    cyg_uint32 tmp = _regval_;                                            \
-    asm volatile ("mtc0   %1,$%2,%3\nnop\n"                               \
-	           : "=r" (tmp)                                           \
-	           : "r" (tmp), "i"  (_cp0_regno_), "i" (_cp0_regsel_) ); \
-}
+#ifdef CYGPKG_HAL_MIPS_GDB_REPORT_CP0
 
-#define HAL_GET_GDB_CP0_REGISTERS( _regval_ )                      \
-    HAL_GET_CP0_REGISTER( _regval_[74],   0, 0 ); /* index    */   \
-    HAL_GET_CP0_REGISTER( _regval_[75],   1, 0 ); /* random   */   \
-    HAL_GET_CP0_REGISTER( _regval_[76],   2, 0 ); /* EntryLo0 */   \
-    HAL_GET_CP0_REGISTER( _regval_[77],   3, 0 ); /* EntryLo1 */   \
-    HAL_GET_CP0_REGISTER( _regval_[78],   4, 0 ); /* context  */   \
-    HAL_GET_CP0_REGISTER( _regval_[79],   5, 0 ); /* PageMask */   \
-    HAL_GET_CP0_REGISTER( _regval_[80],   6, 0 ); /* Wired    */   \
-    HAL_GET_CP0_REGISTER( _regval_[83],   9, 0 ); /* Count    */   \
-    HAL_GET_CP0_REGISTER( _regval_[84],  10, 0 ); /* EntryHi  */   \
-    HAL_GET_CP0_REGISTER( _regval_[85],  11, 0 ); /* Compare  */   \
-    HAL_GET_CP0_REGISTER( _regval_[88],  14, 0 ); /* EPC      */   \
-    HAL_GET_CP0_REGISTER( _regval_[89],  15, 0 ); /* PRId     */   \
-    HAL_GET_CP0_REGISTER( _regval_[90],  16, 0 ); /* Config   */   \
-    HAL_GET_CP0_REGISTER( _regval_[91],  17, 0 ); /* LLAddr   */   \
-    HAL_GET_CP0_REGISTER( _regval_[92],  18, 0 ); /* WatchLo  */   \
-    HAL_GET_CP0_REGISTER( _regval_[93],  19, 0 ); /* WatchHi  */   \
-    HAL_GET_CP0_REGISTER( _regval_[97],  23, 0 ); /* Debug    */   \
-    HAL_GET_CP0_REGISTER( _regval_[98],  24, 0 ); /* DEPC     */   \
-    HAL_GET_CP0_REGISTER( _regval_[102], 28, 0 ); /* TagLo    */   \
-    HAL_GET_CP0_REGISTER( _regval_[104], 30, 0 ); /* ErrorEPC */   \
-    HAL_GET_CP0_REGISTER( _regval_[105], 31, 0 ); /* DESAVE   */   \
-    HAL_GET_CP0_REGISTER( _regval_[106], 16, 1 ); /* Config1  */
+#define HAL_GET_GDB_CP0_REGISTERS( _regval_, _regs_ )                   \
+    HAL_GET_CP0_REGISTER_32( _regval_[74],   0, 0 ); /* index    */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[75],   1, 0 ); /* random   */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[76],   2, 0 ); /* EntryLo0 */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[77],   3, 0 ); /* EntryLo1 */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[78],   4, 0 ); /* context  */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[79],   5, 0 ); /* PageMask */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[80],   6, 0 ); /* Wired    */     \
+    (_regval_)[81] = 0xC0C0C006;                                        \
+    (_regval_)[82] = (_regs_)->badvr;                /* BadVr    */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[83],   9, 0 ); /* Count    */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[84],  10, 0 ); /* EntryHi  */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[85],  11, 0 ); /* Compare  */     \
+    (_regval_)[86] = (_regs_)->sr;                   /* Status   */     \
+    (_regval_)[87] = (_regs_)->cause;                /* Cause    */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[88],  14, 0 ); /* EPC      */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[89],  15, 0 ); /* PRId     */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[90],  16, 0 ); /* Config   */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[91],  17, 0 ); /* LLAddr   */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[92],  18, 0 ); /* WatchLo  */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[93],  19, 0 ); /* WatchHi  */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[94],  20, 0 ); /* XContext */     \
+    (_regval_)[95] = 0xC0C0C021;                                        \
+    (_regval_)[96] = 0xC0C0C022;                                        \
+    HAL_GET_CP0_REGISTER_32( _regval_[97],  23, 0 ); /* Debug    */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[98],  24, 0 ); /* DEPC     */     \
+    (_regval_)[99] = 0xC0C0C025;                                        \
+    HAL_GET_CP0_REGISTER_32( _regval_[100], 26, 0 ); /* ErrCtl   */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[101], 27, 0 ); /* CacheErr */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[102], 28, 0 ); /* TagLo    */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[103], 29, 0 ); /* TagHi    */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[104], 30, 0 ); /* ErrorEPC */     \
+    HAL_GET_CP0_REGISTER_64( _regval_[105], 31, 0 ); /* DESAVE   */     \
+    HAL_GET_CP0_REGISTER_32( _regval_[106], 16, 1 ); /* Config1  */
 
-#define HAL_SET_GDB_CP0_REGISTERS( _regval_ )                      \
-    HAL_SET_CP0_REGISTER( _regval_[74],   0, 0 ); /* index    */   \
-    HAL_SET_CP0_REGISTER( _regval_[76],   2, 0 ); /* EntryLo0 */   \
-    HAL_SET_CP0_REGISTER( _regval_[77],   3, 0 ); /* EntryLo1 */   \
-    HAL_SET_CP0_REGISTER( _regval_[78],   4, 0 ); /* context  */   \
-    HAL_SET_CP0_REGISTER( _regval_[79],   5, 0 ); /* PageMask */   \
-    HAL_SET_CP0_REGISTER( _regval_[80],   6, 0 ); /* Wired    */   \
-    HAL_SET_CP0_REGISTER( _regval_[83],   9, 0 ); /* Count    */   \
-    HAL_SET_CP0_REGISTER( _regval_[84],  10, 0 ); /* EntryHi  */   \
-    HAL_SET_CP0_REGISTER( _regval_[85],  11, 0 ); /* Compare  */   \
-    HAL_SET_CP0_REGISTER( _regval_[90],  16, 0 ); /* Config   */   \
-    HAL_SET_CP0_REGISTER( _regval_[92],  18, 0 ); /* WatchLo  */   \
-    HAL_SET_CP0_REGISTER( _regval_[93],  19, 0 ); /* WatchHi  */   \
-    HAL_SET_CP0_REGISTER( _regval_[97],  23, 0 ); /* Debug    */   \
-    HAL_SET_CP0_REGISTER( _regval_[98],  24, 0 ); /* DEPC     */   \
-    HAL_SET_CP0_REGISTER( _regval_[102], 28, 0 ); /* TagLo    */   \
-    HAL_SET_CP0_REGISTER( _regval_[105], 31, 0 ); /* DESAVE   */
+#define HAL_SET_GDB_CP0_REGISTERS( _regval_, _regs_ )                   \
+    HAL_SET_CP0_REGISTER_32( _regval_[74],   0, 0 ); /* index    */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[76],   2, 0 ); /* EntryLo0 */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[77],   3, 0 ); /* EntryLo1 */     \
+    HAL_SET_CP0_REGISTER_64( _regval_[78],   4, 0 ); /* context  */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[79],   5, 0 ); /* PageMask */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[80],   6, 0 ); /* Wired    */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[83],   9, 0 ); /* Count    */     \
+    HAL_SET_CP0_REGISTER_64( _regval_[84],  10, 0 ); /* EntryHi  */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[85],  11, 0 ); /* Compare  */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[90],  16, 0 ); /* Config   */     \
+    HAL_SET_CP0_REGISTER_64( _regval_[92],  18, 0 ); /* WatchLo  */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[93],  19, 0 ); /* WatchHi  */     \
+    HAL_SET_CP0_REGISTER_64( _regval_[94],  20, 0 ); /* XContext */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[97],  23, 0 ); /* Debug    */     \
+    HAL_SET_CP0_REGISTER_64( _regval_[98],  24, 0 ); /* DEPC     */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[100], 26, 0 ); /* ErrCtl   */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[101], 27, 0 ); /* CacheErr */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[102], 28, 0 ); /* TagLo    */     \
+    HAL_SET_CP0_REGISTER_32( _regval_[103], 29, 0 ); /* TagHi    */     \
+    HAL_SET_CP0_REGISTER_64( _regval_[105], 31, 0 ); /* DESAVE   */
 
 #else
-#define HAL_GET_GDB_CP0_REGISTERS( _regval_ )
-#define HAL_SET_GDB_CP0_REGISTERS( _regval_ )
+#define HAL_GET_GDB_CP0_REGISTERS( _regval_, _regs_ )
+#define HAL_SET_GDB_CP0_REGISTERS( _regval_, _regs_ )
 #endif
 
 // Copy a set of registers from a HAL_SavedRegisters structure into a
@@ -332,7 +335,7 @@ CYG_MACRO_END
     _regval_[36] = (_regs_)->cause;                             \
     _regval_[37] = (_regs_)->pc;                                \
                                                                 \
-    HAL_GET_GDB_CP0_REGISTERS( _regval_ );                      \
+    HAL_GET_GDB_CP0_REGISTERS( _regval_, _regs_ );              \
 }
 
 // Copy a GDB ordered array into a HAL_SavedRegisters structure.
@@ -353,7 +356,7 @@ CYG_MACRO_END
     (_regs_)->cause = _regval_[36];                             \
     (_regs_)->pc = _regval_[37];                                \
                                                                 \
-    HAL_SET_GDB_CP0_REGISTERS( _regval_ );                      \
+    HAL_SET_GDB_CP0_REGISTERS( _regval_, _regs_ );              \
 }
 
 //--------------------------------------------------------------------------
--- a/packages/hal/mips/arch/current/include/mips-regs.h
+++ b/packages/hal/mips/arch/current/include/mips-regs.h
@@ -50,7 +50,11 @@
 
 /* This value must agree with NUMREGS in mips-stub.h. */
 
-#define NUM_REGS 90
+#if defined(CYGPKG_HAL_MIPS_GDB_REPORT_CP0)
+#define NUM_REGS   107
+#else
+#define NUM_REGS    90
+#endif
 
 #ifdef __mips64
   #define REG_SIZE 8
--- a/packages/hal/mips/arch/current/include/mips-stub.h
+++ b/packages/hal/mips/arch/current/include/mips-stub.h
@@ -54,7 +54,7 @@
 extern "C" {
 #endif
 
-#if defined(CYGPKG_HAL_MIPS_MIPS32)
+#if defined(CYGPKG_HAL_MIPS_GDB_REPORT_CP0)
 #define NUMREGS   107
 #else
 #define NUMREGS    90
--- a/packages/hal/mips/arch/current/src/hal_misc.c
+++ b/packages/hal/mips/arch/current/src/hal_misc.c
@@ -57,6 +57,8 @@
 #include <cyg/hal/hal_if.h>             // hal_ctrlc_isr()
 #include <cyg/hal/mips-regs.h>          // FPU cause register definitions
 
+#include CYGHWR_MEMORY_LAYOUT_H
+
 /*------------------------------------------------------------------------*/
 /* If required, define a variable to store the clock period.              */
 
@@ -376,6 +378,15 @@ hal_delay_us(int us)
 }
 
 /*------------------------------------------------------------------------*/
+
+void hal_arch_program_new_stack(void *_func)
+{
+    externC void hal_program_new_stack( void *func, CYG_ADDRESS addr);
+    hal_program_new_stack( (void *)_func,
+                   (CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS)) & ~15 );
+}
+
+/*------------------------------------------------------------------------*/
 /* Idle thread action                                                     */
 
 #include <cyg/infra/diag.h>
--- a/packages/hal/mips/arch/current/src/vectors.S
+++ b/packages/hal/mips/arch/current/src/vectors.S
@@ -819,6 +819,33 @@ FUNC_START(__gccmain)
 FUNC_END(__gccmain)
 
 ##-----------------------------------------------------------------------------
+## Switch to a new stack.
+## This is used in RedBoot to allow code to execute in a different
+## stack context.
+
+FUNC_START(hal_program_new_stack)
+	# Arguments are:
+	# a0 = function to call
+	# a1 = stack pointer to use
+
+	move	v1,sp				# v1 = original stack ptr
+	move	sp,a1				# sp = new stack
+	addi	sp,sp,-32			# make a null frame
+	sva	v1,8(sp)			# save old sp
+	sva	ra,16(sp)			# save old ra
+
+	jalr	a0				# call function
+	 nop
+
+	lva	ra,16(sp)			# restore ra
+	lva	sp,8(sp)			# restore sp
+
+	jr	ra				# go back
+	 nop					# delay slot
+	
+FUNC_END(hal_program_new_stack)
+		
+##-----------------------------------------------------------------------------
 ## hal_zero_bss
 ## Zero bss. Done in assembler to be optimal rather than using memset,
 ## which would risk zeroing bss while using it.
--- a/packages/hal/mips/mips32/current/ChangeLog
+++ b/packages/hal/mips/mips32/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-12-04  Nick Garnett  <nickg@redhat.com>
+
+	* include/var_arch.h: Added macros to read/write CP0 registers.
+
+	* cdl/hal_mips_mips32.cdl: Added CYGPKG_HAL_MIPS_GDB_REPORT_CP0
+	option to enable reporting of CP0 registers to GDB.
+
 2001-03-21  Jesper Skov  <jskov@redhat.com>
 
 	* src/mips_mips32.ld: Added .2ram pattern.
--- a/packages/hal/mips/mips32/current/cdl/hal_mips_mips32.cdl
+++ b/packages/hal/mips/mips32/current/cdl/hal_mips_mips32.cdl
@@ -72,6 +72,11 @@ cdl_package CYGPKG_HAL_MIPS_MIPS32 {
         calculated 1
     }
 
+    cdl_option CYGPKG_HAL_MIPS_GDB_REPORT_CP0 {
+	display "Report contents of CP0 to GDB"
+	calculated 1
+    }
+    
     define_proc {
         puts $::cdl_header "#include <pkgconf/hal_mips.h>"
     }
--- a/packages/hal/mips/mips32/current/include/var_arch.h
+++ b/packages/hal/mips/mips32/current/include/var_arch.h
@@ -51,6 +51,33 @@
 #include <cyg/infra/cyg_type.h>
 #endif
 
+//--------------------------------------------------------------------------
+// Define macros for accessing CP0 registers
+
+#define HAL_GET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )  \
+{                                                                       \
+    cyg_uint32 tmp;                                                     \
+    asm volatile ("mfc0   %0,$%1,%2\nnop\n"                             \
+	           : "=r" (tmp)                                         \
+	           : "i"  (_cp0_regno_), "i"  (_cp0_regsel_)  );        \
+    _regval_ = tmp;                                                     \
+}
+
+#define HAL_SET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )          \
+{                                                                               \
+    cyg_uint32 tmp = _regval_;                                                  \
+    asm volatile ("mtc0   %1,$%2,%3\nnop\n"                                     \
+	           : "=r" (tmp)                                                 \
+	           : "r" (tmp), "i"  (_cp0_regno_), "i" (_cp0_regsel_) );       \
+}
+
+#define HAL_GET_CP0_REGISTER_64( _regval_, _cp0_regno_, _cp0_regsel_ ) \
+        HAL_GET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )
+#define HAL_SET_CP0_REGISTER_64( _regval_, _cp0_regno_, _cp0_regsel_ ) \
+        HAL_SET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )
+
+//--------------------------------------------------------------------------
+
 #ifdef CYGSEM_HAL_USE_ROM_MONITOR_CygMon
 externC int
 hal_diag_irq_check(int vector);
@@ -61,6 +88,8 @@ CYG_MACRO_START                         
 CYG_MACRO_END
 #endif
 
+//--------------------------------------------------------------------------
+
 #ifdef CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
 /* System Control Coprocessor (CP0) exception processing registers */
 /* These supplement the definitions in mips-regs.h */
--- a/packages/hal/mips/mips64/current/ChangeLog
+++ b/packages/hal/mips/mips64/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-12-04  Nick Garnett  <nickg@redhat.com>
+
+	* include/var_arch.h: Added macros to read/write CP0 registers.
+
+	* cdl/hal_mips_mips64.cdl: Added CYGPKG_HAL_MIPS_GDB_REPORT_CP0
+	option to enable reporting of CP0 registers to GDB.
+
 2001-11-06  Mark Salter  <msalter@redhat.com>
 
 	* src/mips_mips64.ld: Add .2ram section.
--- a/packages/hal/mips/mips64/current/cdl/hal_mips_mips64.cdl
+++ b/packages/hal/mips/mips64/current/cdl/hal_mips_mips64.cdl
@@ -82,6 +82,11 @@ cdl_package CYGPKG_HAL_MIPS_MIPS64 {
         calculated 1
     }
 
+    cdl_option CYGPKG_HAL_MIPS_GDB_REPORT_CP0 {
+	display "Report contents of CP0 to GDB"
+	calculated 1
+    }
+
     define_proc {
         puts $::cdl_header "#include <pkgconf/hal_mips.h>"
     }
--- a/packages/hal/mips/mips64/current/include/var_arch.h
+++ b/packages/hal/mips/mips64/current/include/var_arch.h
@@ -57,6 +57,44 @@
 #define CYG_HAL_GDB_REG CYG_WORD64
 
 //--------------------------------------------------------------------------
+// define macros for accessing CP0 registers
+
+#define HAL_GET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )  \
+{                                                                       \
+    cyg_uint32 tmp;                                                     \
+    asm volatile ("mfc0   %0,$%1,%2\nnop;nop;nop\n"                     \
+	           : "=r" (tmp)                                         \
+	           : "i"  (_cp0_regno_), "i"  (_cp0_regsel_)  );        \
+    _regval_ = tmp;                                                     \
+}
+
+#define HAL_SET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )          \
+{                                                                               \
+    cyg_uint32 tmp = _regval_;                                                  \
+    asm volatile ("mtc0   %1,$%2,%3\nnop\n"                                     \
+	           : "=r" (tmp)                                                 \
+	           : "r" (tmp), "i"  (_cp0_regno_), "i" (_cp0_regsel_) );       \
+}
+
+#define HAL_GET_CP0_REGISTER_64( _regval_, _cp0_regno_, _cp0_regsel_ )  \
+{                                                                       \
+    cyg_uint64 tmp;                                                     \
+    asm volatile ("dmfc0   %0,$%1,%2\nnop\n"                            \
+	           : "=r" (tmp)                                         \
+	           : "i"  (_cp0_regno_), "i"  (_cp0_regsel_)  );        \
+    _regval_ = tmp;                                                     \
+}
+
+#define HAL_SET_CP0_REGISTER_64( _regval_, _cp0_regno_, _cp0_regsel_ )          \
+{                                                                               \
+    cyg_uint64 tmp = _regval_;                                                  \
+    asm volatile ("dmtc0   %1,$%2,%3\nnop\n"                                    \
+	           : "=r" (tmp)                                                 \
+	           : "r" (tmp), "i"  (_cp0_regno_), "i" (_cp0_regsel_) );       \
+}
+
+
+//--------------------------------------------------------------------------
 
 #ifdef CYGSEM_HAL_USE_ROM_MONITOR_CygMon
 externC int
--- a/packages/hal/mips/vr4300/current/ChangeLog
+++ b/packages/hal/mips/vr4300/current/ChangeLog
@@ -1,3 +1,12 @@
+2001-12-05  Nick Garnett  <nickg@redhat.com>
+
+	* include/variant.inc: Add ifdef around cache clearing code to
+	only do this in non-RAM-startup configurations. If this is done in
+	a RAM-startup configuration, it can play merry havoc with the
+	state of things like RedBoot's network stack.
+	We now assume, for RAM applications, that our loader has
+	initialized the cache.
+
 2001-10-12  Nick Garnett  <nickg@redhat.com>
 
 	* src/mips_vr4300.ld (SECTION_rom_vectors): Updated this section
--- a/packages/hal/mips/vr4300/current/include/variant.inc
+++ b/packages/hal/mips/vr4300/current/include/variant.inc
@@ -89,6 +89,8 @@
 
 	.macro	hal_cache_init
 
+#ifndef CYG_HAL_STARTUP_RAM
+
 	mfc0	v0,config0		# disable Kseg0 caching in config0 register
 	nop
 	nop
@@ -134,6 +136,7 @@ 1:
         nop                             # delay slot
 
         .set mips0                      # reset ISA to default
+#endif
 
 	.endm
 
--- a/packages/infra/current/ChangeLog
+++ b/packages/infra/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-06  Jesper Skov  <jskov@redhat.com>
+
+	* src/diag.cxx: Added functions to do memory dump in 16 and 32 bit
+	units. Based on changes from Warren Jasper <warrenj@bops.com>.
+	* include/diag.h: Function declarations.
+	
 2001-09-12  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/eprintf.c (__eprintf): Tolerate absence of standard ISO C
--- a/packages/infra/current/include/diag.h
+++ b/packages/infra/current/include/diag.h
@@ -63,10 +63,20 @@ 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);
+externC void diag_dump_buf_32bit(void *buf, CYG_ADDRWORD len);
+externC void diag_dump_buf_16bit(void *buf, CYG_ADDRWORD len);
 externC void diag_dump_buf_with_offset(cyg_uint8     *p, 
                                        CYG_ADDRWORD   s, 
                                        cyg_uint8     *base);
 
+externC void diag_dump_buf_with_offset_32bit(cyg_uint32 *p, 
+                                             CYG_ADDRWORD     s, 
+                                             cyg_uint32      *base);
+
+externC void diag_dump_buf_with_offset_16bit(cyg_uint16 *p, 
+                                             CYG_ADDRWORD     s, 
+                                             cyg_uint16      *base);
+
 externC int  diag_printf( const char *fmt, ... );  /* Formatted print      */
 
 externC void diag_init_putc(void (*putc)(char c, void **param));
--- a/packages/infra/current/src/diag.cxx
+++ b/packages/infra/current/src/diag.cxx
@@ -568,12 +568,11 @@ diag_dump_buf_with_offset(cyg_uint8     
         }
         for (i = 0;  i < 16;  i++) {
             if (i < (int)s) {
-                diag_printf("%02X", p[i] & 0xFF);
+                diag_printf("%02X ", p[i] & 0xFF);
             } else {
                 diag_printf("  ");
             }
-            if ((i % 2) == 1) diag_printf(" ");
-            if ((i % 8) == 7) diag_printf(" ");
+	    if (i == 7) diag_printf(" ");
         }
         diag_printf(" |");
         for (i = 0;  i < 16;  i++) {
@@ -597,5 +596,74 @@ diag_dump_buf(void *p, CYG_ADDRWORD s)
    diag_dump_buf_with_offset((cyg_uint8 *)p, s, 0);
 }
 
+void
+diag_dump_buf_with_offset_32bit(cyg_uint32   *p, 
+				CYG_ADDRWORD  s, 
+				cyg_uint32   *base)
+{
+    int i;
+    if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) {
+        s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p;
+    }
+    while ((int)s > 0) {
+        if (base) {
+            diag_printf("%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
+        } else {
+            diag_printf("%08X: ", p);
+        }
+        for (i = 0;  i < 4;  i++) {
+            if (i < (int)s/4) {
+                diag_printf("%08X ", p[i] );
+            } else {
+                diag_printf("         ");
+            }
+        }
+        diag_printf("\n");
+        s -= 16;
+        p += 4;
+    }
+}
+
+externC void
+diag_dump_buf_32bit(void *p, CYG_ADDRWORD s)
+{
+   diag_dump_buf_with_offset_32bit((cyg_uint32 *)p, s, 0);
+}
+
+void
+diag_dump_buf_with_offset_16bit(cyg_uint16   *p, 
+				CYG_ADDRWORD  s, 
+				cyg_uint16   *base)
+{
+    int i;
+    if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) {
+        s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p;
+    }
+    while ((int)s > 0) {
+        if (base) {
+            diag_printf("%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
+        } else {
+            diag_printf("%08X: ", p);
+        }
+        for (i = 0;  i < 8;  i++) {
+            if (i < (int)s/2) {
+	      diag_printf("%04X ", p[i] );
+	      if (i == 3) diag_printf(" ");
+            } else {
+	      diag_printf("     ");
+            }
+        }
+        diag_printf("\n");
+        s -= 16;
+        p += 8;
+    }
+}
+
+externC void
+diag_dump_buf_16bit(void *p, CYG_ADDRWORD s)
+{
+   diag_dump_buf_with_offset_16bit((cyg_uint16 *)p, s, 0);
+}
+
 /*-----------------------------------------------------------------------*/
 /* EOF infra/diag.c */
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-12-04  Richard Sandiford  <rsandifo@redhat.com>
+
+	* src/stand_alone/eth_drv.c (eth_drv_read): Check that the return
+	buffer is big enough to hold the packet.
+
 2001-11-28  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* doc/driver_doc: Mention preferences on how the ESA should be set.
--- a/packages/io/eth/current/src/stand_alone/eth_drv.c
+++ b/packages/io/eth/current/src/stand_alone/eth_drv.c
@@ -346,13 +346,15 @@ eth_drv_read(char *eth_hdr, char *buf, i
     }
     (sc->funs->poll)(sc);  // Give the driver a chance to fetch packets
     msg = eth_drv_msg_get(&eth_msg_full);
-    if (msg) {
+    if (msg && len >= msg->len - 14) {
         memcpy(eth_hdr, msg->data, 14);
         memcpy(buf, &msg->data[14], msg->len-14);
-        eth_drv_msg_put(&eth_msg_free, msg);
         res = msg->len;
     } else {
-        res = 0;  // No packets available
+        res = 0;
+    }
+    if (msg) {
+        eth_drv_msg_put(&eth_msg_free, msg);
     }
    
     if (dbg) {
--- a/packages/isoinfra/current/ChangeLog
+++ b/packages/isoinfra/current/ChangeLog
@@ -1,3 +1,15 @@
+2001-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* include/netdb.h (gethostbyname): anonymous arguments aren't allowed
+	in C (I thought they were a GNU C extension, sigh).
+
+2001-11-30  Jonathan Larmour  <jlarmour@redhat.com>
+2001-11-30  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/netdb.h: Provide a default NULL implementation of
+	struct hostent, gethostbyname and gethostbyaddr if a real implementation
+	doesn't exist. This makes life easier for legacy code.
+
 2001-10-17  Jesper Skov  <jskov@redhat.com>
 
 	* cdl/isoinfra.cdl: Changed string interfaces to flavor booldata.
--- a/packages/isoinfra/current/include/netdb.h
+++ b/packages/isoinfra/current/include/netdb.h
@@ -52,7 +52,34 @@
 # ifdef CYGBLD_ISO_DNS_HEADER
 #  include CYGBLD_ISO_DNS_HEADER
 # endif
-#endif
+#else
+
+/* Provide dummy entries so that legacy code that relies on the presence
+  of these types/functions still works. */
+
+/* Host name / IP mapping fallback when not using a real DNS implementation */
+struct hostent {
+  char    *h_name;        /* official name of host */
+  char    **h_aliases;    /* alias list */
+  int     h_addrtype;     /* host address type */
+  int     h_length;       /* length of address */
+  char    **h_addr_list;  /* list of addresses */
+};
+#define h_addr  h_addr_list[0]  /* for backward compatibility */
+
+static inline struct hostent *
+gethostbyname( const char *__host )
+{
+  return NULL;
+}
+
+static inline struct hostent *
+gethostbyaddr( const char * __addr, int __len, int __type )
+{
+  return NULL;
+}
+
+#endif /* ifdef CYGINT_ISO_DNS */
 
 #ifdef CYGINT_ISO_NETDB_PROTO
 # ifdef CYGBLD_ISO_NETDB_PROTO_HEADER
--- a/packages/language/c/libc/stdio/current/ChangeLog
+++ b/packages/language/c/libc/stdio/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/common/fflush.cxx (cyg_libc_stdio_flush_all_but): Fix starvation
+	problem when waiting for threads to unlock of lower priority.
+	Fix for bug #57014.
+
 2001-11-23  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/stdio.cdl: Add dependency on stdlib string conversion functions
--- a/packages/language/c/libc/stdio/current/src/common/fflush.cxx
+++ b/packages/language/c/libc/stdio/current/src/common/fflush.cxx
@@ -63,14 +63,14 @@ externC Cyg_ErrNo
 cyg_libc_stdio_flush_all_but( Cyg_StdioStream *not_this_stream )
 {
     cyg_bool files_flushed[FOPEN_MAX] = { false }; // sets all to 0
-    cyg_bool loop_again;
+    cyg_bool loop_again, looped = false;
     cyg_ucount32 i;
     Cyg_ErrNo err=ENOERR;
     Cyg_StdioStream *stream;
 
     do {
         loop_again = false;
-        
+
         for (i=0; (i<FOPEN_MAX) && !err; i++) {
             if (files_flushed[i] == false) {
                 
@@ -90,14 +90,23 @@ cyg_libc_stdio_flush_all_but( Cyg_StdioS
                     // only buffers which we've written to need flushing
                     if ( !stream->flags.last_buffer_op_was_read)
 #endif
-		      {
-                        if ( stream->trylock_me() ) {
+                    {
+                        // we try to flush the first time through so that
+                        // everything is flushed that can be flushed.
+                        // The second time through we should just wait
+                        // in case some other lowerpri thread has locked the
+                        // stream, otherwise we will spin needlessly and
+                        // never let the lower pri thread run!
+                        if ( (looped && stream->lock_me()) || 
+                             stream->trylock_me() ) {
                             err = stream->flush_output_unlocked();
                             stream->unlock_me();
                             files_flushed[i] = true;
                         } // if
-                        else
+                        else {
                             loop_again = true;
+                            looped = true;
+                        }
                     }
                 } // else
             } // if
--- a/packages/net/ftpclient/current/ChangeLog
+++ b/packages/net/ftpclient/current/ChangeLog
@@ -1,4 +1,8 @@
-2001-11-4  Andrew Lunn  <andrew.lunn@ascom.ch>
+2001-12-04  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* src/ftpclient.c: Allow it to compile!
+
+2001-11-04  Andrew Lunn  <andrew.lunn@ascom.ch>
 	
 	* First version. Implements an FTP client which can get and put 
 	  files on a server. 
--- a/packages/net/ftpclient/current/src/ftpclient.c
+++ b/packages/net/ftpclient/current/src/ftpclient.c
@@ -41,6 +41,8 @@
 //
 //==========================================================================
 
+#include <pkgconf/system.h>
+
 #include <network.h>
 #include <stdio.h>
 #include <sys/socket.h>
@@ -186,8 +188,10 @@ connect_to_server(char *hostname,
                   ftp_printf_t ftp_printf) 
 { 
   struct sockaddr_in host; 
-  struct servent *sent; 
-  struct hostent *hp; 
+  struct servent *sent;
+#ifdef CYGPKG_NS_DNS   
+  struct hostent *hp=NULL; 
+#endif
   int s, len;
 
   s = socket(AF_INET, SOCK_STREAM, 0);
@@ -202,13 +206,17 @@ connect_to_server(char *hostname,
     close(s);
     return FTP_BAD;
   }
-  
+
+#ifdef CYGPKG_NS_DNS  
   hp = gethostbyname(hostname);
-  
+
+
   if (hp) {           /* try name first */
     host.sin_family = hp->h_addrtype;
     bcopy(hp->h_addr, &host.sin_addr, hp->h_length);
-  } else {			/* maybe it's a numeric address ?*/
+  } else 
+#endif
+    {			/* maybe it's a numeric address ?*/
     host.sin_family = AF_INET;
     
     if (inet_aton(hostname,&host.sin_addr) == 0)  { 
@@ -649,31 +657,13 @@ output device for outputting error and d
 function take one addition parameter to the normal printf function. The
 first parameter indicates when the message is an error message when
 true. This can be used to filter errors from diagnostic output. In
-this example the error parameter is ignored and everything printed.
-
-The diag_vprintf() function does not use varargs, so we have to do the
-hard work ourselves of unpacking the stack and passing an array of
-pointers*/
-
-externC void diag_vprintf( const char *fmt, CYG_ADDRWORD *args);
+this example the error parameter is ignored and everything printed. */
 
 void ftpclient_printf(unsigned error, const char *fmt, ...) 
 {
   va_list ap;
-  CYG_ADDRWORD args[8];
   
   va_start(ap, fmt);
-
-  args[0] = va_arg(ap,CYG_ADDRWORD);
-  args[1] = va_arg(ap,CYG_ADDRWORD);
-  args[2] = va_arg(ap,CYG_ADDRWORD);
-  args[3] = va_arg(ap,CYG_ADDRWORD);
-  args[4] = va_arg(ap,CYG_ADDRWORD);
-  args[5] = va_arg(ap,CYG_ADDRWORD);
-  args[6] = va_arg(ap,CYG_ADDRWORD);
-  args[7] = va_arg(ap,CYG_ADDRWORD);
-  
-  diag_vprintf( fmt, args);
-
+  diag_vprintf( fmt, ap);
   va_end(ap);
 }
--- a/packages/net/snmp/agent/current/ChangeLog
+++ b/packages/net/snmp/agent/current/ChangeLog
@@ -1,3 +1,13 @@
+2001-11-21  Hugo Tyson  <hmt@redhat.com>
+
+	* src/snmpd.c (snmpd): Explicit execution-time initialization of
+	"running" variable, so that we can restart snmpd without it
+	immediately exiting again.
+
+	* src/snmptask.c (snmpdloop): Make the snmpd thread loop forever,
+	so that we can restart it when the state of all the interfaces
+	changes.
+
 2001-08-14  Gary Thomas  <gthomas@redhat.com>
 
 	* tests/snmpping.c: 
--- a/packages/net/snmp/agent/current/src/snmpd.c
+++ b/packages/net/snmp/agent/current/src/snmpd.c
@@ -622,6 +622,11 @@ void snmpd( void )    {
 #define stderr_log 1
 #endif
 
+    // ---------
+    // En-bloc reinitialization of statics.
+    running = 1;
+    // ---------
+
     SOCK_STARTUP;
     init_agent("snmpd");		/* do what we need to do first. */
     init_mib_modules();
--- a/packages/net/snmp/agent/current/src/snmptask.c
+++ b/packages/net/snmp/agent/current/src/snmptask.c
@@ -166,6 +166,13 @@ static cyg_handle_t netsnmp_thread_handl
 
 externC void snmpd( void );
 
+static void
+snmpdloop( void )
+{
+    while ( 1 )
+        snmpd();
+} 
+
 // Network initialization
 //   This function is called during system initialization to setup the whole
 // networking environment.
@@ -177,7 +184,7 @@ cyg_net_snmp_init(void)
 
     // Create network background thread
     cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+1, // Priority, just lower than the net
-                      snmpd,                    // entry
+                      snmpdloop,                // entry
                       0,                        // entry parameter
                       "snmpd",                  // Name
                       &netsnmp_stack[0],        // Stack
--- a/packages/net/tcpip/current/ChangeLog
+++ b/packages/net/tcpip/current/ChangeLog
@@ -1,3 +1,54 @@
+2001-12-06  Hugo Tyson  <hmt@redhat.com>
+
+	* src/lib/bootp_support.c (init_net): Just re-tabbed and checked
+	the addition to initialize DNS from DHCP info - it had already
+	snuck into the file in the previous change from Andrew.  Include
+	of netdb.h added also, from the patch in Bug 57019.  Also check
+	CYGINT_ISO_DNS for the setup code instead of CYGPKG_ISO_DNS.
+
+2001-12-04  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/lib/bootp_support.c: Check CYGINT_ISO_DNS (from
+	<pkgconf/isoinfra.h>) instead of CYGPKG_ISO_DNS.
+
+2001-12-03   Andrew Lunn  <Andrew.Lunn@ascom.ch>
+
+	* src/lib/bootp_support.c: get_bootp_option(): Take the
+	max length of data we want out of the bootp record.
+	* src/lib/dhcp_prot.c: Pass the length we expect for an option.
+
+2001-08-16  Anssi Pulkkinen <Anssi.Pulkkinen@ascom.ch>
+
+	* src/lib/dhcp_prot.c: Make sure we use the newly calculated xid.
+	
+2001-08-02  Anand Srivastava <Anand.Srivastava@ascom.ch>
+
+        * src/lib/dhcp_prot.c do_dhcp: ID calculation must be done only
+	once. moved it out the loop. 	
+	
+2001-11-21  Hugo Tyson  <hmt@redhat.com>
+
+	* src/lib/dhcp_support.c (dhcp_mgt_entry): If we have an
+	SNMPAGENT, must recycle it whenever we reinitialize all
+	interfaces; call SnmpdShutDown() to cause this.
+	Also re-initialize all loopback interfaces here too.	
+
+2001-11-30  Hugo Tyson  <hmt@redhat.com>
+
+	* src/lib/dhcp_prot.c (set_default_dhcp_tags): New routine to
+	insert all the extra woffle we need neatly each time, keeping the
+	state machine's case arms to the real work.  The new thing this
+	sets is TAG_DHCP_PARM_REQ_LIST, with a list that matches the
+	default set we get from a LINUX dhcpd.  This is because M$ servers
+	need explicit requests for eg. TAG_GATEWAY.  Note that I have
+	included configuration to override the set of tags requested here
+	in the source, but not yet backed up by CDL - we'll see whether
+	anyone needs this.
+	(set_variable_tag): New routine to insert a variable pointed-to
+	data item rather than an int of 1,2 or 4 bytes.
+	(do_dhcp): Call set_default_dhcp_tags() every time we send a
+	packet, rather than ad hoc additions in each state.
+
 2001-11-29  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* include/machine/ansi.h: No longer require BSD string function
--- a/packages/net/tcpip/current/include/bootp.h
+++ b/packages/net/tcpip/current/include/bootp.h
@@ -111,6 +111,8 @@ SOFTWARE.
 #define BP_MINPKTSZ	300	/* to check sizeof(struct bootp) */
 #endif
 
+#define BP_MAX_OPTION_LEN 256
+
 struct bootp {
     unsigned char    bp_op;			/* packet opcode type */
     unsigned char    bp_htype;			/* hardware addr type */
@@ -369,7 +371,7 @@ build_bootp_record(struct bootp *bp,
 __externC void show_bootp(const char *interface, struct bootp *res);
 
 // Interrogate a bootp record for a particular option
-__externC cyg_bool_t get_bootp_option(struct bootp *bp, unsigned char tag, void *res);
+__externC cyg_bool_t get_bootp_option(struct bootp *bp, unsigned char tag, void *res, unsigned int * length);
 
 // ------------------------------------------------------------------------
 // This isn't exactly the right place for this since bootp is not involved
--- a/packages/net/tcpip/current/src/lib/bootp_support.c
+++ b/packages/net/tcpip/current/src/lib/bootp_support.c
@@ -56,9 +56,14 @@
 
 #include <pkgconf/system.h>
 #include <pkgconf/net.h>
+#include <pkgconf/isoinfra.h>
 
 #include <network.h>
 
+#ifdef CYGINT_ISO_DNS
+#include <netdb.h>
+#endif
+
 #ifndef CYGPKG_LIBC_STDIO
 #define perror(s) diag_printf(#s ": %s\n", strerror(errno))
 #endif
@@ -248,6 +253,8 @@ show_bootp(const char *intf, struct boot
     unsigned char *op, *ap = 0, optover;
     unsigned char name[128];
     struct in_addr addr[32];
+    unsigned int length;
+    
     diag_printf("BOOTP[%s] op: %s\n", intf, _bootp_op[bp->bp_op]);
     diag_printf("       htype: %s\n", _bootp_hw_type[bp->bp_htype]);
     diag_printf("        hlen: %d\n", bp->bp_hlen );
@@ -267,7 +274,8 @@ show_bootp(const char *intf, struct boot
     diag_printf("    gateway IP: %s\n", inet_ntoa(bp->bp_giaddr));
 
     optover = 0; // See whether sname and file are overridden for options
-    (void)get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover );
+    length = sizeof(optover);
+    (void)get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover, &length );
     if ( !(1 & optover) && bp->bp_sname[0] )
         diag_printf("        server: %s\n", bp->bp_sname);
     if ( ! (2 & optover) && bp->bp_file[0] )
@@ -362,19 +370,23 @@ show_bootp(const char *intf, struct boot
 }
 
 cyg_bool_t
-get_bootp_option(struct bootp *bp, unsigned char tag, void *opt)
+get_bootp_option(struct bootp *bp, unsigned char tag, void *opt, 
+                 unsigned int *length)
 {
     unsigned char *val = (unsigned char *)opt;
     int i;
     cyg_uint8 optover;
-
+    
 #define SCANTAG( ptr ) CYG_MACRO_START          \
+    unsigned int max;                           \
     unsigned char *op = (ptr);                  \
     while (*op != TAG_END) {                    \
         if (*op == tag) {                       \
-            for (i = 0;  i < *(op+1);  i++) {   \
+            max=(*(op+1)>*length ? *length : *(op+1)); \
+            for (i = 0;  i < max;  i++) {       \
                 *val++ = *(op+i+2);             \
             }                                   \
+            *length=max;                        \
             return true;                        \
         }                                       \
         op += *(op+1)+2;                        \
@@ -387,7 +399,7 @@ CYG_MACRO_END
         return false;
     // else, look for that tag to see if there's more...
     optover = 0;
-    if ( ! get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover ) )
+    if ( ! get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover, length) )
         return false;
 
     if ( 1 & optover ) // then the file field also holds options
@@ -409,6 +421,8 @@ init_net(const char *intf, struct bootp 
     int one = 1;
     struct ecos_rtentry route;
     struct in_addr netmask, gateway;
+    unsigned int length;
+
 
     s = socket(AF_INET, SOCK_DGRAM, 0);
     if (s < 0) {
@@ -436,7 +450,8 @@ init_net(const char *intf, struct bootp 
         return false;
     }
 
-    if (get_bootp_option(bp, TAG_SUBNET_MASK, &addrp->sin_addr)) {
+    length = sizeof(addrp->sin_addr);
+    if (get_bootp_option(bp, TAG_SUBNET_MASK, &addrp->sin_addr,&length)) {
         netmask = addrp->sin_addr;
         if (ioctl(s, SIOCSIFNETMASK, &ifr)) {
             perror("SIOCSIFNETMASK");
@@ -451,7 +466,8 @@ init_net(const char *intf, struct bootp 
         }
     }
 
-    if (get_bootp_option(bp, TAG_IP_BROADCAST, &addrp->sin_addr)) {
+    length = sizeof(addrp->sin_addr);    
+    if (get_bootp_option(bp, TAG_IP_BROADCAST, &addrp->sin_addr,&length)) {
         if (ioctl(s, SIOCSIFBRDADDR, &ifr)) {
             perror("SIOCSIFBRDADDR");
             return false;
@@ -467,7 +483,8 @@ init_net(const char *intf, struct bootp 
     }
 
     // Set up routing
-    if (get_bootp_option(bp, TAG_GATEWAY, &gateway)) {
+    length = sizeof(addrp->sin_addr);
+    if (get_bootp_option(bp, TAG_GATEWAY, &gateway,&length)) {
         // ...and it's a nonzero address...
         if ( 0 != gateway.s_addr ) {
             memset(&route, 0, sizeof(route));
@@ -499,6 +516,21 @@ init_net(const char *intf, struct bootp 
             }
         }
     }
+#ifdef CYGINT_ISO_DNS
+    {
+#define MAX_IP_ADDR_LEN 16
+        char buf[BP_MAX_OPTION_LEN+1];  
+        memset(buf,0,sizeof(buf));
+        length = sizeof(buf);
+        if (get_bootp_option(bp, TAG_DOMAIN_NAME, buf, &length)) {
+            setdomainname(buf, length);
+        }
+        length = sizeof(buf);
+        if (get_bootp_option(bp, TAG_DOMAIN_SERVER, buf, &length)) {
+            cyg_dns_res_init((struct in_addr *)buf);
+        }
+    }
+#endif
     close(s);
     return true;
 }
--- a/packages/net/tcpip/current/src/lib/dhcp_prot.c
+++ b/packages/net/tcpip/current/src/lib/dhcp_prot.c
@@ -169,6 +169,50 @@ set_fixed_tag( struct bootp *ppkt,
     return true;
 }
 
+// Note that this does not permit changing the size of an extant tag.
+static int
+set_variable_tag( struct bootp *ppkt,
+               unsigned char tag,
+               cyg_uint8 *pvalue,
+               int len)
+{
+    unsigned char *op;
+
+    // Initially this will only scan the options field.
+    op = &ppkt->bp_vend[4];
+    while (*op != TAG_END) {
+        if ( op > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
+            CYG_FAIL( "Oversize DHCP packet in set_variable_tag" );
+            return false;
+        }
+        if (*op == tag)                 // Found it...
+            break;
+        op += *(op+1)+2;
+    }
+    
+    if (*op == tag) { // Found it...
+        if ( *(op+1) != len ) {
+            CYG_FAIL( "Wrong size in set_variable_tag" );
+            return false;           // wrong size
+        }
+    }
+    else { // overwrite the end tag and install a new one
+        if ( op + len + 2 > &ppkt->bp_vend[BP_VEND_LEN-1] ) {
+            CYG_FAIL( "Oversize DHCP packet in set_variable_tag append" );
+            return false;
+        }
+        *op = tag;
+        *(op+1) = len;
+        *(op + len + 2) = TAG_END;
+    }
+    // and insert the value.  No order is implied.
+    op += 2;               // point to start of value
+    while ( len-- > 0 ) {
+        *op++ = *pvalue++;
+    }
+    return true;
+}
+
 // ------------------------------------------------------------------------
 // Bring up an interface enough to broadcast, before we know who we are
 
@@ -345,7 +389,8 @@ static inline void new_lease( struct boo
     cyg_resolution_t resolution = 
         cyg_clock_get_resolution(cyg_real_time_clock());
     cyg_handle_t h;
-
+    unsigned int length;
+    
     // Silence any jabbering from past lease on this interface
     no_lease( lease );
     lease->which = lease->next = 0;
@@ -354,7 +399,8 @@ static inline void new_lease( struct boo
                       &lease->alarm, &lease->alarm_obj );
 
     // extract the lease time and scale it &c to now.
-    if(!get_bootp_option( bootp, TAG_DHCP_LEASE_TIME, &tag ))
+    length = sizeof(tag);
+    if(!get_bootp_option( bootp, TAG_DHCP_LEASE_TIME, &tag ,&length))
         tag = 0xffffffff;
 
     if ( 0xffffffff == tag ) {
@@ -370,8 +416,8 @@ static inline void new_lease( struct boo
     then *= 1000000000; // into nS - we know there is room in a tick_count_t
     then = (then / resolution.dividend) * resolution.divisor; // into system ticks
     lease->expiry = now + then;
-
-    if (get_bootp_option( bootp, TAG_DHCP_REBIND_TIME, &tag ))
+    length = sizeof(tag);
+    if (get_bootp_option( bootp, TAG_DHCP_REBIND_TIME, &tag, &length ))
         then = (cyg_uint64)(ntohl(tag));
     else
         then = expiry_then - expiry_then/4;
@@ -379,7 +425,8 @@ static inline void new_lease( struct boo
     then = (then / resolution.dividend) * resolution.divisor; // into system ticks
     lease->t2 = now + then;
 
-    if (get_bootp_option( bootp, TAG_DHCP_RENEWAL_TIME, &tag ))
+    length = sizeof(tag);
+    if (get_bootp_option( bootp, TAG_DHCP_RENEWAL_TIME, &tag, &length ))
         then = (cyg_uint64)(ntohl(tag));
     else
         then = expiry_then/2;
@@ -406,6 +453,45 @@ static inline void new_lease( struct boo
     cyg_alarm_enable( lease->alarm );
 }
 
+// ------------------------------------------------------------------------
+// Set all the tags we want to use when sending a packet.
+// This has expanded to a large, explicit set to interwork better
+// with a variety of DHCP servers.
+
+static void set_default_dhcp_tags( struct bootp *xmit )
+{
+    // Explicitly request full set of params that are default for LINUX
+    // dhcp servers, but not default for others.  This is rather arbitrary,
+    // but it preserves behaviour for people using those servers.
+    // Perhaps configury of this set will be needed in future?
+    //
+    // Here's the set:
+    static cyg_uint8 req_list[]  = {
+#ifdef CYGOPT_NET_DHCP_PARM_REQ_LIST_REPLACE
+        CYGOPT_NET_DHCP_PARM_REQ_LIST_REPLACE ,
+#else
+        TAG_DHCP_SERVER_ID    ,     //     DHCP server id: 10.16.19.66
+        TAG_DHCP_LEASE_TIME   ,     //     DHCP time 51: 60
+        TAG_DHCP_RENEWAL_TIME ,     //     DHCP time 58: 30
+        TAG_DHCP_REBIND_TIME  ,     //     DHCP time 59: 52
+        TAG_SUBNET_MASK       ,     //     subnet mask: 255.255.255.0
+        TAG_GATEWAY           ,     //     gateway: 10.16.19.66
+        TAG_DOMAIN_SERVER     ,     //     domain server: 10.16.19.66
+        TAG_DOMAIN_NAME       ,     //     domain name: hmt10.cambridge.redhat.com
+        TAG_IP_BROADCAST      ,     //     IP broadcast: 10.16.19.255
+#endif
+#ifdef CYGOPT_NET_DHCP_PARM_REQ_LIST_ADDITIONAL
+        CYGOPT_NET_DHCP_PARM_REQ_LIST_ADDITIONAL ,
+#endif
+    };
+
+    if ( req_list[0] ) // So that one may easily turn it all off by configury
+        set_variable_tag( xmit, TAG_DHCP_PARM_REQ_LIST,
+                          &req_list[0], sizeof( req_list ) );
+
+    // Explicitly specify our max message size.
+    set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
+}
 
 // ------------------------------------------------------------------------
 // the DHCP state machine - this does all the work
@@ -423,7 +509,8 @@ do_dhcp(const char *intf, struct bootp *
     struct timeout_state timeout_scratch;
     cyg_uint8 oldstate = *pstate;
     cyg_uint8 msgtype = 0, seen_bootp_reply = 0;
-
+    unsigned int length;
+    
     cyg_uint32 xid;
 
     // IMPORTANT: xmit is the same as res throughout this; *received is a
@@ -494,6 +581,15 @@ do_dhcp(const char *intf, struct bootp *
 
     xid = res->bp_xid; // default to what's there already;
 
+    // generates a new XID
+    {
+      unsigned char* xp = (unsigned char*)&xid;
+      
+      *xp++ = ifr.ifr_hwaddr.sa_data[5];
+      *xp++ = ifr.ifr_hwaddr.sa_data[4];
+      *((cyg_uint16*)xp) = (cyg_uint16)(arc4random() & 0xffff);
+    }
+      
     while ( 1 ) {
 
         // If we are active rather than in the process of shutting down,
@@ -537,15 +633,6 @@ do_dhcp(const char *intf, struct bootp *
                 return false;
             }
 
-            // generates a new XID
-            {
-                unsigned char* xp = (unsigned char*)&xid;
-
-                *xp++ = ifr.ifr_hwaddr.sa_data[5];
-                *xp++ = ifr.ifr_hwaddr.sa_data[4];
-                *((cyg_uint16*)xp) = (cyg_uint16)(arc4random() & 0xffff);
-            }
-
             // Fill in the BOOTP request - DHCPDISCOVER packet
             bzero(xmit, sizeof(*xmit));
             xmit->bp_op = BOOTREQUEST;
@@ -559,8 +646,8 @@ do_dhcp(const char *intf, struct bootp *
 
             // remove the next line to test ability to handle bootp packets.
             set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPDISCOVER, 1 );
-
-            set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
+            // Set all the tags we want to use when sending a packet
+            set_default_dhcp_tags( xmit );
 
 #ifdef CYGDBG_NET_DHCP_CHATTER
             diag_printf( "---------DHCPSTATE_INIT sending:\n" );
@@ -617,13 +704,17 @@ do_dhcp(const char *intf, struct bootp *
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
+                length = sizeof(received->bp_siaddr.s_addr);
                 get_bootp_option( received, TAG_DHCP_SERVER_ID,
-                                  &received->bp_siaddr.s_addr );
+                                  &received->bp_siaddr.s_addr,
+                                  &length);
             }
 
             // see if it was a DHCP reply or a bootp reply; it could be
             // either.
-            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype ) ) {
+            length = sizeof(msgtype);
+            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
+                                   &length) ) {
                 if ( DHCPOFFER == msgtype ) { // all is well
                     // Save the good packet in *xmit
                     bcopy( received, xmit, dhcp_size(received) );
@@ -646,12 +737,13 @@ do_dhcp(const char *intf, struct bootp *
             // then wait for an ACK in DHCPSTATE_REQUEST_RECV.
 
             // Fill in the BOOTP request - DHCPREQUEST packet
+            xmit->bp_xid = xid;
             xmit->bp_op = BOOTREQUEST;
             xmit->bp_flags = htons(0x8000); // BROADCAST FLAG
 
             set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPREQUEST, 1 );
-            set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
-
+            // Set all the tags we want to use when sending a packet
+            set_default_dhcp_tags( xmit );
             // And this will be a new one:
             set_fixed_tag( xmit, TAG_DHCP_REQ_IP, ntohl(xmit->bp_yiaddr.s_addr), 4 );
             
@@ -700,12 +792,16 @@ do_dhcp(const char *intf, struct bootp *
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
+                length = sizeof(received->bp_siaddr.s_addr );
                 get_bootp_option( received, TAG_DHCP_SERVER_ID,
-                                  &received->bp_siaddr.s_addr );
+                                  &received->bp_siaddr.s_addr,
+                                  &length);
             }
 
             // check it was a DHCP reply
-            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype ) ) {
+            length = sizeof(msgtype);
+            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
+                                   &length) ) {
                 if ( DHCPACK == msgtype // Same offer & server?
                      && received->bp_yiaddr.s_addr == xmit->bp_yiaddr.s_addr
                      && received->bp_siaddr.s_addr == xmit->bp_siaddr.s_addr) {
@@ -761,14 +857,15 @@ do_dhcp(const char *intf, struct bootp *
             // type UNICAST straight to the server.  Then wait for an ACK.
 
             // Fill in the BOOTP request - DHCPREQUEST packet
+            xmit->bp_xid = xid;
             xmit->bp_op = BOOTREQUEST;
             xmit->bp_flags = htons(0); // No BROADCAST FLAG
             // Use the *client* address here:
             xmit->bp_ciaddr.s_addr = xmit->bp_yiaddr.s_addr;
 
             set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPREQUEST, 1 );
-            set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
-
+            // Set all the tags we want to use when sending a packet
+            set_default_dhcp_tags( xmit );
             // And this will be a new one:
             set_fixed_tag( xmit, TAG_DHCP_REQ_IP, ntohl(xmit->bp_yiaddr.s_addr), 4 );
             
@@ -828,12 +925,16 @@ do_dhcp(const char *intf, struct bootp *
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
+                length = sizeof(received->bp_siaddr.s_addr);
                 get_bootp_option( received, TAG_DHCP_SERVER_ID,
-                                  &received->bp_siaddr.s_addr );
+                                  &received->bp_siaddr.s_addr,
+                                  &length);
             }
 
             // check it was a DHCP reply
-            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype ) ) {
+            length = sizeof(msgtype);
+            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
+                                   &length) ) {
                 if ( DHCPACK == msgtype  // Same offer?
                      && received->bp_yiaddr.s_addr == xmit->bp_yiaddr.s_addr) {
                     // Save the good packet in *xmit
@@ -860,14 +961,15 @@ do_dhcp(const char *intf, struct bootp *
             // Then wait for an ACK.  This one is BROADCAST.
 
             // Fill in the BOOTP request - DHCPREQUEST packet
+            xmit->bp_xid = xid;
             xmit->bp_op = BOOTREQUEST;
             xmit->bp_flags = htons(0); // no BROADCAST FLAG
             // Use the *client* address here:
             xmit->bp_ciaddr.s_addr = xmit->bp_yiaddr.s_addr;
 
             set_fixed_tag( xmit, TAG_DHCP_MESS_TYPE, DHCPREQUEST, 1 );
-            set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
-
+            // Set all the tags we want to use when sending a packet
+            set_default_dhcp_tags( xmit );
             // And this will be a new one:
             set_fixed_tag( xmit, TAG_DHCP_REQ_IP, ntohl(xmit->bp_yiaddr.s_addr), 4 );
             
@@ -917,12 +1019,16 @@ do_dhcp(const char *intf, struct bootp *
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
+                int length = sizeof(received->bp_siaddr.s_addr );
                 get_bootp_option( received, TAG_DHCP_SERVER_ID,
-                                  &received->bp_siaddr.s_addr );
+                                  &received->bp_siaddr.s_addr,
+                                  &length);
             }
 
             // check it was a DHCP reply
-            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype ) ) {
+            length = sizeof(msgtype);
+            if ( get_bootp_option( received, TAG_DHCP_MESS_TYPE, &msgtype,
+                                   &length) ) {
                 if ( DHCPACK == msgtype  // Same offer?
                      && received->bp_yiaddr.s_addr == xmit->bp_yiaddr.s_addr) {
                     // Save the good packet in *xmit
@@ -991,7 +1097,7 @@ do_dhcp(const char *intf, struct bootp *
             // Just send what you got with a DHCPRELEASE in the message
             // type UNICAST straight to the server.  No ACK.  Then go to
             // NOTBOUND state.
-
+            xmit->bp_xid = xid;
             xmit->bp_op = BOOTREQUEST;
             xmit->bp_flags = htons(0); // no BROADCAST FLAG
             // Use the *client* address here:
--- a/packages/net/tcpip/current/src/lib/dhcp_support.c
+++ b/packages/net/tcpip/current/src/lib/dhcp_support.c
@@ -189,6 +189,7 @@ int dhcp_release( void )
 // The management thread function
 void dhcp_mgt_entry( cyg_addrword_t loop_on_failure )
 {
+    int j;
     while ( 1 ) {
         while ( 1 ) {
             cyg_semaphore_wait( &dhcp_needs_attention );
@@ -196,10 +197,14 @@ void dhcp_mgt_entry( cyg_addrword_t loop
                 break; // If we need to re-bind
         }
         dhcp_halt(); // tear everything down
-        if ( loop_on_failure )
-            init_all_network_interfaces(); // re-initialize
-        else
+        if ( !loop_on_failure )
             return; // exit the thread/return
+        init_all_network_interfaces(); // re-initialize
+        for ( j = 0; j < CYGPKG_NET_NLOOP; j++ )
+            init_loopback_interface( j );
+#ifdef CYGPKG_SNMPAGENT
+        SnmpdShutDown(0); // Cycle the snmpd state
+#endif
     }
 }
 
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,63 @@
+2001-12-06  Jesper Skov  <jskov@redhat.com>
+
+	* src/load.c (do_load): Fix warning.
+	* src/main.c: Added support for dumping memory in 16 and 32 bit
+	units. Based on patch from Warren Jasper <warrenj@bops.com>.
+
+2001-12-05  Hugo Tyson  <hmt@redhat.com>
+
+	* src/flash.c (get_config): If we are editing an IP address, and
+	it is 0.0.0.0 (as you get at "fco -i" time) suppress using that as
+	the initial value of the string, it is unhelpful as a starting
+	point for line editing.
+
+	If we were given a value on the CLI eg. "fco bootp false" because
+	the new value was copied into the holding string, it was not
+	recognized as a change, so the flash was not updated.  Bug!  The
+	fix is to change the order of the strcpy()s so that holdline is
+	before line.
+
+	If the input line for a new value is completely blank, and the
+	type is not string, take this to mean don't change the value.
+	Otherwise typing in an empty line to an IP address goes off and
+	tries to DNS resolve it there and then, looks like a hang.
+
+	(do_flash_config): If we print the message "** invalid entry" do
+	not just loop; set onevalue = NULL so that the user is prompted
+	for a good value.  Otherwise it loops forever trying the same
+	value if you typed "fco bootp goat" (goat being a bad boolean).
+
+	* src/parse.c (parse_bool): Check for (partial) rest of the word
+	either "true" or "false" and nothing extra.  Thus we reject
+	"truefalse" as is all to easy to type in by accident.  "TRU" "T"
+	"tRuE" are all OK of course.
+
+	* src/net/inet_addr.c (inet_aton): Do not accept terminating the
+	dot-quad address with a final dot.  Else typing on the end of a
+	provided-for-editing string is accepted.  Also reject units > 255.
+	Allow typing in either exactly one (large) number or 4 small ones;
+	reject intermediates.  Thus we reject "10.16.19.1110.16.19.33" and
+	"0.0.0.010.16.19.11" as are all to easy to type in by accident,
+	and things like 10.0.0xffff which used to be accepted.  0x0a00ffff
+	is OK though.  This change also prevents the pointer s running off
+	the end of the string if you just entered eg. "1".
+
+2001-12-04  Richard Sandiford  <rsandifo@redhat.com>
+
+	* include/net/net.h (ETH_MAX_PKTLEN): Increase to match definition
+	of MAX_ETH_MSG.
+
+2001-12-04  Richard Sandiford  <rsandifo@redhat.com>
+
+	* src/net/tcp.c (__tcp_poll): Call MS_TICKS_DELAY before __timer_poll.
+	* src/net/net_io.c (net_io_getc): Remove MS_TICKS_DELAY from here...
+	(net_io_getc_nonblock): ...and from here.
+
+2001-11-30  Jesper Skov  <jskov@redhat.com>
+
+	* src/net/net_io.c (net_init): Print ESA for device even if bootp
+	fails.
+
 2001-11-29  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/net/dns.c: Rename index -> ptdindex to avoid conflict with BSD
--- a/packages/redboot/current/include/net/net.h
+++ b/packages/redboot/current/include/net/net.h
@@ -88,7 +88,7 @@ extern unsigned long  ntohs(unsigned sho
  * Minimum ethernet packet length.
  */
 #define ETH_MIN_PKTLEN  60
-#define ETH_MAX_PKTLEN  1514
+#define ETH_MAX_PKTLEN  (1540-14)
 
 typedef unsigned char enet_addr_t[6];
 typedef unsigned char ip_addr_t[4];
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -1340,6 +1340,11 @@ get_config(unsigned char *dp, char *titl
 #ifdef CYGPKG_REDBOOT_NETWORKING
     case CONFIG_IP:
         lp += diag_sprintf(lp, "%s", inet_ntoa((in_addr_t *)val_ptr));
+        if (0 == strcmp("0.0.0.0", line) && !(LIST_OPT_LIST_ONLY & list_opt)) {
+            // then we have a deeply unhelpful starting text - kill it off
+            // (unless we are just listing all values)
+            lp = line;  *lp = '\0';
+        }
         break;
     case CONFIG_ESA:
         for (esa_ptr = 0;  esa_ptr < sizeof(enet_addr_t);  esa_ptr++) {
@@ -1372,8 +1377,8 @@ get_config(unsigned char *dp, char *titl
             ret = strlen(newvalue);
             if (ret > sizeof(line))
                 return CONFIG_BAD;
+            strcpy(hold_line, line); // Hold the old value for comparison
             strcpy(line, newvalue);
-            strcpy(hold_line, newvalue);
             diag_printf("Setting to %s\n", newvalue);
         } else {
             // read from terminal
@@ -1381,6 +1386,9 @@ get_config(unsigned char *dp, char *titl
             ret = _rb_gets_preloaded(line, sizeof(line), 0);
         }
         if (ret < 0) return CONFIG_ABORT;
+        // empty input - leave value untouched (else DNS goes away for a
+        // minute to try to look it up) but we must accept empty value for strings.
+        if (0 == line[0] && CONFIG_STRING != type) return CONFIG_OK; 
         if (strcmp(line, hold_line) == 0) return CONFIG_OK;  // Just a CR - leave value untouched
         lp = &line[strlen(line)-1];
         if (*lp == '.') return CONFIG_DONE;
@@ -1598,6 +1606,7 @@ do_flash_config(int argc, char *argv[])
         case CONFIG_BAD:
             // Nothing - make him do it again
             diag_printf ("** invalid entry\n");
+            onevalue = NULL; // request a good value be typed in - or abort/whatever
         }
     }
 
--- a/packages/redboot/current/src/load.c
+++ b/packages/redboot/current/src/load.c
@@ -301,7 +301,9 @@ do_load(int argc, char *argv[])
     bool decompress;
 #endif
     int chan = -1;
+#if CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS > 1
     bool chan_set;
+#endif
     unsigned long base = 0;
     unsigned long end = 0;
     char type[4];
--- a/packages/redboot/current/src/main.c
+++ b/packages/redboot/current/src/main.c
@@ -87,12 +87,12 @@ RedBoot_cmd("go",
     );
 RedBoot_cmd("dump", 
             "Display (hex dump) a range of memory", 
-            "-b <location> [-l <length>] [-s]",
+            "-b <location> [-l <length>] [-s] [-1|2|4]",
             do_dump 
     );
 RedBoot_cmd("x", 
             "Display (hex dump) a range of memory", 
-            "-b <location> [-l <length>] [-s]",
+            "-b <location> [-l <length>] [-s] [-1|2|4]",
             do_x
     );
 RedBoot_cmd("cksum", 
@@ -414,11 +414,15 @@ do_help(int argc, char *argv[])
 void
 do_dump(int argc, char *argv[])
 {
-    struct option_info opts[3];
+    struct option_info opts[6];
     unsigned long base, len;
     bool base_set, len_set;
     static unsigned long _base, _len;
+    static char _size = 1;
     bool srec_dump;
+    bool set_32bit = false;
+    bool set_16bit = false;
+    bool set_8bit = false;
     int i, n, off, cksum;
     cyg_uint8 ch;
 
@@ -428,7 +432,13 @@ do_dump(int argc, char *argv[])
               (void **)&len, (bool *)&len_set, "length");
     init_opts(&opts[2], 's', false, OPTION_ARG_TYPE_FLG, 
               (void **)&srec_dump, 0, "dump data using Morotola S-records");
-    if (!scan_opts(argc, argv, 1, opts, 3, 0, 0, "")) {
+    init_opts(&opts[3], '4', false, OPTION_ARG_TYPE_FLG,
+              (void *)&set_32bit, (bool *)0, "dump 32 bit units");
+    init_opts(&opts[4], '2', false, OPTION_ARG_TYPE_FLG,
+              (void **)&set_16bit, (bool *)0, "dump 16 bit units");
+    init_opts(&opts[5], '1', false, OPTION_ARG_TYPE_FLG,
+              (void **)&set_8bit, (bool *)0, "dump 8 bit units");
+    if (!scan_opts(argc, argv, 1, opts, 6, 0, 0, "")) {
         return;
     }
     if (!base_set) {
@@ -442,6 +452,15 @@ do_dump(int argc, char *argv[])
             len_set = true;
         }
     }
+
+    if (set_32bit) {
+      _size = 4;
+    } else if (set_16bit) {
+      _size = 2;
+    } else if (set_8bit) {
+      _size = 1;
+    }
+
     if (!len_set) {
         len = 32;
     }
@@ -463,7 +482,17 @@ do_dump(int argc, char *argv[])
             off += n;
         }
     } else {
-        diag_dump_buf((void *)base, len);
+        switch( _size ) {
+        case 1:
+            diag_dump_buf((void *)base, len);
+            break;
+        case 2:
+            diag_dump_buf_16bit((void *)base, len);
+            break;
+        case 4:
+            diag_dump_buf_32bit((void *)base, len);
+            break;
+        }
     }
     _base = base + len;
     _len = len;
--- a/packages/redboot/current/src/net/inet_addr.c
+++ b/packages/redboot/current/src/net/inet_addr.c
@@ -69,7 +69,7 @@ inet_aton(const char *s, in_addr_t *addr
             if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) {
                 // Valid digit
                 val = (val * radix) + digit;
-            } else if (c == '.') {
+            } else if (c == '.' && i < 3) { // all but last terminate by '.'
                 break;
             } else {
                 return false;
@@ -81,6 +81,16 @@ inet_aton(const char *s, in_addr_t *addr
 #else
         res = (res << 8) | val;
 #endif
+        if ('\0' == c) {
+            if (0 == i) { // first field found end of string
+                res = val; // no shifting, use it as the whole thing
+                break; // permit entering a single number
+            }
+            if (3 > i) // we found end of string before getting 4 fields
+                return false;
+        }
+        // after that we check that it was 0..255 only
+        if (val &~0xff) return false;
     }
     addr->s_addr = htonl(res);
     return true;
--- a/packages/redboot/current/src/net/net_io.c
+++ b/packages/redboot/current/src/net/net_io.c
@@ -214,8 +214,6 @@ net_io_getc(void* __ch_data)
         if (--idle_timeout == 0) {
             net_io_flush();
             idle_timeout = 10;
-        } else {
-            MS_TICKS_DELAY();
         }
     }
     CYGARC_HAL_RESTORE_GP();
@@ -336,7 +334,6 @@ net_io_getc_timeout(void* __ch_data, cyg
         res = net_io_getc_nonblock(__ch_data, ch);
         if (res || 0 == delay_count--)
             break;
-        MS_TICKS_DELAY();
     }
 
     CYGARC_HAL_RESTORE_GP();
@@ -599,7 +596,15 @@ 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) {
-                diag_printf("Can't get BOOTP info - network disabled!\n");
+                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]);
+                diag_printf("Can't get BOOTP info for device!\n");
             } else {
                 diag_printf("Can't get BOOTP info, using default IP address\n");
                 have_net = true;
--- a/packages/redboot/current/src/net/tcp.c
+++ b/packages/redboot/current/src/net/tcp.c
@@ -569,6 +569,7 @@ void
 __tcp_poll(void)
 {
     __enet_poll();
+    MS_TICKS_DELAY();
     __timer_poll();
 }
 
--- a/packages/redboot/current/src/parse.c
+++ b/packages/redboot/current/src/parse.c
@@ -367,9 +367,23 @@ parse_bool(char *s, bool *val)
 {
     while (*s == ' ') s++;
     if ((*s == 't') || (*s == 'T')) {
+        char *p = "rue";
+        char *P = "RUE";
+        // check for (partial) rest of the word and no extra including the
+        // terminating zero.  "tru" will match; "truef" will not.
+        while ( *++s ) {
+            if ( *p != *s && *P != *s ) return false;
+            p++; P++;
+        }
         *val = true;
     } else 
     if ((*s == 'f') || (*s == 'F')) {
+        char *p = "alse";
+        char *P = "ALSE";
+        while ( *++s ) {
+            if ( *p != *s && *P != *s ) return false;
+            p++; P++;
+        }
         *val = false;
     } else {
         return false;