changeset 4:1d7f19c9e4d1 ecos-sw-1999-05-11

Merge from eCos master repository on 1999-05-11-21:11:10-BST
author jlarmour
date Tue, 11 May 1999 14:07:25 +0000
parents 69e820d8bae1
children 4e8259f41183
files packages/ChangeLog packages/hal/arm/arch/current/ChangeLog packages/hal/arm/arch/current/include/hal_arch.h packages/hal/arm/arch/current/include/hal_mmu.h packages/hal/arm/arch/current/src/PKGconf.mak packages/hal/arm/arch/current/src/hal_mk_defs.c packages/hal/arm/arch/current/src/vectors.S packages/hal/common/current/ChangeLog packages/hal/common/current/src/PKGconf.mak packages/hal/i386/arch/current/ChangeLog packages/hal/i386/arch/current/src/PKGconf.mak packages/hal/mips/arch/current/ChangeLog packages/hal/mips/arch/current/include/pkgconf/hal_tx39.h packages/hal/mips/arch/current/src/PKGconf.mak packages/hal/mips/jmr3904/current/ChangeLog packages/hal/mn10300/arch/current/ChangeLog packages/hal/mn10300/arch/current/include/hal_cache.h packages/hal/mn10300/arch/current/src/PKGconf.mak packages/hal/powerpc/arch/current/ChangeLog packages/hal/powerpc/arch/current/src/PKGconf.mak packages/hal/powerpc/sim/current/ChangeLog packages/hal/powerpc/sim/current/include/pkgconf/mlt_powerpc_sim_ram.ldi packages/hal/powerpc/sim/current/include/pkgconf/mlt_powerpc_sim_ram.mlt packages/hal/sparclite/arch/current/ChangeLog packages/hal/sparclite/arch/current/src/PKGconf.mak packages/hal/sparclite/sleb/current/ChangeLog packages/hal/sparclite/sleb/current/src/hal_diag.c packages/io/common/current/ChangeLog packages/io/common/current/src/PKGconf.mak packages/io/serial/current/ChangeLog packages/io/serial/current/include/pkgconf/io_serial.h packages/io/serial/current/misc/timeout.inl packages/io/serial/current/src/PKGconf.mak packages/io/serial/current/src/common/serial.c packages/io/serial/current/src/mn10300/mn10300_serial.c packages/io/serial/current/tests/ser_test_protocol.inl packages/io/serial/current/tests/serial1.c packages/io/serial/current/tests/serial4.c packages/io/serial/current/tests/timeout.inl packages/kernel/current/ChangeLog packages/kernel/current/src/common/kapi.cxx packages/kernel/current/tests/except1.cxx packages/kernel/current/tests/kexcept1.c packages/kernel/current/tests/stress_threads.c packages/kernel/current/tests/tm_basic.cxx packages/language/c/libc/current/ChangeLog packages/language/c/libc/current/tests/signal/signal2.c packages/language/c/libc/current/tests/time/clock.c packages/packages packages/pkgconf.tcl packages/pkgconf/makevars packages/pkgconf/makrules.src packages/pkgconf/makrules.tst
diffstat 53 files changed, 1057 insertions(+), 401 deletions(-) [+]
line wrap: on
line diff
--- a/packages/ChangeLog
+++ b/packages/ChangeLog
@@ -1,7 +1,32 @@
-1999-04-26  Bart Veer  <bartv@cygnus.co.uk>
+1999-05-10  Bart Veer  <bartv@cygnus.co.uk>
+
+	* pkgconf.tcl:
+	Add new #define's for the target and platform headers.
+
+1999-04-30  Bart Veer  <bartv@cygnus.co.uk>
 
 	* pkgconf.tcl:
-	Temporary workaround - add a .PRECIOUS for libextras.a
+	Fixed the command line used when generating extras.o (again)
+
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* pkgconf/makevars:
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
+	* pkgconf/makrules.tst:
+	Remove out of date device driver rules
+
+	* pkgconf/makevars: 
+	* pkgconf/makrules.src:
+	Provide general rules for updating libextras.a
+
+1999-04-27  Bart Veer  <bartv@cygnus.co.uk>
+
+	* pkgconf.tcl:
+	Add $(ARCHFLAGS) and $(LDARCHFLAGS) to the command line when
+	generating extras.o from libextras.a
 
 1999-04-16  Bart Veer  <bartv@cygnus.co.uk>
 
@@ -15,6 +40,10 @@ 1999-04-16  Bart Veer  <bartv@cygnus.co.
 	libextras.a will always exist. This is now guaranteed via
 	hal/common/src/dummy.c
 
+1999-04-15  Gary Thomas  <gthomas@cygnus.co.uk>
+
+	* NEWS: Add information about available ARM ports.
+
 1999-04-15  Bart Veer  <bartv@cygnus.co.uk>
 
 	* pkgconf/makrules.src (build):
--- a/packages/hal/arm/arch/current/ChangeLog
+++ b/packages/hal/arm/arch/current/ChangeLog
@@ -1,3 +1,16 @@
+1999-05-10  Gary Thomas  <gthomas@cygnus.co.uk>
+
+	* src/vectors.S: 
+	* src/hal_mk_defs.c: 
+	* include/hal_arch.h: Fix up machine states, initialize stacks.
+
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak:
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
 1999-04-25  Gary Thomas  <gthomas@cygnus.co.uk>
 
 	* src/vectors.S: Fix use of 'RAISE_INTR' which cannot be used in 'mov'
--- a/packages/hal/arm/arch/current/include/hal_arch.h
+++ b/packages/hal/arm/arch/current/include/hal_arch.h
@@ -52,9 +52,10 @@
 
 #define CPSR_IRQ_DISABLE	0x80	// IRQ disabled when =1
 #define CPSR_FIQ_DISABLE	0x40	// FIQ disabled when =1
-#define CPSR_UNDEF_MODE		0x1D
+#define CPSR_FIQ_MODE		0x11
+#define CPSR_IRQ_MODE		0x12
 #define CPSR_SUPERVISOR_MODE	0x13
-#define CPSR_IRQ_MODE		0x12
+#define CPSR_UNDEF_MODE		0x1B
 
 #define CPSR_MODE_BITS          0x1F
 
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/arch/current/include/hal_mmu.h
@@ -0,0 +1,98 @@
+#ifndef CYGONCE_HAL_MMU_H
+#define CYGONCE_HAL_MMU_H
+
+//==========================================================================
+//
+//      hal_mmu.h
+//
+//      MMU definitions
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//
+// -------------------------------------------
+// The contents of this file are subject to the Cygnus eCos Public License
+// Version 1.0 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://sourceware.cygnus.com/ecos
+// 
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+// 
+// The Original Code is eCos - Embedded Cygnus Operating System, released
+// September 30, 1998.
+// 
+// The Initial Developer of the Original Code is Cygnus.  Portions created
+// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-05-10
+// Purpose:      Define MMU for ARM
+// Usage:        #include <cyg/hal/hal_mmu.h>
+
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define MMU_L1_TYPE         0x03  // Descriptor type
+#define MMU_L1_TYPE_Fault   0x00  // Invalid
+#define MMU_L1_TYPE_Page    0x11  // Individual page mapping
+#define MMU_L1_TYPE_Section 0x12  // Mapping for 1M segment
+
+#define MMU_L2_TYPE         0x03  // Descriptor type
+#define MMU_L2_TYPE_Fault   0x00  // Invalid data
+#define MMU_L2_TYPE_Large   0x01  // Large page (64K)
+#define MMU_L2_TYPE_Small   0x02  // Small page (4K)
+
+#define MMU_Bufferable      0x04  // Data can use write-buffer
+#define MMU_Cacheable       0x08  // Data can use cache
+
+#define MMU_AP_Limited     0x000  // Limited access
+#define MMU_AP_Supervisor  0x400  // Supervisor RW, User none
+#define MMU_AP_UserRead    0x800  // Supervisor RW, User read only
+#define MMU_AP_Any         0xC00  // Supervisor RW, User RW
+
+#define MMU_AP_ap0_Any     0x030
+#define MMU_AP_ap1_Any     0x0C0
+#define MMU_AP_ap2_Any     0x300
+#define MMU_AP_ap3_Any     0xC00
+
+#define MMU_AP_All (MMU_AP_ap0_Any|MMU_AP_ap1_Any|MMU_AP_ap2_Any|MMU_AP_ap3_Any)
+
+#define MMU_PAGE_SIZE      0x1000
+#define MMU_SECTION_SIZE   0x100000
+
+#define MMU_CP               p15      // Co-processor ID 
+#define MMU_Control          c1       // Control register
+#define MMU_Base             c2       // Page tables base
+#define MMU_DomainAccess     c3       // Domain access control
+#define MMU_FaultStatus      c5       // Fault status register
+#define MMU_FaultAddress     c6       // Fault Address
+#define MMU_InvalidateCache  c7       // Invalidate cache data
+#define MMU_TLB              c8       // Translation Lookaside Buffer
+
+#define MMU_Control_M  0x001    // Enable MMU
+#define MMU_Control_A  0x002    // Enable address alignment faults
+#define MMU_Control_C  0x004    // Enable cache
+#define MMU_Control_W  0x008    // Enable write-buffer
+#define MMU_Control_P  0x010    // Compatability: 32 bit code
+#define MMU_Control_D  0x020    // Compatability: 32 bit data
+#define MMU_Control_L  0x040    // Compatability:
+#define MMU_Control_B  0x080    // Enable Big-Endian
+#define MMU_Control_S  0x100    // Enable system protection
+#define MMU_Control_R  0x200    // Enable ROM protection
+#define MMU_Control_Init (MMU_Control_M|MMU_Control_P|MMU_Control_D)
+
+//-----------------------------------------------------------------------------
+
+#endif // CYGONCE_HAL_MMU_H
+// End of hal_mmu.h
--- a/packages/hal/arm/arch/current/src/PKGconf.mak
+++ b/packages/hal/arm/arch/current/src/PKGconf.mak
@@ -61,7 +61,7 @@ ldscript.stamp: arm.ld
 	$(CC) -E -P -Wp,-MD,ldscript.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/target.ld $<
 	@echo > ldscript.d
 	@echo $@ ':' $< '\' >> ldscript.d
-	@tail -n +2 ldscript.tmp >> ldscript.d
+	@tail +2 ldscript.tmp >> ldscript.d
 	@rm ldscript.tmp
 	$(TOUCH) $@
 
--- a/packages/hal/arm/arch/current/src/hal_mk_defs.c
+++ b/packages/hal/arm/arch/current/src/hal_mk_defs.c
@@ -92,9 +92,10 @@ main(void)
 #endif
     DEFINE(CPSR_IRQ_DISABLE, CPSR_IRQ_DISABLE);
     DEFINE(CPSR_FIQ_DISABLE, CPSR_FIQ_DISABLE);
-    DEFINE(CPSR_UNDEF_MODE, CPSR_UNDEF_MODE);
+    DEFINE(CPSR_IRQ_MODE, CPSR_IRQ_MODE);
+    DEFINE(CPSR_FIQ_MODE, CPSR_FIQ_MODE);
     DEFINE(CPSR_SUPERVISOR_MODE, CPSR_SUPERVISOR_MODE);
-    DEFINE(CPSR_IRQ_MODE, CPSR_IRQ_MODE);
+    DEFINE(CPSR_UNDEF_MODE, CPSR_UNDEF_MODE);
     DEFINE(CPSR_MODE_BITS, CPSR_MODE_BITS);
     DEFINE(CPSR_INITIAL, CPSR_INITIAL);
     DEFINE(CPSR_THREAD_INITIAL, CPSR_THREAD_INITIAL);
--- a/packages/hal/arm/arch/current/src/vectors.S
+++ b/packages/hal/arm/arch/current/src/vectors.S
@@ -104,6 +104,7 @@ PTR(start)
 	.global	reset_vector
 	.type	reset_vector,function
 reset_vector:
+
 #if defined(CYG_HAL_STARTUP_RAM) && \
     !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
 	mrs	r7,cpsr			// move back to IRQ mode
@@ -192,6 +193,9 @@ 2:
 	mov	r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_IRQ_MODE)
 	msr	cpsr,r0
 	ldr	sp,.__exception_stack
+	mov	r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_FIQ_MODE)
+	msr	cpsr,r0
+	ldr	sp,.__exception_stack
 	mov	r0,#(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE)
 	msr	cpsr,r0
 	ldr	sp,.__exception_stack
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,8 @@
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak:
+	Use the new rules for generating libextras.a
+
 1999-04-27  Jesper Skov  <jskov@cygnus.co.uk>
 
 	* include/pkgconf/hal.h: GDB_BREAK support now available for ARM
--- a/packages/hal/common/current/src/PKGconf.mak
+++ b/packages/hal/common/current/src/PKGconf.mak
@@ -28,25 +28,17 @@
 #####COPYRIGHTEND####
 #==============================================================================
 
-PACKAGE       := hal
+PACKAGE         := hal
 include ../../../../pkgconf/pkgconf.mak
 
