changeset 149:52c99470ec11

Merge from eCos master repository on 2001-01-19-06:43:03-GMT
author jlarmour
date Fri, 19 Jan 2001 07:37:45 +0000
parents 8f2f7615e727
children f0e3fb000de8
files packages/hal/common/current/ChangeLog packages/hal/common/current/src/drv_api.c packages/hal/mn10300/arch/current/ChangeLog packages/hal/mn10300/arch/current/src/vectors.S packages/hal/powerpc/arch/current/ChangeLog packages/hal/powerpc/arch/current/src/ppc_stub.c packages/hal/powerpc/arch/current/src/vectors.S packages/hal/powerpc/ppc40x/current/ChangeLog packages/hal/powerpc/ppc40x/current/cdl/hal_powerpc_ppc40x.cdl packages/hal/powerpc/ppc40x/current/include/var_intr.h packages/hal/powerpc/ppc40x/current/include/var_regs.h packages/hal/powerpc/ppc40x/current/include/variant.inc packages/hal/powerpc/ppc40x/current/src/var_intr.c packages/hal/powerpc/ppc40x/current/src/var_misc.c packages/hal/powerpc/quicc/current/ChangeLog packages/hal/powerpc/quicc/current/src/quicc_smc1.c packages/hal/sh/arch/current/ChangeLog packages/hal/sh/arch/current/cdl/hal_sh.cdl packages/hal/sh/arch/current/src/vectors.S packages/hal/sh/arch/current/tests/intr0.c packages/hal/sh/sh3/current/ChangeLog packages/hal/sh/sh3/current/src/var_misc.c packages/hal/sh/sh3/current/src/variant.S packages/hal/sh/sh4/current/ChangeLog packages/hal/sh/sh4/current/src/var_misc.c packages/hal/sh/sh4/current/src/variant.S packages/hal/v85x/arch/current/ChangeLog packages/hal/v85x/arch/current/src/vectors.S packages/io/eth/current/ChangeLog packages/io/eth/current/src/net/eth_drv.c packages/io/serial/current/tests/ser_test_protocol.inl packages/net/snmp/agent/current/ChangeLog packages/net/snmp/agent/current/src/mibgroup/util_funcs.c packages/redboot/current/ChangeLog packages/redboot/current/include/net/net.h packages/redboot/current/include/redboot.h packages/redboot/current/src/io.c packages/redboot/current/src/net/pktbuf.c packages/redboot/current/src/net/tcp.c packages/redboot/current/src/xyzModem.c
diffstat 40 files changed, 732 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-01-15  Nick Garnett  <nickg@cygnus.co.uk>
+
+	* src/drv_api.c: Initialized isr_disable_counter to 1 so that it
+	indicates that interrupts are initially disabled.
+
 2000-12-15  Gary Thomas  <gthomas@redhat.com>
 
 	* src/generic-stub.c: Define 'version' string to be a weak
--- a/packages/hal/common/current/src/drv_api.c
+++ b/packages/hal/common/current/src/drv_api.c
@@ -60,7 +60,7 @@
 //--------------------------------------------------------------------------
 // Statics
 
-static volatile cyg_int32 isr_disable_counter;  // ISR disable counter
+static volatile cyg_int32 isr_disable_counter = 1;  // ISR disable counter
 
 volatile cyg_int32 dsr_disable_counter asm("cyg_scheduler_sched_lock");  // DSR disable counter
 
--- a/packages/hal/mn10300/arch/current/ChangeLog
+++ b/packages/hal/mn10300/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-01-18  Nick Garnett  <nickg@cygnus.co.uk>
+
+	* src/vectors.S: Added underscore to reference to
+	cyg_scheduler_sched_lock, since CYGBLD_ATTRIB_ASM_ALIAS() now adds
+	one automatically.
+
 2000-11-30  Drew Moseley  <dmoseley@redhat.com>
 
 	* include/hal_arch.h: Handle Cygmon interrupt stack.  ie For
--- a/packages/hal/mn10300/arch/current/src/vectors.S
+++ b/packages/hal/mn10300/arch/current/src/vectors.S
@@ -315,14 +315,14 @@ 9:
 
 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
 	
-	.extern	cyg_scheduler_sched_lock
+	.extern	_cyg_scheduler_sched_lock
 	
 	# Increment the scheduler lock
 			
 	.macro increment_sched_lock reg=d0
-	mov	(cyg_scheduler_sched_lock),\reg
+	mov	(_cyg_scheduler_sched_lock),\reg
 	inc	\reg
-	mov	\reg,(cyg_scheduler_sched_lock)
+	mov	\reg,(_cyg_scheduler_sched_lock)
 	.endm
 
 #else
--- a/packages/hal/powerpc/arch/current/ChangeLog
+++ b/packages/hal/powerpc/arch/current/ChangeLog
@@ -1,3 +1,15 @@
+2001-01-16  Gary Thomas  <gthomas@redhat.com>
+
+	* src/vectors.S (_start): Set up IRQ environment _before_ calling
+	constructors - since they may need it to work.
+
+2001-01-15  Gary Thomas  <gthomas@redhat.com>
+
+	* src/ppc_stub.c: Define new method for achieving single stepping
+	when processor (like 40x) does not support it in hardware.  This
+	method will be invoked if the variant or plaform define the 
+	symbol CYGNUM_HAL_NO_VECTOR_TRACE.
+
 2001-01-03  Gary Thomas  <gthomas@redhat.com>
 
 	* src/hal_intr.c (hal_delay_us): Fix some problems - didn't
--- a/packages/hal/powerpc/arch/current/src/ppc_stub.c
+++ b/packages/hal/powerpc/arch/current/src/ppc_stub.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):     Red Hat, jskov
-// Contributors:  Red Hat, jskov
+// Contributors:  Red Hat, jskov, gthomas
 // Date:          1998-08-20
 // Purpose:       
 // Description:   Helper functions for stub, generic to all PowerPC processors
@@ -55,6 +55,10 @@
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/hal_intr.h>
 
+#ifdef CYGNUM_HAL_NO_VECTOR_TRACE
+#define USE_BREAKPOINTS_FOR_SINGLE_STEP
+#endif
+
 #ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
 #include <cyg/hal/dbg-threads-api.h>    // dbg_currthread_id
 #endif
