changeset 143:6b5f480c6929 ecos-sw-2000-12-08

Merge from eCos master repository on 2000-12-08-02:09:36-GMT
author jlarmour
date Fri, 08 Dec 2000 03:30:06 +0000
parents 12eccf9656f3
children da1052144c56
files packages/ChangeLog packages/compat/posix/current/ChangeLog packages/compat/posix/current/src/signal.cxx packages/cygmon/current/ChangeLog packages/cygmon/current/misc/monitor_cmd.c packages/devs/flash/arm/assabet/current/ChangeLog packages/devs/flash/arm/assabet/current/src/assabet_flash.c packages/devs/flash/arm/ebsa285/current/ChangeLog packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c packages/devs/flash/arm/edb7xxx/current/ChangeLog packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c packages/devs/flash/arm/sa1100mm/current/ChangeLog packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c packages/devs/flash/intel/bootblock/current/ChangeLog packages/devs/flash/intel/bootblock/current/src/bootblock_flash.c packages/devs/flash/powerpc/mbx/current/ChangeLog packages/devs/flash/powerpc/mbx/current/src/mbx_flash.c packages/devs/serial/generic/16x5x/current/ChangeLog packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c packages/devs/serial/powerpc/quicc/current/ChangeLog packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c packages/ecos.db packages/hal/arm/cma230/current/ChangeLog packages/hal/arm/cma230/current/include/hal_cache.h packages/hal/arm/ebsa285/current/ChangeLog packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl packages/hal/arm/ebsa285/current/include/hal_cache.h packages/hal/arm/ebsa285/current/misc/redboot_RAM.cfg packages/hal/arm/ebsa285/current/misc/redboot_ROM.cfg packages/hal/arm/ebsa285/current/src/ebsa285_misc.c packages/hal/arm/ebsa285/current/src/redboot_cmds.c packages/hal/arm/edb7xxx/current/ChangeLog packages/hal/arm/edb7xxx/current/include/hal_cache.h packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h packages/hal/arm/sa11x0/assabet/current/ChangeLog packages/hal/arm/sa11x0/assabet/current/cdl/hal_arm_sa11x0_assabet.cdl packages/hal/arm/sa11x0/assabet/current/misc/redboot_RAM.cfg packages/hal/arm/sa11x0/assabet/current/misc/redboot_ROM.cfg packages/hal/arm/sa11x0/assabet/current/src/assabet_misc.c packages/hal/arm/sa11x0/assabet/current/src/redboot_cmds.c packages/hal/arm/sa11x0/brutus/current/ChangeLog packages/hal/arm/sa11x0/brutus/current/cdl/hal_arm_sa11x0_brutus.cdl packages/hal/arm/sa11x0/brutus/current/misc/redboot_RAM.cfg packages/hal/arm/sa11x0/brutus/current/misc/redboot_ROM.cfg packages/hal/arm/sa11x0/brutus/current/src/brutus_misc.c packages/hal/arm/sa11x0/var/current/ChangeLog packages/hal/arm/sa11x0/var/current/include/hal_cache.h packages/hal/arm/sa11x0/var/current/src/hal_diag.c packages/hal/common/current/ChangeLog packages/hal/common/current/include/hal_misc.h packages/hal/common/current/src/hal_if.c packages/hal/common/current/src/hal_stub.c packages/hal/i386/pc/current/ChangeLog packages/hal/i386/pc/current/src/plf_misc.c packages/hal/mips/arch/current/ChangeLog packages/hal/mips/arch/current/include/hal_cache.h packages/hal/mips/arch/current/include/hal_intr.h packages/hal/mips/arch/current/src/hal_misc.c packages/hal/mips/tx49/current/ChangeLog packages/hal/mips/tx49/current/include/var_cache.h packages/hal/mn10300/arch/current/ChangeLog packages/hal/mn10300/arch/current/include/hal_arch.h packages/hal/mn10300/arch/current/src/vectors.S packages/io/eth/current/ChangeLog packages/io/eth/current/src/stand_alone/eth_drv.c packages/io/flash/current/ChangeLog packages/io/flash/current/include/flash.h packages/io/flash/current/src/flash.c packages/io/pci/current/ChangeLog packages/io/pci/current/cdl/io_pci.cdl packages/io/pci/current/src/pci.c packages/io/serial/current/ChangeLog packages/io/serial/current/src/common/serial.c packages/kernel/current/ChangeLog packages/kernel/current/cdl/kernel.cdl packages/kernel/current/cdl/thread.cdl packages/kernel/current/include/thread.hxx packages/kernel/current/include/thread.inl packages/kernel/current/src/debug/dbg-thread-demux.c packages/kernel/current/src/sched/sched.cxx packages/kernel/current/tests/kcache2.c packages/language/c/libc/time/current/ChangeLog packages/language/c/libc/time/current/tests/clock.c packages/net/snmp/agent/current/ChangeLog packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c packages/net/snmp/agent/current/src/mibgroup/mibII/interfaces.c packages/net/snmp/agent/current/src/mibgroup/mibII/ip.c packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/include/net/net.h packages/redboot/current/include/redboot.h packages/redboot/current/src/flash.c packages/redboot/current/src/io.c packages/redboot/current/src/load.c packages/redboot/current/src/main.c packages/redboot/current/src/misc_funs.c packages/redboot/current/src/net/net_io.c packages/redboot/current/src/net/tcp.c packages/redboot/current/src/net/tftp_client.c packages/redboot/current/src/parse.c packages/redboot/current/src/xyzModem.c packages/redboot/current/src/xyzModem.h packages/services/memalloc/common/current/ChangeLog packages/services/memalloc/common/current/src/heapgen.tcl
diffstat 104 files changed, 1748 insertions(+), 416 deletions(-) [+]
line wrap: on
line diff
--- a/packages/ChangeLog
+++ b/packages/ChangeLog
@@ -1,3 +1,4 @@
+
 2000-11-25  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* pkgconf/rules.mak (mlt_headers): Rewrite to work under Solaris,
--- a/packages/compat/posix/current/ChangeLog
+++ b/packages/compat/posix/current/ChangeLog
@@ -1,3 +1,7 @@
+2000-12-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/signal.cxx: include unistd.h for _exit
+
 2000-11-20  Nick Garnett  <nickg@cygnus.co.uk>
 
 	* src/signal.cxx (cyg_deliver_signals): Added else in code to
--- a/packages/compat/posix/current/src/signal.cxx
+++ b/packages/compat/posix/current/src/signal.cxx
@@ -57,6 +57,7 @@
 
 #include <signal.h>                     // our header
 #include <setjmp.h>
+#include <unistd.h>                     // _exit
 
 #include <cyg/kernel/clock.hxx>
 
--- a/packages/cygmon/current/ChangeLog
+++ b/packages/cygmon/current/ChangeLog
@@ -1,3 +1,8 @@
+2000-12-04  Drew Moseley  <dmoseley@redhat.com>
+
+	* misc/monitor_cmd.c (breakpoint_cmd): Fix typo in printf
+	formatting for error message.
+
 2000-11-20  Drew Moseley  <dmoseley@redhat.com>
 
 	* cdl/cygmon.cdl: Make sure we don't specify vectors.o and target.ld twice.
--- a/packages/cygmon/current/misc/monitor_cmd.c
+++ b/packages/cygmon/current/misc/monitor_cmd.c
@@ -1621,7 +1621,7 @@ Sets a breakpoint at address 4ff5.");
       str2addr (argvect[1], &location);
       if (add_mon_breakpoint (location))
       {
-          xprintf("Unable to set breakpoint at 0x08lx\n", location.addr);
+          xprintf("Unable to set breakpoint at 0x%08lx\n", location.addr);
       }
     }
   return 0;
--- a/packages/devs/flash/arm/assabet/current/ChangeLog
+++ b/packages/devs/flash/arm/assabet/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/assabet_flash.c (flash_code_overlaps): Define stext/etext
+	as array types so no assumptions can be made by the compiler about
+	location.
+
 2000-10-24  Gary Thomas  <gthomas@redhat.com>
 
 	* src/flash_unlock_block.c (flash_unlock_block): 