-LIBRARY       := libtarget.a
-COMPILE       := generic-stub.c thread-packets.c hal_stub.c drv_api.c
+LIBRARY         := libtarget.a
+COMPILE         := generic-stub.c thread-packets.c hal_stub.c drv_api.c
+EXTRAS_COMPILE  := dummy.c
 
-OTHER_OBJS    :=
-OTHER_TARGETS := libextras.stamp
-OTHER_DEPS    := hal_dummy.d
-OTHER_CLEAN   := libextras.clean
+OTHER_OBJS      :=
+OTHER_TARGETS   :=
+OTHER_DEPS      :=
+OTHER_CLEAN     :=
 
 include $(COMPONENT_REPOSITORY)/pkgconf/makrules.src
 
-.PHONY: libextras.clean
-
-libextras.stamp: hal_dummy.o
-	$(AR) crs $(PREFIX)/lib/libextras.a $<
-	@$(TOUCH) $@
-
-libextras.clean:
-	$(RM) hal_dummy.o
-	$(RM) libextras.stamp
--- a/packages/hal/i386/arch/current/ChangeLog
+++ b/packages/hal/i386/arch/current/ChangeLog
@@ -1,3 +1,10 @@
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak: 
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
 1999-04-14  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* src/PKGconf.mak (EXTRAS): Don't generate extras.o here any more
--- a/packages/hal/i386/arch/current/src/PKGconf.mak
+++ b/packages/hal/i386/arch/current/src/PKGconf.mak
@@ -54,7 +54,7 @@ ldscript.stamp: i386.ld
 	$(CC) -E -P -Wp,-MD,ldscript.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/target.ld $<
 	@echo > ldscript.d
 	@echo $@ ':' $< '\' >> ldscript.d
-	@tail -n +2 ldscript.tmp >> ldscript.d
+	@tail +2 ldscript.tmp >> ldscript.d
 	@rm ldscript.tmp
 	$(TOUCH) $@
 
--- a/packages/hal/mips/arch/current/ChangeLog
+++ b/packages/hal/mips/arch/current/ChangeLog
@@ -1,22 +1,29 @@
-1999-04-30  Jesper Skov  <jskov@cygnus.co.uk>
+1999-04-30  Hugo Tyson  <hmt@cygnus.co.uk>
 
+	Merge the following changes from the 1.2.1 release branch,
+	but without any CDL for CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR,
+	it is always on.
+
+    1999-04-30  Jesper Skov  <jskov@cygnus.co.uk>
 	* src/hal_misc.c: Added vector decoding to the below.
-
-1999-04-30  Hugo Tyson  <hmt@masala.cygnus.co.uk>
-
+    1999-04-30  Hugo Tyson  <hmt@masala.cygnus.co.uk>
 	* src/hal_misc.c (hal_init_ctrlc_intr): Chain onto the old value
 	of the ISR when attaching the ctrl-c ISR; this allows chained
 	interrupts to work (otherwise a stack-wrecking interrupt loop
 	occurs).
-
-1999-04-29  Hugo Tyson  <hmt@cygnus.co.uk>
-
+    1999-04-29  Hugo Tyson  <hmt@cygnus.co.uk>
 	* include/pkgconf/hal_tx39.h (CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR): 
 	New config option, on by default.
-
 	* src/hal_misc.c (hal_ctrlc_isr): Enable these features on
 	CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR new config option.
 
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak:
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
 1999-04-20  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* include/hal_intr.h: Don't sync TRR if platform sim - it doesn't need
--- a/packages/hal/mips/arch/current/include/pkgconf/hal_tx39.h
+++ b/packages/hal/mips/arch/current/include/pkgconf/hal_tx39.h
@@ -68,26 +68,12 @@
            memory access speed settings."
    }
    
-   cdl_option CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR {
-       display "Install an Interrupt Service Routine to catch HALT requests"
-       type     bool
-       parent   CYGPKG_HAL_TX39
-       description "
-           This option enables startup code to install a default ISR on the
-           serial debug connection which reads characters looking for the
-           HALT character control-C (\003). This allows a running program
-           to be interrupted from GDB. This option only has effect if eCos
-           is configured to run with the Cygmon ROM monitor on the JMR3904
-           development board. Interrupts must be enabled for the code to
-           work. The serial device drivers, if enabled, do take over the
-           ISR and function correctly."
-   }
-   
    }}CFG_DATA */
 
 
 #define CYGHWR_HAL_MIPS_CPU_FREQ        50
 
+/* NO CDL for this because we want it enabled always. */
 #define CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR
 
 /* -------------------------------------------------------------------*/
--- a/packages/hal/mips/arch/current/src/PKGconf.mak
+++ b/packages/hal/mips/arch/current/src/PKGconf.mak
@@ -57,7 +57,7 @@ ldscript.stamp: tx39.ld
 	$(CC) -E -P -Wp,-MD,ldscript.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/target.ld $<
 	@echo > ldscript.d
 	@echo $@ ':' $< '\' >> ldscript.d
-	@tail -n +2 ldscript.tmp >> ldscript.d
+	@tail +2 ldscript.tmp >> ldscript.d
 	@rm ldscript.tmp
 	$(TOUCH) $@
 
--- a/packages/hal/mips/jmr3904/current/ChangeLog
+++ b/packages/hal/mips/jmr3904/current/ChangeLog
@@ -1,5 +1,8 @@
-1999-04-29  Hugo Tyson  <hmt@cygnus.co.uk>
+1999-04-30  Hugo Tyson  <hmt@cygnus.co.uk>
 
+	Merge the following changes from the 1.2.1 release branch.
+
+   1999-04-29  Hugo Tyson  <hmt@cygnus.co.uk>	
 	* src/hal_diag.c (hal_diag_write_char): Only include the code to
 	read the '+' from GDB and test for ^C there if not installing the
 	default isr to catch these: CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR.
--- a/packages/hal/mn10300/arch/current/ChangeLog
+++ b/packages/hal/mn10300/arch/current/ChangeLog
@@ -1,3 +1,28 @@
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak:
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
+1999-04-20  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+	* include/hal_cache.h: 
+	(HAL_DCACHE_IS_ENABLED) (HAL_ICACHE_IS_ENABLED): Add these new macros
+	(HAL_DCACHE_DISABLE) (HAL_ICACHE_DISABLE): Make variables register
+	variables
+	Ensure the cache has finished its operation before exitting.
+	(HAL_DCACHE_INVALIDATE_ALL) (HAL_ICACHE_INVALIDATE_ALL): Make
+	variables register variables.
+	Re-enable cache if it was enabled on entry.
+	(HAL_DCACHE_WRITE_MODE): Make variables register variables.
+	Re-enable data cache if it was enabled on entry.
+	Ensure the cache has finished its operation before exitting.
+	(HAL_DCACHE_STORE): Make variables register variables.
+	Re-enable data cache if it was enabled on entry.
+
+	These fix PR19887
+
 1999-04-15  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* src/mn10300.ld: Define __bss_end at the end of the BSS
--- a/packages/hal/mn10300/arch/current/include/hal_cache.h
+++ b/packages/hal/mn10300/arch/current/include/hal_cache.h
@@ -213,7 +213,7 @@
 // Enable the data cache
 #define HAL_DCACHE_ENABLE()                     \
 {                                               \
-    CYG_ADDRWORD chctr = *HAL_CHCTR;            \
+    register CYG_ADDRWORD chctr = *HAL_CHCTR;   \
     chctr |= HAL_CHCTR_DCEN;                    \
     *HAL_CHCTR = chctr;                         \
 }
@@ -221,23 +221,33 @@
 // Disable the data cache
 #define HAL_DCACHE_DISABLE()                    \
 {                                               \
-    CYG_ADDRWORD chctr = *HAL_CHCTR;            \
+    register CYG_ADDRWORD chctr = *HAL_CHCTR;   \
     chctr &= ~HAL_CHCTR_DCEN;                   \
     *HAL_CHCTR = chctr;                         \
+    while( HAL_CHCTR_DCBUSY & *HAL_CHCTR );     \
+}
+
+// Query the state of the data cache
+#define HAL_DCACHE_IS_ENABLED(_state_)          \
+{                                               \
+    register CYG_ADDRWORD chctr = *HAL_CHCTR;   \
+    _state_ = (0 != (chctr & HAL_CHCTR_DCEN));  \
 }
 
 // Invalidate the entire cache
 #define HAL_DCACHE_INVALIDATE_ALL()             \
 {                                               \
-    CYG_ADDRWORD chctr, chctr1;                 \
-    chctr = chctr1 = *HAL_CHCTR;                \
-    chctr &= ~HAL_CHCTR_DCEN;                   \
-    *HAL_CHCTR = chctr;                         \
-    while( *HAL_CHCTR & HAL_CHCTR_DCBUSY );     \
+    register CYG_ADDRWORD chctr;                \
+    register CYG_ADDRWORD state;                \
+    HAL_DCACHE_IS_ENABLED(state);               \
+    if (state)                                  \
+        HAL_DCACHE_DISABLE();                   \
+    chctr = *HAL_CHCTR;                         \
     chctr |= HAL_CHCTR_DCINV;                   \
     *HAL_CHCTR = chctr;                         \
-    while( *HAL_CHCTR & HAL_CHCTR_DCBUSY );     \
-    *HAL_CHCTR = chctr1;                        \
+    while( HAL_CHCTR_DCBUSY & *HAL_CHCTR );     \
+    if (state)                                  \
+        HAL_DCACHE_ENABLE();                    \
 }
 
 // Synchronize the contents of the cache with memory.
@@ -249,12 +259,17 @@
 // Set the data cache write mode
 #define HAL_DCACHE_WRITE_MODE( _mode_ )         \
 {                                               \
-    CYG_ADDRWORD chctr;                         \
+    register CYG_ADDRWORD chctr;                \
+    register CYG_ADDRWORD state;                \
+    HAL_DCACHE_IS_ENABLED(state);               \
+    if (state)                                  \
+        HAL_DCACHE_DISABLE();                   \
     chctr = *HAL_CHCTR;                         \
-    HAL_DCACHE_DISABLE();                       \
-    while( *HAL_CHCTR & HAL_CHCTR_DCBUSY );     \
     chctr |= HAL_CHCTR_DCWTMD*(_mode_);         \
     *HAL_CHCTR = chctr;                         \
+    while( HAL_CHCTR_DCBUSY & *HAL_CHCTR );     \
+    if (state)                                  \
+        HAL_DCACHE_ENABLE();                    \
 }
 
 #define HAL_DCACHE_WRITEBACK_MODE       0
@@ -290,10 +305,11 @@
     volatile register CYG_BYTE *way0 = HAL_DCACHE_PURGE_WAY0;   \
     volatile register CYG_BYTE *way1 = HAL_DCACHE_PURGE_WAY1;   \
     int i;                                                      \
-    register CYG_ADDRWORD chctr;                                \
-    chctr = *HAL_CHCTR;                                         \
-    HAL_DCACHE_DISABLE();                                       \
-    while( *HAL_CHCTR & HAL_CHCTR_DCBUSY );                     \
+    register CYG_ADDRWORD state;                                \
+                                                                \
+    HAL_DCACHE_IS_ENABLED(state);                               \
+    if (state)                                                  \
+        HAL_DCACHE_DISABLE();                                   \
                                                                 \
     way0 += ((CYG_ADDRWORD)_base_) & 0x000007f0;                \
     way1 += ((CYG_ADDRWORD)_base_) & 0x000007f0;                \
@@ -304,7 +320,8 @@
         way0 += HAL_DCACHE_LINE_SIZE;                           \
         way1 += HAL_DCACHE_LINE_SIZE;                           \
     }                                                           \
-    *HAL_CHCTR = chctr;                                         \
+    if (state)                                                  \
+        HAL_DCACHE_ENABLE();                                    \
 }
 
 // Preread the given range into the cache with the intention of reading
@@ -324,7 +341,7 @@
 // Enable the instruction cache
 #define HAL_ICACHE_ENABLE()                     \
 {                                               \
-    CYG_ADDRWORD chctr = *HAL_CHCTR;            \
+    register CYG_ADDRWORD chctr = *HAL_CHCTR;   \
     chctr |= HAL_CHCTR_ICEN;                    \
     *HAL_CHCTR = chctr;                         \
 }