@@ -89,6 +93,11 @@ int __computeSignal (unsigned int trap_n
         // The register PS contains the value of SRR1 at the time of
         // exception entry. Bits 11-15 contain information about the
         // cause of the exception. Bits 16-31 the PS (MSR) state.
+#ifdef USE_BREAKPOINTS_FOR_SINGLE_STEP
+        if (__is_single_step(get_register(PC))) {
+            return SIGTRAP;
+        }
+#endif
         switch ((get_register (PS) >> 17) & 0xf){
         case 1:                         /* trap */
             return SIGTRAP;
@@ -98,7 +107,7 @@ int __computeSignal (unsigned int trap_n
         case 8:                         /* floating point */
             return SIGFPE;
         default:                        /* should never happen! */
-            return SIGTERM;
+            return SIGILL;
         }            
 
     case CYGNUM_HAL_VECTOR_RESERVED_A:
@@ -178,6 +187,178 @@ void set_pc (target_register_t pc)
    This may be done by setting breakpoints or setting a single step flag
    in the saved user registers, for example. */
 
+#ifdef USE_BREAKPOINTS_FOR_SINGLE_STEP
+
+#if (HAL_BREAKINST_SIZE == 1)
+typedef cyg_uint8 t_inst;
+#elif (HAL_BREAKINST_SIZE == 2)
+typedef cyg_uint16 t_inst;
+#elif (HAL_BREAKINST_SIZE == 4)
+typedef cyg_uint32 t_inst;
+#else
+#error "Don't know how to handle that size"
+#endif
+
+typedef struct
+{
+  t_inst *targetAddr;
+  t_inst savedInstr;
+} instrBuffer;
+
+static instrBuffer sstep_instr[2];
+static target_register_t irq_state = 0;
+
+static void 
+__insert_break(int indx, target_register_t pc)
+{
+    sstep_instr[indx].targetAddr = (t_inst *)pc;
+    sstep_instr[indx].savedInstr = *(t_inst *)pc;
+    *(t_inst*)pc = (t_inst)HAL_BREAKINST;
+    __data_cache(CACHE_FLUSH);
+    __instruction_cache(CACHE_FLUSH);
+}
+
+static void 
+__remove_break(int indx)
+{
+    if (sstep_instr[indx].targetAddr != 0) {
+        *(sstep_instr[indx].targetAddr) = sstep_instr[indx].savedInstr;
+        sstep_instr[indx].targetAddr = 0;
+        __data_cache(CACHE_FLUSH);
+        __instruction_cache(CACHE_FLUSH);
+    }
+}
+
+int
+__is_single_step(target_register_t pc)
+{
+    return (sstep_instr[0].targetAddr == pc) ||
+        (sstep_instr[1].targetAddr == pc);
+}
+
+
+// Compute the target address for this instruction, if the instruction
+// is some sort of branch/flow change.
+
+struct xl_form {
+    unsigned int op : 6;
+    unsigned int bo : 5;
+    unsigned int bi : 5;
+    unsigned int reserved : 5;
+    unsigned int xo : 10;
+    unsigned int lk : 1;
+};
+
+struct i_form {
+    unsigned int op : 6;
+    signed   int li : 24;
+    unsigned int aa : 1;
+    unsigned int lk : 1;
+};
+
+struct b_form {
+    unsigned int op : 6;
+    unsigned int bo : 5;
+    unsigned int bi : 5;
+    signed   int bd : 14;
+    unsigned int aa : 1;
+    unsigned int lk : 1;
+};
+
+union ppc_insn {
+    unsigned int   word;
+    struct i_form  i;
+    struct b_form  b;
+    struct xl_form xl;
+};
+
+static target_register_t
+__branch_pc(target_register_t pc)
+{
+    union ppc_insn insn;
+
+    insn.word = *(t_inst *)pc;
+
+    // Decode the instruction to determine the instruction which will follow
+    // Note: there are holes in this process, but the important ones work
+    switch (insn.i.op) {
+    case 16:
+	/* bcx */
+	if (insn.b.aa) {
+	    return (target_register_t)(insn.b.bd << 2);
+        } else {
+	    return (target_register_t)((insn.b.bd << 2) + (long)pc);
+        }
+    case 18:
+	/* bx */
+	if (insn.i.aa) {
+	    return (target_register_t)(insn.i.li << 2);
+        } else {
+	    return (target_register_t)((insn.i.li << 2) + (long)pc);
+        }
+    case 19:
+	if (insn.xl.reserved == 0) {
+	    if (insn.xl.xo == 528) {
+		/* bcctrx */
+                return (target_register_t)(get_register(CNT) & ~3);
+	    } else if (insn.xl.xo == 16) {
+		/* bclrx */
+                return (target_register_t)(get_register(LR) & ~3);
+	    }
+	}
+	break;
+    default:
+	break;
+    }
+    return (pc+4);
+}
+
+void __single_step(void)
+{
+    target_register_t msr = get_register(PS);
+    target_register_t pc = get_register(PC);
+    target_register_t next_pc = __branch_pc(pc);
+
+    // Disable interrupts.
+    irq_state = msr & MSR_EE;
+    msr &= ~MSR_EE;
+    put_register (PS, msr);
+
+    // Set a breakpoint at the next instruction
+    __insert_break(0, pc+4);
+    if (next_pc != (pc+4)) {
+        __insert_break(1, next_pc);
+    }
+}
+
+/* Clear the single-step state. */
+
+void __clear_single_step(void)
+{
+    target_register_t msr = get_register (PS);
+
+    // Restore interrupt state.
+    // FIXME: Should check whether the executed instruction changed the
+    // interrupt state - or single-stepping a MSR changing instruction
+    // may result in a wrong EE. Not a very likely scenario though.
+    msr |= irq_state;
+
+    // This function is called much more than its counterpart
+    // __single_step.  Only re-enable interrupts if they where
+    // disabled during the previous cal to __single_step. Otherwise,
+    // this function only makes "extra sure" that no trace or branch
+    // exception will happen.
+    irq_state = 0;
+
+    put_register (PS, msr);
+
+    // Remove breakpoints
+    __remove_break(0);
+    __remove_break(1);
+}
+
+#else
+
 static target_register_t irq_state = 0;
 
 void __single_step (void)
@@ -216,7 +397,7 @@ void __clear_single_step (void)
 
     put_register (PS, msr);
 }
-
+#endif
 
 void __install_breakpoints (void)
 {
--- a/packages/hal/powerpc/arch/current/src/vectors.S
+++ b/packages/hal/powerpc/arch/current/src/vectors.S
@@ -23,7 +23,7 @@
 #                                                                          
 # The Initial Developer of the Original Code is Red Hat.                   
 # Portions created by Red Hat are                                          
-# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 # All Rights Reserved.                                                     
 # -------------------------------------------                              
 #                                                                          
@@ -378,12 +378,12 @@ 2:
         bl      hal_enable_caches
 #endif // CYGHWR_HAL_POWERPC_ENABLE_MMU
 
+        # set up platform specific interrupt environment
+        bl      hal_IRQ_init
+
         # call c++ constructors
         bl      cyg_hal_invoke_constructors
 
-        # set up platform specific interrupt environment
-        bl      hal_IRQ_init
-
 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
         bl      initialize_stub
 #endif
--- a/packages/hal/powerpc/ppc40x/current/ChangeLog
+++ b/packages/hal/powerpc/ppc40x/current/ChangeLog
@@ -1,3 +1,25 @@
+2001-01-18  Gary Thomas  <gthomas@redhat.com>
+
+	* cdl/hal_powerpc_ppc40x.cdl: Move CYGSEM_HAL_USE_ROM_MONITOR to
+	platform CDL.
+
+2001-01-17  Gary Thomas  <gthomas@redhat.com>
+
+	* include/variant.inc: Fix EXISR interrupt decode.
+
+2001-01-16  Gary Thomas  <gthomas@redhat.com>
+
+	* src/var_intr.c (hal_variant_IRQ_init): Add platform IRQ support.
+	(hal_ppc40x_interrupt_configure): Properly configure level interrupts.
+
+2001-01-15  Gary Thomas  <gthomas@redhat.com>
+
+	* include/var_regs.h (SPR_DBSR, SPR_DBCR): Special registers used
+	for debug support.  Too bad the hardware is broken.
+
+	* include/var_intr.h (CYGNUM_HAL_NO_VECTOR_TRACE): Disable common
+	single step code [hardware does not work].
+
 2000-11-21  Gary Thomas  <gthomas@redhat.com>
 
 	* include/variant.inc: Include platform specifics <cyg/hal/plf.inc>
--- a/packages/hal/powerpc/ppc40x/current/cdl/hal_powerpc_ppc40x.cdl
+++ b/packages/hal/powerpc/ppc40x/current/cdl/hal_powerpc_ppc40x.cdl
@@ -84,23 +84,5 @@ cdl_package CYGPKG_HAL_POWERPC_PPC40x {
         no_define
     }
 
-    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
-        display       "Work with a ROM monitor"
-        flavor        bool
-        default_value { (CYG_HAL_STARTUP == "RAM" &&
-                        !CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS &&
-                        !CYGINT_HAL_USE_ROM_MONITOR_UNSUPPORTED &&
-                        !CYGSEM_HAL_POWERPC_COPY_VECTORS) ? 1 : 0 }
-        parent        CYGPKG_HAL_ROM_MONITOR
-        requires      { CYG_HAL_STARTUP == "RAM" }
-        requires      ! CYGSEM_HAL_POWERPC_COPY_VECTORS
-        requires      ! CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-        requires      ! CYGINT_HAL_USE_ROM_MONITOR_UNSUPPORTED
-        description   "
-            Allow coexistence with ROM monitor (CygMon or GDB stubs) by
-            only initializing interrupt vectors on startup, thus leaving
-            exception handling to the ROM monitor."
-    }
-
     compile       var_intr.c var_misc.c variant.S
 }