--- a/packages/devs/flash/arm/assabet/current/src/assabet_flash.c
+++ b/packages/devs/flash/arm/assabet/current/src/assabet_flash.c
@@ -111,7 +111,7 @@ flash_hwr_map_error(int err)
 bool
 flash_code_overlaps(void *start, void *end)
 {
-    extern char _stext, _etext;
+    extern char _stext[], _etext[];
 
     return ((((unsigned long)&_stext >= (unsigned long)start) &&
              ((unsigned long)&_stext < (unsigned long)end)) ||
--- a/packages/devs/flash/arm/ebsa285/current/ChangeLog
+++ b/packages/devs/flash/arm/ebsa285/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/ebsa285_flash.c (flash_code_overlaps): Define stext/etext
+	as array types so no assumptions can be made by the compiler about
+	location.
+
 2000-08-29  Gary Thomas  <gthomas@redhat.com>
 
 	* src/ebsa285_flash.c: Improve error decoding.
--- a/packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c
+++ b/packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c
@@ -106,7 +106,7 @@ flash_hwr_map_error(int err)
 bool
 flash_code_overlaps(void *start, void *end)
 {
-    extern char _stext, _etext;
+    extern char _stext[], _etext[];
 
     return ((((unsigned long)&_stext >= (unsigned long)start) &&
              ((unsigned long)&_stext < (unsigned long)end)) ||
--- a/packages/devs/flash/arm/edb7xxx/current/ChangeLog
+++ b/packages/devs/flash/arm/edb7xxx/current/ChangeLog
@@ -1,3 +1,14 @@
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/edb7xxx_flash.c (flash_code_overlaps): Define stext/etext
+	as array types so no assumptions can be made by the compiler about
+	location.
+
+2000-12-04  Gary Thomas  <gthomas@redhat.com>
+
+	* src/edb7xxx_flash.c (flash_hwr_init): Additional debugging
+	printf statments - in case this stuff fails in the future.
+
 2000-11-21  Gary Thomas  <gthomas@redhat.com>
 
 	* src/flash_query.c: Increase startup timing - didn't always work.
--- a/packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c
+++ b/packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c
@@ -73,8 +73,22 @@ flash_hwr_init(void)
     volatile int *cp = 0xE0000000;
     // See if the data cache is working
     *cp = 0x12345678;
+    printf("ROM cache:\n");
+    printf("cache test = %x\n", *cp);
+    HAL_DCACHE_INVALIDATE_ALL();
+    HAL_DCACHE_DISABLE();
+    printf("cache test = %x\n", *cp);
+    *cp = 0xDEADDEAD;
+    printf("cache test = %x\n", *cp);
+    HAL_DCACHE_ENABLE();
+    printf("cache test = %x\n", *cp);
+    cp = 0x00100000;
+    // See if the data cache is working
+    *cp = 0x12345678;
+    printf("RAM cache:\n");
     printf("cache test = %x\n", *cp);
     HAL_DCACHE_DISABLE();
+    printf("cache test = %x\n", *cp);
     *cp = 0xDEADDEAD;
     printf("cache test = %x\n", *cp);
     HAL_DCACHE_ENABLE();
@@ -88,6 +102,24 @@ flash_hwr_init(void)
     dump_buf(data, sizeof(data));
 #endif
 
+#if 0
+    {
+    volatile int cache_test;
+    volatile int *cp = 0xE0000000;
+    // See if the data cache is working
+    printf("cache test = %x\n", *cp);
+    *cp = 0x56781234;
+    printf("cache test = %x\n", *cp);
+    HAL_DCACHE_INVALIDATE_ALL();
+    HAL_DCACHE_DISABLE();
+    printf("cache test = %x\n", *cp);
+    *cp = 0xDEADDEAD;
+    printf("cache test = %x\n", *cp);
+    HAL_DCACHE_ENABLE();
+    printf("cache test = %x\n", *cp);
+    }
+#endif
+
     if (data[0] != FLASH_Intel_code) {
         printf("Not Intel = %x\n", data[0]);
         return FLASH_ERR_HWR;
@@ -131,7 +163,7 @@ flash_hwr_map_error(int err)
 bool
 flash_code_overlaps(void *start, void *end)
 {
-    extern char _stext, _etext;
+    extern char _stext[], _etext[];
 
     return ((((unsigned long)&_stext >= (unsigned long)start) &&
              ((unsigned long)&_stext < (unsigned long)end)) ||
--- a/packages/devs/flash/arm/sa1100mm/current/ChangeLog
+++ b/packages/devs/flash/arm/sa1100mm/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/sa1100mm_flash.c (flash_code_overlaps): Define stext/etext
+	as array types so no assumptions can be made by the compiler about
+	location.
+
 2000-10-25  Drew Moseley  <dmoseley@redhat.com>
 
 	* src/sa1100mm_flash.c: New file.  Support for SA1100 Multimedia
--- a/packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c
+++ b/packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c
@@ -108,7 +108,7 @@ flash_hwr_map_error(int err)
 bool
 flash_code_overlaps(void *start, void *end)
 {
-    extern char _stext, _etext;
+    extern char _stext[], _etext[];
 
     return ((((unsigned long)&_stext >= (unsigned long)start) &&
              ((unsigned long)&_stext < (unsigned long)end)) ||
--- a/packages/devs/flash/intel/bootblock/current/ChangeLog
+++ b/packages/devs/flash/intel/bootblock/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/bootblock_flash.c (flash_code_overlaps): Define stext/etext
+	as array types so no assumptions can be made by the compiler about
+	location.
+
 2000-11-22  Jesper Skov  <jskov@redhat.com>
 
 	* src/bootblock_flash.c (flash_hwr_init): Invalidate icache
--- a/packages/devs/flash/intel/bootblock/current/src/bootblock_flash.c
+++ b/packages/devs/flash/intel/bootblock/current/src/bootblock_flash.c
@@ -137,7 +137,7 @@ flash_hwr_map_error(int err)
 bool
 flash_code_overlaps(void *start, void *end)
 {
-    extern char _stext, _etext;
+    extern char _stext[], _etext[];
 
     return ((((unsigned long)&_stext >= (unsigned long)start) &&
              ((unsigned long)&_stext < (unsigned long)end)) ||
--- a/packages/devs/flash/powerpc/mbx/current/ChangeLog
+++ b/packages/devs/flash/powerpc/mbx/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/mbx_flash.c (flash_code_overlaps): Define stext/etext
+	as array types so no assumptions can be made by the compiler about
+	location.
+
 2000-10-20  Gary Thomas  <gthomas@redhat.com>
 
 	* src/mbx_flash.c: 
--- a/packages/devs/flash/powerpc/mbx/current/src/mbx_flash.c
+++ b/packages/devs/flash/powerpc/mbx/current/src/mbx_flash.c
@@ -103,7 +103,7 @@ flash_hwr_map_error(int err)
 bool
 flash_code_overlaps(void *start, void *end)
 {
-    extern char _stext, _etext;
+    extern char _stext[], _etext[];
 
     return ((((unsigned long)&_stext >= (unsigned long)start) &&
              ((unsigned long)&_stext < (unsigned long)end)) ||
--- a/packages/devs/serial/generic/16x5x/current/ChangeLog
+++ b/packages/devs/serial/generic/16x5x/current/ChangeLog
@@ -1,3 +1,7 @@
+2000-12-07  Jesper Skov  <jskov@redhat.com>
+
+	* src/ser_16x5x.c (ISR_LS): Corrected value. Spotted by Dave Airlie.
+
 2000-09-18  Jesper Skov  <jskov@redhat.com>
 
 	* src/ser_16x5x.c: Allow clients to specify register
--- a/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
+++ b/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
@@ -118,7 +118,7 @@
 #define ISR_MS  0x00
 #define ISR_nIP 0x01
 #define ISR_Tx  0x02
-#define ISR_LS  0x03
+#define ISR_LS  0x06
 #define ISR_Rx  0x04
 #define ISR_RxTO  0x0C
 
--- a/packages/devs/serial/powerpc/quicc/current/ChangeLog
+++ b/packages/devs/serial/powerpc/quicc/current/ChangeLog
@@ -1,3 +1,10 @@
+2000-12-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/quicc_smc_serial.c: Remove unread tx_enabled variable from
+	quicc_smc_serial_info
+	Ensure quicc serial interrupt is unmasked in general so that rx works!
+	(quicc_smc_serial_start_xmit): Protect better from DSR interruption
+
 2000-10-24  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/quicc_smc_serial.c (quicc_smc_serial_ISR): Return with
--- a/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
+++ b/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
@@ -97,7 +97,6 @@ typedef struct quicc_smc_serial_info {
     int                   txsize, rxsize;            // Length of individual buffers
     cyg_interrupt         serial_interrupt;
     cyg_handle_t          serial_interrupt_handle;
-    bool                  tx_enabled;
 } quicc_smc_serial_info;
 
 static bool quicc_smc_serial_init(struct cyg_devtab_entry *tab);
@@ -452,8 +451,7 @@ quicc_smc_serial_init(struct cyg_devtab_
                                  &smc_chan->serial_interrupt_handle,
                                  &smc_chan->serial_interrupt);
         cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle);
-        cyg_drv_interrupt_mask(smc_chan->int_num);
-        smc_chan->tx_enabled = false;
+        cyg_drv_interrupt_unmask(smc_chan->int_num);
     }
     quicc_smc_serial_config_port(chan, &chan->config, true);
     if (cache_state)
@@ -577,18 +575,16 @@ static void
 quicc_smc_serial_start_xmit(serial_channel *chan)
 {
     quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;
+    cyg_drv_dsr_lock();
     if (smc_chan->txbd->length == 0) {
         // See if there is anything to put in this buffer, just to get it going
-        cyg_drv_dsr_lock();
         (chan->callbacks->xmt_char)(chan);
-        cyg_drv_dsr_unlock();
     }
     if (smc_chan->txbd->length != 0) {
         // Make sure it gets started
         quicc_smc_serial_flush(smc_chan);
     }
-    smc_chan->tx_enabled = true;
-    cyg_drv_interrupt_unmask(smc_chan->int_num);
+    cyg_drv_dsr_unlock();
 }
 
 // Disable the transmitter on the device
@@ -599,11 +595,7 @@ quicc_smc_serial_stop_xmit(serial_channe
     // If anything is in the last buffer, need to get it started
     if (smc_chan->txbd->length != 0) {
         quicc_smc_serial_flush(smc_chan);
-        // Note: interrupt will get masked after this buffer finishes
-    } else {
-        cyg_drv_interrupt_mask(smc_chan->int_num);
     }
-    smc_chan->tx_enabled = false;
 }
 
 // Serial I/O - low level interrupt handler (ISR)
--- a/packages/ecos.db
+++ b/packages/ecos.db
@@ -124,6 +124,7 @@ package CYGPKG_DEVS_FLASH_INTEL_BOOTBLOC
 
 
 
+
 package CYGPKG_DEVS_FLASH_EBSA285 {
 	alias 		{ "FLASH memory support for StrongARM EBSA-285" flash_ebsa285 }
 	directory	devs/flash/arm/ebsa285
@@ -279,6 +280,7 @@ package CYGPKG_IO_SERIAL_MIPS_REF4955 {
     description       "TX49 REF4955 serial device drivers"
 }
 
+
 package CYGPKG_IO_SERIAL_MIPS_VRC4373 {
     alias             { "VRC4373 serial device drivers"
                         devs_serial_mips_vrc4373 vrc4373_serial_driver }
@@ -1153,6 +1155,7 @@ package CYGPKG_HAL_MIPS_TX49_REF4955 {
 }
 
 
+
 package CYGPKG_HAL_MIPS_VR4300 {
 	alias		{ "VR4300 chip HAL" hal_vr4300 vr4300_hal vr4300_arch_hal }
 	directory	hal/mips/vr4300/
--- a/packages/hal/arm/cma230/current/ChangeLog
+++ b/packages/hal/arm/cma230/current/ChangeLog
@@ -1,3 +1,10 @@
+2000-12-04  Hugo Tyson  <hmt@redhat.com>
+
+	* include/hal_cache.h: Consistently ensure that ARM registers used
+	in MCR ops to cache-control coprocessors, where the data doesn't
+	matter, all actually have data zero ("SBZ") as in the Jaggar book.
+	This may well not be necessary, but for the sake of making sure...
+
 2000-10-20  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* include/pkgconf/mlt_arm_cma222_ram.mlt:
--- a/packages/hal/arm/cma230/current/include/hal_cache.h
+++ b/packages/hal/arm/cma230/current/include/hal_cache.h
@@ -126,10 +126,15 @@
 
 // Invalidate the entire cache
 //    mcr  MMU_CP,0,r1,MMU_InvalidateCache,c0
-#define HAL_UCACHE_INVALIDATE_ALL()                             \
-{                                                               \
-    asm volatile ("mcr p15,0,r1,c7,c0,0;" );                      \
-                                                                \
+#define HAL_UCACHE_INVALIDATE_ALL()             \
+{                                               \
+    asm volatile (                              \
+        "mov    r1,#0;"                         \
+	"mcr p15,0,r1,c7,c0,0;"                 \
+        :                                       \
+        :                                       \
+        : "r1","memory" /* Clobber list */      \
+    );                                          \
 }
 
 // Synchronize the contents of the cache with memory.
--- a/packages/hal/arm/ebsa285/current/ChangeLog
+++ b/packages/hal/arm/ebsa285/current/ChangeLog
@@ -1,3 +1,38 @@
+2000-12-04  Hugo Tyson  <hmt@redhat.com>
+
+	* include/hal_cache.h: Consistently ensure that ARM registers used
+	in MCR ops to cache-control coprocessors, where the data doesn't
+	matter, all actually have data zero ("SBZ") as in the Jaggar book.
+	This may well not be necessary, but for the sake of making sure...
+
+2000-12-01  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_cmds.c: Add prototype to remove warning.
+
+2000-11-30  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_cmds.c (do_exec): Complete support for loading
+	Linux, including use of an initial ramdisk image.
+
+2000-12-01  Hugo Tyson  <hmt@redhat.com>
+
+	* include/hal_cache.h: Define addressable cache line operations
+	HAL_DCACHE_STORE(), HAL_DCACHE_INVALIDATE(), HAL_DCACHE_FLUSH()
+	now that I have understood how come the test (kcache2) was
+	failing.  See kernel ChangeLog for details.  Also tidied up a
+	couple of other minor details.
+
+2000-11-28  Drew Moseley  <dmoseley@redhat.com>
+
+	* misc/redboot_RAM.cfg: Implement CYGSEM_REDBOOT_BSP_SYSCALLS.
+	* misc/redboot_ROM.cfg: Ditto.
+
+	* src/ebsa285_misc.c (ebsa285_program_new_stack): New function
+	for switching to an application stack when running a program under
+	a ROM monitor.
+
+	* cdl/hal_arm_sa11x0_ebsa285.cdl: Define HAL_ARCH_PROGRAM_NEW_STACK.
+
 2000-11-19  Gary Thomas  <gthomas@redhat.com>
 
 	* cdl/hal_arm_ebsa285.cdl: Define CYGBLD_HAL_PLATFORM_IO_H.
--- a/packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl
+++ b/packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl
@@ -63,6 +63,7 @@ cdl_package CYGPKG_HAL_ARM_EBSA285 {
 	puts $::cdl_header "#define HAL_PLATFORM_CPU    \"StrongARM 110\""
         puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"EBSA-285\""
         puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header "#define HAL_ARCH_PROGRAM_NEW_STACK ebsa285_program_new_stack"
     }
 
     cdl_component CYG_HAL_STARTUP {
--- a/packages/hal/arm/ebsa285/current/include/hal_cache.h
+++ b/packages/hal/arm/ebsa285/current/include/hal_cache.h
@@ -90,8 +90,8 @@ CYG_MACRO_START                         
         "mrc  p15,0,r1,c1,c0,0;"                                        \
         "bic  r1,r1,#0x000C;" /* but leave MM alone */                  \
         "mcr  p15,0,r1,c1,c0,0;"                                        \
-        "mov    r1, #0;"                                                \
-        "mcr    p15,0,r1,c7,c6,0" /* clear data cache */                \
+        "mov    r1,#0;"                                                 \
+        "mcr  p15,0,r1,c7,c6,0" /* clear data cache */                  \
         :                                                               \
         :                                                               \
         : "r1" /* Clobber list */                                       \
@@ -103,12 +103,12 @@ CYG_MACRO_END
 CYG_MACRO_START                                                         \
     /* this macro can discard dirty cache lines. */                     \
     asm volatile (                                                      \
-        "mov    r1, #0;"                                                \
+        "mov    r1,#0;"                                                 \
         "mcr    p15,0,r1,c7,c6,0;"  /* clear data cache */              \
         "mcr    p15,0,r1,c8,c7,0;"  /* flush I+D TLBs */                \
         :                                                               \
         :                                                               \
-        : "r1" /* Clobber list */                                       \
+        : "r1","memory" /* Clobber list */                              \
         );                                                              \
 CYG_MACRO_END
      
@@ -126,15 +126,9 @@ CYG_MACRO_START                         
         "ldr    r2, [r0], #32;"                                         \
         "teq    r1, r0;"                                                \
         "bne    667b;"                                                  \
-        "mov    r0, #0;"                                                \
+        "mov    r0,#0;"                                                 \
         "mcr    p15,0,r0,c7,c6,0;"  /* clear data cache */              \
         "mcr    p15,0,r0,c7,c10,4;" /* and drain the write buffer */    \
-        "nop;"  /* wait for the writethrough to occur... */             \
-        "nop;"                                                          \
-        "nop;"                                                          \
-        "nop;"                                                          \
-        "nop;"                                                          \
-        "nop"                                                           \
         :                                                               \
         :                                                               \
         : "r0","r1","r2" /* Clobber list */                             \
@@ -187,50 +181,53 @@ CYG_MACRO_END
 
 // Write dirty cache lines to memory and invalidate the cache entries
 // for the given address range.
-// ---- this seems not to work despite the documentation ---
-//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
-//CYG_MACRO_START
-//    HAL_DCACHE_STORE( _base_ , _size_ );
-//    HAL_DCACHE_INVALIDATE( _base_ , _size_ );
-//CYG_MACRO_END
+#define HAL_DCACHE_FLUSH( _base_ , _size_ )     \
+CYG_MACRO_START                                 \
+    HAL_DCACHE_STORE( _base_ , _size_ );        \
+    HAL_DCACHE_INVALIDATE( _base_ , _size_ );   \
+CYG_MACRO_END
 
 // Invalidate cache lines in the given range without writing to memory.
-// ---- this seems not to work despite the documentation ---
-//#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
-//CYG_MACRO_START
-//    register int addr, enda;
-//    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),
-//              enda = (int)(_base_) + (_size_);
-//          addr < enda ;
-//          addr += HAL_DCACHE_LINE_SIZE )
-//    {
-//        asm volatile (
-//                      "mcr  p15,0,%0,c7,c6,1;" /* flush entry away */
-//                      :
-//                      : "r"(addr)
-//                      : "memory"
-//            );
-//    }
-//CYG_MACRO_END
+#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )                        \
+CYG_MACRO_START                                                         \
+    register int addr, enda;                                            \
+    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),         \
+              enda = (int)(_base_) + (_size_);                          \
+          addr < enda ;                                                 \
+          addr += HAL_DCACHE_LINE_SIZE )                                \
+    {                                                                   \
+        asm volatile (                                                  \
+                      "mcr  p15,0,%0,c7,c6,1;" /* flush entry away */   \
+                      :                                                 \
+                      : "r"(addr)                                       \
+                      : "memory"                                        \
+            );                                                          \
+    }                                                                   \
+CYG_MACRO_END
                           
 // Write dirty cache lines to memory for the given address range.
-// ---- this seems not to work despite the documentation ---
-//#define HAL_DCACHE_STORE( _base_ , _size_ )
-//CYG_MACRO_START
-//    register int addr, enda;
-//    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),
-//              enda = (int)(_base_) + (_size_);
-//          addr < enda ;
-//          addr += HAL_DCACHE_LINE_SIZE )
-//    {
-//        asm volatile ("mcr  p15,0,%0,c7,c10,1" /* push entry to RAM */
-//                      :
-//                      : "r"(addr)
-//                      : "memory"
-//            );
-//    }
-//CYG_MACRO_END
-
+#define HAL_DCACHE_STORE( _base_ , _size_ )                             \
+CYG_MACRO_START                                                         \
+    register int addr, enda;                                            \
+    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),         \
+              enda = (int)(_base_) + (_size_);                          \
+          addr < enda ;                                                 \
+          addr += HAL_DCACHE_LINE_SIZE )                                \
+    {                                                                   \
+        asm volatile ("mcr  p15,0,%0,c7,c10,1;" /* push entry to RAM */ \
+                      :                                                 \
+                      : "r"(addr)                                       \
+                      : "memory"                                        \
+            );                                                          \
+    }                                                                   \
+    /* and also drain the write buffer */                               \
+    asm volatile (                                                      \
+        "mov    r1,#0;"                                                 \
+        "mcr    p15,0,r1,c7,c10,4;"                                     \
+        :                                                               \
+        :                                                               \
+        : "r1", "memory" );                                             \
+CYG_MACRO_END
 
 // Preread the given range into the cache with the intention of reading
 // from it later.
--- a/packages/hal/arm/ebsa285/current/misc/redboot_RAM.cfg
+++ b/packages/hal/arm/ebsa285/current/misc/redboot_RAM.cfg
@@ -73,4 +73,7 @@ cdl_component CYGBLD_BUILD_REDBOOT {
     user_value 1
 };
 
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
 
--- a/packages/hal/arm/ebsa285/current/misc/redboot_ROM.cfg
+++ b/packages/hal/arm/ebsa285/current/misc/redboot_ROM.cfg
@@ -77,4 +77,7 @@ cdl_component CYGBLD_BUILD_REDBOOT {
     user_value 1
 };
 
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
 
--- a/packages/hal/arm/ebsa285/current/src/ebsa285_misc.c
+++ b/packages/hal/arm/ebsa285/current/src/ebsa285_misc.c
@@ -467,5 +467,20 @@ void hal_interrupt_set_level(int vector,
     // No interrupts are configurable on this hardware
 }
 
+#include CYGHWR_MEMORY_LAYOUT_H
+typedef void code_fun(void);
+void ebsa285_program_new_stack(void *func)
+{
+    register CYG_ADDRESS stack_ptr asm("sp");
+    register CYG_ADDRESS old_stack asm("r4");
+    register code_fun *new_func asm("r0");
+    old_stack = stack_ptr;
+    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
+    new_func = (code_fun*)func;
+    new_func();
+    stack_ptr = old_stack;
+    return;
+}
+
 /*------------------------------------------------------------------------*/
 // EOF ebsa285_misc.c
--- a/packages/hal/arm/ebsa285/current/src/redboot_cmds.c
+++ b/packages/hal/arm/ebsa285/current/src/redboot_cmds.c
@@ -49,11 +49,13 @@
 #include <cyg/hal/hal_intr.h>
 #include <cyg/hal/hal_cache.h>
 
-
 // Exported CLI function(s)
+static void do_exec(int argc, char *argv[]);
 RedBoot_cmd("exec", 
             "Execute an image - with MMU off", 
-            "[-w timeout] [<entry_point>]",
+            "[-w timeout] [-b <load addr> [-l <length>]] 
+             [-r <ramdisk addr> [-s <ramdisk length>]] 
+             [-c \"kernel command line\"] [<entry_point>]",
             do_exec
     );
 
@@ -67,11 +69,20 @@ do_exec(int argc, char *argv[])
     code_fun *fun, *prg;
     bool wait_time_set;
     int  wait_time, res, i;
-    bool base_addr_set, length_set;
+    bool base_addr_set, length_set, cmd_line_set;
+    bool ramdisk_addr_set, ramdisk_size_set;
     unsigned long base_addr, length;
-    struct option_info opts[3];
+    unsigned long ramdisk_addr, ramdisk_size;
+    struct option_info opts[6];
     char line[8];
     unsigned long *_prg, *ip;
+    char *cmd_line;
+    struct param_struct {
+        unsigned long key;
+        unsigned long rd_start;
+        unsigned long rd_size;
+        unsigned char cmdline[256];
+    } *params = (struct param_struct *)0x100;
 
     entry = (unsigned long)entry_address;  // Default from last 'load' operation
     base_addr = 0x8000;
@@ -81,15 +92,36 @@ do_exec(int argc, char *argv[])
               (void **)&base_addr, (bool *)&base_addr_set, "base address");
     init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, 
               (void **)&length, (bool *)&length_set, "length");
-    if (!scan_opts(argc, argv, 1, opts, 3, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
+    init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_STR, 
+              (void **)&cmd_line, (bool *)&cmd_line_set, "kernel command line");
+    init_opts(&opts[4], 'r', true, OPTION_ARG_TYPE_NUM, 
+              (void **)&ramdisk_addr, (bool *)&ramdisk_addr_set, "ramdisk_addr");
+    init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, 
+              (void **)&ramdisk_size, (bool *)&ramdisk_size_set, "ramdisk_size");
+    if (!scan_opts(argc, argv, 1, opts, 6, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
     {
         return;
     }
+    if (cmd_line_set || ramdisk_addr_set) {
+        params->key = 0xDEADF00D;;
+        params->rd_size = 0;
+    }
+    if (cmd_line_set) {
+        strcpy(params->cmdline, cmd_line);
+    }
+    if (ramdisk_addr_set) {
+        params->rd_start = ramdisk_addr;
+        if (ramdisk_size_set) {
+            params->rd_size = ramdisk_size;
+        } else {
+            params->rd_size = 4096*1024;
+        }
+    }
     if (wait_time_set) {
         printf("About to start execution at %p - abort with ^C within %d seconds\n",
                (void *)entry, wait_time);
         res = gets(line, sizeof(line), wait_time*1000);
-        if (res == -2) {
+        if (res == _GETS_CTRLC) {
             return;
         }
     }
--- a/packages/hal/arm/edb7xxx/current/ChangeLog
+++ b/packages/hal/arm/edb7xxx/current/ChangeLog
@@ -1,3 +1,18 @@
+2000-12-04  Hugo Tyson  <hmt@redhat.com>
+
+	* include/hal_cache.h: Consistently ensure that ARM registers used
+	in MCR ops to cache-control coprocessors, where the data doesn't
+	matter, all actually have data zero ("SBZ") as in the Jaggar book.
+	This may well not be necessary, but for the sake of making sure...
+
+2000-12-04  Gary Thomas  <gthomas@redhat.com>
+
+	* include/hal_platform_setup.h: Reenable caching on FLASH/ROM.
+
+	* include/hal_cache.h: Update cache macros to follow ARM
+	and Cirrus Logic manuals more closely.  These changes seem
+	to allow for cacheable FLASH segments.
+
 2000-11-06  Jesper Skov  <jskov@redhat.com>
 
 	* tests/dram_test.c: Add kernel check.
--- a/packages/hal/arm/edb7xxx/current/include/hal_cache.h
+++ b/packages/hal/arm/edb7xxx/current/include/hal_cache.h
@@ -100,25 +100,25 @@
 #define HAL_UCACHE_ENABLE()                     \
 {                                               \
     asm volatile ("mov  r1,#0x7D;"              \
-                  "mcr  p15,0,r1,c1,c0,0;"        \
+                  "mcr  p15,0,r1,c1,c0,0;"      \
                   :                             \
                   :                             \
                   : "r1" /* Clobber list */     \
         );                                      \
-                                                \
 }
 
 // Disable the data cache
-#define HAL_UCACHE_DISABLE()                    \
-{                                               \
-    asm volatile ("mov  r1,#0x71;"              \
-                  "mcr  p15,0,r1,c1,c0,0;"        \
-                  "mcr  p15,0,r1,c8,c7,0;"  /* flush I+D TLBs */                \
-                  :                             \
-                  :                             \
-                  : "r1" /* Clobber list */     \
-        );                                      \
-                                                \
+#define HAL_UCACHE_DISABLE()                                            \
+{                                                                       \
+    asm volatile ("mov  r1,#0x71;"                                      \
+                  "mcr  p15,0,r1,c1,c0,0;"                              \
+                  "mov  r1,#0;"                                         \
+                  "mcr  p15,0,r1,c8,c7,0;"  /* flush I+D TLBs */        \
+                  "nop; nop; nop; nop; nop;"                            \
+                  :                                                     \
+                  :                                                     \
+                  : "r1" /* Clobber list */                             \
+        );                                                              \
 }
 #endif
 
@@ -127,21 +127,27 @@
 
 // Invalidate the entire cache
 //    mcr  MMU_CP,0,r1,MMU_InvalidateCache,c0
-#define HAL_UCACHE_INVALIDATE_ALL()                             \
-{                                                               \
-    asm volatile ("mcr p15,0,r1,c7,c7,0;" );                      \
-                                                                \
+#define HAL_UCACHE_INVALIDATE_ALL()             \
+{                                               \
+    asm volatile (                              \
+        "mov    r1,#0;"                         \
+	"mcr p15,0,r1,c7,c7,0;"                 \
+	:                                       \
+        :                                       \
+        : "r1","memory" /* Clobber list */      \
+    );                                          \
+                                                \
 }
 
 // Synchronize the contents of the cache with memory.
 #define HAL_UCACHE_SYNC()                                               \
 {                                                                       \
-    cyg_uint32 *ROM = (cyg_uint32 *)0xE0000000;                         \
+    cyg_uint32 *RAM = (cyg_uint32 *)0x00000000;                         \
     int i;                                                              \
     volatile cyg_uint32 val;                                            \
     for (i = 0;  i < HAL_UCACHE_SETS;  i++) {                           \
-        val = *ROM;                                                     \
-        ROM += HAL_UCACHE_LINE_SIZE;                                    \
+        val = *RAM;                                                     \
+        RAM += HAL_UCACHE_LINE_SIZE;                                    \
     }                                                                   \
 }
 
--- a/packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h
+++ b/packages/hal/arm/edb7xxx/current/include/hal_platform_setup.h
@@ -427,7 +427,7 @@ 10:	orr	r0,r5,r6                        
 	ldr	r3,=ROM0_LA_START                                            ;\
 	ldr	r4,=ROM0_LA_END                                              ;\
 	ldr	r5,=ROM0_PA                                                  ;\
-	ldr	r6,=MMU_L1_TYPE_Section|MMU_AP_Any/*|MMU_Cacheable*/             ;\
+	ldr	r6,=MMU_L1_TYPE_Section|MMU_AP_Any|MMU_Cacheable             ;\
 	ldr	r7,=MMU_SECTION_SIZE                                         ;\
 10:	orr	r0,r5,r6                                                     ;\
 	str	r0,[r1],#4                                                   ;\
--- a/packages/hal/arm/sa11x0/assabet/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/assabet/current/ChangeLog
@@ -1,3 +1,18 @@
+2000-11-30  Gary Thomas  <gthomas@redhat.com>
+
+	* src/redboot_cmds.c (do_exec): Use new _GETS_xxx return codes.
+
+2000-11-28  Drew Moseley  <dmoseley@redhat.com>
+
+	* misc/redboot_RAM.cfg: Implement CYGSEM_REDBOOT_BSP_SYSCALLS.
+	* misc/redboot_ROM.cfg: Ditto.
+
+	* src/assabet_misc.c (assabet_program_new_stack): New function
+	for switching to an application stack when running a program under
+	a ROM monitor.
+
+	* cdl/hal_arm_sa11x0_assabet.cdl: Define HAL_ARCH_PROGRAM_NEW_STACK.
+
 2000-10-20  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* include/pkgconf/mlt_arm_sa11x0_assabet_ram.mlt:
--- a/packages/hal/arm/sa11x0/assabet/current/cdl/hal_arm_sa11x0_assabet.cdl
+++ b/packages/hal/arm/sa11x0/assabet/current/cdl/hal_arm_sa11x0_assabet.cdl
@@ -64,6 +64,7 @@ cdl_package CYGPKG_HAL_ARM_SA11X0_ASSABE
 	puts $::cdl_header "#define HAL_PLATFORM_CPU    \"StrongARM 1110\""
         puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Assabet development system\""
         puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header "#define HAL_ARCH_PROGRAM_NEW_STACK assabet_program_new_stack"
     }
 
     cdl_component CYG_HAL_STARTUP {
--- a/packages/hal/arm/sa11x0/assabet/current/misc/redboot_RAM.cfg
+++ b/packages/hal/arm/sa11x0/assabet/current/misc/redboot_RAM.cfg
@@ -70,4 +70,6 @@ cdl_option CYGSEM_REDBOOT_FLASH_CONFIG {
     user_value 1
 };
 
-
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
--- a/packages/hal/arm/sa11x0/assabet/current/misc/redboot_ROM.cfg
+++ b/packages/hal/arm/sa11x0/assabet/current/misc/redboot_ROM.cfg
@@ -74,4 +74,6 @@ cdl_option CYGSEM_REDBOOT_FLASH_CONFIG {
     user_value 1
 };
 
-
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
--- a/packages/hal/arm/sa11x0/assabet/current/src/assabet_misc.c
+++ b/packages/hal/arm/sa11x0/assabet/current/src/assabet_misc.c
@@ -246,3 +246,18 @@ plf_hardware_init(void)
     *SA11X0_GPIO_PIN_DIRECTION |= 0x000003FC;  // Bits 2..9
     *SA11X0_GPIO_PIN_OUTPUT_CLEAR = 0x000003FC;  // Bits 2..9
 }
+
+#include CYGHWR_MEMORY_LAYOUT_H
+typedef void code_fun(void);
+void assabet_program_new_stack(void *func)
+{
+    register CYG_ADDRESS stack_ptr asm("sp");
+    register CYG_ADDRESS old_stack asm("r4");
+    register code_fun *new_func asm("r0");
+    old_stack = stack_ptr;
+    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
+    new_func = (code_fun*)func;
+    new_func();
+    stack_ptr = old_stack;
+    return;
+}
--- a/packages/hal/arm/sa11x0/assabet/current/src/redboot_cmds.c
+++ b/packages/hal/arm/sa11x0/assabet/current/src/redboot_cmds.c
@@ -83,7 +83,7 @@ do_exec(int argc, char *argv[])
         printf("About to start execution at %p - abort with ^C within %d seconds\n",
                (void *)entry, wait_time);
         res = gets(line, sizeof(line), wait_time*1000);
-        if (res == -2) {
+        if (res == _GETS_CTRLC) {
             return;
         }
     }
--- a/packages/hal/arm/sa11x0/brutus/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/brutus/current/ChangeLog
@@ -1,3 +1,14 @@
+2000-11-28  Drew Moseley  <dmoseley@redhat.com>
+
+	* misc/redboot_RAM.cfg: Implement CYGSEM_REDBOOT_BSP_SYSCALLS.
+	* misc/redboot_ROM.cfg: Ditto.
+
+	* src/brutus_misc.c (brutus_program_new_stack): New function
+	for switching to an application stack when running a program under
+	a ROM monitor.
+
+	* cdl/hal_arm_sa11x0_brutus.cdl: Define HAL_ARCH_PROGRAM_NEW_STACK.
+
 2000-11-25  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* misc/redboot_RAM.cfg: Added new import file for redboot
--- a/packages/hal/arm/sa11x0/brutus/current/cdl/hal_arm_sa11x0_brutus.cdl
+++ b/packages/hal/arm/sa11x0/brutus/current/cdl/hal_arm_sa11x0_brutus.cdl
@@ -64,6 +64,7 @@ cdl_package CYGPKG_HAL_ARM_SA11X0_BRUTUS
 	puts $::cdl_header "#define HAL_PLATFORM_CPU    \"StrongARM 1100\""
         puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"Brutus development system\""
         puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header "#define HAL_ARCH_PROGRAM_NEW_STACK brutus_program_new_stack"
     }
 
     cdl_component CYG_HAL_STARTUP {
--- a/packages/hal/arm/sa11x0/brutus/current/misc/redboot_RAM.cfg
+++ b/packages/hal/arm/sa11x0/brutus/current/misc/redboot_RAM.cfg
@@ -55,3 +55,7 @@ cdl_component CYG_HAL_STARTUP {
 cdl_option CYGBLD_BUILD_REDBOOT {
     user_value 1
 };
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
--- a/packages/hal/arm/sa11x0/brutus/current/misc/redboot_ROM.cfg
+++ b/packages/hal/arm/sa11x0/brutus/current/misc/redboot_ROM.cfg
@@ -59,3 +59,7 @@ cdl_component CYG_HAL_STARTUP {
 cdl_option CYGBLD_BUILD_REDBOOT {
     user_value 1
 };
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
--- a/packages/hal/arm/sa11x0/brutus/current/src/brutus_misc.c
+++ b/packages/hal/arm/sa11x0/brutus/current/src/brutus_misc.c
@@ -225,3 +225,18 @@ void
 plf_hardware_init(void)
 {
 }
+
+#include CYGHWR_MEMORY_LAYOUT_H
+typedef void code_fun(void);
+void brutus_program_new_stack(void *func)
+{
+    register CYG_ADDRESS stack_ptr asm("sp");
+    register CYG_ADDRESS old_stack asm("r4");
+    register code_fun *new_func asm("r0");
+    old_stack = stack_ptr;
+    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
+    new_func = (code_fun*)func;
+    new_func();
+    stack_ptr = old_stack;
+    return;
+}
--- a/packages/hal/arm/sa11x0/var/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/var/current/ChangeLog
@@ -1,3 +1,22 @@
+2000-12-04  Hugo Tyson  <hmt@redhat.com>
+
+	* include/hal_cache.h: Consistently ensure that ARM registers used
+	in MCR ops to cache-control coprocessors, where the data doesn't
+	matter, all actually have data zero ("SBZ") as in the Jaggar book.
+	This may well not be necessary, but for the sake of making sure...
+
+2000-12-01  Hugo Tyson  <hmt@redhat.com>
+
+	* include/hal_cache.h: Define addressable cache line operations
+	HAL_DCACHE_STORE(), HAL_DCACHE_INVALIDATE(), HAL_DCACHE_FLUSH()
+	now that I have understood how come the test (kcache2) was
+	failing.  See kernel ChangeLog for details.  Also tidied up a
+	couple of other minor details.
+
+2000-11-27  Gary Thomas  <gthomas@redhat.com>
+
+	* src/hal_diag.c (init_channel): UART setup required on Brutus as well.
+
 2000-11-21  Gary Thomas  <gthomas@redhat.com>
 
 	* src/hal_diag.c (init_channel): Disable broken uart setups on platforms
--- a/packages/hal/arm/sa11x0/var/current/include/hal_cache.h
+++ b/packages/hal/arm/sa11x0/var/current/include/hal_cache.h
@@ -96,6 +96,7 @@ CYG_MACRO_START                         
         "mrc    p15,0,r1,c1,c0,0;"                                      \
         "bic    r1,r1,#0x1000;" /* disable ICache (but not MMU, etc) */ \
         "mcr    p15,0,r1,c1,c0,0;"                                      \
+        "mov    r1,#0;"                                                 \
         "mcr    p15,0,r1,c7,c5,0;"  /* flush ICache */                  \
         "nop;" /* next few instructions may be via cache    */          \
         "nop;"                                                          \
@@ -125,6 +126,7 @@ CYG_MACRO_END
 CYG_MACRO_START                                                         \
     /* this macro can discard dirty cache lines (N/A for ICache) */     \
     asm volatile (                                                      \
+        "mov    r1,#0;"                                                 \
         "mcr    p15,0,r1,c7,c5,0;"  /* flush ICache */                  \
         "mcr    p15,0,r1,c8,c5,0;"  /* flush ITLB only */               \
         "nop;" /* next few instructions may be via cache    */          \
@@ -135,6 +137,7 @@ CYG_MACRO_START                         
         "nop;"                                                          \
         :                                                               \
         :                                                               \
+        : "r1" /* Clobber list */                                       \
         );                                                              \
 CYG_MACRO_END
 
@@ -196,6 +199,7 @@ CYG_MACRO_START                         
         "bic  r1,r1,#0x000C;" /* disable DCache AND write buffer  */    \
                               /* but not MMU and alignment faults */    \
         "mcr  p15,0,r1,c1,c0,0;"                                        \
+        "mov    r1,#0;"                                                 \
         "mcr  p15,0,r1,c7,c6,0" /* clear data cache */                  \
         :                                                               \
         :                                                               \
@@ -216,11 +220,14 @@ CYG_MACRO_END
 
 // Flush the entire dcache (and then both TLBs, just in case)
 #define HAL_DCACHE_INVALIDATE_ALL()                                     \
-CYG_MACRO_START                                                         \
-    /* this macro can discard dirty cache lines. */                     \
-    asm volatile ("mcr    p15,0,r1,c7,c6,0;"                            \
-                  "mcr    p15,0,r1,c8,c7,0;"                            \
-                  : : );                                                \
+CYG_MACRO_START    /* this macro can discard dirty cache lines. */      \
+    asm volatile (                                                      \
+        "mov    r1,#0;"                                                 \
+	"mcr    p15,0,r1,c7,c6,0;"                                      \
+        "mcr    p15,0,r1,c8,c7,0;"                                      \
+        :                                                               \
+	:                                                               \
+	: "r1","memory" );                                              \
 CYG_MACRO_END
 
 
@@ -237,14 +244,9 @@ CYG_MACRO_START                         
         "ldr    r2, [r0], #32;"                                         \
         "teq    r1, r0;"                                                \
         "bne    667b;"                                                  \
+        "mov    r0,#0;"                                                 \
         "mcr    p15,0,r0,c7,c6,0;"  /* flush DCache */                  \
         "mcr    p15,0,r0,c7,c10,4;" /* and drain the write buffer */    \
-        "nop;"  /* wait for the writebacks to occur...     */           \
-        "nop;"                                                          \
-        "nop;"                                                          \
-        "nop;"                                                          \
-        "nop;"                                                          \
-        "nop;"                                                          \
         :                                                               \
         :                                                               \
         : "r0","r1","r2" /* Clobber list */                             \
@@ -290,49 +292,54 @@ CYG_MACRO_END
 
 // Write dirty cache lines to memory and invalidate the cache entries
 // for the given address range.
-// ---- this seems not to work despite the documentation ---
-//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
-//CYG_MACRO_START
-//    HAL_DCACHE_STORE( _base_ , _size_ );
-//    HAL_DCACHE_INVALIDATE( _base_ , _size_ );
-//CYG_MACRO_END
+#define HAL_DCACHE_FLUSH( _base_ , _size_ )     \
+CYG_MACRO_START                                 \
+    HAL_DCACHE_STORE( _base_ , _size_ );        \
+    HAL_DCACHE_INVALIDATE( _base_ , _size_ );   \
+CYG_MACRO_END
 
 // Invalidate cache lines in the given range without writing to memory.
-// ---- this seems not to work despite the documentation ---
-//#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
-//CYG_MACRO_START
-//    register int addr, enda;
-//    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),
-//              enda = (int)(_base_) + (_size_);
-//          addr < enda ;
-//          addr += HAL_DCACHE_LINE_SIZE )
-//    {
-//        asm volatile (
-//                      "mcr  p15,0,%0,c7,c6,1;" /* flush entry away */
-//                      :
-//                      : "r"(addr)
-//                      : "memory"
-//            );
-//    }
-//CYG_MACRO_END
+#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )                        \
+CYG_MACRO_START                                                         \
+    register int addr, enda;                                            \
+    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),         \
+              enda = (int)(_base_) + (_size_);                          \
+          addr < enda ;                                                 \
+          addr += HAL_DCACHE_LINE_SIZE )                                \
+    {                                                                   \
+        asm volatile (                                                  \
+                      "mcr  p15,0,%0,c7,c6,1;" /* flush entry away */   \
+                      :                                                 \
+                      : "r"(addr)                                       \
+                      : "memory"                                        \
+            );                                                          \
+    }                                                                   \
+CYG_MACRO_END
                           
 // Write dirty cache lines to memory for the given address range.
-// ---- this seems not to work despite the documentation ---
-//#define HAL_DCACHE_STORE( _base_ , _size_ )
-//CYG_MACRO_START
-//    register int addr, enda;
-//    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),
-//              enda = (int)(_base_) + (_size_);
-//          addr < enda ;
-//          addr += HAL_DCACHE_LINE_SIZE )
-//    {
-//        asm volatile ("mcr  p15,0,%0,c7,c10,1;" /* push entry to RAM */
-//                      :
-//                      : "r"(addr)
-//                      : "memory"
-//            );
-//    }
-//CYG_MACRO_END
+#define HAL_DCACHE_STORE( _base_ , _size_ )                             \
+CYG_MACRO_START                                                         \
+    register int addr, enda;                                            \
+    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),         \
+              enda = (int)(_base_) + (_size_);                          \
+          addr < enda ;                                                 \
+          addr += HAL_DCACHE_LINE_SIZE )                                \
+    {                                                                   \
+        asm volatile ("mcr  p15,0,%0,c7,c10,1;" /* push entry to RAM */ \
+                      :                                                 \
+                      : "r"(addr)                                       \
+                      : "memory"                                        \
+            );                                                          \
+    }                                                                   \
+    /* and also drain the write buffer */                               \
+    asm volatile (                                                      \
+        "mov    r1,#0;"                                                 \
+	"mcr    p15,0,r1,c7,c10,4;"                                     \
+        :                                                               \
+        :                                                               \
+        : "r1", "memory" /* Clobber list */                             \
+    );                                                                  \
+CYG_MACRO_END
 
 // Preread the given range into the cache with the intention of reading
 // from it later.
--- a/packages/hal/arm/sa11x0/var/current/src/hal_diag.c
+++ b/packages/hal/arm/sa11x0/var/current/src/hal_diag.c
@@ -94,8 +94,8 @@ init_channel(channel_data_t* __ch_data)
     base->utsr0 = SA11X0_UART_RX_IDLE | SA11X0_UART_RX_BEGIN_OF_BREAK |
                   SA11X0_UART_RX_END_OF_BREAK;
 
-#ifdef CYGPKG_HAL_ARM_SA11X0_SA1100MM
-   // This code has problems on other SA11x0 platforms.
+#if defined(CYGPKG_HAL_ARM_SA11X0_SA1100MM) || defined(CYGPKG_HAL_ARM_SA11X0_BRUTUS)
+   // This setup is specific to only a few boards.
    if (SA11X0_UART1_BASE == (volatile unsigned long *)base) {
         cyg_uint32 pdr, afr, par;
 
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,16 @@
+2000-12-06  Jesper Skov  <jskov@redhat.com>
+
+	* src/hal_if.c (delay_us): Ensure proper _GP save/restore.
+	Reduce number of loops in fall-back code.
+
+2000-12-05  Drew Moseley  <dmoseley@redhat.com>
+
+	* src/hal_stub.c (__build_t_packet): Handle
+	CYGARC_REGSIZE_DIFFERS_FROM_TARGET_REGISTER_T with Little Endian
+	target.
+
+	* include/hal_misc.h: Added BIT and SZ_ defines.
+
 2000-11-22  Mark Salter  <msalter@redhat.com>
 
 	* src/hal_misc.c (hal_default_isr): Version check only when
--- a/packages/hal/common/current/include/hal_misc.h
+++ b/packages/hal/common/current/include/hal_misc.h
@@ -44,10 +44,69 @@
 //
 //=============================================================================
 
+#ifndef __ASSEMBLER__
 #include <cyg/infra/cyg_type.h>         // types & externC
 
 externC cyg_bool cyg_hal_is_break(char *buf, int size);
 externC void cyg_hal_user_break( CYG_ADDRWORD *regs );
+#endif
+
+//=============================================================================
+
+#define BIT0            0x00000001
+#define BIT1            0x00000002
+#define BIT2            0x00000004
+#define BIT3            0x00000008
+#define BIT4            0x00000010
+#define BIT5            0x00000020
+#define BIT6            0x00000040
+#define BIT7            0x00000080
+#define BIT8            0x00000100
+#define BIT9            0x00000200
+#define BIT10           0x00000400
+#define BIT11           0x00000800
+#define BIT12           0x00001000
+#define BIT13           0x00002000
+#define BIT14           0x00004000
+#define BIT15           0x00008000
+#define BIT16           0x00010000
+#define BIT17           0x00020000
+#define BIT18           0x00040000
+#define BIT19           0x00080000
+#define BIT20           0x00100000
+#define BIT21           0x00200000
+#define BIT22           0x00400000
+#define BIT23           0x00800000
+#define BIT24           0x01000000
+#define BIT25           0x02000000
+#define BIT26           0x04000000
+#define BIT27           0x08000000
+#define BIT28           0x10000000
+#define BIT29           0x20000000
+#define BIT30           0x40000000
+#define BIT31           0x80000000
+
+#define SZ_1K           0x00000400
+#define SZ_2K           0x00000800
+#define SZ_4K           0x00001000
+#define SZ_8K           0x00002000
+#define SZ_16K          0x00004000
+#define SZ_32K          0x00008000
+#define SZ_64K          0x00010000
+#define SZ_128K         0x00020000
+#define SZ_256K         0x00040000
+#define SZ_512K         0x00080000
+#define SZ_1M           0x00100000
+#define SZ_2M           0x00200000
+#define SZ_4M           0x00400000
+#define SZ_8M           0x00800000
+#define SZ_16M          0x01000000
+#define SZ_32M          0x02000000
+#define SZ_64M          0x04000000
+#define SZ_128M         0x08000000
+#define SZ_256M         0x10000000
+#define SZ_512M         0x20000000
+#define SZ_1G           0x40000000
 
 //-----------------------------------------------------------------------------
 #endif // CYGONCE_HAL_HAL_MISC_H
--- a/packages/hal/common/current/src/hal_if.c
+++ b/packages/hal/common/current/src/hal_if.c
@@ -73,37 +73,37 @@ externC void init_thread_syscall(void * 
 static void
 delay_us(cyg_int32 usecs)
 {
+    CYGARC_HAL_SAVE_GP();
 #ifdef CYGPKG_KERNEL
-    cyg_int32 start, elapsed;
-    cyg_int32 usec_ticks, slice;
-    CYGARC_HAL_SAVE_GP();
+    {
+        cyg_int32 start, elapsed;
+        cyg_int32 usec_ticks, slice;
 
-    // How many ticks total we should wait for.
-    usec_ticks = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
-    usec_ticks /= CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000;
+        // How many ticks total we should wait for.
+        usec_ticks = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+        usec_ticks /= CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000;
 
-    do {
-        // Spin in slices of 1/2 the RTC period. Allows interrupts
-        // time to run without messing up the algorithm. If we spun
-        // for 1 period (or more) of the RTC, there'd be also problems
-        // figuring out when the timer wrapped.  We may lose a tick or
-        // two for each cycle but it shouldn't matter much.
-        slice = usec_ticks % (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD / 2);
+        do {
+            // Spin in slices of 1/2 the RTC period. Allows interrupts
+            // time to run without messing up the algorithm. If we spun
+            // for 1 period (or more) of the RTC, there'd be also problems
+            // figuring out when the timer wrapped.  We may lose a tick or
+            // two for each cycle but it shouldn't matter much.
+            slice = usec_ticks % (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD / 2);
     
-        HAL_CLOCK_READ(&start);
-        do {
-            HAL_CLOCK_READ(&elapsed);
-            elapsed = (elapsed - start); // counts up!
-            if (elapsed < 0)
-                elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
-        } while (elapsed < slice);
-
-        // Adjust by elapsed, not slice, since an interrupt may have
-        // been stalling us for some time.
-        usec_ticks -= elapsed;
-    } while (usec_ticks > 0);
-
-    CYGARC_HAL_RESTORE_GP();
+            HAL_CLOCK_READ(&start);
+            do {
+                HAL_CLOCK_READ(&elapsed);
+                elapsed = (elapsed - start); // counts up!
+                if (elapsed < 0)
+                    elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+            } while (elapsed < slice);
+            
+            // Adjust by elapsed, not slice, since an interrupt may have
+            // been stalling us for some time.
+            usec_ticks -= elapsed;
+        } while (usec_ticks > 0);
+    }
 #else
 #ifdef HAL_DELAY_US
     // Use a HAL feature if defined
@@ -111,16 +111,17 @@ delay_us(cyg_int32 usecs)
 #else
     // If no accurate delay mechanism, just spin for a while. Having
     // an inaccurate delay is much better than no delay at all. The
-    // count of 100 should mean the loop takes something resembling
+    // count of 10 should mean the loop takes something resembling
     // 1us on most CPUs running between 30-100MHz [depends on how many
     // instructions this compiles to, how many dispatch units can be
     // used for the simple loop, actual CPU frequency, etc]
     while (usecs-- > 0) {
         int i;
-        for (i = 0; i < 100; i++);
+        for (i = 0; i < 10; i++);
     }
 #endif
 #endif
+    CYGARC_HAL_RESTORE_GP();
 }
 
 static void
--- a/packages/hal/common/current/src/hal_stub.c
+++ b/packages/hal/common/current/src/hal_stub.c
@@ -647,6 +647,7 @@ void
 {
     target_register_t addr;
     char *ptr = buf;
+    target_register_t extend_val = 0;
 
     *ptr++ = 'T';
     *ptr++ = __tohex (sigval >> 4);
@@ -713,7 +714,6 @@ void
         // GDB is expecting REGSIZE(PC) number of bytes.
         // We only have sizeof(addr) number.  Let's fill
         // the appropriate number of bytes intelligently.
-        target_register_t extend_val = 0;
 #ifdef CYGARC_SIGN_EXTEND_REGISTERS
         {
             unsigned long bits_in_addr = (sizeof(addr) << 3);  // ie Size in bytes * 8
@@ -722,9 +722,14 @@ void
                 extend_val = ~0;
         }
 #endif
-        ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
     }
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+    ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
+#endif
     ptr = __mem2hex((char *)&addr, ptr, sizeof(addr), 0);
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+    ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
+#endif
     *ptr++ = ';';
 
     *ptr++ = __tohex (SP >> 4);
--- a/packages/hal/i386/pc/current/ChangeLog
+++ b/packages/hal/i386/pc/current/ChangeLog
@@ -1,6 +1,12 @@
+2000-12-05  Hugo Tyson  <hmt@redhat.com>
+
+	* src/plf_misc.c (hal_pc_fpe_dsr): Raise the base stack address by
+	CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE if that is defined;
+	otherwise a stack overflow would immediately be reported.
+
 2000-11-02  Fabrice Gautier <Fabrice_Gautier@sdesigns.com>
 
-        * src/platform.inc (hal_cpu_init): Load image from floppy one
+	* src/platform.inc (hal_cpu_init): Load image from floppy one
         sector at a time to avoid "DMA access across 64k boundary" error.
 
 2000-10-20  Jonathan Larmour  <jlarmour@redhat.com>
--- a/packages/hal/i386/pc/current/src/plf_misc.c
+++ b/packages/hal/i386/pc/current/src/plf_misc.c
@@ -107,6 +107,10 @@ void hal_pc_fpe_dsr(CYG_ADDRWORD vector,
         if (hal_pc_fpe_owner)
         {	/* Then save his state at the bottom of his stack. */
             stack = cyg_thread_get_stack_base(hal_pc_fpe_owner) ;
+#ifdef CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE
+            // It might well be zero anyway
+            stack += CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
+#endif
             p = (cyg_uint32*) stack ;
             stack = (cyg_addrword_t) &(p[1]);
             asm("movl %0, %%eax
@@ -118,6 +122,9 @@ fsave (%%eax)"
         }
         hal_pc_fpe_owner = me ;
         stack = cyg_thread_get_stack_base(hal_pc_fpe_owner) ;
+#ifdef CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE
+        stack += CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
+#endif
         p = (cyg_uint32*) stack ;
         if (p[0] == 0xCAFEBABE)
         {
--- a/packages/hal/mips/arch/current/ChangeLog
+++ b/packages/hal/mips/arch/current/ChangeLog
@@ -1,3 +1,19 @@
+2000-12-06  Jesper Skov  <jskov@redhat.com>
+
+	* include/hal_intr.h (HAL_DELAY_US): Added.
+	* src/hal_misc.c (hal_delay_us): Added. And fixed to work with an
+	incrementer that ticks at the pipeline clock rate.
+
+2000-12-05  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* include/hal_cache.h: IWAY->_IWAY, DWAY->_DWAY for namespace 
+	cleanliness
+
+2000-12-05  Jesper Skov  <jskov@redhat.com>
+
+	* include/hal_cache.h: Use variant specific method to select cache
+	WAY.
+
 2000-10-20  Jesper Skov  <jskov@redhat.com>
 
 	* src/hal_misc.c: Update __mem_fault_handler declaration.
--- a/packages/hal/mips/arch/current/include/hal_cache.h
+++ b/packages/hal/mips/arch/current/include/hal_cache.h
@@ -91,24 +91,39 @@
 #endif
 
 //-----------------------------------------------------------------------------
-// Cache instruction uses LSB to specify which WAY to affect. This macro
-// defines the necessary cache instructions to affect all ways.
+// Cache instruction uses LSBs or MSBs (depending on the
+// implementation) of the virtual address to specify which WAY to
+// affect. The _ALL_WAYS macro defines the necessary cache instructions
+// to affect all ways.
+
+#ifdef HAL_MIPS_CACHE_INSN_USES_LSB
+# define _IWAY(_n_) ((_n_)*HAL_ICACHE_SIZE/HAL_ICACHE_WAYS+(_n_))
+# define _DWAY(_n_) ((_n_)*HAL_DCACHE_SIZE/HAL_DCACHE_WAYS+(_n_))
+#else
+# define _IWAY(_n_) ((_n_)*HAL_ICACHE_SIZE/HAL_ICACHE_WAYS)
+# define _DWAY(_n_) ((_n_)*HAL_DCACHE_SIZE/HAL_DCACHE_WAYS)
+#endif
+
 #if (HAL_DCACHE_WAYS == 1)
 #define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )       \
     asm volatile ("cache %0,0(%1);"                      \
                     : : "I" ((_cmd_) | 1), "r"(_addr_) )
 #elif (HAL_DCACHE_WAYS == 2)
-#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )       \
-    asm volatile ("cache %0,0(%1);"                      \
-                  "cache %0,1(%1);"                      \
-                    : : "I" ((_cmd_) | 1), "r"(_addr_) )
+#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )      \
+    asm volatile ("cache %0,0(%1);"                     \
+                  "cache %0,%2(%1);"                    \
+                    : : "I" ((_cmd_) | 1), "r"(_addr_), \
+                        "I" (_DWAY(1)))
 #elif (HAL_DCACHE_WAYS == 4)
-#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )       \
-    asm volatile ("cache %0,0(%1);"                      \
-                  "cache %0,1(%1);"                      \
-                  "cache %0,2(%1);"                      \
-                  "cache %0,3(%1);"                      \
-                    : : "I" ((_cmd_) | 1), "r"(_addr_) )
+#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )      \
+    asm volatile ("cache %0,0(%1);"                     \
+                  "cache %0,%2(%1);"                    \
+                  "cache %0,%3(%1);"                    \
+                  "cache %0,%4(%1);"                    \
+                    : : "I" ((_cmd_) | 1), "r"(_addr_), \
+                        "I" (_DWAY(1)),                  \
+                        "I" (_DWAY(2)),                  \
+                        "I" (_DWAY(3)))
 #else
 # error "Unsupported number of ways"
 #endif
@@ -118,17 +133,21 @@
     asm volatile ("cache %0,0(%1);"                      \
                     : : "I" (_cmd_), "r"(_addr_) )
 #elif (HAL_ICACHE_WAYS == 2)
-#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )       \
-    asm volatile ("cache %0,0(%1);"                      \
-                  "cache %0,1(%1);"                      \
-                    : : "I" (_cmd_), "r"(_addr_) )
+#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )      \
+    asm volatile ("cache %0,0(%1);"                     \
+                  "cache %0,%2(%1);"                    \
+                    : : "I" (_cmd_), "r"(_addr_),       \
+                        "I" (_IWAY(1)))
 #elif (HAL_ICACHE_WAYS == 4)
-#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )       \
-    asm volatile ("cache %0,0(%1);"                      \
-                  "cache %0,1(%1);"                      \
-                  "cache %0,2(%1);"                      \
-                  "cache %0,3(%1);"                      \
-                    : : "I" (_cmd_), "r"(_addr_) )
+#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )      \
+    asm volatile ("cache %0,0(%1);"                     \
+                  "cache %0,%2(%1);"                    \
+                  "cache %0,%3(%1);"                    \
+                  "cache %0,%4(%1);"                    \
+                    : : "I" (_cmd_), "r"(_addr_),       \
+                        "I" (_IWAY(1)),                  \
+                        "I" (_IWAY(2)),                  \
+                        "I" (_IWAY(3)))
 #else
 # error "Unsupported number of ways"
 #endif
--- a/packages/hal/mips/arch/current/include/hal_intr.h
+++ b/packages/hal/mips/arch/current/include/hal_intr.h
@@ -495,6 +495,11 @@ CYG_MACRO_START                         
 CYG_MACRO_END
 #endif
 
+
+//--------------------------------------------------------------------------
+// Microsecond delay function provided in hal_misc.c
+#define HAL_DELAY_US(n)          hal_delay_us(n)
+
 //--------------------------------------------------------------------------
 #endif // ifndef CYGONCE_HAL_HAL_INTR_H
 // End of hal_intr.h
--- a/packages/hal/mips/arch/current/src/hal_misc.c
+++ b/packages/hal/mips/arch/current/src/hal_misc.c
@@ -339,6 +339,30 @@ cyg_uint32 hal_msbit_index(cyg_uint32 ma
 }
 
 /*------------------------------------------------------------------------*/
+/* Delay for some number of useconds.                                     */
+void 
+hal_delay_us(int us)
+{
+    cyg_uint32 val1, val2;
+    int diff;
+    long ticks;
+    // Scale the desired number of microseconds to be a number of
+    // incrementer ticks
+    ticks = us * (CYGNUM_HAL_RTC_PERIOD * CYGNUM_HAL_RTC_DENOMINATOR) / 1000000;
+
+    asm volatile("mfc0 %0,$9;" : "=r"(val1));
+    while (ticks > 0) {
+        do {
+            asm volatile("mfc0 %0,$9;" : "=r"(val2));
+        } while (val1 == val2);
+        diff = val2 - val1;
+        if (diff < 0) diff += CYGNUM_HAL_RTC_PERIOD;
+        ticks -= diff;
+        val1 = val2;
+    }
+}
+
+/*------------------------------------------------------------------------*/
 /* Idle thread action                                                     */
 
 #include <cyg/infra/diag.h>
--- a/packages/hal/mips/tx49/current/ChangeLog
+++ b/packages/hal/mips/tx49/current/ChangeLog
@@ -1,3 +1,8 @@
+2000-12-05  Jesper Skov  <jskov@redhat.com>
+
+	* include/var_cache.h (HAL_MIPS_CACHE_INSN_USES_LSB): The TX49
+	uses LSB in the cache macro.
+
 2000-09-12  Jesper Skov  <jskov@redhat.com>
 
 	* include/variant.inc: Enable div-by-zero FPU exceptions.
--- a/packages/hal/mips/tx49/current/include/var_cache.h
+++ b/packages/hal/mips/tx49/current/include/var_cache.h
@@ -77,6 +77,8 @@
 #define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
 #define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
 
+#define HAL_MIPS_CACHE_INSN_USES_LSB
+
 //-----------------------------------------------------------------------------
 // Cache controls
 
--- a/packages/hal/mn10300/arch/current/ChangeLog
+++ b/packages/hal/mn10300/arch/current/ChangeLog
@@ -1,3 +1,11 @@
+2000-11-30  Drew Moseley  <dmoseley@redhat.com>
+
+	* include/hal_arch.h: Handle Cygmon interrupt stack.  ie For
+	Cygmon we must switch to a new stack immediately on exception to
+	make sure that we don't modify the application stack at all since
+	GDB may be using it.
+	* src/vectors.S: Ditto.
+
 2000-10-20  Jesper Skov  <jskov@redhat.com>
 
 	* src/hal_misc.c: Update __mem_fault_handler declaration.
--- a/packages/hal/mn10300/arch/current/include/hal_arch.h
+++ b/packages/hal/mn10300/arch/current/include/hal_arch.h
@@ -165,6 +165,33 @@ asm volatile (" .globl  _" #_label_ ";" 
 
 // Copy a set of registers from a HAL_SavedRegisters structure into a
 // GDB ordered array.    
+//
+// The CYGMON version should differ by also handling SP and PSW
+// since we will be using a different stack.
+#ifdef CYGPKG_CYGMON
+#define HAL_GET_GDB_REGISTERS( _aregval_ , _regs_ )             \
+{                                                               \
+    CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_);       \
+                                                                \
+    _regval_[0]         = (_regs_)->d0;                         \
+    _regval_[1]         = (_regs_)->d1;                         \
+    _regval_[2]         = (_regs_)->d2;                         \
+    _regval_[3]         = (_regs_)->d3;                         \
+    _regval_[4]         = (_regs_)->a0;                         \
+    _regval_[5]         = (_regs_)->a1;                         \
+    _regval_[6]         = (_regs_)->a2;                         \
+    _regval_[7]         = (_regs_)->a3;                         \
+                                                                \
+    _regval_[8]         = (_regs_)->sp;                         \
+    _regval_[9]         = (_regs_)->pc;                         \
+    _regval_[10]        = (_regs_)->mdr;                        \
+    _regval_[11]        = (_regs_)->psw;                        \
+                                                                \
+    _regval_[12]        = (_regs_)->lar;                        \
+    _regval_[13]        = (_regs_)->lir;                        \
+    HAL_GET_GDB_EXTRA_REGISTERS( _regval_, _regs_ );            \
+}
+#else
 #define HAL_GET_GDB_REGISTERS( _aregval_ , _regs_ )             \
 {                                                               \
     CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_);       \
@@ -188,6 +215,7 @@ asm volatile (" .globl  _" #_label_ ";" 
     _regval_[13]        = (_regs_)->lir;                        \
     HAL_GET_GDB_EXTRA_REGISTERS( _regval_, _regs_ );            \
 }
+#endif
 
 // Copy a GDB ordered array into a HAL_SavedRegisters structure.
 //
--- a/packages/hal/mn10300/arch/current/src/vectors.S
+++ b/packages/hal/mn10300/arch/current/src/vectors.S
@@ -59,6 +59,67 @@
 	
 	.file	"vectors.S"
 
+#ifdef CYGPKG_CYGMON
+##-----------------------------------------------------------------------------
+## Macros for Stack handling when running Cygmon
+        		
+.macro hal_cygmon_switch_app_stack
+	#
+	# Switch to interrupt stack to handle exception
+	#
+
+	# First, save some scratch registers
+	mov	a2(a2_save)
+	mov	a3,(a3_save)
+
+	# Copy the exception frame
+	mov	__cygmon_interrupt_stack-8,a2
+	mov	(sp),a3				// Copy over the saved EPSW
+	mov	a3,(a2)
+	mov	(4,sp),a3			// Copy over the saved PC
+	mov	a3,(4,a2)
+
+	# Save the pre-exception sp in the register image	 
+	add	-4,a2				# space for SP
+	mov	sp,a3
+	add	8,a3				# adjust for exception frame
+	mov	a3,(a2)
+
+	# Actually switch the stack
+	mov	a2,sp
+
+	# Now, restore the scratch registers
+	mov	(a2_save),a2
+	mov	(a3_save),a3
+.endm
+
+.macro hal_cygmon_restore_app_stack
+	// For cygmon we are switching stacks immediately on exception.
+	// We must wait until the very end before restoring the original stack.
+
+	# Save some scratch registers
+	mov	a2,(a2_save)
+	mov	a3,(a3_save)
+
+	# We need to restore the application stack pointer, but we also
+	# need to restore the exception frame.
+	mov	(sp),a2
+	add	4,sp				// remove saved sp
+	add	-8,a2				// adjust for exception frame
+	
+	mov	(sp),a3				// Copy the saved EPSW
+	mov	a3,(a2)
+	mov	(4,sp),a3			// Copy the saved PC
+	mov	a3,(4,a2)
+	mov	a2,sp				// Restore the frame-adjusted SP
+
+	# Restore the scratch registers
+	mov	(a2_save),a2
+	mov	(a3_save),a3
+.endm
+
+#endif // CYGPKG_CYGMON
+
 ##-----------------------------------------------------------------------------
 		
 	.section ".vectors","ax"
@@ -96,7 +157,11 @@ reset_vector:
 
 	.globl __nmi
 __nmi:
+#ifdef CYGPKG_CYGMON
+	hal_cygmon_switch_app_stack
+#else
 	add	-4,sp				# space for SP
+#endif
 	hal_cpu_save_all			# push all registers
 	mov	(_hal_vsr_table+28),a0 
 	jmp	(a0)
@@ -106,7 +171,12 @@ reset_vector:
 
 	.globl __trap
 __trap:
+#ifdef CYGPKG_CYGMON
+	add	-4,sp				# space for PSW
+	hal_cygmon_switch_app_stack
+#else
 	add	-8,sp				# space for SP and PSW
+#endif
 	hal_cpu_save_all			# push all registers
 	mov	(_hal_vsr_table+32),a0
 	jmp	(a0)
@@ -117,7 +187,11 @@ reset_vector:
 	.macro	hardware_vector name
 	.globl	__hardware_vector_\name
 __hardware_vector_\name:
+#ifdef CYGPKG_CYGMON
+	hal_cygmon_switch_app_stack
+#else
 	add	-4,sp				# space for SP
+#endif
 	hal_cpu_save_all
 	mov	\name,d0			# d0 = vector id
 	mov	d0,(0,sp)			# save in dummy stack loc
@@ -272,7 +346,10 @@ 9:
 	
 	increment_sched_lock
 	
-#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+#if defined(CYGPKG_CYGMON)
+        // For Cygmon, we saved this back when we originally switched stacks.
+	mov	(sp),a2				# A2 = saved thread state
+#elif defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
 	# Increment interrupt nesting counter
 	mov	__interrupt_stack,a0		# A0 = interrupt stack top
 	mov	sp,a2				# A2 = SP
@@ -375,7 +452,7 @@ 8:
 2:
 #endif
 
-#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) && !defined(CYGPKG_CYGMON)
 
 	# If we are returning from the last nested interrupt, move back
 	# to the thread stack. interrupt_end() must be called on the
@@ -415,7 +492,11 @@ 2:
 	hal_diag_restore
 	
 	hal_cpu_load_all
+#ifdef CYGPKG_CYGMON
+	hal_cygmon_restore_app_stack
+#else
 	add	4,sp
+#endif
 	rti					# and return
 
 ##-----------------------------------------------------------------------------
@@ -510,20 +591,6 @@ 0:
         
 	mov	sp,a1				# a1 = saved state
 
-#ifdef CYGPKG_CYGMON
-	# Switch to interrupt stack to handle exception
-	# This should probably be done as the first thing in the exception
-	# handler to guard against the possibility of having a bad SP to
-	# begin with.  ie if the user sets the SP to a bad location, we
-	# will not run properly.  Ideally we should switch to monitor mode
-	# on entry to any exception.  However, a lot of other code
-	# assumes things work this way.
-	mov	__interrupt_stack-4,a0
-        mov	a0, sp
-	mov	a1,(sp)
-	add	-4,sp
-#endif
-
 	mov	a1,d0				# d0 = arg1 = saved state
 
 	add	-16,sp				# return link + args
@@ -533,48 +600,10 @@ 0:
 
 	add	16,sp				# pop args
 
-#ifdef CYGPKG_CYGMON
-	add	4,sp				# Restore the old stack
-	mov	(sp),a1
-	mov	a1,sp
-#endif
-
 	hal_cpu_load_all
 
 #ifdef CYGPKG_CYGMON
-	mov	d3,(d3_save)
-	mov	a2,(a2_save)
-	mov	a3,(a3_save)
-
-	# Pop the potentially-new stack pointer into a2
-	mov	(sp),a2
-	add	4,sp
-
-	# Check to see if sp has been modified.
-	# The exception processing pushes 8 bytes onto the stack.
-	# If sp+8 = (sp) then the stack has not been modified.
-	mov	sp,a3
-	add	8, a3
-	cmp	a2,a3
-	beq	8f
-
-	# The stack has been modified.  We need to setup for a proper rti
-	# so the stack is in the correct place.  We just hope that the user
-	# put the stack somewhere we can write to.
-	#
-	# Copy 8 bytes from the old stack to the new stack (ie the exception frame)
-	mov	(-4,a3), d3
-	mov	d3, (-4,a2)
-	mov	(-8,a3), d3
-	mov	d3, (-8,a2)
-
-	# Set the sp register to the new exception frame.
-	add	-8, a2
-	mov	a2, sp
-
-8:	mov	(d3_save),d3
-	mov	(a2_save),a2
-	mov	(a3_save),a3
+	hal_cygmon_restore_app_stack
 #else
 	add	4,sp
 #endif
@@ -590,12 +619,24 @@ hal_lsbit_table:
 	
 #ifdef CYGPKG_CYGMON
         .section ".bss"
+d0_save:
+	.long	0
+d1_save:
+	.long	0
+d2_save:
+	.long	0
 d3_save:
 	.long	0
+a0_save:
+	.long	0
+a1_save:
+	.long	0
 a2_save:
 	.long	0
 a3_save:
 	.long	0
+sp_save:
+	.long	0
 #endif
 
 ##-----------------------------------------------------------------------------
@@ -614,7 +655,11 @@ a3_save:
 	calls	_cyg_hal_exception_handler	# call C code
 	add	8,sp				# pop args
 	hal_cpu_load_all
+#ifdef CYGPKG_CYGMON
+	hal_cygmon_restore_app_stack
+#else
 	add	4,sp
+#endif
 	rets
 
 ##-----------------------------------------------------------------------------
@@ -702,6 +747,18 @@ a3_save:
 _cyg_interrupt_stack:
 __interrupt_stack:
 	
+#ifdef CYGPKG_CYGMON
+	.balign 16
+	.global __cygmon_interrupt_stack_base
+__cygmon_interrupt_stack_base:
+	.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+	.byte 0
+	.endr
+	.balign 16
+	.global __cygmon_interrupt_stack
+__cygmon_interrupt_stack:
+#endif
+
 	.long	0,0,0,0,0,0,0,0	
 
 ##-----------------------------------------------------------------------------
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,8 @@
+2000-12-02  Gary Thomas  <gthomas@redhat.com>
+
+	* src/stand_alone/eth_drv.c (eth_drv_write): Debug: dump packet
+	before calling hardware routine for improved usability.
+
 2000-10-30  Gary Thomas  <gthomas@redhat.com>
 
 	* include/eth_drv.h: Fix compile error in stand-alone mode.
--- a/packages/io/eth/current/src/stand_alone/eth_drv.c
+++ b/packages/io/eth/current/src/stand_alone/eth_drv.c
@@ -248,7 +248,6 @@ eth_drv_write(char *eth_hdr, char *buf, 
     sg_list[1].buf = (CYG_ADDRESS)buf;
     sg_list[1].len = len;
     packet_sent = 0;
-    (sc->funs->send)(sc, sg_list, sg_len, len+14, (CYG_ADDRWORD)&packet_sent);
     if (net_debug) {
         int old_console;
         old_console = start_console();
@@ -257,6 +256,7 @@ eth_drv_write(char *eth_hdr, char *buf, 
         dump_buf((CYG_ADDRWORD)buf, len);
         end_console(old_console);
     }
+    (sc->funs->send)(sc, sg_list, sg_len, len+14, (CYG_ADDRWORD)&packet_sent);
 
     while (!packet_sent) {
         (sc->funs->poll)(sc);
--- a/packages/io/flash/current/ChangeLog
+++ b/packages/io/flash/current/ChangeLog
@@ -1,3 +1,12 @@
+2000-12-06  Jesper Skov  <jskov@redhat.com>
+
+	* src/flash.c (flash_dev_query): Added. Allows reloc/cache magic
+	to be removed from device drivers (eventually). Also fixed some
+	warnings, and made function references use char[] instead of just
+	char to prevent MIPS compiler from messing up.
+
+	* include/flash.h: Added FLASH_ERR_DRV_VERIFY and flash_dev_query.
+
 2000-11-27  Jesper Skov  <jskov@redhat.com>
 
 	* src/flash.c: Do all flash access inside properly
--- a/packages/io/flash/current/include/flash.h
+++ b/packages/io/flash/current/include/flash.h
@@ -52,6 +52,7 @@
 externC int flash_init(void *work_space, int work_space_length);
 externC int flash_erase(void *base, int len, void **err_address);
 externC int flash_program(void *flash_base, void *ram_base, int len, void **err_address);
+externC void flash_dev_query(void *data);
 #if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING // This is an *interface*
 externC int flash_lock(void *base, int len, void **err_address);
 externC int flash_unlock(void *base, int len, void **err_address);
@@ -75,6 +76,7 @@ externC int printf(char* fmt, ...);
 #define FLASH_ERR_HWR             0x08  // Hardware (configuration?) problem
 #define FLASH_ERR_ERASE_SUSPEND   0x09  // Device is in erase suspend mode
 #define FLASH_ERR_PROGRAM_SUSPEND 0x0a  // Device is in in program suspend mode
+#define FLASH_ERR_DRV_VERIFY      0x0b  // Driver failed to verify data
 
 #ifdef _FLASH_PRIVATE_
 
--- a/packages/io/flash/current/src/flash.c
+++ b/packages/io/flash/current/src/flash.c
@@ -52,7 +52,9 @@
 #include <cyg/io/flash.h>
 
 
-// When this flag is set, 
+// When this flag is set, do not actually jump to the relocated code.
+// This can be used for running the function in place (RAM startup only),
+// allowing calls to diag_printf() and similar.
 #undef RAM_FLASH_DEV_DEBUG
 #if !defined(CYG_HAL_STARTUP_RAM) && defined(RAM_FLASH_DEV_DEBUG)
 # warning "Can only enable the flash debugging when configured for RAM startup"
@@ -77,6 +79,32 @@ flash_init(void *work_space, int work_sp
     return FLASH_ERR_OK;
 }
 
+// FIXME: Want to change all drivers to use this function. But it may
+// make sense to wait till device structure pointer arguments get
+// added as well.
+void
+flash_dev_query(void* data)
+{
+    extern char flash_query[], flash_query_end[];
+    typedef void code_fun(void*);
+    int code_len;
+    code_fun *_flash_query;
+    int d_cache, i_cache;
+    void* flash_id;
+
+    // Query the device driver - copy 'query' code to RAM for execution
+    code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query;
+    _flash_query = (code_fun *)flash_info.work_space;
+    memcpy(_flash_query, &flash_query, code_len);
+
+    HAL_FLASH_CACHES_OFF(d_cache, i_cache);
+#ifdef RAM_FLASH_DEV_DEBUG
+    _flash_query = &flash_query;
+#endif
+    (*_flash_query)(data);
+    HAL_FLASH_CACHES_ON(d_cache, i_cache);
+}
+
 int
 flash_verify_addr(void *target)
 {
@@ -117,7 +145,7 @@ flash_erase(void *addr, int len, void **
 {
     unsigned short *block, *end_addr;
     int stat = 0;
-    extern char flash_erase_block, flash_erase_block_end;
+    extern char flash_erase_block[], flash_erase_block_end[];
     int code_len;
     typedef int code_fun(unsigned short *);
     code_fun *_flash_erase_block;
@@ -136,7 +164,7 @@ flash_erase(void *addr, int len, void **
     block = (unsigned short *)((unsigned long)addr & flash_info.block_mask);
     end_addr = (unsigned short *)((unsigned long)addr+len);
 
-    printf("... Erase from %p-%p: ", block, end_addr);
+    printf("... Erase from %p-%p: ", (void*)block, (void*)end_addr);
 
     while (block < end_addr) {
 #ifdef RAM_FLASH_DEV_DEBUG
@@ -161,7 +189,7 @@ flash_program(void *_addr, void *_data, 
 {
     int stat = 0;
     int code_len, size;
-    extern char flash_program_buf, flash_program_buf_end;
+    extern char flash_program_buf[], flash_program_buf_end[];
     typedef int code_fun(unsigned short *, unsigned short *, int);
     code_fun *_flash_program_buf;
     unsigned short *addr = (unsigned short *)_addr;
@@ -178,7 +206,7 @@ flash_program(void *_addr, void *_data, 
     memcpy(_flash_program_buf, &flash_program_buf, code_len);
     HAL_FLASH_CACHES_OFF(d_cache, i_cache);
 
-    printf("... Program from %p-%p at %p: ", data, (void*)(((unsigned long)data)+len), addr);
+    printf("... Program from %p-%p at %p: ", (void*)data, (void*)(((unsigned long)data)+len), (void*)addr);
 
     while (len > 0) {
         size = len;
@@ -209,7 +237,7 @@ flash_lock(void *addr, int len, void **e
 {
     unsigned short *block, *end_addr;
     int stat = 0;
-    extern char flash_lock_block, flash_lock_block_end;
+    extern char flash_lock_block[], flash_lock_block_end[];
     int code_len;
     typedef int code_fun(unsigned short *);
     code_fun *_flash_lock_block;
@@ -253,7 +281,7 @@ flash_unlock(void *addr, int len, void *
 {
     unsigned short *block, *end_addr;
     int stat = 0;
-    extern char flash_unlock_block, flash_unlock_block_end;
+    extern char flash_unlock_block[], flash_unlock_block_end[];
     int code_len;
     typedef int code_fun(unsigned short *, int, int);
     code_fun *_flash_unlock_block;
@@ -317,6 +345,8 @@ flash_errmsg(int err)
         return "Device/region is write-protected";
     case FLASH_ERR_NOT_INIT:
         return "FLASH sub-system not initialized";
+    case FLASH_ERR_DRV_VERIFY:
+        return "Data verify failed after operation";
     default:
         return "Unknown error";
     }
--- a/packages/io/pci/current/ChangeLog
+++ b/packages/io/pci/current/ChangeLog
@@ -1,3 +1,13 @@
+2000-12-02  Gary Thomas  <gthomas@redhat.com>
+
+	* src/pci.c: 
+	* cdl/io_pci.cdl: Add CDL to control debug prints.
+
+2000-11-30  Gary Thomas  <gthomas@redhat.com>
+
+	* src/pci.c (cyg_pci_find_next): Improve debug prints when
+	scanning the bus, showing vendor and device code for each slot.
+
 2000-11-19  Gary Thomas  <gthomas@redhat.com>
 
 	* src/pci.c (cyg_pci_find_device): Don't update 'devid' if no
--- a/packages/io/pci/current/cdl/io_pci.cdl
+++ b/packages/io/pci/current/cdl/io_pci.cdl
@@ -82,6 +82,16 @@ cdl_package CYGPKG_IO_PCI {
                 the set of global flags if present."
         }
 
+        cdl_option CYGPKG_IO_PCI_DEBUG {
+            display "Enable debugging."
+            flavor  bool
+            default_value 0
+            description   "
+                This option enables minimal debugging of the PCI library.
+                In particular, it will print information about devices as the
+                PCI bus is being scanned/searched."
+        }
+
         cdl_option CYGPKG_IO_PCI_TESTS {
             display "PCI tests"
             flavor  data
--- a/packages/io/pci/current/src/pci.c
+++ b/packages/io/pci/current/src/pci.c
@@ -46,6 +46,7 @@
 //=============================================================================
 
 #include <pkgconf/hal.h>
+#include <pkgconf/io_pci.h>
 #include <cyg/io/pci_hw.h>
 
 // CYG_PCI_PRESENT only gets defined for targets that provide PCI HAL support.
@@ -412,8 +413,8 @@ cyg_pci_find_next( cyg_pci_device_id cur
     cyg_uint8 dev = CYG_PCI_DEV_GET_DEV(devfn);
     cyg_uint8 fn = CYG_PCI_DEV_GET_FN(devfn);
 
-#ifdef DEBUG_PCI
-    printf("cyg_pci_find_next: start[%x] ...",(unsigned)cur_devid);
+#ifdef CYGPKG_IO_PCI_DEBUG
+    printf("cyg_pci_find_next: start[%x] ...\n",(unsigned)cur_devid);
 #endif
 
     // If this is the initializer, start with 0/0/0
@@ -450,8 +451,10 @@ cyg_pci_find_next( cyg_pci_device_id cur
                 devfn = CYG_PCI_DEV_MAKE_DEVFN(dev, fn);
                 cyg_pcihw_read_config_uint16(bus, devfn,
                                              CYG_PCI_CFG_VENDOR, &vendor);
-
                 if (CYG_PCI_VENDOR_UNDEFINED != vendor) {
+#ifdef CYGPKG_IO_PCI_DEBUG
+                printf("   Bus: %d, Dev: %d, Fn: %d, Vendor: %x\n", bus, dev, fn, vendor);
+#endif
                     *next_devid = CYG_PCI_DEV_MAKE_ID(bus, devfn);
                     return true;
                 }
@@ -459,7 +462,7 @@ cyg_pci_find_next( cyg_pci_device_id cur
         }
     }
 
-#ifdef DEBUG_PCI
+#ifdef CYGPKG_IO_PCI_DEBUG
     printf("nothing.\n");
 #endif
 
@@ -476,6 +479,9 @@ cyg_pci_find_device( cyg_uint16 vendor, 
 {
     cyg_pci_device_id new_devid = *devid;
 
+#ifdef CYGPKG_IO_PCI_DEBUG
+    printf("cyg_pci_find_device - vendor: %x, device: %x\n", vendor, device);
+#endif
     // Scan entire bus, check for matches on valid devices.
     while (cyg_pci_find_next(new_devid, &new_devid)) {
         cyg_uint8 bus = CYG_PCI_DEV_GET_BUS(new_devid);
@@ -485,11 +491,14 @@ cyg_pci_find_device( cyg_uint16 vendor, 
         // Check that vendor matches.
         cyg_pcihw_read_config_uint16(bus, devfn,
                                      CYG_PCI_CFG_VENDOR, &v);
+        cyg_pcihw_read_config_uint16(bus, devfn,
+                                     CYG_PCI_CFG_DEVICE, &d);
+#ifdef CYGPKG_IO_PCI_DEBUG
+        printf("... PCI vendor = %x, device = %x\n", v, d);
+#endif
         if (v != vendor) continue;
 
         // Check that device matches.
-        cyg_pcihw_read_config_uint16(bus, devfn,
-                                     CYG_PCI_CFG_DEVICE, &d);
         if (d == device) {
             *devid = new_devid;
             return true;
@@ -765,7 +774,7 @@ cyg_pci_configure_bus( cyg_uint8 bus,
     // Scan only this bus for valid devices.
     devid = CYG_PCI_DEV_MAKE_ID(bus, 0) | CYG_PCI_NULL_DEVFN;
 
-#ifdef DEBUG_PCI
+#ifdef CYGPKG_IO_PCI_DEBUG
     printf("Configuring bus %d.\n", bus);
 #endif
 
@@ -776,7 +785,7 @@ cyg_pci_configure_bus( cyg_uint8 bus,
 	// Get the device info
 	cyg_pci_get_device_info(devid, &dev_info);
 
-#ifdef DEBUG_PCI
+#ifdef CYGPKG_IO_PCI_DEBUG
 	printf("\n");
 	printf("Configuring PCI Bus   : %d\n", bus);
 	printf("            PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));
@@ -958,7 +967,7 @@ cyg_pci_configure_bus( cyg_uint8 bus,
 					  dev_info.header.bridge.control);
 	}
     }
-#ifdef DEBUG_PCI
+#ifdef CYGPKG_IO_PCI_DEBUG
     printf("Finished configuring bus %d.\n", bus);
 #endif
 
--- a/packages/io/serial/current/ChangeLog
+++ b/packages/io/serial/current/ChangeLog
@@ -1,3 +1,9 @@
+2000-12-08  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/common/serial.c: Fix CYGOPT_IO_SERIAL_FLOW_CONTROL_HW ->
+	CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS typo when declaring callbacks
+	Thanks to Brian Danilko for reporting.
+
 2000-11-22  Jesper Skov  <jskov@redhat.com>
 
 	* src/common/serial.c: Changed #ifdef to #if used on an interface
--- a/packages/io/serial/current/src/common/serial.c
+++ b/packages/io/serial/current/src/common/serial.c
@@ -80,7 +80,7 @@ static xmt_req_reply_t serial_data_xmt_r
                                            int* chars_avail, 
                                            unsigned char** chars);
 static void serial_data_xmt_done(serial_channel *chan, int chars_sent);
-# ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+# ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
 SERIAL_CALLBACKS(cyg_io_serial_callbacks, 
                  serial_init, 
                  serial_xmt_char, 
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,57 @@
+2000-12-07  Jesper Skov  <jskov@redhat.com>
+
+	* src/debug/dbg-thread-demux.c: Add comment about the use of
+	DBG_SYSCALL_THREAD_VEC_NUM vs CYGNUM_CALL_IF_DBG_SYSCALL.
+
+2000-12-06  Hugo Tyson  <hmt@redhat.com>
+
+	* include/thread.inl (attach_stack): Additional assert check for
+	unsigned wrap of the stack size in subtracting the signature
+	areas' size.  Also round to whole words better.
+
+2000-12-05  Hugo Tyson  <hmt@redhat.com>
+
+	* cdl/thread.cdl (CYGFUN_KERNEL_THREADS_STACK_CHECKING): New
+	option, to control new stack check features.  Enabled by default,
+	but only active if CYGPKG_INFRA_DEBUG and CYGDBG_USE_ASSERTS
+	anyway, plus checking *all* threads is possible, but default off,
+	iff CYGVAR_KERNEL_THREADS_LIST.
+
+	* include/thread.hxx (class Cyg_HardwareThread): Define
+	check_stack() function.
+
+	* include/thread.inl (attach_stack): Add initialization of a
+	signature in the top and base of the stack, if so configured.
+	(check_stack): New function to check that signature for
+	correctness; minor re-ordering to permit more inlining.
+
+	* src/sched/sched.cxx (unlock_inner): Check departing and incoming
+	thread stacks if CYGFUN_KERNEL_THREADS_STACK_CHECKING.  Also, if
+	CYGFUN_KERNEL_ALL_THREADS_STACK_CHECKING, check all registered
+	thread stacks.  This is placed here to get executed every
+	clocktick and other interrupts that call DSRs, rather than messing
+	with interrupt_end() or the idle thread.
+
+2000-12-04  Hugo Tyson  <hmt@redhat.com>
+
+	* tests/kcache2.c (entry0): Make this more robust against a
+	complete absence of useful caches.  Previous change was not
+	careful enough.
+
+2000-12-01  Hugo Tyson  <hmt@redhat.com>
+
+	* cdl/kernel.cdl: Build the kcache tests for SA11x0 family; they
+	were being omitted by default as part of ARM family.  They work on
+	SA1110, so this should be OK.  They're OK on EBSAs too.  See
+	associated fix to cache macros in SA11x0 and EBSSA HALs.
+
+	* tests/kcache2.c (entry0): Fix the test; the problem was it
+	assumed that a write to a previously unseen location would end up
+	in the cache.  It ain't so on StrongARMs.  Also make tests safe
+	wrt interrupts possibly perturbing the cache, add explicit tests
+	for HAL_DCACHE_INVALIDATE_ALL(), ...DISABLE() and ...SYNC(), and
+	improve the tests for cache line invalidate and store.
+
 2000-10-30  Jesper Skov  <jskov@redhat.com>
 
 	* cdl/synch.cdl: Replaced CYGINT_KERNEL_SCHEDULER_CAN_YIELD with
--- a/packages/kernel/current/cdl/kernel.cdl
+++ b/packages/kernel/current/cdl/kernel.cdl
@@ -309,6 +309,7 @@ cdl_package CYGPKG_KERNEL {
             calculated { 
                 CYGPKG_HAL_ARM_AEB ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \
                 CYGPKG_HAL_ARM_EBSA285 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
+                CYGPKG_HAL_ARM_SA11X0 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
                 CYGPKG_HAL_ARM_EDB7XXX ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \
                 CYGPKG_HAL_ARM_CMA230 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \
                 CYGPKG_HAL_ARM ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \
--- a/packages/kernel/current/cdl/thread.cdl
+++ b/packages/kernel/current/cdl/thread.cdl
@@ -82,6 +82,44 @@ cdl_option CYGFUN_KERNEL_THREADS_STACK_L
         does not imply any form of run-time stack overflow checking."
 }
 
+cdl_component CYGFUN_KERNEL_THREADS_STACK_CHECKING {
+    display       "Check thread stacks for overflows"
+    active_if     CYGPKG_INFRA_DEBUG
+    active_if     CYGDBG_USE_ASSERTS
+    default_value 1
+    description   "
+        This option enables a variety of checks for stack overflow
+        including signatures at the top and base of thread stacks,
+        which are asserted for correctness whenever a thread switches."
+
+    cdl_option CYGFUN_KERNEL_ALL_THREADS_STACK_CHECKING {
+	display   "Check all threads whenever possible"
+	active_if  CYGVAR_KERNEL_THREADS_LIST
+	default_value 0
+	description "
+	This option enables more active checking of all threads for
+	wrongdoing.  In theory, checking threads other than the old and new
+	executing threads in a thread-switch is pointless, because no other
+	thread has run, so no other stack can be exceeded.  But errors such
+	as memory scribbling, dangling pointers, overlapping use of store
+	or errors accessing objects adjacent to a stack which can be very
+	hard to find can be detected this way, saving debug time."
+    }
+
+    cdl_option CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE {
+	display   "Signature size in bytes, at stack top and bottom"
+	flavor data
+	default_value 32
+	legal_values 8 to 512
+	description "
+	This is the size of the area reserved for a signature at the top
+	and bottom of all stacks.  It also provides a buffer zone for
+	detecting overflow before external objects are corrupted, hence the
+	ability to vary it here.  But if you are short of stack, increasing
+	this value will make the overflow more, not less likely, of course."
+    }
+}
+
 cdl_component CYGVAR_KERNEL_THREADS_DATA {
     display            "Support for per-thread data"
     requires           CYGFUN_KERNEL_THREADS_STACK_LIMIT
@@ -223,3 +261,4 @@ cdl_option CYGIMP_IDLE_THREAD_YIELD {
         If the scheduler configuration only has a single priority
         level, then the idle thread must yield each time around its loop."
 }
+
--- a/packages/kernel/current/include/thread.hxx
+++ b/packages/kernel/current/include/thread.hxx
@@ -156,6 +156,12 @@ public:
     
     CYG_ADDRESS get_stack_limit();
 #endif    
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+
+    inline void check_stack(void);
+
+#endif
 };
 
 // -------------------------------------------------------------------------
--- a/packages/kernel/current/include/thread.inl
+++ b/packages/kernel/current/include/thread.inl
@@ -56,10 +56,56 @@
 
 #include <cyg/kernel/clock.inl>
 
+#ifndef CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE
+#define CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE (0)
+#endif
+
 //==========================================================================
 // Inlines for Cyg_HardwareThread
 
 // -------------------------------------------------------------------------
+// get the size/base of this thread's stack
+
+inline CYG_ADDRESS
+Cyg_HardwareThread::get_stack_base()
+{
+    return stack_base - CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
+}
+
+inline cyg_uint32
+Cyg_HardwareThread::get_stack_size()
+{
+    return stack_size + 2 * CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
+}
+
+// -------------------------------------------------------------------------
+// Check the stack bounds of this thread:
+#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+inline void Cyg_HardwareThread::check_stack(void)
+{
+    cyg_uint32 sig = (cyg_uint32)this;
+    cyg_uint32 *base = (cyg_uint32 *)get_stack_base();
+    cyg_uint32 *top =  (cyg_uint32 *)(stack_base + stack_size);
+    unsigned int i;
+
+    CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base not word aligned" );
+    CYG_ASSERT( 0 == (3 & (cyg_uint32)top),  "stack  top not word aligned" );
+
+    CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base,
+                "Stack_ptr below base" );
+    CYG_ASSERT( (cyg_uint32)stack_ptr <= ((cyg_uint32)stack_base + stack_size),
+                "Stack_ptr above top" );
+
+    for ( i = 0;
+          i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
+          i++ ) {
+        CYG_ASSERT( (sig ^ (i * 0x01010101)) == base[i], "Stack base corrupt" );
+        CYG_ASSERT( (sig ^ (i * 0x10101010)) ==  top[i], "Stack top corrupt"  );
+    }            
+}
+#endif
+
+// -------------------------------------------------------------------------
 // Attach a stack to this thread. If there is a HAL defined macro to
 // do this, then we use that, otherwise assume a falling stack.
 inline void Cyg_HardwareThread::attach_stack(CYG_ADDRESS s_base, cyg_uint32 s_size)
@@ -68,6 +114,38 @@ inline void Cyg_HardwareThread::attach_s
     CYG_ASSERT( s_size >= CYGNUM_HAL_STACK_SIZE_MINIMUM,
                 "Stack size too small");
 #endif
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+    {
+        cyg_uint32 sig = (cyg_uint32)this;
+        cyg_uint32 *base = (cyg_uint32 *)s_base;
+        cyg_uint32 *top =  (cyg_uint32 *)(s_base + s_size -
+            CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);
+
+        unsigned int i;
+
+        CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base alignment" );
+        CYG_ASSERT( 0 == (3 & (cyg_uint32)top),  "stack  top alignment" );
+
+        for ( i = 0;
+              i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
+              i++ ) {
+            base[i] = (sig ^ (i * 0x01010101));
+             top[i] = (sig ^ (i * 0x10101010));
+        }            
+        // This check for overlap of the two signature areas also detects
+        // wrap round zero of the size in the unsigned subtraction below.
+        CYG_ASSERT( &base[i] < &top[0], "Stack is so small size wrapped" );
+        // Use this 'i' expression to round correctly to whole words.
+        s_base += i * sizeof(cyg_uint32);
+        s_size -= i * sizeof(cyg_uint32) * 2;
+        // This is a complete guess, the 256; the point is to assert early that
+        // this might go badly wrong.  It would not detect wrap of unsigned size.
+        CYG_ASSERT( s_size >= 256,
+                    "Stack size too small after allocating checking buffer");
+    }
+#endif
+
     stack_base = s_base;
     stack_size = s_size;
 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
@@ -83,6 +161,10 @@ inline void Cyg_HardwareThread::attach_s
     stack_ptr = stack_base + stack_size;
 
 #endif
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+    check_stack();
+#endif
 }
 
 // -------------------------------------------------------------------------
@@ -104,21 +186,6 @@ inline Cyg_HardwareThread::Cyg_HardwareT
 };
 
 // -------------------------------------------------------------------------
-// get the size/base of this thread's stack
-
-inline CYG_ADDRESS
-Cyg_HardwareThread::get_stack_base()
-{
-    return stack_base;
-}
-
-inline cyg_uint32
-Cyg_HardwareThread::get_stack_size()
-{
-    return stack_size;
-}
-
-// -------------------------------------------------------------------------
 
 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
 
--- a/packages/kernel/current/src/debug/dbg-thread-demux.c
+++ b/packages/kernel/current/src/debug/dbg-thread-demux.c
@@ -132,6 +132,12 @@ static int dbg_thread_syscall_rmt(
     return ret;
 }
 
+
+// Note: This constant is the same as the one defined in hal_if.h:
+// #define CYGNUM_CALL_IF_DBG_SYSCALL                15
+// But we don't have the hal_if on all the platforms we support this
+// intercalling on. Maintaining backwards compatibility is so much fun!
+
 #define DBG_SYSCALL_THREAD_VEC_NUM 15
 
 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
--- a/packages/kernel/current/src/sched/sched.cxx
+++ b/packages/kernel/current/src/sched/sched.cxx
@@ -138,6 +138,20 @@ void Cyg_Scheduler::unlock_inner( cyg_uc
 
         CYG_ASSERTCLASS( current, "Bad current thread" );
 
+#ifdef CYGFUN_KERNEL_ALL_THREADS_STACK_CHECKING
+        // should have  CYGVAR_KERNEL_THREADS_LIST
+        current = Cyg_Thread::get_list_head();
+        while ( current ) {
+            current->check_stack();
+            current = current->get_list_next();
+        }
+        current = current_thread;
+#endif
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+        current->check_stack();
+#endif
+
         // If the current thread is going to sleep, or someone
         // wants a reschedule, choose another thread to run
 
@@ -159,6 +173,9 @@ void Cyg_Scheduler::unlock_inner( cyg_uc
                 // Count this thread switch
                 thread_switches++;
                 
+#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
+                next->check_stack(); // before running it
+#endif
                 // Switch contexts
                 HAL_THREAD_SWITCH_CONTEXT( &current->stack_ptr,
                                            &next->stack_ptr );
--- a/packages/kernel/current/tests/kcache2.c
+++ b/packages/kernel/current/tests/kcache2.c
@@ -234,8 +234,10 @@ static void test_dread_hint(void)
 #endif
 
 // -------------------------------------------------------------------------
-// Test of data cache line store.
-// Just check that the macro compiles.
+// Test of data cache line store
+//  o No semantic requirement.
+//  o Check that flushed data is written to memory.
+//  o Simple invocation check of macro.
 #ifdef HAL_DCACHE_STORE
 static void test_dstore(void)
 {
@@ -260,13 +262,86 @@ static void test_dstore(void)
         (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
          & ~(HAL_DCACHE_LINE_SIZE-1));
 
-    aligned_p[0] = 42;
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
 
     HAL_DCACHE_STORE(aligned_p, HAL_DCACHE_LINE_SIZE);
+
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data");
+
+    HAL_DCACHE_INVALIDATE_ALL(); // Discard...
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data after invalidate all");
 }
 #endif
 
 // -------------------------------------------------------------------------
+// Test of data cache total flush (sync).
+//  o No semantic requirement.
+//  o Check that flushed data is written to memory.
+//  o Simple invocation check of macro.
+#ifdef HAL_DCACHE_LINE_SIZE // So we can find our way around memory
+static void test_dsync(void)
+{
+    volatile cyg_uint8* aligned_p;
+    cyg_int32 i;
+    register CYG_INTERRUPT_STATE oldints;
+
+    CYG_TEST_INFO("Data cache sync all");
+
+    for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+        m[i] = 0;
+    
+    HAL_DISABLE_INTERRUPTS(oldints);
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_DISABLE();
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_INVALIDATE_ALL();
+    HAL_DCACHE_ENABLE();
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    aligned_p =  (volatile cyg_uint8*) 
+        (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
+         & ~(HAL_DCACHE_LINE_SIZE-1));
+
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 43 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+    HAL_DCACHE_SYNC();
+
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data");
+    CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
+                   "memory didn't contain flushed data next block");
+
+    HAL_DCACHE_INVALIDATE_ALL();
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data after invalidate");
+    CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
+                   "memory didn't contain flushed data next block after invalidate");
+
+    HAL_DCACHE_DISABLE();
+
+    CYG_TEST_CHECK(42 == aligned_p[0],
+                   "memory didn't contain flushed data after disable");
+    CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
+                   "memory didn't contain flushed data next block after disable");
+
+    HAL_DCACHE_ENABLE();
+}
+#endif // HAL_DCACHE_LINE_SIZE
+
+// -------------------------------------------------------------------------
 // Test of data cache line flush.
 //  o Requires write-back cache.
 //  o Check that flushed data is written to memory.
@@ -295,29 +370,135 @@ static void test_dflush(void)
         (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
          & ~(HAL_DCACHE_LINE_SIZE-1));
 
-    aligned_p[0] = 42;
-    aligned_p[HAL_DCACHE_LINE_SIZE] = 43;
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 43 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
 
     HAL_DCACHE_FLUSH(aligned_p, HAL_DCACHE_LINE_SIZE);
 
     HAL_DCACHE_DISABLE();
 
+    HAL_RESTORE_INTERRUPTS(oldints);
+
     CYG_TEST_CHECK(42 == aligned_p[0],
                    "memory didn't contain flushed data");
     CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE], 
                    "flushed beyond region");
 
     HAL_DCACHE_ENABLE();
-
 }
 #endif
 
 // -------------------------------------------------------------------------
+// Test of data cache disable (which does NOT force contents out to RAM)
+//  o Requires write-back cache [so NOT invoked unconditionally]
+//  o Check that dirty data is not written to memory and is invalidated
+//    in the cache.
+//  o Simple invocation check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
+static void test_ddisable(void)
+{
+    volatile cyg_uint8* aligned_p;
+    cyg_int32 i;
+    register CYG_INTERRUPT_STATE oldints;
+
+    CYG_TEST_INFO("Data cache gross disable");
+
+    for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+        m[i] = 0;
+    
+    HAL_DISABLE_INTERRUPTS(oldints);
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_DISABLE();
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_INVALIDATE_ALL();
+    HAL_DCACHE_ENABLE();
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    aligned_p =  (volatile cyg_uint8*) 
+        (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
+         & ~(HAL_DCACHE_LINE_SIZE-1));
+
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
+    aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
+
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+    HAL_DCACHE_DISABLE();
+
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    CYG_TEST_CHECK(0 == aligned_p[0] &&
+                   0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+                   "cache/memory contained invalidated data");
+    CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
+                   "next block contained invalidated data");
+
+    HAL_DCACHE_ENABLE();
+}
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
+
+// -------------------------------------------------------------------------
+// Test of data cache total invalidate.
+//  o Requires write-back cache.
+//  o Check that invalidated data is not written to memory and is invalidated
+//    in the cache.
+//  o Simple invocation check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
+#ifdef HAL_DCACHE_INVALIDATE_ALL
+static void test_dinvalidate_all(void)
+{
+    volatile cyg_uint8* aligned_p;
+    cyg_int32 i;
+    register CYG_INTERRUPT_STATE oldints;
+
+    CYG_TEST_INFO("Data cache invalidate all");
+
+    for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+        m[i] = 0;
+    
+    HAL_DISABLE_INTERRUPTS(oldints);
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_DISABLE();
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_INVALIDATE_ALL();
+    HAL_DCACHE_ENABLE();
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    aligned_p =  (volatile cyg_uint8*) 
+        (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
+         & ~(HAL_DCACHE_LINE_SIZE-1));
+
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
+    aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
+
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+    HAL_DCACHE_INVALIDATE_ALL();
+
+    HAL_RESTORE_INTERRUPTS(oldints);
+
+    CYG_TEST_CHECK(0 == aligned_p[0] &&
+                   0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+                   "cache/memory contained invalidated data");
+    CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
+                   "next block contained invalidated data");
+}
+#endif
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
+
+// -------------------------------------------------------------------------
 // Test of data cache line invalidate.
 //  o Requires write-back cache.
 //  o Check that invalidated data is not written to memory and is invalidated
 //    in the cache.
 //  o Simple range check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
 #ifdef HAL_DCACHE_INVALIDATE
 static void test_dinvalidate(void)
 {
@@ -342,20 +523,36 @@ static void test_dinvalidate(void)
         (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2]) 
          & ~(HAL_DCACHE_LINE_SIZE-1));
 
-    aligned_p[0] = 43;
+    HAL_DISABLE_INTERRUPTS(oldints);
+
+    aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
     aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
 
-    aligned_p[HAL_DCACHE_LINE_SIZE] = 42;
+    aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
 
     HAL_DCACHE_INVALIDATE(aligned_p, HAL_DCACHE_LINE_SIZE);
 
+    HAL_RESTORE_INTERRUPTS(oldints);
+
     CYG_TEST_CHECK(0 == aligned_p[0] &&
                    0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
                    "cache/memory contained invalidated data");
     CYG_TEST_CHECK(42 == aligned_p[HAL_DCACHE_LINE_SIZE],
                    "invalidated beyond range");
+
+    HAL_DCACHE_SYNC();
+    HAL_DCACHE_DISABLE();
+
+    CYG_TEST_CHECK(0 == aligned_p[0] &&
+                   0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+                   "cache/memory contained invalidated data after SYNC/DIS");
+    CYG_TEST_CHECK(42 == aligned_p[HAL_DCACHE_LINE_SIZE],
+                   "invalidated beyond range after SYNC/DIS");
+
+    HAL_DCACHE_ENABLE();
 }
 #endif
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
 
 // -------------------------------------------------------------------------
 // Test of instruction cache locking.
@@ -541,26 +738,30 @@ static void time_dlock(void)
 // -------------------------------------------------------------------------
 static void entry0( cyg_addrword_t data )
 {
+    int numtests = 0;
 #ifdef HAL_DCACHE_QUERY_WRITE_MODE
     int wmode;
 #endif
 #ifdef HAL_DCACHE_LOCK
-    time_dlock();
+    time_dlock(); numtests++;
 #endif
 #ifdef HAL_ICACHE_LOCK
-    time_ilock();
+    time_ilock(); numtests++;
+#endif
+#ifdef HAL_DCACHE_LINE_SIZE // So we can find our way around memory
+    test_dsync(); numtests++;
 #endif
 #ifdef HAL_DCACHE_STORE
-    test_dstore();
+    test_dstore(); numtests++;
 #endif
 #ifdef HAL_DCACHE_READ_HINT
-    test_dread_hint();
+    test_dread_hint(); numtests++;
 #endif
 #ifdef HAL_DCACHE_WRITE_HINT
-    test_dwrite_hint();
+    test_dwrite_hint(); numtests++;
 #endif
 #ifdef HAL_DCACHE_ZERO
-    test_dzero();
+    test_dzero(); numtests++;
 #endif
 
     // The below tests only work on a copy-back cache.
@@ -568,16 +769,24 @@ static void entry0( cyg_addrword_t data 
     HAL_DCACHE_QUERY_WRITE_MODE( wmode );
  
     if ( HAL_DCACHE_WRITEBACK_MODE == wmode ) {
+        test_ddisable(); numtests++;
+#ifdef HAL_DCACHE_INVALIDATE
+        test_dinvalidate_all(); numtests++;
+#endif
 #ifdef HAL_DCACHE_FLUSH
-        test_dflush();
+        test_dflush(); numtests++;
 #endif
 #ifdef HAL_DCACHE_INVALIDATE
-        test_dinvalidate();
+        test_dinvalidate(); numtests++;
 #endif
     }
 #endif // def HAL_DCACHE_QUERY_WRITE_MODE
-
-    CYG_TEST_PASS_FINISH("End of test");
+    if ( numtests ) {
+        CYG_TEST_PASS_FINISH("End of test");
+    }
+    else {
+        CYG_TEST_NA( "No applicable cache tests" );
+    }
 }
 
 // -------------------------------------------------------------------------
--- a/packages/language/c/libc/time/current/ChangeLog
+++ b/packages/language/c/libc/time/current/ChangeLog
@@ -1,3 +1,10 @@
+2000-11-29  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* tests/clock.c: Some targets are quite inconsistent, so skip
+	6 samples now, and increase the tolerance to 40%.
+	Also NA if tracing enabled.
+	Also output the mean and maximum error reached, even when passing.
+
 2000-11-27  Jesper Skov  <jskov@redhat.com>
 
 	* tests/clock.c: Skip fourth sample too.
--- a/packages/language/c/libc/time/current/tests/clock.c
+++ b/packages/language/c/libc/time/current/tests/clock.c
@@ -44,6 +44,7 @@
 #include <pkgconf/libc_time.h>   // Configuration header
 #include <pkgconf/system.h>
 #include <pkgconf/isoinfra.h>
+#include <pkgconf/infra.h>
 
 #include <cyg/infra/testcase.h>
 
@@ -54,6 +55,8 @@
 # define NA_MSG "Cannot run on synthetic target"
 #elif !defined(CYGINT_ISO_MAIN_STARTUP)
 # define NA_MSG "Requires main() startup"
+#elif defined(CYGDBG_USE_TRACING)
+# define NA_MSG "Cannot give an accurate test when tracing is enabled"
 #endif
 
 #ifdef NA_MSG
@@ -78,10 +81,10 @@ cyg_start(void)
 
 // This defines how many loops before we decide that
 // the clock doesnt work
-#define MAX_TIMEOUT 1000000
+#define MAX_TIMEOUT 100000
 
 // Percentage error before we declare fail: range 0 - 100
-#define TOLERANCE 25
+#define TOLERANCE 40
 
 // Number of samples to take
 #define SAMPLES 30
@@ -96,7 +99,8 @@ cyg_start(void)
 // that the other samples. Probably due to cache/timing effect after the
 // previous loop.
 // Finally, ctrs[3] is skipped because it's also very fast on ARM targets.
-#define SKIPPED_SAMPLES 4
+
+#define SKIPPED_SAMPLES 6
 
 
 // FUNCTIONS
@@ -144,7 +148,7 @@ static clock_t clocks[SAMPLES];
 int
 main(int argc, char *argv[])
 {
-    unsigned long mean=0, sum=0;
+    unsigned long mean=0, sum=0, maxerr=0;
     int i;
 
     CYG_TEST_INIT();
@@ -153,8 +157,7 @@ main(int argc, char *argv[])
                   "clock() function");
 
     // First disable the caches - they may affect the timing loops
-    // below - especially if tracing or assertions are enabled, causing
-    // the elapsed time during the clock() call to vary.
+    // below - causing the elapsed time during the clock() call to vary.
     {
         register CYG_INTERRUPT_STATE oldints;
 
@@ -214,8 +217,11 @@ main(int argc, char *argv[])
                         err);
             CYG_TEST_FAIL_FINISH("clock() within tolerance");
         }
+        if (err > maxerr)
+            maxerr=err;
     }
 
+    diag_printf("mean=%d, maxerr=%d\n", mean, maxerr);
     CYG_TEST_PASS_FINISH("clock() stable");
 
 } // main()
--- a/packages/net/snmp/agent/current/ChangeLog
+++ b/packages/net/snmp/agent/current/ChangeLog
@@ -1,3 +1,15 @@
+2000-11-29  Hugo Tyson  <hmt@redhat.com>
+2000-11-29  Andrew Lunn <Andrew.Lunn@ascom.ch>
+	* src/mibgroup/mibII/dot3.c (var_dot3StatsTable): 
+	* src/mibgroup/mibII/interfaces.c (var_ifTable): 
+	Undo Hugo's fix; it fails if there are holes in the if_index space
+	(not something I expected).  Use this fix instead, from Andrew.
+	[CASE 104939]
+	
+	* src/mibgroups/mibII/ip.c: IPADENTIFINDEX should return the
+	interface index as seen in the interface group.  This is not the
+	if_index but merely acquired by counting.
+
 2000-11-17  Hugo Tyson  <hmt@redhat.com>
 
 	* src/mibgroup/mibII/dot3.c (var_dot3StatsTable): 
--- a/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c
+++ b/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c
@@ -225,11 +225,11 @@ var_dot3StatsTable(struct variable *vp,
          == MATCH_FAILED )
         return NULL;
 
-    interface_count = name[ (*length)-1 ];
-    for ( ifp = ifnet.tqh_first; ifp ; ifp = ifp->if_list.tqe_next )
-        if ( interface_count == ifp->if_index )
-            break;
-
+    for ( interface_count = name[ (*length)-1 ], ifp = ifnet.tqh_first;
+          interface_count > 1 && ifp != 0;
+          interface_count-- )
+        ifp = ifp->if_list.tqe_next;
+    
     if ( ! ifp )
         return NULL;
 
--- a/packages/net/snmp/agent/current/src/mibgroup/mibII/interfaces.c
+++ b/packages/net/snmp/agent/current/src/mibgroup/mibII/interfaces.c
@@ -288,10 +288,10 @@ var_ifTable(struct variable *vp,
          == MATCH_FAILED )
         return NULL;
     
-    interface_count = name[ (*length)-1 ];
-    for ( ifp = ifnet.tqh_first; ifp ; ifp = ifp->if_list.tqe_next )
-        if ( interface_count == ifp->if_index )
-            break;
+    for ( interface_count = name[ (*length)-1 ], ifp = ifnet.tqh_first;
+          interface_count > 1 && ifp != 0;
+          interface_count-- )
+        ifp = ifp->if_list.tqe_next;
 
     if ( ! ifp )
         return NULL;
--- a/packages/net/snmp/agent/current/src/mibgroup/mibII/ip.c
+++ b/packages/net/snmp/agent/current/src/mibgroup/mibII/ip.c
@@ -99,6 +99,7 @@ CONNECTION WITH THE USE OR PERFORMANCE O
 #include <netinet/ip_var.h>
 
 extern struct in_ifaddrhead in_ifaddr;
+extern struct ifnet_head ifnet;
 
 #include <eth_drv.h>
 
@@ -400,7 +401,10 @@ var_ipAddrTable(struct variable *vp,
 
     register struct in_ifaddr *ia;
     register struct in_ifaddr *low_ia = NULL;
-    
+
+    register struct ifnet *ifp;
+    int interface_count = 1;
+
     /* fill in object part of name for current (less sizeof instance part) */
     memcpy( (char *)current,(char *)vp->name, (int)vp->namelen * sizeof(oid));
 
@@ -454,7 +458,15 @@ var_ipAddrTable(struct variable *vp,
         return (unsigned char *) string;
 
     case IPADENTIFINDEX:
-        long_ret = low_ia->ia_ifa.ifa_ifp->if_index;
+        ifp =  ifnet.tqh_first;
+        while (ifp && ifp->if_index != low_ia->ia_ifa.ifa_ifp->if_index) {
+            interface_count++;
+            ifp = ifp->if_list.tqe_next;
+        }
+        if (!ifp) {
+            return NULL;
+        }
+        long_ret = interface_count;
         return (unsigned char *) &long_ret;
 
     case IPADENTNETMASK:
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,74 @@
+2000-12-07  Gary Thomas  <gthomas@redhat.com>
+
+	* src/main.c (cyg_start): Make CLI command buffer static.
+	(do_reset): New command - reset platform from CLI.
+
+	* src/io.c (dump_buf_with_offset): Change signature for 
+	more generic export.
+
+	* include/redboot.h: Export 'dump_buf_with_offset' function.
+
+	* cdl/redboot.cdl: Define CLI command buffer - static with
+	user specified length - to accomodate some environments which
+	may want excrutiatingly long commands.
+
+2000-12-07  Jesper Skov  <jskov@redhat.com>
+
+	* src/misc_funs.c (strlen): NULL ptr string has length 0.
+
+	* src/load.c (load_srec_image): Refuse to load data to a location
+	not in RAM.
+
+	* src/flash.c (fis_create): Hack around another MIPS compiler bug.
+
+2000-12-06  Jesper Skov  <jskov@redhat.com>
+
+	* src/load.c: Suppress verbosity when using xyz modem download.
+	
+	* src/main.c: Fix warnings.
+	* src/load.c: Fix warnings.
+
+	* src/parse.c (parse_num): Hack around MIPS compiler bug.
+
+2000-12-01  Gary Thomas  <gthomas@redhat.com>
+
+	* src/xyzModem.h: 
+	* src/xyzModem.c (xyzModem_stream_close): New function - tidy up
+	and print some statistics about the download.  Better handling
+	of CAN (cancel) function.
+
+	* src/load.c (load_srec_image): Consume all data, not just to
+	final record.  This makes Ymodem happier.  Also, call xyzModem_close().
+
+2000-11-30  Gary Thomas  <gthomas@redhat.com>
+
+	* src/flash.c (fis_create): Add new option '-n' which suppresses
+	the copy from RAM to FLASH.  Used to simply update the FIS directory.
+	Also misc printf() changes - add 0x everywhere hex is used.
+
+	* src/net/net_io.c (_net_io_getc_nonblock): Abstract function.
+	(net_io_getc_nonblock): Add minimal handling of telnet escape
+	sequences - required to properly handle ^C.
+
+	* src/main.c (cyg_start): Support network connection during
+	boot/startup script.  Use new codes from 'gets()'.
+
+	* src/flash.c (fis_create): Cleanup to remove warnings.
+
+	* include/net/net.h (BSPLOG): Update for new start/end_console().
+
+	* src/io.c (gets): 
+	* include/redboot.h (_GETS_xxx): Define result codes from 
+	'gets()' function.
+
+2000-11-28  Gary Thomas  <gthomas@redhat.com>
+
+	* src/parse.c (parse): Support escaped quote marks inside of
+	quoted string.  "ab\"c\"" is 'ab"c"'.
+
+	* src/net/tftp_client.c (tftp_stream_open): Read first datum from
+	file during open to ensure that errors are reported.
+
 2000-11-27  Drew Moseley  <dmoseley@redhat.com>
 
 	* src/main.c: Switch to an application stack before running a
--- a/packages/redboot/current/cdl/redboot.cdl
+++ b/packages/redboot/current/cdl/redboot.cdl
@@ -137,6 +137,16 @@ cdl_package CYGPKG_REDBOOT {
           that port."
     }
 
+    cdl_option CYGPKG_REDBOOT_MAX_CMD_LINE {
+        display       "Maximum command line length"
+        flavor        data
+        default_value 256
+        description   "
+          This option allows control over how long the CLI command line
+          should be.  As such, it allows control over how much stack space 
+          is required by RedBoot during command processing."
+    }
+
     cdl_component CYGPKG_REDBOOT_FLASH {
         display       "Allow RedBoot to support FLASH programming"
         flavor        bool
--- a/packages/redboot/current/include/net/net.h
+++ b/packages/redboot/current/include/net/net.h
@@ -579,7 +579,7 @@ extern char *inet_ntoa(in_addr_t *);
 #define NET_SUPPORT_TCP  1
 
 #ifdef BSP_LOG
-#define BSPLOG(x) { start_console(); x; end_console(); }
+#define BSPLOG(x) { int old_console = start_console(); x; end_console(old_console); }
 #define bsp_log printf
 #else
 #define BSPLOG(x)
--- a/packages/redboot/current/include/redboot.h
+++ b/packages/redboot/current/include/redboot.h
@@ -101,9 +101,17 @@ int  strncmpci(const char *s1, const cha
 char *strcpy(char *s1, const char *s2);
 
 void mon_write_char(char c);
-int  gets(char *line, int len, int timeout);
 bool verify_action(char *fmt, ...);
 void dump_buf(void *, CYG_ADDRWORD);
+void dump_buf_with_offset(void *, CYG_ADDRWORD, void *);
+
+// Read a single line of input from the console, possibly with timeout
+int  gets(char *line, int len, int timeout);
+// Result codes from 'gets()'
+#define _GETS_TIMEOUT -1
+#define _GETS_CTRLC   -2
+#define _GETS_GDB      0
+#define _GETS_OK       1
 
 // "console" selection
 int  start_console(void);
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -114,7 +114,8 @@ local_cmd_entry("load",
     );
 local_cmd_entry("create",
                 "Create an image",
-                "-b <mem_base> -l <image_length> [-s <data_length>] [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] <name>",
+                "-b <mem_base> -l <image_length> [-s <data_length>] 
+                [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>",
                 fis_create,
                 FIS_cmds
     );
@@ -197,7 +198,7 @@ fis_init(int argc, char *argv[])
     if (full_init) {
         if ((stat = flash_erase((void *)((unsigned long)flash_start+(2*block_size)), 
                                 (blocks-4)*block_size, (void **)&err_addr)) != 0) {
-            printf("   initialization failed %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+            printf("   initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
         }
     } else {
         printf("    Warning: device contents not erased, some blocks may not be usable\n");
@@ -242,11 +243,11 @@ fis_init(int argc, char *argv[])
     flash_unlock((void *)fis_base, block_size, (void **)&err_addr);
 #endif
     if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) {
-            printf("   initialization failed %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+            printf("   initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
     } else {
         if ((stat = flash_program(fis_base, fis_work_block, 
                                   img_count*sizeof(*img), (void **)&err_addr)) != 0) {
-            printf("Error writing image descriptors at %p: %x(%s)\n", 
+            printf("Error writing image descriptors at %p: 0x%x(%s)\n", 
                    err_addr, stat, flash_errmsg(stat));
         }
     }
@@ -373,10 +374,11 @@ fis_create(int argc, char *argv[])
     bool flash_addr_set = false;
     bool length_set = false;
     bool img_size_set = false;
+    bool no_copy = false;
     void *fis_addr, *err_addr;
     struct fis_image_desc *img;
     bool slot_found;
-    struct option_info opts[6];
+    struct option_info opts[7];
     bool prog_ok;
 
     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
@@ -391,13 +393,16 @@ fis_create(int argc, char *argv[])
               (void **)&length, (bool *)&length_set, "image length [in FLASH]");
     init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, 
               (void **)&img_size, (bool *)&img_size_set, "image size [actual data]");
-    if (!scan_opts(argc, argv, 2, opts, 6, (void *)&name, OPTION_ARG_TYPE_STR, "file name"))
+    init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, 
+              (void **)&no_copy, (bool *)0, "don't copy from RAM to FLASH, just update directory");
+    if (!scan_opts(argc, argv, 2, opts, 7, (void *)&name, OPTION_ARG_TYPE_STR, "file name"))
     {
         fis_usage("invalid arguments");
         return;
     }
 
-    if (!mem_addr_set || !length_set || !name) {
+    if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) ||
+        !length_set || !name) {
         fis_usage("required parameter missing");
         return;
     }
@@ -406,11 +411,13 @@ fis_create(int argc, char *argv[])
     }
     // 'length' is size of FLASH image, 'img_size' is actual data size
     // Round up length to FLASH block size
+#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken
     length = ((length + block_size - 1) / block_size) * block_size;
     if (length < img_size) {
-        printf("Invalid FLASH image size/length combination");
+        printf("Invalid FLASH image size/length combination\n");
         return;
     }
+#endif
     if (flash_addr_set &&
         ((stat = flash_verify_addr((void *)flash_addr)) ||
          (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) {
@@ -418,18 +425,20 @@ fis_create(int argc, char *argv[])
         printf("   valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
         return;
     }
-    if ((mem_addr < (unsigned long)ram_start) ||
-        ((mem_addr+img_size) >= (unsigned long)ram_end)) {
-        printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
-        printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
-    }
     if (strlen(name) >= sizeof(img->name)) {
         printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name));
         return;
     }
-    if (!flash_addr_set && !fis_find_free(&flash_addr, length)) {
-        printf("Can't locate %ld bytes free in FLASH\n", length);
-        return;
+    if (!no_copy) {
+        if ((mem_addr < (unsigned long)ram_start) ||
+            ((mem_addr+img_size) >= (unsigned long)ram_end)) {
+            printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
+            printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
+        }
+        if (!flash_addr_set && !fis_find_free(&flash_addr, length)) {
+            printf("Can't locate %ld bytes free in FLASH\n", length);
+            return;
+        }
     }
     // Find a slot in the directory for this entry
     // First, see if an image by this name is already present
@@ -444,7 +453,7 @@ fis_create(int argc, char *argv[])
                 return;
             }
             if (img->size != length) {
-                printf("Image found, but LENGTH is incorrect (0x%x != 0x%x)\n", img->size, length);
+                printf("Image found, but LENGTH is incorrect (0x%lx != 0x%lx)\n", img->size, length);
                 return;
             }
             if (!verify_action("An image named '%s' exists", name)) {
@@ -465,24 +474,26 @@ fis_create(int argc, char *argv[])
             }
         }
     }
-    // Safety check - make sure the address range is not within the code we're running
-    if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) {
-        printf("Can't program this region - contains code in use!\n");
-        return;
-    }
-    prog_ok = true;
-    if (prog_ok) {
-        // Erase area to be programmed
-        if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-            printf("Can't erase region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
-            prog_ok = false;
+    if (!no_copy) {
+        // Safety check - make sure the address range is not within the code we're running
+        if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) {
+            printf("Can't program this region - contains code in use!\n");
+            return;
         }
-    }
-    if (prog_ok) {
-        // Now program it
-        if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) {
-            printf("Can't program region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
-            prog_ok = false;
+        prog_ok = true;
+        if (prog_ok) {
+            // Erase area to be programmed
+            if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
+                printf("Can't erase region at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
+                prog_ok = false;
+            }
+        }
+        if (prog_ok) {
+            // Now program it
+            if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) {
+                printf("Can't program region at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
+                prog_ok = false;
+            }
         }
     }
     // Update directory
@@ -493,18 +504,18 @@ fis_create(int argc, char *argv[])
     img->entry_point = entry_addr_set ? entry_addr : (unsigned long)entry_address;  // Hope it's been set
     img->size = length;
     img->data_length = img_size;
-    img->file_cksum = _cksum((unsigned long *)mem_addr, img_size);
+    img->file_cksum = _cksum((unsigned long *)flash_addr, img_size);
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
     // Insure [quietly] that the directory is unlocked before trying to update
     flash_unlock((void *)fis_addr, block_size, (void **)&err_addr);
 #endif
     if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) {
-        printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+        printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
         // Don't try to program if the erase failed
     } else {
         // Now program it
         if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) {
-            printf("Error programming at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+            printf("Error programming at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
         }
     }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -550,7 +561,7 @@ fis_erase(int argc, char *argv[])
         return;
     }
     if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+        printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
     }
 }
 
@@ -588,7 +599,7 @@ fis_lock(int argc, char *argv[])
         return;
     }
     if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        printf("Error locking at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+        printf("Error locking at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
     }
 }
 
@@ -624,7 +635,7 @@ fis_unlock(int argc, char *argv[])
         return;
     }
     if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) {
-        printf("Error unlocking at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+        printf("Error unlocking at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
     }
 }
 #endif
@@ -665,7 +676,7 @@ fis_delete(int argc, char *argv[])
     }
     // Erase Data blocks (free space)
     if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) {
-        printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+        printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
     }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
     // Insure [quietly] that the directory is unlocked before trying to update
@@ -674,12 +685,12 @@ fis_delete(int argc, char *argv[])
     // Update directory
     memset(img, 0xFF, sizeof(*img));
     if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) {
-        printf("Error erasing at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+        printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
         // Don't try to program if the erase failed
     } else {
         // Now program it
         if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) {
-            printf("Error programming at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+            printf("Error programming at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
         }
     }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
@@ -697,6 +708,7 @@ fis_load(int argc, char *argv[])
     bool mem_addr_set = false;
     bool show_cksum = false;
     struct option_info opts[2];
+    unsigned long cksum;
 
     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 
               (void **)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address");
@@ -722,15 +734,15 @@ fis_load(int argc, char *argv[])
     }
     memcpy((void *)mem_addr, (void *)img->flash_base, img->size);
     entry_address = (unsigned long *)img->entry_point;
+    cksum = _cksum((unsigned long *)mem_addr, img->data_length);
+    if (show_cksum) {
+        printf("Checksum: 0x%08lx\n", cksum);
+    }
     if (img->file_cksum) {
-        unsigned long cksum = _cksum((unsigned long *)mem_addr, img->data_length);
         if (cksum != img->file_cksum) {
-            printf("** Warning - checksum failure.  stored: %08lx, computed: %08lx\n",
+            printf("** Warning - checksum failure.  stored: 0x%08lx, computed: 0x%08lx\n",
                    img->file_cksum, cksum);
         }
-        if (show_cksum) {
-            printf("Checksum: %08lx\n", cksum);
-        }
     }
 }
 
@@ -744,7 +756,7 @@ do_flash_init(void)
         init = 1;
         if ((stat = flash_init((void *)(ram_end-FLASH_MIN_WORKSPACE), 
                                FLASH_MIN_WORKSPACE)) != 0) {
-            printf("FLASH: driver init failed!, status: %x\n", stat);
+            printf("FLASH: driver init failed!, status: 0x%x\n", stat);
             return false;
         }
         flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end);
@@ -1078,11 +1090,11 @@ do_flash_config(int argc, char *argv[])
         flash_unlock((void *)cfg_base, block_size, (void **)&err_addr);
 #endif
         if ((stat = flash_erase(cfg_base, block_size, (void **)&err_addr)) != 0) {
-            printf("   initialization failed %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
+            printf("   initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
         } else {
             if ((stat = flash_program(cfg_base, (void *)&config, 
                                       sizeof(config), (void **)&err_addr)) != 0) {
-                printf("Error writing config data at %p: %x(%s)\n", 
+                printf("Error writing config data at %p: 0x%x(%s)\n", 
                        err_addr, stat, flash_errmsg(stat));
             }
         }
--- a/packages/redboot/current/src/io.c
+++ b/packages/redboot/current/src/io.c
@@ -191,7 +191,7 @@ gets(char *buf, int buflen, int timeout)
                 timeout -= 50;
             }
             if (res == false) {
-                return -1;  // Input timed out
+                return _GETS_TIMEOUT;  // Input timed out
             }
         } else {
             mon_read_char(&c);
@@ -201,7 +201,7 @@ gets(char *buf, int buflen, int timeout)
         case 0x03: // ^C
             if (ptr == buf) {
                 printf("^C\n");
-                return -2;
+                return _GETS_CTRLC;
             }
             *ptr++ = c;
             break;
@@ -219,7 +219,7 @@ gets(char *buf, int buflen, int timeout)
                 mon_write_char('\n');
 	    }
             last_ch = c;
-            return 1;
+            return _GETS_OK;
         case '\b':
         case 0x7F:  // DEL
             if (ptr != buf) {
@@ -236,7 +236,7 @@ gets(char *buf, int buflen, int timeout)
             if (ptr == buf) {
                 // Give up and try GDB protocol
                 ungetDebugChar(c);  // Push back character so stubs will see it
-                return 0;
+                return _GETS_GDB;
             }
             // Fall through - accept '$' at other than start of line
         default:
@@ -250,11 +250,12 @@ gets(char *buf, int buflen, int timeout)
 }
 
 void
-dump_buf_with_offset(cyg_uint8     *p, 
-                     CYG_ADDRWORD   s, 
-                     cyg_uint8     *base)
+dump_buf_with_offset(void *_p, CYG_ADDRWORD s, void *_base)
 {
     int i, c;
+    cyg_uint8 *p = (cyg_uint8 *)_p;
+    cyg_uint8 *base = (cyg_uint8 *)_base;
+
     if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) {
         s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p;
     }
--- a/packages/redboot/current/src/load.c
+++ b/packages/redboot/current/src/load.c
@@ -153,7 +153,7 @@ load_srec_image(int (*getc)(void), unsig
                 lowest_address = (unsigned long)(addr - addr_offset);
             }
             if ((addr < ram_start) || (addr > ram_end)) {
-                printf("Attempt to load S-record data to address: %p [not in RAM]\n", addr);
+                printf("Attempt to load S-record data to address: %p [not in RAM]\n", (void*)addr);
                 return;
             }
             count -= ((type-'1'+2)+1);
@@ -182,7 +182,8 @@ load_srec_image(int (*getc)(void), unsig
             offset += ('9'-type+2);
             entry_address = (unsigned long *)addr;
             printf("Entry point: %p, address range: %p-%p\n", 
-                   entry_address, (void *)lowest_address, (void *)highest_address);
+                   (void*)entry_address, (void *)lowest_address, (void *)highest_address);
+            while ((c = (*getc)()) > 0) ;  // Swallow rest of data
             return;
         default:
             printf("Invalid S-record at offset 0x%lx, type: %x\n", 
@@ -337,6 +338,10 @@ do_load(int argc, char *argv[])
         printf("usage: load %s\n", usage);
         return;
     }
+    if (base_addr_set && ((base < ram_start) || (base > ram_end))) {
+        printf("Specified address (%p) is not in RAM.\n", (void*)base);
+        return;
+    }
 #ifdef CYGPKG_REDBOOT_NETWORKING
     if (mode == MODE_TFTP) {
         res = tftp_stream_open(filename, &host, TFTP_OCTET, &err);    
@@ -353,7 +358,8 @@ do_load(int argc, char *argv[])
             printf("Can't load '%s': %s\n", filename, xyzModem_error(err));
             return;
         }
-        redboot_getc_init(xyzModem_stream_read, verbose);
+        // Suppress verbosity when using xyz modem download
+        redboot_getc_init(xyzModem_stream_read, 0 && verbose);
     }
     // Read initial header - to determine file [image] type
     for (i = 0;  i < sizeof(type);  i++) {
@@ -392,5 +398,8 @@ do_load(int argc, char *argv[])
         tftp_stream_close(&err);
     }
 #endif
+    if (mode != MODE_TFTP) {
+        xyzModem_stream_close(&err);
+    }
     return;
 }
--- a/packages/redboot/current/src/main.c
+++ b/packages/redboot/current/src/main.c
@@ -51,6 +51,7 @@
 #include CYGHWR_MEMORY_LAYOUT_H
 
 #include <cyg/hal/hal_tables.h>
+#include <cyg/hal/plf_stub.h>
 
 // Builtin Self Test (BIST)
 externC void bist(void);
@@ -84,6 +85,13 @@ RedBoot_cmd("cache",
             "[ON | OFF]",
             do_caches 
     );
+#ifdef HAL_STUB_PLATFORM_RESET
+RedBoot_cmd("reset", 
+            "Reset the system", 
+            "",
+            do_reset 
+    );
+#endif
 
 // Define table boundaries
 CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
@@ -105,7 +113,7 @@ do_version(int argc, char *argv[])
     printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
 #endif
     printf("Copyright (C) 2000, Red Hat, Inc.\n\n");
-    printf("RAM: %p-%p\n", ram_start, ram_end);
+    printf("RAM: %p-%p\n", (void*)ram_start, (void*)ram_end);
 }
 
 //
@@ -114,9 +122,9 @@ do_version(int argc, char *argv[])
 void
 cyg_start(void)
 {
-    int res;
+    int res = 0;
     bool prompt = true;
-    char line[256];
+    static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
     struct cmd *cmd;
     int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
     struct init_tab_entry *init_entry;
@@ -149,8 +157,23 @@ cyg_start(void)
         printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                script_timeout_ms/1000, script_timeout_ms%1000);
         script = (unsigned char *)0;
-        res = gets(line, sizeof(line), script_timeout_ms);
-        if (res == -2) {
+        while (script_timeout_ms >= 10) {
+            res = gets(line, sizeof(line), 10);
+            if (res == _GETS_OK) {
+                printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
+                       script_timeout_ms/1000, script_timeout_ms%1000);
+                continue;  // Ignore anything but ^C
+            }
+            if (res != _GETS_TIMEOUT) break;
+#ifdef CYGPKG_REDBOOT_NETWORKING
+            if (have_net) {
+                // Check for incoming TCP debug connection
+                net_io_test();
+            }
+#endif
+            script_timeout_ms -= 10;
+        }
+        if (res == _GETS_CTRLC) {
             script = (unsigned char *)0;  // Disable script
         } else {
             script = hold_script;  // Re-enable script
@@ -164,7 +187,7 @@ cyg_start(void)
             prompt = false;
         }
         res = gets(line, sizeof(line), 250);
-        if (res < 0) {
+        if (res == _GETS_TIMEOUT) {
             // No input arrived
 #ifdef CYGPKG_REDBOOT_NETWORKING
             if (have_net) {
@@ -173,7 +196,7 @@ cyg_start(void)
             }
 #endif
         } else {
-            if (res == 0) {
+            if (res == _GETS_GDB) {
                 // Special case of '$' - need to start GDB protocol
                 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
 #ifdef HAL_ARCH_PROGRAM_NEW_STACK
@@ -186,7 +209,7 @@ cyg_start(void)
                     if ((cmd = parse(line, &argc, &argv[0])) != (struct cmd *)0) {
                         (cmd->fun)(argc, argv);
                     } else {
-                        printf("** Error: Illegal command: %s\n", line);
+                        printf("** Error: Illegal command: \"%s\"\n", argv[0]);
                     }
                 }
                 prompt = true;
@@ -284,7 +307,7 @@ do_go(int argc, char *argv[])
         printf("About to start execution at %p - abort with ^C within %d seconds\n",
                (void *)entry, wait_time);
         res = gets(line, sizeof(line), wait_time*1000);
-        if (res == -2) {
+        if (res == _GETS_CTRLC) {
             return;
         }
     }
@@ -303,6 +326,19 @@ do_go(int argc, char *argv[])
 #endif
 }
 
+#ifdef HAL_STUB_PLATFORM_RESET
+void
+do_reset(int argc, char *argv[])
+{
+    printf("... Resetting.");
+    CYGACC_CALL_IF_DELAY_US(2*100000);
+    printf("\n");
+    CYGACC_CALL_IF_DELAY_US(50000);
+    HAL_STUB_PLATFORM_RESET();
+    printf("!! oops, RESET not working on this platform\n");
+}
+#endif
+
 // 
 // [Null] Builtin [Power On] Self Test
 //
--- a/packages/redboot/current/src/misc_funs.c
+++ b/packages/redboot/current/src/misc_funs.c
@@ -49,7 +49,8 @@ int
 strlen(const char *s)
 {
     int len = 0;
-    while (*s++) len++;
+    if (s)
+        while (*s++) len++;
     return len;
 }
 
--- a/packages/redboot/current/src/net/net_io.c
+++ b/packages/redboot/current/src/net/net_io.c
@@ -109,9 +109,17 @@ static unsigned char *out_bufp;
 // Functions in this module
 static void net_io_flush(void);
 static void net_io_revert_console(void);
+static void net_io_putc(void*, cyg_uint8);
+
+// Special characters used by Telnet - must be interpretted here
+#define TELNET_IAC    0xFF // Interpret as command (escape)
+#define TELNET_IP     0xF4 // Interrupt process
+#define TELNET_WONT   0xFC // I Won't do it
+#define TELNET_DO     0xFD // Will you XXX
+#define TELNET_TM     0x06 // Time marker (special DO/WONT after IP)
 
 static cyg_bool
-net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+_net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
 {
     if (in_buflen == 0) {
         __tcp_poll();
@@ -149,6 +157,39 @@ net_io_getc_nonblock(void* __ch_data, cy
     }
 }
 
+static cyg_bool
+net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    if (_net_io_getc_nonblock(__ch_data, ch)) {
+        if (*ch == TELNET_IAC) {
+            cyg_uint8 esc;
+            // Telnet escape - need to read/handle more
+            while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
+            if (esc == TELNET_IP) {
+                // Special case for ^C == Interrupt Process
+                *ch = 0x03;  
+                // Just in case the other end needs synchronizing
+                net_io_putc(__ch_data, TELNET_IAC);
+                net_io_putc(__ch_data, TELNET_WONT);
+                net_io_putc(__ch_data, TELNET_TM);
+                net_io_flush();
+                return true;
+            }
+            if (esc == TELNET_DO) {
+                // Telnet DO option
+                while (!_net_io_getc_nonblock(__ch_data, &esc)) ;                
+                // Respond with WONT option
+                net_io_putc(__ch_data, TELNET_IAC);
+                net_io_putc(__ch_data, TELNET_WONT);
+                net_io_putc(__ch_data, esc);
+                return false;  // Ignore this whole thing!
+            }
+        }
+    } else {
+        return false;
+    }
+}
+
 static cyg_uint8
 net_io_getc(void* __ch_data)
 {
--- a/packages/redboot/current/src/net/tcp.c
+++ b/packages/redboot/current/src/net/tcp.c
@@ -611,10 +611,10 @@ int
 void
 __tcp_drain(tcp_socket_t *s)
 {
-    BSPLOG(bsp_log("__tcp_drain.\n"));
+//    BSPLOG(bsp_log("__tcp_drain.\n"));
     while (s->state != _CLOSED && s->data_bytes)
 	__tcp_poll();
-    BSPLOG(bsp_log("__tcp_drain done.\n"));
+//    BSPLOG(bsp_log("__tcp_drain done.\n"));
 }
 
 
--- a/packages/redboot/current/src/net/tftp_client.c
+++ b/packages/redboot/current/src/net/tftp_client.c
@@ -193,6 +193,7 @@ tftp_stream_open(char *filename,
     struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
     char *cp, *fp;
     static int get_port = 7700;
+    char test_buf;
 
     if (tftp_stream.open) {
         *err = TFTP_INVALID;  // Already open
@@ -239,7 +240,17 @@ tftp_stream_open(char *filename,
     tftp_stream.last_good_block = 0;
     tftp_stream.total_timeouts = 0;
 
-    return 0;
+    // Try and read the first byte [block] since no errors are
+    // reported until then.
+    if (tftp_stream_read(&test_buf, 1, err) == 1) {
+        // Back up [rewind] over this datum
+        tftp_stream.bufp--;
+        tftp_stream.avail++;
+        return 0;  // Open and first read successful
+    } else {
+        tftp_stream.open = false;
+        return -1; // Couldn't read
+    }
 }
 
 int
--- a/packages/redboot/current/src/parse.c
+++ b/packages/redboot/current/src/parse.c
@@ -64,6 +64,7 @@ struct cmd *
 parse(char *line, int *argc, char **argv)
 {
     char *cp = line;
+    char *pp;
     int indx = 0;
 
     while (*cp) {
@@ -82,10 +83,19 @@ parse(char *line, int *argc, char **argv
                 if (argv[indx-1] == cp) {
                     argv[indx-1] = ++cp;
                 }
-                while (*cp && *cp != '"') cp++;
+                pp = cp;
+                while (*cp && *cp != '"') {
+                    if (*cp == '\\') {
+                        // Skip over escape - allows for escaped '"'
+                        cp++;
+                    }
+                    // Move string to swallow escapes
+                    *pp++ = *cp++;
+                }
                 if (!*cp) {
                     printf("Unbalanced string!\n");
                 } else {
+                    if (pp != cp) *pp = '\0';
                     *cp++ = '\0';
                     break;
                 }
@@ -298,7 +308,17 @@ parse_num(char *s, unsigned long *val, c
         c = *s++;
         if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) {
             // Valid digit
+#ifdef CYGPKG_HAL_MIPS
+            // FIXME: tx49 compiler generates 0x2539018 for MUL which
+            // isn't any good.
+            if (16 == radix)
+                result = result << 4;
+            else
+                result = 10 * result;
+            result += digit;
+#else
             result = (result * radix) + digit;
+#endif
         } else {
             if (delim != (char *)0) {
                 // See if this character is one of the delimiters
--- a/packages/redboot/current/src/xyzModem.c
+++ b/packages/redboot/current/src/xyzModem.c
@@ -62,12 +62,13 @@ static struct {
     unsigned char pkt[1024], *bufp;
     unsigned char blk,cblk,crc1,crc2;
     unsigned char next_blk;  // Expected block
-    int len, mode;
+    int len, mode, total_retries;
+    int total_SOH, total_STX, total_CAN;
     bool crc_mode, at_eof;
 } xyz;
 
-#define xyzModem_CHAR_TIMEOUT 1000  // 1 second
-#define xyzModem_MAX_RETRIES    20
+#define xyzModem_CHAR_TIMEOUT            2000  // 2 seconds
+#define xyzModem_MAX_RETRIES             20
 #define xyzModem_MAX_RETRIES_WITH_CRC    10
 
 // Table of CRC constants - implements x^16+x^12+x^5+1
@@ -193,10 +194,13 @@ xyzModem_get_hdr(void)
         if (res) {
             switch (c) {
             case SOH:
+                xyz.total_SOH++;
             case STX:
+                if (c == STX) xyz.total_STX++;
                 hdr_found = true;
                 break;
             case CAN:
+                xyz.total_CAN++;
                 ZM_DEBUG(zm_dump(__LINE__));
                 return xyzModem_cancel;
             case EOT:
@@ -300,6 +304,10 @@ xyzModem_stream_open(char *filename, int
     xyz.crc_mode = true;
     xyz.at_eof = false;
     xyz.mode = mode;
+    xyz.total_retries = 0;
+    xyz.total_SOH = 0;
+    xyz.total_STX = 0;
+    xyz.total_CAN = 0;
 
     while (retries-- > 0) {
         stat = xyzModem_get_hdr();
@@ -316,8 +324,12 @@ xyzModem_stream_open(char *filename, int
             if (--crc_retries <= 0) xyz.crc_mode = false;
             CYGACC_CALL_IF_DELAY_US(5*100000);   // Extra delay for startup
             CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+            xyz.total_retries++;
             ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__));
         }
+        if (stat == xyzModem_cancel) {
+            break;
+        }
     }
     *err = stat;
     return -1;
@@ -350,11 +362,15 @@ xyzModem_stream_read(char *buf, int size
                         stat = xyzModem_sequence;
                     }
                 }
+                if (stat == xyzModem_cancel) {
+                    break;
+                }
                 if (stat == xyzModem_eof) {
                     CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
                     ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__));
                     if (xyz.mode == xyzModem_ymodem) {
                         CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+                        xyz.total_retries++;
                         stat = xyzModem_get_hdr();                        
                         CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
                         ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__));
@@ -363,6 +379,7 @@ xyzModem_stream_read(char *buf, int size
                     break;
                 }
                 CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
+                xyz.total_retries++;
                 ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__));
             }
             if (stat < 0) {
@@ -383,6 +400,15 @@ xyzModem_stream_read(char *buf, int size
     return total;
 }
 
+void
+xyzModem_stream_close(int *err)
+{
+    printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", 
+           xyz.crc_mode ? "CRC" : "Cksum",
+           xyz.total_SOH, xyz.total_STX, xyz.total_CAN,
+           xyz.total_retries);
+}
+
 char *
 xyzModem_error(int err)
 {
--- a/packages/redboot/current/src/xyzModem.h
+++ b/packages/redboot/current/src/xyzModem.h
@@ -59,8 +59,9 @@
 #define xyzModem_cksum    -7
 #define xyzModem_sequence -8
 
-int xyzModem_stream_open(char *filename, int mode, int *err);    
-int xyzModem_stream_read(char *buf, int size, int *err);    
+int   xyzModem_stream_open(char *filename, int mode, int *err);    
+void  xyzModem_stream_close(int *err);    
+int   xyzModem_stream_read(char *buf, int size, int *err);    
 char *xyzModem_error(int err);
 
 #endif // _XYZMODEM_H_
--- a/packages/services/memalloc/common/current/ChangeLog
+++ b/packages/services/memalloc/common/current/ChangeLog
@@ -1,3 +1,8 @@
+2000-11-28  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/heapgen.tcl: Don't use cygpath -s for now as not all cygwins
+	have it yet.
+
 2000-11-25  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/memalloc.cdl: Make sure PWD variable doesn't clash with bash PWD
--- a/packages/services/memalloc/common/current/src/heapgen.tcl
+++ b/packages/services/memalloc/common/current/src/heapgen.tcl
@@ -1,7 +1,7 @@
 #!/bin/sh
 # these lines restart using the tcl shell \
     exec sh -c "if ( echo | cygtclsh80 ) 2>/dev/null ; then \
-      exec cygtclsh80 \"${0}\" \"\`echo \\\"\\\`cygpath -ws \\\"${1}\\\" \\\`\\\" |sed 's#\\\\\\\\#/#g'\`\" \"\`echo \\\"\\\`cygpath -ws \\\"${2}\\\" \\\`\\\" |sed 's#\\\\\\\\#/#g'\`\" ; \
+      exec cygtclsh80 \"${0}\" \"\`echo \\\"\\\`cygpath -w \\\"${1}\\\" \\\`\\\" |sed 's#\\\\\\\\#/#g'\`\" \"\`echo \\\"\\\`cygpath -w \\\"${2}\\\" \\\`\\\" |sed 's#\\\\\\\\#/#g'\`\" ; \
     elif ( echo | tclsh ) 2>/dev/null ; then \
       exec tclsh \"${0}\" ${1+${*}} ; \
     else \
@@ -9,6 +9,9 @@
       exit 1 ; \
     fi"
 
+#FIXMEFIXMEFIXME the above should use cygpath -ws, not cygpath -w but we
+#can't rely on everyone having up-to-date cygwin tools (1.1.5+)
+
 #===============================================================================
 #
 #    heapgen.tcl