@@ -332,23 +349,33 @@
 // Disable the instruction cache
 #define HAL_ICACHE_DISABLE()                    \
 {                                               \
-    CYG_ADDRWORD chctr = *HAL_CHCTR;            \
+    register CYG_ADDRWORD chctr = *HAL_CHCTR;   \
     chctr &= ~HAL_CHCTR_ICEN;                   \
     *HAL_CHCTR = chctr;                         \
+    while( HAL_CHCTR_ICBUSY & *HAL_CHCTR );     \
+}
+
+// Query the state of the instruction cache
+#define HAL_ICACHE_IS_ENABLED(_state_)          \
+{                                               \
+    register CYG_ADDRWORD chctr = *HAL_CHCTR;   \
+    _state_ = (0 != (chctr & HAL_CHCTR_ICEN));  \
 }
 
 // Invalidate the entire cache
 #define HAL_ICACHE_INVALIDATE_ALL()             \
 {                                               \
-    CYG_ADDRWORD chctr, chctr1;                 \
-    chctr1 = *HAL_CHCTR;                        \
-    HAL_ICACHE_DISABLE();                       \
-    while( *HAL_CHCTR & HAL_CHCTR_ICBUSY );     \
+    register CYG_ADDRWORD chctr;                \
+    register CYG_ADDRWORD state;                \
+    HAL_ICACHE_IS_ENABLED(state);               \
+    if (state)                                  \
+        HAL_ICACHE_DISABLE();                   \
     chctr = *HAL_CHCTR;                         \
     chctr |= HAL_CHCTR_ICINV;                   \
     *HAL_CHCTR = chctr;                         \
-    while( *HAL_CHCTR & HAL_CHCTR_ICBUSY );     \
-    *HAL_CHCTR = chctr1;                        \
+    while( HAL_CHCTR_ICBUSY & *HAL_CHCTR );     \
+    if (state)                                  \
+        HAL_ICACHE_ENABLE();                    \
 }
 
 // Synchronize the contents of the cache with memory.
--- a/packages/hal/mn10300/arch/current/src/PKGconf.mak
+++ b/packages/hal/mn10300/arch/current/src/PKGconf.mak
@@ -57,7 +57,7 @@ ldscript.stamp: mn10300.ld
 	$(CC) -E -P -Wp,-MD,ldscript.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/target.ld $<
 	@echo > ldscript.d
 	@echo $@ ':' $< '\' >> ldscript.d
-	@tail -n +2 ldscript.tmp >> ldscript.d
+	@tail +2 ldscript.tmp >> ldscript.d
 	@rm ldscript.tmp
 	$(TOUCH) $@
 
--- a/packages/hal/powerpc/arch/current/ChangeLog
+++ b/packages/hal/powerpc/arch/current/ChangeLog
@@ -1,3 +1,10 @@
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak: 
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
 1999-04-19  Jesper Skov  <jskov@cygnus.co.uk>
         PR 19861
 	* src/vectors.S (_start): Rewrote the hal_zero_bss code in
--- a/packages/hal/powerpc/arch/current/src/PKGconf.mak
+++ b/packages/hal/powerpc/arch/current/src/PKGconf.mak
@@ -57,7 +57,7 @@ ldscript.stamp: powerpc.ld
 	$(CC) -E -P -Wp,-MD,ldscript.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/target.ld $<
 	@echo > ldscript.d
 	@echo $@ ':' $< '\' >> ldscript.d
-	@tail -n +2 ldscript.tmp >> ldscript.d
+	@tail +2 ldscript.tmp >> ldscript.d
 	@rm ldscript.tmp
 	$(TOUCH) $@
 