--- a/packages/hal/powerpc/ppc40x/current/include/var_intr.h
+++ b/packages/hal/powerpc/ppc40x/current/include/var_intr.h
@@ -25,7 +25,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -55,6 +55,9 @@
 #define CYGNUM_HAL_VECTOR_INSTR_TLB_MISS    18
 #define CYGNUM_HAL_VECTOR_DEBUG             32
 
+// No 'trace'/'single step' trap on this processor
+#define CYGNUM_HAL_NO_VECTOR_TRACE
+
 #define CYGNUM_HAL_VSR_MAX                  CYGNUM_HAL_VECTOR_DEBUG
 
 // Special handling for interrupts
--- a/packages/hal/powerpc/ppc40x/current/include/var_regs.h
+++ b/packages/hal/powerpc/ppc40x/current/include/var_regs.h
@@ -26,7 +26,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -136,6 +136,13 @@
 #define TSR_PIS         0x08000000  // Programmable timer interrupt
 #define TSR_FIS         0x04000000  // Fixed timer interrupt
 
+// Debug registers
+#define SPR_DBSR        1008
+#define SPR_DBCR        1010
+
+#define DBCR_IDM        0x40000000  // Internal debug enable
+#define DBCR_IC         0x08000000  // Instruction completion
+
 #endif //  CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
 
 //-----------------------------------------------------------------------------
--- a/packages/hal/powerpc/ppc40x/current/include/variant.inc
+++ b/packages/hal/powerpc/ppc40x/current/include/variant.inc
@@ -25,7 +25,7 @@
 #                                                                          
 # The Initial Developer of the Original Code is Red Hat.                   
 # Portions created by Red Hat are                                          
-# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 # All Rights Reserved.                                                     
 # -------------------------------------------                              
 #                                                                          
@@ -246,7 +246,7 @@ 0:	mfdcr	r3,DCR_EXISR			# Interrupt stat
 	cntlzw	r3,\dreg			# find highest "1" bit
 	slwi	r3,r3,2
 	lwi	\dreg,EXISR_TAB			# convert bit # to signal #
-	lwz	\dreg,0(\dreg)
+	lwzx	\dreg,\dreg,r3
 1:      stw     \dreg,CYGARC_PPCREG_VECTOR(\state) # update vector in state frame.
         slwi    \dreg,\dreg,2                   # convert to byte offset.
         .endm                              
--- a/packages/hal/powerpc/ppc40x/current/src/var_intr.c
+++ b/packages/hal/powerpc/ppc40x/current/src/var_intr.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    jskov
-// Contributors: jskov
+// Contributors: jskov, gthomas
 // Date:         2000-02-11
 // Purpose:      PowerPC variant interrupt handlers
 // Description:  This file contains code to handle interrupt related issues
@@ -121,6 +121,9 @@ hal_variant_IRQ_init(void)
 
     // Disable timers
     CYGARC_MTSPR(SPR_TCR, 0);
+
+    // Let the platform do any overrides
+    hal_platform_IRQ_init();
 }
 
 externC void 
