changeset 195:67850532eebb

Merge from eCos master repository on 2001-11-02-06:43:03-GMT
author jlarmour
date Fri, 02 Nov 2001 16:12:33 +0000
parents feb0fcf83327
children 9b55e9c69693
files packages/ChangeLog packages/NEWS packages/devs/eth/arm/integrator/current/ChangeLog packages/devs/eth/arm/integrator/current/cdl/integrator_eth_drivers.cdl packages/devs/eth/arm/integrator/current/include/integrator_info.h packages/devs/eth/arm/integrator/current/src/if_integrator.c packages/devs/flash/amd/am29xxxxx/current/ChangeLog packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl packages/devs/flash/arm/integrator/current/ChangeLog packages/devs/flash/arm/integrator/current/cdl/flash_integrator.cdl packages/devs/flash/arm/integrator/current/src/flash.h packages/devs/flash/arm/integrator/current/src/flash_erase_block.c packages/devs/flash/arm/integrator/current/src/flash_program_buf.c packages/devs/flash/arm/integrator/current/src/flash_query.c packages/devs/flash/arm/integrator/current/src/integrator_flash.c packages/devs/serial/arm/integrator/current/ChangeLog packages/devs/serial/arm/integrator/current/cdl/ser_arm_integrator.cdl packages/devs/serial/arm/integrator/current/src/integrator_serial.h packages/devs/serial/arm/integrator/current/src/integrator_serial_with_ints.c packages/ecos.db packages/hal/arm/arch/current/ChangeLog packages/hal/arm/arch/current/src/arm.ld packages/hal/arm/arm9/var/current/ChangeLog packages/hal/arm/arm9/var/current/include/hal_cache.h packages/hal/arm/arm9/var/current/src/arm9_misc.c packages/hal/arm/integrator/current/ChangeLog packages/hal/arm/integrator/current/cdl/hal_arm_integrator.cdl packages/hal/arm/integrator/current/include/hal_cache.h packages/hal/arm/integrator/current/include/hal_diag.h packages/hal/arm/integrator/current/include/hal_integrator.h packages/hal/arm/integrator/current/include/hal_platform_ints.h packages/hal/arm/integrator/current/include/hal_platform_setup.h packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_ram.h packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_ram.ldi packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_ram.mlt packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_rom.h packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_rom.ldi packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_rom.mlt packages/hal/arm/integrator/current/include/plf_io.h packages/hal/arm/integrator/current/include/plf_stub.h packages/hal/arm/integrator/current/misc/redboot_RAM.ecm packages/hal/arm/integrator/current/misc/redboot_ROM.ecm packages/hal/arm/integrator/current/src/Notes_GDB_stub packages/hal/arm/integrator/current/src/flash.c packages/hal/arm/integrator/current/src/hal_diag.c packages/hal/arm/integrator/current/src/integrator_misc.c packages/hal/arm/integrator/current/src/prog_flash.c packages/hal/arm/sa11x0/assabet/current/ChangeLog packages/hal/arm/sa11x0/flexanet/current/ChangeLog packages/hal/arm/sa11x0/flexanet/current/include/flexanet.h packages/hal/arm/sa11x0/flexanet/current/include/hal_platform_setup.h packages/hal/arm/sa11x0/var/current/ChangeLog packages/hal/arm/sa11x0/var/current/cdl/hal_arm_sa11x0.cdl packages/hal/i386/pcmb/current/ChangeLog packages/hal/i386/pcmb/current/src/pcmb_misc.c packages/hal/mips/atlas/current/ChangeLog packages/hal/mips/atlas/current/cdl/hal_mips_atlas.cdl packages/hal/mips/vrc437x/current/ChangeLog packages/hal/mips/vrc437x/current/cdl/hal_mips_vr4300_vrc437x.cdl packages/hal/mips/vrc437x/current/include/platform.inc packages/hal/mips/vrc437x/current/include/plf_intr.h packages/hal/mn10300/stb/current/ChangeLog packages/hal/mn10300/stb/current/cdl/hal_mn10300_am33_stb.cdl packages/io/eth/current/ChangeLog packages/io/eth/current/doc/driver_doc packages/io/eth/current/src/net/eth_drv.c packages/io/flash/current/ChangeLog packages/io/flash/current/src/flash.c packages/kernel/current/ChangeLog packages/kernel/current/tests/kcache2.c packages/net/tcpip/current/ChangeLog packages/net/tcpip/current/cdl/net.cdl packages/net/tcpip/current/include/machine/ansi.h packages/net/tcpip/current/src/ecos/support.c packages/net/tcpip/current/src/lib/recv.c packages/net/tcpip/current/src/sys/net/if_ethersubr.c packages/pkgconf/fixhtml.tcl packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/include/redboot.h packages/redboot/current/include/sib.h packages/redboot/current/src/flash.c packages/redboot/current/src/io.c packages/redboot/current/src/main.c
diffstat 85 files changed, 10160 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/packages/ChangeLog
+++ b/packages/ChangeLog
@@ -1,3 +1,8 @@
+2001-10-30  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* ecos.db: Added ARM Integrator target including HAL, serial driver, 
+	eth driver and flash driver packages.
+
 2001-10-19  Lars Lindqvist  <Lars.Lindqvist@combitechsystems.com>
 2001-10-19  Jonathan Larmour  <jlarmour@redhat.com>
 
--- a/packages/NEWS
+++ b/packages/NEWS
@@ -1,3 +1,6 @@
+* Incorporated ARM Development board aka INTEGRATOR port from Philippe Robin
+  at ARM. Includes FLASH, ethernet and serial drivers, along with RedBoot
+  support.
 * Added ARM E7T (AEB-2) serial device drivers contributed by 
   Lars Lindqvist at Combitech <Lars.Lindqvist@combitechsystems.com>
 * Flash driver added for the SH EDK7708 platform.
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/arm/integrator/current/ChangeLog
@@ -0,0 +1,31 @@
+2000-08-21  Philippe Robin
+	* adapted from ebsa285
+
+//===========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//===========================================================================
+	
+	
+
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/arm/integrator/current/cdl/integrator_eth_drivers.cdl
@@ -0,0 +1,149 @@
+# ====================================================================
+#
+#	integrator_eth_drivers.cdl
+#
+#	Ethernet drivers
+#	Intel PRO/100+ platform specific support for ARM Integrator
+#
+# ====================================================================
+#####COPYRIGHTBEGIN####
+#                                                                          
+# -------------------------------------------                              
+# The contents of this file are subject to the Red Hat eCos Public License 
+# Version 1.1 (the "License"); you may not use this file except in         
+# compliance with the License.  You may obtain a copy of the License at    
+# http://www.redhat.com/                                                   
+#                                                                          
+# Software distributed under the License is distributed on an "AS IS"      
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+# License for the specific language governing rights and limitations under 
+# the License.                                                             
+#                                                                          
+# The Original Code is eCos - Embedded Configurable Operating System,      
+# released September 30, 1998.                                             
+#                                                                          
+# The Initial Developer of the Original Code is Red Hat.                   
+# Portions created by Red Hat are                                          
+# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Philippe Robin
+# Original data:  hmt
+# Contributors:	  
+# Date:           November 7, 2000
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_INTEGRATOR {
+    display       "Intel PRO/100+ ethernet driver for ARM Integrator"
+
+    parent        CYGPKG_IO_ETH_DRIVERS
+    active_if     CYGPKG_IO_ETH_DRIVERS
+    active_if     CYGPKG_HAL_ARM_INTEGRATOR
+
+    implements    CYGHWR_NET_DRIVER_ETH0
+    implements    CYGHWR_NET_DRIVER_ETH1
+    # yes, there should be two of these "implement"s
+    implements    CYGHWR_NET_DRIVERS
+    implements    CYGHWR_NET_DRIVERS
+    include_dir   cyg/devs/eth
+
+    # SNMP demands to know stuff; this sadly makes us break the neat
+    # abstraction of the device having nothing exported.
+    # The other one is used by other tests:
+    include_files include/integrator_info.h
+    # and tell them that it is available
+    define_proc {
+	puts $::cdl_system_header \
+       "#define CYGBLD_DEVS_ETH_DEVICE_H <pkgconf/devs_eth_arm_integrator.h>"
+	puts $::cdl_header \
+       "#define CYGBLD_DEVS_ETH_INFO_H <cyg/devs/eth/integrator_info.h>"
+    }
+
+    description   "Ethernet driver for Intel PRO/100+ boards on ARM Integrator."
+    compile       -library=libextras.a if_integrator.c
+
+    cdl_option CYGDBG_DEVS_ETH_ARM_INTEGRATOR_CHATTER {
+	display "Prints ethernet device status info during startup"
+	default_value 0
+	description   "
+	    The ethernet device initialization code can print lots of info
+	    to confirm that it has found the devices on the PCI bus, read
+	    the MAC address from EEPROM correctly, and so on, and also
+	    displays the mode (10/100MHz, half/full duplex) of the
+	    connection."
+    }
+
+    cdl_option CYGNUM_DEVS_ETH_ARM_INTEGRATOR_DEV_COUNT {
+	display "Number of supported interfaces."
+        legal_values  1 2
+	default_value 1
+        flavor        data
+	description   "
+	    This option selects the number of PCI ethernet interfaces to
+            be supported by the driver."
+    }
+
+    cdl_component CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_STATISTICS {
+	display "Keep Ethernet statistics"
+	default_value 1
+	description   "
+	    The ethernet device can maintain statistics about the network,
+	    specifically a great variety of error rates which are useful
+	    for network management.  SNMP for example uses this
+	    information.  There is some performance cost in maintaining
+	    this information; disable this option to recoup that."
+
+	cdl_option CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_82559_STATISTICS {
+	    display "Keep i82559 Internal statistics"
+	    default_value 1
+	    description   "
+	        The i82559 keeps internal counters, and it is possible to
+	        acquire these.  But the i82559 (reputedly) does not service
+	        the network whilst uploading the data to RAM from its
+	        internal registers.  If throughput is a problem, disable
+	        this option to acquire only those statistics gathered by
+	        software, so that the i82559 never sleeps."
+	}
+    }
+
+    cdl_component CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM {
+	display "SIOCSIFHWADDR records MAC address in EEPROM"
+	default_value 0
+	description   "
+	    The ioctl() socket call with operand SIOCSIFHWADDR sets the
+	    interface hardware address - the MAC address or ethernet
+	    address.  This option causes the new MAC address to be written
+	    into the EEPROM associated with the interface, so that the new
+	    MAC address is permanently recorded.  Doing this should be a
+	    carefully chosen decision, hence this option."
+    }
+
+    cdl_component CYGPKG_DEVS_ETH_ARM_INTEGRATOR_OPTIONS {
+        display "Intel PRO/100+ ethernet driver build options for ARM Integrator"
+        flavor  none
+	no_define
+
+        cdl_option CYGPKG_DEVS_ETH_ARM_INTEGRATOR_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "-D_KERNEL -D__ECOS" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the Intel EBSA285 with PRO/100+ ethernet driver
+                package. These flags are used in addition to the set of
+                global flags."
+        }
+    }
+
+}
+
+# EOF integrator_eth_drivers.cdl
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/arm/integrator/current/include/integrator_info.h
@@ -0,0 +1,206 @@
+#ifndef CYGONCE_DEVS_ETH_ARM_INTEGRATOR_INTEGRATOR_INFO_H
+#define CYGONCE_DEVS_ETH_ARM_INTEGRATOR_INTEGRATOR_INFO_H
+/*==========================================================================
+//
+//        integrator_info.h
+//
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Philippe Robin
+// Original data: hmt
+// Contributors:
+// Date:          November 7, 2000
+// Description:
+//
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/devs_eth_arm_integrator.h>
+
+#undef CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_SIZE
+#define CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_SIZE  0x100000
+
+#ifdef CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_STATISTICS
+# define KEEP_STATISTICS
+# define nDISPLAY_STATISTICS
+# define nDISPLAY_82559_STATISTICS
+#else
+# define nKEEP_STATISTICS
+# define nDISPLAY_STATISTICS
+# define nDISPLAY_82559_STATISTICS
+#endif
+
+
+// ------------------------------------------------------------------------
+//
+//                       STATISTICAL COUNTER STRUCTURE
+//
+// ------------------------------------------------------------------------
+#ifdef KEEP_STATISTICS
+typedef struct {
+/*  0 */    cyg_uint32 tx_good;
+/*  4 */    cyg_uint32 tx_max_collisions;
+/*  8 */    cyg_uint32 tx_late_collisions;
+/* 12 */    cyg_uint32 tx_underrun;
+/* 16 */    cyg_uint32 tx_carrier_loss;
+/* 20 */    cyg_uint32 tx_deferred;
+/* 24 */    cyg_uint32 tx_single_collisions;
+/* 28 */    cyg_uint32 tx_mult_collisions;
+/* 32 */    cyg_uint32 tx_total_collisions;
+/* 36 */    cyg_uint32 rx_good;
+/* 40 */    cyg_uint32 rx_crc_errors;
+/* 44 */    cyg_uint32 rx_align_errors;
+/* 48 */    cyg_uint32 rx_resource_errors;
+/* 52 */    cyg_uint32 rx_overrun_errors;
+/* 56 */    cyg_uint32 rx_collisions; // Always 0
+/* 60 */    cyg_uint32 rx_short_frames;
+// In this setup; can also be flow-control counts after.
+// If these are to be used, a config command (as in set promiscuous mode)
+// must be issued at start, to let those stats escape.  Params are in
+// comments around the config command setup...
+/* 64 */    cyg_uint32 done;
+} I82559_COUNTERS;
+
+
+typedef struct {
+    cyg_uint32 interrupts;
+    cyg_uint32 rx_count;
+    cyg_uint32 rx_deliver;
+    cyg_uint32 rx_resource;
+    cyg_uint32 rx_restart;
+    cyg_uint32 tx_count;
+    cyg_uint32 tx_complete;
+    cyg_uint32 tx_dropped;
+} STATISTICS;
+
+
+extern STATISTICS statistics[2];
+#ifdef CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_82559_STATISTICS
+extern I82559_COUNTERS i82559_counters[2];
+#endif
+
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+//
+//                      DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+// The system seems to work OK with as few as 8 of RX and TX descriptors.
+// It limps very painfully with only 4.
+// Performance is better with more than 8.
+// But the size of non-cached (so useless for anything else)
+// memory window is 1Mb, so we might as well use it all.
+//
+// 128 for these uses the whole 1Mb, near enough.
+
+#ifndef MAX_RX_DESCRIPTORS
+#define MAX_RX_DESCRIPTORS	8     // number of Rx descriptors 128
+#endif
+#ifndef MAX_TX_DESCRIPTORS
+#define MAX_TX_DESCRIPTORS	8     // number of Tx descriptors
+#endif
+
+
+typedef struct i82559 {
+    cyg_uint8                           // (split up for atomic byte access)
+        found:1,                        // was hardware discovered?
+        mac_addr_ok:1,                  // can we bring up?
+        active:1,                       // has this if been brung up?
+        spare1:5; 
+    cyg_uint8
+        spare2:8; 
+    cyg_uint8
+        tx_in_progress:1,               // transmit in progress flag
+        tx_queue_full:1,                // all Tx descriptors used flag
+        spare3:6; 
+    cyg_uint8  index;                   // 0 or 1 or whatever
+    cyg_uint32 devid;                   // PCI device id
+    cyg_uint32 memory_address;          // PCI memory address
+    cyg_uint32 io_address;              // memory mapped I/O address
+    cyg_uint8  mac_address[6];          // mac (hardware) address
+    void *ndp;                          // Network Device Pointer
+
+    int next_rx_descriptor;             // descriptor index for RFDs
+    struct rfd *rx_ring[MAX_RX_DESCRIPTORS]; // location of Rx descriptors
+
+    int tx_descriptor_add;              // descriptor index for additions
+    int tx_descriptor_active;           // descriptor index for active tx
+    int tx_descriptor_remove;           // descriptor index for remove
+
+    struct txcb *tx_ring[MAX_TX_DESCRIPTORS];  // location of Tx descriptors
+    unsigned long tx_keys[MAX_TX_DESCRIPTORS];
+                                        // keys for tx q management
+
+    // Interrupt handling stuff
+    cyg_vector_t    vector;             // interrupt vector
+    cyg_handle_t    interrupt_handle;   // handle for int.handler
+    cyg_interrupt   interrupt_object;
+
+#ifdef KEEP_STATISTICS
+    void *p_statistics;                 // pointer to statistical counters
+#endif
+
+} I82559;
+
+
+
+// ------------------------------------------------------------------------
+//
+//                   82559 GENERAL STATUS REGISTER
+//
+// ------------------------------------------------------------------------
+#define GEN_STATUS_FDX          0x04    // 1 = full duplex, 0 = half
+#define GEN_STATUS_100MBPS      0x02    // 1 = 100 Mbps, 0 = 10 Mbps
+#define GEN_STATUS_LINK         0x01    // 1 = link up, 0 = link down
+
+extern int i82559_status( struct eth_drv_sc *sc );
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+void update_statistics(struct i82559* p_i82559);
+#endif
+
+
+#ifdef CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_82559_STATISTICS
+#define ETH_STATS_INIT( p ) \
+        update_statistics( (struct i82559 *)((p)->driver_private) )
+#else
+#define ETH_STATS_INIT( p ) // otherwise do nothing
+#endif
+
+#define CYGDAT_DEVS_ETH_DESCRIPTION "Intel EtherPRO 10/100+ (i82559)"
+
+#define ETH_DEV_DOT3STATSETHERCHIPSET 1,3,6,1,2,1,10,7,8,2,5
+
+#endif /* ifndef CYGONCE_DEVS_ETH_ARM_INTEGRATOR_INTEGRATOR_INFO_H */
+
+/* EOF integrator_info.h */
+
new file mode 100644
--- /dev/null
+++ b/packages/devs/eth/arm/integrator/current/src/if_integrator.c
@@ -0,0 +1,2712 @@
+//==========================================================================
+//
+//      if_integrator.c
+//
+//	Ethernet drivers
+//	ARM Integrator with Intel PRO/100+ platform specific support
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources,
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    hmt, gthomas
+// Contributors: Ron Spence, Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      
+// Description:  hardware driver for 82559 Intel PRO/100+ ethernet and
+//               ARM INTEGRATOR development boards
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_integrator.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <netdev.h>
+#include <eth_drv.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h>  /* Needed for struct ifnet */
+#else
+#include <cyg/hal/hal_if.h>
+#endif
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+// So we can check the validity of the PCI window against the MLTs opinion,
+// and thereby what the malloc heap consumes willy-nilly:
+#include CYGHWR_MEMORY_LAYOUT_H
+#else
+#error "Need PCI package here"
+#endif
+
+// Exported statistics and the like
+#include <cyg/devs/eth/integrator_info.h>
+#include <eth_drv_stats.h>
+
+// ------------------------------------------------------------------------
+
+#ifdef CYGDBG_DEVS_ETH_ARM_INTEGRATOR_CHATTER
+#define noDEBUG_82559 // This one prints stuff as packets come and go
+#define DEBUG          // Startup printing mainly
+#define DEBUG_EE       // Some EEPROM specific retries &c
+#endif
+
+#define os_printf diag_printf
+#define db_printf diag_printf
+
+// ------------------------------------------------------------------------
+// I/O access macros as inlines for type safety
+
+static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
+{   *((volatile cyg_uint8 *)io_address) = value;    }
+
+static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
+{   *((volatile cyg_uint16 *)io_address) = value;   }
+
+static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{   *((volatile cyg_uint32 *)io_address) = value;   }
+
+static inline cyg_uint8 INB(cyg_uint32 io_address)
+{   return *((volatile cyg_uint8 *)io_address);     }
+
+static inline cyg_uint16 INW(cyg_uint32 io_address)
+{   return *((volatile cyg_uint16 *)io_address);    }
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+{   return *((volatile cyg_uint32 *)io_address);    }
+
+#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
+static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory)
+{    return (p_memory); }
+
+#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))
+static inline cyg_uint32 bus_to_virt(cyg_uint32 p_memory)
+{    return (p_memory); }
+
+
+// ------------------------------------------------------------------------
+//                                                                      
+//                   82559 REGISTER OFFSETS (I/O SPACE)                 
+//                                                                      
+// ------------------------------------------------------------------------
+#define SCBStatus       0               // Rx/Command Unit command and status.
+#define SCBCmd          2               // Rx/Command Unit command and status.
+#define SCBPointer      4               // General purpose pointer.
+#define SCBPort         8               // Misc. commands and operands.
+#define SCBflash        12              // Flash memory control.
+#define SCBeeprom       14              // EEPROM memory control.
+#define SCBCtrlMDI      16              // MDI interface control.
+#define SCBEarlyRx      20              // Early receive byte count.
+#define SCBGenControl   28              // 82559 General Control Register
+#define SCBGenStatus    29              // 82559 General Status register
+
+
+// ------------------------------------------------------------------------
+//
+//               82559 SCB STATUS WORD DEFNITIONS
+//
+// ------------------------------------------------------------------------
+#define SCB_STATUS_CX   0x8000          // CU finished command (transmit)
+#define SCB_STATUS_FR   0x4000          // frame received
+#define SCB_STATUS_CNA  0x2000          // CU left active state
+#define SCB_STATUS_RNR  0x1000          // receiver left ready state
+#define SCB_STATUS_MDI  0x0800          // MDI read/write cycle done
+#define SCB_STATUS_SWI  0x0400          // software generated interrupt
+#define SCB_STATUS_FCP  0x0100          // flow control pause interrupt
+
+#define SCB_INTACK_MASK 0xFD00          // all the above
+
+#define SCB_INTACK_TX (SCB_STATUS_CX | SCB_STATUS_CNA)
+#define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR)
+
+// ------------------------------------------------------------------------
+//
+//               82559 PORT INTERFACE COMMANDS
+//
+// ------------------------------------------------------------------------
+#define I82559_RESET            0x00000000 // software reset
+#define I82559_SELFTEST         0x00000001 // 82559 selftest command
+#define I82559_SELECTIVE_RESET  0x00000002
+#define I82559_DUMP             0x00000003
+#define I82559_DUMP_WAKEUP      0x00000007
+
+
+
+// ------------------------------------------------------------------------
+//
+//                   82559 EEPROM INTERFACE
+//
+// ------------------------------------------------------------------------
+//  EEPROM_Ctrl bits.
+#define EE_SHIFT_CLK	0x01            // EEPROM shift clock.
+#define EE_CS		0x02            // EEPROM chip select.
+#define EE_DATA_WRITE	0x04            // EEPROM chip data in.
+#define EE_DATA_READ	0x08            // EEPROM chip data out.
+#define EE_ENB		(0x4800 | EE_CS)
+
+// Delay between EEPROM clock transitions.
+#define eeprom_delay(usec)		udelay(usec);
+
+// The EEPROM commands include the always-set leading bit.
+#define EE_WRITE_CMD(a)     (5 << (a))
+#define EE_READ_CMD(a)	    (6 << (a))
+#define EE_ERASE_CMD(a)	    (7 << (a))
+#define EE_WRITE_EN_CMD(a)  (19 << ((a)-2))
+#define EE_WRITE_DIS_CMD(a) (16 << ((a)-2))
+#define EE_ERASE_ALL_CMD(a) (18 << ((a)-2))
+
+#define EE_TOP_CMD_BIT(a)      ((a)+2) // Counts down to zero
+#define EE_TOP_DATA_BIT        (15)    // Counts down to zero
+
+#define EEPROM_ENABLE_DELAY (10) // Delay at chip select
+
+#define EEPROM_SK_DELAY  (2) // Delay between clock edges *and* data
+                             // read or transition; 3 of these per bit.
+#define EEPROM_DONE_DELAY (100) // Delay when all done
+
+
+// ------------------------------------------------------------------------
+//
+//               SYSTEM CONTROL BLOCK COMMANDS
+//
+// ------------------------------------------------------------------------
+// CU COMMANDS
+#define CU_NOP          0x0000
+#define	CU_START        0x0010
+#define	CU_RESUME       0x0020
+#define	CU_STATSADDR    0x0040          // Load Dump Statistics ctrs addr
+#define	CU_SHOWSTATS    0x0050          // Dump statistics counters.
+#define	CU_ADDR_LOAD    0x0060          // Base address to add to CU commands
+#define	CU_DUMPSTATS    0x0070          // Dump then reset stats counters.
+
+// RUC COMMANDS
+#define RUC_NOP         0x0000
+#define	RUC_START       0x0001
+#define	RUC_RESUME      0x0002
+#define RUC_ABORT       0x0004
+#define	RUC_ADDR_LOAD   0x0006          // (seems not to clear on acceptance)
+#define RUC_RESUMENR    0x0007
+
+#define SCB_M	        0x0100          // 0 = enable interrupt, 1 = disable
+#define SCB_SI          0x0200          // 1 - cause device to interrupt
+
+#define CU_STATUS_MASK  0x00C0
+#define RU_STATUS_MASK  0x003C
+
+#define RU_STATUS_IDLE  (0<<2)
+#define RU_STATUS_SUS   (1<<2)
+#define RU_STATUS_NORES (2<<2)
+#define RU_STATUS_READY (4<<2)
+#define RU_STATUS_NO_RBDS_SUS   ((1<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2))
+
+
+
+#define MAX_MEM_RESERVED_IOCTL 1000
+
+// ------------------------------------------------------------------------
+//
+//               RECEIVE FRAME DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+typedef struct rfd {
+    volatile union {
+        cyg_uint32 u32_status;         // result of receive operation
+        cyg_uint16 u16_status[2];
+    } u_status;
+    volatile cyg_uint32 link;           // offset from RU base to next RFD
+    volatile cyg_uint32 rdb_address;    // pointer to Rx data buffer
+    volatile cyg_uint32 count:14,       // number of bytes received +
+        f:1,                            //   + EOF & F flags
+        eof:1,
+            size:16;                    // size of the data buffer
+    volatile cyg_uint8 buffer[0];       // data buffer (simple mode)
+} RFD;
+
+// The status is split into two shorts to get atomic access to the EL bit;
+// the upper word is not written by the device, so we can just hit it,
+// leaving the lower word (which the device updates) alone.  Otherwise
+// there's a race condition between software moving the end-of-list (EL)
+// bit round and the device writing into the previous slot.
+
+#define rxstatus    u_status.u32_status
+#define rxstatus_hi u_status.u16_status[1]
+#define rxstatus_lo u_status.u16_status[0]
+
+#define RFD_STATUS_EL   0x80000000      // 1=last RFD in RFA
+#define RFD_STATUS_S    0x40000000      // 1=suspend RU after receiving frame
+#define RFD_STATUS_H    0x00100000      // 1=RFD is a header RFD
+#define RFD_STATUS_SF   0x00080000      // 0=simplified, 1=flexible mode
+#define RFD_STATUS_C    0x00008000      // completion of received frame
+#define RFD_STATUS_OK   0x00002000      // frame received with no errors
+
+#define RFD_STATUS_HI_EL   0x8000       // 1=last RFD in RFA
+#define RFD_STATUS_HI_S    0x4000       // 1=suspend RU after receiving frame
+#define RFD_STATUS_HI_H    0x0010       // 1=RFD is a header RFD
+#define RFD_STATUS_HI_SF   0x0008       // 0=simplified, 1=flexible mode
+
+#define RFD_STATUS_LO_C    0x8000       // completion of received frame
+#define RFD_STATUS_LO_OK   0x2000       // frame received with no errors
+
+#define RFD_RX_CRC          0x00000800  // crc error
+#define RFD_RX_ALIGNMENT    0x00000400  // alignment error
+#define RFD_RX_RESOURCE     0x00000200  // out of space, no resources
+#define RFD_RX_DMA_OVER     0x00000100  // DMA overrun
+#define RFD_RX_SHORT        0x00000080  // short frame error
+#define RFD_RX_LENGTH       0x00000020  //
+#define RFD_RX_ERROR        0x00000010  // receive error
+#define RFD_RX_NO_ADR_MATCH 0x00000004  // no address match
+#define RFD_RX_IA_MATCH     0x00000002  // individual address does not match
+#define RFD_RX_TCO          0x00000001  // TCO indication
+
+
+typedef struct rbd {
+    volatile cyg_uint32 count:14,       // bytes used in buffer
+        f:1,                            // buffer has been used (filled)
+        eof:1;                          // last receive buffer in frame
+    volatile cyg_uint32 next_rbd;       // next RBD (RU base relative)
+    volatile cyg_uint32 buffer_address; // address of receive data buffer
+    volatile cyg_uint32 size:15,        // size of the associated buffer
+        el:1;                           // buffer of this RBD is last
+} RBD;
+
+
+// ------------------------------------------------------------------------
+//
+//               TRANSMIT FRAME DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+typedef struct txcb {
+    volatile cyg_uint32 txstatus:16,      // result of transmit operation
+        command:16;                     // transmit command
+    volatile cyg_uint32 link;           // offset from RU base to next RFD
+    volatile cyg_uint32 tbd_address;    // pointer to Rx data buffer
+    volatile cyg_uint32 count:15,       // number of bytes in transmit buffer
+        eof:1,
+        tx_threshold:8,
+        tbd_number:8;
+    volatile cyg_uint8 buffer[0];       // data buffer (simple mode)
+} TxCB;
+
+
+#define TxCB_CMD_TRANSMIT   0x0004      // transmit command
+#define TxCB_CMD_SF         0x0008      // 0=simplified, 1=flexible mode
+#define TxCB_CMD_NC         0x0010      // 0=CRC insert by controller
+#define TxCB_CMD_I          0x2000      // generate interrupt on completion
+#define TxCB_CMD_S          0x4000      // suspend on completion
+#define TxCB_CMD_EL         0x8000      // last command block in CBL
+
+
+// ------------------------------------------------------------------------
+//
+//                   STRUCTURES ADDED FOR PROMISCUOUS MODE
+//
+// ------------------------------------------------------------------------
+typedef struct {
+    cyg_uint32 cb_status_word:13,
+        cb_ok:1,
+        cb_dc:1,
+        cb_complete:1,
+        cb_cmd:3,
+        cb_cmd_word:10,
+        cb_int:1,
+        cb_suspend:1,
+        cb_el:1;
+    cyg_uint32 cb_link_offset;
+} CB_STRUCT;
+
+
+typedef struct {
+    CB_STRUCT cb_entry;
+    cyg_uint8 config_bytes[24];
+} CONFIG_CMD_STRUCT;
+
+// ------------------------------------------------------------------------
+//
+//                       STATISTICAL COUNTER STRUCTURE
+//
+// ------------------------------------------------------------------------
+#ifdef KEEP_STATISTICS
+STATISTICS statistics[2];
+I82559_COUNTERS i82559_counters[2];
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+//
+//                      DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+
+#define MAX_RX_PACKET_SIZE  1536        // maximum Rx packet size
+#define MAX_TX_PACKET_SIZE  1536        // maximum Tx packet size
+
+
+// This is encapsulated here so that a change to > 2 interfaces can
+// easily be accommodated.
+
+#define IF_BAD_82559( _p_ )                                     \
+    CYG_ASSERT( (&i82559[0] == (_p_)) || (&i82559[1] == (_p_)), \
+                "Bad pointer-to-i82559" );                      \
+    if ( (&i82559[0] != (_p_)) && (&i82559[1] != (_p_)) )
+
+// ------------------------------------------------------------------------
+// Instantiate the interfaces that we have:
+
+// number of interfaces
+#define MAX_82559 CYGNUM_DEVS_ETH_ARM_INTEGRATOR_DEV_COUNT 
+
+I82559 i82559[MAX_82559];               // i82559 device info. structure
+
+// eth0
+
+ETH_DRV_SC(integrator_sc0,
+           &i82559[0],                  // Driver specific data
+           "eth0",                      // Name for this interface
+           i82559_start,
+           i82559_stop,
+           i82559_ioctl,
+           i82559_can_send,
+           i82559_send,
+           i82559_recv,
+           i82559_deliver,
+           i82559_poll,
+           i82559_int_vector);
+
+NETDEVTAB_ENTRY(integrator_netdev0, 
+                "integrator-0", 
+                integrator_i82559_init, 
+                &integrator_sc0);
+
+#if (MAX_82559 > 1)
+
+// eth1
+
+ETH_DRV_SC(integrator_sc1,
+           &i82559[1],                  // Driver specific data
+           "eth1",                      // Name for this interface
+           i82559_start,
+           i82559_stop,
+           i82559_ioctl,
+           i82559_can_send,
+           i82559_send,
+           i82559_recv,
+           i82559_deliver,
+           i82559_poll,
+           i82559_int_vector);
+
+NETDEVTAB_ENTRY(integrator_netdev1, 
+                "integrator-1", 
+                integrator_i82559_init, 
+                &integrator_sc1);
+
+#else
+int integrator_netdev1 = -1; // for asserts about valid addresses
+int integrator_sc1 = -1;
+#endif // eth1 is included
+
+// This is in a macro so that if more devices arrive it can easily be changed
+#define CHECK_NDP_SC_LINK() CYG_MACRO_START                                \
+    CYG_ASSERT( ((void *)ndp == (void *)&integrator_netdev0) ||               \
+                ((void *)ndp == (void *)&integrator_netdev1), "Bad ndp" );    \
+    CYG_ASSERT( ((void *)sc == (void *)&integrator_sc0) ||                    \
+                ((void *)sc == (void *)&integrator_sc1), "Bad sc" );          \
+    CYG_ASSERT( (void *)p_i82559 == sc->driver_private, "sc pointer bad" );\
+CYG_MACRO_END
+
+// ------------------------------------------------------------------------
+//
+// Managing the memory that is windowed onto the PCI bus
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32 i82559_heap_size;
+static cyg_uint8 *i82559_heap_base;
+static cyg_uint8 *i82559_heap_free;
+
+static void *mem_reserved_ioctl = (void*)0;
+// uncacheable memory reserved for ioctl calls
+
+static int mux_device_index = 0;
+
+// ------------------------------------------------------------------------
+//
+//                       FUNCTION PROTOTYPES
+//
+// ------------------------------------------------------------------------
+
+static int pci_init_find_82559s(void);
+
+static void i82559_reset(struct i82559* p_i82559);
+
+static void InitRxRing(struct i82559* p_i82559);
+static void ResetRxRing(struct i82559* p_i82559);
+static void InitTxRing(struct i82559* p_i82559);
+static void ResetTxRing(struct i82559* p_i82559);
+
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+static void program_eeprom(cyg_uint32 , cyg_uint32 , cyg_uint8 * );
+#endif
+#ifdef CYGPKG_NET
+static int eth_set_promiscuous_mode(struct i82559* p_i82559);
+#endif
+
+// debugging/logging only:
+void dump_txcb(TxCB *p_txcb);
+void DisplayStatistics(void);
+void update_statistics(struct i82559* p_i82559);
+void dump_rfd(RFD *p_rfd, int anyway );
+void dump_all_rfds( int intf );
+void dump_packet(cyg_uint8 *p_buffer, int length);
+
+// ------------------------------------------------------------------------
+// utilities
+// ------------------------------------------------------------------------
+
+static // inline
+void wait_for_cmd_done(long scb_ioaddr)
+{
+    register int CSRstatus;
+    register int wait = 0x100000;
+    do CSRstatus = INB(scb_ioaddr + SCBCmd) ;
+    while( CSRstatus && --wait >= 0);
+    CYG_ASSERT( wait > 0, "wait_for_cmd_done" );
+}
+
+static inline void Mask82559Interrupt(struct i82559* p_i82559)
+{
+    cyg_drv_interrupt_mask(p_i82559->vector);
+}
+
+static inline void UnMask82559Interrupt(struct i82559* p_i82559)
+{
+    cyg_drv_interrupt_unmask(p_i82559->vector);
+}
+
+#ifdef CYGDBG_USE_ASSERTS // an indication of a debug build
+static int acknowledge82559interrupt_compensating = 0;
+#endif
+
+static void Acknowledge82559Interrupt(struct i82559* p_i82559)
+{
+    cyg_uint32 sources, mask;
+    cyg_uint32 ioaddr;
+    cyg_uint16 status;
+    int loops = 64;
+
+    cyg_drv_interrupt_acknowledge(p_i82559->vector);
+
+    // It appears that some time can be taken before the interrupt source
+    // *really* quietens down... this is ugly, but effective.
+    // Without it, we get "Spurious Interrupt!" failures.
+    ioaddr = p_i82559->io_address; // get I/O address for 82559
+    mask = (1 << p_i82559->vector); // Do not include the MUX vector or we
+    sources = *(cyg_uint32 *)INTEGRATOR_IRQCONT_IRQSTATUS; //...get hung on the other 82559
+    status = INW(ioaddr + SCBStatus);
+
+    while ( ((0 != (sources & mask)) || (0 != (status & SCB_INTACK_MASK)))
+            && --loops >= 0) {
+        OUTW( status & SCB_INTACK_MASK, ioaddr + SCBStatus);
+        cyg_drv_interrupt_acknowledge(p_i82559->vector);
+
+#ifdef CYGDBG_USE_ASSERTS
+        acknowledge82559interrupt_compensating++; // verify this is executed
+#endif
+        sources = *(cyg_uint32 *)INTEGRATOR_IRQCONT_IRQSTATUS;
+        status = INW(ioaddr + SCBStatus);
+    }
+    CYG_ASSERT( loops >= 0, "Acknowledge82559Interrupt" );
+}
+
+
+static void udelay(int delay)
+{
+  int i;
+  // the loop is going to take 3 ticks.  At 228 MHz, to give uS, multiply
+  // by 228/3 = 76 near enough.  No volatile is needed on i; gcc recognizes
+  // delay loops and does NOT elide them.
+  for ( i = 76 * delay; i ; i--)
+    ;
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+
+static void *pciwindow_mem_alloc(int size)
+{
+    void *p_memory;
+
+    CYG_ASSERT(
+        (CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_BASE <= (int)i82559_heap_free)
+        &&
+        ((CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_BASE + 
+          CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_SIZE) > (int)i82559_heap_free)
+        &&
+        (0 < i82559_heap_size)
+        &&
+        (CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_SIZE >= i82559_heap_size)
+        &&
+        (CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_BASE == (int)i82559_heap_base),
+        "Heap variables corrupted" );
+
+    p_memory = (void *)0;
+    size = (size + 3) & ~3;
+    if ( (i82559_heap_free + size) < (i82559_heap_base + i82559_heap_size) ) {
+        cyg_uint32 *p;
+        p_memory = (void *)i82559_heap_free;
+        i82559_heap_free += size;
+        for ( p = (cyg_uint32 *)p_memory; size > 0; size -= 4 )
+            *p++ = 0;
+    }
+
+    return p_memory;
+}
+
+// ------------------------------------------------------------------------
+//
+//                       GET EEPROM SIZE
+//
+// ------------------------------------------------------------------------
+static int get_eeprom_size(long ioaddr)
+{
+    unsigned short retval = 0;
+    int ee_addr = ioaddr + SCBeeprom;
+    int i, addrbits;
+
+    // Should already be not-selected, but anyway:
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay(EEPROM_ENABLE_DELAY);
+    OUTW(EE_ENB, ee_addr);
+    eeprom_delay(EEPROM_ENABLE_DELAY);
+    
+    // Shift the read command bits out.
+    for (i = 2; i >= 0; i--) {
+        short dataval = (6 & (1 << i)) ? EE_DATA_WRITE : 0;
+        OUTW(EE_ENB | dataval               , ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB | dataval               , ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+    }
+    // Now clock out address zero, looking for the dummy 0 data bit
+    for ( i = 1; i <= 12; i++ ) {
+        OUTW(EE_ENB               , ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB               , ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        retval = INW(ee_addr) & EE_DATA_READ;
+        if ( 0 == retval )
+            break; // The dummy zero est arrive'
+    }
+
+#ifdef DEBUG_EE
+    os_printf( "eeprom data bits %d (ioaddr %x)\n", i, ee_addr );
+#endif
+    if ( 6 != i && 8 != i ) {
+#ifdef DEBUG_EE
+        os_printf( "*****EEPROM data bits not 6 or 8*****\n" );
+#endif
+        i = 6;
+    }
+    addrbits = i;
+
+    // clear the dataval, leave the clock low to read in the data regardless
+    OUTW(EE_ENB, ee_addr);
+    eeprom_delay(1);
+    
+    retval = INW(ee_addr);
+    if ( (EE_DATA_READ & retval) != 0 ) {
+#ifdef DEBUG_EE
+        os_printf( "Size EEPROM: Dummy data bit not 0, reg %x\n" , retval );
+#endif
+    }
+    eeprom_delay(1);
+    
+    for (i = EE_TOP_DATA_BIT; i >= 0; i--) {
+        OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        retval = INW(ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+    }
+    
+    // Terminate the EEPROM access.
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay(EEPROM_DONE_DELAY);
+    
+    return addrbits;
+}
+
+
+// ------------------------------------------------------------------------
+//
+//                       READ EEPROM
+//
+// ------------------------------------------------------------------------
+static int read_eeprom(long ioaddr, int location, int addr_len)
+{
+    unsigned short retval = 0;
+    int ee_addr = ioaddr + SCBeeprom;
+    int read_cmd = location | EE_READ_CMD(addr_len);
+    int i, tries = 10;
+
+ try_again:
+    // Should already be not-selected, but anyway:
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay(EEPROM_ENABLE_DELAY);
+    OUTW(EE_ENB, ee_addr);
+    eeprom_delay(EEPROM_ENABLE_DELAY);
+    
+    // Shift the read command bits out, changing only one bit per time.
+    for (i = EE_TOP_CMD_BIT(addr_len); i >= 0; i--) {
+        short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+        OUTW(EE_ENB | dataval               , ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB | dataval               , ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+    }
+
+    // clear the dataval, leave the clock low
+    OUTW(EE_ENB, ee_addr);
+    eeprom_delay(1);
+    
+    retval = INW(ee_addr);
+    // This should show a zero in the data read bit to confirm that the
+    // address transfer is compelete.  If not, go to the start and try
+    // again!
+    if ( (0 != (retval & EE_DATA_READ)) && (tries-- > 0) ) {
+    // Terminate the EEPROM access.
+        OUTW(EE_ENB & ~EE_CS, ee_addr);
+        eeprom_delay(EEPROM_DONE_DELAY);
+#ifdef DEBUG_EE
+        os_printf( "Warning: Retrying EEPROM read word %d, address %x, try %d\n",
+                   location,  ee_addr, tries+1 );
+#endif
+        goto try_again;
+    }
+
+    // This fires with one device on one of the customer boards!
+    // (but is OK on all other h/w.  Worrying huh.)
+    if ( (EE_DATA_READ & retval) != 0 ) {
+#ifdef DEBUG_EE
+        os_printf( "Read EEPROM: Dummy data bit not 0, reg %x\n" , retval );
+#endif
+    }
+    eeprom_delay(1);
+    retval = 0;
+
+    for (i = EE_TOP_DATA_BIT; i >= 0; i--) {
+        OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+        retval = (retval << 1) | ((INW(ee_addr) & EE_DATA_READ) ? 1 : 0);
+        eeprom_delay(EEPROM_SK_DELAY);
+        OUTW(EE_ENB, ee_addr);
+        eeprom_delay(EEPROM_SK_DELAY);
+    }
+    
+    // Terminate the EEPROM access.
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay(EEPROM_DONE_DELAY);
+    
+    return retval;
+}
+
+
+// ------------------------------------------------------------------------
+//
+//                NETWORK INTERFACE INITIALIZATION
+//
+//  Function : Init82559
+//
+//  Description :
+//       This routine resets, configures, and initializes the chip.
+//       It also clears the ethernet statistics structure, and selects
+//       which statistics are supported by this driver.
+//
+// ------------------------------------------------------------------------
+static bool
+integrator_i82559_init(struct cyg_netdevtab_entry * ndp)
+{
+    static int initialized = 0; // only probe PCI et al *once*
+
+    struct eth_drv_sc *sc;
+    cyg_uint32 selftest;
+    volatile cyg_uint32 *p_selftest;
+    cyg_uint32 ioaddr;
+    cyg_uint16 checksum;
+    int count;
+    int i;
+    int addr_length;
+    cyg_uint8 mac_address[6];
+    struct i82559 *p_i82559;
+
+#ifdef DEBUG
+    db_printf("integrator_i82559_init\n");
+#endif
+
+    sc = (struct eth_drv_sc *)(ndp->device_instance);
+    p_i82559 = (struct i82559 *)(sc->driver_private);
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "Bad device private pointer %x\n", sc->driver_private );
+#endif
+        return 0;
+    }
+
+    CHECK_NDP_SC_LINK();
+
+    if ( 0 == initialized++ ) {
+        // then this is the first time ever:
+        if ( ! pci_init_find_82559s() ) {
+#ifdef DEBUG
+            os_printf( "pci_init_find_82559s failed" );
+#endif
+            return 0;
+        }
+    }
+
+    if ( ! p_i82559->found ) // no device on PCI bus
+        return (0);
+
+    ioaddr = p_i82559->io_address; // get I/O address for 82559
+
+#ifdef DEBUG
+    os_printf("Init82559 %d @ %x\n82559 Self Test\n",
+              p_i82559->index, (int)ndp);
+#endif
+
+    Mask82559Interrupt(p_i82559);
+
+    wait_for_cmd_done(ioaddr); // make sure no command operating
+
+    i82559_reset(p_i82559);
+
+    // Perform a system self-test. (get enough mem to round address)
+    if ( (selftest = (cyg_uint32)pciwindow_mem_alloc(32) ) == 0)
+        return (0);
+
+    p_selftest = (cyg_uint32 *) ((selftest + 15) & ~0xf);
+    p_selftest[0] = p_selftest[1] = -1;
+
+    OUTL( (VIRT_TO_BUS(p_selftest)) | I82559_SELFTEST, ioaddr + SCBPort);
+    count = 0x7FFFF;                // Timeout for self-test.
+    do {
+        udelay(10);
+    } while ( (p_selftest[1] == -1)  &&  (--count >= 0) );
+
+    Acknowledge82559Interrupt(p_i82559);
+    UnMask82559Interrupt(p_i82559);
+    
+    if (count < 0) {
+        // Test timed out.
+#ifdef DEBUG
+        os_printf("Self test failed\n");
+#endif
+        return (0);
+    }
+#ifdef DEBUG
+    os_printf("  General self-test: %s.\n"
+              "  Serial sub-system self-test: %s.\n"
+              "  Internal registers self-test: %s.\n"
+              "  ROM checksum self-test: %s (%08X).\n",
+              p_selftest[1] & 0x1000 ? "failed" : "passed",
+              p_selftest[1] & 0x0020 ? "failed" : "passed",
+              p_selftest[1] & 0x0008 ? "failed" : "passed",
+              p_selftest[1] & 0x0004 ? "failed" : "passed",
+              p_selftest[0]);
+#endif
+
+    // read eeprom and get 82559's mac address
+    addr_length = get_eeprom_size(ioaddr);
+    // (this is the length of the *EEPROM*s address, not MAC address)
+
+    for (checksum = 0, i = 0, count = 0; count < 64; count++) {
+        cyg_uint16 value;
+        // read word from eeprom
+        value = read_eeprom(ioaddr, count, addr_length);
+#ifdef DEBUG_EE
+        // os_printf( "%2d: %04x\n", count, value );
+#endif
+        checksum += value;
+        if (count < 3) {
+            mac_address[i++] = value & 0xFF;
+            mac_address[i++] = (value >> 8) & 0xFF;
+        }
+    }
+
+    // If the EEPROM checksum is wrong, the MAC address read from the
+    // EEPROM is probably wrong as well. In that case, we don't set
+    // mac_addr_ok, but continue the initialization. If then somebody calls
+    // i82559_start without calling eth_set_mac_address() first, we refuse
+    // to bring up the interface, because running with an invalid MAC
+    // address is not a very brilliant idea.
+
+    if ((checksum & 0xFFFF) != 0xBABA)  {
+        // selftest verified checksum, verify again
+#ifdef DEBUG_EE
+        os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n",
+                   checksum, p_i82559->index);
+#endif
+    } else {
+        p_i82559->mac_addr_ok = 1;
+#ifdef DEBUG_EE
+        os_printf("Valid EEPROM checksum %x\n", checksum);
+#endif
+    }
+#ifdef DEBUG
+    os_printf("MAC Address = %02X %02X %02X %02X %02X %02X\n",
+              mac_address[0], mac_address[1], mac_address[2], mac_address[3],
+              mac_address[4], mac_address[5]);
+#endif
+
+    // record the MAC address in the device structure
+    p_i82559->mac_address[0] = mac_address[0];
+    p_i82559->mac_address[1] = mac_address[1];
+    p_i82559->mac_address[2] = mac_address[2];
+    p_i82559->mac_address[3] = mac_address[3];
+    p_i82559->mac_address[4] = mac_address[4];
+    p_i82559->mac_address[5] = mac_address[5];
+    
+    // and record the net dev pointer
+    p_i82559->ndp = (void *)ndp;
+    
+    InitRxRing(p_i82559);
+    InitTxRing(p_i82559);
+
+    // Initialize upper level driver
+    if ( p_i82559->mac_addr_ok )
+        (sc->funs->eth_drv->init)(sc, &(p_i82559->mac_address[0]) );
+    else
+        (sc->funs->eth_drv->init)(sc, 0 );
+
+    return (1);
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : i82559_start
+//
+// ------------------------------------------------------------------------
+static void i82559_start( struct eth_drv_sc *sc,
+                          unsigned char *enaddr, int flags )
+{
+    struct i82559 *p_i82559;
+    cyg_uint32 ioaddr;
+#ifdef KEEP_STATISTICS
+    void *p_statistics;
+#endif
+#ifdef CYGPKG_NET
+    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+
+    p_i82559 = (struct i82559 *)sc->driver_private;
+    
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_start: Bad device pointer %x\n", p_i82559 );
+#endif
+        return;
+    }
+
+    if ( ! p_i82559->mac_addr_ok ) {
+#ifdef DEBUG
+        os_printf("i82559_start %d: invalid MAC address, "
+                  "can't bring up interface\n",
+                  p_i82559->index );
+#endif
+        return;
+    }
+
+    if ( p_i82559->active )
+        i82559_stop( sc );
+
+    ioaddr = p_i82559->io_address; // get 82559's I/O address
+
+#ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_82559_STATISTICS
+    p_i82559->p_statistics =
+        p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS));
+    memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS));
+    wait_for_cmd_done(ioaddr); // make sure no command operating
+                                        // set statistics dump address
+    OUTL(VIRT_TO_BUS(p_statistics), ioaddr + SCBPointer);
+    OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd);
+
+    wait_for_cmd_done(ioaddr); // make sure no command operating
+    OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump
+#endif
+#endif
+
+    // Set the base address
+    wait_for_cmd_done(ioaddr);
+    OUTL(0, ioaddr + SCBPointer);       // load ru base address = 0
+    OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd);
+    udelay( 1000 );                     // load pointer to Rx Ring
+    OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer);
+    OUTW(RUC_START, ioaddr + SCBCmd);
+    
+    p_i82559->active = 1;
+
+#ifdef CYGPKG_NET
+    if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+         != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+        ) || (ifp->if_flags & IFF_PROMISC)
+        ) {
+        eth_set_promiscuous_mode(p_i82559);
+    }
+#endif
+
+#ifdef DEBUG
+    {
+        int status = i82559_status( sc );
+        os_printf("i82559_start %d flg %x Link = %s, %s Mbps, %s Duplex\n",
+                  p_i82559->index,
+                  *(int *)p_i82559,
+                  status & GEN_STATUS_LINK ? "Up" : "Down",
+                  status & GEN_STATUS_100MBPS ?  "100" : "10",
+                  status & GEN_STATUS_FDX ? "Full" : "Half");
+    }
+#endif
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : i82559_status
+//
+// ------------------------------------------------------------------------
+int i82559_status( struct eth_drv_sc *sc )
+{
+    int status;
+    struct i82559 *p_i82559;
+    cyg_uint32 ioaddr;
+    p_i82559 = (struct i82559 *)sc->driver_private;
+    
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_status: Bad device pointer %x\n", p_i82559 );
+#endif
+        return 0;
+    }
+
+    ioaddr = p_i82559->io_address; // get 82559's I/O address
+
+    status = INB(ioaddr + SCBGenStatus);
+
+    return status;
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : BringDown82559
+//
+// ------------------------------------------------------------------------
+
+static void i82559_stop( struct eth_drv_sc *sc )
+{
+    struct i82559 *p_i82559;
+
+    p_i82559 = (struct i82559 *)sc->driver_private;
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_stop: Bad device pointer %x\n", p_i82559 );
+#endif
+        return;
+    }
+   
+#ifdef DEBUG
+    os_printf("i82559_stop %d flg %x\n", p_i82559->index, *(int *)p_i82559 );
+#endif
+
+    p_i82559->active = 0;               // stop people tormenting it
+    i82559_reset(p_i82559);             // that should stop it
+
+    ResetRxRing( p_i82559 );
+    ResetTxRing( p_i82559 );
+}
+
+
+// ------------------------------------------------------------------------
+//
+//  Function : InitRxRing
+//
+// ------------------------------------------------------------------------
+static void InitRxRing(struct i82559* p_i82559)
+{
+    int i, j;
+    RFD *rfd;
+    RFD *p_rfd = 0;
+#ifdef DEBUG_82559
+    os_printf("InitRxRing %d\n", p_i82559->index);
+#endif
+    for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {
+        rfd = (RFD *)pciwindow_mem_alloc(sizeof(RFD) + MAX_RX_PACKET_SIZE);
+        p_i82559->rx_ring[i] = rfd;
+        if ( i )
+            p_rfd->link = VIRT_TO_BUS(rfd);
+        p_rfd = (RFD *)rfd;
+    }
+    // link last RFD to first:
+    p_rfd->link = VIRT_TO_BUS(p_i82559->rx_ring[0]);
+
+    ResetRxRing( p_i82559 );
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : ResetRxRing
+//
+// ------------------------------------------------------------------------
+static void ResetRxRing(struct i82559* p_i82559)
+{
+    RFD *p_rfd;
+    int i;
+#ifdef DEBUG_82559
+    os_printf("ResetRxRing %d\n", p_i82559->index);
+#endif
+    for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {
+        p_rfd = p_i82559->rx_ring[i];
+        CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+        CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
+        CYG_ASSERT( p_i82559->rx_ring[
+                 ( i ? (i-1) : (MAX_RX_DESCRIPTORS-1) )
+            ]->link == VIRT_TO_BUS(p_rfd), "rfd linked list broken" );
+        p_rfd->rxstatus = 0;
+        p_rfd->count = 0;
+        p_rfd->f = 0;
+        p_rfd->eof = 0;
+        p_rfd->rdb_address = 0xFFFFFFFF;
+        p_rfd->size = MAX_RX_PACKET_SIZE;
+    }
+    p_i82559->next_rx_descriptor = 0;
+    // And set an end-of-list marker in the previous one.
+    p_rfd->rxstatus = RFD_STATUS_EL;
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : PacketRxReady        (Called from delivery thread)
+//
+// ------------------------------------------------------------------------
+static void PacketRxReady(struct i82559* p_i82559)
+{
+    RFD *p_rfd;
+    int next_descriptor;
+    int length;
+    struct cyg_netdevtab_entry *ndp;
+    struct eth_drv_sc *sc;
+    cyg_uint32 ioaddr;
+    cyg_uint16 status;
+
+    ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+    sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+    CHECK_NDP_SC_LINK();
+
+    ioaddr = p_i82559->io_address;
+
+    next_descriptor = p_i82559->next_rx_descriptor;
+    p_rfd = p_i82559->rx_ring[next_descriptor];
+
+    CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+    CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
+
+    while ( p_rfd->rxstatus & RFD_STATUS_C ) {
+        p_rfd->rxstatus_hi |= RFD_STATUS_HI_EL;
+        length = p_rfd->count;
+
+#ifdef DEBUG_82559
+        os_printf( "Device %d (eth%d), rx descriptor %d:\n", 
+                   p_i82559->index, p_i82559->index, next_descriptor );
+//        dump_rfd( p_rfd, 1 );
+#endif
+
+        p_i82559->next_rx_descriptor = next_descriptor;
+        // Check for bogusly short packets; can happen in promisc mode:
+        // Asserted against and checked by upper layer driver.
+#ifdef CYGPKG_NET
+        if ( length > sizeof( struct ether_header ) )
+            // then it is acceptable; offer the data to the network stack
+#endif
+        (sc->funs->eth_drv->recv)( sc, length );
+
+        p_rfd->count = 0;
+        p_rfd->f = 0;
+        p_rfd->eof = 0;
+        p_rfd->rxstatus_lo = 0;
+
+        // The just-emptied slot is now ready for re-use and already marked EL;
+        // we can now remove the EL marker from the previous one.
+        if ( 0 == next_descriptor )
+            p_rfd = p_i82559->rx_ring[ MAX_RX_DESCRIPTORS-1 ];
+        else
+            p_rfd = p_i82559->rx_ring[ next_descriptor-1 ];
+        // The previous one: check it *was* marked before clearing.
+        CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No prev EL" );
+        p_rfd->rxstatus_hi = 0; // that word is not written by the device.
+
+#ifdef KEEP_STATISTICS
+        statistics[p_i82559->index].rx_deliver++;
+#endif
+        if (++next_descriptor >= MAX_RX_DESCRIPTORS)
+            next_descriptor = 0;
+        p_rfd = p_i82559->rx_ring[next_descriptor];
+
+        CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+        CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
+    }
+
+    // See if the RU has gone idle (usually because of out of resource
+    // condition) and restart it if needs be.
+    Mask82559Interrupt(p_i82559);
+    status = INW(ioaddr + SCBStatus);
+
+    if ( RU_STATUS_READY != (status & RU_STATUS_MASK) ) {
+        // Acknowledge the RX INT sources
+        OUTW( SCB_INTACK_RX, ioaddr + SCBStatus);
+        // (see pages 6-10 & 6-90)
+
+#ifdef KEEP_STATISTICS
+        statistics[p_i82559->index].rx_restart++;
+#endif
+        // There's an end-of-list marker out there somewhere...
+        // So mop it up; it takes a little time but this is infrequent.
+        ResetRxRing( p_i82559 );  
+        next_descriptor = 0;        // re-initialize next desc.
+        // wait for SCB command complete
+        wait_for_cmd_done(ioaddr);
+        // load pointer to Rx Ring
+        OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]),
+             ioaddr + SCBPointer);
+        OUTW(RUC_START, ioaddr + SCBCmd);
+        Acknowledge82559Interrupt(p_i82559);
+    }
+    UnMask82559Interrupt(p_i82559);
+
+    p_i82559->next_rx_descriptor = next_descriptor;
+}
+
+// and the callback function
+
+static void i82559_recv( struct eth_drv_sc *sc,
+                         struct eth_drv_sg *sg_list, int sg_len )
+{
+    struct i82559 *p_i82559;
+    RFD *p_rfd;
+    int next_descriptor;
+    int total_len;
+    struct eth_drv_sg *last_sg;
+    volatile cyg_uint8 *from_p;
+
+    p_i82559 = (struct i82559 *)sc->driver_private;
+    
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_recv: Bad device pointer %x\n", p_i82559 );
+#endif
+        return;
+    }
+
+    next_descriptor = p_i82559->next_rx_descriptor;
+    p_rfd = p_i82559->rx_ring[next_descriptor];
+    
+    CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+    CYG_ASSERT( (cyg_uint8 *)p_rfd <  i82559_heap_free, "rfd over" );
+
+    CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_C, "No complete frame" );
+    CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_EL, "No marked frame" );
+
+    CYG_ASSERT( p_rfd->rxstatus_lo & RFD_STATUS_LO_C, "No complete frame 2" );
+    CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No marked frame 2" );
+    
+    if ( 0 == (p_rfd->rxstatus & RFD_STATUS_C) )
+        return;
+        
+    total_len = p_rfd->count;
+    
+#ifdef DEBUG_82559
+    os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",
+              p_i82559->index, (int)p_i82559, p_rfd->rxstatus, sg_len, total_len);
+#endif
+
+    // Copy the data to the network stack
+    from_p = &p_rfd->buffer[0];
+
+    // check we have memory to copy into; we would be called even if
+    // caller was out of memory in order to maintain our state.
+    if ( 0 == sg_len || 0 == sg_list )
+        return; // caller was out of mbufs
+
+    CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+    CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+    for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+        cyg_uint8 *to_p;
+        int l;
+            
+        to_p = (cyg_uint8 *)(sg_list->buf);
+        l = sg_list->len;
+
+        CYG_ASSERT( 0 <= l, "sg length -ve" );
+
+        if ( 0 >= l || 0 == to_p )
+            return; // caller was out of mbufs
+
+        if ( l > total_len )
+            l = total_len;
+
+        memcpy( to_p, (unsigned char *)from_p, l );
+        from_p += l;
+        total_len -= l;
+    }
+
+    CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
+    CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
+    CYG_ASSERT( &p_rfd->buffer[0] < from_p, "from_p wild in rx" );
+    CYG_ASSERT( &p_rfd->buffer[0] + MAX_RX_PACKET_SIZE >= from_p,
+                "from_p overflow in rx" );
+}    
+
+
+// ------------------------------------------------------------------------
+//
+//  Function : InitTxRing
+//
+// ------------------------------------------------------------------------
+static void InitTxRing(struct i82559* p_i82559)
+{
+    int i, j;
+    cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82559
+    os_printf("InitTxRing %d\n", p_i82559->index);
+#endif
+    ioaddr = p_i82559->io_address;
+    for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) {
+        p_i82559->tx_ring[i] = (TxCB *)pciwindow_mem_alloc(
+            sizeof(TxCB) + MAX_TX_PACKET_SIZE);
+    }
+    ResetTxRing(p_i82559);
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : ResetTxRing
+//
+// ------------------------------------------------------------------------
+static void ResetTxRing(struct i82559* p_i82559)
+{
+    int i;
+    cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82559
+    os_printf("ResetTxRing %d\n", p_i82559->index);
+#endif
+    ioaddr = p_i82559->io_address;
+    p_i82559->tx_descriptor_add =
+        p_i82559->tx_descriptor_active = 
+        p_i82559->tx_descriptor_remove = 0;
+    p_i82559->tx_in_progress =
+        p_i82559->tx_queue_full = 0;
+
+    for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) {
+        TxCB *p_txcb = p_i82559->tx_ring[i];
+        CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
+        CYG_ASSERT( (cyg_uint8 *)p_txcb <  i82559_heap_free, "txcb over" );
+
+        p_txcb->txstatus = 0;
+        p_txcb->command = 0;
+        p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb);
+        p_txcb->tbd_address = 0xFFFFFFFF;
+        p_txcb->tbd_number = 0;
+        p_txcb->tx_threshold = 16;
+        p_txcb->eof = 1;
+        p_txcb->count = 0;
+        p_i82559->tx_keys[i] = 0;
+    }
+    
+    wait_for_cmd_done(ioaddr);
+    OUTL(0, ioaddr + SCBPointer);
+    OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd);
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : TxMachine          (Called from FG & ISR)
+//
+// This steps the Tx Machine onto the next record if necessary - allowing
+// for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+static void TxMachine(struct i82559* p_i82559)
+{
+    int tx_descriptor_active;
+    cyg_uint32 ioaddr;
+
+    tx_descriptor_active = p_i82559->tx_descriptor_active;
+    ioaddr = p_i82559->io_address;  
+    
+    // See if the CU is idle when we think it isn't; this is the only place
+    // tx_descriptor_active is advanced. (Also recovers from a dropped intr)
+    if ( p_i82559->tx_in_progress ) {
+        cyg_uint16 status;
+        status = INW(ioaddr + SCBStatus);
+        if ( 0 == (status & CU_STATUS_MASK) ) {
+            // It is idle.  So ack the TX interrupts
+            OUTW( SCB_INTACK_TX, ioaddr + SCBStatus);
+            // (see pages 6-10 & 6-90)
+
+            // and step on to the next queued tx.
+            p_i82559->tx_in_progress = 0;
+            if ( ++tx_descriptor_active >= MAX_TX_DESCRIPTORS )
+                tx_descriptor_active = 0;
+            p_i82559->tx_descriptor_active = tx_descriptor_active;
+        }
+    }
+
+    // is the CU idle, and there a next tx to set going?
+    if ( ( ! p_i82559->tx_in_progress )
+         && p_i82559->tx_descriptor_add != tx_descriptor_active ) {
+        TxCB *p_txcb;
+        p_txcb = p_i82559->tx_ring[tx_descriptor_active];
+        CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
+        CYG_ASSERT( (cyg_uint8 *)p_txcb <  i82559_heap_free, "txcb over" );
+#ifdef DEBUG_82559
+        os_printf("Tx %d %x: Starting Engines\n",
+                  p_i82559->index, (int)p_i82559);
+#endif
+        // make sure no command operating
+        wait_for_cmd_done(ioaddr); 
+        // start Tx operation
+        OUTL(VIRT_TO_BUS(p_txcb), ioaddr + SCBPointer);
+        OUTW(CU_START, ioaddr + SCBCmd);
+        p_i82559->tx_in_progress = 1;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : TxDone          (Called from delivery thread)
+//
+// This returns Tx's from the Tx Machine to the stack (ie. reports
+// completion) - allowing for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+static void TxDone(struct i82559* p_i82559)
+{
+    struct cyg_netdevtab_entry *ndp;
+    struct eth_drv_sc *sc;
+    int tx_descriptor_remove = p_i82559->tx_descriptor_remove;
+
+    ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+    sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+    CHECK_NDP_SC_LINK();
+
+    // "Done" txen are from here to active, OR 
+    // the remove one if the queue is full AND its status is nonzero:
+    while (  (tx_descriptor_remove != p_i82559->tx_descriptor_active) ||
+             ( p_i82559->tx_queue_full &&
+              (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->txstatus) ) ) {
+        unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ];
+#ifdef DEBUG_82559
+        os_printf("TxDone %d %x: KEY %x\n",
+                  p_i82559->index, (int)p_i82559, key );
+#endif
+        (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ );
+        
+        if ( ++tx_descriptor_remove >= MAX_TX_DESCRIPTORS )
+            tx_descriptor_remove = 0;
+        p_i82559->tx_descriptor_remove = tx_descriptor_remove;
+        p_i82559->tx_queue_full = 0;
+    }
+}
+
+
+// ------------------------------------------------------------------------
+//
+//  Function : i82559_can_send
+//
+// ------------------------------------------------------------------------
+
+static int 
+i82559_can_send(struct eth_drv_sc *sc)
+{
+    struct i82559 *p_i82559;
+
+    p_i82559 = (struct i82559 *)sc->driver_private;
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 );
+#endif
+        return 0;
+    }
+    
+    // Advance TxMachine atomically
+    Mask82559Interrupt(p_i82559);
+    TxMachine(p_i82559);
+    Acknowledge82559Interrupt(p_i82559);
+    PacketRxReady(p_i82559);		/* FIX: 16/07/01 added from ebsa */
+    UnMask82559Interrupt(p_i82559);
+
+    return ! p_i82559->tx_queue_full;
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : i82559_send
+//
+// ------------------------------------------------------------------------
+
+static void
+i82559_send(struct eth_drv_sc *sc,
+            struct eth_drv_sg *sg_list, int sg_len, int total_len,
+            unsigned long key)
+{
+    struct i82559 *p_i82559;
+    int tx_descriptor_add;
+    TxCB *p_txcb;
+    cyg_uint32 ioaddr;
+
+    p_i82559 = (struct i82559 *)sc->driver_private;
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 );
+#endif
+        return;
+    }
+
+#ifdef DEBUG_82559
+    os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x = %d\n",
+              p_i82559->index, (int)p_i82559, sg_len, total_len, key, *(int *)key);
+#endif
+
+    if ( ! p_i82559->active )
+        return;                         // device inactive, no return
+
+#ifdef KEEP_STATISTICS
+    statistics[p_i82559->index].tx_count++;
+#endif
+    ioaddr = p_i82559->io_address;      // get device I/O address
+
+    if ( p_i82559->tx_queue_full ) {
+#ifdef KEEP_STATISTICS
+        statistics[p_i82559->index].tx_dropped++;
+#endif
+#ifdef DEBUG_82559
+        os_printf( "i82559_send: Queue full, device %x, key %x\n",
+                   p_i82559, key );
+#endif
+    } else {
+        struct eth_drv_sg *last_sg;
+        volatile cyg_uint8 *to_p;
+
+        tx_descriptor_add = p_i82559->tx_descriptor_add;
+
+        p_i82559->tx_keys[tx_descriptor_add] = key;
+
+        p_txcb = p_i82559->tx_ring[tx_descriptor_add];
+
+        CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
+        CYG_ASSERT( (cyg_uint8 *)p_txcb <  i82559_heap_free, "txcb over" );
+
+        p_txcb->txstatus = 0;
+        p_txcb->command = TxCB_CMD_TRANSMIT | TxCB_CMD_S
+                                | TxCB_CMD_I | TxCB_CMD_EL;
+        p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb);
+        p_txcb->tbd_address = 0xFFFFFFFF;
+        p_txcb->tbd_number = 0;
+        p_txcb->tx_threshold = 16;
+        p_txcb->eof = 1;
+        p_txcb->count = total_len;
+
+        // Copy from the sglist into the txcb
+        to_p = &p_txcb->buffer[0];
+
+        CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+        CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+        for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+            cyg_uint8 *from_p;
+            int l;
+            
+            from_p = (cyg_uint8 *)(sg_list->buf);
+            l = sg_list->len;
+
+            if ( l > total_len )
+                l = total_len;
+
+            memcpy( (unsigned char *)to_p, from_p, l );
+            to_p += l;
+            total_len -= l;
+
+            if ( 0 > total_len ) 
+                break; // Should exit via sg_last normally
+        }
+
+        CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
+        CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
+        CYG_ASSERT( &p_txcb->buffer[0] < to_p, "to_p wild in tx" );
+        CYG_ASSERT( &p_txcb->buffer[0] + MAX_TX_PACKET_SIZE >= to_p,
+                    "to_p overflow in tx" );
+  
+        // Next descriptor
+        if ( ++tx_descriptor_add >= MAX_TX_DESCRIPTORS)
+            tx_descriptor_add = 0;
+        p_i82559->tx_descriptor_add = tx_descriptor_add;
+
+        // From this instant, interrupts can advance the world and start,
+        // even complete, this tx request...
+
+        if ( p_i82559->tx_descriptor_remove == tx_descriptor_add )
+            p_i82559->tx_queue_full = 1;
+    }
+
+    // Try advancing the Tx Machine regardless
+
+    // no more interrupts until started
+    Mask82559Interrupt(p_i82559);
+
+    // Check that either:
+    //     tx is already active, there is other stuff queued,
+    // OR  this tx just added is the current active one
+    // OR  this tx just added is already complete
+    CYG_ASSERT(
+        // The machine is busy:
+        (p_i82559->tx_in_progress == 1) ||
+        // or: The machine is idle and this just added is the next one
+	(((p_i82559->tx_descriptor_add-1) == p_i82559->tx_descriptor_active)
+	 || ((0 == p_i82559->tx_descriptor_add) &&
+	     ((MAX_TX_DESCRIPTORS-1) == p_i82559->tx_descriptor_active))) ||
+        // or: This tx is already complete
+        (p_i82559->tx_descriptor_add == p_i82559->tx_descriptor_active),
+                "Active/add mismatch" );
+
+    // Advance TxMachine atomically
+    TxMachine(p_i82559);
+    Acknowledge82559Interrupt(p_i82559);
+    PacketRxReady(p_i82559);		/* FIX: 16/07/01 added from ebsa */
+    UnMask82559Interrupt(p_i82559);
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : i82559_reset
+//
+// ------------------------------------------------------------------------
+static void i82559_reset(struct i82559* p_i82559)
+{
+    cyg_uint32 ioaddr;
+    int count;
+
+    ioaddr = p_i82559->io_address;
+    // make sure no command operating
+    wait_for_cmd_done(ioaddr);   
+
+    OUTL(I82559_SELECTIVE_RESET, ioaddr + SCBPort);
+  
+    for (count = 10 ; count-- ; ) {
+        udelay(1000);
+    }
+
+    OUTL(I82559_RESET, ioaddr + SCBPort);
+    
+    for (count = 10 ; count-- ; ) {
+      udelay(1000);
+    }
+}
+
+
+// ------------------------------------------------------------------------
+//
+//                       INTERRUPT HANDLERS
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32 eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+    struct i82559* p_i82559 = (struct i82559 *)data;
+    cyg_uint16 status;
+    cyg_uint32 ioaddr;
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_isr: Bad device pointer %x\n", (cyg_uint8 *)p_i82559 );
+#endif
+        return 0;
+    }
+
+    ioaddr = p_i82559->io_address;
+    status = INW(ioaddr + SCBStatus);
+
+    // Acknowledge all INT sources that were active
+    OUTW( status & SCB_INTACK_MASK, ioaddr + SCBStatus);
+    // (see pages 6-10 & 6-90)
+
+#ifdef KEEP_STATISTICS
+    statistics[p_i82559->index].interrupts++;
+
+    // receiver left ready state ?
+    if ( status & SCB_STATUS_RNR )
+        statistics[p_i82559->index].rx_resource++;
+
+    // frame receive interrupt ?
+    if ( status & SCB_STATUS_FR )
+        statistics[p_i82559->index].rx_count++;
+
+    // transmit interrupt ?
+    if ( status & SCB_STATUS_CX )
+        statistics[p_i82559->index].tx_complete++;
+#endif
+
+    // Advance the Tx Machine regardless
+    TxMachine(p_i82559);
+
+    // it should have settled down now...
+    Acknowledge82559Interrupt(p_i82559);
+
+    return CYG_ISR_CALL_DSR;        // schedule DSR
+}
+
+
+// ------------------------------------------------------------------------
+static
+void eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    struct i82559* p_i82559 = (struct i82559 *)data;
+    struct cyg_netdevtab_entry *ndp =
+        (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+    struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+    // but here, it must be a *sc:
+    eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+}
+
+// ------------------------------------------------------------------------
+// This is called from the function below (used to be uni-DSR)
+static inline void
+uni_deliver(struct i82559* p_i82559)
+{
+    // First pass any rx data up the stack
+    PacketRxReady(p_i82559);
+
+    // Then scan for completed Txen and inform the stack
+    TxDone(p_i82559);
+}
+
+// ------------------------------------------------------------------------
+
+void i82559_deliver(struct eth_drv_sc *sc)
+{
+    struct i82559* p_i82559;
+    int device_index = mux_device_index;
+
+    // Since this must mux both devices, the incoming arg is ignored.
+    mux_device_index ^= 1; // look at the other one first next time.
+    do {
+        p_i82559 = &i82559[device_index];
+        if ( p_i82559->active )
+            uni_deliver( p_i82559 );
+        device_index ^= 1;
+    } while ( device_index == mux_device_index );
+}
+
+// ------------------------------------------------------------------------
+// Device table entry to operate the chip in a polled mode.
+
+void i82559_poll(struct eth_drv_sc *sc)
+{
+    struct i82559 *p_i82559;
+    p_i82559 = (struct i82559 *)sc->driver_private;
+    
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_poll: Bad device pointer %x\n", p_i82559 );
+#endif
+        return;
+    }
+/**/
+    // Do these atomically
+    Mask82559Interrupt(p_i82559);
+/**/
+    // As it happens, this driver always requests the DSR to be called:
+    (void)eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+
+    i82559_deliver( p_i82559 );
+/**/
+    Acknowledge82559Interrupt(p_i82559);
+    UnMask82559Interrupt(p_i82559);
+/**/
+}
+
+// ------------------------------------------------------------------------
+// Determine interrupt vector used by a device - for attaching GDB stubs
+// packet handler.
+int
+i82559_int_vector(struct eth_drv_sc *sc)
+{
+    struct i82559 *p_i82559;
+    p_i82559 = (struct i82559 *)sc->driver_private;
+    return (p_i82559->vector);
+}
+
+// ------------------------------------------------------------------------
+//
+//  Function : pci_init_find_82559s
+//
+// This is called exactly once at the start of time to:
+//  o scan the PCI bus for objects
+//  o record them in the device table
+//  o acquire all the info needed for the driver to access them
+//  o instantiate interrupts for them
+//  o attach those interrupts appropriately
+// ------------------------------------------------------------------------
+static int
+pci_init_find_82559s( void )
+{
+    cyg_pci_device_id devid;
+    cyg_pci_device dev_info;
+    cyg_uint16 cmd;
+    int device_index;
+
+#ifdef DEBUG
+    db_printf("pci_init_find_82559s()\n");
+#endif
+
+    // allocate memory to be used in ioctls later
+    if (mem_reserved_ioctl != (void*)0) {
+#ifdef DEBUG
+        db_printf("pci_init_find_82559s() called > once\n");
+#endif
+        return 0;
+    }
+
+    // First initialize the heap in PCI window'd memory
+    i82559_heap_size = CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_SIZE;
+    i82559_heap_base = (cyg_uint8 *)CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_BASE;
+    i82559_heap_free = i82559_heap_base;
+
+    mem_reserved_ioctl = pciwindow_mem_alloc(MAX_MEM_RESERVED_IOCTL);     
+
+    cyg_pci_init();
+
+    devid = CYG_PCI_NULL_DEVID;
+
+    for (device_index = 0; device_index < MAX_82559; device_index++) {
+        struct i82559 *p_i82559 = &i82559[device_index];
+        p_i82559->index = device_index;
+
+        if (cyg_pci_find_device(0x8086, 0x1229, &devid) ) {
+#ifdef DEBUG
+            db_printf("eth%d = 82559\n", device_index);
+#endif
+            cyg_pci_get_device_info(devid, &dev_info);
+
+            if (cyg_pci_translate_interrupt(&dev_info, &p_i82559->vector)) {
+#ifdef DEBUG
+                db_printf(" Wired to HAL vector %d\n", p_i82559->vector);
+#endif
+                cyg_drv_interrupt_create(
+                    p_i82559->vector,
+                    0,                  // Priority - unused
+                    (CYG_ADDRWORD)p_i82559, // Data item passed to ISR & DSR
+                    eth_isr,            // ISR
+                    eth_dsr,            // DSR
+                    &p_i82559->interrupt_handle, // handle to intr obj
+                    &p_i82559->interrupt_object ); // space for int obj
+
+                cyg_drv_interrupt_attach(p_i82559->interrupt_handle);
+
+                // Don't unmask the interrupt yet, that could get us into a
+                // race.
+            } else {
+                p_i82559->vector=0;
+#ifdef DEBUG
+                db_printf(" Does not generate interrupts.\n");
+#endif
+            }
+
+            if (cyg_pci_configure_device(&dev_info)) {
+#ifdef DEBUG
+                int i;
+                db_printf("Found device on bus %d, devfn 0x%02x:\n",
+                          CYG_PCI_DEV_GET_BUS(devid),
+                          CYG_PCI_DEV_GET_DEVFN(devid));
+
+                if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+                    db_printf(" Note that board is active. Probed"
+                              " sizes and CPU addresses invalid!\n");
+                }
+                db_printf(" Vendor    0x%04x", dev_info.vendor);
+                db_printf("\n Device    0x%04x", dev_info.device);
+                db_printf("\n Command   0x%04x, Status 0x%04x\n",
+                          dev_info.command, dev_info.status);
+                
+                db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+                db_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+                db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+                          dev_info.header.normal.sub_vendor, 
+                          dev_info.header.normal.sub_id);
+
+                for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+                    db_printf(" BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
+                    db_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+                              dev_info.base_size[i], dev_info.base_map[i]);
+                }
+                db_printf(" eth%d configured\n", device_index);
+#endif
+                p_i82559->found = 1;
+                p_i82559->active = 0;
+                p_i82559->devid = devid;
+                p_i82559->memory_address = dev_info.base_map[0];
+                p_i82559->io_address = dev_info.base_map[1];
+#ifdef DEBUG
+                db_printf(" memory address = 0x%08x\n", dev_info.base_map[0]);
+                db_printf(" I/O address = 0x%08x\n", dev_info.base_map[1]);
+#endif
+
+                // Don't use cyg_pci_set_device_info since it clears
+                // some of the fields we want to print out below.
+                cyg_pci_read_config_uint16(dev_info.devid, CYG_PCI_CFG_COMMAND, &cmd);
+                cmd |= CYG_PCI_CFG_COMMAND_IO // enable I/O space
+                    | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
+                    | CYG_PCI_CFG_COMMAND_MASTER; // enable bus master
+                cyg_pci_write_config_uint16(dev_info.devid, CYG_PCI_CFG_COMMAND, cmd);
+
+                // Now the PCI part of the device is configured, reset it. This 
+                // should make it safe to enable the interrupt
+                i82559_reset(p_i82559);
+
+                if (p_i82559->vector != 0) {
+                    cyg_drv_interrupt_acknowledge(p_i82559->vector);
+                    cyg_drv_interrupt_unmask(p_i82559->vector);
+                }
+#ifdef DEBUG
+                db_printf(" **** Device enabled for I/O and Memory and Bus Master\n");
+#endif
+            }
+            else {
+                p_i82559->found = 0;
+                p_i82559->active = 0;
+#ifdef DEBUG
+                db_printf("Failed to configure device %d\n",device_index);
+#endif
+            }
+        }
+        else {
+            p_i82559->found = 0;
+            p_i82559->active = 0;
+#ifdef DEBUG
+            db_printf("eth%d not found\n", device_index);
+#endif
+        }
+    }
+
+    // Now a delay to ensure the hardware has "come up" before you try to
+    // use it.  Yes, really, the full 2 seconds.  It's only really
+    // necessary if DEBUG is off - otherwise all that printout wastes
+    // enough time.  No kidding.
+    udelay( 20000 );
+    return 1;
+}
+
+#ifdef CYGPKG_NET
+// ------------------------------------------------------------------------
+//
+//  Function : eth_set_promiscuous_mode
+//
+//  Return : 0 = It worked.
+//           non0 = It failed.
+// ------------------------------------------------------------------------
+
+static int eth_set_promiscuous_mode(struct i82559* p_i82559)
+{
+    cyg_uint32  ioaddr;
+    volatile CONFIG_CMD_STRUCT *ccs;
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "eth_set_promiscuos_mode: Bad device pointer %x\n",
+                   p_i82559 );
+#endif
+        return -1;
+    }
+
+    ioaddr = p_i82559->io_address;  
+    wait_for_cmd_done(ioaddr); 
+    // load cu base address = 0 */ 
+    OUTL(0, ioaddr + SCBPointer);         
+    // 32 bit linear addressing used
+                                        
+    OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd);
+    // wait for SCB command complete
+    wait_for_cmd_done(ioaddr);   
+  
+    ccs = (CONFIG_CMD_STRUCT *)mem_reserved_ioctl;
+  
+    // Check the malloc we did earlier worked
+    if (ccs == (void*)0) 
+        return 2; // Failed
+  
+    ccs->cb_entry.cb_cmd=0x2;
+    ccs->cb_entry.cb_cmd_word=0x0;
+    ccs->cb_entry.cb_status_word=0x0;
+    ccs->cb_entry.cb_int=0;
+    ccs->cb_entry.cb_suspend=1;
+    ccs->cb_entry.cb_el=1;
+    ccs->cb_entry.cb_complete=0;
+    ccs->cb_entry.cb_link_offset=VIRT_TO_BUS((cyg_uint32)&ccs);
+    
+    // Default values from the Intel Manual
+    ccs->config_bytes[0]=0x13;
+    ccs->config_bytes[1]=0x8;
+    ccs->config_bytes[2]=0x0;
+    ccs->config_bytes[3]=0x0;
+    ccs->config_bytes[4]=0x0;
+    ccs->config_bytes[5]=0x0;
+    ccs->config_bytes[6]=0xb2; // (promisc ? 0x80 : 0) | 0x32 for small stats,
+    ccs->config_bytes[7]=0x0;  // \      ditto         | 0x12 for stats with PAUSE stats
+    ccs->config_bytes[8]=0x0;  //  \     ditto         | 0x16 for PAUSE + TCO stats
+    ccs->config_bytes[9]=0x0;
+    ccs->config_bytes[10]=0x28;
+    ccs->config_bytes[11]=0x0;
+    ccs->config_bytes[12]=0x60;
+    ccs->config_bytes[13]=0x0;          // arp
+    ccs->config_bytes[14]=0x0;          // arp
+    
+    ccs->config_bytes[15]=0x81;         // promiscuous mode set
+                                        // \ or 0x80 for normal mode.
+    ccs->config_bytes[16]=0x0;
+    ccs->config_bytes[17]=0x40;
+    ccs->config_bytes[18]=0x72;         // Keep the Padding Enable bit
+    
+    // wait for SCB command complete
+    wait_for_cmd_done(ioaddr);   
+    
+    OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer); 
+    OUTW(SCB_M | CU_START, ioaddr + SCBCmd);    
+  
+    udelay(10000);
+
+    // now check for result ...
+    wait_for_cmd_done(ioaddr);   
+  
+    if ( (!ccs->cb_entry.cb_ok) || (!ccs->cb_entry.cb_complete) )
+        return 1; // Failed
+
+    wait_for_cmd_done(ioaddr);
+    /* load pointer to Rx Ring */
+    
+    OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]),
+         ioaddr + SCBPointer);
+    OUTW(RUC_START, ioaddr + SCBCmd);
+
+    return 0; // OK
+}
+#endif
+
+// ------------------------------------------------------------------------
+// We use this as a templete when writing a new MAC address into the
+// eeproms. The MAC address in the first few bytes is over written
+// with the correct MAC address and then the whole lot is programmed
+// into the serial EEPROM. The checksum is calculated on the fly and
+// sent instead of the last two bytes.
+// The values are copied from the Intel EtherPro10/100+ &c devices
+// in the Integrator boards.
+
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+
+#define ee00 0x00, 0x00 // shorthand
+
+static char eeprom_burn[126] = { 
+/* halfword addresses! */
+/*  0: */  0x00, 0x90,   0x27, 0x8c,       0x57, 0x82,   0x03, 0x02,
+/*  4: */     ee00   ,   0x01, 0x02,       0x01, 0x47,      ee00   ,
+/*  8: */  0x13, 0x72,   0x06, 0x83,       0xa2, 0x40,   0x0c, 0x00,
+/*  C: */  0x86, 0x80,      ee00   ,          ee00   ,      ee00   ,
+/* 10: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 14: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 18: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 1C: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 20: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 24: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 28: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 2C: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 30: */  0x28, 0x01,      ee00   ,          ee00   ,      ee00   ,
+/* 34: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 38: */     ee00   ,      ee00   ,          ee00   ,      ee00   ,
+/* 3C: */     ee00   ,      ee00   ,          ee00   
+};
+#undef ee00
+
+#endif
+
+// ------------------------------------------------------------------------
+//
+//  Function : eth_set_mac_address
+//
+//  Return : 0 = It worked.
+//           non0 = It failed.
+// ------------------------------------------------------------------------
+static int eth_set_mac_address(struct i82559* p_i82559, char *addr)
+{
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+    int checksum, i, count;
+    // (this is the length of the *EEPROM*s address, not MAC address)
+    int addr_length;
+#endif
+    cyg_uint32  ioaddr;
+    volatile CONFIG_CMD_STRUCT *ccs;
+  
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "eth_set_mac_address : Bad device pointer %x\n",
+                   p_i82559 );
+#endif
+        return -1;
+    }
+
+    ioaddr = p_i82559->io_address;      
+    
+    wait_for_cmd_done(ioaddr); 
+
+    ccs = (CONFIG_CMD_STRUCT *)mem_reserved_ioctl;
+    if (ccs == (void*)0)
+        return 2;
+
+    ccs->cb_entry.cb_cmd=0x1;
+    ccs->cb_entry.cb_cmd_word=0x0;
+    ccs->cb_entry.cb_status_word=0x0;
+    ccs->cb_entry.cb_int=0;
+    ccs->cb_entry.cb_suspend=1;
+    ccs->cb_entry.cb_el=1;
+  
+    memcpy((char *)(ccs->config_bytes),addr,6);
+
+    ccs->config_bytes[6]=0x0;
+    ccs->config_bytes[7]=0x0;
+  
+    ioaddr = p_i82559->io_address;  
+  
+    OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer); 
+    OUTW(SCB_M | CU_START, ioaddr + SCBCmd);    
+    // Next delay seems to be required, otherwise,
+    // cb_ok/cb_complete won't be set later.
+
+    udelay(1000);
+    wait_for_cmd_done(ioaddr);   
+  
+    // now check for result ...
+    if ( (!ccs->cb_entry.cb_ok) || (!ccs->cb_entry.cb_complete) )
+        return 3;
+  
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+
+    addr_length = get_eeprom_size( ioaddr );
+
+    // now set this address in the device eeprom ....
+    (void)memcpy(eeprom_burn,addr,6);
+
+    // No idea what these were for...
+    // eeprom_burn[20] &= 0xfe;   
+    // eeprom_burn[20] |= p_i82559->index;   
+        
+    program_eeprom( ioaddr, addr_length, eeprom_burn );
+   
+    // update 82559 driver data structure ...
+    udelay( 100000 );
+
+    // by reading EEPROM to get the mac address back
+    for (checksum = 0, i = 0, count = 0; count < 64; count++) {
+        cyg_uint16 value;
+        // read word from eeprom
+        value = read_eeprom(ioaddr, count, addr_length);
+        checksum += value;
+        if (count < 3) {
+            p_i82559->mac_address[i++] = value & 0xFF;
+            p_i82559->mac_address[i++] = (value >> 8) & 0xFF;
+        }
+    }
+    
+#ifdef DEBUG
+    os_printf("MAC Address = %02X %02X %02X %02X %02X %02X\n",
+              p_i82559->mac_address[0], p_i82559->mac_address[1],
+              p_i82559->mac_address[2], p_i82559->mac_address[3],
+              p_i82559->mac_address[4], p_i82559->mac_address[5]);
+#endif
+
+    p_i82559->mac_addr_ok = 1;
+
+    for ( i = 0, count = 0; i < 6; i++ )
+        if ( p_i82559->mac_address[i] != addr[i] )
+            count++;
+
+    if ( count ) {
+#ifdef DEBUG
+        os_printf( "Warning: MAC Address read back wrong!  %d bytes differ.\n",
+                   count );
+#endif
+        p_i82559->mac_addr_ok = 0;
+    }
+
+    // If the EEPROM checksum is wrong, the MAC address read from the
+    // EEPROM is probably wrong as well. In that case, we don't set
+    // mac_addr_ok.
+    if ((checksum & 0xFFFF) != 0xBABA)  {
+#ifdef DEBUG
+        os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n",
+                   checksum, p_i82559->index);
+#endif
+        p_i82559->mac_addr_ok = 0;
+    }
+#else
+    p_i82559->mac_addr_ok = 1;
+#endif // ! CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+
+    return p_i82559->mac_addr_ok ? 0 : 1;
+}
+
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+// ------------------------------------------------------------------------
+static void
+write_eeprom(long ioaddr, int location, int addr_len, unsigned short value)
+{
+    int ee_addr = ioaddr + SCBeeprom;
+    int write_cmd = location | EE_WRITE_CMD(addr_len); 
+    int i;
+    
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay( 100 );
+    OUTW(EE_ENB, ee_addr);
+    eeprom_delay( 100 );
+
+//    os_printf("\n write_eeprom : write_cmd : %x",write_cmd);  
+//    os_printf("\n addr_len : %x  value : %x ",addr_len,value);  
+
+    /* Shift the write command bits out. */
+    for (i = (addr_len+2); i >= 0; i--) {
+        short dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+        OUTW(EE_ENB | dataval, ee_addr);
+        eeprom_delay(100);
+        OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(150);
+    }
+    OUTW(EE_ENB, ee_addr);
+        
+    for (i = 15; i >= 0; i--) {
+        short dataval = (value & (1 << i)) ? EE_DATA_WRITE : 0;
+        OUTW(EE_ENB | dataval, ee_addr);
+        eeprom_delay(100);
+        OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay(150);
+    }
+
+    /* Terminate the EEPROM access. */
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay(150000); // let the write take effect
+}
+
+// ------------------------------------------------------------------------
+static int write_enable_eeprom(long ioaddr,  int addr_len)
+{
+    int ee_addr = ioaddr + SCBeeprom;
+    int write_en_cmd = EE_WRITE_EN_CMD(addr_len); 
+    int i;
+
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    OUTW(EE_ENB, ee_addr);
+
+#ifdef DEBUG_82559
+    os_printf("write_en_cmd : %x",write_en_cmd);
+#endif
+
+    // Shift the wr/er enable command bits out.
+    for (i = (addr_len+2); i >= 0; i--) {
+	short dataval = (write_en_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+	OUTW(EE_ENB | dataval, ee_addr);
+	eeprom_delay(100);
+	OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+	eeprom_delay(150);
+    }
+
+    // Terminate the EEPROM access.
+    OUTW(EE_ENB & ~EE_CS, ee_addr);
+    eeprom_delay(EEPROM_DONE_DELAY);
+}
+
+
+// ------------------------------------------------------------------------
+static void
+program_eeprom(cyg_uint32 ioaddr, cyg_uint32 eeprom_size, cyg_uint8 *data)
+{
+  cyg_uint32 i;
+  cyg_uint16 checksum = 0;
+  cyg_uint16 value;
+
+  // First enable erase/write operations on the eeprom.
+  // This is done through the EWEN instruction.
+  write_enable_eeprom( ioaddr, eeprom_size );
+
+  for (i=0 ; i< 63 ; i++) {
+    value = ((unsigned short *)data)[i];
+    checksum += value;
+#ifdef DEBUG_82559
+    os_printf("\n i : %x ... value to be written : %x",i,value);
+#endif
+    write_eeprom( ioaddr, i, eeprom_size, value);
+#ifdef DEBUG_82559
+    os_printf("\n val read : %x ",read_eeprom(ioaddr,i,eeprom_size));
+#endif
+  }
+  value = 0xBABA - checksum;
+#ifdef DEBUG_82559
+  os_printf("\n i : %x ... checksum adjustment val to be written : %x",i,value);
+#endif
+  write_eeprom( ioaddr, i, eeprom_size, value );
+}
+
+// ------------------------------------------------------------------------
+#endif // ! CYGPKG_DEVS_ETH_ARM_INTEGRATOR_WRITE_EEPROM
+
+
+// ------------------------------------------------------------------------
+//
+//  Function : eth_get_mac_address
+//
+// ------------------------------------------------------------------------
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+static int eth_get_mac_address(struct i82559* p_i82559, char *addr)
+{
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "eth_get_mac_address : Bad device pointer %x\n",
+                   p_i82559 );
+#endif
+        return -1;
+    }
+
+    memcpy( addr, (char *)(&p_i82559->mac_address[0]), 6 );
+    return 0;
+}
+#endif
+// ------------------------------------------------------------------------
+//
+//  Function : i82559_ioctl
+//
+// ------------------------------------------------------------------------
+static int i82559_ioctl(struct eth_drv_sc *sc, unsigned long key,
+                        void *data, int data_length)
+{
+    struct i82559 *p_i82559;
+
+    p_i82559 = (struct i82559 *)sc->driver_private;
+
+    IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+        os_printf( "i82559_ioctl/control: Bad device pointer %x\n", p_i82559 );
+#endif
+        return -1;
+    }
+
+#ifdef DEBUG
+    db_printf( "i82559_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
+               p_i82559->index, p_i82559, key, data, data_length );
+#endif
+
+    switch ( key ) {
+
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+    case ETH_DRV_SET_MAC_ADDRESS:
+        if ( 6 != data_length )
+            return -2;
+        return eth_set_mac_address( p_i82559, data );
+#endif
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+    case ETH_DRV_GET_MAC_ADDRESS:
+        return eth_get_mac_address( p_i82559, data );
+#endif
+#ifdef ETH_DRV_GET_IF_STATS_UD
+    case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+        ETH_STATS_INIT( sc );    // so UPDATE the statistics structure
+#endif
+        // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+    case ETH_DRV_GET_IF_STATS:
+#endif
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+    {
+        struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+        int i;
+        static unsigned char my_chipset[]
+            = { ETH_DEV_DOT3STATSETHERCHIPSET };
+
+        strcpy( p->description, CYGDAT_DEVS_ETH_DESCRIPTION );
+        CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+        for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+            if ( 0 == (p->snmp_chipset[i] = my_chipset[i]) )
+                break;
+
+        i = i82559_status( sc );
+
+        if ( !( i & GEN_STATUS_LINK) ) {
+            p->operational = 2;         // LINK DOWN
+            p->duplex = 1;              // UNKNOWN
+            p->speed = 0;
+        }
+        else {
+            p->operational = 3;            // LINK UP
+            p->duplex = (i & GEN_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
+            p->speed = ((i & GEN_STATUS_100MBPS) ? 100 : 10) * 1000000;
+        }
+
+#ifdef KEEP_STATISTICS
+        {
+            I82559_COUNTERS *pc = &i82559_counters[ p_i82559->index ];
+            STATISTICS      *ps = &statistics[      p_i82559->index ];
+
+            // Admit to it...
+            p->supports_dot3        = true;
+
+            // Those commented out are not available on this chip.
+
+            p->tx_good              = pc->tx_good             ;
+            p->tx_max_collisions    = pc->tx_max_collisions   ;
+            p->tx_late_collisions   = pc->tx_late_collisions  ;
+            p->tx_underrun          = pc->tx_underrun         ;
+            p->tx_carrier_loss      = pc->tx_carrier_loss     ;
+            p->tx_deferred          = pc->tx_deferred         ;
+            //p->tx_sqetesterrors   = pc->tx_sqetesterrors    ;
+            p->tx_single_collisions = pc->tx_single_collisions;
+            p->tx_mult_collisions   = pc->tx_mult_collisions  ;
+            p->tx_total_collisions  = pc->tx_total_collisions ;
+            p->rx_good              = pc->rx_good             ;
+            p->rx_crc_errors        = pc->rx_crc_errors       ;
+            p->rx_align_errors      = pc->rx_align_errors     ;
+            p->rx_resource_errors   = pc->rx_resource_errors  ;
+            p->rx_overrun_errors    = pc->rx_overrun_errors   ;
+            p->rx_collisions        = pc->rx_collisions       ;
+            p->rx_short_frames      = pc->rx_short_frames     ;
+            //p->rx_too_long_frames = pc->rx_too_long_frames  ;
+            //p->rx_symbol_errors   = pc->rx_symbol_errors    ;
+        
+            p->interrupts           = ps->interrupts          ;
+            p->rx_count             = ps->rx_count            ;
+            p->rx_deliver           = ps->rx_deliver          ;
+            p->rx_resource          = ps->rx_resource         ;
+            p->rx_restart           = ps->rx_restart          ;
+            p->tx_count             = ps->tx_count            ;
+            p->tx_complete          = ps->tx_complete         ;
+            p->tx_dropped           = ps->tx_dropped          ;
+        }
+#endif // KEEP_STATISTICS
+
+        p->tx_queue_len = MAX_TX_DESCRIPTORS;
+
+        return 0; // OK
+    }
+#endif
+
+    default:
+        break;
+    }
+    return -1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Statistics update...
+//
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_ARM_INTEGRATOR_KEEP_82559_STATISTICS
+void update_statistics(struct i82559* p_i82559)
+{
+    I82559_COUNTERS *p_statistics;
+    cyg_uint32 *p_counter;
+    cyg_uint32 *p_register;
+    int reg_count;
+    
+    Mask82559Interrupt(p_i82559);
+
+    // This points to the sthared memory stats area/command block
+    p_statistics = (I82559_COUNTERS *)(p_i82559->p_statistics);
+
+    if ( (p_statistics->done & 0xFFFF) == 0xA007 ) {
+        p_counter = (cyg_uint32 *)&i82559_counters[ p_i82559->index ];
+        p_register = (cyg_uint32 *)p_statistics;
+        for ( reg_count = 0;
+              reg_count < sizeof( I82559_COUNTERS ) / sizeof( cyg_uint32 ) - 1;
+              reg_count++ ) {
+            *p_counter += *p_register;
+            p_counter++;
+            p_register++;
+        }
+        p_statistics->done = 0;
+        // make sure no command operating
+        wait_for_cmd_done(p_i82559->io_address);
+        // start register dump
+        OUTW(CU_DUMPSTATS, p_i82559->io_address + SCBCmd);
+    }
+    Acknowledge82559Interrupt(p_i82559);
+    UnMask82559Interrupt(p_i82559);
+}
+#endif
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+//
+//
+//           CODE FOR DEBUGGING PURPOSES ONLY
+//
+//
+// ------------------------------------------------------------------------
+void dump_txcb(TxCB *p_txcb)
+{
+    os_printf("TxCB @ %x\n", (int)p_txcb);
+    os_printf("status = %04X ", p_txcb->txstatus);
+    os_printf("command = %04X ", p_txcb->command);
+    os_printf("link = %08X ", p_txcb->link);
+    os_printf("tbd = %08X ", p_txcb->tbd_address);
+    os_printf("count = %d ", p_txcb->count);
+    os_printf("eof = %x ", p_txcb->eof);
+    os_printf("threshold = %d ", p_txcb->tx_threshold);
+    os_printf("tbd number = %d\n", p_txcb->tbd_number);
+}
+
+// This is intended to be the body of a THREAD that prints stuff every 10
+// seconds or so:
+#ifdef KEEP_STATISTICS
+#ifdef DISPLAY_STATISTICS
+void DisplayStatistics(void)
+{
+    int i;
+    I82559_COUNTERS *p_statistics;
+    cyg_uint32 *p_counter;
+    cyg_uint32 *p_register;
+    int reg_count;
+    int status;
+    
+    while ( 1 ) {
+#ifdef DISPLAY_82559_STATISTICS
+        for ( i = 0; i < 2; i ++ ) {
+            p_statistics = (I82559_COUNTERS *)i82559[i].p_statistics;
+            if ( (p_statistics->done & 0xFFFF) == 0xA007 ) {
+                p_counter = (cyg_uint32 *)&i82559_counters[i];
+                p_register = (cyg_uint32 *)&p_statistics->tx_good;
+                for ( reg_count = 20; reg_count != 0; reg_count--) {
+                    *p_counter += *p_register;
+                    p_counter++;
+                    p_register++;
+                }
+                p_statistics->done = 0;
+                // make sure no command operating
+            	wait_for_cmd_done(i82559[i].io_address);
+                // start register dump
+                OUTW(CU_DUMPSTATS, i82559[i].io_address + SCBCmd);
+            }
+        }
+#endif
+        os_printf("\nRx\nPackets = %d  %d\n",
+        statistics[0].rx_count, statistics[1].rx_count);
+        os_printf("Deliver   %d  %d\n",
+        statistics[0].rx_deliver, statistics[1].rx_deliver);
+        os_printf("Resource  %d  %d\n",
+        statistics[0].rx_resource, statistics[1].rx_resource);
+        os_printf("Restart   %d  %d\n",
+        statistics[0].rx_restart, statistics[1].rx_restart);
+
+#ifdef DISPLAY_82559_STATISTICS
+        os_printf("Count     %d  %d\n",
+        i82559_counters[0].rx_good, i82559_counters[1].rx_good);
+        os_printf("CRC       %d  %d\n",
+        i82559_counters[0].rx_crc_errors, i82559_counters[1].rx_crc_errors);
+        os_printf("Align     %d  %d\n",
+        i82559_counters[0].rx_align_errors, i82559_counters[1].rx_align_errors);
+        os_printf("Resource  %d  %d\n",
+        i82559_counters[0].rx_resource_errors, i82559_counters[1].rx_resource_errors);
+        os_printf("Overrun   %d  %d\n",
+        i82559_counters[0].rx_overrun_errors, i82559_counters[1].rx_overrun_errors);
+        os_printf("Collision %d  %d\n",
+        i82559_counters[0].rx_collisions, i82559_counters[1].rx_collisions);
+        os_printf("Short     %d  %d\n",
+        i82559_counters[0].rx_short_frames, i82559_counters[1].rx_short_frames);
+#endif
+        os_printf("\nTx\nPackets = %d  %d\n",
+        statistics[0].tx_count, statistics[1].tx_count);
+        os_printf("Complete  %d  %d\n",
+        statistics[0].tx_complete, statistics[1].tx_complete);
+        os_printf("Dropped   %d  %d\n",
+        statistics[0].tx_dropped, statistics[1].tx_dropped);
+        os_printf("Count     %d  %d\n",
+        i82559_counters[0].tx_good, i82559_counters[1].tx_good);
+#ifdef DISPLAY_82559_STATISTICS
+        os_printf("Collision %d  %d\n",
+        i82559_counters[0].tx_max_collisions,i82559_counters[1].tx_max_collisions);
+        os_printf("Late Col. %d  %d\n",
+        i82559_counters[0].tx_late_collisions,i82559_counters[1].tx_late_collisions);
+        os_printf("Underrun  %d  %d\n",
+        i82559_counters[0].tx_underrun,i82559_counters[1].tx_underrun);
+        os_printf("Carrier   %d  %d\n",
+        i82559_counters[0].tx_carrier_loss,i82559_counters[1].tx_carrier_loss);
+        os_printf("Deferred  %d  %d\n",
+        i82559_counters[0].tx_deferred, i82559_counters[1].tx_deferred);
+        os_printf("1 Col     %d  %d\n",
+        i82559_counters[0].tx_single_collisions, i82559_counters[0].tx_single_collisions);
+        os_printf("Mult. Col %d  %d\n",
+        i82559_counters[0].tx_mult_collisions, i82559_counters[0].tx_mult_collisions);
+        os_printf("Total Col %d  %d\n",
+        i82559_counters[0].tx_total_collisions, i82559_counters[0].tx_total_collisions);
+#endif
+        status = INB(i82559[0].io_address + SCBGenStatus);
+        os_printf("Interface 0 Link = %s, %s Mbps, %s Duplex\n",
+            status & GEN_STATUS_LINK ? "Up" : "Down",
+            status & GEN_STATUS_100MBPS ?  "100" : "10",
+            status & GEN_STATUS_FDX ? "Full" : "Half");
+
+        status = INB(i82559[1].io_address + SCBGenStatus);
+        os_printf("Interface 1 Link = %s, %s Mbps, %s Duplex\n",
+            status & GEN_STATUS_LINK ? "Up" : "Down",
+            status & GEN_STATUS_100MBPS ?  "100" : "10",
+            status & GEN_STATUS_FDX ? "Full" : "Half");
+
+        cyg_thread_delay(1000);
+    }
+}
+#endif // DISPLAY_STATISTICS
+#endif // KEEP_STATISTICS
+
+void dump_rfd(RFD *p_rfd, int anyway )
+{
+    if ( (0 != p_rfd->rxstatus) || anyway ) {
+        os_printf("RFD @ %x = ", (int)p_rfd);
+        os_printf("status = %x ", p_rfd->rxstatus);
+        os_printf("link = %x ", p_rfd->link);
+//        os_printf("rdb_address = %x ", p_rfd->rdb_address);
+        os_printf("count = %x ", p_rfd->count);
+        os_printf("f = %x ", p_rfd->f);
+        os_printf("eof = %x ", p_rfd->eof);
+        os_printf("size = %x\n", p_rfd->size);
+        os_printf("[%04x %04x %04x] ",
+                  *((cyg_uint16 *)(&(p_rfd->buffer[0]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[2]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[4]))) );
+        os_printf("[%04x %04x %04x] %04x : ",          
+                  *((cyg_uint16 *)(&(p_rfd->buffer[6]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[8]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[10]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[12]))) );
+        os_printf("(%04x %04x %04x %04x) ",            
+                  *((cyg_uint16 *)(&(p_rfd->buffer[14]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[16]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[18]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[20]))) );
+        os_printf("[%04x %04x %04x] ",                 
+                  *((cyg_uint16 *)(&(p_rfd->buffer[22]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[24]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[26]))) );
+        os_printf("%d.%d.%d.%d ",
+                  *((cyg_uint8  *)(&(p_rfd->buffer[28]))),
+                  *((cyg_uint8  *)(&(p_rfd->buffer[29]))),
+                  *((cyg_uint8  *)(&(p_rfd->buffer[30]))),
+                  *((cyg_uint8  *)(&(p_rfd->buffer[31]))) );
+        os_printf("[%04x %04x %04x] ",                 
+                  *((cyg_uint16 *)(&(p_rfd->buffer[32]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[34]))),
+                  *((cyg_uint16 *)(&(p_rfd->buffer[36]))) );
+        os_printf("%d.%d.%d.%d ...\n",
+                  *((cyg_uint8  *)(&(p_rfd->buffer[38]))),
+                  *((cyg_uint8  *)(&(p_rfd->buffer[39]))),
+                  *((cyg_uint8  *)(&(p_rfd->buffer[40]))),
+                  *((cyg_uint8  *)(&(p_rfd->buffer[41]))) );
+    }
+}
+
+void dump_all_rfds( int intf )
+{
+    struct i82559* p_i82559 = &i82559[intf];
+    int i, j;
+    j = p_i82559->next_rx_descriptor;
+    os_printf("rx descriptors for interface %d (eth%d):\n", intf, intf );
+    for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ )
+        dump_rfd( p_i82559->rx_ring[i], (i > (j-3) && (i <= j)) );
+    os_printf("next rx descriptor = %x\n\n", j);
+}
+
+
+void dump_packet(cyg_uint8 *p_buffer, int length)
+{
+    int count;
+
+    count = 0;
+    while ( length > 0 ) {
+        if ( count == 0 )
+            os_printf("\n");
+        count = (count + 1) & 0x0F;
+        os_printf("%02X ", *p_buffer++);
+        length--;
+    }
+    os_printf("\n");
+}
+
+// ------------------------------------------------------------------------
+
+// EOF if_integrator.c
--- a/packages/devs/flash/amd/am29xxxxx/current/ChangeLog
+++ b/packages/devs/flash/amd/am29xxxxx/current/ChangeLog
@@ -1,3 +1,14 @@
+2001-10-31  Jesper Skov  <jskov@redhat.com>
+
+	* include/flash_am29xxxxx_parts.inl: Removed fix me comments -
+	description is accurate.
+
+2001-10-30  Jesper Skov  <jskov@redhat.com>
+	From Gary:
+	* include/flash_am29xxxxx_parts.inl: Added preliminary AM29LV640
+	support. Still needs some tweaks.
+	* cdl/flash_amd_am29xxxxx.cdl: Same.
+
 2001-09-26  Gary Thomas  <gthomas@redhat.com>
 
 	* include/flash_am29xxxxx.inl (flash_erase_block): 
--- a/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl
+++ b/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl
@@ -77,6 +77,16 @@ cdl_package CYGPKG_DEVS_FLASH_AMD_AM29XX
             part in the family."
     }
 
+    cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV640 {
+        display       "AMD AM29LV640 flash memory support"
+        default_value 0
+        implements    CYGINT_DEVS_FLASH_AMD_VARIANTS
+        description   "
+            When this option is enabled, the AMD flash driver will be
+            able to recognize and handle the AMD29LV640
+            part in the family."
+    }
+
     cdl_option CYGHWR_DEVS_FLASH_AMD_AM29DL324D {
         display       "AMD AM29DL324D flash memory support"
         default_value 0
--- a/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl
+++ b/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl
@@ -362,6 +362,18 @@
     },
 #endif
 
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV640
+    {   // MBM29LV640xx
+        device_id  : FLASHWORD(0x22d7),
+        block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+        block_count: 128,
+        device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE,
+        base_mask  : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1),
+        bootblock  : false,  
+        banked     : false
+    },
+#endif
+
 #endif // 16 bit devices
 
 #endif // CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_PARTS_INL
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/ChangeLog
@@ -0,0 +1,30 @@
+2001-10-30  Philippe Robin <Philippe.Robin@arm.com>
+2001-10-30  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* Initial version of ARM Integrator flash driver.
+
+//===========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/cdl/flash_integrator.cdl
@@ -0,0 +1,84 @@
+# ====================================================================
+#
+#      flash_integrator.cdl
+#
+#      FLASH memory - Hardware support on ARM INTEGRATOR
+#
+# ====================================================================
+#####COPYRIGHTBEGIN####
+#                                                                          
+# -------------------------------------------                              
+# The contents of this file are subject to the Red Hat eCos Public License 
+# Version 1.1 (the "License"); you may not use this file except in         
+# compliance with the License.  You may obtain a copy of the License at    
+# http://www.redhat.com/                                                   
+#                                                                          
+# Software distributed under the License is distributed on an "AS IS"      
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+# License for the specific language governing rights and limitations under 
+# the License.                                                             
+#                                                                          
+# The Original Code is eCos - Embedded Configurable Operating System,      
+# released September 30, 1998.                                             
+#                                                                          
+# The Initial Developer of the Original Code is Red Hat.                   
+# Portions created by Red Hat are                                          
+# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Philippe Robin
+# Original data:  gthomas
+# Contributors:
+# Date:           November 7, 2000
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_INTEGRATOR {
+    display       "ARM INTEGRATOR FLASH memory support"
+
+    parent        CYGPKG_IO_FLASH
+    active_if	  CYGPKG_IO_FLASH
+    active_if	  CYGPKG_HAL_ARM_INTEGRATOR
+    requires      { CYGNUM_FLASH_WORKSPACE_SIZE == 0x10000 }
+    
+    implements    CYGINT_REDBOOT_ARM_FLASH_SIB_SUPPORTED
+    implements    CYGHWR_IO_FLASH_DEVICE
+
+    include_dir   .
+#    include_files ; # none _exported_ whatsoever
+    description   "FLASH memory device support for ARM INTEGRATOR"
+    compile       integrator_flash.c
+
+    make -priority 1 {
+        flash_erase_block.o: $(REPOSITORY)/$(PACKAGE)/src/flash_erase_block.c
+        $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_erase_block.c
+        echo " .globl flash_erase_block_end" >>flash_erase_block.s
+        echo "flash_erase_block_end:" >>flash_erase_block.s
+        $(CC) -c -o flash_erase_block.o flash_erase_block.s
+        $(AR) rcs $(PREFIX)/lib/libtarget.a flash_erase_block.o
+    }
+    make -priority 1 {
+        flash_program_buf.o: $(REPOSITORY)/$(PACKAGE)/src/flash_program_buf.c
+        $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_program_buf.c
+        echo " .globl flash_program_buf_end" >>flash_program_buf.s
+        echo "flash_program_buf_end:" >>flash_program_buf.s
+        $(CC) -c -o flash_program_buf.o flash_program_buf.s
+        $(AR) rcs $(PREFIX)/lib/libtarget.a flash_program_buf.o
+    }
+    make -priority 1 {
+        flash_query.o: $(REPOSITORY)/$(PACKAGE)/src/flash_query.c
+        $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_query.c
+        echo " .globl flash_query_end" >>flash_query.s
+        echo "flash_query_end:" >>flash_query.s
+        $(CC) -c -o flash_query.o flash_query.s
+        $(AR) rcs $(PREFIX)/lib/libtarget.a flash_query.o
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/src/flash.h
@@ -0,0 +1,65 @@
+//==========================================================================
+//
+//      flash.h
+//
+//      Flash programming - device constants, etc.
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _FLASH_HWR_H_
+#define _FLASH_HWR_H_
+
+// INTEGRATOR FLASH layout
+//   4x 28F008SA, one device per byte-lane
+//   each device is 16x64k blocks
+
+#define FLASH_Read_ID      0x90909090
+#define FLASH_Read_Status  0x70707070
+#define FLASH_Clear_Status 0x50505050
+#define FLASH_Status_Ready 0x80808080
+#define FLASH_Program      0x10101010
+#define FLASH_Block_Erase  0x20202020
+#define FLASH_Confirm      0xD0D0D0D0
+#define FLASH_Reset        0xFFFFFFFF
+
+#define FLASH_BLOCK_SIZE   0x20000
+
+#define FLASH_Intel_code   0x89
+#define FLASH_28F320       0xD4
+
+#endif  // _FLASH_HWR_H_
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/src/flash_erase_block.c
@@ -0,0 +1,92 @@
+//==========================================================================
+//
+//      flash_erase_block.c
+//
+//      Flash programming
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_integrator.h>
+
+//
+// CAUTION!  This code must be copied to RAM before execution.  Therefore,
+// it must not contain any code which might be position dependent!
+//
+
+int
+flash_erase_block(volatile cyg_uint32 *block)
+{
+    volatile cyg_uint32 stat = 0;
+    int timeout = 5000000;    
+    int cache_on;
+
+    HAL_DCACHE_IS_ENABLED(cache_on);
+    if (cache_on) {
+        HAL_DCACHE_SYNC();
+        HAL_DCACHE_DISABLE();
+    }
+
+    HAL_FLASH_WRITE_ENABLE();
+    // Clear any error conditions
+    *block = FLASH_Clear_Status;
+
+    // Set to erase
+    *block = FLASH_Block_Erase;
+    *block = FLASH_Confirm;
+    while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) {
+        *block = FLASH_Read_Status;
+	stat = *block;
+        if (--timeout == 0) break;
+    }
+
+    // Restore ROM to "normal" mode
+    *block = FLASH_Reset;
+
+    HAL_FLASH_WRITE_DISABLE();
+
+    if (cache_on) {
+        HAL_DCACHE_ENABLE();
+    }
+
+    return stat;
+}
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/src/flash_program_buf.c
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+//      flash_program_buf.c
+//
+//      Flash programming
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_integrator.h>
+
+//
+// CAUTION!  This code must be copied to RAM before execution.  Therefore,
+// it must not contain any code which might be position dependent!
+//
+
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+{
+    unsigned long stat;
+    int timeout = 5000000;
+    int cache_on;
+    volatile unsigned long *orig_addr = addr;
+
+    HAL_DCACHE_IS_ENABLED(cache_on);
+    if (cache_on) {
+        HAL_DCACHE_SYNC();
+        HAL_DCACHE_DISABLE();
+    }
+
+    HAL_FLASH_WRITE_ENABLE();
+
+    // Clear any error conditions
+    *addr = FLASH_Clear_Status;
+
+    while (len > 0) {
+        *addr = FLASH_Program;
+        *addr = *data++;
+        timeout = 5000000;
+        while(((stat = *addr) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+            if (--timeout == 0) {
+                goto bad;
+            }
+        }
+        addr++;
+        len -= sizeof(unsigned long);
+    }
+
+    // Restore ROM to "normal" mode
+ bad:
+    *orig_addr = FLASH_Reset;            
+
+    HAL_FLASH_WRITE_DISABLE();
+
+    if (cache_on) {
+        HAL_DCACHE_ENABLE();
+    }
+
+    return stat;
+}
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/src/flash_query.c
@@ -0,0 +1,93 @@
+//==========================================================================
+//
+//      flash_query.c
+//
+//      Flash programming - query device
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_integrator.h>
+
+//
+// CAUTION!  This code must be copied to RAM before execution.  Therefore,
+// it must not contain any code which might be position dependent!
+//
+
+#define CNT 20*1000*10  // Approx 200ms
+
+int
+flash_query(unsigned char *data)
+{
+    volatile unsigned long *lROM;
+    volatile unsigned char *cROM;
+    int i, cnt;
+    int cache_on;
+    volatile cyg_uint8 *ptr = 0x24000000;
+    cyg_uint8 val;
+
+    HAL_DCACHE_IS_ENABLED(cache_on);
+    if (cache_on) {
+        HAL_DCACHE_SYNC();
+        HAL_DCACHE_DISABLE();
+    }
+
+    HAL_FLASH_WRITE_ENABLE();
+
+    lROM = 0x24000000;
+    cROM = 0x24000000;
+
+    lROM[0] = FLASH_Read_ID;
+    for (cnt = CNT;  cnt > 0;  cnt--) ;
+    for (i = 0;  i < 8;  i++) {
+        *data++ = cROM[i];
+    }
+    lROM[0] = FLASH_Reset;
+
+    HAL_FLASH_WRITE_DISABLE();
+
+    if (cache_on) {
+        HAL_DCACHE_ENABLE();
+    }
+
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/packages/devs/flash/arm/integrator/current/src/integrator_flash.c
@@ -0,0 +1,1016 @@
+//==========================================================================
+//
+//      integrator_flash.c
+//
+//      Flash programming
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+
+#define  _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+#include "flash.h"
+
+#define ARM_INTEGRATOR_FLASH
+
+extern int strncmp(const char *s1, const char *s2, int len);
+
+#define INTEGRATOR_NUM_REGIONS 256
+
+int
+flash_hwr_init(void)
+{
+    unsigned char data[96];
+    extern char flash_query, flash_query_end;
+    typedef int code_fun(unsigned char *);
+    code_fun *_flash_query;
+    int code_len, stat, num_regions, region_size;
+
+    // Copy 'program' code to RAM for execution
+    code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query;
+    _flash_query = (code_fun *)flash_info.work_space;
+    memcpy(_flash_query, &flash_query, code_len);
+    HAL_DCACHE_SYNC();  // Should guarantee this code will run
+    HAL_ICACHE_DISABLE(); // is also required to avoid old contents
+
+    stat = (*_flash_query)(data);
+
+    HAL_ICACHE_ENABLE();
+
+    if ( data[4] == FLASH_28F320 ) {
+        num_regions = INTEGRATOR_NUM_REGIONS;
+        region_size = FLASH_BLOCK_SIZE;
+        flash_info.block_size = region_size;
+        flash_info.blocks = num_regions;
+        flash_info.start = (void *)0x24000000;
+        flash_info.end = (void *)(0x24000000+(num_regions*region_size));
+        return FLASH_ERR_OK;
+    } else {
+        diag_printf("Can't identify FLASH, sorry\n");
+        diag_dump_buf(data, sizeof(data));
+        return FLASH_ERR_HWR;
+    }
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+    if (err & 0x7E) {
+        if (err & 0x10) {
+            return FLASH_ERR_PROGRAM;
+        } else 
+        if (err & 0x20) {
+            return FLASH_ERR_ERASE;
+        } else 
+        return FLASH_ERR_HWR;  // FIXME
+    } else {
+        return FLASH_ERR_OK;
+    }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+    extern char _stext, _etext;
+
+    return ((((unsigned long)&_stext >= (unsigned long)start) &&
+             ((unsigned long)&_stext < (unsigned long)end)) ||
+            (((unsigned long)&_etext >= (unsigned long)start) &&
+             ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+
+#ifdef ARM_INTEGRATOR_FLASH
+#define FLASH_BASE	   0x24000000
+#define FLASH_SIZE	   0x02000000
+
+/*     type information :-
+ * 0xffff ffff     -       deleted (usual flash erased value)
+ * 0x0000 xxxx     -       Reserved for ARM usage:
+ * Bit 0           -       ARM Executable Image
+ * Bit 1           -       System Information Block
+ * Bit 2           -       File System Block
+ * 0xyyyy 0000     -       Available for customers (y != 0)
+ */
+#define TYPE_DELETED       0xFFFFFFFF
+#define TYPE_ARM_MASK      0x0000FFFF
+#define TYPE_CUSTOM_MASK   0xFFFF0000
+#define TYPE_ARM_EXEC      0x00000001
+#define TYPE_ARM_SIB       0x00000002
+#define TYPE_ARM_SYSBLOCK  0x00000004
+
+/* Filetypes */
+
+#define  UNKNOWN_FILE      0x00000000
+#define  MOT_S_RECORD      0x00000001
+#define  INTEL_HEX         0x00000002
+#define  ELF               0x00000004
+#define  DWARF             0x00000008
+#define  ARM_AOF           0x00000010
+#define  ARM_AIF           0x00000020
+#define  PLAIN_BINARY      0x00000040
+#define  ARM_AIF_BIN       0x00000080
+#define  MCS_TYPE          0x00000100
+
+#define  CONVERT_TYPE      (MOT_S_RECORD | INTEL_HEX | MCS_TYPE | ELF)
+
+#define SIB_OWNER_STRING_SIZE   32
+#define MAX_SIB_SIZE            512
+#define MAX_SIB_INDEX		64
+
+#define NoOfElements(array)	(sizeof(array) / sizeof(array[0]))
+#define AddressToBlock(address) ((((cyg_uint32)(address)) - FLASH_BASE) / FLASH_BLOCK_SIZE)
+#define BlockToAddress(block)   (((block) * FLASH_BLOCK_SIZE) + FLASH_BASE)
+#define BlockBaseAddress(address) (((cyg_uint32)(address)) & ~(FLASH_BLOCK_SIZE - 1))
+#define FooterAddress(block)    ((tFooter *)((BlockToAddress(block) + FLASH_BLOCK_SIZE) \
+						- sizeof (tFooter)))
+#define InFlash(address)        ((((cyg_uint32)(address)) >= FLASH_BASE) && (((cyg_uint32)(address))\
+					 < (FLASH_BASE + FLASH_SIZE)))
+
+#define NO_OF_BLOCKS    (FLASH_SIZE / FLASH_BLOCK_SIZE)
+
+#define SIB_HEADER_SIGNATURE    0xA00FFF9F /* This is an invalid instruction - MULGE pc,pc,pc */
+#define FLASH_FOOTER_SIGNATURE  0xA0FFFF9F /* This is an invalid instruction - SMULALGES pc,pc,pc */
+
+
+typedef struct SIBType {
+    cyg_uint32  signature;
+    cyg_uint32  size;
+    char        owner[SIB_OWNER_STRING_SIZE];
+    cyg_uint32  index;
+    cyg_uint32  revision;
+    cyg_uint32  checksum;
+} tSIB; 
+
+typedef struct SIBInfoType {
+    cyg_uint32 SIB_number;      /* Unique number of SIB Block            */
+    cyg_uint32 SIB_Extension;   /* Base of SIB Flash Block               */
+    char Label[16];             /* String space for ownership string     */
+    cyg_uint32 checksum;        /* SIB Image checksum                    */
+} tSIBInfo;
+
+typedef struct FooterType {
+    void        *infoBase;      /* Address of first word of ImageFooter  */
+    char        *blockBase;     /* Start of area reserved by this footer */
+    cyg_uint32  signature;      /* 'Magic' number proves it's a footer   */
+    cyg_uint32  type;           /* Area type: ARM Image, SIB, customer   */
+    cyg_uint32  checksum;       /* Just this structure                   */
+} tFooter ;
+
+typedef struct ImageInfoType {
+    cyg_uint32 bootFlags;       /* Boot flags, compression etc.          */
+    cyg_uint32 imageNumber;     /* Unique number, selects for boot etc.  */
+    char *loadAddress;          /* Address program should be loaded to   */
+    cyg_uint32 length;          /* Actual size of image                  */
+    char *address;                /* Image is executed from here           */
+    char name[16];              /* Null terminated                       */
+    char *headerBase;           /* Flash Address of any stripped header  */
+    cyg_uint32 header_length;   /* Length of header in memory            */
+    cyg_uint32 headerType;      /* AIF, RLF, s-record etc.               */
+    cyg_uint32 checksum;        /* Image checksum (inc. this struct)     */
+} tImageInfo;
+
+/* globals */
+
+static tFooter 		*active_flash_footers[NO_OF_BLOCKS];
+static tSIB    		*active_sibs[MAX_SIB_INDEX];
+static char 		active_id_string[SIB_OWNER_STRING_SIZE];
+static cyg_uint32 	buffer[MAX_SIB_SIZE / sizeof(cyg_uint32)];
+static cyg_uint32 	*free_ptr;
+static cyg_uint32 	free_space;
+
+//
+// find_free_space()
+//
+// This routine searches backwards from the end of flash, this is to ensure 
+// that any SIB's are at the end of flash and therefore less likely to be 
+// overwritten by the boot monitor loader.  
+//
+// RETURNS: NULL or pointer on area of free space
+
+static cyg_uint32 *
+find_free_space(int size)
+{
+    tFooter *footer;
+    int     required_blocks;
+    int     free_blocks;
+
+    //Calculate the number of blocks required.
+    required_blocks = (size / FLASH_BLOCK_SIZE) + 1;
+
+    // Get a pointer to the last possible footer in flash.
+    footer = (tFooter *)(FLASH_BASE + FLASH_SIZE - sizeof(tFooter));
+
+    free_blocks = 0;
+
+    while (free_blocks < required_blocks) {
+        // Skip pass any allocated blocks
+        while (footer->signature == FLASH_FOOTER_SIGNATURE) {
+            footer = (tFooter *)(footer->blockBase - sizeof (tFooter));
+
+            if ((cyg_uint32)footer < FLASH_BASE)
+                return NULL;
+	}
+
+        // Count free blocks
+        free_blocks = 0;
+
+        while (footer->signature != FLASH_FOOTER_SIGNATURE) {
+            free_blocks++;
+
+            // Have we found enough.
+            if (free_blocks >= required_blocks)
+                break;
+
+            footer = (tFooter *)((cyg_uint32)footer - FLASH_BLOCK_SIZE);
+
+            if ((cyg_uint32)footer < FLASH_BASE)
+                return NULL;
+	}
+    }
+
+    // Return the address of the first location of the free space.
+    return (cyg_uint32 *)BlockBaseAddress(footer);
+}
+
+//
+// arm_fis_find_free()
+//
+
+bool
+arm_fis_find_free(cyg_uint32 *addr, cyg_uint32 size)
+{
+    tFooter *footer;
+    int     required_blocks;
+    int     free_blocks;
+
+    //Calculate the number of blocks required.
+    required_blocks = (size / FLASH_BLOCK_SIZE) + 1;
+
+    footer = FooterAddress(AddressToBlock(*addr));
+    free_blocks = 0;
+
+    while (free_blocks < required_blocks) {
+        // Skip pass any allocated blocks
+        while (footer->signature == FLASH_FOOTER_SIGNATURE) {
+            footer = (tFooter *)((cyg_uint32)footer + FLASH_BLOCK_SIZE);
+
+            if ((cyg_uint32)footer > (FLASH_BASE + FLASH_SIZE))
+                return 0;
+	}
+
+        // Count free blocks
+        free_blocks = 0;
+	*addr = (tFooter *)((cyg_uint32)footer + sizeof(tFooter) - FLASH_BLOCK_SIZE);
+
+        while (footer->signature != FLASH_FOOTER_SIGNATURE) {
+            free_blocks++;
+
+            // Have we found enough.
+            if (free_blocks >= required_blocks)
+                break;
+
+            footer = (tFooter *)((cyg_uint32)footer + FLASH_BLOCK_SIZE);
+
+            if ((cyg_uint32)footer > (FLASH_BASE + FLASH_SIZE))
+                return 0;
+	}
+    }
+
+    // Return the address of the first location of the free space.
+    return 1;
+}
+
+//
+//  sib_checksum() - calculate SIB checksum.
+//
+
+static cyg_uint32 
+sib_checksum(tSIB *sib)
+{
+    cyg_uint32	checksum;
+    cyg_uint32  *ptr;
+    int         size;
+
+    checksum    = 0;
+    size        = sib->size;
+    ptr         = (cyg_uint32 *)sib;
+
+    while (size > 0) {
+        cyg_uint32 word;
+
+        word = *ptr++;
+
+        if (word > ~checksum) checksum++;
+
+        checksum += word;
+        size -= sizeof (word);
+    }
+
+    return ~checksum;
+}
+
+// footer_checksum() - calculate the footer checksum.
+static cyg_uint32 
+footer_checksum(tFooter *footer)
+{
+    cyg_uint32	checksum;
+    cyg_uint32	*ptr;
+    int         size;
+
+    checksum    = 0;
+    size        = sizeof (tFooter);
+    ptr         = (cyg_uint32 *)footer;
+
+    while (size > 0) {
+        cyg_uint32 word;
+
+        word = *ptr++;
+
+        if (word > ~checksum) checksum++;
+
+        checksum += word;
+        size -= sizeof (word);
+    }
+
+    return ~checksum;
+}
+
+// write_sib() - internal routine to write a SIB to flash.
+//
+// RETURN: -1 if error 0 otherwise
+
+static int 
+write_sib(tSIB *sib)
+{
+    cyg_uint32  *ptr;
+
+    // Is there space available for this SIB.
+    if (sib->size > free_space) {
+        int required_space;
+        int count;
+        int block;
+        tFooter footer;
+        tFooter *footer_ptr;
+
+        // If not then we need to allocate a new area in flash.
+        //
+        // First calculate the size required for the new area by
+        // adding up the size of all the active SIB's.
+        //
+        required_space = sib->size;
+
+        for (count = 0; count < MAX_SIB_INDEX; count++) {
+            tSIB *sib2;
+
+            sib2 = active_sibs[count];
+
+            if (sib2 != NULL) required_space += sib2->size;
+	}
+
+        // Get a pointer to the free space.
+        free_ptr = find_free_space (required_space);
+
+        // Build a flash footer to describe this area.
+        footer.blockBase    = (char *)BlockBaseAddress(free_ptr);
+        footer.infoBase     = NULL;
+        footer.type         = TYPE_ARM_SIB;
+        footer.signature    = FLASH_FOOTER_SIGNATURE;
+        footer.checksum     = 0;
+        footer.checksum     = footer_checksum (&footer);
+
+        // Calculate the address where the footer will live in flash
+        // and write it to flash.
+        block = AddressToBlock((cyg_uint32)free_ptr + required_space + sizeof (tFooter));
+        
+        footer_ptr = FooterAddress(block);
+
+#ifdef TO_CHECK
+	if (sysFlashWrite(FLASH_CAST(&footer), sizeof(tFooter), 
+			  ((cyg_uint32)footer_ptr - FLASH_BASE),
+			  flashType, 0) != OK)
+	    return -1;
+#endif
+	if (flash_program_buf(footer_ptr, (unsigned long *)&footer, sizeof(tFooter)) < 0 )
+	    return -1;
+
+        // Update the free space global varible.
+        free_space = ((AddressToBlock(footer_ptr) - block + 1) * FLASH_BLOCK_SIZE)
+			- sizeof (tFooter);
+    }
+
+    // If the SIB that we are writing is already in flash then it need to
+    // be copied into memory as it may become unreadable when we start
+    // programming the flash (if it is in the same flash part).
+    if (InFlash(sib)) {
+        cyg_uint32  *src;
+        cyg_uint32  *dest;
+        int         size;
+        tSIB        *tmp_sib;
+
+        size    = sib->size;
+        src     = (cyg_uint32 *)sib;
+        dest    = buffer;
+
+        while (size > 0) {
+            *dest++ = *src++;
+            size -= sizeof (cyg_uint32);
+	}
+
+        // Increment the revision count.
+        tmp_sib = (tSIB *)buffer;
+        tmp_sib->revision = sib->revision + 1;
+
+        ptr = buffer;
+    } else
+        ptr = (cyg_uint32 *)sib;
+
+    // Write the SIB to flash.
+#ifdef TO_CHECK
+    if (sysFlashWrite(FLASH_CAST(ptr), sib->size, (int)((cyg_uint32)free_ptr - FLASH_BASE), 
+		      flashType, 0) != OK)
+        return -1;
+#endif
+
+    if (flash_program_buf((cyg_uint32)free_ptr, ptr, sib->size) < 0 ) 
+        return -1;
+
+    // Update the free space, free pointer and active SIB's varibles
+    // to reflect this write.
+    free_space  -= sib->size;
+    free_ptr    = (cyg_uint32 *)((cyg_uint32)free_ptr - sib->size);
+
+    active_sibs[sib->index] = sib;
+
+    return 0;
+}
+
+// delete_sib() - delete a SIB.
+//
+// This will delete at least a whole flash block and therefore any active
+// SIB's will need to be rewritten.
+
+static int 
+delete_sib (tSIB *sib_to_delete)
+{
+    int         block;
+    tFooter     *footer;
+    tSIB        *sib;    
+    int         delete_size;
+
+    // Calculate the first address of this flash block and the
+    // first possible footer location.
+    //
+    block   = AddressToBlock(sib_to_delete);
+    footer  = FooterAddress(block);
+
+    // Search for the footer for this block.
+    while (footer->signature != FLASH_FOOTER_SIGNATURE)
+        footer = (tFooter *)((cyg_uint32)footer + FLASH_BLOCK_SIZE);
+
+    if (footer_checksum (footer) != 0)
+        return -1;
+
+    // Now get the a pointer to the first SIB.
+    sib = (tSIB *)footer->blockBase;
+
+    // Now search through all the SIB's.
+    while (sib->signature == SIB_HEADER_SIGNATURE) {
+        if (sib_checksum (sib) != 0)
+            break;
+  
+	// Any valid and active SIB will need to be rewritten.
+        if (sib->index < MAX_SIB_INDEX) {
+            if ((active_sibs[sib->index] == NULL) || 
+                (sib->revision > active_sibs[sib->index]->revision)) {
+                write_sib (sib);
+	    }
+	}
+
+        // Move onto next SIB.
+        sib = (tSIB *)((cyg_uint32)sib + sib->size);
+    }
+
+    // Calculate how much space needs to be deleted, it may be multiple
+    // blocks, and delete it.
+    delete_size = (AddressToBlock(footer) - block + 1) * FLASH_BLOCK_SIZE;
+
+    // !! must add code for cases where (delete_size > block_size)
+#ifdef TO_CHECK
+    return sysFlashEraseBlock((cyg_uint32 *)footer->blockBase, sysFlashTypeGet());
+#endif
+    return flash_erase_block((cyg_uint32 *)footer->blockBase);
+    }
+
+// SIB_Open() -  Open all SIB's with the owner by 'id_string'.
+//
+// RETURN: -1 if error 0 otherwise
+
+int 
+SIB_Open(char *id_string, int *sib_count, int private_flag)
+{
+    int     count;
+    tFooter *footer;
+    int     no_of_sibs;
+
+    // Initialize various globals.
+    memset(active_id_string, 0, SIB_OWNER_STRING_SIZE);
+    free_ptr    = NULL;
+    free_space  = 0;
+    *sib_count  = 0;
+
+    // Find all the active footers.
+    fLib_FindFooter((cyg_uint32 *)FLASH_BASE, FLASH_SIZE, active_flash_footers);
+
+    // Initialise the active SIB array.
+    for (count = 0; count < MAX_SIB_INDEX; count++)
+        active_sibs[count] = NULL;
+
+    // Populate the active SIB array with all the active SIB found in flash.
+    count       = 0;
+    no_of_sibs  = 0;
+
+    while ((footer = active_flash_footers[count++]) != NULL) {
+        tSIB    *sib;
+
+        if (footer->type != TYPE_ARM_SIB)
+            continue;
+
+        sib = (tSIB *)footer->blockBase;
+
+        while (sib->signature == SIB_HEADER_SIGNATURE) {
+            char    c;
+            char    *ptr1;
+            char    *ptr2;
+
+            if (sib_checksum (sib) != 0)
+                return -1;
+
+            ptr1 = id_string;
+            ptr2 = sib->owner;
+
+            while ((c = *ptr1++) != '\0') {
+                if (c != *ptr2++)
+                    break;
+	    }
+
+            if (c == '\0') {
+	        // If two SIB's have the same name and index the one with the
+	        // highest revision is considered to be the active one.
+                if (sib->index < MAX_SIB_INDEX) {
+                    tSIB *current_sib;
+
+                    current_sib = active_sibs[sib->index];
+
+                    if (current_sib == NULL) {
+                        active_sibs[sib->index] = sib;
+		    } else if (sib->revision > current_sib->revision) {
+                        delete_sib(current_sib);
+                        active_sibs[sib->index] = sib;
+		    } else {
+                        tSIB *old_sib;
+
+                        old_sib = sib;
+                        sib = (tSIB *)((cyg_uint32)sib + sib->size); 
+                        
+                        delete_sib(old_sib);
+
+                        continue;
+		    }
+		} else
+                    return -1;
+
+                no_of_sibs++;
+	    }
+
+            sib = (tSIB *)((cyg_uint32)sib + sib->size);
+	}
+    }
+
+    memcpy(active_id_string, id_string, SIB_OWNER_STRING_SIZE);
+
+    *sib_count = no_of_sibs;
+
+    return 0;
+}
+
+// SIB_Close() - close access to SIBs
+
+int 
+SIB_Close(void)
+{
+    int count;
+
+    memset(active_id_string, 0, SIB_OWNER_STRING_SIZE);
+
+    // Initialise the active SIB array.
+    for (count = 0; count < MAX_SIB_INDEX; count++)
+        active_sibs[count] = NULL;
+
+    return 0;
+}
+
+
+// SIB_GetSize() - Get the size of the user data in a SIB.
+
+int 
+SIB_GetSize(int sib_index, int *data_size)
+{
+    tSIB    *sib;
+
+    sib = active_sibs[sib_index];
+
+    if (sib == NULL) {
+        *data_size = 0;
+        return -1;
+    }
+
+    *data_size = sib->size = sizeof(tSIB);
+
+    return 0;
+}
+
+// SIB_Program() - create or update a SIB with new user data.
+//
+// Return: 0 if OK -1 otherwise
+
+int 
+SIB_Program(int sib_index, void *data_block, int data_size)
+{
+    tSIB    *old_sib;
+    tSIB    *new_sib;
+    int     sib_size;
+    cyg_uint32  *src;
+    cyg_uint32  *dest;
+
+    // Calculate the size of the SIB as a whole.
+    sib_size = data_size + sizeof(tSIB);
+
+    if (sib_size > MAX_SIB_SIZE)
+        return -1;
+
+    // Create the new SIB in local memory
+    new_sib = (tSIB *)&buffer;
+
+    new_sib->signature   = SIB_HEADER_SIGNATURE;
+    new_sib->size        = sib_size;
+    new_sib->index       = sib_index;
+
+    memcpy(new_sib->owner, active_id_string, SIB_OWNER_STRING_SIZE);
+
+    // Increment the revision number if this is updating a SIB.
+    old_sib = active_sibs[sib_index];
+
+    if (old_sib == NULL)
+        new_sib->revision = 0;
+    else
+        new_sib->revision = old_sib->revision + 1;
+
+    // Copy the user data into the SIB.
+    src     = (cyg_uint32 *)data_block;
+    dest    = (cyg_uint32 *)((cyg_uint32)new_sib + sizeof(tSIB));
+
+    while (data_size > 0) {
+        *dest++ = *src++;
+        data_size -= sizeof (cyg_uint32);
+    }
+
+    // Finally calculate the checksum and call write_sib.
+    new_sib->checksum = 0;
+    new_sib->checksum = sib_checksum (new_sib);
+
+    if (write_sib (new_sib) != 0)
+        return -1;
+ 
+    // Delete the SIB that this one replaces if there is one.
+    if (old_sib != NULL)
+        delete_sib (old_sib);
+
+    return 0;
+}
+
+// SIB_Erase() - erase a SIB
+//
+// Return: -1 if error 0 otherwise
+
+int 
+SIB_Erase(int sib_index)
+{
+    tSIB *sib;
+
+    sib = active_sibs[sib_index];
+
+    active_sibs[sib_index] = NULL;
+    
+    return delete_sib (sib);
+}
+
+// fLib_FindFooter() - find footer in flash memory
+//
+// Scan the flash memory from start for size bytes, returning a list of pointers to the
+// image footers. Pointer list should point to an area of ram supplied by the application
+// and should be large enough to contain a pointer to each logical block of flash in the 
+// specified area.
+// If the size is defined as zero, only the address of the next footer found is returned.
+// Parameters:
+//   cyg_uint32 *start
+//     pointer to the address of the flash memory to be scanned
+//   cyg_uint32 size
+//     size of the flash memory in bytes 
+//   tFooter **list                     
+//     pointer to a list of pointers to footers
+//
+//   Returns: number of flash footers found.                                      
+//
+
+cyg_uint32 
+fLib_FindFooter(cyg_uint32 *start, cyg_uint32 size, tFooter *list[])
+{                                                                                           
+    cyg_uint32    *end ;
+    cyg_uint32    count = 0;
+    cyg_uint32    logical_block = FLASH_BLOCK_SIZE;
+    cyg_uint32    block_mask;
+    tFooter   *test;
+
+    end = flash_info.end;
+   
+    // Start looking at each block boundary to see if there is a 
+    // structured footer there if so that is a footer to put in the footer list
+    //
+    // Initially we must get the nearest logical block boundary to the 
+    // initial address
+    block_mask = logical_block - 1;
+  
+    start = (cyg_uint32*)((int)start | block_mask);
+  
+    test = (tFooter*)(start - (sizeof(tFooter) >> 2) );
+    test = (tFooter*) ((char*)test + 1);
+  
+    // Now test should be at the first available footer location
+  
+    for ( ; (cyg_uint32*)test < end; test = (tFooter*)((char*)test + logical_block)) {
+        // initial check is to see if the type is deleted (ie empty block)
+	if (TYPE_DELETED != test->type) {
+	   // next check for a signature in the footer
+         
+	   if (FLASH_FOOTER_SIGNATURE == test->signature) {
+	      cyg_uint32 check = 0;
+	      cyg_uint32 *check_ptr = (cyg_uint32 *)test;
+	      count = (sizeof(tFooter) - 4) >> 2;	// sizeof will return bytes
+            
+	      // We're pretty certain by now but lets check the checksum to make fully sure
+	      for ( ; count > 0; count--) {
+		  if (*check_ptr > ~check)
+            	      check++;
+            	  check += *check_ptr++;
+	      }
+            
+	      if (test->checksum == ~check) {
+		  if (size != 0 )
+		      *list++ = test;
+		  else {
+		      // If the size was set at 0 - return only the first found footer
+		      *list = test;
+		      return 1;
+		  }
+	      }
+	   }
+	}
+	// This should carry on through checking each logical block boundary to end */
+    }
+
+    // tidy up the array/list
+    *list = NULL;
+    return count;
+}
+
+//
+// fLib_DeleteImage(tFooter *foot, tFlash *flash)
+//
+// Delete the image in flash as detailed by the specified image footer. We will have to
+// define the flash device to access the relevant flash delete routines
+// Parameters
+//   tFooter *foot
+//      pointer to the footer which defines the image to be deleted
+//
+// Returns: 0 if successful, otherwise -1.
+//
+
+static int
+fLib_DeleteImage(tFooter *foot)
+{                                                                                                 
+    cyg_uint32 delete_size , block_mask = flash_info.block_size;
+    cyg_uint8 *erase_addr = foot->blockBase;
+    cyg_uint8  complete_flag = 0;
+  
+     // presume that the erase size is chosen to cover the boundary size
+    block_mask -= 1;
+ 
+    delete_size = ((tImageInfo*)foot->infoBase)->length +
+      			((tImageInfo*)foot->infoBase)->header_length +
+      			sizeof (tImageInfo) + sizeof (tFooter);
+    delete_size |= block_mask;
+    delete_size += 1; /* for the boundary */
+
+    while (!complete_flag ) {
+      if (  delete_size > flash_info.block_size) {
+         delete_size -= flash_info.block_size;
+      } else 
+         complete_flag = 1;
+
+      flash_erase_block(erase_addr);
+      erase_addr += flash_info.block_size;
+    }
+    return 0;
+}
+
+//
+// fLib_FindImage(tFooter **list, cyg_uint32 imageNo, tFooter *foot)
+//
+// Scan the list of flash footers looking for a footer with an imageNumber which
+// matches the specified number.
+// If the specified footer pointer is not NULL, the footer is copied from flash.
+// Parameters:
+//   tFooter **list
+//      pointer to a list of pointers to footers
+//   unsigned32 imageNo
+//      number of image to be located
+//   tFooter *foot
+//      pointer to where the found footer should be copied
+//
+// Returns: 1 if successful, otherwise 0
+//
+
+static int
+fLib_FindImage(tFooter **list, char *name, tFooter *foot)
+{
+  // Initially, if there are no images in the flash we can just return so check 
+  if (*list == NULL)
+        return 0;
+  
+  // Now we can start checking for the images that are in flash
+  while (*list != NULL) {
+      tImageInfo *im = (tImageInfo *)(*list)->infoBase;
+      if (strncmp(name, im->name, 16) == 0 ) {
+         *foot = **list;
+         return 1;
+      }
+      list++;      
+  }
+
+  return 0;
+}
+
+#define FLASH_ADRS 0x23000000                                                      
+
+int 
+markBlock()
+{
+        tFooter footer;
+	tFooter *current;
+	cyg_uint32  writeOffset;
+
+        // Build a flash footer to describe this area.
+        footer.blockBase    = (char *)FLASH_ADRS;
+        footer.infoBase     = NULL;
+        footer.type         = 0x10000; //TYPE_WRS_SIB;
+        footer.signature    = FLASH_FOOTER_SIGNATURE;
+        footer.checksum     = 0;
+        footer.checksum     = footer_checksum (&footer);
+
+	current = (tFooter *)(FLASH_ADRS + FLASH_BLOCK_SIZE - sizeof (tFooter));
+
+	if ( current->type == TYPE_ARM_SIB)
+	    return 1;
+
+	writeOffset = FLASH_ADRS + FLASH_BLOCK_SIZE - sizeof (tFooter);
+
+	if (flash_program_buf(writeOffset, (unsigned long *)&footer, sizeof(tFooter)) < 0 ) 
+	    return 0;
+
+#ifdef TO_CHECK
+	if (sysFlashWrite(FLASH_CAST(&footer), sizeof(tFooter), 
+				  writeOffset,
+				  flashType, 0) != OK)
+		    return 0;
+#endif
+}
+
+void 
+arm_fis_list(void)
+{
+    int count = 0;
+    tFooter *footer;
+
+    fLib_FindFooter((cyg_uint32 *)FLASH_BASE, FLASH_SIZE, active_flash_footers);
+
+    diag_printf("Name              FLASH addr   Mem addr    Length    Entry point\n");
+    while ((footer = active_flash_footers[count++]) != NULL) {
+	if (footer->type == TYPE_ARM_EXEC) {
+	    diag_printf("%-16s  0x%08lX   0x%08lX  0x%06lX  0x%08lX\n",
+		   ((tImageInfo *)footer->infoBase)->name, 
+		   FLASH_BASE, footer->blockBase, 
+		   ((tImageInfo *)footer->infoBase)->length,
+		   ((tImageInfo *)footer->infoBase)->loadAddress);
+	} 
+    }
+}
+
+void 
+arm_fis_delete(char *name)
+{
+    tFooter footer;
+
+    if ( name == NULL ) return;
+
+    fLib_FindFooter((cyg_uint32 *)FLASH_BASE, FLASH_SIZE, active_flash_footers);
+
+    if ( fLib_FindImage(active_flash_footers, name, &footer) ) {
+        diag_printf("Found Image %s, base 0x%x\n", name, footer.blockBase);
+	fLib_DeleteImage(&footer);
+    }
+}
+
+static void 
+SIB_test(void)
+{
+    int count;
+    tFooter *footer;
+
+    fLib_FindFooter((cyg_uint32 *)FLASH_BASE, FLASH_SIZE, active_flash_footers);
+
+
+    // Find everything that looks like a SIB.
+    count       = 0;
+
+    diag_printf("\n");
+    while ((footer = active_flash_footers[count++]) != NULL) {
+	if (footer->type == TYPE_ARM_EXEC) {
+	    diag_printf("Blk: %d Image Nb: %3d Name: %s Load address: 0x%x Length 0x%x\n\n",
+		   AddressToBlock(footer->blockBase),
+		   ((tImageInfo *) footer->infoBase)->imageNumber,
+		   ((tImageInfo *)footer->infoBase)->name, 
+		   ((tImageInfo *)footer->infoBase)->loadAddress,
+		   ((tImageInfo *)footer->infoBase)->length);
+	} else if (footer->type == TYPE_ARM_SIB) {
+	    tSIB    *sib;
+
+	    sib = (tSIB *)footer->blockBase;
+	    diag_printf("SIB Address     Owner                        Size  Idx  Rev\n");
+	    diag_printf("-----------     -----                        ----  ---  ---\n");
+	    while (sib->signature == SIB_HEADER_SIGNATURE) {
+                if (sib_checksum (sib) == 0) {
+                    diag_printf("0x%08X  %-32s %4d %4d %4d\n\n", 
+			   (int)sib, sib->owner, sib->size, sib->index, sib->revision);
+		    sib = (tSIB *)((cyg_uint32)sib + sib->size);
+		} else {
+		    diag_printf("0x%08X  *** Bad Checksum ***\n", (int)sib);
+                break;
+		}
+	    }
+
+	} 
+    }
+}
+#endif // ARM_INTEGRATOR_FLASH
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/integrator/current/ChangeLog
@@ -0,0 +1,31 @@
+2001-10-30  Philippe Robin  <Philippe.Robin@arm.com>
+2001-10-30  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* New package for ARM Integrator serial driver derived from
+	ARM PID serial driver.
+
+//===========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. 
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/integrator/current/cdl/ser_arm_integrator.cdl
@@ -0,0 +1,170 @@
+# ====================================================================
+#
+#      ser_arm_integrator.cdl
+#
+#      eCos serial ARM/INTEGRATOR configuration data
+#
+# ====================================================================
+#####COPYRIGHTBEGIN####
+#                                                                          
+# -------------------------------------------                              
+# The contents of this file are subject to the Red Hat eCos Public License 
+# Version 1.1 (the "License"); you may not use this file except in         
+# compliance with the License.  You may obtain a copy of the License at    
+# http://www.redhat.com/                                                   
+#                                                                          
+# Software distributed under the License is distributed on an "AS IS"      
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+# License for the specific language governing rights and limitations under 
+# the License.                                                             
+#                                                                          
+# The Original Code is eCos - Embedded Configurable Operating System,      
+# released September 30, 1998.                                             
+#                                                                          
+# The Initial Developer of the Original Code is Red Hat.                   
+# Portions created by Red Hat are                                          
+# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      David A Rusling
+# Original data:  David A Rusling
+# Contributors:	  Philippe Robin
+# Date:           November 7, 2000
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_INTEGRATOR {
+    display       "ARM INTEGRATOR serial device drivers"
+
+    parent        CYGPKG_IO_SERIAL_DEVICES
+    active_if     CYGPKG_IO_SERIAL
+    active_if     CYGPKG_HAL_ARM_INTEGRATOR
+
+    requires      CYGPKG_ERROR
+    include_dir   cyg/io
+    description   "
+           This option enables the serial device drivers for the
+           ARM INTEGRATOR."
+    doc           redirect/ecos-device-drivers.html
+
+    compile       -library=libextras.a   integrator_serial_with_ints.c
+
+    define_proc {
+        puts $::cdl_system_header "/***** serial driver proc output start *****/"
+        puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_integrator.h>"
+        puts $::cdl_system_header "/*****  serial driver proc output end  *****/"
+    }
+
+    cdl_component CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0 {
+	display       "ARM INTEGRATOR serial port 0 driver"
+	flavor        bool
+	default_value 1
+	description   "
+        This option includes the serial device driver for the ARM INTEGRATOR 
+        port 0."
+
+	cdl_option CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_NAME {
+	    display       "Device name for ARM INTEGRATOR serial port 0 driver"
+	    flavor        data
+	    default_value {"\"/dev/ser0\""}
+	    description   "
+            This option specifies the name of the serial device for the 
+            ARM INTEGRATOR port 0."
+	}
+
+	cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BAUD {
+	    display       "Baud rate for the ARM INTEGRATOR serial port 0 driver"
+	    flavor        data
+	    legal_values  { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+	    		    4800 7200 9600 14400 19200 38400 57600 115200 234000
+			   }
+	    default_value 38400
+	    description   "
+            This option specifies the default baud rate (speed) for the 
+            ARM INTEGRATOR port 0."
+	}
+
+	cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE {
+	    display       "Buffer size for the ARM INTEGRATOR serial port 0 driver"
+	    flavor        data
+	    legal_values  0 to 8192
+	    default_value 128
+	    description   "
+            This option specifies the size of the internal buffers used 
+            for the ARM INTEGRATOR port 0."
+	}
+    }
+
+    cdl_component CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL1 {
+	display       "ARM INTEGRATOR serial port 1 driver"
+	flavor        bool
+	default_value 1
+	description   "
+        This option includes the serial device driver for the ARM INTEGRATOR 
+        port 1."
+
+	cdl_option CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_NAME {
+	    display       "Device name for ARM INTEGRATOR serial port 1 driver"
+	    flavor        data
+	    default_value {"\"/dev/ser1\""}
+	    description   "
+            This option specifies the name of the serial device for the 
+            ARM INTEGRATOR port 1."
+	}
+
+	cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BAUD {
+	    display       "Baud rate for the ARM INTEGRATOR serial port 1 driver"
+	    flavor        data
+	    legal_values  { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+                      4800 7200 9600 14400 19200 38400 57600 115200 234000
+            }
+	    default_value 38400
+	    description   "
+            This option specifies the default baud rate (speed) for the
+            ARM INTEGRATOR port 1."
+	}
+    }
+
+    cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE {
+        display       "Buffer size for the ARM INTEGRATOR serial port 1 driver"
+        flavor        data
+        legal_values  0 to 8192
+        default_value 128
+        description   "
+            This option specifies the size of the internal buffers used 
+            for the ARM INTEGRATOR port 1."
+    }
+
+    cdl_component CYGPKG_IO_SERIAL_ARM_INTEGRATOR_TESTING {
+        display    "Testing parameters"
+        flavor     bool
+        calculated 1
+        active_if  CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0
+
+# FIXME: I have no idea what the integrator hardware doesn't support -Jifl
+#        implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+#        implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+#        implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+        
+        cdl_option CYGPRI_SER_TEST_SER_DEV {
+            display       "Serial device used for testing"
+            flavor        data
+            default_value { CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_NAME }
+        }
+
+        define_proc {
+            puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"arminteg\""
+            puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV  \"/dev/tty0\""
+        }
+    }
+}
+
+# EOF ser_arm_integrator.cdl
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/integrator/current/src/integrator_serial.h
@@ -0,0 +1,205 @@
+#ifndef CYGONCE_ARM_INTEGRATOR_SERIAL_H
+#define CYGONCE_ARM_INTEGRATOR_SERIAL_H
+
+// ====================================================================
+//
+//      integrator_serial.h
+//
+//      Device I/O - Description of ARM INTEGRATOR serial hardware
+//
+// ====================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           David A Rusling
+// Contributors:        Philippe Robin
+// Date:        	November 7, 2000
+// Purpose:     	Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on ARM INTEGRATOR7T
+
+struct serial_port {
+    unsigned char _byte[32];
+};
+
+// Little-endian version
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+
+#define reg(n) _byte[n*4]
+
+#else // Big-endian version
+
+#define reg(n) _byte[(n*4)^3]
+
+#endif
+
+/* -------------------------------------------------------------------------------
+ *  From AMBA UART (PL010) Block Specification (ARM-0001-CUST-DSPC-A03)
+ * -------------------------------------------------------------------------------
+ *  UART Register Offsets.
+ *  
+ */
+#define AMBA_UARTDR                     0x00	 /*  Data read or written from the interface. */
+#define AMBA_UARTRSR                    0x04	 /*  Receive status register (Read). */
+#define AMBA_UARTECR                    0x04	 /*  Error clear register (Write). */
+#define AMBA_UARTLCR_H                  0x08	 /*  Line control register, high byte. */
+#define AMBA_UARTLCR_M                  0x0C	 /*  Line control register, middle byte. */
+#define AMBA_UARTLCR_L                  0x10	 /*  Line control register, low byte. */
+#define AMBA_UARTCR                     0x14	 /*  Control register. */
+#define AMBA_UARTFR                     0x18	 /*  Flag register (Read only). */
+#define AMBA_UARTIIR                    0x1C	 /*  Interrupt indentification register (Read). */
+#define AMBA_UARTICR                    0x1C	 /*  Interrupt clear register (Write). */
+#define AMBA_UARTILPR                   0x20	 /*  IrDA low power counter register. */
+
+#define AMBA_UARTRSR_OE                 0x08
+#define AMBA_UARTRSR_BE                 0x04
+#define AMBA_UARTRSR_PE                 0x02
+#define AMBA_UARTRSR_FE                 0x01
+
+#define AMBA_UARTFR_TXFF                0x20
+#define AMBA_UARTFR_RXFE                0x10
+#define AMBA_UARTFR_BUSY                0x08
+#define AMBA_UARTFR_TMSK                (AMBA_UARTFR_TXFF + AMBA_UARTFR_BUSY)
+ 
+#define AMBA_UARTCR_RTIE                0x40
+#define AMBA_UARTCR_TIE                 0x20
+#define AMBA_UARTCR_RIE                 0x10
+#define AMBA_UARTCR_MSIE                0x08
+#define AMBA_UARTCR_IIRLP               0x04
+#define AMBA_UARTCR_SIREN               0x02
+#define AMBA_UARTCR_UARTEN              0x01
+ 
+#define AMBA_UARTLCR_H_WLEN_8           0x60
+#define AMBA_UARTLCR_H_WLEN_7           0x40
+#define AMBA_UARTLCR_H_WLEN_6           0x20
+#define AMBA_UARTLCR_H_WLEN_5           0x00
+#define AMBA_UARTLCR_H_FEN              0x10
+#define AMBA_UARTLCR_H_STP2             0x08
+#define AMBA_UARTLCR_H_EPS              0x04
+#define AMBA_UARTLCR_H_PEN              0x02
+#define AMBA_UARTLCR_H_BRK              0x01
+
+#define AMBA_UARTIIR_RTIS               0x08
+#define AMBA_UARTIIR_TIS                0x04
+#define AMBA_UARTIIR_RIS                0x02
+#define AMBA_UARTIIR_MIS                0x01
+
+#define ARM_BAUD_460800                 1
+#define ARM_BAUD_230400                 3
+#define ARM_BAUD_115200                 7
+#define ARM_BAUD_57600                  15
+#define ARM_BAUD_38400                  23
+#define ARM_BAUD_19200                  47
+#define ARM_BAUD_14400                  63
+#define ARM_BAUD_9600                   95
+#define ARM_BAUD_4800                   191
+#define ARM_BAUD_2400                   383
+#define ARM_BAUD_1200                   767
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS  0x04
+#define IER_MS  0x08
+
+// Line Control Register
+#define LCR_WL5 0x00    // Word length
+#define LCR_WL6 0x20
+#define LCR_WL7 0x40
+#define LCR_WL8 0x60
+
+#define LCR_SB1 0x00    // Number of stop bits
+#define LCR_SB1_5 0x00  // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x08
+
+#define LCR_PN  0x00    // Parity mode - none
+#define LCR_PE  0x06    // Parity mode - even
+#define LCR_PO  0x02    // Parity mode - odd
+#define LCR_PM  0x00    // Forced "mark" parity
+#define LCR_PS  0x00    // Forced "space" parity
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08   // Enable interrupts
+
+static unsigned short select_baud[] = {
+    0,               // Unused
+    0,               // 50
+    0,               // 75
+    0,               // 110
+    0,               // 134.5
+    0,               // 150
+    0,               // 200
+    0,               // 300
+    0,               // 600
+    ARM_BAUD_1200,   // 1200
+    0,               // 1800
+    ARM_BAUD_2400,   // 2400
+    0,               // 3600
+    ARM_BAUD_4800,   // 4800
+    0,               // 7200
+    ARM_BAUD_9600,   // 9600
+    ARM_BAUD_14400,  // 14400
+    ARM_BAUD_19200,  // 19200
+    ARM_BAUD_38400,  // 38400
+    ARM_BAUD_57600,  // 57600
+    ARM_BAUD_115200, // 115200
+    ARM_BAUD_230400, // 230400
+};
+
+static unsigned char select_word_length[] = {
+    LCR_WL5,    // 5 bits / word (char)
+    LCR_WL6,
+    LCR_WL7,
+    LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+    0,
+    LCR_SB1,    // 1 stop bit
+    LCR_SB1_5,  // 1.5 stop bit
+    LCR_SB2     // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+    LCR_PN,     // No parity
+    LCR_PE,     // Even parity
+    LCR_PO,     // Odd parity
+    LCR_PM,     // Mark parity
+    LCR_PS,     // Space parity
+};
+
+#endif // CYGONCE_ARM_INTEGRATOR_SERIAL_H
new file mode 100644
--- /dev/null
+++ b/packages/devs/serial/arm/integrator/current/src/integrator_serial_with_ints.c
@@ -0,0 +1,402 @@
+//==========================================================================
+//
+//      io/serial/arm/integrator_serial_with_ints.c
+//
+//      ARM INTEGRATOR Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    David A Rusling
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      INTEGRATOR Serial I/O module (interrupt driven)
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io.h>
+#include <pkgconf/io_serial.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_INTEGRATOR
+#include "integrator_serial.h"
+
+typedef struct integrator_serial_info {
+    CYG_ADDRWORD   base;
+    CYG_WORD       int_num;
+    cyg_interrupt  serial_interrupt;
+    cyg_handle_t   serial_interrupt_handle;
+} integrator_serial_info;
+
+static bool integrator_serial_init(struct cyg_devtab_entry *tab);
+static bool integrator_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo integrator_serial_lookup(struct cyg_devtab_entry **tab, 
+                                   struct cyg_devtab_entry *sub_tab,
+                                   const char *name);
+static unsigned char integrator_serial_getc(serial_channel *chan);
+static Cyg_ErrNo integrator_serial_set_config(serial_channel *chan, cyg_uint32 key,
+					      const void *xbuf, cyg_uint32 *len);
+static void integrator_serial_start_xmit(serial_channel *chan);
+static void integrator_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 integrator_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void       integrator_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(integrator_serial_funs, 
+                   integrator_serial_putc, 
+                   integrator_serial_getc,
+                   integrator_serial_set_config,
+                   integrator_serial_start_xmit,
+                   integrator_serial_stop_xmit
+    );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0
+#define INTEGRATOR_UART0_BASE           0x16000000	 /*  UART 0 */
+static integrator_serial_info integrator_serial_info0 = {INTEGRATOR_UART0_BASE, CYGNUM_HAL_INTERRUPT_UARTINT0};
+#if CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE > 0
+static unsigned char integrator_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE];
+static unsigned char integrator_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(integrator_serial_channel0,
+                                       integrator_serial_funs, 
+                                       integrator_serial_info0,
+                                       CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BAUD),
+                                       CYG_SERIAL_STOP_DEFAULT,
+                                       CYG_SERIAL_PARITY_DEFAULT,
+                                       CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                                       CYG_SERIAL_FLAGS_DEFAULT,
+                                       &integrator_serial_out_buf0[0], sizeof(integrator_serial_out_buf0),
+                                       &integrator_serial_in_buf0[0], sizeof(integrator_serial_in_buf0)
+    );
+#else
+static SERIAL_CHANNEL(integrator_serial_channel0,
+                      integrator_serial_funs, 
+                      integrator_serial_info0,
+                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BAUD),
+                      CYG_SERIAL_STOP_DEFAULT,
+                      CYG_SERIAL_PARITY_DEFAULT,
+                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                      CYG_SERIAL_FLAGS_DEFAULT
+    );
+#endif
+
+DEVTAB_ENTRY(integrator_serial_io0, 
+             CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_NAME,
+             0,                     // Does not depend on a lower level interface
+             &cyg_io_serial_devio, 
+             integrator_serial_init, 
+             integrator_serial_lookup,     // Serial driver may need initializing
+             &integrator_serial_channel0
+    );
+#endif //  CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL1
+#define INTEGRATOR_UART1_BASE           0x17000000	 /*  UART 1 */
+static integrator_serial_info integrator_serial_info1 = {INTEGRATOR_UART1_BASE, CYGNUM_HAL_INTERRUPT_UARTINT1};
+#if CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE > 0
+static unsigned char integrator_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE];
+static unsigned char integrator_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(integrator_serial_channel1,
+                                       integrator_serial_funs, 
+                                       integrator_serial_info1,
+                                       CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BAUD),
+                                       CYG_SERIAL_STOP_DEFAULT,
+                                       CYG_SERIAL_PARITY_DEFAULT,
+                                       CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                                       CYG_SERIAL_FLAGS_DEFAULT,
+                                       &integrator_serial_out_buf1[0], sizeof(integrator_serial_out_buf1),
+                                       &integrator_serial_in_buf1[0], sizeof(integrator_serial_in_buf1)
+    );
+#else
+static SERIAL_CHANNEL(integrator_serial_channel1,
+                      integrator_serial_funs, 
+                      integrator_serial_info1,
+                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BAUD),
+                      CYG_SERIAL_STOP_DEFAULT,
+                      CYG_SERIAL_PARITY_DEFAULT,
+                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
+                      CYG_SERIAL_FLAGS_DEFAULT
+    );
+#endif
+
+DEVTAB_ENTRY(integrator_serial_io1, 
+             CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_NAME,
+             0,                     // Does not depend on a lower level interface
+             &cyg_io_serial_devio, 
+             integrator_serial_init, 
+             integrator_serial_lookup,     // Serial driver may need initializing
+             &integrator_serial_channel1
+    );
+#endif //  CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL1
+
+#define GET_INTERRUPT_STATUS(p)           IO_READ((p) + AMBA_UARTIIR)
+#define GET_STATUS(p)		          (IO_READ((p) + AMBA_UARTFR))
+#define GET_CHAR(p)		          (IO_READ((p) + AMBA_UARTDR))
+#define PUT_CHAR(p, c)		          (IO_WRITE(((p) + AMBA_UARTDR), (c)))
+#define IO_READ(p)                        ((*(volatile unsigned int *)(p)) & 0xFF)
+#define IO_WRITE(p, c)                    (*(unsigned int *)(p) = (c))
+#define RX_DATA(s)		          (((s) & AMBA_UARTFR_RXFE) == 0)
+#define TX_READY(s)		          (((s) & AMBA_UARTFR_TXFF) == 0)
+#define TX_EMPTY(p)		          ((GET_STATUS(p) & AMBA_UARTFR_TMSK) == 0)
+
+// debugging help
+static int chars_rx = 0 ;
+static int chars_tx = 0 ;
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+integrator_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+    unsigned int port = (unsigned int)integrator_chan->base;
+    unsigned short baud_divisor = select_baud[new_config->baud];
+    unsigned char _lcr ;
+
+    // don't do this baud rate...
+    if (baud_divisor == 0) return false;  // Invalid configuration
+
+    // first, disable everything 
+    IO_WRITE(port + AMBA_UARTCR, 0x0);
+
+    // Set baud rate 
+    IO_WRITE(port + AMBA_UARTLCR_M, ((baud_divisor & 0xf00) >> 8));
+    IO_WRITE(port + AMBA_UARTLCR_L, (baud_divisor & 0xff));
+    
+    // ----------v----------v----------v----------v---------- 
+    // NOTE: MUST BE WRITTEN LAST (AFTER UARTLCR_M & UARTLCR_L) 
+    // ----------^----------^----------^----------^----------
+    _lcr = 
+      select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | 
+      select_stop_bits[new_config->stop] |
+      select_parity[new_config->parity] | AMBA_UARTLCR_H_FEN ;
+    IO_WRITE(port + AMBA_UARTLCR_H, _lcr);
+    
+    // finally, enable the uart 
+    IO_WRITE(port + AMBA_UARTCR, (AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE | AMBA_UARTCR_UARTEN));
+
+    // save the configuration
+    if (new_config != &chan->config) {
+        chan->config = *new_config;
+    }
+
+    // success
+    return true;
+}
+
+// Function to initialize the device.  Called at bootstrap time.
+static bool 
+integrator_serial_init(struct cyg_devtab_entry *tab)
+{
+    serial_channel *chan = (serial_channel *)tab->priv;
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+    diag_printf("INTEGRATOR SERIAL init - dev: %x.%d\n", integrator_chan->base, integrator_chan->int_num);
+#endif
+    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
+    if (chan->out_cbuf.len != 0) {
+        cyg_drv_interrupt_create(integrator_chan->int_num,
+                                 99,                     // Priority - what goes here?
+                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
+                                 integrator_serial_ISR,
+                                 integrator_serial_DSR,
+                                 &integrator_chan->serial_interrupt_handle,
+                                 &integrator_chan->serial_interrupt);
+        cyg_drv_interrupt_attach(integrator_chan->serial_interrupt_handle);
+        cyg_drv_interrupt_unmask(integrator_chan->int_num);
+    }
+    integrator_serial_config_port(chan, &chan->config, true);
+    return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo 
+integrator_serial_lookup(struct cyg_devtab_entry **tab, 
+                  struct cyg_devtab_entry *sub_tab,
+                  const char *name)
+{
+    serial_channel *chan = (serial_channel *)(*tab)->priv;
+    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
+    return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+integrator_serial_putc(serial_channel *chan, unsigned char c)
+{
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+    unsigned int status = GET_STATUS(integrator_chan->base) ;
+
+    if (TX_READY(status)) {
+// Transmit buffer is empty
+        PUT_CHAR(integrator_chan->base, c) ;
+	chars_tx++ ;
+        return true;
+    } else {
+// No space
+        return false;
+    }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char 
+integrator_serial_getc(serial_channel *chan)
+{
+    unsigned char c;
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+    unsigned int status ;
+
+    do {
+        status = GET_STATUS(integrator_chan->base) ;
+    } while (!RX_DATA(status)) ;                   // Wait for char
+
+    chars_rx++ ;
+
+    // get it 
+    c = GET_CHAR(integrator_chan->base) ;
+    return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+integrator_serial_set_config(serial_channel *chan, cyg_uint32 key, const void *xbuf,
+                      cyg_uint32 *len)
+{
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+    switch (key) {
+    case CYG_IO_SET_CONFIG_SERIAL_INFO:
+      {
+        cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+        if ( *len < sizeof(cyg_serial_info_t) ) {
+            return -EINVAL;
+        }
+        *len = sizeof(cyg_serial_info_t);
+        if ( true != integrator_serial_config_port(chan, config, false) )
+            return -EINVAL;
+      }
+      break;
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+#ifdef FIXME
+    case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+      {
+          volatile struct serial_port *port = (volatile struct serial_port *)integrator_chan->base;
+          cyg_uint8 *f = (cyg_uint8 *)xbuf;
+          unsigned char mask=0;
+          if ( *len < *f )
+              return -EINVAL;
+          
+          if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX )
+              mask = MCR_RTS;
+          if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX )
+              mask |= MCR_DTR;
+          if (*f) // we should throttle
+              port->REG_mcr &= ~mask;
+          else // we should no longer throttle
+              port->REG_mcr |= mask;
+      }
+      break;
+    case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+        // Nothing to do because we do support both RTSCTS and DSRDTR flow
+        // control.
+        // Other targets would clear any unsupported flags here.
+        // We just return ENOERR.
+      break;
+#else
+#error "Flow control for Integrator not integrated!"
+#endif
+#endif
+    default:
+        return -EINVAL;
+    }
+    return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+integrator_serial_start_xmit(serial_channel *chan)
+{
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+    IO_WRITE(integrator_chan->base + AMBA_UARTCR, 
+	     IO_READ(integrator_chan->base + AMBA_UARTCR) | AMBA_UARTCR_TIE);
+}
+
+// Disable the transmitter on the device
+static void 
+integrator_serial_stop_xmit(serial_channel *chan)
+{
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+    IO_WRITE(integrator_chan->base + AMBA_UARTCR, 
+	     IO_READ(integrator_chan->base + AMBA_UARTCR) & ~AMBA_UARTCR_TIE);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32 
+integrator_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+    cyg_drv_interrupt_mask(integrator_chan->int_num);
+    cyg_drv_interrupt_acknowledge(integrator_chan->int_num);
+    return CYG_ISR_CALL_DSR;  // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void       
+integrator_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+    serial_channel *chan = (serial_channel *)data;
+    integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+    volatile unsigned char isr = GET_INTERRUPT_STATUS(integrator_chan->base) ;
+
+    while ((isr & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_TIS | AMBA_UARTIIR_RIS)) != 0) {
+        if (isr & AMBA_UARTIIR_TIS) {
+            (chan->callbacks->xmt_char)(chan);
+        } else if (isr & AMBA_UARTIIR_RTIS) {
+	    chars_rx++ ;
+            (chan->callbacks->rcv_char)(chan, GET_CHAR(integrator_chan->base));
+        } else if (isr & AMBA_UARTIIR_RIS) {
+	    chars_rx++ ;
+            (chan->callbacks->rcv_char)(chan, GET_CHAR(integrator_chan->base));
+        }
+	isr = GET_INTERRUPT_STATUS(integrator_chan->base) ;
+    }
+    cyg_drv_interrupt_unmask(integrator_chan->int_num);
+}
+#endif
--- a/packages/ecos.db
+++ b/packages/ecos.db
@@ -132,6 +132,7 @@ package CYGPKG_DEVS_FLASH_INTEL_BOOTBLOC
            This package contains hardware support for Intel boot block flash memory."
 }
 
+
 package CYGPKG_DEVS_FLASH_AMD_AM29XXXXX {
 	alias 		{ "Support for AMD AM29xxxxx flash memory" flash_amd_am29xxxxx }
 	directory	devs/flash/amd/am29xxxxx
@@ -303,6 +304,16 @@ package CYGPKG_DEVS_FLASH_IQ80310 {
 	   on the Cyclone IQ80310 platform."
 }
 
+package CYGPKG_DEVS_FLASH_INTEGRATOR {
+        alias           { "FLASH memory support for ARM INTEGRATOR" flash_integrator }
+        directory       devs/flash/arm/integrator
+        script          flash_integrator.cdl
+        hardware
+        description "
+           This package contains hardware support for FLASH memory
+           on the ARM INTEGRATOR platform."
+}
+
 package CYGPKG_DEVS_FLASH_MBX {
 	alias 		{ "FLASH memory support for Motorola PowerPC/860 MBX" flash_mbx }
 	directory	devs/flash/powerpc/mbx
@@ -433,6 +444,15 @@ package CYGPKG_IO_SERIAL_ARM_E7T {
     description       "ARM AEB-2 (E7T) serial device drivers"
 }
 
+package CYGPKG_IO_SERIAL_ARM_INTEGRATOR {
+    alias             { "ARM INTEGRATOR serial device drivers"
+                        devs_serial_arm_integrator integrator_serial_driver }
+    hardware
+    directory         devs/serial/arm/integrator
+    script            ser_arm_integrator.cdl    
+    description       "ARM INTEGRATOR serial device drivers"
+}
+
 package CYGPKG_IO_SERIAL_ARM_AT91 {
     alias 	      { "Atmel AT91 evaluation board (EB40)"
                         devs_serial_arm_at91 at91_serial_driver }
@@ -713,6 +733,15 @@ package CYGPKG_DEVS_ETH_ARM_FLEXANET {
                    ethernet device on the Flexanet board."
 }
 
+package CYGPKG_DEVS_ETH_ARM_INTEGRATOR {
+        alias           { "ARM INTEGRATOR with Intel PRO/100+ ethernet driver"
+                           devs_eth_arm_integrator integrator_eth_driver }
+        hardware
+        directory       devs/eth/arm/integrator
+        script          integrator_eth_drivers.cdl
+        description     "Ethernet driver for Intel PRO/100+ boards on ARM INTEGRATOR."
+}
+
 package CYGPKG_DEVS_ETH_POWERPC_QUICC {
 	alias 		{ "QUICC ethernet driver" quicc_eth_driver }
 	hardware
@@ -1179,6 +1208,16 @@ The e7t HAL package provides the support
 Evaluator7T board (aka the AEB-2)."
 }
 
+package CYGPKG_HAL_ARM_INTEGRATOR {
+        alias           { "ARM development board (INTEGRATOR)" hal_arm_integrator arm_integrator_hal }
+        directory       hal/arm/integrator
+        script          hal_arm_integrator.cdl
+        hardware
+        description "
+        The INTEGRATOR HAL package provides the support needed to 
+        run eCos on a ARM INTEGRATOR eval board."
+}
+
 package CYGPKG_HAL_ARM_AT91 {
 	alias		{ "Atmel evaluation board (EB40)" hal_arm_at91 arm_at91_hal }
 	directory	hal/arm/at91
@@ -1209,6 +1248,7 @@ package CYGPKG_HAL_ARM_ARM9 {
         eCos on a ARM9 based systems."
 }
 
+
 package CYGPKG_HAL_ARM_SA11X0 {
 	alias		{ "Intel SA11X0 Chipset" hal_arm_sa11x0 }
 	directory	hal/arm/sa11x0/var
@@ -1929,6 +1969,21 @@ The aeb target provides the packages nee
 Evaluator7T board (aka AEB-2)."
 }
 
+target integrator {
+        alias { "ARM development board (INTEGRATOR)" INTEGRATOR }
+        packages { CYGPKG_HAL_ARM 
+                   CYGPKG_HAL_ARM_INTEGRATOR 
+                   CYGPKG_IO_PCI
+                   CYGPKG_DEVS_ETH_ARM_INTEGRATOR
+                   CYGPKG_IO_SERIAL_ARM_INTEGRATOR
+                   CYGPKG_DEVS_FLASH_INTEGRATOR
+        }
+        description "
+        The INTEGRATOR target provides the packages needed to 
+        run eCos on an ARM development board (formerly known 
+        as INTEGRATOR)."
+}
+
 target at91 {
 	alias { "Atmel evaluation board (EB40)" eb40 }
 	packages { CYGPKG_HAL_ARM
@@ -1956,6 +2011,7 @@ target ebsa285 {
         eCos on an Intel EBSA285 StrongARM board."
 }
 
+
 target assabet {
 	alias { "Intel StrongARM SA1110 board" assabet }
 	packages { CYGPKG_HAL_ARM
--- a/packages/hal/arm/arch/current/ChangeLog
+++ b/packages/hal/arm/arch/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-10-29  Hugo Tyson  <hmt@redhat.com>
+
+	* src/arm.ld (SECTION_rom_vectors): Define symbols used for ROMRAM
+	startup; for some reason these were not in the trunk.  They are:
+	__rom_vectors_vma and __rom_vectors_lma
+
 2001-10-24  Gary Thomas  <gthomas@redhat.com>
 
 	* src/hal_misc.c (hal_msbindex): Fix calculation.
--- a/packages/hal/arm/arch/current/src/arm.ld
+++ b/packages/hal/arm/arch/current/src/arm.ld
@@ -87,8 +87,10 @@ OUTPUT_FORMAT(elf32-bigarm)
 
 #define SECTION_rom_vectors(_region_, _vma_, _lma_) \
     .rom_vectors _vma_ : _lma_ \
-    { FORCE_OUTPUT; KEEP (*(.vectors)) } \
-    > _region_
+    { __rom_vectors_vma = ABSOLUTE(.); \
+      FORCE_OUTPUT; KEEP (*(.vectors)) } \
+    > _region_ \
+    __rom_vectors_lma = LOADADDR(.rom_vectors);
 
 #define SECTION_text(_region_, _vma_, _lma_) \
     .text _vma_ : _lma_ \
--- a/packages/hal/arm/arm9/var/current/ChangeLog
+++ b/packages/hal/arm/arm9/var/current/ChangeLog
@@ -1,3 +1,13 @@
+2001-11-01  Jesper Skov  <jskov@redhat.com>
+
+	* src/arm9_misc.c (cyg_hal_arm9_soft_reset): Attempt at soft
+	reset. Doesn't quite work though, and it's unclear why.
+
+2001-10-28  Gary Thomas  <gthomas@redhat.com>
+
+	* include/hal_cache.h: Fix DATA cache flush for 920,922.  This was
+	off-by-one, leaving part of the cache unflushed.
+
 2001-08-13  Jesper Skov  <jskov@redhat.com>
 
 	* include/hal_cache.h: Support ARM variants 920, 922, 925 and 940.
--- a/packages/hal/arm/arm9/var/current/include/hal_cache.h
+++ b/packages/hal/arm/arm9/var/current/include/hal_cache.h
@@ -72,7 +72,7 @@
 
 # define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX
 # define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX_STEP  0x20
-# define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX_LIMIT 0xe0
+# define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX_LIMIT 0x100
 
 #elif defined(CYGPKG_HAL_ARM_ARM9_ARM922T)
 # define HAL_ICACHE_SIZE                 0x2000
@@ -89,7 +89,7 @@
 
 # define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX
 # define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX_STEP  0x20
-# define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX_LIMIT 0x60
+# define CYGHWR_HAL_ARM_ARM9_CLEAN_DCACHE_INDEX_LIMIT 0x80
 
 #elif defined(CYGPKG_HAL_ARM_ARM9_ARM925T)
 # define HAL_ICACHE_SIZE                 0x4000
--- a/packages/hal/arm/arm9/var/current/src/arm9_misc.c
+++ b/packages/hal/arm/arm9/var/current/src/arm9_misc.c
@@ -75,5 +75,26 @@ void hal_hardware_init(void)
 #endif
 }
 
+void
+cyg_hal_arm9_soft_reset(CYG_ADDRESS entry)
+{
+
+    /* It would probably make more sense to have the
+       clear/drain/invalidate after disabling the cache and MMU, but
+       then we'd have to know the (unmapped) address of this code. */
+    asm volatile ("mov r1, #0;"
+                  "mcr p15,0,r1,c7,c7,0;"  /* clear I+DCache */
+                  "mcr p15,0,r1,c7,c10,4;" /* Drain Write Buffer */
+                  "mcr p15,0,r1,c8,c7,0;"  /* Invalidate TLBs */
+                  "mrc p15,0,r1,c1,c0,0;"
+                  "bic r1,r1,#0x1000;"     /* disable ICache */
+                  "bic r1,r1,#0x0007;"     /* disable DCache, MMU and alignment faults */
+                  "mcr p15,0,r1,c1,c0,0;"
+                  "nop;"                   /* delay 1 */
+                  "mov pc, %0;"            /* delay 2  - next instruction should be fetched flat */
+                  : : "r" (entry) : "r1");
+    for(;;);
+}
+
 /*------------------------------------------------------------------------*/
 // EOF arm9_misc.c
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/ChangeLog
@@ -0,0 +1,29 @@
+2001-10-30  Philippe Robin <Philippe.Robin@arm.com>
+
+	* Initial version of integrator package.
+
+//===========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//===========================================================================
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/cdl/hal_arm_integrator.cdl
@@ -0,0 +1,457 @@
+# ====================================================================
+#
+#      hal_arm_integrator.cdl
+#
+#      INTEGRATOR board HAL package configuration data
+#
+# ====================================================================
+#####COPYRIGHTBEGIN####
+#                                                                          
+# -------------------------------------------                              
+# The contents of this file are subject to the Red Hat eCos Public License 
+# Version 1.1 (the "License"); you may not use this file except in         
+# compliance with the License.  You may obtain a copy of the License at    
+# http://www.redhat.com/                                                   
+#                                                                          
+# Software distributed under the License is distributed on an "AS IS"      
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+# License for the specific language governing rights and limitations under 
+# the License.                                                             
+#                                                                          
+# The Original Code is eCos - Embedded Configurable Operating System,      
+# released September 30, 1998.                                             
+#                                                                          
+# The Initial Developer of the Original Code is Red Hat.                   
+# Portions created by Red Hat are                                          
+# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      David A Rusling
+# Original data:  gthomas
+# Contributors:   Philippe Robin
+# Date:           November 7, 2000
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL_ARM_INTEGRATOR {
+    display       "ARM INTEGRATOR evaluation board"
+    parent        CYGPKG_HAL_ARM
+    define_header hal_arm_integrator.h
+    include_dir   cyg/hal
+    hardware
+    description   "
+        The integrator HAL package provides the support needed to run
+        eCos on an ARM INTEGRATOR evaluation board."
+
+    compile       hal_diag.c integrator_misc.c 
+
+    implements    CYGINT_HAL_DEBUG_GDB_STUBS
+    implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT_NOT_GUARANTEED
+    implements    CYGINT_HAL_ARM_THUMB_ARCH
+    implements    CYGINT_HAL_ARM_BIGENDIAN
+    implements    CYGINT_HAL_ARM_ARCH_ARM7
+    implements    CYGINT_HAL_ARM_ARCH_ARM9
+
+    define_proc {
+        puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H   <pkgconf/hal_arm.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_integrator.h>"
+        puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_IO_H <cyg/hal/plf_io.h>"
+        puts $::cdl_header ""
+        puts $::cdl_header "#define HAL_PLATFORM_CPU    \"ARM 7TDMI\""
+        puts $::cdl_header "#define HAL_PLATFORM_BOARD  \"INTEGRATOR\""
+        puts $::cdl_header "#define HAL_PLATFORM_EXTRA  \"\""
+        puts $::cdl_header ""
+    }
+
+
+    cdl_component CYG_HAL_STARTUP {
+        display       "Startup type"
+        flavor        data
+        legal_values  {"RAM" "ROM"}
+        default_value {"RAM"}
+	no_define
+	define -file system.h CYG_HAL_STARTUP
+        description   "
+            When targetting the INTEGRATOR eval board it is possible to build
+            the system for either RAM bootstrap or ROM bootstrap(s). Select
+            'ram' when building programs to load into RAM using onboard
+            debug software such as Angel or eCos GDB stubs.  Select 'rom'
+            when building a stand-alone application which will be put
+            into ROM."
+
+    }
+
+   cdl_option CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_BASE {
+       display            "Base of memory accessible via PCI space"
+       flavor             data
+       legal_values       0 to 0x80000000
+       default_value      0x80000000
+       active_if          CYGPKG_IO_PCI
+       description "
+           This option determines the base of the INTEGRATOR memory 
+           which can be accessed via the PCI bus. Change in 256kB
+           increments."
+   }
+
+   cdl_option CYGHWR_HAL_ARM_INTEGRATOR_PCI_MEM_MAP_SIZE {
+       display            "Size of memory accessible via PCI space"
+       flavor             data
+       legal_values       0 to 0x100000
+       default_value      0x100000
+       active_if          CYGPKG_IO_PCI
+       description "
+           This option determines the size of the INTEGRATOR memory 
+           which can be accessed via the PCI bus. Change in 256kB
+           increments."
+   }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT {
+        display      "Default console channel."
+        flavor       data
+        calculated   0
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD {
+        display       "Diagnostic serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 115200
+        default_value 38400
+        description   "
+            This option selects the baud rate used for the diagnostic port.
+            Note: this should match the value chosen for the GDB port if the
+            diagnostic and GDB port are the same."
+    }
+
+    cdl_option CYGHWR_HAL_ARM_INTEGRATOR_GDB_PORT {
+        display       "GDB serial port"
+        flavor        data
+        legal_values  0 1
+        default_value 1
+        description   "
+            The INTEGRATOR board has two separate serial ports.  This option
+            chooses which of these ports will be used to connect to a host
+            running GDB."
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD {
+        display       "GDB serial port baud rate"
+        flavor        data
+        legal_values  9600 19200 38400 115200
+        default_value 38400
+        description   "
+            This option controls the baud rate used for the GDB connection."
+    }
+
+    cdl_option CYGHWR_HAL_ARM_INTEGRATOR_DIAG_LEDS {
+        display          "Enable use of PPx LEDs"
+        default_value    1
+        description      "
+            Enabling this option causes eCos to flash the LEDs during
+            early board initialization. See vectors.S for
+            details. Before calling cyg_start, PP0 is switched on,
+            PP1-3 are switched off. The application code can use the
+            function hal_diag_led() to control the LEDs after this
+            point."
+   }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+        display      "Number of communication channels on the board"
+        flavor       data
+        calculated   2
+    }
+
+    cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+        display          "Debug serial port"
+        active_if        CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE
+        flavor 		 data
+        legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+        default_value    1
+        description      "
+            The INTEGRATOR board has two serial ports. This option
+            chooses which port will be used to connect to a host
+            running GDB."
+     }
+
+     cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+         display          "Diagnostic serial port"
+         active_if        CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
+         flavor data
+         legal_values     0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+         default_value    0
+         description      "
+            The INTEGRATOR board has two serial ports.  This option
+            chooses which port will be used for diagnostic output."
+     }
+
+    # Real-time clock/counter specifics
+    cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+        display       "Real-time clock constants"
+        flavor        none
+    
+        cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+            display       "Real-time clock numerator"
+            flavor        data
+            calculated    1000000000
+        }
+        cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+            display       "Real-time clock denominator"
+            flavor        data
+            calculated    100
+        }
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+           calculated    12500
+        }
+    }
+
+    cdl_component CYGBLD_GLOBAL_OPTIONS {
+        display "Global build options"
+        flavor  none
+        parent  CYGPKG_NONE
+        description   "
+	    Global build options including control over
+	    compiler flags, linker flags and choice of toolchain."
+
+
+        cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+            display "Global command prefix"
+            flavor  data
+            no_define
+            default_value { CYGHWR_THUMB ? "thumb-elf" : "arm-elf" }
+            description "
+                This option specifies the command prefix used when
+                invoking the build tools."
+        }
+
+        cdl_option CYGBLD_GLOBAL_CFLAGS {
+            display "Global compiler flags"
+            flavor  data
+            no_define
+            default_value { (CYGBLD_ARM_ENABLE_THUMB_INTERWORK && CYGHWR_HAL_ARM_BIGENDIAN) ? "-mthumb-interwork -mbig-endian -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" :
+            CYGBLD_ARM_ENABLE_THUMB_INTERWORK ? "-mthumb-interwork -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" :
+            (CYGHWR_HAL_ARM_CPU_FAMILY == "ARM9") && CYGHWR_HAL_ARM_BIGENDIAN ? "-mcpu=arm9 -mbig-endian -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" :
+            (CYGHWR_HAL_ARM_CPU_FAMILY == "ARM9") && ! CYGHWR_HAL_ARM_BIGENDIAN ? "-mcpu=arm9 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" :
+            (CYGHWR_HAL_ARM_CPU_FAMILY != "ARM9") && CYGHWR_HAL_ARM_BIGENDIAN ? "-mcpu=arm7tdmi -mbig-endian -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" :
+            "-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+            description   "
+                This option controls the global compiler flags which are used to
+                compile all packages by default. Individual packages may define
+                options which override these global flags."
+        }
+
+        cdl_option CYGBLD_GLOBAL_LDFLAGS {
+            display "Global linker flags"
+            flavor  data
+            no_define
+            default_value { ((CYGHWR_THUMB || CYGSEM_HAL_ROM_MONITOR) && CYGHWR_HAL_ARM_BIGENDIAN) ? "-mthumb-interwork -mbig-endian -g -nostdlib -Wl,--gc-sections -Wl,-static" :
+            (CYGHWR_THUMB || CYGSEM_HAL_ROM_MONITOR) ? "-mthumb-interwork -g -nostdlib -Wl,--gc-sections -Wl,-static" :
+            (CYGHWR_HAL_ARM_CPU_FAMILY == "ARM9") && CYGHWR_HAL_ARM_BIGENDIAN ? "-mcpu=arm9 -mbig-endian -g -nostdlib -Wl,--gc-sections -Wl,-static" :
+            (CYGHWR_HAL_ARM_CPU_FAMILY == "ARM9") && ! CYGHWR_HAL_ARM_BIGENDIAN ? "-mcpu=arm9 -g -nostdlib -Wl,--gc-sections -Wl,-static" :
+            (CYGHWR_HAL_ARM_CPU_FAMILY != "ARM9") && CYGHWR_HAL_ARM_BIGENDIAN ? "-mcpu=arm7tdmi -mbig-endian -g -nostdlib -Wl,--gc-sections -Wl,-static" :
+            "-mcpu=arm7tdmi -g -nostdlib -Wl,--gc-sections -Wl,-static" }
+            description   "
+                This option controls the global linker flags. Individual
+                packages may define options which override these global flags."
+        }
+
+        cdl_option CYGBLD_BUILD_GDB_STUBS {
+            display "Build GDB stub ROM image"
+            default_value 0
+            requires CYGBLD_BUILD_COMMON_GDB_STUBS
+            requires { CYG_HAL_STARTUP == "ROM" }
+            requires CYGSEM_HAL_ROM_MONITOR
+            requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+            requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+            requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+            requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+            requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+            no_define
+            description "
+                This option enables the building of the GDB stubs for the
+                board. The address of the ELF headers in the image are
+                adjusted to ensure loading at an address in memory used
+                by the flash tool."
+
+            make -priority 320 {
+                <PREFIX>/bin/gdb_module.bin : <PREFIX>/bin/gdb_module.img
+                @mv $< $(<:.img=.elf)
+                $(OBJCOPY) --strip-debug --change-addresses=0xFC060000 $(<:.img=.elf) $<
+                $(OBJCOPY) -O binary $(<:.img=.elf) $@
+            }
+        }
+
+        cdl_option CYGBLD_BUILD_FLASH_TOOL {
+            display "Build flash programming tool"
+            default_value 0
+            requires { CYG_HAL_STARTUP == "RAM" }
+            requires CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1
+            requires CYGPKG_LIBC
+            requires CYGPKG_KERNEL
+            no_define
+            description "This option enables the building of the flash programming tool for copying the GDB stubs into flash memory."
+            make -priority 320 {
+                <PREFIX>/bin/prog_flash.img : <PACKAGE>/src/prog_flash.c
+                @sh -c "mkdir -p src $(dir $@)"
+                $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o src/prog_flash.o $<
+                @echo $@ ": \\" > $(notdir $@).deps
+                @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+                @tail +2 deps.tmp >> $(notdir $@).deps
+                @echo >> $(notdir $@).deps
+                @rm deps.tmp
+                $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ src/prog_flash.o
+            }
+        }
+
+        cdl_option CYGBLD_BUILD_FLASH_TOOL_BE {
+            display "Build flash programming tool for BE images on LE boards"
+            default_value 0
+            requires { CYG_HAL_STARTUP == "RAM" }
+            requires CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1
+            requires CYGPKG_LIBC
+            requires CYGPKG_KERNEL
+            no_define
+            description "This option enables the building of the flash
+                         programming tool for copying the GDB stubs
+                         into flash memory. The tool built by enabling
+                         this option must be used when programming BE
+                         images on LE boards."
+            make -priority 320 {
+                <PREFIX>/bin/prog_flash_BE_image_LE_system.img : <PACKAGE>/src/prog_flash.c
+                @sh -c "mkdir -p src $(dir $@)"
+                $(CC) -DBE_IMAGE -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o src/prog_flash_be.o $<
+                @echo $@ ": \\" > $(notdir $@).deps
+                @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+                @tail +2 deps.tmp >> $(notdir $@).deps
+                @echo >> $(notdir $@).deps
+                @rm deps.tmp
+                $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ src/prog_flash_be.o
+            }
+        }
+    }
+
+    cdl_component CYGHWR_MEMORY_LAYOUT {
+        display "Memory layout"
+        flavor data
+        no_define
+        calculated { CYG_HAL_STARTUP == "RAM" ? "arm_integrator_ram" : \
+                                                "arm_integrator_rom" }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+            display "Memory layout linker script fragment"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+            calculated { CYG_HAL_STARTUP == "RAM" ? "<pkgconf/mlt_arm_integrator_ram.ldi>" : \
+                                                    "<pkgconf/mlt_arm_integrator_rom.ldi>" }
+        }
+
+        cdl_option CYGHWR_MEMORY_LAYOUT_H {
+            display "Memory layout header file"
+            flavor data
+            no_define
+            define -file system.h CYGHWR_MEMORY_LAYOUT_H
+            calculated { CYG_HAL_STARTUP == "RAM" ? "<pkgconf/mlt_arm_integrator_ram.h>" : \
+                                                    "<pkgconf/mlt_arm_integrator_rom.h>" }
+        }
+    }
+
+
+    cdl_option CYGSEM_HAL_ROM_MONITOR {
+        display       "Behave as a ROM monitor"
+        flavor        bool
+        default_value 0
+        parent        CYGPKG_HAL_ROM_MONITOR
+        requires      { CYG_HAL_STARTUP == "ROM" }
+        description   "
+            Enable this option if this program is to be used as a ROM monitor,
+            i.e. applications will be loaded into RAM on the board, and this
+            ROM monitor may process exceptions or interrupts generated from the
+            application. This enables features such as utilizing a separate
+            interrupt stack when exceptions are generated."
+    }
+
+    cdl_component CYGPKG_CYGMON_HAL_OPTIONS {
+        display       "CygMon HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_CYGMON
+        active_if     CYGPKG_CYGMON
+        description   "
+            This option also lists the target's requirements for a valid CygMon
+            configuration."
+
+        cdl_option CYGBLD_BUILD_CYGMON_BIN {
+            display       "Build CygMon ROM binary image"
+            active_if     CYGBLD_BUILD_CYGMON
+            default_value 1
+            no_define
+            description "This option enables the conversion of the CygMon ELF
+                         image to a binary image suitable for ROM programming."
+    
+            make -priority 325 {
+                <PREFIX>/bin/cygmon.bin : <PREFIX>/bin/cygmon.elf
+                $(OBJCOPY) --strip-debug --change-addresses=0xFC060000 $< $(@:.bin=.img) 
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O binary $< $@
+            }
+        }
+    }
+
+    cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+         display       "Work with a ROM monitor"
+         flavor        booldata
+         legal_values  { "Generic" "GDB_stubs" }
+         default_value { CYG_HAL_STARTUP == "RAM" ? "GDB_stubs" : 0 }
+         parent        CYGPKG_HAL_ROM_MONITOR
+         requires      { CYG_HAL_STARTUP == "RAM" }
+         description   "
+             Support can be enabled for different varieties of ROM monitor.
+             This support changes various eCos semantics such as the encoding
+             of diagnostic output, or the overriding of hardware interrupt
+             vectors.
+             Firstly there is \"Generic\" support which prevents the HAL
+             from overriding the hardware vectors that it does not use, to
+             instead allow an installed ROM monitor to handle them. This is
+             the most basic support which is likely to be common to most
+             implementations of ROM monitor.
+             \"GDB_stubs\" provides support when GDB stubs are included in
+             the ROM monitor or boot ROM."
+     }
+
+    cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+        display       "Redboot HAL options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid Redboot
+            configuration."
+    
+        cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+            display       "Build Redboot ROM binary image"
+            active_if     CYGBLD_BUILD_REDBOOT
+            default_value 1
+            no_define
+            description "This option enables the conversion of the Redboot ELF
+                         image to a binary image suitable for ROM programming."
+    
+            make -priority 325 {
+                <PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
+                $(OBJCOPY) --strip-debug $< $(@:.bin=.img) 
+                $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+                $(OBJCOPY) -O binary $< $@
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/hal_cache.h
@@ -0,0 +1,174 @@
+#ifndef CYGONCE_HAL_CACHE_H
+#define CYGONCE_HAL_CACHE_H
+
+//=============================================================================
+//
+//      hal_cache.h
+//
+//      HAL cache control API
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    David A Rusling
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      Cache control API
+// Description:  The macros defined here provide the HAL APIs for handling
+//               cache control operations.
+// Usage:
+//               #include <cyg/hal/hal_cache.h>
+//               ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Cache dimensions
+
+// Data cache
+#define HAL_DCACHE_SIZE                 0    // Size of data cache in bytes
+#define HAL_DCACHE_LINE_SIZE            0    // Size of a data cache line
+#define HAL_DCACHE_WAYS                 0    // Associativity of the cache
+
+// Instruction cache
+#define HAL_ICACHE_SIZE                 0    // Size of cache in bytes
+#define HAL_ICACHE_LINE_SIZE            0    // Size of a cache line
+#define HAL_ICACHE_WAYS                 0    // Associativity of the cache
+
+#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+
+//-----------------------------------------------------------------------------
+// Global control of data cache
+
+// Enable the data cache
+#define HAL_DCACHE_ENABLE()
+
+// Disable the data cache
+#define HAL_DCACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_DCACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_DCACHE_SYNC()
+
+// Query the state of the data cache
+#define HAL_DCACHE_IS_ENABLED(_state_)	0
+
+// Purge contents of data cache
+#define HAL_DCACHE_PURGE_ALL()
+
+// Set the data cache refill burst size
+//#define HAL_DCACHE_BURST_SIZE(_size_)
+
+// Set the data cache write mode
+//#define HAL_DCACHE_WRITE_MODE( _mode_ )
+
+//#define HAL_DCACHE_WRITETHRU_MODE       0
+//#define HAL_DCACHE_WRITEBACK_MODE       1
+
+// Load the contents of the given address range into the data cache
+// and then lock the cache so that it stays there.
+//#define HAL_DCACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+//#define HAL_DCACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+//#define HAL_DCACHE_UNLOCK_ALL()
+
+//-----------------------------------------------------------------------------
+// Data cache line control
+
+// Allocate cache lines for the given address range without reading its
+// contents from memory.
+//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory and invalidate the cache entries
+// for the given address range.
+//#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )
+
+// Write dirty cache lines to memory for the given address range.
+//#define HAL_DCACHE_STORE( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of reading
+// from it later.
+//#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
+
+// Preread the given range into the cache with the intention of writing
+// to it later.
+//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
+
+// Allocate and zero the cache lines associated with the given range.
+//#define HAL_DCACHE_ZERO( _base_ , _size_ )
+
+//-----------------------------------------------------------------------------
+// Global control of Instruction cache
+
+// Enable the instruction cache
+#define HAL_ICACHE_ENABLE()
+
+// Disable the instruction cache
+#define HAL_ICACHE_DISABLE()
+
+// Invalidate the entire cache
+#define HAL_ICACHE_INVALIDATE_ALL()
+
+// Synchronize the contents of the cache with memory.
+#define HAL_ICACHE_SYNC()
+
+// Set the instruction cache refill burst size
+//#define HAL_ICACHE_BURST_SIZE(_size_)
+
+// Load the contents of the given address range into the instruction cache
+// and then lock the cache so that it stays there.
+//#define HAL_ICACHE_LOCK(_base_, _size_)
+
+// Undo a previous lock operation
+//#define HAL_ICACHE_UNLOCK(_base_, _size_)
+
+// Unlock entire cache
+//#define HAL_ICACHE_UNLOCK_ALL()
+
+//-----------------------------------------------------------------------------
+// Instruction cache line control
+
+// Invalidate cache lines in the given range without writing to memory.
+//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_HAL_CACHE_H
+// End of hal_cache.h
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/hal_diag.h
@@ -0,0 +1,86 @@
+#ifndef CYGONCE_HAL_DIAG_H
+#define CYGONCE_HAL_DIAG_H
+
+/*=============================================================================
+//
+//      hal_diag.h
+//
+//      HAL Support for Kernel Diagnostic Routines
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   David A Rusling
+// Contributors: Philippe Robin
+// Date:        November 7, 2000
+// Purpose:     HAL Support for Kernel Diagnostic Routines
+// Description: Diagnostic routines for use during kernel development.
+// Usage:       #include <cyg/hal/hal_diag.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+
+#include <cyg/hal/hal_if.h>
+
+#define HAL_DIAG_INIT() hal_if_diag_init()
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+
+#else // everything by steam
+
+/*---------------------------------------------------------------------------*/
+/* functions implemented in hal_diag.c                                       */
+
+externC void hal_diag_init(void);
+externC void hal_diag_write_char(char c);
+externC void hal_diag_read_char(char *c);
+
+/*---------------------------------------------------------------------------*/
+
+#define HAL_DIAG_INIT() hal_diag_init()
+
+#define HAL_DIAG_WRITE_CHAR(_c_) hal_diag_write_char(_c_)
+
+#define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_)
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+/*---------------------------------------------------------------------------*/
+// LED
+
+externC void hal_diag_led(int n);
+
+/*---------------------------------------------------------------------------*/
+/* end of hal_diag.h                                                         */
+#endif /* CYGONCE_HAL_DIAG_H */
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/hal_integrator.h
@@ -0,0 +1,433 @@
+#ifndef CYGONCE_HAL_INTEGRATOR_H
+#define CYGONCE_HAL_INTEGRATOR_H
+
+/*=============================================================================
+//
+//      hal_integrator.h
+//
+//      HAL Description of INTEGRATOR board
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Philippe Robin
+// Contributors: 
+// Date:         November 7, 2000
+// Purpose:      
+// Description:
+// Usage:        #include <cyg/hal/hal_integrator.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+
+#define INTEGRATOR_HDR_BASE             0x10000000
+#define INTEGRATOR_HDR_CTRL_OFFSET      0x0C
+#define INTEGRATOR_HDR_CTRL_REMAP       0x04
+
+#define INTEGRATOR_BOOT_ROM_BASE	0x20000000
+#define INTEGRATOR_HDR0_SDRAM_BASE      0x80000000
+
+#define INTEGRATOR_DBG_ALPHA_OFFSET     0x00
+#define INTEGRATOR_DBG_LEDS_OFFSET      0x04
+#define INTEGRATOR_DBG_SWITCH_OFFSET    0x08
+
+#define INTEGRATOR_DBG_BASE             0x1A000000
+#define INTEGRATOR_DBG_ALPHA            (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET)
+#define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
+#define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
+
+#define INTEGRATOR_UART0_BASE                   0x16000000	 /*  UART 0 */
+#define INTEGRATOR_UART1_BASE                   0x17000000	 /*  UART 1 */
+
+#define INTEGRATOR_IRQCONT_BASE              	0x14000000
+
+#define INTEGRATOR_IRQSTATUS			0x00
+#define INTEGRATOR_IRQRAWSTATUS		 	0x04
+#define INTEGRATOR_IRQENABLE			0x08
+#define INTEGRATOR_IRQENABLESET	        	0x08
+#define INTEGRATOR_IRQENABLECLEAR		0x0C
+
+#define INTEGRATOR_IRQSOFT			0x10
+#define INTEGRATOR_IRQSOFTSET		        0x10
+#define INTEGRATOR_IRQSOFTCLEAR		        0x14
+
+#define INTEGRATOR_FIQSTATUS			0x20
+#define INTEGRATOR_FIQRAWSTATUS			0x24
+#define INTEGRATOR_FIQENABLE			0x28
+#define INTEGRATOR_FIQENABLESET			0x28
+#define INTEGRATOR_FIQENABLECLEAR		0x2C
+
+#define INTEGRATOR_IRQCONT_IRQSTATUS		(INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQSTATUS)
+#define INTEGRATOR_IRQCONT_IRQRAWSTATUS         (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQRAWSTATUS)
+#define INTEGRATOR_IRQCONT_IRQENABLE            (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQENABLE)
+#define INTEGRATOR_IRQCONT_IRQENABLESET         (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQENABLESET)
+#define INTEGRATOR_IRQCONT_IRQENABLECLEAR       (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQENABLECLEAR)
+#define INTEGRATOR_IRQCONT_IRQSOFT              (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQSOFT)
+#define INTEGRATOR_IRQCONT_IRQSOFTSET           (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQSOFTSET)
+#define INTEGRATOR_IRQCONT_IRQSOFTCLEAR         (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_IRQSOFTCLEAR)
+#define INTEGRATOR_IRQCONT_FIQSTATUS            (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_FIQSTATUS)
+#define INTEGRATOR_IRQCONT_FIQRAWSTATUS         (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_FIQRAWSTATUS)
+#define INTEGRATOR_IRQCONT_FIQENABLE            (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_FIQENABLE)
+#define INTEGRATOR_IRQCONT_FIQENABLESET         (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_FIQENABLESET)
+#define INTEGRATOR_IRQCONT_FIQENABLECLEAR       (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_FIQENABLECLEAR)
+#define INTEGRATOR_IRQCONT_FIQSOFT              (INTEGRATOR_IRQCONT_BASE + INTEGRATOR_FIQSOFT)
+
+// Interrupt controller registers
+#define CYG_DEVICE_ICTL_BASE            INTEGRATOR_IRQCONT_BASE
+#define CYG_DEVICE_IRQ_Status \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_ICTL_BASE + INTEGRATOR_IRQSTATUS))
+    // Current status, read only
+#define CYG_DEVICE_IRQ_Enable \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_ICTL_BASE + INTEGRATOR_IRQENABLE))
+    // Enable status, read only
+#define CYG_DEVICE_IRQ_EnableSet \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_ICTL_BASE + INTEGRATOR_IRQENABLESET))
+    // Enable (1's only), write only
+#define CYG_DEVICE_IRQ_EnableClear \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_ICTL_BASE + INTEGRATOR_IRQENABLECLEAR))
+    // Disable (1's only), write only
+
+// Timer registers
+#define INTEGRATOR_CT_BASE              0x13000000	 /*  Counter/Timers */
+
+#define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
+#define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
+#define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
+
+#define CYG_DEVICE_TIMER_BASE           INTEGRATOR_TIMER2_BASE
+
+#define CYG_DEVICE_TIMER_LOAD \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_TIMER_BASE + 0x00))
+    // Load value, read/write
+#define CYG_DEVICE_TIMER_CURRENT \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_TIMER_BASE + 0x04))
+    // Current value, read
+#define CYG_DEVICE_TIMER_CONTROL \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_TIMER_BASE + 0x08))
+    // Control register, read/write
+#define CYG_DEVICE_TIMER_CLEAR \
+    ((volatile cyg_uint32 *) (CYG_DEVICE_TIMER_BASE + 0x0C))
+    // Clears interrrupt, write only
+
+// Clock/timer control register
+#define CTL_ENABLE      0x80            // Bit   7: 1 - counter enabled
+#define CTL_DISABLE     0x00            //          0 - counter disabled
+#define CTL_FREERUN     0x00            // Bit   6: 0 - free running counter
+#define CTL_PERIODIC    0x40            //          1 - periodic timer mode
+#define CTL_SCALE_1     0x00            // Bits 32: 00 - Scale clock by 1
+#define CTL_SCALE_16    0x04            //          01 - Scale by 16
+#define CTL_SCALE_256   0x08            //          10 - Scale by 256
+                                        //               12.8us/tick
+/*-------------------------------------------------------------------------------
+ *  From AMBA UART (PL010) Block Specification (ARM-0001-CUST-DSPC-A03)
+ * -------------------------------------------------------------------------------
+ *  UART Register Offsets.
+ */
+#define AMBA_UARTDR                     0x00	 /*  Data read or written from the interface. */
+#define AMBA_UARTRSR                    0x04	 /*  Receive status register (Read). */
+#define AMBA_UARTECR                    0x04	 /*  Error clear register (Write). */
+#define AMBA_UARTLCR_H                  0x08	 /*  Line control register, high byte. */
+#define AMBA_UARTLCR_M                  0x0C	 /*  Line control register, middle byte. */
+#define AMBA_UARTLCR_L                  0x10	 /*  Line control register, low byte. */
+#define AMBA_UARTCR                     0x14	 /*  Control register. */
+#define AMBA_UARTFR                     0x18	 /*  Flag register (Read only). */
+#define AMBA_UARTIIR                    0x1C	 /*  Interrupt indentification register (Read). */
+#define AMBA_UARTICR                    0x1C	 /*  Interrupt clear register (Write). */
+#define AMBA_UARTILPR                   0x20	 /*  IrDA low power counter register. */
+
+#define AMBA_UARTRSR_OE                 0x08
+#define AMBA_UARTRSR_BE                 0x04
+#define AMBA_UARTRSR_PE                 0x02
+#define AMBA_UARTRSR_FE                 0x01
+
+#define AMBA_UARTFR_TXFF                0x20
+#define AMBA_UARTFR_RXFE                0x10
+#define AMBA_UARTFR_BUSY                0x08
+#define AMBA_UARTFR_TMSK                (AMBA_UARTFR_TXFF + AMBA_UARTFR_BUSY)
+ 
+#define AMBA_UARTCR_RTIE                0x40
+#define AMBA_UARTCR_TIE                 0x20
+#define AMBA_UARTCR_RIE                 0x10
+#define AMBA_UARTCR_MSIE                0x08
+#define AMBA_UARTCR_IIRLP               0x04
+#define AMBA_UARTCR_SIREN               0x02
+#define AMBA_UARTCR_UARTEN              0x01
+ 
+#define AMBA_UARTLCR_H_WLEN_8           0x60
+#define AMBA_UARTLCR_H_WLEN_7           0x40
+#define AMBA_UARTLCR_H_WLEN_6           0x20
+#define AMBA_UARTLCR_H_WLEN_5           0x00
+#define AMBA_UARTLCR_H_FEN              0x10
+#define AMBA_UARTLCR_H_STP2             0x08
+#define AMBA_UARTLCR_H_EPS              0x04
+#define AMBA_UARTLCR_H_PEN              0x02
+#define AMBA_UARTLCR_H_BRK              0x01
+
+#define AMBA_UARTIIR_RTIS               0x08
+#define AMBA_UARTIIR_TIS                0x04
+#define AMBA_UARTIIR_RIS                0x02
+#define AMBA_UARTIIR_MIS                0x01
+
+#define ARM_BAUD_460800                 1
+#define ARM_BAUD_230400                 3
+#define ARM_BAUD_115200                 7
+#define ARM_BAUD_57600                  15
+#define ARM_BAUD_38400                  23
+#define ARM_BAUD_19200                  47
+#define ARM_BAUD_14400                  63
+#define ARM_BAUD_9600                   95
+#define ARM_BAUD_4800                   191
+#define ARM_BAUD_2400                   383
+#define ARM_BAUD_1200                   767
+
+// PCI Base area
+#define INTEGRATOR_PCI_BASE		0x40000000
+#define INTEGRATOR_PCI_SIZE		0x3FFFFFFF
+
+// memory map as seen by the CPU on the local bus
+#define CPU_PCI_IO_ADRS		0x60000000 	// PCI I/O space base
+#define CPU_PCI_IO_SIZE		0x10000	
+
+#define CPU_PCI_CNFG_ADRS	0x61000000	// PCI config space
+#define CPU_PCI_CNFG_SIZE	0x1000000
+
+#define PCI_MEM_BASE            0x40000000   // 512M to xxx
+//  unused 256M from A0000000-AFFFFFFF might be used for I2O ???
+#define PCI_IO_BASE             0x60000000   // 16M to xxx
+//  unused (128-16)M from B1000000-B7FFFFFF
+#define PCI_CONFIG_BASE         0x61000000   // 16M to xxx
+//  unused ((128-16)M - 64K) from XXX
+
+#define PCI_V3_BASE             0x62000000
+
+// V3 PCI bridge controller
+#define V3_BASE			0x62000000    // V360EPC registers
+
+#define V3_PCI_VENDOR           0x00000000
+#define V3_PCI_DEVICE           0x00000002
+#define V3_PCI_CMD              0x00000004
+#define V3_PCI_STAT             0x00000006
+#define V3_PCI_CC_REV           0x00000008
+#define V3_PCI_HDR_CF           0x0000000C
+#define V3_PCI_IO_BASE          0x00000010
+#define V3_PCI_BASE0            0x00000014
+#define V3_PCI_BASE1            0x00000018
+#define V3_PCI_SUB_VENDOR       0x0000002C
+#define V3_PCI_SUB_ID           0x0000002E
+#define V3_PCI_ROM              0x00000030
+#define V3_PCI_BPARAM           0x0000003C
+#define V3_PCI_MAP0             0x00000040
+#define V3_PCI_MAP1             0x00000044
+#define V3_PCI_INT_STAT         0x00000048
+#define V3_PCI_INT_CFG          0x0000004C
+#define V3_LB_BASE0             0x00000054
+#define V3_LB_BASE1             0x00000058
+#define V3_LB_MAP0              0x0000005E
+#define V3_LB_MAP1              0x00000062
+#define V3_LB_BASE2             0x00000064
+#define V3_LB_MAP2              0x00000066
+#define V3_LB_SIZE              0x00000068
+#define V3_LB_IO_BASE           0x0000006E
+#define V3_FIFO_CFG             0x00000070
+#define V3_FIFO_PRIORITY        0x00000072
+#define V3_FIFO_STAT            0x00000074
+#define V3_LB_ISTAT             0x00000076
+#define V3_LB_IMASK             0x00000077
+#define V3_SYSTEM               0x00000078
+#define V3_LB_CFG               0x0000007A
+#define V3_PCI_CFG              0x0000007C
+#define V3_DMA_PCI_ADR0         0x00000080
+#define V3_DMA_PCI_ADR1         0x00000090
+#define V3_DMA_LOCAL_ADR0       0x00000084
+#define V3_DMA_LOCAL_ADR1       0x00000094
+#define V3_DMA_LENGTH0          0x00000088
+#define V3_DMA_LENGTH1          0x00000098
+#define V3_DMA_CSR0             0x0000008B
+#define V3_DMA_CSR1             0x0000009B
+#define V3_DMA_CTLB_ADR0        0x0000008C
+#define V3_DMA_CTLB_ADR1        0x0000009C
+#define V3_DMA_DELAY            0x000000E0
+#define V3_MAIL_DATA            0x000000C0
+#define V3_PCI_MAIL_IEWR        0x000000D0
+#define V3_PCI_MAIL_IERD        0x000000D2
+#define V3_LB_MAIL_IEWR         0x000000D4
+#define V3_LB_MAIL_IERD         0x000000D6
+#define V3_MAIL_WR_STAT         0x000000D8
+#define V3_MAIL_RD_STAT         0x000000DA
+#define V3_QBA_MAP              0x000000DC
+
+// SYSTEM register bits
+#define V3_SYSTEM_M_RST_OUT             (1 << 15)
+#define V3_SYSTEM_M_LOCK                (1 << 14)
+
+//  PCI_CFG bits
+#define V3_PCI_CFG_M_RETRY_EN           (1 << 10)
+#define V3_PCI_CFG_M_AD_LOW1            (1 << 9)
+#define V3_PCI_CFG_M_AD_LOW0            (1 << 8)
+
+// PCI MAP register bits (PCI -> Local bus)
+#define V3_PCI_MAP_M_MAP_ADR            0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH        (1 << 15)
+#define V3_PCI_MAP_M_ROM_SIZE           (1 << 11 | 1 << 10)
+#define V3_PCI_MAP_M_SWAP               (1 << 9 | 1 << 8)
+#define V3_PCI_MAP_M_ADR_SIZE           0x000000F0
+#define V3_PCI_MAP_M_REG_EN             (1 << 1)
+#define V3_PCI_MAP_M_ENABLE             (1 << 0)
+
+// 9 => 512M window size
+#define V3_PCI_MAP_M_ADR_SIZE_512M      0x00000090
+
+// A => 1024M window size
+#define V3_PCI_MAP_M_ADR_SIZE_1024M     0x000000A0
+
+// LB_BASE register bits (Local bus -> PCI)
+#define V3_LB_BASE_M_MAP_ADR            0xFFF00000
+#define V3_LB_BASE_M_SWAP               (1 << 8 | 1 << 9)
+#define V3_LB_BASE_M_ADR_SIZE           0x000000F0
+#define V3_LB_BASE_M_PREFETCH           (1 << 3)
+#define V3_LB_BASE_M_ENABLE             (1 << 0)
+
+// PCI COMMAND REGISTER bits
+#define V3_COMMAND_M_FBB_EN             (1 << 9)
+#define V3_COMMAND_M_SERR_EN            (1 << 8)
+#define V3_COMMAND_M_PAR_EN             (1 << 6)
+#define V3_COMMAND_M_MASTER_EN          (1 << 2)
+#define V3_COMMAND_M_MEM_EN             (1 << 1)
+#define V3_COMMAND_M_IO_EN              (1 << 0)
+
+#define INTEGRATOR_SC_BASE		0x11000000
+#define INTEGRATOR_SC_PCIENABLE_OFFSET	0x18
+#define INTEGRATOR_SC_PCIENABLE \
+			(INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
+
+
+
+#define SZ_256M                         0x10000000
+
+// Integrator EBI register definitions
+
+#define INTEGRATOR_EBI_BASE 0x12000000
+
+#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
+#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
+#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
+#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
+#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
+
+#define INTEGRATOR_EBI_CSR0 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
+#define INTEGRATOR_EBI_CSR1 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define INTEGRATOR_EBI_CSR2 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
+#define INTEGRATOR_EBI_CSR3 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
+#define INTEGRATOR_EBI_LOCK (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+#define INTEGRATOR_EBI_8_BIT            0x00
+#define INTEGRATOR_EBI_16_BIT           0x01
+#define INTEGRATOR_EBI_32_BIT           0x02
+#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
+#define INTEGRATOR_EBI_SYNC             0x08
+#define INTEGRATOR_EBI_WS_2             0x00
+#define INTEGRATOR_EBI_WS_3             0x10
+#define INTEGRATOR_EBI_WS_4             0x20
+#define INTEGRATOR_EBI_WS_5             0x30
+#define INTEGRATOR_EBI_WS_6             0x40
+#define INTEGRATOR_EBI_WS_7             0x50
+#define INTEGRATOR_EBI_WS_8             0x60
+#define INTEGRATOR_EBI_WS_9             0x70
+#define INTEGRATOR_EBI_WS_10            0x80
+#define INTEGRATOR_EBI_WS_11            0x90
+#define INTEGRATOR_EBI_WS_12            0xA0
+#define INTEGRATOR_EBI_WS_13            0xB0
+#define INTEGRATOR_EBI_WS_14            0xC0
+#define INTEGRATOR_EBI_WS_15            0xD0
+#define INTEGRATOR_EBI_WS_16            0xE0
+#define INTEGRATOR_EBI_WS_17            0xF0
+
+#define FL_SC_CONTROL			0x06	// Enable Flash Write and Vpp
+
+/* 
+ *  System Controller
+ * 
+ */
+#define INTEGRATOR_SC_ID_OFFSET         0x00
+#define INTEGRATOR_SC_OSC_OFFSET        0x04
+#define INTEGRATOR_SC_CTRLS_OFFSET      0x08
+#define INTEGRATOR_SC_CTRLC_OFFSET      0x0C
+#define INTEGRATOR_SC_DEC_OFFSET        0x10
+#define INTEGRATOR_SC_ARB_OFFSET        0x14
+#define INTEGRATOR_SC_PCIENABLE_OFFSET  0x18
+#define INTEGRATOR_SC_LOCK_OFFSET       0x1C
+
+#define INTEGRATOR_SC_BASE              0x11000000
+#define INTEGRATOR_SC_ID                (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET)
+#define INTEGRATOR_SC_OSC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET)
+#define INTEGRATOR_SC_CTRLS             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
+#define INTEGRATOR_SC_CTRLC             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
+#define INTEGRATOR_SC_DEC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET)
+#define INTEGRATOR_SC_ARB               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET)
+#define INTEGRATOR_SC_PCIENABLE         (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
+#define INTEGRATOR_SC_LOCK              (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET)
+
+
+#define HAL_FLASH_WRITE_ENABLE()								\
+	{											\
+		volatile cyg_uint32 *ebi_csr1 = (volatile cyg_uint32 *)INTEGRATOR_EBI_CSR1;	\
+												\
+		/* allow write access to EBI_CSR1 area (Flash) */				\
+     		*ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE;					\
+												\
+		if (!(*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE)) {				\
+		    *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 0xA05F;			\
+		    *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE;					\
+		    *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 0;				\
+		}										\
+												\
+		/* Enable Vpp and allow write access to Flash in system controller */		\
+		*(volatile unsigned int *)INTEGRATOR_SC_CTRLS = FL_SC_CONTROL;			\
+	}
+
+#define HAL_FLASH_WRITE_DISABLE()								\
+	{											\
+		volatile cyg_uint32 *ebi_csr1 = (volatile cyg_uint32 *)INTEGRATOR_EBI_CSR1;	\
+												\
+		/* disable write access to EBI_CSR1 area (Flash) */				\
+		*ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE;					\
+												\
+		if (*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE) {					\
+		    *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 0xA05F;			\
+		    *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE;					\
+		    *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 1;				\
+		}										\
+												\
+		/* Disable Vpp and disable write access to Flash in system controller */	\
+		*(volatile unsigned int *)INTEGRATOR_SC_CTRLS = 0;				\
+	}
+
+
+#endif //CYGONCE_HAL_INTEGRATOR_H
+
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/hal_platform_ints.h
@@ -0,0 +1,90 @@
+#ifndef CYGONCE_HAL_PLATFORM_INTS_H
+#define CYGONCE_HAL_PLATFORM_INTS_H
+//==========================================================================
+//
+//      hal_platform_ints.h
+//
+//      HAL Interrupt and clock support
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    David A Rusling
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      Define Interrupt support
+// Description:  The interrupt details for the INTEGRATOR are defined here.
+// Usage:
+//               #include <cyg/hal/hal_platform_ints.h>
+//               ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define CYGNUM_HAL_INTERRUPT_SOFTINT                     0
+#define CYGNUM_HAL_INTERRUPT_UARTINT0                    1
+#define CYGNUM_HAL_INTERRUPT_UARTINT1                    2
+#define CYGNUM_HAL_INTERRUPT_KMIINT0                     3
+#define CYGNUM_HAL_INTERRUPT_KMIINT1                     4
+#define CYGNUM_HAL_INTERRUPT_TIMERINT0                   5
+#define CYGNUM_HAL_INTERRUPT_TIMERINT1                   6
+#define CYGNUM_HAL_INTERRUPT_TIMERINT2                   7
+#define CYGNUM_HAL_INTERRUPT_RTCINT                      8
+#define CYGNUM_HAL_INTERRUPT_EXPINT0                     9
+#define CYGNUM_HAL_INTERRUPT_EXPINT1                     10
+#define CYGNUM_HAL_INTERRUPT_EXPINT2                     11
+#define CYGNUM_HAL_INTERRUPT_EXPINT3                     12
+#define CYGNUM_HAL_INTERRUPT_PCIINT0                     13
+#define CYGNUM_HAL_INTERRUPT_PCIINT1                     14
+#define CYGNUM_HAL_INTERRUPT_PCIINT2                     15
+#define CYGNUM_HAL_INTERRUPT_PCIINT3                     16
+#define CYGNUM_HAL_INTERRUPT_V3INT                       17
+#define CYGNUM_HAL_INTERRUPT_CPINT0                      18
+#define CYGNUM_HAL_INTERRUPT_CPINT1                      19
+#define CYGNUM_HAL_INTERRUPT_LBUSTIMEOUT                 20
+#define CYGNUM_HAL_INTERRUPT_APCINT                      21
+#define CYGNUM_HAL_INTERRUPT_CM_SOFTINT                  24
+#define CYGNUM_HAL_INTERRUPT_CM_COMMRX                   25
+#define CYGNUM_HAL_INTERRUPT_CM_COMMTX                   26
+
+#define CYGNUM_HAL_ISR_MIN                        0
+#define CYGNUM_HAL_ISR_MAX                        26
+#define CYGNUM_HAL_ISR_COUNT                      27
+
+// The vector used by the Real time clock
+#define CYGNUM_HAL_INTERRUPT_RTC                  CYGNUM_HAL_INTERRUPT_TIMERINT2
+
+//----------------------------------------------------------------------------
+// Reset.
+
+#define HAL_PLATFORM_RESET() CYG_EMPTY_STATEMENT
+
+#define HAL_PLATFORM_RESET_ENTRY 0x4000000
+
+#endif // CYGONCE_HAL_PLATFORM_INTS_H
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/hal_platform_setup.h
@@ -0,0 +1,81 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+
+/*=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    David A Rusling
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:     ARM INTEGRATOR platform specific support routines
+// Description: 
+// Usage:       #include <cyg/hal/hal_platform_setup.h>
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <cyg/hal/hal_integrator.h>
+
+// Define macro used to diddle the LEDs during early initialization.
+// Can use r0+r1. Argument in \x.
+// Control the LEDs PP0-PP3. This requires the jumpers on pins 9-16 to
+// be set on LK11 in order to be visible. Otherwise the parallel port
+// data pins are diddled instead.
+
+#ifdef CYGHWR_HAL_ARM_INTEGRATOR_DIAG_LEDS
+#define CYGHWR_LED_MACRO				\
+        mov     r1, #(15 & (\x))			;\
+        ldr     r0,=INTEGRATOR_DBG_BASE			;\
+        strb    r1, [r0, #INTEGRATOR_DBG_LEDS_OFFSET]                    ;
+#endif
+
+#define PLATFORM_SETUP1                                                   \
+        ldr     r0,=INTEGRATOR_DBG_BASE                                  ;\
+        ldr     r1,=0                                                    ;\
+        strb    r1, [r0, #INTEGRATOR_DBG_LEDS_OFFSET]                    ;\
+	ldr	r0, =INTEGRATOR_HDR_BASE                                 ;\
+	ldr	r1, [r0, #INTEGRATOR_HDR_CTRL_OFFSET]                    ;\
+	orr	r1, r1, #INTEGRATOR_HDR_CTRL_REMAP	                 ;\
+        str     r1, [r0, #INTEGRATOR_HDR_CTRL_OFFSET]                    ;\
+	ldr	r1, =INTEGRATOR_IRQCONT_BASE                             ;\
+        ldr	r0, =0xFFFFFFFF                                          ;\
+	str	r0, [r1, #INTEGRATOR_IRQENABLECLEAR]             	 ;\
+	str	r0, [r1, #INTEGRATOR_FIQENABLECLEAR]             	 ;\
+        ldr     r0,=INTEGRATOR_DBG_BASE                                  ;\
+        ldr     r1,=0xF                                                  ;\
+        strb    r1, [r0, #INTEGRATOR_DBG_LEDS_OFFSET]                    ;
+
+/*---------------------------------------------------------------------------*/
+/* end of hal_platform_setup.h                                               */
+#endif /* CYGONCE_HAL_PLATFORM_SETUP_H */
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_ram.h
@@ -0,0 +1,13 @@
+// eCos memory layout - Tue Feb 29 14:11:30 2000
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#define CYGMEM_REGION_ram (0)
+#define CYGMEM_REGION_ram_SIZE (0x01000000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+extern char CYG_LABEL_NAME (_reserved) [];
+#define CYGMEM_SECTION_reserved (CYG_LABEL_NAME (_reserved))
+#define CYGMEM_SECTION_reserved_SIZE (0x8000)
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_ram.ldi
@@ -0,0 +1,24 @@
+// eCos memory layout - Tue Feb 29 14:11:30 2000
+
+// This is a generated file - do not edit
+
+MEMORY
+{
+    ram : ORIGIN = 0, LENGTH = 0x01000000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    __reserved = 0; . = __reserved + 0x8000;
+    SECTION_rom_vectors (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTIONS_END
+}
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_ram.mlt
@@ -0,0 +1,12 @@
+version 0
+region ram 0 01000000 0 !
+section reserved 8000 1 0 0 1 1 1 1 0 0 rom_vectors rom_vectors !
+section rom_vectors 0 4 0 1 0 1 0 1 text text !
+section text 0 4 0 1 0 1 0 1 fini fini !
+section fini 0 4 0 1 0 1 0 1 rodata rodata !
+section rodata 0 4 0 1 0 1 0 1 rodata1 rodata1 !
+section rodata1 0 4 0 1 0 1 0 1 fixup fixup !
+section fixup 0 4 0 1 0 1 0 1 gcc_except_table gcc_except_table !
+section gcc_except_table 0 4 0 1 0 1 0 1 data data !
+section data 0 4 0 1 0 1 0 1 bss bss !
+section bss 0 4 0 1 0 0 0 0 !
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_rom.h
@@ -0,0 +1,16 @@
+// eCos memory layout - Tue Feb 29 14:25:49 2000
+
+// This is a generated file - do not edit
+
+#include <cyg/infra/cyg_type.h>
+#include <stddef.h>
+
+#define CYGMEM_REGION_ram (0)
+#define CYGMEM_REGION_ram_SIZE (0x01000000)
+#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
+#define CYGMEM_REGION_rom (0x24000000)
+#define CYGMEM_REGION_rom_SIZE (0x02000000)
+#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R)
+extern char CYG_LABEL_NAME (_reserved) [];
+#define CYGMEM_SECTION_reserved (CYG_LABEL_NAME (_reserved))
+#define CYGMEM_SECTION_reserved_SIZE (0x800)
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_rom.ldi
@@ -0,0 +1,25 @@
+// eCos memory layout - Tue Feb 29 14:25:49 2000
+
+// This is a generated file - do not edit
+
+MEMORY
+{
+    ram : ORIGIN = 0, LENGTH = 0x01000000
+    rom : ORIGIN = 0x24000000, LENGTH = 0x02000000
+}
+
+SECTIONS
+{
+    SECTIONS_BEGIN
+    SECTION_rom_vectors (rom, 0x24000000, LMA_EQ_VMA)
+    SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
+    SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
+    __reserved = 0; . = __reserved + 0x800;
+    SECTION_data (ram, ALIGN (0x4), FOLLOWING (.gcc_except_table))
+    SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
+    SECTIONS_END
+}
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/pkgconf/mlt_arm_integrator_rom.mlt
@@ -0,0 +1,13 @@
+version 0
+region ram 0 01000000 0 !
+region rom 24000000 02000000 1 !
+section reserved 800 1 0 0 1 1 1 0 0 0 data !
+section data 0 4 1 1 0 1 0 0 bss !
+section bss 0 4 0 1 0 0 0 0 !
+section rom_vectors 0 1 0 1 1 1 1 1 24000000 02000000 text text !
+section text 0 4 0 1 0 1 0 1 fini fini !
+section fini 0 4 0 1 0 1 0 1 rodata rodata !
+section rodata 0 4 0 1 0 1 0 1 rodata1 rodata1 !
+section rodata1 0 4 0 1 0 1 0 1 fixup fixup !
+section fixup 0 4 0 1 0 1 0 1 gcc_except_table gcc_except_table !
+section gcc_except_table 0 4 0 1 0 0 0 1 data !
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/plf_io.h
@@ -0,0 +1,362 @@
+#ifndef CYGONCE_PLF_IO_H
+#define CYGONCE_PLF_IO_H
+
+//=============================================================================
+//
+//      plf_io.h
+//
+//      Platform specific IO support
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Philippe Robin
+// Contributors: David A Rusling
+// Date:         November 7, 2000
+// Purpose:      Integrator PCI IO support macros
+// Description: 
+// Usage:        #include <cyg/hal/plf_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal_arm_integrator.h>
+
+#include <cyg/hal/hal_integrator.h>
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_platform_ints.h>  // Interrupt vectors
+
+// Initialization of the PCI bus.
+#define HAL_PCI_INIT()                                                  	\
+    CYG_MACRO_START                                                     	\
+    volatile int i, j;								\
+										\
+    /* setting this register will take the V3 out of reset */			\
+										\
+    *(cyg_uint32 *)(INTEGRATOR_SC_PCIENABLE) = 1;				\
+										\
+    /* wait a few usecs to settle the device and the PCI bus */			\
+										\
+    for (i = 0; i < 100 ; i++)							\
+	   j = i + 1;								\
+										\
+    /* Now write the Base I/O Address Word to V3_BASE + 0x6C */			\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_LB_IO_BASE) = (cyg_uint16)(V3_BASE >> 16);	\
+										\
+    do {									\
+        *(cyg_uint8 *)(V3_BASE + V3_MAIL_DATA) = 0xAA;				\
+	*(cyg_uint8 *)(V3_BASE + V3_MAIL_DATA + 4) = 0x55;			\
+    } while (*(cyg_uint8 *)(V3_BASE + V3_MAIL_DATA) != 0xAA ||			\
+	     *(cyg_uint8 *)(V3_BASE + V3_MAIL_DATA + 4) != 0x55);		\
+										\
+    /* Make sure that V3 register access is not locked, if it is, unlock it */	\
+										\
+    if ((*(cyg_uint16 *)(V3_BASE + V3_SYSTEM) & V3_SYSTEM_M_LOCK)  		\
+				== V3_SYSTEM_M_LOCK)				\
+	*(cyg_uint16 *)(V3_BASE + V3_SYSTEM) = 0xA05F;				\
+										\
+    /* Ensure that the slave accesses from PCI are disabled while we */		\
+    /* setup windows */								\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_PCI_CMD) &= 					\
+				~(V3_COMMAND_M_MEM_EN | V3_COMMAND_M_IO_EN);	\
+										\
+    /* Clear RST_OUT to 0; keep the PCI bus in reset until we've finished */	\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_SYSTEM) &= ~V3_SYSTEM_M_RST_OUT;		\
+										\
+    /* Make all accesses from PCI space retry until we're ready for them */	\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_PCI_CFG) |= V3_PCI_CFG_M_RETRY_EN;		\
+										\
+    /* Set up any V3 PCI Configuration Registers that we absolutely have to */	\
+    /* LB_CFG controls Local Bus protocol. */					\
+    /* Enable LocalBus byte strobes for READ accesses too. */			\
+    /* set bit 7 BE_IMODE and bit 6 BE_OMODE */					\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_LB_CFG) |= 0x0C0;				\
+										\
+    /* PCI_CMD controls overall PCI operation. */				\
+    /* Enable PCI bus master. */						\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_PCI_CMD) |= 0x04;				\
+										\
+    /* PCI_MAP0 controls where the PCI to CPU memory window is on Local Bus*/	\
+										\
+    *(cyg_uint32 *)(V3_BASE + V3_PCI_MAP0) = (INTEGRATOR_BOOT_ROM_BASE) |	\
+					(V3_PCI_MAP_M_ADR_SIZE_512M |		\
+					V3_PCI_MAP_M_REG_EN |			\
+					V3_PCI_MAP_M_ENABLE);			\
+										\
+    /* PCI_BASE0 is the PCI address of the start of the window */		\
+										\
+    *(cyg_uint32 *)(V3_BASE + V3_PCI_BASE0) = INTEGRATOR_BOOT_ROM_BASE;		\
+										\
+    /* PCI_MAP1 is LOCAL address of the start of the window */			\
+										\
+    *(cyg_uint32 *)(V3_BASE + V3_PCI_MAP1) = (INTEGRATOR_HDR0_SDRAM_BASE) |	\
+			(V3_PCI_MAP_M_ADR_SIZE_1024M | V3_PCI_MAP_M_REG_EN |	\
+			 V3_PCI_MAP_M_ENABLE);					\
+										\
+    /* PCI_BASE1 is the PCI address of the start of the window */		\
+										\
+    *(cyg_uint32 *)(V3_BASE + V3_PCI_BASE1) = INTEGRATOR_HDR0_SDRAM_BASE;	\
+										\
+    /* Set up the windows from local bus memory into PCI configuration, */	\
+    /* I/O and Memory. */							\
+    /* PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this. */		\
+										\
+    *(cyg_uint16 *)(V3_BASE +V3_LB_BASE2) = 					\
+			((CPU_PCI_IO_ADRS >> 24) << 8) | V3_LB_BASE_M_ENABLE;	\
+    *(cyg_uint16 *)(V3_BASE + V3_LB_MAP2) = 0;					\
+										\
+    /* PCI Configuration, use LB_BASE1/LB_MAP1. */				\
+										\
+    /* PCI Memory use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1 */			\
+    /* Map first 256Mbytes as non-prefetchable via BASE0/MAP0 */		\
+    /* (INTEGRATOR_PCI_BASE == PCI_MEM_BASE) */					\
+										\
+    *(cyg_uint32 *)(V3_BASE + V3_LB_BASE0) = 					\
+			INTEGRATOR_PCI_BASE | (0x80 | V3_LB_BASE_M_ENABLE);	\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_LB_MAP0) = 					\
+			((INTEGRATOR_PCI_BASE >> 20) << 0x4) | 0x0006;		\
+										\
+    /* Map second 256 Mbytes as prefetchable via BASE1/MAP1 */			\
+										\
+    *(cyg_uint32 *)(V3_BASE + V3_LB_BASE1) = 					\
+			INTEGRATOR_PCI_BASE | (0x84 | V3_LB_BASE_M_ENABLE);	\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_LB_MAP1) = 					\
+			(((INTEGRATOR_PCI_BASE + SZ_256M) >> 20) << 4) | 0x0006;\
+										\
+    /* Allow accesses to PCI Configuration space */				\
+    /* and set up A1, A0 for type 1 config cycles */				\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_PCI_CFG) = 					\
+			((*(cyg_uint16 *)(V3_BASE + V3_PCI_CFG)) &		\
+			   ~(V3_PCI_CFG_M_RETRY_EN | V3_PCI_CFG_M_AD_LOW1) ) |	\
+			   V3_PCI_CFG_M_AD_LOW0;				\
+										\
+    /* now we can allow in PCI MEMORY accesses */				\
+										\
+    *(cyg_uint16 *)(V3_BASE + V3_PCI_CMD) = 					\
+		(*(cyg_uint16 *)(V3_BASE + V3_PCI_CMD)) | V3_COMMAND_M_MEM_EN;	\
+										\
+    /* Set RST_OUT to take the PCI bus is out of reset, PCI devices can */	\
+    /* initialise and lock the V3 system register so that no one else */	\
+    /* can play with it */							\
+										\
+   *(cyg_uint16 *)(V3_BASE + V3_SYSTEM) = 					\
+		(*(cyg_uint16 *)(V3_BASE + V3_SYSTEM)) | V3_SYSTEM_M_RST_OUT;	\
+										\
+   *(cyg_uint16 *)(V3_BASE + V3_SYSTEM) = 					\
+		(*(cyg_uint16 *)(V3_BASE + V3_SYSTEM)) | V3_SYSTEM_M_LOCK;	\
+                                                                         	\
+    CYG_MACRO_END
+
+
+// V3 access routines
+#define _V3Write16(o,v) (*(volatile cyg_uint16 *)(PCI_V3_BASE + (cyg_uint32)(o)) \
+					 = (cyg_uint16)(v))
+#define _V3Read16(o)    (*(volatile cyg_uint16 *)(PCI_V3_BASE + (cyg_uint32)(o)))
+
+#define _V3Write32(o,v) (*(volatile cyg_uint32 *)(PCI_V3_BASE + (cyg_uint32)(o)) \
+					= (cyg_uint32)(v))
+#define _V3Read32(o)    (*(volatile cyg_uint32 *)(PCI_V3_BASE + (cyg_uint32)(o)))
+
+// _V3OpenConfigWindow - open V3 configuration window
+#define _V3OpenConfigWindow() 							\
+    {										\
+    /* Set up base0 to see all 512Mbytes of memory space (not	     */		\
+    /* prefetchable), this frees up base1 for re-use by configuration*/		\
+    /* memory */								\
+										\
+    _V3Write32 (V3_LB_BASE0, ((INTEGRATOR_PCI_BASE & 0xFFF00000) |		\
+			     0x90 | V3_LB_BASE_M_ENABLE));			\
+    /* Set up base1 to point into configuration space, note that MAP1 */	\
+    /* register is set up by pciMakeConfigAddress(). */				\
+										\
+    _V3Write32 (V3_LB_BASE1, ((CPU_PCI_CNFG_ADRS & 0xFFF00000) |		\
+			     0x40 | V3_LB_BASE_M_ENABLE));			\
+    }
+
+// _V3CloseConfigWindow - close V3 configuration window
+#define _V3CloseConfigWindow()							\
+    {										\
+    /* Reassign base1 for use by prefetchable PCI memory */			\
+    _V3Write32 (V3_LB_BASE1, (((INTEGRATOR_PCI_BASE + SZ_256M) & 0xFFF00000)	\
+					| 0x84 | V3_LB_BASE_M_ENABLE));		\
+    _V3Write16 (V3_LB_MAP1,							\
+	    (((INTEGRATOR_PCI_BASE + SZ_256M) & 0xFFF00000) >> 16) | 0x0006);	\
+										\
+    /* And shrink base0 back to a 256M window (NOTE: MAP0 already correct) */	\
+										\
+    _V3Write32 (V3_LB_BASE0, ((INTEGRATOR_PCI_BASE & 0xFFF00000) |		\
+			     0x80 | V3_LB_BASE_M_ENABLE));			\
+    }
+
+// Compute address necessary to access PCI config space for the given
+// bus and device.
+#define HAL_PCI_CONFIG_ADDRESS( __bus, __devfn, __offset ) \
+    ({                                                                   		\
+    cyg_uint32 __address, __devicebit;							\
+    cyg_uint16 __mapaddress;								\
+    cyg_uint32 __dev = CYG_PCI_DEV_GET_DEV(__devfn);	/* FIXME to check!! (slot?) */	\
+											\
+    if (__bus == 0) {									\
+	/* local bus segment so need a type 0 config cycle */				\
+        /* build the PCI configuration "address" with one-hot in A31-A11 */		\
+        __address = PCI_CONFIG_BASE;							\
+        __address |= ((__devfn & 0x07) << 8);						\
+        __address |= __offset & 0xFF;							\
+        __mapaddress = 0x000A;    /* 101=>config cycle, 0=>A1=A0=0 */			\
+        __devicebit = (1 << (__dev + 11));						\
+											\
+        if ((__devicebit & 0xFF000000) != 0) {						\
+            /* high order bits are handled by the MAP register */			\
+            __mapaddress |= (__devicebit >> 16);					\
+        } else {									\
+            /* low order bits handled directly in the address */			\
+            __address |= __devicebit;							\
+        }										\
+    } else {	/* bus !=0 */								\
+        /* not the local bus segment so need a type 1 config cycle */			\
+        /* A31-A24 are don't care (so clear to 0) */					\
+        __mapaddress = 0x000B;    /* 101=>config cycle, 1=>A1&A0 from PCI_CFG */	\
+        __address = PCI_CONFIG_BASE;							\
+        __address |= ((__bus & 0xFF) << 16);  	/* bits 23..16 = bus number 	*/	\
+        __address |= ((__dev & 0x1F) << 11);  	/* bits 15..11 = device number  */	\
+        __address |= ((__devfn & 0x07) << 8);  	/* bits 10..8  = function number*/	\
+        __address |= __offset & 0xFF;  		/* bits  7..0  = register number*/	\
+    }											\
+    _V3Write16(V3_LB_MAP1, __mapaddress);						\
+											\
+    __address;										\
+    })
+
+// Read a value from the PCI configuration space of the appropriate
+// size at an address composed from the bus, devfn and offset.
+#define HAL_PCI_CFG_READ_UINT8( __bus, __devfn, __offset, __val )  		\
+    {										\
+    _V3OpenConfigWindow();							\
+    __val = *(cyg_uint8 *)HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset); 	\
+    _V3CloseConfigWindow();							\
+    }
+
+#define HAL_PCI_CFG_READ_UINT16( __bus, __devfn, __offset, __val )  		\
+    {										\
+    _V3OpenConfigWindow();							\
+    __val = *(cyg_uint16 *)HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset); 	\
+    _V3CloseConfigWindow();							\
+    }
+
+#define HAL_PCI_CFG_READ_UINT32( __bus, __devfn, __offset, __val )  		\
+    {										\
+    _V3OpenConfigWindow();							\
+    __val = *(cyg_uint32 *)HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset); 	\
+    _V3CloseConfigWindow();							\
+    }
+
+// Write a value to the PCI configuration space of the appropriate
+// size at an address composed from the bus, devfn and offset.
+#define HAL_PCI_CFG_WRITE_UINT8( __bus, __devfn, __offset, __val )		\
+    {										\
+    _V3OpenConfigWindow();							\
+    *(cyg_uint8 *)HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset) = __val; 	\
+    _V3CloseConfigWindow();							\
+    }
+
+#define HAL_PCI_CFG_WRITE_UINT16( __bus, __devfn, __offset, __val )		\
+    {										\
+    _V3OpenConfigWindow();							\
+    *(cyg_uint16 *)HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset) = __val; 	\
+    _V3CloseConfigWindow();							\
+    }
+
+#define HAL_PCI_CFG_WRITE_UINT32( __bus, __devfn, __offset, __val )		\
+    {										\
+    _V3OpenConfigWindow();							\
+    *(cyg_uint32 *)HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset) = __val; 	\
+    _V3CloseConfigWindow();							\
+    }
+
+//-----------------------------------------------------------------------------
+// Resources
+
+// Map PCI device resources starting from these addresses in PCI space.
+#define HAL_PCI_ALLOC_BASE_MEMORY 0
+#define HAL_PCI_ALLOC_BASE_IO     0x4000
+
+// This is where the PCI spaces are mapped in the CPU's address space.
+#define HAL_PCI_PHYSICAL_MEMORY_BASE    (PCI_MEM_BASE)
+#define HAL_PCI_PHYSICAL_IO_BASE        (PCI_IO_BASE)
+
+// Translate the PCI interrupt requested by the device (INTA#, INTB#,
+// INTC# or INTD#) to the associated CPU interrupt (i.e., HAL vector).
+#define INTA CYGNUM_HAL_INTERRUPT_PCIINT0
+#define INTB CYGNUM_HAL_INTERRUPT_PCIINT1
+#define INTC CYGNUM_HAL_INTERRUPT_PCIINT2
+#define INTD CYGNUM_HAL_INTERRUPT_PCIINT3
+
+#define HAL_PCI_TRANSLATE_INTERRUPT( __bus, __devfn, __vec, __valid)          \
+    CYG_MACRO_START                                                           \
+    cyg_uint8 __req;                                                          \
+    cyg_uint32 __dev;							      \
+    /* DANGER! For now this is the SDM interrupt table... */	      	      \
+    static const cyg_uint8 irq_tab[12][4] = {	      			      \
+		/* INTA  INTB  INTC  INTD */				      \
+		{INTA, INTB, INTC, INTD},  /* idsel 20, slot  9 */	      \
+		{INTB, INTC, INTD, INTA},  /* idsel 21, slot 10 */	      \
+		{INTC, INTD, INTA, INTB},  /* idsel 22, slot 11 */	      \
+		{INTD, INTA, INTB, INTC},  /* idsel 23, slot 12 */	      \
+		{INTA, INTB, INTC, INTD},  /* idsel 24, slot 13 */	      \
+		{INTB, INTC, INTD, INTA},  /* idsel 25, slot 14 */	      \
+		{INTC, INTD, INTA, INTB},  /* idsel 26, slot 15 */	      \
+		{INTD, INTA, INTB, INTC},  /* idsel 27, slot 16 */	      \
+		{INTA, INTB, INTC, INTD},  /* idsel 28, slot 17 */	      \
+		{INTB, INTC, INTD, INTA},  /* idsel 29, slot 18 */	      \
+		{INTC, INTD, INTA, INTB},  /* idsel 30, slot 19 */	      \
+		{INTD, INTA, INTB, INTC}   /* idsel 31, slot 20 */	      \
+    };								      	      \
+    HAL_PCI_CFG_READ_UINT8(__bus, __devfn, CYG_PCI_CFG_INT_PIN, __req);       \
+    __dev  = CYG_PCI_DEV_GET_DEV(__devfn);	/* FIXME to check!! (slot?)*/ \
+									      \
+    /* if PIN = 0, default to A */					      \
+    if (__req == 0)							      \
+	__req = 1;							      \
+									      \
+    __vec = irq_tab[__dev - 9][__req - 1];				      \
+    __valid = true;                                                           \
+    CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// end of plf_io.h
+#endif // CYGONCE_PLF_IO_H
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/include/plf_stub.h
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+//      plf_stub.h
+//
+//      Platform header for GDB stub support.
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   David A Rusling
+// Contributors:Philippe Robin
+// Date:        November 7, 2000
+// Purpose:     Platform HAL stub support for ARM INTEGRATOR boards.
+// Usage:       #include <cyg/hal/plf_stub.h>
+//              
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_integrator.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/infra/cyg_type.h>         // CYG_UNUSED_PARAM
+
+#include <cyg/hal/arm_stub.h>           // architecture stub support
+
+//----------------------------------------------------------------------------
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+externC void cyg_hal_plf_comms_init(void);
+
+#define HAL_STUB_PLATFORM_INIT_SERIAL()       cyg_hal_plf_comms_init()
+
+#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
+#define HAL_STUB_PLATFORM_INTERRUPTIBLE       0
+#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ()    CYG_EMPTY_STATEMENT
+
+//----------------------------------------------------------------------------
+// Stub initializer.
+#define HAL_STUB_PLATFORM_INIT()              CYG_EMPTY_STATEMENT
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/misc/redboot_RAM.ecm
@@ -0,0 +1,72 @@
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+    description "" ;
+    hardware    integrator ;
+    template    redboot ;
+    package -hardware CYGPKG_HAL_ARM current ;
+    package -hardware CYGPKG_HAL_ARM_INTEGRATOR current ;
+    package -hardware CYGPKG_IO_PCI current ;
+    package -hardware CYGPKG_DEVS_ETH_ARM_INTEGRATOR current ;
+    package -hardware CYGPKG_IO_SERIAL_ARM_INTEGRATOR current ;
+    package -hardware CYGPKG_DEVS_FLASH_INTEGRATOR current ;
+    package -template CYGPKG_HAL current ;
+    package -template CYGPKG_INFRA current ;
+    package -template CYGPKG_REDBOOT current ;
+    package CYGPKG_IO_FLASH current ;
+    package CYGPKG_IO_ETH_DRIVERS current ;
+};
+
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+    inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+    inferred_value 0
+};
+
+cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_DIAG {
+    user_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+    user_value RAM
+};
+
+cdl_component CYGBLD_BUILD_REDBOOT {
+    user_value 1
+};
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
+
+
+
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/misc/redboot_ROM.ecm
@@ -0,0 +1,76 @@
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+    description "" ;
+    hardware    integrator ;
+    template    redboot ;
+    package -hardware CYGPKG_HAL_ARM current ;
+    package -hardware CYGPKG_HAL_ARM_INTEGRATOR current ;
+    package -hardware CYGPKG_IO_PCI current ;
+    package -hardware CYGPKG_DEVS_ETH_ARM_INTEGRATOR current ;
+    package -hardware CYGPKG_IO_SERIAL_ARM_INTEGRATOR current ;
+    package -hardware CYGPKG_DEVS_FLASH_INTEGRATOR current ;
+    package -template CYGPKG_HAL current ;
+    package -template CYGPKG_INFRA current ;
+    package -template CYGPKG_REDBOOT current ;
+    package CYGPKG_IO_FLASH current ;
+    package CYGPKG_IO_ETH_DRIVERS current ;
+};
+
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+    user_value 0
+};
+
+cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+    inferred_value 0
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+    inferred_value 1
+};
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+    inferred_value 0
+};
+
+#cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_DIAG {
+#    user_value 1
+#};
+
+cdl_option CYGSEM_HAL_ROM_MONITOR {
+    user_value 1
+};
+
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+    inferred_value 0 0
+};
+
+cdl_component CYG_HAL_STARTUP {
+    user_value ROM
+};
+
+cdl_component CYGBLD_BUILD_REDBOOT {
+    user_value 1
+};
+
+cdl_option CYGSEM_REDBOOT_BSP_SYSCALLS {
+  inferred_value 1
+};
+
+
+
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/src/Notes_GDB_stub
@@ -0,0 +1,56 @@
+===========================================================================
+####COPYRIGHTBEGIN####
+                                                                          
+ -------------------------------------------                              
+ The contents of this file are subject to the Red Hat eCos Public License 
+ Version 1.1 (the "License"); you may not use this file except in         
+ compliance with the License.  You may obtain a copy of the License at    
+ http://www.redhat.com/                                                   
+                                                                          
+ Software distributed under the License is distributed on an "AS IS"      
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+ License for the specific language governing rights and limitations under 
+ the License.                                                             
+                                                                          
+ The Original Code is eCos - Embedded Configurable Operating System,      
+ released September 30, 1998.                                             
+                                                                          
+ The Initial Developer of the Original Code is Red Hat.                   
+ Portions created by Red Hat are                                          
+ Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+ All Rights Reserved.                                                     
+ -------------------------------------------                              
+                                                                          
+####COPYRIGHTEND####
+===========================================================================
+
+How to build and install the GDB module on ARM Integrator
+
+Make GDB module
+~~~~~~~~~~~~~~~
+Configure and build using the 'stubs' template for the PID
+target. These are the necessary CLI instructions. It can also be done
+from the Configtool by selecting the appropriate templates.
+
+ % cd /tmp
+ % mkdir stubs
+ % cd stubs
+ % ecosconfig new integrator stubs
+ % ecosconfig tree
+ % make
+
+This will install some files in ./install/bin:
+
+ gdb_module.elf:   The built stubs image
+ gdb_module.bin:   The image converted to binary (suitable for burning to ROM)
+ gdb_module.img:   The relocated ELF image (suitable for FLASH writing, see below)
+
+
+Prepare board for eCos
+~~~~~~~~~~~~~~~~~~~~~~
+
+Program FLASH
+~~~~~~~~~~~~~
+The GDB module can be programmed into the begining of the user flash using an ARM debugger 
+connected to the board either via Angel or Multi-ICE. 
+
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/src/flash.c
@@ -0,0 +1,669 @@
+//==========================================================================
+//
+//        flash.c
+//
+//        ARM INTEGRATOR A/P FLASH program tool
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     gthomas
+// Contributors:  Philippe Robin
+// Date:          November 7, 2000
+// Description:   Tool used to program onboard FLASH image
+//####DESCRIPTIONEND####
+
+//
+// This program will program the FLASH on INTEGRATOR A/P board
+//
+
+#include <pkgconf/libc.h>   // Configuration header
+
+#include <cyg/kernel/kapi.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cyg/infra/testcase.h>
+#include <sys/cstartup.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  1
+#endif
+
+#define PROGRAM_COMMAND    0x00100010
+#define PROGRAM_VERIFY     0x00D000D0
+#define READ_STATUS        0x70707070
+#define SR_MASK            0x00800080
+#define READ_ARRAY         0x00FF00FF
+#define BLOCK_ERASE        0x00200020
+#define BLOCK_WRITE_MODE   0x00E800E8
+#define BLOCK_LOCK_BITS    0x00600060
+#define CFI_QUERY_OFFS     0x00000055
+#define CFI_QUERY_COMMAND  0x00980098
+#define CFI_DATA_OFFS      0x00000020
+#define SYS_INFO_SIZE_OFF  0x00000027
+#define SYS_INFO_WB_OFF    0x0000002A
+#define SYS_ERASE_SIZE_OFF 0x0000002F
+#define STATUS_READY_MASK  0x00800080
+#define BANK_BOUNDARY      0x0001FFFF
+#define STATUS_ERROR       0x00100010
+#define MAX_WRITE_BUFF     0xF
+
+// Integrator EBI register definitions
+
+#define INTEGRATOR_EBI_BASE 0x12000000
+
+#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
+#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
+#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
+#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
+#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
+
+#define INTEGRATOR_EBI_CSR0 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
+#define INTEGRATOR_EBI_CSR1 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define INTEGRATOR_EBI_CSR2 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
+#define INTEGRATOR_EBI_CSR3 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
+#define INTEGRATOR_EBI_LOCK (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+#define INTEGRATOR_EBI_8_BIT            0x00
+#define INTEGRATOR_EBI_16_BIT           0x01
+#define INTEGRATOR_EBI_32_BIT           0x02
+#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
+#define INTEGRATOR_EBI_SYNC             0x08
+#define INTEGRATOR_EBI_WS_2             0x00
+#define INTEGRATOR_EBI_WS_3             0x10
+#define INTEGRATOR_EBI_WS_4             0x20
+#define INTEGRATOR_EBI_WS_5             0x30
+#define INTEGRATOR_EBI_WS_6             0x40
+#define INTEGRATOR_EBI_WS_7             0x50
+#define INTEGRATOR_EBI_WS_8             0x60
+#define INTEGRATOR_EBI_WS_9             0x70
+#define INTEGRATOR_EBI_WS_10            0x80
+#define INTEGRATOR_EBI_WS_11            0x90
+#define INTEGRATOR_EBI_WS_12            0xA0
+#define INTEGRATOR_EBI_WS_13            0xB0
+#define INTEGRATOR_EBI_WS_14            0xC0
+#define INTEGRATOR_EBI_WS_15            0xD0
+#define INTEGRATOR_EBI_WS_16            0xE0
+#define INTEGRATOR_EBI_WS_17            0xF0
+
+#define FL_SC_CONTROL			0x06	// Enable Flash Write and Vpp
+
+
+#define INVALID_FTYPE		0x00000000
+#define UNKNOWN_FTYPE		0xFFFFFFFF
+#define ATMEL_FTYPE		0x00000001
+#define INTEL_FTYPE		0x00000002
+
+#define FLASH_TYPE_MASK		(ATMEL_FTYPE | INTEL_FTYPE)
+
+// On Some platforms Boot and program flash may be part of the same device
+#define INTEGRATED_FTYPE	0x80000000
+#define BOOT_FTYPE		0x40000000
+#define APP_FTYPE		0x20000000
+
+#define FLASH_USAGE_MASK	(BOOT_FTYPE | APP_FTYPE)
+
+#define DEFAULT_FLASH_MASK 0xFFFFFFF8
+#define FLASH_BLOCK_SIZE	0x00020000	// 128Kb
+#define EPROM_BASE		0x20000000
+#define EPROM_SIZE		0x00080000	// 512Kb
+#define FLASH_BASE		0x24000000
+#define FLASH_SIZE		0x02000000	// 32Mb
+
+typedef int flashWrite(char *address, unsignedint  data, char *flash);
+typedef int flashWriteBlock(char *address, unsigned int *data, unsigned int size, char *flash);
+typedef int flashRead(char *address, unsigned int *value);
+typedef int flashReadBlock(char *address, unsigned int *data, unsigned int size);
+typedef int flashErase(char *address, unsigned size, char *flash);
+typedef int flashInit(char *address, char *flash);
+typedef int flashClose(char *address, char *flash);
+
+typedef struct flashType {
+    char *base;			// Base Address of flash
+    char *physicalBase;		// before mem initialisation
+    unsigned int size;		// Size of flash, in bytes
+    unsigned int type;		// Atmel / Intel (CFI) / Unknown
+    unsigned int writeSize;	// Size of physical block
+    unsigned int eraseSize;	// Size of block erase
+    unsigned int logicalSize;	// Size of logical block
+    flashWrite *write;   	// Write one word
+    flashWriteBlock *writeBlock;// Write a block of writeSize bytes
+    flashRead *read;     	// Read one word
+    flashReadBlock *readBlock;  // Read a block of writeSize bytes
+    flashErase *erase;   	// Erase a block of eraseSize bytes
+    flashInit *init;     	// Lock a flash device
+    flashClose *close;		// Unlock a flash device
+    char *ident;		// identification string
+    struct flashType *next;     // Pointer to next flash device
+} tFlash;
+
+tFlash Integrator_Flash[2] = {
+    {
+	(char *)EPROM_BASE,	// Base Address of flash
+	(char *)EPROM_BASE,	// Physical Address of flash
+	EPROM_SIZE,	        // Size of flash, in bytes (512K)
+	BOOT_FTYPE | ATMEL_FTYPE,// Flash type
+	FLASH_BLOCK_SIZE,	// Size of physical block
+	FLASH_BLOCK_SIZE,	// Size of block erase
+	FLASH_BLOCK_SIZE,	// Size of logical block
+	ATMEL_Write_Word,	// Write one word
+	ATMEL_Write_Block,	// Write a block of WriteSize
+	ATMEL_Read_Word,
+	ATMEL_Read_Block,
+	ATMEL_Erase_Block,
+	0,			// Lock a flash device
+	0,			// Unlock a flash device
+	"Atmel",		// Null terminated Info string
+	(tFlash *)&Integrator_Flash[1] // Pointer to next tFlash struct
+    },
+    {
+	(char *)FLASH_BASE,	// Base Address of flash
+	(char *)FLASH_BASE,	// Physical Address of flash
+	FLASH_SIZE,		// Size of flash, in bytes
+	APP_FTYPE | INTEL_FTYPE,// Flash type
+	FLASH_BLOCK_SIZE,	// Size of physical block
+	FLASH_BLOCK_SIZE,	// Size of block erase
+	FLASH_BLOCK_SIZE,	// Size of logical block
+	CFI_Write_Word,         // Write one word
+        CFI_Write_Block,        // Write a block of writeSize bytes
+        CFI_Read_Word,          // Read one word
+        CFI_Read_Block,         // Read a block of writeSize bytes
+        CFI_Erase_Block,        // Erase a block of eraseSize bytes
+	0,			// Lock a flash device
+	0,			// Unlock a flash device
+	"Intel 28F320S3",       // Null terminated Info string
+	0			// Pointer to next tFlash struct
+   }
+};
+
+#define SYNC_COUNT 63
+
+extern void diag_printf(const char *, ...);
+int identify_FLASH(void);
+void write_sector(int, char *);
+bool load_srecords(char (*readc)(), CYG_ADDRESS *start, int *size);
+
+char dbuf[256];
+char *raw = (char *)0x10000;
+char *flash_buffer = (char *)0x30000;
+int pos, len;
+
+// FUNCTIONS
+
+externC void
+cyg_package_start( void )
+{
+#ifdef CYGPKG_LIBC
+    cyg_iso_c_start();
+#else
+    (void)main(0, NULL);
+#endif
+} // cyg_package_start()
+
+char nextch(void)
+{
+    return (raw[pos++]);
+}
+
+int
+main( int argc, char *argv[] )
+{
+    int i, j, size;
+    CYG_ADDRESS entry;
+    char c;
+
+    diag_printf("FLASH here!\n");
+
+    CFI_Identify_Flash(Integrator_Flash[1]);
+
+    while (identify_FLASH() == 0) {
+        diag_printf("... Please change FLASH jumper - hit C/R to continue:");
+        do {
+            hal_diag_read_char(&c);
+        } while ((c != '\r') && (c != '\n'));
+        diag_printf("\n");
+    }
+ restart:
+    diag_printf("Ready file - hit C/R to continue:");
+    while (TRUE) {
+        hal_diag_read_char(&c);
+        if (c == '>') break;
+    }
+    i = 0;  j = 0;
+    while (1) {
+        hal_diag_read_char(&c);
+        if (c == '!') {
+            diag_printf("... Reset\n");
+            goto restart;
+        }
+        raw[i++] = c;
+        if (++j == SYNC_COUNT) {
+            hal_diag_write_char(c);
+            j = 0;
+        }
+        if (c == ':') break;
+    }
+    diag_printf("\n");
+    pos = 0;  len = i;
+    if (load_srecords(nextch, &entry, &size)) {
+        diag_printf("Read %x bytes, entry: %x\n", size, entry);
+        dump_buf(flash_buffer, 128);
+        diag_printf("\nData loaded - hit '!' to continue:");
+        while (TRUE) {
+            hal_diag_read_char(&c);
+            if (c == '!') break;
+        }
+        diag_printf("\n");
+        diag_printf("...Programming FLASH\n");
+        pos = 0;  i = 0;
+        while (pos < size) {
+            write_sector(i++, flash_buffer+pos);
+            pos += 256;
+        }
+    } else {
+        // Display buffer around failure        
+        dump_buf(&raw[pos-32], 64);
+    }
+    diag_printf("All done!\n");
+    while (1) ;
+}
+
+int
+CFI_Identify_Flash(tFlash * flash)
+{                                    
+     int offset = CFI_DATA_OFFS;
+   
+     // CFI query to check for CFI string "QRY"
+     // Write 0x98 to address flash + 55
+    *(unsigned int *)(flash->base + CFI_QUERY_OFFS) = CFI_QUERY_COMMAND;
+   
+    if ( *(flash->base + offset) == 'Q') {
+         int temp = 0;
+         offset += 2;
+
+         if ( *(flash->base+ offset) == 'R') {
+	     temp =  *(flash->base+ SYS_INFO_SIZE_OFF); // read block size
+	     flash->size = 2 ^ temp;
+	     temp = *(flash->base+ SYS_ERASE_SIZE_OFF);	// Read Erase Regions
+	     temp += ( *(flash->base+ SYS_ERASE_SIZE_OFF + 1) << 4);
+           
+	     flash->eraseSize = temp * 256;
+	     // Read Max write Buffer (logical Block size)
+         } else
+	   return FALSE;
+    }
+     
+    // Reset for Read operation
+   *(unsigned int *)(flash->base)  = READ_ARRAY; 
+
+   return TRUE;
+}
+
+// Adapted from ARM sample code
+#define SEQ_ADD1                0x5555
+#define SEQ_ADD2                0xAAAA
+#define START_CMD1              0xAA
+#define START_CMD2              0x55
+#define ID_CMD                  0x90
+#define PROG_CMD                0xA0
+#define STOP_CMD                0xF0
+
+#define MAN_ATMEL               0x1F
+#define ATMEL_AT29C040_ID       0X5B
+#define ATMEL_AT29C040A_ID      0XA4
+#define ATMEL_AT29C1024_ID      0X25
+#define ATMEL_SECTOR_SIZE       256
+#define ATMEL_MAX_SECTORS       2048
+
+int manuf_code, device_code, sector_size, max_no_of_sectors, word_mode;
+volatile char *FLASH = (volatile char *)0x24000000;
+
+int
+identify_FLASH(void )
+{
+    // enable write to the Flash
+    flashWriteEnable();
+  
+    // Enter Software Product Identification Mode
+    FLASH[SEQ_ADD1] = START_CMD1;
+    FLASH[SEQ_ADD2] = START_CMD2;
+    FLASH[SEQ_ADD1] = ID_CMD;
+
+    // Wait at least 10ms
+    cyg_thread_delay(2);
+
+    // Read Manufacturer and device code from the device
+    manuf_code = FLASH[0];
+    device_code = FLASH[1];
+
+    diag_printf("manuf: %x, device: %x\n", manuf_code, device_code);
+
+    // Exit Software Product Identification Mode
+    FLASH[SEQ_ADD1] = START_CMD1;
+    FLASH[SEQ_ADD2] = START_CMD2;
+    FLASH[SEQ_ADD1] = STOP_CMD;
+
+    // Wait at least 10ms
+    cyg_thread_delay(5)
+
+    // disble write to the Flash
+    flashWriteDisable();;
+
+    if (manuf_code != MAN_ATMEL) {
+        diag_printf ( "Error: Wrong Manufaturer: %02x\n",manuf_code );
+        return (0);
+    }
+
+    switch (device_code) {
+    case  ATMEL_AT29C040A_ID:
+        diag_printf ("AT29C040A recognised\n");
+        sector_size = ATMEL_SECTOR_SIZE;
+        max_no_of_sectors = ATMEL_MAX_SECTORS;
+        word_mode = FALSE;
+        break;
+    case  ATMEL_AT29C1024_ID:
+        diag_printf ("AT29C1024 recognised\n");
+        sector_size = ATMEL_SECTOR_SIZE;
+        max_no_of_sectors = ATMEL_MAX_SECTORS;
+        word_mode = TRUE;
+        break;
+    default :
+        diag_printf ( "Error: Unsupported device: %02x\n", device_code);
+        return (0);
+    }
+    return (1);
+}
+
+void
+write_sector(int num, char *buf)
+{
+    int i, cnt;
+    volatile char *wrt = (volatile int *)&FLASH[num*sector_size];
+
+//    diag_printf("Writing to %08x\n", wrt);
+    // Enter Program Mode
+    FLASH[SEQ_ADD1] = START_CMD1;
+    FLASH[SEQ_ADD2] = START_CMD2;
+    FLASH[SEQ_ADD1] = PROG_CMD;
+
+    // Note: write bytes as longs regardless of bus width
+    for (i = 0;  i < sector_size;  i++) {
+        wrt[i] = buf[i];
+    }
+
+    // Wait for sector to program
+    cnt = 0;
+    i = sector_size - 1;
+    while (wrt[i] != buf[i]) {
+        if (cnt++ > 0x01000000) break;
+    }
+//    diag_printf("Out - i: %d, wrt[i] = %08X.%08X, buf[i] = %08X, count = %x\n", i, &wrt[i], wrt[i], buf[i], cnt);
+
+    // Verify
+    for (i = 0;  i < sector_size;  i++) {
+        for (cnt = 0;  cnt < 10;  cnt++) {
+            if (*wrt == *buf) break;
+            cyg_thread_delay(1);
+        }
+        if (cnt == 10) {
+            diag_printf("Can't program at 0x%08X: %02X not %02X\n", wrt, *wrt, *buf);
+        }
+        wrt++;  buf++;
+    }
+}
+
+void 
+flashWriteEnable(void)
+{
+     volatile unsigned int *ebi_csr1 = (volatile unsigned int *)INTEGRATOR_EBI_CSR1;
+
+     // allow write access to EBI_CSR1 area (Flash)
+
+     *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE;
+
+     if (!(*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE)) {
+	 *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 0xA05F;
+	 *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE;
+	 *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 0;
+     }
+
+     /* Enable Vpp and allow write access to Flash in system controller */
+
+     *(volatile unsigned int *)INTEGRATOR_SC_CTRLS = FL_SC_CONTROL;
+}
+
+//
+// flashWriteDisable: disable write access to the Flash memory
+//
+
+void 
+flashWriteDisable(void)
+{
+     volatile unsigned int *ebi_csr1 = (volatile unsigned int *)INTEGRATOR_EBI_CSR1;
+
+     // disable write access to EBI_CSR1 area (Flash)
+
+     *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE;
+
+     if (*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE) {
+	 *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 0xA05F;
+	 *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE;
+	 *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 1;
+     }
+
+     // Disable Vpp and disable write access to Flash in system controller
+
+     *(volatile unsigned int *)INTEGRATOR_SC_CTRLS = 0;
+}
+
+// S-record download code - viciously 'adapted' from "kernel/src/sload/sload.c"
+
+/*---------------------------------------------------------------------------*/
+/*
+//
+//      An srecord looks like this:
+//
+// byte count-+     address
+// start ---+ |        |       data        +- checksum
+//          | |        |                   |
+//        S01000006F6B692D746573742E73726563E4
+//        S315000448600000000000000000FC00005900000000E9
+//        S31A0004000023C1400037DE00F023604000377B009020825000348D
+//        S30B0004485A0000000000004E
+//        S70500040000F6
+//
+//      S<type><length><address><data><checksum>
+//
+//      Where 
+//      - length (2 characters)
+//        is the number of bytes following upto the checksum. Note that
+//        this is not the number of chars following, since it takes two
+//        chars to represent a byte.
+//      - type (2 characters)
+//        is one of:
+//        0) header record
+//        1) two byte address data record
+//        2) three byte address data record
+//        3) four byte address data record
+//        5) record containing the number of S1, S2, or S3 records
+//        7) four byte address termination record
+//        8) three byte address termination record
+//        9) two byte address termination record
+//       
+//      - address (4, 6, or 8 characters)
+//        is the start address of the data following, or in the case of
+//        a termination record, the start address of the image
+//      - data (0-2n characters)
+//        is the data.
+//      - checksum (2 characters)
+//        is the sum of all the raw byte data in the record, from the length
+//        upwards, modulo 256 and subtracted from 255.
+//
+// Useful S-records for testing purposes:
+//   Start record:
+//      S00B0000737461303030447563
+//   This sets the default address to be 0x02005000:
+//      S31A020050002700801481C4E0B0A15000000100000091D02000018F
+//      S31A0200501500000001000000010000002700801881C4E2E4A150C1
+//      S311020080A42407070A090B0A0781050000E1
+//   Termination record:
+//      S70502005000A8
+//
+*/
+
+#define S0      0
+#define S1      1
+#define S2      2
+#define S3      3
+#define S5      5
+#define S7      7
+#define S8      8
+#define S9      9
+
+/*---------------------------------------------------------------------------*/
+
+int hex2digit(char c)
+{
+    if( c & 0x40 ) c += 9;;
+    return c &0x0f;
+    
+//    return ( c <= '9' ? c - '0' :
+//             c <= 'Z' ? c - 'A' + 10 :
+//             c - 'a' + 10);
+}
+
+/*---------------------------------------------------------------------------*/
+
+bool load_srecords(char (*readc)(), 
+                   CYG_ADDRESS *start,
+                   int *size)
+{
+    CYG_ADDRESS addr, load_addr;
+    int addrsize;
+    int length;
+    int i;
+    cyg_uint8 chksum, ochksum;
+    cyg_uint8 val;
+    cyg_uint8 *tdata;    
+    char s;
+    char type;
+    char len0;
+    char len1;
+    bool first = true;
+
+    
+    do {
+        // Skip whitespace characters until we find something that
+        // might be an 'S'.
+        do {
+            s = readc();
+        } while( s == '\r' || s == '\n' || s == ' ');
+
+        // Check that this is an S record
+        if( s != 'S' ) {
+            diag_printf("Invalid 'S' record\n");
+            return false;
+        }
+
+        // First 4 bytes are standard S + type + len
+        type = readc();
+        len0 = readc();
+        len1 = readc();
+        
+        // decode the type
+        type = hex2digit(type);
+
+        // determine address size
+        switch (type) {
+        case S0:                        // start records have no address
+            addrsize = 0;
+            break;
+        case S1:                        // two byte address
+        case S9:
+            addrsize = 4;
+            break;
+        case S2:                        // 3 byte address
+        case S8:
+            addrsize = 6;
+            break;   
+        case S3:                        // 4 byte address
+        case S7:
+            addrsize = 8;
+            break;
+        }
+
+        length  = hex2digit (len0) << 4;
+        length |= hex2digit (len1);
+        chksum = length;
+
+        // read the address
+        addr = 0;
+        for (i = 0; i < addrsize; i++) {
+            val = hex2digit(readc());
+            addr = (addr << 4) | val;
+        }
+
+        // calculate the checksum, which is done by the byte, not the digit
+        for (i = 0; i < addrsize*4; i += 8) {
+            chksum += ((addr >>  i) & 0xff);
+        }
+
+        // decide where to load this data
+        if (first && (type != S0)) {
+            load_addr = addr;
+            first = false;
+        }
+
+        // read the data and put it directly into memory where it belongs
+        tdata = (cyg_uint8 *)((addr - load_addr) + flash_buffer);
+        if (type < S7) {
+            *size = (addr - load_addr);
+        }
+        val = 0;
+        for (i = 0; i < ((length - 1) * 2) - addrsize; i += 2 ) {
+            val  = hex2digit (readc()) << 4;
+            val |= hex2digit (readc());
+            chksum += val;
+            if( type != S0 ) *tdata++ = val;
+            if (type < S7) *size = *size + 1;
+        }
+
+        // now get the old checksum
+        ochksum = hex2digit(readc()) << 4;
+        ochksum |= hex2digit(readc());
+        chksum = ~chksum;
+        if (chksum != ochksum) {
+            diag_printf("Bad checksum - addr: %x\n", addr);
+            return false;
+        }
+        
+    } while( type < S7 );
+
+    *start = addr;
+    return true;
+}
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/src/hal_diag.c
@@ -0,0 +1,669 @@
+/*=============================================================================
+//
+//      hal_diag.c
+//
+//      HAL diagnostic output code
+//
+//=============================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     David A Rusling
+// Contributors:  Philippe Robin
+// Date:          November 7, 2000
+// Purpose:       HAL diagnostic output
+// Description:   Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_integrator.h> // board specifics
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_arch.h>           // basic machine info
+#include <cyg/hal/hal_intr.h>           // interrupt macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_integrator.h>        // Hardware definitions
+
+
+/*---------------------------------------------------------------------------*/
+void abcd(void);
+
+/* Codes for ASCI characters 32-127 */
+unsigned int char_codes[] = {
+    0x0000, 0x2400, 0x0044, 0x7E12, 0x25DA, 0x4848, 0x2580, 0x0400,
+    0x0072, 0x001E, 0x7F80, 0x2580, 0x4000, 0x0180, 0x0000, 0x4800,
+    0x007E, 0x080C, 0x01B6, 0x011E, 0x01CC, 0x01DA, 0x01FA, 0x2802,
+    0x01FE, 0x01CE, 0x2400, 0x4400, 0x1800, 0x0190, 0x4200, 0x01A6,
+    0x217E, 0x01EE, 0x251E, 0x0072, 0x241E, 0x00F2, 0x00E2, 0x017A,
+    0x01EC, 0x2412, 0x001C, 0x18E0, 0x0070, 0x0A6C, 0x126C, 0x007E,
+    0x01E6, 0x107E, 0x11E6, 0x01DA, 0x2402, 0x007C, 0x4860, 0x506C,
+    0x5A00, 0x2A00, 0x4812, 0x0072, 0x1200, 0x001E, 0x0046, 0x0010,
+    0x0200, 0x01BE, 0x01F8, 0x01B0, 0x01BC, 0x01F6, 0x2980, 0x01DE,
+    0x01E8, 0x2000, 0x001C, 0x3500, 0x2400, 0x21A8, 0x01A8, 0x01B8,
+    0x01E6, 0x01CE, 0x01A0, 0x01DA, 0x00F0, 0x0038, 0x4020, 0x5028,
+    0x5A00, 0x030C, 0x4190, 0x2480, 0x2400, 0x2500, 0x0640, 0x0000
+};
+
+/* Codes for hexadecimal characters */
+unsigned int hex_codes[] = {
+    0x007E, 0x080C, 0x01B6, 0x011E, 0x01CC, 0x01DA, 0x01FA, 0x2802,
+    0x01FE, 0x01CE, 0x01EE, 0x01F8, 0x0072, 0x01BC, 0x00F2, 0x00E2
+};
+
+void hal_diag_alpha_led_char(char c1, char c2);
+
+
+// AMBA uart access macros
+#define GET_STATUS(p)		(IO_READ((p) + AMBA_UARTFR))
+#define GET_CHAR(p)		(IO_READ((p) + AMBA_UARTDR))
+#define PUT_CHAR(p, c)		(IO_WRITE(((p) + AMBA_UARTDR), (c)))
+#define IO_READ(p)              ((*(volatile unsigned int *)(p)) & 0xFF)
+#define IO_WRITE(p, c)          (*(unsigned int *)(p) = (c))
+#define RX_DATA(s)		(((s) & AMBA_UARTFR_RXFE) == 0)
+#define TX_READY(s)		(((s) & AMBA_UARTFR_TXFF) == 0)
+#define TX_EMPTY(p)		((GET_STATUS(p) & AMBA_UARTFR_TMSK) == 0)
+#define RX_EMPTY(p)		((GET_STATUS(p) & AMBA_UARTFR_RXFE) == 0)
+// Define the serial registers.
+
+//-----------------------------------------------------------------------------
+typedef struct {
+    cyg_uint8* base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+} channel_data_t;
+
+//-----------------------------------------------------------------------------
+
+#if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 9600)
+#define ARM_INTEGRATOR_BAUD_DIVISOR	ARM_BAUD_9600
+#elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 19200)
+#define ARM_INTEGRATOR_BAUD_DIVISOR	ARM_BAUD_9600
+#elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 38400)
+#define ARM_INTEGRATOR_BAUD_DIVISOR	ARM_BAUD_38400
+#elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 57600)
+#define ARM_INTEGRATOR_BAUD_DIVISOR	ARM_BAUD_57600
+#elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 115200)
+#define ARM_INTEGRATOR_BAUD_DIVISOR	ARM_BAUD_115200
+#endif
+
+static void
+cyg_hal_plf_serial_init_channel(void* __ch_data)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+
+    // first, disable everything
+    IO_WRITE(base + AMBA_UARTCR, 0x0);
+      
+    // Set baud rate CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+    IO_WRITE(base + AMBA_UARTLCR_M, ((ARM_INTEGRATOR_BAUD_DIVISOR & 0xf00) >> 8));
+    IO_WRITE(base + AMBA_UARTLCR_L, (ARM_INTEGRATOR_BAUD_DIVISOR & 0xff));
+      
+    // ----------v----------v----------v----------v----------
+    // NOTE: MUST BE WRITTEN LAST (AFTER UARTLCR_M & UARTLCR_L)
+    // ----------^----------^----------^----------^----------
+    // set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled
+    IO_WRITE(base + AMBA_UARTLCR_H, (AMBA_UARTLCR_H_WLEN_8 | AMBA_UARTLCR_H_FEN));
+  
+    // finally, enable the uart
+    IO_WRITE(base + AMBA_UARTCR, AMBA_UARTCR_UARTEN);
+
+}
+
+void
+cyg_hal_plf_serial_putc(void *__ch_data, char c)
+{
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint8* base = chan->base;
+    cyg_uint32 status;
+    CYGARC_HAL_SAVE_GP();
+
+    do {
+      status = GET_STATUS(base);
+    } while (!TX_READY(status));	// wait until ready
+
+    PUT_CHAR(base, c);
+
+    if (c == '\n') {
+      do {
+	status = GET_STATUS(base);
+      } while (!TX_READY(status));	// wait until ready
+      
+      PUT_CHAR(base, '\r');
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint32 status ;
+    long timeout = 100;  // A long time...
+
+    do {
+      status = GET_STATUS(base);
+      if (--timeout == 0) return false ; 
+    } while (!RX_DATA(status));	// wait until ready
+
+    *ch = GET_CHAR(base);
+
+    return true;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
+    || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
+
+static channel_data_t integrator_ser_channels[2] = {
+    { (cyg_uint8*)0x16000000, 1000, CYGNUM_HAL_INTERRUPT_UARTINT0 },
+    { (cyg_uint8*)0x17000000, 1000, CYGNUM_HAL_INTERRUPT_UARTINT1 }
+};
+
+static void
+cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
+                         cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while(__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+    for(;;) {
+        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+        
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    int ret = 0;
+    cyg_uint8 status;
+    CYGARC_HAL_SAVE_GP();
+
+    switch (__func) {
+    case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+	// Ensure that only Receive ints are generated.
+	status = IO_READ(chan->base + AMBA_UARTCR);
+
+	status |= (AMBA_UARTCR_RTIE | AMBA_UARTCR_RIE);
+	HAL_WRITE_UINT32(chan->base + AMBA_UARTCR, status);
+
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        break;
+    case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+	irq_state = 0;
+
+	status = IO_READ(chan->base + AMBA_UARTCR);
+	status &= ~(AMBA_UARTCR_RTIE | AMBA_UARTCR_TIE | AMBA_UARTCR_RIE | AMBA_UARTCR_MSIE);
+	HAL_WRITE_UINT32(chan->base + AMBA_UARTCR, status);
+
+        HAL_INTERRUPT_MASK(chan->isr_vector);
+        break;
+    case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+    case __COMMCTL_SET_TIMEOUT:
+    {
+        va_list ap;
+
+        va_start(ap, __func);
+
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+
+        va_end(ap);
+    }        
+    default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    int res = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    char c;
+    CYGARC_HAL_SAVE_GP();
+
+    cyg_drv_interrupt_acknowledge(chan->isr_vector);
+
+    *__ctrlc = 0;
+    if ( !RX_EMPTY(chan->base) ) { 
+        c = GET_CHAR(chan->base);
+
+        if( cyg_hal_is_break( &c , 1 ) )
+            *__ctrlc = 1;
+
+        res = CYG_ISR_HANDLED;
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static void
+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);
+
+    // Disable interrupts.
+    HAL_INTERRUPT_MASK(integrator_ser_channels[0].isr_vector);
+    HAL_INTERRUPT_MASK(integrator_ser_channels[1].isr_vector);
+
+    // Init channels
+    cyg_hal_plf_serial_init_channel(&integrator_ser_channels[0]);
+    cyg_hal_plf_serial_init_channel(&integrator_ser_channels[1]);
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &integrator_ser_channels[0]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+    // Set channel 1
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &integrator_ser_channels[1]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT2
+    cyg_hal_gdb_isr_attach();	// FIXME, hack to get CTRLC working
+#endif 
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef CYGHWR_HAL_ARM_INTEGRATOR_DIAG_LEDS
+
+void
+hal_diag_led(int n)
+{
+    volatile unsigned int *leds = (unsigned int *)INTEGRATOR_DBG_LEDS ;
+
+    *leds |= (n & 0xF) ;
+}
+void
+hal_diag_alpha_led(unsigned int val)
+{
+  volatile unsigned int *led = (unsigned int *)INTEGRATOR_DBG_BASE;
+
+  while (*led & 0x01) ;
+
+  *led = val;
+}
+
+void
+hal_diag_alpha_led_char(char c1, char c2)
+{
+  volatile unsigned int *led = (unsigned int *)INTEGRATOR_DBG_BASE;
+  unsigned int current;
+
+  current = *led;
+  if (c1) {
+    if (c1 < 32 || c1 > 127) c1=32;
+    if (c1 >= 'a' && c1 < 'z') c1 -= 32;
+
+    current &= ~(0x00007FFE << 14);
+    current |= (char_codes[c1-32] << 14);
+    }
+    
+    if (c2) {
+        if (c2 < 32 || c2 > 127) c2 = 32;
+	if (c2 >= 'a' && c2 <= 'z') c2 -= 32;
+        
+        current &= ~(0x00007FFE);
+        current |= char_codes[c2-32];
+    }
+    
+    hal_diag_alpha_led(current);
+}
+
+#endif // CYGHWR_HAL_ARM_INTEGRATOR_DIAG_LEDS
+
+//=============================================================================
+// Compatibility with older stubs
+//=============================================================================
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#include <cyg/hal/hal_stub.h>           // cyg_hal_gdb_interrupt
+#endif
+
+#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL==0
+// This is the base address of the A-channel
+#define CYG_DEVICE_SERIAL_BASE                  INTEGRATOR_UART0_BASE
+#define CYG_DEVICE_SERIAL_INT                   1
+#else
+// This is the base address of the B-channel
+#define CYG_DEVICE_SERIAL_BASE                  INTEGRATOR_UART1_BASE
+#define CYG_DEVICE_SERIAL_INT                   2
+#endif
+
+static channel_data_t integrator_ser_channel = {
+    (cyg_uint8*)CYG_DEVICE_SERIAL_BASE, 0, CYG_DEVICE_SERIAL_INT
+};
+
+// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e.
+// totally stand-alone) system.
+
+#if defined(CYG_HAL_STARTUP_ROM) || !defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
+#define HAL_DIAG_USES_HARDWARE
+#endif
+
+#ifndef HAL_DIAG_USES_HARDWARE
+#if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL != CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL)
+#define HAL_DIAG_USES_HARDWARE
+#endif
+#endif
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT2
+// Attempt to provide CtrlC support?
+static cyg_interrupt gdb_interrupt;
+static cyg_handle_t  gdb_interrupt_handle;
+
+// This ISR is called only for serial receive interrupts.
+int 
+cyg_hal_gdb_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+    cyg_uint8 c;
+
+    hal_diag_read_char(&c);  // Fetch the character
+    cyg_drv_interrupt_acknowledge(CYG_DEVICE_SERIAL_INT);
+    if( 3 == c ) {  // ^C
+        // Ctrl-C: set a breakpoint at PC so GDB will display the
+        // correct program context when stopping rather than the
+        // interrupt handler.
+        cyg_hal_gdb_interrupt (regs->pc);
+    }
+    return 0;  // No need to run DSR
+}
+
+int
+cyg_hal_gdb_isr_attach(void)
+{
+    cyg_drv_interrupt_create(CYG_DEVICE_SERIAL_INT,
+                             99,                     // Priority - what goes here?
+                             0,                      //  Data item passed to interrupt handler
+                             cyg_hal_gdb_isr,
+                             0,
+                             &gdb_interrupt_handle,
+                             &gdb_interrupt);
+    cyg_drv_interrupt_attach(gdb_interrupt_handle);
+}
+#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+
+#ifdef HAL_DIAG_USES_HARDWARE
+
+void hal_diag_init(void)
+{
+    static int init = 0;
+    int i;
+    char *msg = "\n\rARM eCos\n\r";
+
+    if (init++) return;
+
+    cyg_hal_plf_serial_init_channel(&integrator_ser_channel);
+
+    while (*msg) {
+        cyg_hal_plf_serial_putc(&integrator_ser_channel, *msg++);
+	for (i=0; i < 1000; i++) ;
+    }
+}
+
+#ifdef DEBUG_DIAG
+#ifndef CYG_HAL_STARTUP_ROM
+#define DIAG_BUFSIZE 2048
+static char diag_buffer[DIAG_BUFSIZE];
+static int diag_bp = 0;
+#endif // CYG_HAL_STARTUP_ROM
+#endif // DEBUG_DIAG
+
+void hal_diag_write_char(char c)
+{
+    hal_diag_init();
+
+    cyg_hal_plf_serial_putc(&integrator_ser_channel, c);
+
+#ifdef DEBUG_DIAG
+    diag_buffer[diag_bp++] = c;
+    if (diag_bp == DIAG_BUFSIZE) diag_bp = 0;
+#endif
+}
+
+void hal_diag_read_char(char *c)
+{
+    *c = cyg_hal_plf_serial_getc(&integrator_ser_channel);
+}
+
+#else // HAL_DIAG relies on GDB
+
+// Initialize diag port - assume GDB channel is already set up
+void hal_diag_init(void)
+{
+    if (0) cyg_hal_plf_serial_init_channel(&integrator_ser_channel); // avoid warning
+}
+
+// Actually send character down the wire
+static void
+hal_diag_write_char_serial(char c)
+{
+    hal_diag_init();
+
+    cyg_hal_plf_serial_putc(&integrator_ser_channel, c);
+}
+
+static bool
+hal_diag_read_serial(char *c)
+{
+    return cyg_hal_plf_serial_getc_nonblock(&integrator_ser_channel, c);
+}
+
+void 
+hal_diag_read_char(char *c)
+{
+    while (!hal_diag_read_serial(c)) ;
+}
+
+void 
+hal_diag_write_char(char c)
+{
+    static char line[100];
+    static int pos = 0;
+
+    // No need to send CRs
+    if( c == '\r' ) return;
+
+    line[pos++] = c;
+
+    if( c == '\n' || pos == sizeof(line) )
+    {
+        CYG_INTERRUPT_STATE old;
+
+        // Disable interrupts. This prevents GDB trying to interrupt us
+        // while we are in the middle of sending a packet. The serial
+        // receive interrupt will be seen when we re-enable interrupts
+        // later.
+        
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
+#else
+        HAL_DISABLE_INTERRUPTS(old);
+#endif
+
+        while(1)
+        {
+            static char hex[] = "0123456789ABCDEF";
+            cyg_uint8 csum = 0;
+            int i;
+            char c1;
+        
+            hal_diag_write_char_serial('$');
+            hal_diag_write_char_serial('O');
+            csum += 'O';
+            for( i = 0; i < pos; i++ )
+            {
+                char ch = line[i];
+                char h = hex[(ch>>4)&0xF];
+                char l = hex[ch&0xF];
+                hal_diag_write_char_serial(h);
+                hal_diag_write_char_serial(l);
+                csum += h;
+                csum += l;
+            }
+            hal_diag_write_char_serial('#');
+            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
+            hal_diag_write_char_serial(hex[csum&0xF]);
+
+            // Wait for the ACK character '+' from GDB here and handle
+            // receiving a ^C instead.  This is the reason for this clause
+            // being a loop.
+            if (!hal_diag_read_serial(&c1))
+                continue;   // No response - try sending packet again
+
+            if( c1 == '+' )
+                break;              // a good acknowledge
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+            cyg_drv_interrupt_acknowledge(CYG_DEVICE_SERIAL_INT);
+            if( c1 == 3 ) {
+                // Ctrl-C: breakpoint.
+                cyg_hal_gdb_interrupt ((target_register_t)__builtin_return_address(0));
+                break;
+            }
+#endif
+            // otherwise, loop round again
+        }
+        
+        pos = 0;
+
+        // And re-enable interrupts
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
+#else
+        HAL_RESTORE_INTERRUPTS(old);
+#endif
+        
+    }
+}
+#endif
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+/*---------------------------------------------------------------------------*/
+/* End of hal_diag.c */
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/src/integrator_misc.c
@@ -0,0 +1,178 @@
+//==========================================================================
+//
+//      integrator_misc.c
+//
+//      HAL misc board support code for ARM INTEGRATOR7
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    David A Rusling
+// Contributors: Philippe Robin
+// Date:         November 7, 2000
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_trac.h>         // tracing macros
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_arch.h>           // Register state info
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_intr.h>           // necessary?
+#include <cyg/hal/hal_integrator.h>
+
+/*------------------------------------------------------------------------*/
+// On-board timer
+/*------------------------------------------------------------------------*/
+
+// forward declarations
+void hal_if_init(void);
+
+// declarations
+static cyg_uint32 _period;
+
+void hal_clock_initialize(cyg_uint32 period)
+{
+    //diag_init();  diag_printf("%s(%d)\n", __PRETTY_FUNCTION__, period);
+    //diag_printf("psr = %x\n", psr());
+    HAL_WRITE_UINT32(CYG_DEVICE_TIMER_CONTROL, CTL_DISABLE);    // Turn off
+    HAL_WRITE_UINT32(CYG_DEVICE_TIMER_LOAD, period);
+    HAL_WRITE_UINT32(CYG_DEVICE_TIMER_CONTROL,
+		     CTL_ENABLE | CTL_PERIODIC | CTL_SCALE_16);
+    _period = period;
+}
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+    //diag_init();  diag_printf("%s\n", __PRETTY_FUNCTION__);
+    HAL_WRITE_UINT32(CYG_DEVICE_TIMER_CLEAR, 0);
+    _period = period;
+}
+
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+    cyg_uint32 value;
+//    diag_init();  diag_printf("%s\n", __PRETTY_FUNCTION__);
+    HAL_READ_UINT32(CYG_DEVICE_TIMER_CURRENT, value);
+    value &= 0xFFFF;
+    *pvalue = _period - (value & 0xFFFF);   // Note: counter is only 16 bits
+                                            //       and decreases
+}
+
+void hal_hardware_init(void)
+{
+    // Any hardware/platform initialization that needs to be done.
+
+    // Clear all interrupt sources
+    HAL_WRITE_UINT32(CYG_DEVICE_IRQ_EnableClear, 0xFFFF); 
+
+    // FIXME: The line with the thumb check is a hack, allowing
+    // the farm to run test. Problem is that virtual vector table
+    // API needs to be ARM/Thumb consistent. Will fix later.
+#ifndef __thumb__
+    // Set up eCos/ROM interfaces
+    hal_if_init();
+#endif
+}
+
+//
+// This routine is called to respond to a hardware interrupt (IRQ).  It
+// should interrogate the hardware and return the IRQ vector number.
+
+int hal_IRQ_handler(void)
+{
+    // Do hardware-level IRQ handling
+    int irq_status, vector;
+    HAL_READ_UINT32(CYG_DEVICE_IRQ_Status, irq_status);
+    //diag_init();  diag_printf("IRQ status: 0x%x\n", irq_status); 
+    for (vector = 1;  vector <= 16;  vector++) {
+        if (irq_status & (1<<vector)) return vector;
+    }
+    return -1 ; // This shouldn't happen!
+}
+
+//
+// Interrupt control
+//
+
+void hal_interrupt_mask(int vector)
+{
+    //diag_init();  diag_printf("hal_interrupt_mask(%d)\n", vector);
+    HAL_WRITE_UINT32(CYG_DEVICE_IRQ_EnableClear, 1<<vector);
+}
+
+#if 0
+void hal_interrupt_status(void)
+{
+    int irq_status, irq_enable, timer_status, timer_value, timer_load;
+    HAL_READ_UINT32(CYG_DEVICE_IRQ_Status, irq_status);
+    HAL_READ_UINT32(CYG_DEVICE_IRQ_Enable, irq_enable);
+    HAL_READ_UINT32(CYG_DEVICE_TIMER_LOAD, timer_load);
+    HAL_READ_UINT32(CYG_DEVICE_TIMER_CURRENT, timer_value);
+    HAL_READ_UINT32(CYG_DEVICE_TIMER_CONTROL, timer_status);    
+    diag_printf("Interrupt: IRQ: %x.%x, TIMER: %x.%x.%x, psr: %x\n",
+                irq_status, irq_enable, timer_status, timer_value,
+                timer_load, psr());
+}
+#endif
+
+void hal_interrupt_unmask(int vector)
+{
+    //diag_init();  diag_printf("hal_interrupt_unmask(%d)\n", vector);
+    HAL_WRITE_UINT32(CYG_DEVICE_IRQ_EnableSet, 1<<vector);
+}
+
+void hal_interrupt_acknowledge(int vector)
+{
+    //diag_init();  diag_printf("%s(%d)\n", __PRETTY_FUNCTION__, vector);
+}
+
+void hal_interrupt_configure(int vector, int level, int up)
+{
+    //diag_init();  diag_printf("%s(%d,%d,%d)\n", __PRETTY_FUNCTION__, vector, level, up);
+}
+
+void hal_interrupt_set_level(int vector, int level)
+{
+    //diag_init();  diag_printf("%s(%d,%d)\n", __PRETTY_FUNCTION__, vector, level);
+}
+
+void hal_show_IRQ(int vector, int data, int handler)
+{
+    //    diag_printf("IRQ - vector: %x, data: %x, handler: %x\n", vector, data, handler);
+}
+ 
+/*---------------------------------------------------------------------------*/
+/* End of hal_misc.c */
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/integrator/current/src/prog_flash.c
@@ -0,0 +1,292 @@
+//==========================================================================
+//
+//        prog_flash.c
+//
+//        ARM INTEGRATOR eval board FLASH program tool
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     gthomas
+// Contributors:  Philippe Robin
+// Date:          November 7, 2000
+// Description:   Tool used to program onboard FLASH image
+//####DESCRIPTIONEND####
+
+//
+// This program will program the FLASH on the PID board
+// It is similar to 'flash' (which also downloads S records) but it always
+// programs from a fixed buffer.  This is sufficient to load/update the GDB
+// stubs on the board.
+//
+
+#include <pkgconf/libc.h>   // Configuration header
+
+#include <cyg/kernel/kapi.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cyg/infra/testcase.h>
+#include <sys/cstartup.h>
+#include <cyg/hal/hal_integrator.h>
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  1
+#endif
+
+
+#define INVALID_FTYPE		0x00000000
+#define UNKNOWN_FTYPE		0xFFFFFFFF
+#define ATMEL_FTYPE		0x00000001
+#define INTEL_FTYPE		0x00000002
+
+#define FLASH_TYPE_MASK		(ATMEL_FTYPE | INTEL_FTYPE)
+
+// On Some platforms Boot and program flash may be part of the same device
+#define INTEGRATED_FTYPE	0x80000000
+#define BOOT_FTYPE		0x40000000
+#define APP_FTYPE		0x20000000
+
+#define FLASH_USAGE_MASK	(BOOT_FTYPE | APP_FTYPE)
+
+#define DEFAULT_FLASH_MASK 0xFFFFFFF8
+#define FLASH_BLOCK_SIZE	0x00020000	// 128Kb
+#define EPROM_BASE		0x20000000
+#define EPROM_SIZE		0x00080000	// 512Kb
+#define FLASH_BASE		0x24000000
+#define FLASH_SIZE		0x02000000	// 32Mb
+
+typedef struct flashType {
+    char *base;			// Base Address of flash
+    char *physicalBase;		// before mem initialisation
+    unsigned int size;		// Size of flash, in bytes
+    unsigned int type;		// Atmel / Intel (CFI) / Unknown
+    unsigned int writeSize;	// Size of physical block
+    unsigned int eraseSize;	// Size of block erase
+    unsigned int logicalSize;	// Size of logical block
+    char *ident;		// identification string
+} tFlash;
+
+tFlash Integrator_Flash[2] =
+{
+    {
+	(char *)EPROM_BASE,		// Base Address of flash
+	(char *)EPROM_BASE,		// Physical Address of flash
+	EPROM_SIZE,			// Size of flash, in bytes (512K)
+	BOOT_FTYPE | ATMEL_FTYPE,	// Flash type
+	FLASH_BLOCK_SIZE,	// Size of physical block
+	FLASH_BLOCK_SIZE,	// Size of block erase
+	FLASH_BLOCK_SIZE,	// Size of logical block
+	"Atmel",		// Null terminated Info string
+    },
+    {
+	(char *)FLASH_BASE,	// Base Address of flash
+	(char *)FLASH_BASE,	// Physical Address of flash
+	FLASH_SIZE,		// Size of flash, in bytes
+	APP_FTYPE | INTEL_FTYPE,	// Flash type
+	FLASH_BLOCK_SIZE,	// Size of physical block
+	FLASH_BLOCK_SIZE,	// Size of block erase
+	FLASH_BLOCK_SIZE,	// Size of logical block
+	"Intel 28F320S3",       // Null terminated Info string
+   }
+};
+
+
+extern void diag_printf(const char *, ...);
+int identify_FLASH(void);
+void write_sector(int, char *);
+
+char *flash_buffer =     (char *)0x60000;
+char *flash_buffer_end = (char *)0x80000;
+
+#ifdef BE_IMAGE
+#define BUF(x) buf[x^3]
+#else
+#define BUF(x) buf[x]
+#endif
+
+// FUNCTIONS
+
+externC void
+cyg_package_start( void )
+{
+#ifdef CYGPKG_LIBC
+    cyg_iso_c_start();
+#else
+    (void)main(0, NULL);
+#endif
+} // cyg_package_start()
+
+int
+main( int argc, char *argv[] )
+{
+    int i;
+
+    diag_printf("FLASH here!\n");
+    while (identify_FLASH() == 0) {
+        diag_printf("... Please change FLASH jumper\n");
+        cyg_thread_delay(5*100);
+    }
+    diag_printf("About to program FLASH using data at %x..%x\n", flash_buffer, flash_buffer_end);
+    diag_printf("*** Press RESET now to abort!\n");
+    cyg_thread_delay(5*100);
+    diag_printf("\n");
+    diag_printf("...Programming FLASH\n");
+
+    i = 0;
+    while (flash_buffer < flash_buffer_end) {
+        write_sector(i++, flash_buffer);
+        flash_buffer += 256;
+    }
+    diag_printf("All done!\n");
+    while (1) ;
+}
+
+// Adapted from ARM sample code
+#define SEQ_ADD1                0x5555
+#define SEQ_ADD2                0x2aaa
+#define START_CMD1              0xaaaaaaaa
+#define START_CMD2              0x55555555
+#define ID_CMD                  0x90909090
+#define PROG_CMD                0xA0
+#define STOP_CMD                0xf0f0f0f0
+
+#define MAN_ATMEL               0x1F
+#define ATMEL_AT29C040_ID       0X5B
+#define ATMEL_AT29C040A_ID      0XA4
+#define ATMEL_AT29C1024_ID      0X25
+#define ATMEL_SECTOR_SIZE       256
+#define ATMEL_MAX_SECTORS       2048
+
+#define MAN_INTEL		0xB0
+#define INTEL_28F320S3_ID	0xD4
+
+int manuf_code, device_code;
+int sector_size, max_no_of_sectors, word_mode;
+volatile unsigned int *FLASH = (volatile unsigned int *)0x24000000;
+
+int
+identify_FLASH(void )
+{
+    unsigned int *ptr = (unsigned int *)FLASH;
+
+    HAL_FLASH_WRITE_ENABLE();
+
+    // Enter Software Product Identification Mode
+    FLASH[SEQ_ADD1] = START_CMD1;
+    FLASH[SEQ_ADD2] = START_CMD2;
+    FLASH[SEQ_ADD1] = ID_CMD;
+
+    // Wait at least 10ms
+    cyg_thread_delay(4);
+
+    // Read Manufacturer and device code from the device
+    manuf_code   = *ptr++ & 0xff;
+    device_code  = *ptr & 0xff;
+    
+    diag_printf("manuf: 0x%x, device: 0x%x\n", manuf_code, device_code);
+
+    // Exit Software Product Identification Mode
+    FLASH[SEQ_ADD1] = START_CMD1;
+    FLASH[SEQ_ADD2] = START_CMD2;
+    FLASH[SEQ_ADD1] = STOP_CMD;
+
+    // Wait at least 10ms
+    cyg_thread_delay(5);
+
+    HAL_FLASH_WRITE_DISABLE();
+
+    if (manuf_code != MAN_ATMEL || manuf_code != MAN_INTEL) {
+        diag_printf ( "Error: Wrong Manufaturer: %02x\n", manuf_code );
+        return (0);
+    }
+
+    switch (device_code) {
+    case  ATMEL_AT29C040A_ID:
+        diag_printf ("AT29C040A recognised\n");
+        sector_size = ATMEL_SECTOR_SIZE;
+        max_no_of_sectors = ATMEL_MAX_SECTORS;
+        word_mode = FALSE;
+        break;
+
+    case  ATMEL_AT29C1024_ID:
+        diag_printf ("AT29C1024 recognised\n");
+        sector_size = ATMEL_SECTOR_SIZE;
+        max_no_of_sectors = ATMEL_MAX_SECTORS;
+        word_mode = TRUE;
+        break;
+
+    case  INTEL_28F320S3_ID:
+        diag_printf ("INTEL_28F320S3 recognised\n");
+        sector_size = FLASH_BLOCK_SIZE;
+	//        max_no_of_sectors = ATMEL_MAX_SECTORS;
+        word_mode = TRUE;
+        break;
+
+    default :
+        diag_printf ( "Error: Unsupported device: %02x\n", device_code);
+        return (0);
+    }
+    return (1);
+}
+
+void
+write_sector(int num, char *buf)
+{
+    int i, cnt;
+    volatile char *wrt = (volatile char *)&FLASH[num*sector_size];
+
+//    diag_printf("Writing to %08x\n", wrt);
+    // Enter Program Mode
+    FLASH[SEQ_ADD1] = START_CMD1;
+    FLASH[SEQ_ADD2] = START_CMD2;
+    FLASH[SEQ_ADD1] = PROG_CMD;
+
+    // Note: write bytes as longs regardless of bus width
+    for (i = 0;  i < sector_size;  i++) {
+        wrt[i] = BUF(i);
+    }
+
+    // Wait for sector to program
+    cnt = 0;
+    i = sector_size - 1;
+    while (wrt[i] != BUF(i)) {
+        if (cnt++ > 0x01000000) break;
+    }
+//    diag_printf("Out - i: %d, wrt[i] = %08X.%08X, BUF(i) = %08X, count = %x\n", i, &wrt[i], wrt[i], BUF(i), cnt);
+
+    // Verify
+    for (i = 0;  i < sector_size;  i++) {
+        for (cnt = 0;  cnt < 10;  cnt++) {
+            if (wrt[i] == BUF(i)) break;
+            cyg_thread_delay(1);
+        }
+        if (cnt == 10) {
+            diag_printf("Can't program at 0x%08X: %02X not %02X\n", wrt, *wrt, BUF(0));
+        }
+    }
+}
--- a/packages/hal/arm/sa11x0/assabet/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/assabet/current/ChangeLog
@@ -1,4 +1,4 @@
-2001-10-20  Nicolar Pitre <nico@cam.org>
+2001-10-20  Nicolas Pitre <nico@cam.org>
 
 	* include/hal_platform_setup.h:	Wake up from deep sleep mode.
 
--- a/packages/hal/arm/sa11x0/flexanet/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/flexanet/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-10-30  Jordi Colomer <jco@ict.es>
+
+	* include/flexanet.h: minor changes to the GPIO usage.
+	* include/hal_platform_setup.h: solved some problems with the
+	sleep/wakeup procedure.
+
 2001-10-04  Jordi Colomer <jco@ict.es>
 
 	* include/hal_platform_setup.h: Add sleep/resume support.
--- a/packages/hal/arm/sa11x0/flexanet/current/include/flexanet.h
+++ b/packages/hal/arm/sa11x0/flexanet/current/include/flexanet.h
@@ -68,7 +68,7 @@ extern void flexanet_BCR(unsigned long m
 // GPIO settings
 //
 #define SA1110_GPIO_DIR       0x080037FE
-#define SA1110_GPIO_ALT       0x080037FE
+#define SA1110_GPIO_ALT       0x080037FC
 #define SA1110_GPIO_CLR       0x080037FE
 #define SA1110_GPIO_SET       0x00000000
 
@@ -123,7 +123,7 @@ extern void flexanet_BCR(unsigned long m
 #define SA1110_GPIO_GUI_IRQ	        (1<<23)  /* IRQ from GUI board (i.e., UCB1300) */
 #define SA1110_GPIO_ETH_IRQ	        (1<<24)  /* IRQ from Ethernet controller */
 #define SA1110_GPIO_INTIP_IRQ    	(1<<25)  /* Measurement IRQ (INTIP) */
-#define SA1110_GPIO_LED_RED	        (1<<26)  /* General-purpose red LED */
+#define SA1110_GPIO_XMI_IRQ	        (1<<26)  /* External Module Insertion interrupt */
 
 /* IRQ mappings from GPIOs */
 #define SA1110_IRQ_GPIO_CF1_CD		CYGNUM_HAL_INTERRUPT_GPIO14
--- a/packages/hal/arm/sa11x0/flexanet/current/include/hal_platform_setup.h
+++ b/packages/hal/arm/sa11x0/flexanet/current/include/hal_platform_setup.h
@@ -56,6 +56,7 @@
 #if defined(CYG_HAL_STARTUP_ROM)
 #define PLATFORM_SETUP1 _platform_setup1
 #define CYGHWR_HAL_ARM_HAS_MMU
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
 
 #if (CYGHWR_HAL_ARM_SA11X0_PROCESSOR_CLOCK == 59000)
 #define SA11X0_PLL_CLOCK 0x0        
@@ -127,18 +128,54 @@
 #define STATIC_1_CONFIG_VALUE	0x2C290001
 
 
+// Macros that handle the red debug LED wired to GPIO-1
+
+        .macro    _red_led_on
+        
+        // Turn on the red LED on GPIO-1
+        ldr     r3,=SA11X0_GPIO_PIN_OUTPUT_SET
+        ldr     r2,=0x02
+        str     r2,[r3]
+        .endm
+        
+        .macro    _red_led_off
+        
+        // Turn off the red LED on GPIO-1
+        ldr     r3,=SA11X0_GPIO_PIN_OUTPUT_CLEAR
+        ldr     r2,=0x02
+        str     r2,[r3]        
+        .endm
+
 
 // This macro represents the initial startup code for the platform,
 // when the startup is ROM.
 
+// Red LED is turned on during redboot execution and turned off
+// right before entering the operating system.
+
+// Green LED is turned off during the redboot execution and
+// on right before entering the operating system on a reset
+// (not on a wake-up).
+
         .macro  _platform_setup1
         
-        // Reset the BCR (LEDs off)
+        // Disable all interrupts (ICMR not specified on power-up)
+        ldr     r1,=SA11X0_ICMR
+        mov     r0,#0
+        str     r0,[r1]
+        
+        // Disable IRQs and FIQs
+        mov     r0, #(CPSR_IRQ_DISABLE | \
+                      CPSR_FIQ_DISABLE | \
+                      CPSR_SUPERVISOR_MODE)
+        msr     cpsr, r0
+        
+        // Reset the BCR (green LED off)
         ldr     r1,=SA1110_BOARD_CONTROL
         ldr     r2,=SA1110_BCR_MIN
         str     r2,[r1]
 
-        // Set up GPIOs
+        // Set up GPIOs (red LED off)
         ldr     r1,=SA11X0_GPIO_PIN_DIRECTION
         ldr     r2,=SA1110_GPIO_DIR
         str     r2,[r1]
@@ -154,7 +191,10 @@
         ldr     r1,=SA11X0_GPIO_PIN_OUTPUT_SET
         ldr     r2,=SA1110_GPIO_SET
         str     r2,[r1]
-        
+
+        // Turn on the red LED
+        _red_led_on
+
         // Disable clock switching
         mcr     p15,0,r0,\
                 SA11X0_TEST_CLOCK_AND_IDLE_REGISTER,\
@@ -174,19 +214,14 @@
         nop
         nop
 
-        // Turn on the red LED on GPIO-1
-        ldr     r1,=SA11X0_GPIO_PIN_OUTPUT_SET
-        ldr     r2,=(1<<1)
-        str     r2,[r1]        
-
-	// Let the PLL settle down	
+        // Let the PLL settle down	
         ldr     r1,=20000
 10:     sub     r1,r1,#1
         cmp     r1,#0
         bne     10b        
 
         // Initialize DRAM controller. See table below.
-	// The DRAM banks are set to disabled.
+        // The DRAM banks are set to disabled.
 	
         ldr     r1,=dram_table
         ldr     r2,=__exception_handlers
@@ -205,46 +240,42 @@ 11:     ldr     r3,[r1],#4
 
         // Release DRAM hold (PSSR register, bit DH)
 	
-	// This bit is set upon exit from sleep mode and indicates that the 
-	// nRAS/nSDCS 3:0 and nCAS/DQM 3:0 continue to be held low and that 
-	// the DRAMs are still in self-refresh mode. This bit should be cleared 
-	// by the processor (by writing a one to it) after the DRAM interface 
-	// has been configured but before any DRAM access is attempted. 
-	// The nRAS/nSDCS and nCAS/DQM lines are released when this bit is
-	// cleared. This bit is cleared on hardware reset.
-	
+        // This bit is set upon exit from sleep mode and indicates that the 
+        // nRAS/nSDCS 3:0 and nCAS/DQM 3:0 continue to be held low and that 
+        // the DRAMs are still in self-refresh mode. This bit should be cleared 
+        // by the processor (by writing a one to it) after the DRAM interface 
+        // has been configured but before any DRAM access is attempted. 
+        // The nRAS/nSDCS and nCAS/DQM lines are released when this bit is
+        // cleared. This bit is cleared on hardware reset.
+
         ldr     r1,=SA11X0_PWR_MGR_SLEEP_STATUS
         ldr     r2,=SA11X0_DRAM_CONTROL_HOLD
         str     r2,[r1]
 
-	// On hardware reset in systems containing DRAM or SDRAM, 
-	// trigger a number (typically eight) of refresh cycles by attempting 
-	// nonburst read or write accesses to any disabled DRAM bank. 
-	// Each such access causes a simultaneous CBR for all four banks.
+        // On hardware reset in systems containing DRAM or SDRAM, 
+        // trigger a number (typically eight) of refresh cycles by attempting 
+        // nonburst read or write accesses to any disabled DRAM bank. 
+        // Each such access causes a simultaneous CBR for all four banks.
 	
         ldr     r1,=SA11X0_RAM_BANK0_BASE
         ldr     r2,[r1]
-	nop
-	nop
+        ldr     r2,[r1]
         ldr     r2,[r1]
-	nop
-	nop
+        ldr     r2,[r1]
         ldr     r2,[r1]
-	nop
-	nop
+        ldr     r2,[r1]
         ldr     r2,[r1]
-	nop
-	nop
+        ldr     r2,[r1]
 	
         // Enable DRAM bank 0
         ldr     r1,=SA11X0_DRAM_CONFIGURATION
         ldr     r2,=DRAM_CONFIG_VALUE
-	orr	r2, r2, #0x01
+        orr     r2, r2, #0x01
         str     r2,[r1]
 
         b       19f        
 
-	// Memory controller settings (register, value)        
+        // Memory controller settings (register, value)        
 
 dram_table:
 
@@ -260,14 +291,9 @@ dram_table:
         .word   SA11X0_DRAM_CONFIGURATION,    DRAM_CONFIG_VALUE
         .word   SA11X0_STATIC_CONTROL_0,      STATIC_0_CONFIG_VALUE
         .word   SA11X0_STATIC_CONTROL_1,      STATIC_1_CONFIG_VALUE
-	.word   0, 0
+        .word   0, 0
 19:
 
-        // Release peripheral hold (set by RESET)
-        ldr     r1,=SA11X0_PWR_MGR_SLEEP_STATUS
-        ldr     r2,=SA11X0_PERIPHERAL_CONTROL_HOLD
-        str     r2,[r1]
-
         // If waking up from sleep, jump to the resume function
         // pointed by the scratchpad register.
         ldr     r1,=SA11X0_RESET_STATUS
@@ -276,6 +302,9 @@ 19:
         bne     20f
         ldr     r1,=SA11X0_PWR_MGR_SCRATCHPAD
         ldr     r1,[r1]
+
+        _red_led_off
+        
         mov     pc,r1
         nop
 20:     nop        
@@ -307,8 +336,13 @@ 10:
         ldr     r2,=SA1110_BCR_MIN
         orr     r2,r2,#SA1110_BCR_LED_GREEN
         str     r2,[r1]
+        
+        // Turn off red LED
+        _red_led_off
+        
         .endm
-        
+
+                
 #else // defined(CYG_HAL_STARTUP_ROM)
 #define PLATFORM_SETUP1
 #endif
--- a/packages/hal/arm/sa11x0/var/current/ChangeLog
+++ b/packages/hal/arm/sa11x0/var/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-10-31  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/hal_arm_sa11x0.cdl: Indicate support of variable baud rates.
+
 2001-10-09  Hugo Tyson  <hmt@redhat.com>
 
 	* src/hal_diag.c (cyg_hal_plf_serial_isr): As well as the sticky
--- a/packages/hal/arm/sa11x0/var/current/cdl/hal_arm_sa11x0.cdl
+++ b/packages/hal/arm/sa11x0/var/current/cdl/hal_arm_sa11x0.cdl
@@ -52,6 +52,7 @@ cdl_package CYGPKG_HAL_ARM_SA11X0 {
         package."
 
     implements    CYGINT_HAL_ARM_ARCH_STRONGARM
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
 
     # Let the architectural HAL see this variant's interrupts file -
     # the SA11x0 has no variation between targets here.
--- a/packages/hal/i386/pcmb/current/ChangeLog
+++ b/packages/hal/i386/pcmb/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-11-01  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/pcmb_misc.c (hal_pcmb_init): Fix typo:
+	CYGPKG_HAL_I386_PCMB_HAL_MEMSIZE_BIOS -> 
+	CYGPKG_HAL_I386_PCMB_MEMSIZE_BIOS
+
 2001-10-19  Ian Campbell  <icampbell@arcom.co.uk>
 
 	* cdl/hal_i386_pcmb.cdl: Add cdl_options for
--- a/packages/hal/i386/pcmb/current/src/pcmb_misc.c
+++ b/packages/hal/i386/pcmb/current/src/pcmb_misc.c
@@ -75,7 +75,7 @@ void hal_pcmb_init(void)
     cyg_hal_pcmb_memsize_extended = CYGNUM_HAL_I386_PCMB_MEMSIZE_EXTENDED;
 #endif
 
-#ifdef CYGPKG_HAL_I386_PCMB_HAL_MEMSIZE_BIOS
+#ifdef CYGPKG_HAL_I386_PCMB_MEMSIZE_BIOS
     cyg_uint8 lo,hi;
     
     HAL_READ_CMOS( 0x15, lo );
--- a/packages/hal/mips/atlas/current/ChangeLog
+++ b/packages/hal/mips/atlas/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-10-31  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/hal_mips_atlas.cdl: Indicate support of variable baud rates.
+
 2001-07-20  David Woodhouse  <dwmw2@redhat.com>
 
 	* src/redboot_cmds.c: Remove. Obsoleted by generic MIPS version.
--- a/packages/hal/mips/atlas/current/cdl/hal_mips_atlas.cdl
+++ b/packages/hal/mips/atlas/current/cdl/hal_mips_atlas.cdl
@@ -59,6 +59,7 @@ cdl_package CYGPKG_HAL_MIPS_ATLAS {
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
     implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
 
     cdl_option CYGBLD_HAL_TARGET_H {
         display       "Variant header"
--- a/packages/hal/mips/vrc437x/current/ChangeLog
+++ b/packages/hal/mips/vrc437x/current/ChangeLog
@@ -1,3 +1,18 @@
+2001-10-31  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/hal_mips_vr4300_vrc437x.cdl: Indicate support of variable baud
+	rates.
+
+2001-10-30  Nick Garnett  <nickg@redhat.com>
+
+	* include/platform.inc:
+	Added local version of hal_intc_decode to make chaining work
+	correctly.
+	
+	* include/plf_intr.h:
+	Added local version of HAL_TRANSLATE_VECTOR() to make chaining
+	work correctly.
+
 2001-10-24  Nick Garnett  <nickg@redhat.com>
 
 	* include/hal_diag.h: Fixed problem with support for virtual
--- a/packages/hal/mips/vrc437x/current/cdl/hal_mips_vr4300_vrc437x.cdl
+++ b/packages/hal/mips/vrc437x/current/cdl/hal_mips_vr4300_vrc437x.cdl
@@ -54,6 +54,7 @@ cdl_package CYGPKG_HAL_MIPS_VR4300_VRC43
 
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
 
    cdl_option CYGSEM_HAL_MIPS_VR4300_VRC437X_DIAG_ACKS_INT_0 {
        display          "Acknowledge spurious interrupt 0 on output"
--- a/packages/hal/mips/vrc437x/current/include/platform.inc
+++ b/packages/hal/mips/vrc437x/current/include/platform.inc
@@ -239,6 +239,25 @@ 2:
 #define CYGPKG_HAL_MIPS_INTC_INIT_DEFINED
 
 #------------------------------------------------------------------------------
+# Interrupt Translator.
+# This translates an interrupt number into an ISR table offset. Vector 0
+# contains a special ISR for dealing with spurious interrupts from the
+# Vrc437x, and vectors 1-3 contain springboards, so we chain via vector 4.
+# This macro translates interrupt 0 to vector 0 and all others to vector 4.
+
+#ifndef CYGPKG_HAL_MIPS_INTC_TRANSLATE_DEFINED
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+	.macro	hal_intc_translate inum,vnum
+	beqz	\inum,1f	# jump if interrupt is zero
+	 move	v0,zero		# set v0=0 in delay slot
+	addi	v0,v0,4		# non zero vector, inc v0
+1:	move	\vnum,v0	# store 0 or 4 in vnum
+	.endm
+#define CYGPKG_HAL_MIPS_INTC_TRANSLATE_DEFINED
+#endif
+#endif
+
+#------------------------------------------------------------------------------
 # Monitor initialization.
 	
 #ifndef CYGPKG_HAL_MIPS_MON_DEFINED
--- a/packages/hal/mips/vrc437x/current/include/plf_intr.h
+++ b/packages/hal/mips/vrc437x/current/include/plf_intr.h
@@ -117,6 +117,24 @@
 #define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
 
 //--------------------------------------------------------------------------
+// Vector translation.
+// For chained interrupts we only have a single vector though which all
+// are passed. For unchained interrupts we have a vector per interrupt.
+// Vector 0 has a special catcher ISR for spurious interrupts from the VRC437X
+// and vectors 1-3 are springboards, so we chain through vector 4.
+
+#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
+
+#define HAL_TRANSLATE_VECTOR(_vector_,_index_)  \
+{                                               \
+    if ((_vector_)==0)                          \
+        (_index_) = 0;                          \
+    else                                        \
+        (_index_) = 4;                          \
+}   
+#endif
+
+//--------------------------------------------------------------------------
 // controller access code
 
 #define CYGHWR_HAL_MIPS_VRC4372_BASE            0xbc000000
--- a/packages/hal/mn10300/stb/current/ChangeLog
+++ b/packages/hal/mn10300/stb/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-10-31  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/hal_mn10300_am33_stb.cdl: Indicate support of variable baud rates.
+
 2001-09-05  David Howells  <dhowells@redhat.com>
 
 	* src/plf_misc.c: made inclusion here of hal_ctrlc_isr()
--- a/packages/hal/mn10300/stb/current/cdl/hal_mn10300_am33_stb.cdl
+++ b/packages/hal/mn10300/stb/current/cdl/hal_mn10300_am33_stb.cdl
@@ -55,6 +55,7 @@ cdl_package CYGPKG_HAL_MN10300_AM33_STB 
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
     implements    CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+    implements    CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
 
     requires CYGSEM_HAL_UNCACHED_FLASH_ACCESS == 1;
 
@@ -112,6 +113,7 @@ cdl_package CYGPKG_HAL_MN10300_AM33_STB 
        flavor data
        legal_values     9600 19200 38400 115200
        default_value    38400
+       define           CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
        description      "
            This option selects the baud rate used for the diagnostic port.
            Note: this should match the value chosen for the GDB port if the
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,21 @@
+2001-10-30  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* doc/driver_doc: Add description of poll, deliver and int_vector
+	driver functions.
+
+2001-10-29  Hugo Tyson  <hmt@redhat.com>
+
+	* src/net/eth_drv.c (eth_drv_tickle_devices): [CASE 106613] Rather
+	than calling can_send() in the device driver directly, call our
+	own eth_drv_send() function which will also dequeue a waiting
+	packet if we find we indeed can_send().  This helps to recover
+	from queue full situations within the if_ethersubr layer above.
+	This change is belt & braces with a similar call in the code which
+	drops a packet if the queue is full, in the main network code in
+	net/tcpip/.../src/sys/net/if_ethersubr.c (ether_output); this
+	change will recover the situation shortly even if the application
+	gives up trying to send because of ENOBUFS.
+
 2001-10-18  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/eth_drivers.cdl: Rename CYGSEM_IO_ETH_DRIVERS_DEBUG to
--- a/packages/io/eth/current/doc/driver_doc
+++ b/packages/io/eth/current/doc/driver_doc
@@ -11,7 +11,7 @@ supported TCP/IP stack, or any other, wi
 
 A driver instance is contained within a "struct eth_drv_sc".
 
-   struct eth_drv_funs {
+   struct eth_hwr_funs {
       // Initialize hardware (including startup)
       void (*start)(struct eth_drv_sc *sc,
                     unsigned char *enaddr);
@@ -34,10 +34,19 @@ A driver instance is contained within a 
       void (*recv)(struct eth_drv_sc *sc,
                    struct eth_drv_sg *sg_list,
                    int sg_len);
+      // Deliver data to/from device from/to stack memory space
+      // (moves lots of memcpy()s out of DSRs into thread)
+      void (*deliver)(struct eth_drv_sc *sc);
+      // Poll for interrupts/device service
+      void (*poll)(struct eth_drv_sc *sc);
+      // Get interrupt information from hardware driver
+      int (*int_vector)(struct eth_drv_sc *sc);
+      // Logical driver interface
+      struct eth_drv_funs *eth_drv, *eth_drv_old;
   };
 
   struct eth_drv_sc {
-      struct eth_drv_funs *funs;
+      struct eth_hwr_funs *funs;
       void                *driver_private;
       const char          *dev_name;
       struct arpcom       sc_arpcom; /* ethernet common */
@@ -216,6 +225,35 @@ interface.  The 'eth_drv_recv()' functio
 and structures for the data and then calls "HRDWR_recv()" to actually
 move the data from the interface.
 
+static void
+HRDWR_deliver(struct eth_drv_sc *sc)
+=========================================================================
+
+This function is actually a call back, and notifies the driver that delivery
+is happening. This allows it to actually do the copy of packet data to/from
+the hardware from/to the packet buffer. And once that's done, then do things
+like unmask its interrupts, and free any relevant resources so it can process
+further packets.
+
+In general it will be called from the user thread responsible for delivering
+network packets.
+
+static void
+HRDWR_poll(struct eth_drv_sc *sc)
+=========================================================================
+
+This function is used when in a non-interrupt driven system, e.g. when
+interrupts are completely disabled. This allows the driver time to check
+whether anything needs doing either for transmission, or to check if
+anything has been received, or if any other processing needs doing..
+
+static int
+HRDWR_int_vector(struct eth_drv_sc *sc)
+=========================================================================
+
+This function returns the interrupt vector number used for RX interrupts.
+This is so the common GDB stubs infrastructure can detect when to check
+for incoming ctrl-c's when doing debugging over ethernet.
 
 Upper layer functions - called by drivers
 =========================================
--- a/packages/io/eth/current/src/net/eth_drv.c
+++ b/packages/io/eth/current/src/net/eth_drv.c
@@ -851,8 +851,15 @@ void eth_drv_tickle_devices( void )
     cyg_netdevtab_entry_t *t;
     for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
         struct eth_drv_sc *sc = (struct eth_drv_sc *)t->device_instance;
-        if ( ETH_DRV_STATE_ACTIVE & sc->state )
-            (*sc->funs->can_send)(sc);
+        if ( ETH_DRV_STATE_ACTIVE & sc->state ) {
+            struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+            // Try to dequeue a packet for this interface, if we can.  This
+            // will call can_send() for active interfaces.  It is calls to
+            // this function from tx_done() which normally provide
+            // continuous transmissions; otherwise we do not get control.
+            // This call fixes that.
+            eth_drv_send(ifp);
+        }
     }
 }
 #endif // CYGPKG_NET_FAST_THREAD_TICKLE_DEVS
--- a/packages/io/flash/current/ChangeLog
+++ b/packages/io/flash/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-10-28  Gary Thomas  <gthomas@redhat.com>
+
+	* src/flash.c (flash_erase): Don't call hardware layer if block
+	appears to be already erased [faster and less wear & tear].
+
 2001-10-25  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* include/flash_dev.h: Fix test of 4x16-bit flash parts.
--- a/packages/io/flash/current/src/flash.c
+++ b/packages/io/flash/current/src/flash.c
@@ -202,8 +202,21 @@ flash_erase(void *addr, int len, void **
     FLASH_Enable(block, end_addr);
     while (block < end_addr) {
         // Supply the blocksize for a gross check for erase success
-        stat = (*_flash_erase_block)(block, flash_info.block_size);
-        stat = flash_hwr_map_error(stat);
+        int i;
+        unsigned char *dp;
+        bool erased = true;
+
+        dp = (unsigned char *)block;
+        for (i = 0;  i < flash_info.block_size;  i++) {
+            if (*dp++ != (unsigned char)0xFF) {
+                erased = false;
+                break;
+            }
+        }
+        if (!erased) {
+            stat = (*_flash_erase_block)(block, flash_info.block_size);
+            stat = flash_hwr_map_error(stat);
+        }
         if (stat) {
             *err_addr = (void *)block;
             break;
@@ -275,7 +288,7 @@ flash_program(void *_addr, void *_data, 
         stat = flash_hwr_map_error(stat);
 #ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM
         if (0 == stat) // Claims to be OK
-            if (memcmp(addr, data, size) != 0) {
+            if (memcmp(addr, data, size) != 0) {                
                 stat = 0x0BAD;
                 (*flash_info.pf)("V");
             }
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,12 @@
+2001-10-30  Nick Garnett  <nickg@redhat.com>
+
+	* tests/kcache2.c (test_dsync):
+	Added call to HAL_ICACHE_INVALIDATE_ALL() just before DCACHE
+	disable. In platforms where both caches are controlled together,
+	such as the VR4300, not doing this can result in strange behaviour
+	as the ICACHE gets turned off under the program's feet, when it is
+	not ready for it.
+
 2001-10-17  Jesper Skov  <jskov@redhat.com>
 
 	* tests/dhrystone.c: CYGINT_ISO_STRING_STRFUNCS check changed to
@@ -6,7 +15,7 @@ 2001-10-17  Jesper Skov  <jskov@redhat.c
 2001-10-12  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* cdl/synch.cdl (CYGIMP_KERNEL_SYNCH_MQUEUE_NOT_INLINE): New option
-	to avoid inliningn mqueue implementation.
+	to avoid inlining mqueue implementation.
 
 	* src/sync/mqueue.cxx: New file to provide non-inline version of
 	mqueue functions.
--- a/packages/kernel/current/tests/kcache2.c
+++ b/packages/kernel/current/tests/kcache2.c
@@ -330,6 +330,7 @@ static void test_dsync(void)
     CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE], 
                    "memory didn't contain flushed data next block after invalidate");
 
+    HAL_ICACHE_INVALIDATE_ALL();    
     HAL_DCACHE_DISABLE();
 
     CYG_TEST_CHECK(42 == aligned_p[0],
--- a/packages/net/tcpip/current/ChangeLog
+++ b/packages/net/tcpip/current/ChangeLog
@@ -1,3 +1,24 @@
+2001-11-02  Gary Thomas  <gthomas@redhat.com>
+
+	* src/ecos/support.c: 
+	* include/machine/ansi.h: Add C++ support [externC].
+
+2001-11-11  Andrew Lunn <andrew.lunn@ascom.ch>
+
+	*src/lib/recv.c: Implement the recv() call.
+
+2001-10-29  Hugo Tyson  <hmt@redhat.com>
+
+	* src/sys/net/if_ethersubr.c (ether_output): [CASE 106613] Even if
+	the queue is full, and we are dropping the packet, try to start
+	the interface anyway, to give it a chance to empty the queue if
+	the device has recovered from whatever made the queue fill up in
+	the first place - being unplugged from the network for example.
+	This change is belt & braces with a similar policy in the periodic
+	tickle function in the logical ether driver in io/eth/... ; this
+	change will recover the situation immediately if the application
+	continues trying to send despite ENOBUFS.
+
 2001-10-25  Hugo Tyson  <hmt@redhat.com>
 
 	* src/sys/net/if_bridge.c (bridge_broadcast): Count if_obytes in
--- a/packages/net/tcpip/current/cdl/net.cdl
+++ b/packages/net/tcpip/current/cdl/net.cdl
@@ -132,6 +132,7 @@ cdl_package CYGPKG_NET {
         lib/shutdown.c \
         lib/sendto.c \
         lib/recvfrom.c \
+        lib/recv.c \
         lib/getsockname.c \
         lib/getpeername.c \
         lib/getsockopt.c \
--- a/packages/net/tcpip/current/include/machine/ansi.h
+++ b/packages/net/tcpip/current/include/machine/ansi.h
@@ -58,8 +58,8 @@
 // Mappings of BSD-style functions used in networking code to those provided
 // by the eCos environment.
 
-void net_memcpy(void *d, void *s, int n);
-void net_memset(void *s, int v, int n);
+externC void net_memcpy(void *d, void *s, int n);
+externC void net_memset(void *s, int v, int n);
 
 #define bcopy(s,d,n) net_memcpy(d,s,n)
 #define bzero(s,n)   net_memset(s,0,n)
--- a/packages/net/tcpip/current/src/ecos/support.c
+++ b/packages/net/tcpip/current/src/ecos/support.c
@@ -364,7 +364,7 @@ cyg_cltom(u_long x)
     return res;
 }
 
-void 
+externC void 
 net_memcpy(void *d, void *s, int n)
 {
     START_STATS();
@@ -372,7 +372,7 @@ net_memcpy(void *d, void *s, int n)
     FINISH_STATS(stats_memcpy);
 }
 
-void 
+externC void 
 net_memset(void *s, int v, int n)
 {
     START_STATS();
new file mode 100644
--- /dev/null
+++ b/packages/net/tcpip/current/src/lib/recv.c
@@ -0,0 +1,67 @@
+//==========================================================================
+//
+//      lib/recv.c
+//
+//      recv() system call
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources,
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas,andrew.lunn@ascom.ch
+// Contributors: gthomas
+// Date:         2001-11-01
+// Purpose:      
+// Description:  
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <sys/param.h>
+#include <cyg/io/file.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+
+ssize_t	
+recv(int s, const void *buf, size_t buflen, 
+       int flags)
+{
+    
+    return(recvfrom(s,buf,buflen,NULL,0));
+}
--- a/packages/net/tcpip/current/src/sys/net/if_ethersubr.c
+++ b/packages/net/tcpip/current/src/sys/net/if_ethersubr.c
@@ -591,6 +591,11 @@ ether_output(ifp, m0, dst, rt0)
 	 * not yet active.
 	 */
 	if (IF_QFULL(&ifp->if_snd)) {
+                // Let the interface try a dequeue anyway, in case the
+                // interface has "got better" from whatever made the queue
+                // fill up - being unplugged for example.
+                if ((ifp->if_flags & IFF_OACTIVE) == 0)
+                    (*ifp->if_start)(ifp);
 		IF_DROP(&ifp->if_snd);
 		splx(s);
 		senderr(ENOBUFS);
--- a/packages/pkgconf/fixhtml.tcl
+++ b/packages/pkgconf/fixhtml.tcl
@@ -115,6 +115,10 @@ foreach file $files {
 	    regsub -all "&equals;" $data "\\&#0061;" data
             regsub -all "&num;"    $data "\\&#0035;" data
             regsub -all "&plus;"   $data "\\&#0043;" data
+            regsub -all "&percnt;" $data "\\&#0037;" data
+            regsub -all "&dollar;" $data "\\&#0036;" data
+            regsub -all "&boxv;"   $data "\\&#9474;" data
+            regsub -all "&bsol;"   $data "\\&#0092;" data
 
 	    # Now write the data back to the file. Do not bother to
 	    # keep an old version lying around, the html files can be
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,66 @@
+2001-11-01  Jesper Skov  <jskov@redhat.com>
+
+	* src/flash.c (fis_init): tweaks to the SIB protection code.
+
+2001-11-01  Gary Thomas  <gthomas@redhat.com>
+
+	* src/flash.c (fis_init): Need to init block fully, otherwise old
+	images can persist after init.
+
+2001-10-31  Jesper Skov  <jskov@redhat.com>
+
+	* include/sib.h: Contains information about ARM Boot Monitor flash
+	block information.
+
+	* cdl/redboot.cdl: Added CYGOPT_REDBOOT_FIS_DIRECTORY_ARM_SIB_ID
+	option.
+
+	* src/flash.c (fis_init): Added code to add ARM Boot Monitor
+	footer on FIS block.
+	
+2001-10-30  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/flash.c (fis_delete): Prototype arm_fis_delete in correct place.
+	(fis_list): Fix compilation problem - this isn't C++!
+
+2001-10-30  Philippe Robin <Philippe.Robin@arm.com>
+2001-10-30  Jonathan Larmour  <jlarmour@redhat.com>
+	
+	* cdl/redboot.cdl: Add CYGINT_REDBOOT_ARM_FLASH_SIB_SUPPORTED and
+	CYGHWR_REDBOOT_ARM_FLASH_SIB to indicate support for, and a request
+	to provide ARM flash block structure support.
+
+	* src/flash.c (fis_list): Call out to driver for ARM block FIS listing.
+	(fis_delete): Call out to driver for ARM block FIS deletion.
+
+2001-10-29  Gary Thomas  <gthomas@redhat.com>
+
+	* src/main.c (cyg_start): New pseudo-commands, useful for scripts.
+	'# anything' - treated like a comment.
+	'= anything' - comment, but prints command line on console.
+
+	* src/flash.c (expand_aliases): Don't expand aliases which are
+	quoted, but only on the command line.  This allows aliases to
+	expand into other aliases which are within quoted strings.
+
+	* include/redboot.h: 
+	* src/io.c (_rb_gets_preloaded): New function which allows for a
+	buffer to be displayed and edited in place.  This is extremely
+	useful for 'fconfig', now that better line editing functions are
+	supported.
+
+	* src/flash.c (get_config): Using new function _rb_gets_preloaded(),
+	which supports edit-in-place for data items.
+
+2001-10-28  Gary Thomas  <gthomas@redhat.com>
+
+	* src/main.c (cyg_start): 
+	* src/io.c (_rb_gets): 
+	* include/redboot.h: Add new global control 'cmd_history' which is
+	used to enable/disable command history collection.  This keeps the
+	history from being cluttered with things like 'y' (answers to simple
+	questions).
+
 2001-10-26  Gary Thomas  <gthomas@redhat.com>
 
 	* src/io.c (_rb_gets): Fix ^A editing - was timing out, thus erasing
--- a/packages/redboot/current/cdl/redboot.cdl
+++ b/packages/redboot/current/cdl/redboot.cdl
@@ -33,7 +33,7 @@
 #
 # Author(s):      gthomas
 # Original data:  gthomas
-# Contributors:
+# Contributors:   Philippe Robin
 # Date:           2000-05-01
 #
 #####DESCRIPTIONEND####
@@ -406,6 +406,16 @@ cdl_package CYGPKG_REDBOOT {
                     under this name for use in updating the ROM-based
                     RedBoot that boots the board."
             }
+
+            cdl_option CYGOPT_REDBOOT_FIS_DIRECTORY_ARM_SIB_ID {
+                display         "Include ARM SIB ID in FIS"
+                default_value   0
+                description "
+                  If set, this option will cause the last 5 words of
+                  the FIS to include the special ID needed for the
+                  flash to be recognized as a reserved area for RedBoot
+                  by an ARM BootRom monitor."
+            }
         }
 
         cdl_component CYGSEM_REDBOOT_FLASH_CONFIG {
@@ -485,6 +495,24 @@ cdl_package CYGPKG_REDBOOT {
               When this option is enabled, RedBoot will use CRC checksums
               when reading and writing flash images."
         }
+
+        cdl_interface CYGINT_REDBOOT_ARM_FLASH_SIB_SUPPORTED {
+            display       "ARM FLASH drivers support SIB flash block structure"
+            active_if     CYGPKG_HAL_ARM
+            description   "This interface is implemented by a flash driver
+                           to indicate that it supports the ARM SIB flash
+                           block structure"
+        }
+
+        cdl_option CYGHWR_REDBOOT_ARM_FLASH_SIB {
+            display       "Use ARM SIB flash block structure"
+            flavor        bool
+            active_if     CYGINT_REDBOOT_ARM_FLASH_SIB_SUPPORTED
+            default_value 1
+            description "
+              This option is used to interpret ARM Flash System information
+              blocks."
+        }
     }
 
     cdl_component CYGPKG_REDBOOT_DISK {
--- a/packages/redboot/current/include/redboot.h
+++ b/packages/redboot/current/include/redboot.h
@@ -82,6 +82,9 @@ EXTERN bool console_selected;
 #endif
 EXTERN bool console_echo;
 EXTERN bool gdb_active;
+#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
+EXTERN bool cmd_history;
+#endif
 
 #ifdef CYGPKG_REDBOOT_NETWORKING
 EXTERN bool have_net, use_bootp;
@@ -111,6 +114,9 @@ externC bool verify_action(char *fmt, ..
 
 // Read a single line of input from the console, possibly with timeout
 externC int  _rb_gets(char *line, int len, int timeout);
+// Just like _rb_gets(), except that the line buffer is assumed to contain
+// valid input data.  This provides an easy mechanism for edit-in-place.
+externC int  _rb_gets_preloaded(char *line, int len, int timeout);
 // Result codes from 'gets()'
 #define _GETS_TIMEOUT -1
 #define _GETS_CTRLC   -2
new file mode 100644
--- /dev/null
+++ b/packages/redboot/current/include/sib.h
@@ -0,0 +1,134 @@
+#ifndef _SIB_H_
+#define _SIB_H_
+//==========================================================================
+//
+//      sib.h
+//
+//      RedBoot - structure of ARM flash file format
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Philippe Robin
+// Contributors: Philippe Robin, jskov
+// Date:         2001-10-31
+// Purpose:      
+// Description:  
+//              
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+
+/*     type information :-
+ * 0xffff ffff     -        deleted (usual flash erased value)
+ * 0x0000 xxxx     -        Reserved for ARM usage:
+ * Bit 0           -        ARM Executable Image
+ * Bit 1           -        System Information Block
+ * Bit 2           -        File System Block
+ * 0xyyyy 0000     -        Available for customers (y != 0)
+ */
+#define TYPE_DELETED        0xFFFFFFFF
+#define TYPE_ARM_MASK       0x0000FFFF
+#define TYPE_CUSTOM_MASK    0xFFFF0000
+#define TYPE_ARM_EXEC       0x00000001
+#define TYPE_ARM_SIB        0x00000002
+#define TYPE_ARM_SYSBLOCK   0x00000004
+
+/* This is the type we use for RedBoot blocks */
+#define TYPE_REDHAT_REDBOOT 0x52420000
+
+/* The ARM monitor may be using a different memory mapping than RedBoot */
+#ifndef _ADDR_REDBOOT_TO_ARM
+# define _ADDR_REDBOOT_TO_ARM(x)
+#endif
+
+/* Filetypes */
+
+#define  UNKNOWN_FILE      0x00000000
+#define  MOT_S_RECORD      0x00000001
+#define  INTEL_HEX         0x00000002
+#define  ELF               0x00000004
+#define  DWARF             0x00000008
+#define  ARM_AOF           0x00000010
+#define  ARM_AIF           0x00000020
+#define  PLAIN_BINARY      0x00000040
+#define  ARM_AIF_BIN       0x00000080
+#define  MCS_TYPE          0x00000100
+
+#define  CONVERT_TYPE      (MOT_S_RECORD | INTEL_HEX | MCS_TYPE | ELF)
+
+#define SIB_OWNER_STRING_SIZE   32
+#define MAX_SIB_SIZE            512
+#define MAX_SIB_INDEX		64
+
+#define SIB_HEADER_SIGNATURE    0xA00FFF9F /* This is an invalid instruction - MULGE pc,pc,pc */
+#define FLASH_FOOTER_SIGNATURE  0xA0FFFF9F /* This is an invalid instruction - SMULALGES pc,pc,pc */
+
+
+typedef struct SIBType {
+    cyg_uint32  signature;
+    cyg_uint32  size;
+    char        owner[SIB_OWNER_STRING_SIZE];
+    cyg_uint32  index;
+    cyg_uint32  revision;
+    cyg_uint32  checksum;
+} tSIB; 
+
+typedef struct SIBInfoType {
+    cyg_uint32 SIB_number;      /* Unique number of SIB Block            */
+    cyg_uint32 SIB_Extension;   /* Base of SIB Flash Block               */
+    char Label[16];             /* String space for ownership string     */
+    cyg_uint32 checksum;        /* SIB Image checksum                    */
+} tSIBInfo;
+
+typedef struct FooterType {
+    void        *infoBase;      /* Address of first word of ImageFooter  */
+    char        *blockBase;     /* Start of area reserved by this footer */
+    cyg_uint32  signature;      /* 'Magic' number proves it's a footer   */
+    cyg_uint32  type;           /* Area type: ARM Image, SIB, customer   */
+    cyg_uint32  checksum;       /* Just this structure                   */
+} tFooter ;
+
+typedef struct ImageInfoType {
+    cyg_uint32 bootFlags;       /* Boot flags, compression etc.          */
+    cyg_uint32 imageNumber;     /* Unique number, selects for boot etc.  */
+    char *loadAddress;          /* Address program should be loaded to   */
+    cyg_uint32 length;          /* Actual size of image                  */
+    char *address;                /* Image is executed from here           */
+    char name[16];              /* Null terminated                       */
+    char *headerBase;           /* Flash Address of any stripped header  */
+    cyg_uint32 header_length;   /* Length of header in memory            */
+    cyg_uint32 headerType;      /* AIF, RLF, s-record etc.               */
+    cyg_uint32 checksum;        /* Image checksum (inc. this struct)     */
+} tImageInfo;
+
+
+#endif // _SIB_H_
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -46,6 +46,7 @@
 #include <redboot.h>
 #include <cyg/io/flash.h>
 #include <fis.h>
+#include <sib.h>
 
 // CLI function
 static cmd_fun do_fis;
@@ -216,6 +217,7 @@ fis_init(int argc, char *argv[])
 
     // Create a pseudo image for RedBoot
     img = (struct fis_image_desc *)fis_work_block;
+    memset(img, 0xFF, block_size);  // Start with erased data
 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
     memset(img, 0, sizeof(*img));
     strcpy(img->name, "(reserved)");
@@ -274,6 +276,42 @@ fis_init(int argc, char *argv[])
     img->size = block_size;
     img++;
 
+#ifdef CYGOPT_REDBOOT_FIS_DIRECTORY_ARM_SIB_ID
+    // FIS gets the size of a full block - note, this should be changed
+    // if support is added for multi-block FIS structures.
+    img = (struct fis_image_desc *)((CYG_ADDRESS)fis_work_block + block_size);
+    // Add a footer so the FIS will be recognized by the ARM Boot
+    // Monitor as a reserved area.
+    {
+        tFooter* footer_p = (tFooter*)((CYG_ADDRESS)img - sizeof(tFooter));
+        cyg_uint32 check = 0;
+        cyg_uint32 *check_ptr = (cyg_uint32 *)footer_p;
+        cyg_int32 count = (sizeof(tFooter) - 4) >> 2;
+
+        // Prepare footer. Try to protect all but the reserved space
+        // and the first RedBoot image (which is expected to be
+        // bootable), but fall back to just protecting the FIS if it's
+        // not at the default position in the flash.
+#if defined(CYGOPT_REDBOOT_FIS_RESERVED_BASE) && (-1 == CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK)
+        footer_p->blockBase = (char*)_ADDR_REDBOOT_TO_ARM(flash_start);
+        footer_p->blockBase += CYGNUM_REDBOOT_FLASH_RESERVED_BASE + redboot_image_size;
+#else
+        footer_p->blockBase = _ADDR_REDBOOT_TO_ARM(fis_work_block);
+#endif
+        footer_p->infoBase = NULL;
+        footer_p->signature = FLASH_FOOTER_SIGNATURE;
+        footer_p->type = TYPE_REDHAT_REDBOOT;
+
+        // and compute its checksum
+        for ( ; count > 0; count--) {
+            if (*check_ptr > ~check)
+                check++;
+            check += *check_ptr++;
+        }
+        footer_p->checksum = ~check;
+    }
+#endif
+
     // Do this after creating the initialized table because that inherently
     // calculates where the high water mark of default RedBoot images is.
 
@@ -371,6 +409,13 @@ fis_list(int argc, char *argv[])
     bool show_datalen = false;
     struct option_info opts[2];
 
+#ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB
+    // FIXME: this is somewhat half-baked
+    extern void arm_fis_list(void);
+    arm_fis_list();
+    return;
+#endif
+
     init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, 
               (void **)&show_datalen, (bool *)0, "display data length");
 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
@@ -688,6 +733,7 @@ fis_create(int argc, char *argv[])
     }
 }
 
+extern void arm_fis_delete(char *);
 static void
 fis_delete(int argc, char *argv[])
 {
@@ -702,6 +748,11 @@ fis_delete(int argc, char *argv[])
         fis_usage("invalid arguments");
         return;
     }
+#ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB
+    // FIXME: this is somewhat half-baked
+    arm_fis_delete(name);
+    return;
+#endif
     slot_found = false;
     img = (struct fis_image_desc *)fis_work_block;
     num_reserved = 0;
@@ -1238,7 +1289,7 @@ static void config_init(void);
 static int
 get_config(unsigned char *dp, char *title, int list_opt, char *newvalue )
 {
-    char line[256], *sp, *lp;
+    char line[256], hold_line[256], *sp, *lp;
     int ret;
     bool hold_bool_val, new_bool_val, enable;
     unsigned long hold_int_val, new_int_val;
@@ -1258,6 +1309,7 @@ get_config(unsigned char *dp, char *titl
             return CONFIG_OK;  // Disabled field
         }
     }
+    lp = line;  *lp = '\0';
     val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);
     if (LIST_OPT_NICKNAMES & list_opt)
         diag_printf("%s: ", CONFIG_OBJECT_KEY(dp));
@@ -1271,26 +1323,25 @@ get_config(unsigned char *dp, char *titl
     switch (type = CONFIG_OBJECT_TYPE(dp)) {
     case CONFIG_BOOL:
         memcpy(&hold_bool_val, val_ptr, sizeof(bool));
-        diag_printf("%s ", hold_bool_val ? "true" : "false");
+        lp += diag_sprintf(lp, "%s", hold_bool_val ? "true" : "false");
         break;
     case CONFIG_INT:
         memcpy(&hold_int_val, val_ptr, sizeof(unsigned long));
-        diag_printf("%ld ", hold_int_val);
+        lp += diag_sprintf(lp, "%ld", hold_int_val);
         break;
 #ifdef CYGPKG_REDBOOT_NETWORKING
     case CONFIG_IP:
-        diag_printf("%s ", inet_ntoa((in_addr_t *)val_ptr));
+        lp += diag_sprintf(lp, "%s", inet_ntoa((in_addr_t *)val_ptr));
         break;
     case CONFIG_ESA:
         for (esa_ptr = 0;  esa_ptr < sizeof(enet_addr_t);  esa_ptr++) {
-            diag_printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]);
-            if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":");
+            lp += diag_sprintf(lp, "0x%02X", ((unsigned char *)val_ptr)[esa_ptr]);
+            if (esa_ptr < (sizeof(enet_addr_t)-1)) lp += diag_sprintf(lp, ":");
         }
-        diag_printf(" ");
         break;
 #endif
     case CONFIG_STRING:
-        diag_printf("%s ", (unsigned char *)val_ptr);
+        lp += diag_sprintf(lp, "%s", (unsigned char *)val_ptr);
         break;
     case CONFIG_SCRIPT:
         diag_printf("\n");
@@ -1305,7 +1356,7 @@ get_config(unsigned char *dp, char *titl
         break;
     }
     if (LIST_OPT_LIST_ONLY & list_opt) {
-        diag_printf("\n");
+        diag_printf("%s\n", line);
         return CONFIG_OK;
     }
     if (type != CONFIG_SCRIPT) {
@@ -1314,14 +1365,18 @@ get_config(unsigned char *dp, char *titl
             if (ret > sizeof(line))
                 return CONFIG_BAD;
             strcpy(line, newvalue);
+            strcpy(hold_line, newvalue);
             diag_printf("Setting to %s\n", newvalue);
+        } else {
+            // read from terminal
+            strcpy(hold_line, line);
+            ret = _rb_gets_preloaded(line, sizeof(line), 0);
         }
-        else // read from terminal
-            ret = _rb_gets(line, sizeof(line), 0);
         if (ret < 0) return CONFIG_ABORT;
-        if (strlen(line) == 0) return CONFIG_OK;  // Just a CR - leave value untouched
-        if (line[0] == '.') return CONFIG_DONE;
-        if (line[0] == '^') return CONFIG_BACK;
+        if (strcmp(line, hold_line) == 0) return CONFIG_OK;  // Just a CR - leave value untouched
+        lp = &line[strlen(line)-1];
+        if (*lp == '.') return CONFIG_DONE;
+        if (*lp == '^') return CONFIG_BACK;
     }
     switch (type) {
     case CONFIG_BOOL:
@@ -1661,8 +1716,11 @@ lookup_alias(char *alias, char *alias_bu
 // Expand aliases, this is recursive. ie if one alias contains other
 // aliases, these will also be expanded from the insertion point
 // onwards.
+//
+// If 'iter' is zero, then quoted strings are not expanded
+//
 bool
-_expand_aliases(char *line, int len)
+_expand_aliases(char *line, int len, int iter)
 {
     char *lp = line;
     char *ms, *me, *ep;
@@ -1727,7 +1785,7 @@ bool
                     diag_printf("Alias '%s' not defined\n", ms);
                     *me = '|';
                 }
-            } else if (c == '"') {
+            } else if ((c == '"') && (iter == 0)) {
                 // Skip quoted strings
                 while (*lp && (*lp != '"')) lp++;
             }            
@@ -1739,7 +1797,10 @@ bool
 void
 expand_aliases(char *line, int len)
 {
-    while (_expand_aliases(line, len)) ;
+    int iter = 0;
+
+    while (_expand_aliases(line, len, iter++)) {
+    }
 }
 #endif //  CYGSEM_REDBOOT_FLASH_ALIASES
 
--- a/packages/redboot/current/src/io.c
+++ b/packages/redboot/current/src/io.c
@@ -277,13 +277,13 @@ getc_script(char *cp)
 //
 // Read a line of input from the user
 // Return:
-//    n: 'n' valid characters received
-//    0: '$' (GDB lead-in)
-//   -1: No input before timeout
-//   -2: ^C typed
+//        _GETS_OK: 'n' valid characters received
+//       _GETS_GDB: '$' (GDB lead-in)
+//   _GETS_TIMEOUT: No input before timeout
+//     _GETS_CTRLC: ^C typed
 //
 int
-_rb_gets(char *buf, int buflen, int timeout)
+_rb_gets_preloaded(char *buf, int buflen, int timeout)
 {
     char *ip = buf;   // Insertion point
     char *eol = buf;  // End of line
@@ -308,6 +308,12 @@ int
     char *xp;
 #endif
 
+    // Display current buffer data
+    while (*eol) {
+        mon_write_char(*eol++);
+    }
+    ip = eol;
+
     while (true) {
 #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
         if (getc_script(&c))
@@ -423,14 +429,27 @@ int
                 eol = ip;
             }
             break;
+        case CTRL('D'):
+            // Erase the character under the cursor
+            if (ip != eol) {
+                xp = ip;
+                eol--;
+                while (xp != eol) {
+                    *xp = *(xp+1);
+                    mon_write_char(*xp++);
+                }
+                mon_write_char(' ');  // Erases last character
+                mon_write_char('\b');
+                while (xp-- != ip) {
+                    mon_write_char('\b');
+                }
+            }
+            break;
 #endif // CYGNUM_REDBOOT_CMD_LINE_EDITING
         case CTRL('C'): // ^C
-            if (ip == buf) {
-                diag_printf("^C\n");
-                return _GETS_CTRLC;
-            }
-            *ip++ = c;
-            break;
+            // Abort current input
+            diag_printf("^C\n");
+            return _GETS_CTRLC;
         case '\n':
         case '\r':
             // If previous character was the "other" end-of-line, ignore this one
@@ -446,10 +465,12 @@ int
 	    }
             last_ch = c;
 #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
-            // Save current line
-            if (++_cl_index == _CL_NUM_LINES) _cl_index = 0;
-            if (_cl_index > _cl_max_index) _cl_max_index = _cl_index;
-            strcpy(_cl_lines[_cl_index], buf);
+            if (cmd_history) {
+                // Save current line - only when enabled
+                if (++_cl_index == _CL_NUM_LINES) _cl_index = 0;
+                if (_cl_index > _cl_max_index) _cl_max_index = _cl_index;
+                strcpy(_cl_lines[_cl_index], buf);
+            }
 #endif
             return _GETS_OK;
         case '\b':
@@ -554,6 +575,13 @@ int
     }
 }
 
+int
+_rb_gets(char *buf, int buflen, int timeout)
+{
+    *buf = '\0';  // Empty buffer
+    return _rb_gets_preloaded(buf, buflen, timeout);
+}
+
 bool
 verify_action(char *fmt, ...)
 {
--- a/packages/redboot/current/src/main.c
+++ b/packages/redboot/current/src/main.c
@@ -285,7 +285,13 @@ cyg_start(void)
             diag_printf("RedBoot> ");
             prompt = false;
         }
+#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
+        cmd_history = true;  // Enable history collection
+#endif
         res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
+#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
+        cmd_history = false;  // Enable history collection
+#endif
         if (res == _GETS_TIMEOUT) {
             // No input arrived
         } else {
@@ -318,11 +324,19 @@ cyg_start(void)
                 expand_aliases(line, sizeof(line));
 #endif
 		command = (char *)&line;
-                while (strlen(command) > 0) {                    
-                    if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
-                        (cmd->fun)(argc, argv);
-                    } else {
-                        diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
+                if ((*command == '#') || (*command == '=')) {
+                    // Special cases
+                    if (*command == '=') {
+                        // Print line on console
+                        diag_printf("%s\n", &line[2]);
+                    }
+                } else {
+                    while (strlen(command) > 0) {                    
+                        if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
+                            (cmd->fun)(argc, argv);
+                        } else {
+                            diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
+                        }
                     }
                 }
                 prompt = true;