--- a/packages/hal/powerpc/sim/current/ChangeLog
+++ b/packages/hal/powerpc/sim/current/ChangeLog
@@ -1,3 +1,9 @@
+1999-04-28  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* include/pkgconf/mlt_powerpc_sim_ram.ldi: 
+	* include/pkgconf/mlt_powerpc_sim_ram.mlt: 
+	Increased memory size to 1MB.
+	
 1999-04-08  John Dallaway  <jld@cygnus.co.uk>
 
 	* include/pkgconf/*.ldi: Revised SECTION_* macro arguments to
--- a/packages/hal/powerpc/sim/current/include/pkgconf/mlt_powerpc_sim_ram.ldi
+++ b/packages/hal/powerpc/sim/current/include/pkgconf/mlt_powerpc_sim_ram.ldi
@@ -28,7 +28,7 @@
 
 MEMORY
 {
-    ram : ORIGIN = 0, LENGTH = 0x80000
+    ram : ORIGIN = 0, LENGTH = 0x100000
 }
 
 SECTIONS
--- a/packages/hal/powerpc/sim/current/include/pkgconf/mlt_powerpc_sim_ram.mlt
+++ b/packages/hal/powerpc/sim/current/include/pkgconf/mlt_powerpc_sim_ram.mlt
@@ -1,5 +1,5 @@
 version 0
-region ram 0 80000 0 !
+region ram 0 100000 0 !
 section vectors 0 1 0 1 1 0 1 0 0 0 !
 section text 0 1 0 1 1 1 1 1 4000 4000 fini fini !
 section fini 0 4 0 1 0 1 0 1 rodata1 rodata1 !
--- a/packages/hal/sparclite/arch/current/ChangeLog
+++ b/packages/hal/sparclite/arch/current/ChangeLog
@@ -1,3 +1,10 @@
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak:
+	Remove the -n argument to tail, it does not appear to be required
+	on any supported host and causes problems with some
+	implementations of tail.
+
 1999-04-15  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* src/sparclite.ld: Define __bss_end at the end of the BSS
--- a/packages/hal/sparclite/arch/current/src/PKGconf.mak
+++ b/packages/hal/sparclite/arch/current/src/PKGconf.mak
@@ -59,7 +59,7 @@ ldscript.stamp: sparclite.ld
 	$(CC) -E -P -Wp,-MD,ldscript.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $(PREFIX)/lib/target.ld $<
 	@echo > ldscript.d
 	@echo $@ ':' $< '\' >> ldscript.d
-	@tail -n +2 ldscript.tmp >> ldscript.d
+	@tail +2 ldscript.tmp >> ldscript.d
 	@rm ldscript.tmp
 	$(TOUCH) $@
 
--- a/packages/hal/sparclite/sleb/current/ChangeLog
+++ b/packages/hal/sparclite/sleb/current/ChangeLog
@@ -1,3 +1,8 @@
+1999-04-23  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* src/hal_diag.c (hal_bsp_console_write): Added a workaround for PR
+	19926.
+
 1999-04-09  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* include/hal_cache.h (HAL_[DI]CACHE_IS_ENABLED): 
--- a/packages/hal/sparclite/sleb/current/src/hal_diag.c
+++ b/packages/hal/sparclite/sleb/current/src/hal_diag.c
@@ -175,10 +175,32 @@ typedef struct {
     void *__dbg_vector;
     void *__kill_vector;
     struct bsp_comm_procs *__console_procs;
+    struct bsp_comm_procs *__debug_procs;
+    void *__flush_dcache;
+    void *__flush_icache;
+    void *__cpu_data;
+    void *__board_data;
+    void *__sysinfo;
+    int  (*__set_debug_comm)(int __comm_id);
+    void *__set_console_comm;
 } bsp_shared_t;
 
 
 static int
+hal_bsp_set_debug_comm(int arg)
+{
+    bsp_shared_t *shared;
+
+    shared = (bsp_shared_t *)
+        (CYGMON_VECTOR_TABLE[ BSP_NOTVEC_BSP_COMM_PROCS ]);
+
+    if (0 != shared->__set_debug_comm) {
+        return (*(shared->__set_debug_comm))(arg);
+    }
+    return 0;
+}
+
+static int
 hal_bsp_console_write(const char *p, int len)
 {
     bsp_shared_t *shared;
@@ -191,6 +213,23 @@ hal_bsp_console_write(const char *p, int
 
     if (0 != com) {
         com->__write(com->ch_data, p, len);
+
+#if 1
+        // FIXME: This is a workaround for PR 19926; CygMon does not
+        // expect to be sharing the line with a serial driver (which
+        // can be excused :) and so doesn't acknowledge the interrupt.
+        // In normal circumstances CygMon would handle the resulting
+        // interrupt and do the right thing.  However, when using the
+        // serial driver it is handling the interrupts and gets
+        // mightily confused by these spurious interrupts.
+        //
+        // As a workaround, ask CygMon which communication port is
+        // using for console output. If this is the serial port 
+        // (comm 0), acknowledge the interrupt.
+        if ( 0 == hal_bsp_set_debug_comm( -1 ) )
+            HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_VECTOR_INTERRUPT_10 );
+#endif
+
         return 1;
     }
     return 0;
@@ -238,7 +277,7 @@ void hal_diag_write_char(char c)
 
         // And re-enable interrupts
         HAL_RESTORE_INTERRUPTS(old);
-       
+
     }
 }
 
--- a/packages/io/common/current/ChangeLog
+++ b/packages/io/common/current/ChangeLog
@@ -1,3 +1,8 @@
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak (EXTRAS_COMPILE):
+	Use the new rules for generating libextras.a
+
 1999-04-15  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* src/iosys.c (cyg_io_set_config): Only dereference len if non-NULL
--- a/packages/io/common/current/src/PKGconf.mak
+++ b/packages/io/common/current/src/PKGconf.mak
@@ -32,8 +32,9 @@ PACKAGE       := io
 include ../../../../pkgconf/pkgconf.mak
 include ../../../../pkgconf/system.mak
 
-LIBRARY        := libextras.a
-COMPILE        := iosys.c ioinit.cxx io_diag.c
+LIBRARY        :=
+COMPILE        :=
+EXTRAS_COMPILE := iosys.c ioinit.cxx io_diag.c
 OTHER_OBJS     :=
 OTHER_CLEAN    :=
 
--- a/packages/io/serial/current/ChangeLog
+++ b/packages/io/serial/current/ChangeLog
@@ -1,8 +1,65 @@
+
+1999-05-05  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* tests/ser_test_protocol.inl: Tidied up a bit and added
+	description of protocol.
+
+1999-05-05  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* src/common/serial.c (serial_write, serial_read): Clear abort
+	flag at entry.
+
+1999-05-05  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* tests/serial4.c (serial_test): Handle config fails correctly.
+
+	* tests/ser_test_protocol.inl: Better change_config
+	handling. Simple recovery and negotiation isn't timing
+	dependant. 
+
+1999-05-05  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* tests/timeout.inl: Updated with the below changes.
+
+1999-05-05  Gary Thomas  <gthomas@cygnus.co.uk>
+
+	* misc/timeout.inl (timeout): Timeouts are relative, but alarms 
+	need absolute time values.
+
+1999-05-04  Jesper Skov  <jskov@cygnus.co.uk>
+        PR 20018
+	* tests/serial1.c (serial_test): Always PASS, regardless of
+	configuration.
+
+1999-05-04  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* tests/ser_test_protocol.inl: Reverse order of configurations -
+	run tests with slow baud rate first.
+	Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04  Jesper Skov  <jskov@cygnus.co.uk>
+ 	* src/mn10300/mn10300_serial.c:
+ 	Use interrupt enable/disable feature of serial port2 to allow
+ 	coexistence with CygMon/hal_diag.
+ 
+ 	* tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28  Bart Veer  <bartv@cygnus.co.uk>
+
+	* src/PKGconf.mak (EXTRAS_COMPILE):
+	Use the new rules for generating libextras.a
+
+
 1999-04-20  Gary Thomas  <gthomas@cygnus.co.uk>
 
 	* src/arm/aeb_serial.c: 
 	* src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20  Jesper Skov  <jskov@cygnus.co.uk>
 
+	* tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+	for SLEB. Only run test on SLEB if CygMon isn't used for diag
+	output.
+	
 1999-04-15  Jesper Skov  <jskov@cygnus.co.uk>
         PR 19752
 	* tests/serial3.c:
--- a/packages/io/serial/current/include/pkgconf/io_serial.h
+++ b/packages/io/serial/current/include/pkgconf/io_serial.h
@@ -384,6 +384,8 @@
 #define CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE 128
 
 
+
+
 /* ----------------------------------------------------------------------------
    {{CFG_DATA
    cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT {
--- a/packages/io/serial/current/misc/timeout.inl
+++ b/packages/io/serial/current/misc/timeout.inl
@@ -73,7 +73,7 @@ do_timeout(cyg_handle_t alarm, cyg_addrw
     }
     if (min_delta != 0x7FFFFFFF) {
         // Still something to do, schedule it
-        cyg_alarm_initialize(timeout_alarm_handle, min_delta, 0);
+        cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
         last_delta = min_delta;
     }
 }
@@ -110,7 +110,7 @@ timeout(cyg_int32 delta, timeout_fun *fu
     }
     if (min_delta != 0x7FFFFFFF) {
         // Still something to do, schedule it
-        cyg_alarm_initialize(timeout_alarm_handle, min_delta, 0);
+        cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
         last_delta = min_delta;
     }
     return stamp;
--- a/packages/io/serial/current/src/PKGconf.mak
+++ b/packages/io/serial/current/src/PKGconf.mak
@@ -32,25 +32,25 @@ PACKAGE       := io_serial
 include ../../../../pkgconf/pkgconf.mak
 include ../../../../pkgconf/system.mak
 
-LIBRARY       := libextras.a
-COMPILE       := common/serial.c common/tty.c common/haldiag.c
+LIBRARY         := 
+EXTRAS_COMPILE  := common/serial.c common/tty.c common/haldiag.c
 ifdef CYG_HAL_ARM_PID
-COMPILE       += arm/pid_serial_with_ints.c
+EXTRAS_COMPILE  += arm/pid_serial_with_ints.c
 endif
 ifdef CYG_HAL_ARM_AEB
-COMPILE       += arm/aeb_serial.c
+EXTRAS_COMPILE  += arm/aeb_serial.c
 endif
 ifdef CYG_HAL_MN10300_STDEVAL1
-COMPILE       += mn10300/mn10300_serial.c
+EXTRAS_COMPILE  += mn10300/mn10300_serial.c
 endif
 ifdef CYG_HAL_TX39
-COMPILE       += mips/tx3904_serial.c
+EXTRAS_COMPILE  += mips/tx3904_serial.c
 endif
 ifdef CYG_HAL_POWERPC_COGENT
-COMPILE       += powerpc/cogent_serial_with_ints.c
+EXTRAS_COMPILE  += powerpc/cogent_serial_with_ints.c
 endif
 ifdef CYG_HAL_SPARCLITE_SLEB
-COMPILE       += sparclite/sleb_sdtr.c
+EXTRAS_COMPILE  += sparclite/sleb_sdtr.c
 endif
 OTHER_OBJS    :=
 OTHER_CLEAN   :=
--- a/packages/io/serial/current/src/common/serial.c
+++ b/packages/io/serial/current/src/common/serial.c
@@ -103,6 +103,7 @@ serial_write(cyg_io_handle_t handle, con
     int next;
     cbuf_t *cbuf = &chan->out_cbuf;
     Cyg_ErrNo res = ENOERR;
+    cbuf->abort = false;
 
     cyg_drv_mutex_lock(&cbuf->lock);
     if (cbuf->len == 0) {
@@ -153,6 +154,7 @@ serial_read(cyg_io_handle_t handle, void
     cyg_int32 size = 0;
     cbuf_t *cbuf = &chan->in_cbuf;
     Cyg_ErrNo res = ENOERR;
+    cbuf->abort = false;
 
     cyg_drv_mutex_lock(&cbuf->lock);
     if (cbuf->len == 0) {
--- a/packages/io/serial/current/src/mn10300/mn10300_serial.c
+++ b/packages/io/serial/current/src/mn10300/mn10300_serial.c
@@ -110,6 +110,7 @@ static void       mn10300_serial_tx_DSR(
 #define LCR_WL8         0x80    // 8 bit chars
 #define LCR_RXE         0x4000  // receive enable
 #define LCR_TXE         0x8000  // transmit enable
+#define LCR_TWE         0x0100  // interrupt enable (only on serial2)
 
 //-------------------------------------------------------------------------
 // MN10300 timer registers:
@@ -449,12 +450,6 @@ mn10300_serial_config_port(serial_channe
     mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
     cyg_uint16 cr = 0;
 
-#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)
-    // If we are using CYGMON, do not reinitialize serial 2 at this
-    // point, since it appears to upset GDB.
-    if( mn10300_chan->is_serial2 ) return true;
-#endif    
-    
     // Disable device entirely.
     HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0);
     HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0);
@@ -506,8 +501,13 @@ mn10300_serial_config_port(serial_channe
     // enable RX and TX
     cr |= LCR_RXE | LCR_TXE;
 #else
-    // Enable RX only
-    cr |= LCR_RXE;
+    if( mn10300_chan->is_serial2 ) {
+        cr |= LCR_RXE | LCR_TXE;        // enable Rx and TX
+        cr &= ~LCR_TWE;                 // disable transmit interrupts
+    } else {
+        // Enable RX only
+        cr |= LCR_RXE;
+    }
 #endif
     
     // Write CR into hardware
@@ -528,12 +528,6 @@ bool mn10300_serial_init(struct cyg_devt
     serial_channel *chan = (serial_channel *)tab->priv;
     mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
 
-#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)
-    // If we are using CYGMON, do not reinitialize serial 2. If we do then we
-    // will steal the receive interrupt and disable Ctrl-C handling.
-    if( mn10300_chan->is_serial2 ) return true;
-#endif    
-    
     (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
 
 #ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE    
@@ -641,7 +635,10 @@ mn10300_serial_start_xmit(serial_channel
 
     HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
 
-    cr |= LCR_TXE;
+    if( mn10300_chan->is_serial2 )
+        cr |= LCR_TWE;                  // enable transmit interrupts
+    else
+        cr |= LCR_TXE;                  // enable TX
 
     HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
 
@@ -672,7 +669,10 @@ mn10300_serial_stop_xmit(serial_channel 
     
     HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
 
-    cr &= ~LCR_TXE;
+    if( mn10300_chan->is_serial2 )
+        cr &= ~LCR_TWE;                 // disable transmit interrupts
+    else
+        cr &= ~LCR_TXE;                 // disable transmission
 
     HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
 
--- a/packages/io/serial/current/tests/ser_test_protocol.inl
+++ b/packages/io/serial/current/tests/ser_test_protocol.inl
@@ -56,8 +56,16 @@
 
 #include <cyg/hal/hal_intr.h>           // for reclaiming interrup vector
 
+#ifdef CYG_HAL_SPARCLITE_SLEB
+#include <pkgconf/hal_sparclite_sleb.h> // CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT
+#endif
+
 //----------------------------------------------------------------------------
 // Definition of which device to run tests on on various platforms.
+
+#define NA_MSG "No test device specified"
+
+
 #if defined(CYGPKG_HAL_POWERPC_COGENT)                          \
     && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT)                 \
     && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B)
@@ -92,24 +100,29 @@
 #endif
 #if defined(CYGPKG_HAL_MN10300_STDEVAL1)                \
     && defined(CYGPKG_IO_SERIAL_MN10300)                \
-    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL1)
-// Note: Serial1 is *not* the same port as GDB is using. It seems that
-// CygMon is interfering with the tests if run on the same port.
-// This configuration allows the serial driver to be tested using the
-// filter in stand alone mode (option -n).
-# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME
-# if defined(CYGPKG_IO_SERIAL_TTY_TTY1)
+    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL2)
+# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME
+# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)
 #  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
 # endif
 #endif
 #if defined(CYGPKG_HAL_SPARCLITE_SLEB)                    \
     && defined(CYGPKG_IO_SERIAL_SPARCLITE_SLEB)           \
     && defined(CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1)
-# define TEST_SER_DEV CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME
-# define SER_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9
-# define SER_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10
-# if defined(CYGPKG_IO_SERIAL_TTY_TTY0)
-#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV
+# undef NA_MSG
+# define NA_MSG "CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT is unset"
+# if !defined(CYG_HAL_STARTUP_RAM) \
+     || defined(CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT)
+#  define TEST_SER_DEV CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME
+// The interrupt vectors are normally in CygMon's control. Steal them back,
+// but beware that this results in GDB acknowledge characters showing up in
+// the serial driver if CygMon is used for hal_diag output.
+// Set CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT in hal_sparclite_sleb as a workaround.
+#  define SER_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9
+#  define SER_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10
+#  if defined(CYGPKG_IO_SERIAL_TTY_TTY0)
+#   define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV
+#  endif
 # endif
 #endif
 
@@ -165,12 +178,21 @@ typedef struct ser_cfg {
 // A few predefined configurations. These must all be valid for any
 // given target until change_config is behaving correctly.
 cyg_ser_cfg_t test_configs[] = {
-#if !defined(CYGPKG_HAL_TX39_JMR3904) &&        \
-    !defined(CYGPKG_HAL_ARM_PID) &&             \
-    !defined(CYGPKG_HAL_ARM_AEB) &&             \
-    !defined(CYGPKG_HAL_MN10300_STDEVAL1) &&    \
-    !defined(CYGPKG_HAL_SPARCLITE_SLEB)
-    { CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_WORD_LENGTH_8, 
+
+#if !defined(CYGPKG_HAL_TX39_JMR3904) && !defined(CYGPKG_HAL_ARM_PID)
+    { CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_WORD_LENGTH_8, 
+      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
+#endif
+
+    { CYGNUM_SERIAL_BAUD_14400, CYGNUM_SERIAL_WORD_LENGTH_8, 
+      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
+
+    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, 
+      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
+
+#if !defined(CYGPKG_HAL_SPARCLITE_SLEB) &&      \
+    !defined(CYGPKG_HAL_ARM_AEB)
+    { CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_WORD_LENGTH_8, 
       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
 #endif
 
@@ -181,14 +203,12 @@ cyg_ser_cfg_t test_configs[] = {
       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
 #endif
 
-    { CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_WORD_LENGTH_8, 
-      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
-
-    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, 
-      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
-
-#if !defined(CYGPKG_HAL_TX39_JMR3904) && !defined(CYGPKG_HAL_ARM_PID)
-    { CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_WORD_LENGTH_8, 
+#if !defined(CYGPKG_HAL_TX39_JMR3904) &&        \
+    !defined(CYGPKG_HAL_ARM_PID) &&             \
+    !defined(CYGPKG_HAL_ARM_AEB) &&             \
+    !defined(CYGPKG_HAL_MN10300_STDEVAL1) &&    \
+    !defined(CYGPKG_HAL_SPARCLITE_SLEB)
+    { CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_WORD_LENGTH_8, 
       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },
 #endif
 
@@ -252,7 +272,8 @@ do {                                    
 
 //----------------------------------------------------------------------------
 // Macros for read/write to serial with error cheking.
-cyg_uint32 r_stamp;
+static volatile cyg_uint32 r_stamp;
+static volatile int aborted;
 
 // This routine will be called if the read "times out"
 static void
@@ -261,6 +282,7 @@ do_abort(void *handle)
     cyg_io_handle_t io_handle = (cyg_io_handle_t)handle;
     cyg_int32 len = 1;  // Need something here
     cyg_io_get_config(io_handle, CYG_IO_GET_CONFIG_SERIAL_ABORT, 0, &len);
+    aborted = 1;
 }
 #include "timeout.inl"
 
@@ -286,6 +308,7 @@ do_abort(void *handle)
     int __res;                                                          \
     cyg_uint32 __len = 1;                                               \
     __res = cyg_io_write((__h), (__d), (__l));                          \
+    if (ENOERR != __res) diag_printf("[%d]\n", __res);                  \
     CYG_TEST_CHECK(ENOERR == __res, "cyg_io_write failed");             \
     __res = cyg_io_get_config((__h),                                    \
                               CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,    \
@@ -344,27 +367,45 @@ hang(void)
 
 //-----------------------------------------------------------------------------
 // Configuration changing function.
-// FIXME: This is still slightly bogus in that it doesn't check for target
-//        capabilities. Correct way is;
-//            o try setting new cfg
-//            o restore
-//            o if OK:
-//               o send cfg to target
-//               o if reply OK:
-//                  o change to new cfg
+//
+// First change to the new config and back again to determine if the driver
+// can handle the config.
+// If not, return error.
+//
+// Then query the host for its capability to use the config:
+// Format out:
+//  "@CONFIG:<baud rate code>:<#data bits>:<#stop bits>:<parity on/off>!"
+// Format in:
+//  OK/ER
+//
+// On ER, return error.
 //
-// Host&protocol currently only supports:
-//  - no/even parity
+// On OK, change to the new configuration. Resynchronize with the host:
+//  Write 'T'-chars to the host.
+//   The host will echo anything it reads until it sees a 'O' character.
+//  Continue until four 'T'-chars has been read back.
+//  Then send a single 'O'-character. This will signal success to the host.
+//
+// If the synchronization has not succeeded within 100 ticks
+// (configurable in the protocol), both host and target will revert to
+// the previous configuration and attempt to synchronize again. If
+// this fails, this call will hang and the host will consider the test
+// a failure.
+//
+// To Do:
+//  Host&protocol currently only supports:
+//   - no/even parity
 int
 change_config(cyg_io_handle_t handle, cyg_ser_cfg_t* cfg)
 {
+    cyg_serial_info_t old_cfg, new_cfg;
     const char cmd[] = "@CONFIG:";
     char reply[2];
     int msglen;
-    int res;
+    int res, len;
     cyg_uint8 *p1;
-    
-    // Prepare and send the command.
+
+    // Prepare the command.
     p1 = &cmd_buffer[0];
     p1 = strcpy(p1, &cmd[0]);
     p1 = itoa(p1, cfg->baud_rate);
@@ -375,60 +416,179 @@ change_config(cyg_io_handle_t handle, cy
     *p1++ = ':';
     p1 = itoa(p1, cfg->parity);
     *p1++ = '!';
-    *p1++ = 0;
+    *p1 = 0;                            // note: we may append to this later
 
+    // Tell user what we're up to.
     CYG_TEST_INFO(&cmd_buffer[1]);
 
+    // Change to new config and then back to determine if the driver likes it.
+    len = sizeof(old_cfg);
+    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, 
+                            &old_cfg, &len);
+    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, 
+                            &new_cfg, &len);
+    if (res != ENOERR) {
+        diag_printf("Can't get serial config - DEVIO error: %d\n", res);
+        hang();
+    }
+
+    new_cfg.baud = cfg->baud_rate;
+    new_cfg.word_length = cfg->data_bits;
+    new_cfg.stop = cfg->stop_bits;
+    new_cfg.parity = cfg->parity;
+
+    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, 
+                            &new_cfg, &len);
+
+    // Driver didn't like it. It will not have changed anything, so it's
+    // safe to return now.
+    if (ENOERR != res) {
+        // Let user know that the config was skipped due to the target.
+        const char txt_tskipped[] = "- skipped by target!";
+        p1 = strcpy(p1, txt_tskipped);
+        *p1 = 0;
+        CYG_TEST_INFO(&cmd_buffer[1]);
+        return res;
+    }
+
+    // Succeeded. Change back to the original config so we can communicate
+    // with the host.
+    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, 
+                            &old_cfg, &len);
+    if (ENOERR != res) {
+        diag_printf("change_config: set_config failed/1 (%d)\n", res);
+        hang();
+    }
+
+    // Send command to host and read host's reply.
     msglen = strlen(&cmd_buffer[0]);
     Tcyg_io_write(handle, &cmd_buffer[0], &msglen);
-
     msglen = 2;
     Tcyg_io_read(handle, &reply[0], &msglen);
 
-    if (reply[0] == 'O') {
-        // Change config
-        cyg_serial_info_t serial_info;
-        int len = sizeof(serial_info);
-        res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &serial_info, &len);
-        if (res != ENOERR) {
-            diag_printf("Can't get serial config - DEVIO error: %d\n", res);
-            hang();
-        }
+    // Did host accept configuration?
+    if ('O' != reply[0] || 'K' != reply[1]) {
+        // Let user know that the config was skipped due to the host.
+        const char txt_hskipped[] = "- skipped by host!";
+        p1 = strcpy(p1, txt_hskipped);
+        *p1 = 0;
+        CYG_TEST_INFO(&cmd_buffer[1]);
+        diag_printf("Host didn't accept config (%02x, %02x).\n",
+                    reply[0], reply[1]);
+
+        res = ENOSUPP;
+        return res;
+    }
+
+    // Now test the new configuration: Loop until we read what we
+    // write.  This may hang (as seen from the host), but only when we
+    // get totally lost, in which case there's not much else to do
+    // really. In this case the host will consider the test a FAIL.
+    len = sizeof(new_cfg);
+    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, 
+                            &new_cfg, &len);
+    if (ENOERR != res) {
+        diag_printf("change_config: set_config failed/2 (%d)\n", res);
+        hang();
+    }
+
+    // Note: Only sends a single char - a string wuld be safer, but if
+    // there's not a 1-1 relationship between outgoing and incoming
+    // chars, the reader needs to be smarter. Compensate by
+    // requirering the char to be read 4 times in succession.
+    for (;;) {
+        int change_succeeded = 0;
+        int using_old_config = 0;
+        int matches = 0;
+        char in_buf[1];
+        int len;
+        char out_buf[1];
+
+        out_buf[0] = 'a';
 
-        serial_info.baud = cfg->baud_rate;
-        serial_info.word_length = cfg->data_bits;
-        serial_info.stop = cfg->stop_bits;
-        serial_info.parity = cfg->parity;
+        aborted = 0;                    // global abort flag
+        // FIXME: Timeout time needs to be configurable, and needs to
+        // be sent to the host before getting here. That would allow
+        // changing the timeout by just rebuilding the test - without
+        // changing the host software.
+        r_stamp = timeout(100, do_abort, handle);
+        while (!aborted) {
+            len = 1;
+            res = cyg_io_write(handle, out_buf, &len);
+            if (ENOERR != res && -EINTR != res) {
+                // We may have to reset the driver here if the fail
+                // was due to a framing or parity error.
+                break;
+            }
+        
+            len = 1;
+            res = cyg_io_read(handle, in_buf, &len);
+            if (ENOERR != res && -EINTR != res) {
+                // We may have to reset the driver here if the fail
+                // was due to a framing or parity error.
+                break;
+            }
+        
+            // Check for match.
+            if (out_buf[0] == in_buf[0]) {
+                matches++;
+                // We want 4 in succession before we accept it.
+                if (4 == matches) {
+                    change_succeeded = 1;
+                    break;
+                }
+            } else
+                matches = 0;
+        }
+        untimeout(r_stamp);
+        
+        // Did we succeed?
+        if (change_succeeded) {
+            // Yup! Send 'O' to host so it knows we're OK.
+            const char ok_str[1] = "O";
+            len = 1;
+            res = cyg_io_write(handle, ok_str, &len);
+            if (res != ENOERR) {
+                diag_printf("write failed - DEVIO error: %d\n", res);
+                hang();
+            }
 
-        res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &len);
-        if (res != ENOERR) {
-            diag_printf("Can't set serial config - DEVIO error: %d\n", res);
-            hang();
+            // Now wait for the 'O' to be echoed so we know both lines
+            // have been emptied.
+            r_stamp = timeout(100, do_abort, handle);
+            do {
+                len = 1;
+                res = cyg_io_read(handle, in_buf, &len);
+                CYG_ASSERT(ENOERR == res, "Failed when waiting for 'O'");
+            } while ('O' != in_buf[0]);
+            untimeout(r_stamp);
+
+            // If we had to revert to the old configuration, return error.
+            if (using_old_config)
+                return -EIO;
+            else
+                return ENOERR;
         }
 
-        res = ENOERR;
-    } else {
-        res = ENOSUPP;
-#ifdef __DEVELOPER__
-        diag_printf("Host didn't accept config (%02x, %02x).\n",
-                    reply[0], reply[1]);
-#endif
-    }
+        // We didn't. Due to an IO error?
+        if (ENOERR != res && -EINTR != res) {
+            // We may have to reset the driver if the fail was due to
+            // a framing or parity error.
+        }
 
-#if 0
-    // FIXME: This is needed to prevent sending data at the new baud rate
-    // before the host is ready.... Need to fiddle this a bit more.
-    // Loop counts for ARM and PII in host side source. Replace with
-    // timed loops.
-    {
-        int i;
-        for (i = 0; i < 100000; i++);
-    }
-#else
-    cyg_thread_delay(80);               // this requires kernel
-#endif
-
-    return res;
+        // Revert to the old configuration and try again.
+        len = sizeof(old_cfg);
+        res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, 
+                                &old_cfg, &len);
+        if (res != ENOERR) {
+            diag_printf("change_config: set_config failed/3 (%d)\n", res);
+            hang();
+        }
+        out_buf[0] = 't';               // change the char so a developer can
+                                        // see this has happened by the chars
+                                        // being written.
+        using_old_config = 1;
+    }        
 }
 
 
@@ -791,7 +951,7 @@ test_open_ser( cyg_io_handle_t* handle )
         CYG_TEST_FAIL_FINISH("Can't lookup " TEST_SER_DEV);
     }
 #else
-    CYG_TEST_NA("No test device specified");
+    CYG_TEST_NA(NA_MSG);
 #endif
 }
 
@@ -818,7 +978,7 @@ test_open_tty( cyg_io_handle_t* handle )
         CYG_TEST_FAIL_FINISH("Can't lookup " TEST_TTY_DEV);
     }
 #else
-    CYG_TEST_NA("No test device specified");
+    CYG_TEST_NA(NA_MSG);
 #endif
 }
 
--- a/packages/io/serial/current/tests/serial1.c
+++ b/packages/io/serial/current/tests/serial1.c
@@ -62,17 +62,20 @@ cyg_handle_t thread_handle;
 
 
 void
-serial_api_test(cyg_io_handle_t* handle)
+serial_api_test(int dummy)
 {
+    cyg_io_handle_t handle;
     int res, len;
     unsigned char buffer[16];
 
     // Always return...
-    if (handle)
+    if (dummy)
         return;
 
     CYG_TEST_FAIL_FINISH("Not reached");
 
+    test_open_ser(&handle);
+
     // read & write
     res = cyg_io_read(handle, &buffer[0], &len);
     res = cyg_io_write(handle, &buffer[0], &len);
@@ -98,11 +101,7 @@ serial_api_test(cyg_io_handle_t* handle)
 void
 serial_test( void )
 {
-    cyg_io_handle_t ser_handle;
-
-    test_open_ser(&ser_handle);
-
-    serial_api_test(&ser_handle);
+    serial_api_test(1);
 
     CYG_TEST_PASS_FINISH("serial1 test OK");
 }
--- a/packages/io/serial/current/tests/serial4.c
+++ b/packages/io/serial/current/tests/serial4.c
@@ -84,10 +84,11 @@ serial_test( void )
         int msglen = strlen(msg);
 
         for (i = 0; i < count; i++){
-            change_config(ser_handle, &test_configs[i]);
-            test_binary(ser_handle,    128, MODE_EOP_ECHO);
-            test_binary(ser_handle,    256, MODE_NO_ECHO);
-            Tcyg_io_write(ser_handle, msg, &msglen);
+            if (ENOERR == change_config(ser_handle, &test_configs[i])) {
+                test_binary(ser_handle,    128, MODE_EOP_ECHO);
+                test_binary(ser_handle,    256, MODE_NO_ECHO);
+                Tcyg_io_write(ser_handle, msg, &msglen);
+            }
         }
     }
 
--- a/packages/io/serial/current/tests/timeout.inl
+++ b/packages/io/serial/current/tests/timeout.inl
@@ -73,7 +73,7 @@ do_timeout(cyg_handle_t alarm, cyg_addrw
     }
     if (min_delta != 0x7FFFFFFF) {
         // Still something to do, schedule it
-        cyg_alarm_initialize(timeout_alarm_handle, min_delta, 0);
+        cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
         last_delta = min_delta;
     }
 }
@@ -110,7 +110,7 @@ timeout(cyg_int32 delta, timeout_fun *fu
     }
     if (min_delta != 0x7FFFFFFF) {
         // Still something to do, schedule it
-        cyg_alarm_initialize(timeout_alarm_handle, min_delta, 0);
+        cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
         last_delta = min_delta;
     }
     return stamp;
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,6 +1,42 @@
+1999-05-10  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* tests/stress_threads.c (main_program): Added workaround for a
+	few PRs.
+
+1999-05-07  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* src/common/kapi.cxx (cyg_scheduler_unlock, cyg_scheduler_lock):
+	Make these simple calls to the scheduler.
+
+1999-05-07  Jesper Skov  <jskov@cygnus.co.uk>
+
+	* tests/stress_threads.c (setup_death_alarm): Reduce run time on
+	synthetic target.
+
+1999-05-06  Jesper Skov  <jskov@cygnus.co.uk>
+        
+	* tests/stress_threads.c: Reversed priorities of agents.
+
+1999-05-06  Jesper Skov  <jskov@cygnus.co.uk>
+        PRs 20040, (20027), 19991
+	* tests/stress_threads.c: Added main_thread handling resource
+	deallocation and printing.
+
+1999-04-27  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+	* tests/stress_threads.c: 
+	If there aren't enough priorities, output an N/A, rather than
+	stopping compilation with a #error
+
 1999-04-28  Jesper Skov  <jskov@cygnus.co.uk>
         PR 19850
- 	* tests/stress_threads.c: Don't print text from alarm handler.
+	* tests/stress_threads.c: Don't print text from alarm handler.
+
+1999-04-28  Jesper Skov  <jskov@cygnus.co.uk>
+        PR 19945 workaround
+	* tests/kexcept1.c: 
+	* tests/except1.cxx:
+	Made NA to PowerPC SIM.
 
 1999-04-27  Gary Thomas  <gthomas@cygnus.co.uk>
 
@@ -10,6 +46,8 @@ 1999-04-27  Gary Thomas  <gthomas@cygnus
 	can show up cache effects.
 	Show thread stack usage.
 
+	Fix merge screwup :-(
+
 1999-04-26  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* include/kapi.h: Add missing function cyg_thread_delete();
@@ -34,7 +72,7 @@ 1999-04-23  Mark Galassi  <rosalia@cygnu
 	(perform_stressful_tasks): added writing of a bit pattern to the
 	malloc()-ed spaces.  Also reduced stack requirements for threads.
 
-1999-04-23  Hugo Tyson  <hmt@cygnus.co.uk>
+1999-04-23  Hugo Tyson  <hmt@masala.cygnus.co.uk>
 
 	* src/common/timer.cxx (Cyg_Timer::activate): we must also disable
 	the alarm when resetting it so as to remove it from its queue, so
@@ -45,7 +83,7 @@ 1999-04-23  Hugo Tyson  <hmt@cygnus.co.u
 	enable CYGIMP_KERNEL_COUNTERS_MULTI_LIST,
 	value CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE {8}.
 	The PR is 19475.
-
+	
 1999-04-21  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* tests/bin_sem1.cxx (bin_sem1_main): Doh!  Use priorities 4 and 5
@@ -54,11 +92,6 @@ 1999-04-21  Hugo Tyson  <hmt@cygnus.co.u
 	assert in the attempt to set thread 0's prio to 1, "prios not
 	unique").  PR 19904.
 
-1999-04-20  Hugo Tyson  <hmt@cygnus.co.uk>
-
-	* tests/stress_threads.c: applied my patch to fix stack sizes.
-	And timing, in simulator; branch now matches the trunk.
-
 1999-04-20  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* tests/kcache2.c: 
@@ -72,6 +105,10 @@ 1999-04-19  Jonathan Larmour  <jlarmour@
 	scheduling problems if the clock rolls over immediately
 	Fix for PR 19516
 
+1999-04-20  Mark Galassi  <rosalia@cygnus.com>
+
+	* tests/stress_threads.c: applied Hugo's patch to fix stack sizes.
+ 
 1999-04-19  Hugo Tyson  <hmt@cygnus.co.uk>
 
 	* tests/bin_sem1.cxx (bin_sem1_main): Add priorities to the
--- a/packages/kernel/current/src/common/kapi.cxx
+++ b/packages/kernel/current/src/common/kapi.cxx
@@ -104,30 +104,16 @@ externC void cyg_scheduler_start(void)
     Cyg_Scheduler::start();
 }
 
-/* Lock the scheduler. We only allow this to take the lock from */
-/* zero to 1. Any other transition implies that this function   */
-/* is being called from an ISR/DSR or some other illegal place. */
+/* Lock the scheduler. */
 externC void cyg_scheduler_lock(void)
 {
     Cyg_Scheduler::lock();
-    
-    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1 ,
-                "Cannot nest calls to cyg_scheduler_lock");
-
-    if( Cyg_Scheduler::get_sched_lock() != 1 )
-        Cyg_Scheduler::unlock();        
 }
 