@@ -264,10 +267,10 @@ hal_ppc40x_interrupt_configure(int vecto
     if ((vector >= CYGNUM_HAL_INTERRUPT_EXT0) &&
         (vector <= CYGNUM_HAL_INTERRUPT_EXT4)) {
         mask = 0x03 << (30 - ((vector - CYGNUM_HAL_INTERRUPT_EXT0)*2));
-        new_state = 0x00;        
+        new_state = (dir & 0x01);  // Up/Down    
         if (level == 0) {
             // Edge triggered
-            new_state = 0x02 | (dir & 0x01);  // Up/Down
+            new_state = 0x02;
         }
         new_state <<= (30 - ((vector - CYGNUM_HAL_INTERRUPT_EXT0)*2));
         CYGARC_MFDCR(DCR_IOCR, iocr);
--- a/packages/hal/powerpc/ppc40x/current/src/var_misc.c
+++ b/packages/hal/powerpc/ppc40x/current/src/var_misc.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    jskov
-// Contributors: jskov
+// Contributors: jskov, gthomas
 // Date:         2000-02-04
 // Purpose:      HAL miscellaneous functions
 // Description:  This file contains miscellaneous functions provided by the
--- a/packages/hal/powerpc/quicc/current/ChangeLog
+++ b/packages/hal/powerpc/quicc/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-01-15  Gary Thomas  <gthomas@redhat.com>
+
+	* src/quicc_smc1.c: Provide for multiple serial input buffers
+	since the single buffer/descriptor model fails miserably on some
+	newer chips [at least 855T].
+
 2001-01-03  Gary Thomas  <gthomas@redhat.com>
 
 	* include/ppc8xx.h: Layout of I2C and IDMA was [slightly] wrong.
--- a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c
+++ b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    Red Hat
-// Contributors: hmt
+// Contributors: hmt, gthomas
 // Date:         1999-06-08
 // Purpose:      Provide basic Serial IO for MBX board
 // Description:  Serial IO for MBX boards which connect their debug channel
@@ -69,11 +69,11 @@
 #define UART_BIT_RATE(n) (((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/16)/n)
 #define UART_BAUD_RATE CYGNUM_HAL_QUICC_DIAG_BAUD
 
-#define Rxbd     0x2800       /* Rx Buffer Descriptor Offset */
-#define Txbd     0x2808       /* Tx Buffer Descriptor Offset */
-
-#define Rxbuf    ((volatile char *)eppc + 0x2810)
-#define Txbuf    ((volatile char *)eppc + 0x2820)
+#define Txbd     0x2800       /* Tx Buffer Descriptor Offset */
+#define Txbuf    ((volatile char *)eppc + 0x2808)
+#define Rxbd     0x2810       /* Rx Buffer Descriptor Offset */
+#define NUM_Rxbd 4
+#define Rxbuf    ((volatile char *)eppc + Rxbd + (NUM_Rxbd*sizeof(struct cp_bufdesc)))
 
 // SMC Events (interrupts)
 #define QUICC_SMCE_BRK 0x10  // Break received
@@ -81,6 +81,7 @@
 #define QUICC_SMCE_TX  0x02  // Tx interrupt
 #define QUICC_SMCE_RX  0x01  // Rx interrupt
 
+static struct cp_bufdesc *next_rxbd;
 
 /*
  *  Initialize SMC1 as a uart.
@@ -112,10 +113,6 @@ cyg_hal_plf_serial_init_channel(void)
     /* SMC1 Uart parameter ram */
     uart_pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u;
 
-    /* tx and rx buffer descriptors */
-    txbd = (struct cp_bufdesc *)((char *)eppc + Txbd);
-    rxbd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
-
     /*
      *  Set up the PortB pins for UART operation.
      *  Set PAR and DIR to allow SMCTXD1 and SMRXD1
@@ -124,11 +121,9 @@ cyg_hal_plf_serial_init_channel(void)
     eppc->pip_pbpar |= 0xc0;
     eppc->pip_pbdir &= ~0xc0;
 
-
     /* Configure baud rate generator (Section 16.13.2) */
     eppc->brgc1 = 0x10000 | (UART_BIT_RATE(UART_BAUD_RATE)<<1);
 
-
     /*
      *  NMSI mode, BRG1 to SMC1
      *  (Section 16.12.5.2)
@@ -143,11 +138,6 @@ cyg_hal_plf_serial_init_channel(void)
     uart_pram->tbase = Txbd;
 
     /*
-     *  Init Rx & Tx params for SMC1
-     */
-    eppc->cp_cr = 0x91;
-
-    /*
      *  SDMA & LCD bus request level 5
      *  (Section 16.10.2.1)
      */
@@ -175,12 +165,24 @@ cyg_hal_plf_serial_init_channel(void)
     /* 1 break char sent on top XMIT */
     uart_pram->brkcr = 1;
 
-    /* setup RX buffer descriptor */
-    rxbd->length = 0;
-    rxbd->buffer = Rxbuf;
-    rxbd->ctrl   = 0xb000;
+    /* setup RX buffer descriptors */
+    rxbd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
+    next_rxbd = rxbd;
+    for (i = 0;  i < NUM_Rxbd;  i++) {
+        rxbd->length = 0;
+        rxbd->buffer = Rxbuf+i;
+        rxbd->ctrl   = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
+        if (i == (NUM_Rxbd-1)) {
+            rxbd->ctrl   |= QUICC_BD_CTL_Wrap;
+        }
+        rxbd++;
+    }
+    // Compiler bug: for whatever reason, the Wrap code above fails!
+    rxbd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
+    rxbd[NUM_Rxbd-1].ctrl   |= QUICC_BD_CTL_Wrap;
 
     /* setup TX buffer descriptor */
+    txbd = (struct cp_bufdesc *)((char *)eppc + Txbd);
     txbd->length = 1;
     txbd->buffer = Txbuf;
     txbd->ctrl   = 0x2000;
@@ -199,6 +201,11 @@ cyg_hal_plf_serial_init_channel(void)
     eppc->smc_regs[0].smc_smcmr = 0x4820;
     eppc->smc_regs[0].smc_smcmr = 0x4823;
 
+    /*
+     *  Init Rx & Tx params for SMC1
+     */
+    eppc->cp_cr = 0x91;
+
 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // remove below
 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
     HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_CPM_SMC1 );
@@ -300,7 +307,7 @@ cyg_hal_plf_serial_getc_nonblock(void* _
     int cache_state;
 
     /* rx buffer descriptor */
-    bd = (struct cp_bufdesc *)((char *)eppc + uart_pram->rbptr);
+    bd = next_rxbd;
 
     if (bd->ctrl & QUICC_BD_CTL_Ready)
         return false;
@@ -310,6 +317,13 @@ cyg_hal_plf_serial_getc_nonblock(void* _
     bd->length = 0;
     bd->buffer[0] = '\0';
     bd->ctrl |= QUICC_BD_CTL_Ready;
+    if (bd->ctrl & QUICC_BD_CTL_Wrap) {
+        bd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
+    } else {
+        bd++;
+    }
+    next_rxbd = bd;
+
     // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
     HAL_DCACHE_IS_ENABLED(cache_state);
     if (cache_state) {
@@ -434,14 +448,20 @@ cyg_hal_plf_serial_isr(void *__ch_data, 
         eppc->smc_regs[0].smc_smce = QUICC_SMCE_RX;
 
         /* rx buffer descriptors */
-        bd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
+        bd = next_rxbd;
 
         if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) {
             
             // then there be a character waiting
             ch = bd->buffer[0];
             bd->length = 1;
-            bd->ctrl   = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int;
+            bd->ctrl   |= QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
+            if (bd->ctrl & QUICC_BD_CTL_Wrap) {
+                bd = (struct cp_bufdesc *)((char *)eppc + Rxbd);
+            } else {
+                bd++;
+            }
+            next_rxbd = bd;
         
             if( cyg_hal_is_break( &ch , 1 ) )
                 *__ctrlc = 1;
@@ -466,7 +486,6 @@ cyg_hal_plf_serial_init(void)
 {
     hal_virtual_comm_table_t* comm;
     int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-    volatile EPPC *eppc = eppc_base();
 
     static int init = 0;  // It's wrong to do this more than once
     if (init) return;
--- a/packages/hal/sh/arch/current/ChangeLog
+++ b/packages/hal/sh/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-01-18  Jesper Skov  <jskov@redhat.com>
+
+	Case 105302
+	* src/vectors.S: Moved ILVL table to variant code.
+	* tests/intr0.c: Added.
+
 2001-01-04  Jesper Skov  <jskov@redhat.com>
 
 	* src/sh.ld: Make sure .data and .bss section sizes are aligned.
--- a/packages/hal/sh/arch/current/cdl/hal_sh.cdl
+++ b/packages/hal/sh/arch/current/cdl/hal_sh.cdl
@@ -165,4 +165,13 @@ cdl_package CYGPKG_HAL_SH {
 	no_define
         calculated  { "src/sh.ld" }
     }
+
+    cdl_option CYGPKG_HAL_SH_TESTS {
+        display "SH tests"
+        flavor  data
+        no_define
+        calculated { "tests/intr0" }
+        description   "
+            This option specifies the set of tests for the SH HAL."
+    }
 }
--- a/packages/hal/sh/arch/current/src/vectors.S
+++ b/packages/hal/sh/arch/current/src/vectors.S
@@ -832,36 +832,6 @@ SYM_DEF(hal_interrupt_objects)
         .long   0
         .endr
 
-#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
-SYM_DEF(cyg_hal_ILVL_table)
-        # The first entries in the table have static priorities.
-
-        .byte   0xf                     // NMI
-        .byte   0xf                     // Reserved
-        .byte   0xf                     // LVL0
-        .byte   0xe                     // LVL1
-        .byte   0xd                     // LVL2
-        .byte   0xc                     // LVL3
-        .byte   0xb                     // LVL4
-        .byte   0xa                     // LVL5
-        .byte   0x9                     // LVL6
-        .byte   0x8                     // LVL7
-        .byte   0x7                     // LVL8
-        .byte   0x6                     // LVL9
-        .byte   0x5                     // LVL10
-        .byte   0x4                     // LVL11
-        .byte   0x3                     // LVL12
-        .byte   0x2                     // LVL13
-        .byte   0x1                     // LVL14
-        .byte   0xf                     // Reserved
-
-        # The rest of the table consists of programmable levels, maintained
-        # by the HAL_INTERRUPT_SET_LEVEL macro.
-        .rept   (CYGNUM_HAL_ISR_MAX-CYGNUM_HAL_INTERRUPT_RESERVED_3E0)
-        .byte   0xf
-        .endr
-#endif // CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
-
 #---------------------------------------------------------------------------
 ## Temporary interrupt stack
         
new file mode 100644
--- /dev/null
+++ b/packages/hal/sh/arch/current/tests/intr0.c
@@ -0,0 +1,141 @@
+//==========================================================================
+//
+//        intr0.c
+//
+//        Interrupt controls test
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000, 20001 Red Hat, Inc.
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jskov
+// Contributors:  jskov
+// Date:          2001-01-18
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#if defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_intr.h>
+
+// -------------------------------------------------------------------------
+
+#define NTHREADS 1
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+// -------------------------------------------------------------------------
+
+// This is (tick time * 1.5) 
+#define TICK_DELAY (1500000 / CYGNUM_HAL_RTC_DENOMINATOR)
+
+static void
+entry0( cyg_addrword_t data )
+{
+    int tick;
+
+    // Scheduler and thus timer interrupts are running by the
+    // time we get here.
+
+    // Wait for next tick
+    tick = cyg_current_time();
+    do {} while (cyg_current_time() == tick);
+    tick = cyg_current_time();
+
+    // Then mask timer interrupts
+    HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_RTC);
+
+    // and wait for the time when the next tick should have come
+    // and check it didn't trigger an interrupt
+    hal_delay_us(TICK_DELAY);
+    CYG_TEST_CHECK(cyg_current_time() == tick, "Timer interrupt while masked");
+
+    // Now change interrupt level, and make the check again. Changing
+    // level should not affect interrupt mask state.
+    HAL_INTERRUPT_SET_LEVEL(CYGNUM_HAL_INTERRUPT_RTC, 8);
+    hal_delay_us(TICK_DELAY);
+    CYG_TEST_CHECK(cyg_current_time() == tick, 
+                   "Timer interrupt after changing level");
+
+    // Finally unmask the interrupt and make sure it results in ticks.
+    HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_RTC);
+    hal_delay_us(TICK_DELAY);
+    CYG_TEST_CHECK(cyg_current_time() != tick, 
+                   "No timer interrupt after unmask");
+
+    CYG_TEST_PASS_FINISH("SH intr0 test end");
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+
+    cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "intr",
+        (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+    cyg_thread_resume(thread[0]);
+
+    cyg_scheduler_start();
+}
+
+// -------------------------------------------------------------------------
+
+#else // def CYGFUN_KERNEL_API_C
+#define N_A_MSG "Kernel C API layer disabled"
+#endif // def CYGFUN_KERNEL_API_C
+#else // def CYGPKG_KERNEL
+#define N_A_MSG "Needs kernel"
+#endif // def CYGPKG_KERNEL
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG
+
+// -------------------------------------------------------------------------
+// EOF intr0.c
--- a/packages/hal/sh/sh3/current/ChangeLog
+++ b/packages/hal/sh/sh3/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-01-18  Jesper Skov  <jskov@redhat.com>
+
+	Case 105302
+	* src/var_misc.c: Separate interrupt level and mask controls.
+	* src/variant.S: Include cyg_hal_ILVL_table and
+	cyg_hal_IMASK_table.
+
 2000-11-22  Jesper Skov  <jskov@redhat.com>
 
  	* src/variant.S: Mangle symbols.
--- a/packages/hal/sh/sh3/current/src/var_misc.c
+++ b/packages/hal/sh/sh3/current/src/var_misc.c
@@ -92,27 +92,17 @@ hal_variant_init(void)
 //---------------------------------------------------------------------------
 // Interrupt function support
 
-#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
 externC cyg_uint8 cyg_hal_ILVL_table[];
-#define HAL_UPDATE_ILVL_TABLE(_vector_, _level_)                         \
-    /* Update the ILVL table, so it is easy for the interrupt entry */   \
-    /* code to find out the level of a given interrupt source.      */   \
-    cyg_hal_ILVL_table[(_vector_)] = (_level_)
-#else
-#define HAL_UPDATE_ILVL_TABLE(_vector_, _level_)
-#endif
+externC cyg_uint8 cyg_hal_IMASK_table[];
 
-void
-hal_interrupt_set_level(int vector, int level)
+static void
+hal_interrupt_update_level(int vector)
 {
     cyg_uint16 iprX;                                                     
-                                                                         
-    CYG_ASSERT((0 <= (level) && 15 >= (level)), "Illegal level");    
-    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)                         
-                && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector"); 
-                                                                         
-    HAL_UPDATE_ILVL_TABLE(vector, level);                            
-                                                                         
+    int level;
+
+    level = cyg_hal_IMASK_table[vector] ? cyg_hal_ILVL_table[vector] : 0;
+
     switch( (vector) ) {                                               
     case CYGNUM_HAL_INTERRUPT_NMI:                                       
         /* fall through */                                               
@@ -297,6 +287,18 @@ hal_interrupt_set_level(int vector, int 
 }
 
 void
+hal_interrupt_set_level(int vector, int level)
+{
+    CYG_ASSERT((0 <= (level) && 15 >= (level)), "Illegal level");    
+    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)                         
+                && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector"); 
+                                                                         
+    cyg_hal_ILVL_table[vector] = level;
+
+    hal_interrupt_update_level(vector);
+}
+
+void
 hal_interrupt_mask(int vector)                                    
 {
     switch( (vector) ) {                                                
@@ -306,7 +308,8 @@ hal_interrupt_mask(int vector)
         /* Can only be masked by fiddling Imask in SR. */                 
         break;                                                            
     case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0 ... CYGNUM_HAL_ISR_MAX:            
-        HAL_INTERRUPT_SET_LEVEL((vector), 0);                           
+        cyg_hal_IMASK_table[vector] = 0;
+        hal_interrupt_update_level(vector);
         break;                                                            
     case CYGNUM_HAL_INTERRUPT_RESERVED_1E0:                               
     case CYGNUM_HAL_INTERRUPT_RESERVED_3E0:                               
@@ -328,7 +331,8 @@ hal_interrupt_unmask(int vector)
         /* Can only be unmasked by fiddling Imask in SR. */               
         break;                                                            
     case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0 ... CYGNUM_HAL_ISR_MAX:            
-        HAL_INTERRUPT_SET_LEVEL((vector), 1);                           
+        cyg_hal_IMASK_table[vector] = 1;
+        hal_interrupt_update_level(vector);
         break;                                                            
     case CYGNUM_HAL_INTERRUPT_RESERVED_1E0:                               
     case CYGNUM_HAL_INTERRUPT_RESERVED_3E0:                               
--- a/packages/hal/sh/sh3/current/src/variant.S
+++ b/packages/hal/sh/sh3/current/src/variant.S
@@ -46,6 +46,7 @@
 #include <cyg/hal/sh3_offsets.inc>
 
 #include <cyg/hal/arch.inc>
+#include <cyg/hal/hal_intr.h>
 
 #---------------------------------------------------------------------------
 # Cache operations
@@ -186,3 +187,43 @@ FUNC_START(cyg_hal_cache_write_mode)
         .long   0x1fffffff              ! mask off top 3 bits
 $BASE:
         .long   0xa0000000              ! base of non-cachable memory
+
+        .data
+
+SYM_DEF(cyg_hal_ILVL_table)
+        # The first entries in the table have static priorities.
+
+        .byte   0xf                     // NMI
+        .byte   0xf                     // Reserved
+        .byte   0xf                     // LVL0
+        .byte   0xe                     // LVL1
+        .byte   0xd                     // LVL2
+        .byte   0xc                     // LVL3
+        .byte   0xb                     // LVL4
+        .byte   0xa                     // LVL5
+        .byte   0x9                     // LVL6
+        .byte   0x8                     // LVL7
+        .byte   0x7                     // LVL8
+        .byte   0x6                     // LVL9
+        .byte   0x5                     // LVL10
+        .byte   0x4                     // LVL11
+        .byte   0x3                     // LVL12
+        .byte   0x2                     // LVL13
+        .byte   0x1                     // LVL14
+        .byte   0xf                     // Reserved
+
+        # The rest of the table consists of programmable levels, maintained
+        # by the HAL_INTERRUPT_SET_LEVEL macro. 
+        # These default to the highest level so that a spurious
+        # interrupt cause the IPL to be suddenly lowered to allow all
+        # interrupts. This should give a better chance at tracking down
+        # the problem.
+        .rept   (CYGNUM_HAL_ISR_MAX-CYGNUM_HAL_INTERRUPT_RESERVED_3E0)
+        .byte   0xf
+        .endr
+
+        # All interrupts are masked initally. Set to 1 to enable.
+SYM_DEF(cyg_hal_IMASK_table)
+        .rept   (CYGNUM_HAL_ISR_MAX)
+        .byte   0x0
+        .endr
--- a/packages/hal/sh/sh4/current/ChangeLog
+++ b/packages/hal/sh/sh4/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-01-18  Jesper Skov  <jskov@redhat.com>
+
+	Case 105302
+	* src/var_misc.c: Separate interrupt level and mask controls.
+	* src/variant.S: Include cyg_hal_ILVL_table and
+	cyg_hal_IMASK_table.
+
 2000-11-22  Jesper Skov  <jskov@redhat.com>
 
 	* src/variant.S: Mangle symbols.
--- a/packages/hal/sh/sh4/current/src/var_misc.c
+++ b/packages/hal/sh/sh4/current/src/var_misc.c
@@ -93,26 +93,16 @@ hal_variant_init(void)
 
 //---------------------------------------------------------------------------
 
-#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
 externC cyg_uint8 cyg_hal_ILVL_table[];
-#define HAL_UPDATE_ILVL_TABLE(_vector_, _level_)                         \
-    /* Update the ILVL table, so it is easy for the interrupt entry */   \
-    /* code to find out the level of a given interrupt source.      */   \
-    cyg_hal_ILVL_table[(_vector_)] = (_level_)
-#else
-#define HAL_UPDATE_ILVL_TABLE(_vector_, _level_)
-#endif
+externC cyg_uint8 cyg_hal_IMASK_table[];
 
-void
-hal_interrupt_set_level(int vector, int level)
+static void
+hal_interrupt_update_level(int vector)
 {
-    cyg_uint16 iprX;
+    cyg_uint16 iprX;                                                     
+    int level;
 
-    CYG_ASSERT((0 <= (level) && 15 >= (level)), "Illegal level");
-    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
-                && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
-
-    HAL_UPDATE_ILVL_TABLE(vector, level);
+    level = cyg_hal_IMASK_table[vector] ? cyg_hal_ILVL_table[vector] : 0;
 
     switch( (vector) ) {
     case CYGNUM_HAL_INTERRUPT_NMI:
@@ -217,6 +207,18 @@ hal_interrupt_set_level(int vector, int 
 }
 
 void
+hal_interrupt_set_level(int vector, int level)
+{
+    CYG_ASSERT((0 <= (level) && 15 >= (level)), "Illegal level");
+    CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
+                && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
+
+    cyg_hal_ILVL_table[vector] = level;
+
+    hal_interrupt_update_level(vector);
+}
+
+void
 hal_interrupt_mask(int vector)                                    
 {
     switch( vector ) {
@@ -226,7 +228,8 @@ hal_interrupt_mask(int vector)
         /* Can only be masked by fiddling Imask in SR. */
         break;
     case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_ISR_MAX:
-        HAL_INTERRUPT_SET_LEVEL((vector), 0);
+        cyg_hal_IMASK_table[vector] = 0;
+        hal_interrupt_update_level(vector);
         break;
     case CYGNUM_HAL_INTERRUPT_RESERVED_1E0:
     case CYGNUM_HAL_INTERRUPT_RESERVED_3E0:
@@ -247,8 +250,9 @@ hal_interrupt_unmask(int vector)
     case CYGNUM_HAL_INTERRUPT_LVL0...CYGNUM_HAL_INTERRUPT_LVL14:
         /* Can only be unmasked by fiddling Imask in SR. */
         break;
-    case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_ISR_MAX:
-        HAL_INTERRUPT_SET_LEVEL((vector), 1);
+    case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_ISR_MAX: 
+        cyg_hal_IMASK_table[vector] = 1;
+        hal_interrupt_update_level(vector);
         break;
     case CYGNUM_HAL_INTERRUPT_RESERVED_1E0:
     case CYGNUM_HAL_INTERRUPT_RESERVED_3E0:
@@ -260,7 +264,6 @@ hal_interrupt_unmask(int vector)
     }
 }
 
-
 void
 hal_interrupt_acknowledge(int vector)
 {
--- a/packages/hal/sh/sh4/current/src/variant.S
+++ b/packages/hal/sh/sh4/current/src/variant.S
@@ -46,6 +46,7 @@
 #include <cyg/hal/sh4_offsets.inc>
 
 #include <cyg/hal/arch.inc>
+#include <cyg/hal/hal_intr.h>
 	
 #---------------------------------------------------------------------------
 # Cache operations
@@ -204,3 +205,44 @@ FUNC_START(cyg_hal_icache_invalidate_all
 	.long	CYGARC_REG_CCR_ICE
 $nCYGARC_REG_CCR_ICI:
 	.long	CYGARC_REG_CCR_ICI
+
+
+        .data
+
+SYM_DEF(cyg_hal_ILVL_table)
+        # The first entries in the table have static priorities.
+
+        .byte   0xf                     // NMI
+        .byte   0xf                     // Reserved
+        .byte   0xf                     // LVL0
+        .byte   0xe                     // LVL1
+        .byte   0xd                     // LVL2
+        .byte   0xc                     // LVL3
+        .byte   0xb                     // LVL4
+        .byte   0xa                     // LVL5
+        .byte   0x9                     // LVL6
+        .byte   0x8                     // LVL7
+        .byte   0x7                     // LVL8
+        .byte   0x6                     // LVL9
+        .byte   0x5                     // LVL10
+        .byte   0x4                     // LVL11
+        .byte   0x3                     // LVL12
+        .byte   0x2                     // LVL13
+        .byte   0x1                     // LVL14
+        .byte   0xf                     // Reserved
+
+        # The rest of the table consists of programmable levels, maintained
+        # by the HAL_INTERRUPT_SET_LEVEL macro. 
+        # These default to the highest level so that a spurious
+        # interrupt cause the IPL to be suddenly lowered to allow all
+        # interrupts. This should give a better chance at tracking down
+        # the problem.
+        .rept   (CYGNUM_HAL_ISR_MAX-CYGNUM_HAL_INTERRUPT_RESERVED_3E0)
+        .byte   0xf
+        .endr
+
+        # All interrupts are masked initally. Set to 1 to enable.
+SYM_DEF(cyg_hal_IMASK_table)
+        .rept   (CYGNUM_HAL_ISR_MAX)
+        .byte   0x0
+        .endr
--- a/packages/hal/v85x/arch/current/ChangeLog
+++ b/packages/hal/v85x/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-01-18  Nick Garnett  <nickg@cygnus.co.uk>
+
+	* src/vectors.S: Added underscore to reference to
+	cyg_scheduler_sched_lock, since CYGBLD_ATTRIB_ASM_ALIAS() now adds
+	one automatically.
+
 2000-10-20  Jesper Skov  <jskov@redhat.com>
 
 	* src/hal_misc.c: Update __mem_fault_handler declaration.
--- a/packages/hal/v85x/arch/current/src/vectors.S
+++ b/packages/hal/v85x/arch/current/src/vectors.S
@@ -351,8 +351,8 @@ 10:
         // increment the scheduler lock and handle the interrupt
 
 #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT			
-        .extern	cyg_scheduler_sched_lock
-        lea     cyg_scheduler_sched_lock,r7
+        .extern	_cyg_scheduler_sched_lock
+        lea     _cyg_scheduler_sched_lock,r7
         ld.w    0[r7],r8
         addi    1,r8,r8
         st.w    r8,0[r7]
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-01-15  Jesper Skov  <jskov@redhat.com>
+
+	* src/net/eth_drv.c (eth_drv_init): Do not use enaddr if NULL.
+
 2001-01-07  Gary Thomas  <gthomas@redhat.com>
 
 	* cdl/eth_drivers.cdl: Add interface 'CYGPKG_NET_DRIVER_FRAMEWORK'
--- a/packages/io/eth/current/src/net/eth_drv.c
+++ b/packages/io/eth/current/src/net/eth_drv.c
@@ -295,7 +295,8 @@ eth_drv_init(struct eth_drv_sc *sc, unsi
     struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 
     // Set up hardware address
-    bcopy(enaddr, &sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
+    if (NULL != enaddr)
+        bcopy(enaddr, &sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
 
     // Initialize ifnet structure
     bcopy((void *)sc->dev_name, ifp->if_xname, IFNAMSIZ);
--- a/packages/io/serial/current/tests/ser_test_protocol.inl
+++ b/packages/io/serial/current/tests/ser_test_protocol.inl
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -32,7 +32,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):     jskov
-// Contributors:  jskov
+// Contributors:  jskov, gthomas
 // Date:          1999-03-17
 // Description:   Protocol implementation used to test eCos serial devices.
 //                Relies on ser_filter to be present on the host side to
@@ -56,7 +56,7 @@
 #include <cyg/infra/diag.h>
 #include <cyg/infra/cyg_ass.h>
 
-#include <cyg/hal/hal_intr.h>           // for reclaiming interrup vector
+#include <cyg/hal/hal_intr.h>           // for reclaiming interrupt vector
 
 //----------------------------------------------------------------------------
 // Definition of which device to run tests on on various platforms.
--- a/packages/net/snmp/agent/current/ChangeLog
+++ b/packages/net/snmp/agent/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-01-17  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/mibgroup/util_funcs.c (restart_hook): Don't use alarm() in eCos
+	(wait_on_exec): Don't use waitpid() in eCos
+	The above prevent link errors.
+
 2001-01-10  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/snmpagent.cdl: Clarify ISO C requirements
--- a/packages/net/snmp/agent/current/src/mibgroup/util_funcs.c
+++ b/packages/net/snmp/agent/current/src/mibgroup/util_funcs.c
@@ -233,12 +233,14 @@ int exec_command(struct extensible *ex)
 
 void wait_on_exec(struct extensible *ex)
 {
+#ifndef __ECOS
 #ifndef EXCACHETIME
     if (ex->pid && waitpid(ex->pid,&ex->result,0) < 0) {
       setPerrorstatus("waitpid");
     }
     ex->pid = 0;
 #endif
+#endif
 }
 
 #define MAXARGS 30
@@ -528,7 +530,9 @@ restart_hook(int action,
 #ifdef SIGALRM
     signal(SIGALRM,restart_doit);
 #endif
+#ifndef __ECOS
     alarm(RESTARTSLEEP);
+#endif
   } 
   return SNMP_ERR_NOERROR;
 }
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,25 @@
+2001-01-18  Gary Thomas  <gthomas@redhat.com>
+
+	* include/net/net.h: 
+	* src/net/pktbuf.c (__pktbuf_alloc): 
+	* src/net/tcp.c (__tcp_listen): Remove obsolete code regarding
+	'eth_hdr' stored with packet buffer.
+
+2001-01-17  Hugo Tyson  <hmt@redhat.com>
+
+	* src/io.c (dump_buf_with_offset): Fix previous change so it
+	compiles; variable names used not same as parm names in func.
+
+2001-01-16  Gary Thomas  <gthomas@redhat.com>
+
+	* src/xyzModem.c: Improved debug support - now allows debug 
+	trace to be kept in memory and dumped at completion.
+
+	* src/io.c (vdump_buf_with_offset): New function which allows
+	dumping via any generic "print" function.
+
+	* include/redboot.h: Export new print/dump functions.
+
 2001-01-08  Gary Thomas  <gthomas@redhat.com>
 
 	* src/net/arp.c: Add special case handling for ARP(self).
--- a/packages/redboot/current/include/net/net.h
+++ b/packages/redboot/current/include/net/net.h
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -260,9 +260,6 @@ typedef struct {
 
 typedef struct _pktbuf {
     struct _pktbuf *next;
-#if 0
-    eth_header_t   *eth_hdr;		/* pointer to ethernet header */
-#endif
     union {
 	ip_header_t *__iphdr;		/* pointer to IP header */
 	arp_header_t *__arphdr;		/* pointer to ARP header */
--- a/packages/redboot/current/include/redboot.h
+++ b/packages/redboot/current/include/redboot.h
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -90,9 +90,11 @@ EXTERN int script_timeout;
 #endif
 
 // Prototypes
-int  printf(char *fmt, ...);
+typedef int _printf_fun(char *fmt, ...);
+_printf_fun printf;
 int  vprintf(char *fmt, va_list ap);
 int  sprintf(char *buf, char *fmt, ...);
+int  vsprintf(char *buf, char *fmt, va_list ap);
 int  strlen(const char *str);
 int  strcmp(const char *s1, const char *s2);
 int  strncmp(const char *s1, const char *s2, int len);
@@ -104,6 +106,7 @@ void mon_write_char(char c);
 bool verify_action(char *fmt, ...);
 void dump_buf(void *, CYG_ADDRWORD);
 void dump_buf_with_offset(void *, CYG_ADDRWORD, void *);
+void vdump_buf_with_offset(_printf_fun *pf, void *, CYG_ADDRWORD, void *);
 
 // Read a single line of input from the console, possibly with timeout
 int  gets(char *line, int len, int timeout);
--- a/packages/redboot/current/src/io.c
+++ b/packages/redboot/current/src/io.c
@@ -250,7 +250,7 @@ gets(char *buf, int buflen, int timeout)
 }
 
 void
-dump_buf_with_offset(void *_p, CYG_ADDRWORD s, void *_base)
+vdump_buf_with_offset(_printf_fun *pf, void *_p, CYG_ADDRWORD s, void *_base)
 {
     int i, c;
     cyg_uint8 *p = (cyg_uint8 *)_p;
@@ -261,20 +261,20 @@ dump_buf_with_offset(void *_p, CYG_ADDRW
     }
     while ((int)s > 0) {
         if (base) {
-            printf("0x%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
+            (*pf)("0x%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base);
         } else {
-            printf("0x%08X: ", (CYG_ADDRWORD)p);
+            (*pf)("0x%08X: ", (CYG_ADDRWORD)p);
         }
         for (i = 0;  i < 16;  i++) {
             if (i < (int)s) {
-                printf("%02X", p[i] & 0xFF);
+                (*pf)("%02X", p[i] & 0xFF);
             } else {
-                printf("  ");
+                (*pf)("  ");
             }
-            if ((i % 2) == 1) printf(" ");
-            if ((i % 8) == 7) printf(" ");
+            if ((i % 2) == 1) (*pf)(" ");
+            if ((i % 8) == 7) (*pf)(" ");
         }
-        printf(" |");
+        (*pf)(" |");
         for (i = 0;  i < 16;  i++) {
             if (i < (int)s) {
                 c = p[i] & 0xFF;
@@ -282,15 +282,21 @@ dump_buf_with_offset(void *_p, CYG_ADDRW
             } else {
                 c = ' ';
             }
-            printf("%c", c);
+            (*pf)("%c", c);
         }
-        printf("|\n");
+        (*pf)("|\n");
         s -= 16;
         p += 16;
     }
 }
 
 void
+dump_buf_with_offset(void *p, CYG_ADDRWORD s, void *base)
+{
+    vdump_buf_with_offset(printf, p, s, base);
+}
+
+void
 dump_buf(void *p, CYG_ADDRWORD s)
 {
    dump_buf_with_offset((cyg_uint8 *)p, s, 0);
--- a/packages/redboot/current/src/net/pktbuf.c
+++ b/packages/redboot/current/src/net/pktbuf.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -111,12 +111,7 @@ pktbuf_t *
 
     if (p) {
 	free_list = p->next;
-#if 0
-	p->eth_hdr = (eth_header_t *)p->buf;
-	p->ip_hdr  = (ip_header_t *)(p->eth_hdr + 1);
-#else
 	p->ip_hdr  = (ip_header_t *)p->buf;
-#endif
 	p->tcp_hdr = (tcp_header_t *)(p->ip_hdr + 1);
 	p->pkt_bytes = 0;
 #if BUFF_STATS
--- a/packages/redboot/current/src/net/tcp.c
+++ b/packages/redboot/current/src/net/tcp.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -581,12 +581,7 @@ int
     s->our_port = port;
     s->pkt.buf = (word *)s->pktbuf;
     s->pkt.bufsize = ETH_MAX_PKTLEN;
-#if 0
-    s->pkt.eth_hdr = (eth_header_t *)s->pkt.buf;
-    s->pkt.ip_hdr  = (ip_header_t *)(s->pkt.eth_hdr + 1);
-#else
     s->pkt.ip_hdr  = (ip_header_t *)s->pkt.buf;
-#endif
     s->pkt.tcp_hdr = (tcp_header_t *)(s->pkt.ip_hdr + 1);
 
     s->next = tcp_list;
--- a/packages/redboot/current/src/xyzModem.c
+++ b/packages/redboot/current/src/xyzModem.c
@@ -23,7 +23,7 @@
 //                                                                          
 // The Initial Developer of the Original Code is Red Hat.                   
 // Portions created by Red Hat are                                          
-// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
 // All Rights Reserved.                                                     
 // -------------------------------------------                              
 //                                                                          
@@ -108,13 +108,13 @@ static unsigned short crc16[] = {
 };
 
 #ifdef DEBUG
-
+#ifndef USE_SPRINTF
 //
 // Note: this debug setup only works if the target platform has two serial ports
 // available so that the other one (currently only port 1) can be used for debug
 // messages.
 //
-void
+static int
 zm_dprintf(char *fmt, ...)
 {
     int cur_console;
@@ -127,33 +127,60 @@ zm_dprintf(char *fmt, ...)
     CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console);
 }
 
-void
+static void
+zm_flush(void)
+{
+}
+
+#else
+//
+// Note: this debug setup works by storing the strings in a fixed buffer
+//
+static char *zm_out = (char *)0x00200000;
+static char *zm_out_start = (char *)0x00200000;
+
+static int
+zm_dprintf(char *fmt, ...)
+{
+    int len;
+    va_list args;
+
+    va_start(args, fmt);
+    len = vsprintf(zm_out, fmt, args);
+    zm_out += len;
+}
+
+static void
+zm_flush(void)
+{
+    char *p = zm_out_start;
+    while (*p) mon_write_char(*p++);
+    zm_out = zm_out_start;
+}
+#endif
+
+static void
 zm_dump_buf(void *buf, int len)
 {
-    int cur_console;
-
-    cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
-    dump_buf(buf, len);
-    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console);
+    vdump_buf_with_offset(zm_dprintf, buf, len, 0);
 }
 
 static unsigned char zm_buf[2048];
 static unsigned char *zm_bp;
 
-void
+static void
 zm_new(void)
 {
     zm_bp = zm_buf;
 }
 
-void
+static void
 zm_save(unsigned char c)
 {
     *zm_bp++ = c;
 }
 
-void
+static void
 zm_dump(int line)
 {
     zm_dprintf("Packet at line: %d\n", line);
@@ -211,6 +238,7 @@ xyzModem_get_hdr(void)
             }
         } else {
             // Data stream timed out
+            ZM_DEBUG(zm_dump(__LINE__));
             return xyzModem_timeout;
         }
     }
@@ -219,11 +247,13 @@ xyzModem_get_hdr(void)
     res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.blk);
     ZM_DEBUG(zm_save(xyz.blk));
     if (!res) {
+        ZM_DEBUG(zm_dump(__LINE__));
         return xyzModem_timeout;
     }
     res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.cblk);
     ZM_DEBUG(zm_save(xyz.cblk));
     if (!res) {
+        ZM_DEBUG(zm_dump(__LINE__));
         return xyzModem_timeout;
     }
     xyz.len = (c == SOH) ? 128 : 1024;
@@ -234,18 +264,21 @@ xyzModem_get_hdr(void)
         if (res) {
             xyz.pkt[i] = c;
         } else {
+            ZM_DEBUG(zm_dump(__LINE__));
             return xyzModem_timeout;
         }
     }
     res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc1);
     ZM_DEBUG(zm_save(xyz.crc1));
     if (!res) {
+        ZM_DEBUG(zm_dump(__LINE__));
         return xyzModem_timeout;
     }
     if (xyz.crc_mode) {
         res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc2);
         ZM_DEBUG(zm_save(xyz.crc2));
         if (!res) {
+            ZM_DEBUG(zm_dump(__LINE__));
             return xyzModem_timeout;
         }
     }
@@ -332,6 +365,7 @@ xyzModem_stream_open(char *filename, int
         }
     }
     *err = stat;
+    ZM_DEBUG(zm_flush());
     return -1;
 }
 
@@ -407,6 +441,7 @@ xyzModem_stream_close(int *err)
            xyz.crc_mode ? "CRC" : "Cksum",
            xyz.total_SOH, xyz.total_STX, xyz.total_CAN,
            xyz.total_retries);
+    ZM_DEBUG(zm_flush());
 }
 
 char *