-/* Unlock the scheduler. Like lock, we only allow a 1->0        */
-/* transition.                                                  */
+/* Unlock the scheduler. */
 externC void cyg_scheduler_unlock(void)
 {
-    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1 ,
-                "Bad call to cyg_scheduler_unlock");
-
-    if( Cyg_Scheduler::get_sched_lock() == 1 )
-        Cyg_Scheduler::unlock();
-    
+    Cyg_Scheduler::unlock();
 }
 
 /*---------------------------------------------------------------------------*/
--- a/packages/kernel/current/tests/except1.cxx
+++ b/packages/kernel/current/tests/except1.cxx
@@ -135,9 +135,14 @@ static void entry0( CYG_ADDRWORD data )
     p->deregister_exception(CYGNUM_HAL_EXCEPTION_MAX);
     p->deregister_exception(CYGNUM_HAL_EXCEPTION_MAX);
 
-#ifdef CYGPKG_HAL_I386_LINUX
+#if 0
+#elif defined(CYGPKG_HAL_POWERPC_SIM)
+    // The exception generated by the SIM is not recognized by GDB.
+    // PR 19945 workaround.
+    CYG_TEST_NA("Not applicable to PowerPC SIM");
+#elif defined(CYGPKG_HAL_I386_LINUX)
     // We can't catch segmentation violation exceptions on Linux.
-    CYG_TEST_PASS_FINISH("Except 1 OK");
+    CYG_TEST_NA("Not applicable to synthetic target");
 #endif
 
     for(n = CYGNUM_HAL_EXCEPTION_MIN; n <= CYGNUM_HAL_EXCEPTION_MAX; n++) {
--- a/packages/kernel/current/tests/kexcept1.c
+++ b/packages/kernel/current/tests/kexcept1.c
@@ -143,9 +143,14 @@ static void entry0( CYG_ADDRWORD data )
     cyg_exception_clear_handler(CYGNUM_HAL_EXCEPTION_MAX);
     cyg_exception_clear_handler(CYGNUM_HAL_EXCEPTION_MAX);
 
-#ifdef CYGPKG_HAL_I386_LINUX
+#if 0
+#elif defined(CYGPKG_HAL_POWERPC_SIM)
+    // The exception generated by the SIM is not recognized by GDB.
+    // PR 19945 workaround.
+    CYG_TEST_NA("Not applicable to PowerPC SIM");
+#elif defined(CYGPKG_HAL_I386_LINUX)
     // We can't catch segmentation violation exceptions on Linux.
-    CYG_TEST_PASS_FINISH("Except 1 OK");
+    CYG_TEST_NA("Not applicable to synthetic target");
 #endif
 
     for(n = CYGNUM_HAL_EXCEPTION_MIN; n <= CYGNUM_HAL_EXCEPTION_MAX; n++) {
--- a/packages/kernel/current/tests/stress_threads.c
+++ b/packages/kernel/current/tests/stress_threads.c
@@ -30,10 +30,19 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):     rosalia
-// Contributors:  rosalia
+// Contributors:  rosalia, jskov
 // Date:          1999-04-13
 // Description:   Very simple thread stress test, with some memory
 //                allocation and alarm handling.
+//
+// Notes:
+//  If client_makes_request is big, it means that there are made many more
+//  client requests than can be serviced. Consequently, clients are wasting
+//  CPU time and should be sleeping more.
+//
+//  The list of handler invocations show how many threads are running
+//  at the same time. The more powerful the CPU, the more the numbers
+//  should spread out.
 //####DESCRIPTIONEND####
 
 #include <pkgconf/system.h>
@@ -65,50 +74,59 @@
 
 /* if TIME_LIMIT is defined, it represents the number of seconds this
    test should last; if it is undefined the test will go forever */
-#define DEATH_TIME_LIMIT 15
+#define DEATH_TIME_LIMIT 20
 /*  #undef DEATH_TIME_LIMIT */
 
 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL)
 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)
 
-#define N_CLIENTS 4
+/* Allocate priorities in this order. This ensures that handlers
+   (which are the ones using the CPU) get enough CPU time to actually
+   complete their tasks. */
+#define N_MAIN 1
+#define MAX_HANDLERS 19
 #define N_LISTENERS 4
-#define MAX_HANDLERS 19
+#define N_CLIENTS 4
 
-#if (CYGNUM_KERNEL_SCHED_PRIORITIES < (N_CLIENTS+N_LISTENERS+MAX_HANDLERS))
-# error "not enough priorities available"
-#endif
+#if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS))
 
 /* if we use the bitmap scheduler we must make sure we don't use the
    same priority more than once, so we must store those already in use */
-static char priority_in_use[N_CLIENTS+N_LISTENERS+MAX_HANDLERS];
+static volatile char priority_in_use[N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS];
 
 /* now declare (and allocate space for) some kernel objects, like the
    threads we will use */
-cyg_thread client_thread_s[N_CLIENTS];
+cyg_thread main_thread_s;
+cyg_thread handler_thread_s[MAX_HANDLERS];
 cyg_thread listener_thread_s[N_LISTENERS];
-cyg_thread handler_thread_s[MAX_HANDLERS];
+cyg_thread client_thread_s[N_CLIENTS];
 
 /* space for stacks for all threads */
-char client_stack[N_CLIENTS][STACK_SIZE];
+char main_stack[STACK_SIZE];
+char handler_stack[MAX_HANDLERS][STACK_SIZE2];
 char listener_stack[N_LISTENERS][STACK_SIZE];
-char handler_stack[MAX_HANDLERS][STACK_SIZE2];
+char client_stack[N_CLIENTS][STACK_SIZE];
 
 /* now the handles for the threads */
-cyg_handle_t clientH[N_CLIENTS];
-cyg_handle_t listenerH[N_LISTENERS];
+cyg_handle_t mainH;
 cyg_handle_t handlerH[MAX_HANDLERS];
-
-#ifdef DEATH_TIME_LIMIT
-/* how many client threads have been killed by the death handler */
-int n_clients_killed = 0;
-#endif /* DEATH_TIME_LIMIT */
+cyg_handle_t listenerH[N_LISTENERS];
+cyg_handle_t clientH[N_CLIENTS];
 
 /* and now variables for the procedure which is the thread */
-cyg_thread_entry_t client_program, listener_program, handler_program;
+cyg_thread_entry_t main_program, client_program, listener_program, 
+    handler_program;
 
 /* a few mutexes used in the code */
-cyg_mutex_t client_request_lock, handler_slot_lock, statistics_print_lock;
+cyg_mutex_t client_request_lock, handler_slot_lock, statistics_print_lock, 
+    free_handler_lock;
+
+/* global variables with which the handler IDs and thread priorities
+   to free are communicated from handlers to main_program. Access to
+   these are protected by free_handler_lock. An id of -1 means the
+   that the variables are empty. */
+volatile int free_handler_pri = 0;
+volatile int free_handler_id = -1;
 
 /* a global variable with which the client and server coordinate */
 int client_makes_request = 0;
@@ -138,23 +156,21 @@ struct s_statistics statistics;
 /* some function prototypes; those with the sc_ prefix are
    "statistics-collecting" versions of the cyg_ primitives */
 void sc_thread_create(
-    cyg_addrword_t        sched_info,           /* scheduling info (eg pri)  */
+    cyg_addrword_t      sched_info,             /* scheduling info (eg pri)  */
     cyg_thread_entry_t  *entry,                 /* entry point function      */
-    cyg_addrword_t        entry_data,           /* entry data                */
+    cyg_addrword_t      entry_data,             /* entry data                */
     char                *name,                  /* optional thread name      */
     void                *stack_base,            /* stack base, NULL = alloc  */
     cyg_ucount32        stack_size,             /* stack size, 0 = default   */
     cyg_handle_t        *handle,                /* returned thread handle    */
     cyg_thread          *thread                 /* put thread here           */
 );
-void sc_thread_exit(void);
 
 int get_handler_slot(cyg_handle_t current_threadH);
 void perform_stressful_tasks(void);
 void permute_array(char a[], int size, int seed);
 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
                        cyg_alarm *death_alarm_p, int *killed_p);
-void handle_death(cyg_handle_t deathH, cyg_handle_t alarmH);
 void print_statistics(void);
 
 /* we need to declare the alarm handling function (which is defined
@@ -175,35 +191,53 @@ void cyg_user_start(void)
 
   cyg_mutex_init(&client_request_lock);
   cyg_mutex_init(&statistics_print_lock);
+  cyg_mutex_init(&free_handler_lock);
 
   /* initialize statistics */
   memset(&statistics, 0, sizeof(statistics));
 
+  /* clear priority table */
+  for (i = 0; i < sizeof(priority_in_use); i++)
+      priority_in_use[i] = 0;
+
+  /* initialize main thread */
+  {
+      char thread_name[] = "main";
+
+      sc_thread_create(0, main_program, (cyg_addrword_t) 0,
+                       thread_name, (void *) main_stack, STACK_SIZE,
+                       &mainH, &main_thread_s);
+      priority_in_use[0]++;
+  }
+
   /* initialize all handler threads to not be in use */
   for (i = 0; i < MAX_HANDLERS; ++i) {
     handler_thread_in_use[i] = 0;
   }
+  for (i = 0; i < N_LISTENERS; ++i) {
+    int prio;
+    char thread_name[20];
+    sprintf(thread_name, "listener-%02d", i);
+    prio = N_MAIN + MAX_HANDLERS + i;
+    sc_thread_create(prio, listener_program, (cyg_addrword_t) i,
+                      thread_name, (void *) listener_stack[i], STACK_SIZE,
+                      &listenerH[i], &listener_thread_s[i]);
+    CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
+    priority_in_use[prio]++;
+  }
   for (i = 0; i < N_CLIENTS; ++i) {
     int prio;
     char thread_name[20];
     sprintf(thread_name, "client-%02d", i);
-    prio = i;
+    prio = N_MAIN + MAX_HANDLERS + N_LISTENERS + i;
     sc_thread_create(prio, client_program, (cyg_addrword_t) i,
                       thread_name, (void *) client_stack[i], STACK_SIZE,
                       &(clientH[i]), &client_thread_s[i]);
-    priority_in_use[prio] = 1;
-  }
-  for (i = 0; i < N_LISTENERS; ++i) {
-    int prio;
-    char thread_name[20];
-    sprintf(thread_name, "listener-%02d", i);
-    prio = N_CLIENTS + i;
-    sc_thread_create(prio, listener_program, (cyg_addrword_t) i,
-                      thread_name, (void *) listener_stack[i], STACK_SIZE,
-                      &listenerH[i], &listener_thread_s[i]);
-    priority_in_use[prio] = 1;
+    CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
+    priority_in_use[prio]++;
   }
 
+  cyg_thread_resume(mainH);
   for (i = 0; i < N_CLIENTS; ++i) {
     cyg_thread_resume(clientH[i]);
   }
@@ -220,11 +254,75 @@ void cyg_user_start(void)
                    (cyg_addrword_t) 4000,
                    &report_alarmH, &report_alarm);
   if (cyg_test_is_simulator) {
-    cyg_alarm_initialize(report_alarmH, cyg_current_time()+300, 400);
+    cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, 200);
   } else {
     cyg_alarm_initialize(report_alarmH, cyg_current_time()+300, 4000);
   }
+}
 
+/* main_program() -- frees resources and prints status. */
+void main_program(cyg_addrword_t data)
+{
+#ifdef DEATH_TIME_LIMIT
+    cyg_handle_t deathH;
+    cyg_alarm death_alarm;
+    int is_dead = 0;
+
+    setup_death_alarm(0, &deathH, &death_alarm, &is_dead);
+#endif /* DEATH_TIME_LIMIT */
+
+    printf("# Starting main\n");
+
+    for (;;) {
+        int handler_id = -1;
+        int handler_pri = 0;
+
+        cyg_mutex_lock(&free_handler_lock); {
+            // If any handler has left its ID, copy the ID and
+            // priority values to local variables, and free up the
+            // global communication variables again.
+            if (-1 != free_handler_id) {
+                handler_id = free_handler_id;
+                handler_pri = free_handler_pri;
+                free_handler_id = -1;
+            }
+        } cyg_mutex_unlock(&free_handler_lock);
+
+        if (-1 != handler_id) {
+            // Free the handler resources. This is done outside of the
+            // free_handler_lock to avoid deadlocks.
+            cyg_mutex_lock(&handler_slot_lock); {
+                CYG_ASSERT(1 == priority_in_use[handler_pri], 
+                           "Priority not in use!");
+                CYG_ASSERT(1 == handler_thread_in_use[handler_id], 
+                           "Handler not in use!");
+                handler_thread_in_use[handler_id]--;
+                priority_in_use[handler_pri]--;
+                // Finally delete the handler thread.
+                {
+                    // workaround for PRs 20054-20058/20065
+                    cyg_thread_kill(handlerH[handler_id]);
+                }
+                cyg_thread_delete(handlerH[handler_id]);
+            } cyg_mutex_unlock(&handler_slot_lock);
+        }
+
+        // Print status if time.
+        if (time_to_report) {
+            time_to_report = 0;
+            print_statistics();
+        }
+
+#ifdef DEATH_TIME_LIMIT
+        // Stop test if time.
+        if (is_dead) {
+            print_statistics();
+            CYG_TEST_PASS_FINISH("Kernel thread stress test OK");
+        }
+#endif /* DEATH_TIME_LIMIT */
+
+        cyg_thread_delay(3);
+    }
 }
 
 /* client_program() -- an obnoxious client which makes a lot of requests */
@@ -232,19 +330,13 @@ void client_program(cyg_addrword_t data)
 {
   int delay;
 
-  cyg_handle_t counterH, deathH, system_clockH;
-  cyg_alarm death_alarm;
-  int is_dead = 0;
-
-  setup_death_alarm(data, &deathH, &death_alarm, &is_dead);
-
   printf("# Starting client-%d\n", (int) data);
 
   system_clockH = cyg_real_time_clock();
   cyg_clock_to_counter(system_clockH, &counterH);
 
   for (;;) {
-    delay = (rand() % 3);
+    delay = (rand() % 20);
 
     /* now send a request to the server */
     cyg_mutex_lock(&client_request_lock); {
@@ -254,11 +346,6 @@ void client_program(cyg_addrword_t data)
 
     cyg_thread_delay(10+delay);
 /*      cyg_thread_delay(0); */
-#ifdef DEATH_TIME_LIMIT
-    if (is_dead) {
-      handle_death(deathH, report_alarmH);
-    }
-#endif /* DEATH_TIME_LIMIT */
   }
 }
 
@@ -267,40 +354,40 @@ void client_program(cyg_addrword_t data)
 void listener_program(cyg_addrword_t data)
 {
 /*   int message = (int) data; */
-  int handler_slot;
+    int handler_slot;
 
-  printf("# Beginning execution; thread data is %d\n", (int) data);
+    printf("# Beginning execution; thread data is %d\n", (int) data);
 
-  for (;;) {
-#ifdef DEATH_TIME_LIMIT
-    /* as an extra task, the listener sees if all clients have been
-       killed off, so it can report that the test is over */
-    if (n_clients_killed == N_CLIENTS) {
-      n_clients_killed = -1;    /* so we don't call this again */
-      CYG_TEST_PASS_FINISH("Kernel thread stress test OK");
+    for (;;) {
+        int make_request = 0;
+        cyg_mutex_lock(&client_request_lock); {
+            if (client_makes_request > 0) {
+                --client_makes_request;
+                make_request = 1;
+            }
+        } cyg_mutex_unlock(&client_request_lock);
+        
+        if (make_request) {
+            int prio;
+            /* printf("just got a request from a client (count = %d)\n", */
+            /*        client_makes_request); */
+
+            handler_slot = get_handler_slot(listenerH[(int) data]);
+            prio = N_MAIN+handler_slot;
+
+            CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
+            priority_in_use[prio]++;
+            sc_thread_create(prio, handler_program,
+                             (cyg_addrword_t) handler_slot,
+                             "handler", (void *) handler_stack[handler_slot],
+                             STACK_SIZE2, &handlerH[handler_slot],
+                             &handler_thread_s[handler_slot]);
+            cyg_thread_resume(handlerH[handler_slot]);
+            ++statistics.handler_invocation_histogram[handler_slot];
+        }
+
+        cyg_thread_delay(2 + (rand() % 10));
     }
-#endif /* DEATH_TIME_LIMIT */
-    if (client_makes_request > 0) {
-      int prio;
-      /*          printf("just got a request from a client (count = %d)\n", */
-      /*                 client_makes_request); */
-      cyg_mutex_lock(&client_request_lock); {
-        --client_makes_request;
-      } cyg_mutex_unlock(&client_request_lock);
-
-      handler_slot = get_handler_slot(listenerH[(int) data]);
-      prio = N_CLIENTS+N_LISTENERS+handler_slot;
-      priority_in_use[prio] = 1;
-      sc_thread_create(prio, handler_program,
-                       (cyg_addrword_t) handler_slot,
-                       "handler", (void *) handler_stack[handler_slot],
-                       STACK_SIZE2, &handlerH[handler_slot],
-                       &handler_thread_s[handler_slot]);
-      cyg_thread_resume(handlerH[handler_slot]);
-      ++statistics.handler_invocation_histogram[handler_slot];
-    }
-    cyg_thread_delay(1);
-  }
 }
 
 /* handler_program() -- is spawned to handle each incoming request */
@@ -309,56 +396,56 @@ void handler_program(cyg_addrword_t data
   /* here is where we perform specific stressful tasks */
   perform_stressful_tasks();
 
-  if (time_to_report) {
-    time_to_report = 0;
-    print_statistics();
-  }
-
   cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000)))));
 /*    cyg_thread_delay(0); */
 
-  /* lock the scheduler before we declare this thread slot available
-     and quit; note that cyg_thread_exit() will unlock the scheduler
-     as many times as necessary */
-  cyg_mutex_lock(&handler_slot_lock); {
-    handler_thread_in_use[data] = 0;
-    priority_in_use[N_CLIENTS + N_LISTENERS + (int) data] = 0;
-  } cyg_mutex_unlock(&handler_slot_lock);
-  /* FIXME: could there be a race condition right here? I unlock the
-     scheduler, so I could get pre-empted out, but meanwhile I have
-     declared this thread available again.  must fix it. */
-  sc_thread_exit();
+  ++statistics.thread_exits;
+  {
+      // Loop until the handler id and priority can be communicated to
+      // the main_program.
+      int freed = 0;
+      do {
+          cyg_mutex_lock(&free_handler_lock); {
+              if (-1 == free_handler_id) {
+                  free_handler_id = data;
+                  free_handler_pri = N_MAIN+(int) data;
+                  freed = 1;
+              }
+          } cyg_mutex_unlock(&free_handler_lock);
+          if (!freed)
+              cyg_thread_delay(2);
+      } while (!freed);
+  }
+
+  // Then wait for the main_program to kill us.
+  for (;;) {
+      cyg_thread_delay(100);
+  }
 }
 
 /* look for an available handler thread */
 int get_handler_slot(cyg_handle_t current_threadH)
 {
-  int i;
-  int found = 0;
+    int i;
+    int found = 0;
 
-  while (!found) {
-    for (i = 0; i < MAX_HANDLERS; ++i) {
-      cyg_mutex_lock(&handler_slot_lock); {
-        if (!handler_thread_in_use[i]) {
-          found = 1;
-          handler_thread_in_use[i] = 1;
-        }
-      } cyg_mutex_unlock(&handler_slot_lock);
-      if (found) {
-        break;
-      }
-#ifdef DEATH_TIME_LIMIT
-      /* must do a check here to see if all clients have been killed,
-         since otherwise we might end up in an infinite loop */
-      if (n_clients_killed == N_CLIENTS) {
-	n_clients_killed = -1;    /* so we don't call this again */
-	CYG_TEST_PASS_FINISH("Kernel thread stress test OK");
-      }
-#endif
+    while (!found) {
+        cyg_mutex_lock(&handler_slot_lock); {
+            for (i = 0; i < MAX_HANDLERS; ++i) {
+                if (!handler_thread_in_use[i]) {
+                    found = 1;
+                    handler_thread_in_use[i]++;
+                    break;
+                }
+            }
+        } cyg_mutex_unlock(&handler_slot_lock);
+        if (!found)
+            cyg_thread_delay(1);
     }
-    cyg_thread_delay(1);
-  }
-  return i;
+
+    CYG_ASSERT(1 == handler_thread_in_use[i], "Handler usage count wrong!");
+
+    return i;
 }
 
 /* do things which will stress the system */
@@ -386,9 +473,12 @@ void perform_stressful_tasks()
     ++statistics.malloc_tries;
 /*      spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */
     spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE);
-    if (i % 100 == 0) {
+    if (i % (MAX_MALLOCED_SPACES/10) == 0) {
       cyg_thread_yield();
     }
+    if (i % (MAX_MALLOCED_SPACES/15) == 0) {
+      cyg_thread_delay(i % 5);
+    }
   }
 
   /* now free it all up */
@@ -426,7 +516,7 @@ void perform_stressful_tasks()
 
 /* report_alarm_func() is invoked as an alarm handler, so it should be
    quick and simple.  in this case it sets a global flag which is
-   checked by threads. */
+   checked by main_program. */
 void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
 {
     time_to_report = 1;
@@ -437,7 +527,6 @@ void report_alarm_func(cyg_handle_t alar
 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
                        cyg_alarm *death_alarm_p, int *killed_p)
 {
-#ifdef DEATH_TIME_LIMIT
   cyg_handle_t system_clockH, counterH;
   cyg_resolution_t rtc_res;
 
@@ -455,9 +544,14 @@ void setup_death_alarm(cyg_addrword_t da
        *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend));
     if ( cyg_test_is_simulator )
         tick_delay /= 10;
+#ifdef CYGPKG_HAL_I386_LINUX 
+    // 20 seconds is a long time compared to the run time of other tests.
+    // Reduce to 10 seconds, allowing more tests to get run.
+    tick_delay /= 2;
+#endif
+
     cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0);
   }
-#endif /* DEATH_TIME_LIMIT */
 }
 
 /* death_alarm_func() is the alarm handler that kills the current
@@ -470,23 +564,11 @@ void death_alarm_func(cyg_handle_t alarm
   *killed_p = 1;
 }
 
-#ifdef DEATH_TIME_LIMIT
-/* handle_death is called by a client thread when it dies; it kills
-   off the alarm */
-void handle_death(cyg_handle_t deathH, cyg_handle_t alarmH)
-{
-  ++n_clients_killed;
-  cyg_alarm_delete(deathH);
-  cyg_alarm_delete(alarmH);
-  cyg_thread_exit();
-}
-#endif /* DEATH_TIME_LIMIT */
-
 /* now I write the sc_ versions of the cyg_functions */
 void sc_thread_create(
-    cyg_addrword_t        sched_info,          /* scheduling info (eg pri)  */
+    cyg_addrword_t      sched_info,            /* scheduling info (eg pri)  */
     cyg_thread_entry_t  *entry,                /* entry point function      */
-    cyg_addrword_t        entry_data,          /* entry data                */
+    cyg_addrword_t      entry_data,            /* entry data                */
     char                *name,                 /* optional thread name      */
     void                *stack_base,           /* stack base, NULL = alloc  */
     cyg_ucount32        stack_size,            /* stack size, 0 = default   */
@@ -501,14 +583,6 @@ void sc_thread_create(
                     stack_base, stack_size, handle, thread);
 }
 
-void sc_thread_exit()
-{
-/*    printf("exiting\n"); */
-/*    fflush(stdout); */
-  ++statistics.thread_exits;
-  cyg_thread_exit();
-}
-
 void print_statistics(void)
 {
   int i;
@@ -525,6 +599,12 @@ void print_statistics(void)
   } cyg_mutex_unlock(&statistics_print_lock);
 }
 
+#else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >=    */
+      /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
+#define N_A_MSG "not enough priorities available"
+#endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >=    */
+       /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
+
 #else /* CYGSEM_LIBC_MALLOC */
 # define N_A_MSG "this test needs malloc"
 #endif /* CYGSEM_LIBC_MALLOC */
--- a/packages/kernel/current/tests/tm_basic.cxx
+++ b/packages/kernel/current/tests/tm_basic.cxx
@@ -69,7 +69,7 @@ typedef struct fun_times {
 } fun_times;
 
 #define NSAMPLES         32
-#define NTEST_THREADS    24
+#define NTEST_THREADS    16
 #define NTHREAD_SWITCHES 128
 #define NMUTEXES         32
 #define NMBOXES          32
@@ -1571,6 +1571,7 @@ void tm_basic_main( void )
     new_thread(run_all_tests, 0);
     
     Cyg_Scheduler::scheduler.start();
+
 }
 
 externC void
--- a/packages/language/c/libc/current/ChangeLog
+++ b/packages/language/c/libc/current/ChangeLog
@@ -1,9 +1,18 @@
+1999-04-30  Jesper Skov  <jskov@lassi.cygnus.co.uk>
+        PR 19945/19946 workaround
+	* tests/signal/signal2.c: Disabled test 3 for PowerPC sim.
+
 1999-04-19  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* include/time.inl:
 	Ensure all calls to cyg_libc_time_year_is_leap() are with the full
 	year, and not the direct contents of a struct tm, which are (year-1900)
 
+1999-04-19  Jesper Skov  <jskov@cygnus.co.uk>
+        PR 19308, 19410, 19528
+	* tests/time/clock.c (test): Also disable data cache which may
+	affect timing when tracing/assertions are enabled.
+
 1999-04-15  Jonathan Larmour  <jlarmour@cygnus.co.uk>
 
 	* src/clibincl/stdiosupp.hxx:
--- a/packages/language/c/libc/current/tests/signal/signal2.c
+++ b/packages/language/c/libc/current/tests/signal/signal2.c
@@ -210,6 +210,10 @@ main( int argc, char *argv[] )
     state = 2;
 
 #if 0
+#elif defined(CYGPKG_HAL_POWERPC_SIM)
+    // The exception generated by the SIM is not recognized by GDB.
+    // PR 19945 workaround.
+    CYG_TEST_PASS("Test 3 not applicable to PowerPC SIM");
 #else
     if (0==setjmp(jbuf)) {
         cause_memerror();
--- a/packages/language/c/libc/current/tests/time/clock.c
+++ b/packages/language/c/libc/current/tests/time/clock.c
@@ -66,6 +66,7 @@
 #if RUN_TEST
 
 #include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
 
 # define START_TEST( test ) test(0)
 
@@ -112,9 +113,21 @@ test( CYG_ADDRWORD data )
     clock_t clock_init;
     clock_t clock_first=0, clock_second=0, clock_third=0;
 
-    // First disable the instruction cache - it may affect the timing loops
-    // below
-    HAL_ICACHE_DISABLE();
+    // 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.
+    {
+        register CYG_INTERRUPT_STATE oldints;
+
+        HAL_DISABLE_INTERRUPTS(oldints);
+        HAL_DCACHE_SYNC();
+        HAL_ICACHE_DISABLE();
+        HAL_DCACHE_DISABLE();
+        HAL_DCACHE_SYNC();
+        HAL_ICACHE_INVALIDATE_ALL();
+        HAL_DCACHE_INVALIDATE_ALL();
+        HAL_RESTORE_INTERRUPTS(oldints);
+    }
 
     // This waits for a clock tick, to ensure that we are at the
     // start of a clock period. Then sit in a tight loop to get
--- a/packages/packages
+++ b/packages/packages
@@ -144,6 +144,7 @@ package CYGPKG_HAL_ARM_AEB {
 	hardware
 }
 
+
 package CYGPKG_HAL_I386 {
 	alias		{ "i386 common HAL" hal_i386 i386_hal i386_arch_hal }
 	directory	hal/i386/arch
--- a/packages/pkgconf.tcl
+++ b/packages/pkgconf.tcl
@@ -5560,6 +5560,11 @@ endif"
 	puts $file "\n"
 	puts $file "#define CYGHWR_MEMORY_LAYOUT_LDI <pkgconf/mlt_[set pkgconf::config_data(target)]_[set pkgconf::config_data(platform)]_[set pkgconf::config_data(startup)].ldi>"
 	puts $file "#define CYGHWR_MEMORY_LAYOUT_H   <pkgconf/mlt_[set pkgconf::config_data(target)]_[set pkgconf::config_data(platform)]_[set pkgconf::config_data(startup)].h>"
+
+	# Also output details of the HAL header files that should be included
+	puts $file "\n"
+	puts $file "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_[set pkgconf::config_data(target)].h>"
+	puts $file "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_[set pkgconf::config_data(target)]_[set pkgconf::config_data(platform)].h>"
 	
 	puts $file "\
 \n#endif  /* CYGONCE_PKGCONF_SYSTEM_H */ 		
@@ -5656,14 +5661,13 @@ proc pkgconf::produce_makefile { } {
     puts $makefile \
 "
 include pkgconf/pkgconf.mak
-.PHONY: default build clean tests headers
-.PRECIOUS: $(PREFIX)/lib/libextras.a"
+.PHONY: default build clean tests headers"
 
     puts $makefile "\nbuild: $(PREFIX)/lib/extras.o"
     puts $makefile "\t@echo Build finished."
 
     puts $makefile "\n$(PREFIX)/lib/extras.o: $(PREFIX)/lib/libextras.a"
-    puts $makefile "\t$(LD) --whole-archive $(PREFIX)/lib/libextras.a -r -o $(PREFIX)/lib/extras.o"
+    puts $makefile "\t$(CC) $(ARCHFLAGS) $(LDARCHFLAGS) -nostdlib -Wl,-r -Wl,--whole-archive $(PREFIX)/lib/libextras.a -o $(PREFIX)/lib/extras.o"
     
     puts $makefile "\n$(PREFIX)/lib/libextras.a: headers"
     foreach src_dir $pkgconf::src_dirs {
--- a/packages/pkgconf/makevars
+++ b/packages/pkgconf/makevars
@@ -260,20 +260,22 @@ INCLUDE_PATH :=
 	$(CC)  -c $(INCLUDE_PATH) $(CFLAGS) $($(notdir $<)-CFLAGS)  -Wp,-MD,$(@:.o=.tmp) -o $@ $< 
 	@echo > $(@:.o=.d)
 	@echo $@ ':' $< '\' >> $(@:.o=.d)
-	@$(TAIL) -n +2 $(@:.o=.tmp) >> $(@:.o=.d)
+	@$(TAIL) +2 $(@:.o=.tmp) >> $(@:.o=.d)
 	@$(RM) $(@:.o=.tmp)
 
 $(PACKAGE)_%.o : %.cxx
 	$(CXX) -c $(INCLUDE_PATH) $(CXXFLAGS) $($(notdir $<)-CXXFLAGS) -Wp,-MD,$(@:.o=.tmp) -o $@ $< 
 	@echo > $(@:.o=.d)
 	@echo $@ ':' $< '\' >> $(@:.o=.d)
-	@$(TAIL) -n +2 $(@:.o=.tmp) >> $(@:.o=.d)
+	@$(TAIL) +2 $(@:.o=.tmp) >> $(@:.o=.d)
 	@$(RM) $(@:.o=.tmp)
 
 $(PACKAGE)_%.o : %.S
 	$(CXX)  -c $(INCLUDE_PATH) $(CFLAGS) -Wp,-MD,$(@:.o=.tmp) -o $@ $< 
 	@echo > $(@:.o=.d)
 	@echo $@ ':' $< '\' >> $(@:.o=.d)
-	@$(TAIL) -n +2 $(@:.o=.tmp) >> $(@:.o=.d)
+	@$(TAIL) +2 $(@:.o=.tmp) >> $(@:.o=.d)
 	@$(RM) $(@:.o=.tmp)
 
+$(PREFIX)/lib/libextras.a(%) : %
+	$(AR) rcs $(PREFIX)/lib/libextras.a $<
--- a/packages/pkgconf/makrules.src
+++ b/packages/pkgconf/makrules.src
@@ -40,17 +40,21 @@ VPATH        := . $(COMPONENT_REPOSITORY
 # from the list of source files. OTHER_OBJS and OTHER_DEPS are
 # provided as an escape mechanism, as is OTHER_TARGETS.
 
-COMPILE      += $(DRIVERS)
-DRIVER_DEPS  := $(DRIVERS:.c=.D)
-OTHER_TARGETS += $(DRIVER_DEPS)
 OBJECTS      := $(COMPILE:.cxx=.o)
 OBJECTS      := $(OBJECTS:.c=.o)
 OBJECTS      := $(OBJECTS:.S=.o)
 OBJECTS	     := $(foreach obj,$(OBJECTS),$(dir $(obj))$(PACKAGE)_$(notdir $(obj)))
 DEPS         := $(OBJECTS:.o=.d)
 
-OBJECTS      := $(OBJECTS) $(OTHER_OBJS)
-DEPS	     := $(DEPS) $(OTHER_DEPS)
+EXTRAS_OBJECTS := $(EXTRAS_COMPILE:.cxx=.o)
+EXTRAS_OBJECTS := $(EXTRAS_OBJECTS:.c=.o)
+EXTRAS_OBJECTS := $(EXTRAS_OBJECTS:.S=.o)
+EXTRAS_OBJECTS := $(foreach obj,$(EXTRAS_OBJECTS),$(dir $(obj))$(PACKAGE)_$(notdir $(obj)))
+DEPS           := $(DEPS) $(EXTRAS_OBJECTS:.o=.d)
+
+OBJECTS        := $(OBJECTS) $(OTHER_OBJS)
+EXTRAS_OBJECTS := $(EXTRAS_OBJECTS) $(EXTRAS_OTHER_OBJECTS)
+DEPS	       := $(DEPS) $(OTHER_DEPS)
 
 # The header file search path is as follows:
 #
@@ -73,21 +77,31 @@ INCLUDE_PATH := $(INCLUDE_PATH) -I$(PREF
 # This is the default target. It is responsible for updating the library,
 # building any special targets, and updating the dependency information.
 
-build: $(LIBRARY).stamp $(OTHER_TARGETS)
+build: $(LIBRARY).stamp extras $(OTHER_TARGETS)
 ifneq ($(strip $(DEPS)),)
 	@$(CAT) $(DEPS) > makefile.deps
 endif
 
 
 # Updating the library involves using ar with any object files that
-# have been rebuilt.
+# have been rebuilt. A few packages may not involve any object files
+# at all.
 
 $(LIBRARY).stamp: $(OBJECTS)
 ifneq ($(strip $(OBJECTS)),)
-	$(AR) crs $(PREFIX)/lib/$(LIBRARY) $?
+	$(AR) rcs $(PREFIX)/lib/$(LIBRARY) $?
 endif
 	$(TOUCH) $@
 
+# Updating libextras.a may or may not be a no-op, many packages
+# will not want to put anything there.
+.PHONY: extras
+ifeq ($(strip $(EXTRAS_OBJECTS)),)
+extras:
+else
+extras: $(PREFIX)/lib/libextras.a($(EXTRAS_OBJECTS))
+endif
+
 # The clean target cleans up the intermediate files, any object
 # files, and any dependency files.
 
@@ -97,6 +111,9 @@ clean: $(OTHER_CLEAN)
 ifneq ($(strip $(OBJECTS)),)
 	$(RM) $(OBJECTS)
 endif
+ifneq ($(strip $(EXTRAS_OBJECTS)),)
+	$(RM) $(EXTRAS_OBJECTS)
+endif
 ifneq ($(strip $(DEPS)),)
 	@$(RM) $(DEPS)
 endif
@@ -110,6 +127,10 @@ ifneq ($(strip $(OBJECTS)),)
 $(OBJECTS) : $(BUILD_TREE)/pkgconf/pkgconf.mak
 $(OBJECTS) : $(BUILD_TREE)/pkgconf/makevars $(PACKAGE_RULES_FILE)
 endif
+ifneq ($(strip $(EXTRAS_OBJECTS)),)
+$(EXTRAS_OBJECTS) : $(BUILD_TREE)/pkgconf/pkgconf.mak
+$(EXTRAS_OBJECTS) : $(BUILD_TREE)/pkgconf/makevars $(PACKAGE_RULES_FILE)
+endif
 ifneq ($(strip $(OTHER_TARGETS)),)
 $(OTHER_TARGETS) : $(BUILD_TREE)/pkgconf/pkgconf.mak
 $(OTHER_TARGETS) : $(BUILD_TREE)/pkgconf/makevars $(PACKAGE_RULES_FILE)
--- a/packages/pkgconf/makrules.tst
+++ b/packages/pkgconf/makrules.tst
@@ -79,13 +79,12 @@ endif
 ifneq ($(STAMPS),)
 
 LIBDEPS := $(wildcard $(PREFIX)/lib/*)
-DRIVER_DEPS := $(wildcard $(PREFIX)/lib/*driver.o)
 
 %.stamp: $(PACKAGE)_%.o $(LIBDEPS)
 ifneq ($(IGNORE_LINK_ERRORS),)
-	-$(CC) -o $(PREFIX)/tests/$(PACKAGE)/$*$(EXEEXT) $< $(DRIVER_DEPS) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -nostdlib
+	-$(CC) -o $(PREFIX)/tests/$(PACKAGE)/$*$(EXEEXT) $< $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -nostdlib
 else
-	$(CC) -o $(PREFIX)/tests/$(PACKAGE)/$*$(EXEEXT) $< $(DRIVER_DEPS) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -nostdlib
+	$(CC) -o $(PREFIX)/tests/$(PACKAGE)/$*$(EXEEXT) $< $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -nostdlib
 endif
 	@$(TOUCH) $@