Index: c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,93 @@
+##
+## $Id$
+##
+
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+include $(top_srcdir)/../../../../automake/compile.am
+include $(top_srcdir)/../../bsp.am
+
+dist_project_lib_DATA = bsp_specs
+
+include_HEADERS = include/bsp.h
+include_HEADERS += include/tm27.h
+
+libcpudir = ../../../libcpu/@RTEMS_CPU@
+
+nodist_include_HEADERS = include/bspopts.h
+DISTCLEANFILES = include/bspopts.h
+
+noinst_PROGRAMS =
+
+include_bspdir = $(includedir)/bsp
+
+include_HEADERS += include/coverhd.h
+include_bsp_HEADERS = include/tqm.h include/8xx_immap.h \
+    include/irq.h include/irq-config.h \
+    ../../shared/include/irq-generic.h\
+    $(libcpudir)/@exceptions@/bspsupport/vectors.h \
+    $(libcpudir)/@exceptions@/bspsupport/ppc_exc_bspsupp.h
+
+
+EXTRA_DIST = times-tqm866
+
+EXTRA_DIST += startup/start.S
+start.$(OBJEXT): startup/start.S
+	$(CPPASCOMPILE) -o $@ -c $<
+project_lib_DATA = start.$(OBJEXT)
+
+EXTRA_DIST += ../../powerpc/shared/start/rtems_crti.S
+rtems_crti.$(OBJEXT): ../../powerpc/shared/start/rtems_crti.S
+	$(CPPASCOMPILE) -o $@ -c $<
+project_lib_DATA += rtems_crti.$(OBJEXT)
+
+dist_project_lib_DATA += startup/linkcmds.base\
+                         startup/linkcmds.tqm8xx
+
+irq_SOURCES = include/irq-config.h \
+	irq/irq.c \
+	../../shared/src/irq-generic.c \
+	../../shared/src/irq-legacy.c
+
+# clock_SOURCES = ../shared/clock/clock.c
+p_clock_SOURCES = clock/p_clock.c
+
+console_SOURCES = console/console.c
+timer_SOURCES = timer/timer.c
+startup_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \
+    ../../shared/bsppost.c ../../shared/bsppredriverhook.c \
+    startup/bspstart.c ../../shared/bootcard.c \
+    startup/mmutlbtab.c startup/cpuinit.c \
+    ../../shared/sbrk.c ../../shared/gnatinstallhandler.c
+
+if HAS_NETWORKING
+network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
+noinst_PROGRAMS += network.rel
+network_rel_SOURCES = network/network_scc.c network/network_fec.c
+network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(network_CPPFLAGS)
+network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+endif
+
+noinst_LIBRARIES = libbsp.a
+libbsp_a_SOURCES = $(irq_SOURCES) \
+    $(startup_SOURCES) $(console_SOURCES) \
+    $(p_clock_SOURCES) $(timer_SOURCES)
+
+libbsp_a_LIBADD = \
+    $(libcpudir)/shared/cpuIdent.rel \
+    $(libcpudir)/shared/cache.rel \
+    $(libcpudir)/@exceptions@/rtems-cpu.rel \
+    $(libcpudir)/@exceptions@/raw_exception.rel \
+    $(libcpudir)/@exceptions@/exc_bspsupport.rel \
+    $(libcpudir)/mpc8xx/console-generic.rel \
+    $(libcpudir)/mpc8xx/cpm.rel \
+    $(libcpudir)/mpc8xx/clock.rel \
+    $(libcpudir)/mpc8xx/mmu.rel \
+    $(libcpudir)/mpc8xx/timer.rel
+
+if HAS_NETWORKING
+libbsp_a_LIBADD += network.rel
+endif
+
+include $(srcdir)/preinstall.am
+include $(top_srcdir)/../../../../automake/local.am
Index: c/src/lib/libbsp/powerpc/tqm8xx/README
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/README	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/README	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,141 @@
+#
+#  $Id$
+#
+
+This is a README file for the tqm8xx BSP
+
+
+Summary
+-------
+
+BSP NAME:           tqm8xx
+BOARD:              various boards based on TQ Components TQM8xx modules
+BUS:                No backplane. 
+CPU FAMILY:         PowerPC
+CPU:                PowerPC MPC860 or MPC866
+COPROCESSORS:       Built-in Motorola QUICC
+MODE:               32 bit mode
+
+BOOT MONITOR:       TQMon 
+
+PERIPHERALS
+===========
+TIMERS:             PIT / Timebase
+  RESOLUTION:       1 microsecond / frequency = clock-speed / 16
+SERIAL PORTS:       1-4 SCCs, 1-2 SMC
+REAL-TIME CLOCK:    <none>
+DMA:                Each SCC and SMC.
+VIDEO:              <none>
+SCSI:               <none>
+NETWORKING:         Ethernet 10 Mbps on SCC1 and/or 
+                    10/100Mbps on FEC (for MPC866T)		    
+		   
+
+DRIVER INFORMATION
+==================
+CLOCK DRIVER:       yes
+CONSOLE DRIVER:     yes
+SHMSUPP:            N/A
+TIMER DRIVER:       yes
+NETWORK DRIVER:	    yes
+
+NOTES
+=====
+On-chip resources:
+	SCC1		network or serial port
+	SCC2		serial port
+	SCC3		serial port
+	SCC4		serial port
+	SMC1		serial port
+	SMC2		serial port
+	CLK1		network
+	CLK2		network
+	CLK3
+	CLK4
+	CLK5
+	CLK6
+	CLK7
+	CLK8
+	BRG1		console
+	BRG2		console
+	BRG3		console
+	BRG4		console
+	RTC
+	PIT		clock
+	TB
+	DEC
+	SWT	
+	UPMA
+	UPMB
+	IRQ0
+	IRQ1
+	IRQ2		
+	IRQ3		
+	IRQ4		
+	IRQ5	
+	IRQ6
+	IRQ7
+	IRQ_LVL0	
+	IRQ_LVL1
+	IRQ_LVL2
+	IRQ_LVL3
+	IRQ_LVL4
+	IRQ_LVL5
+	IRQ_LVL6
+	IRQ_LVL7
+	
+
+Board description
+-----------------
+Clock rate:     50MHz - 133MHz.
+Bus width:      32 bit Flash, 32 bit DRAM
+FLASH:	        2-8MB
+RAM:            32-256MB SDRAM
+
+
+Installation
+------------
+<tbd>
+
+
+Port Description
+Console driver
+---------------
+
+This BSP contains a console driver for polled and interrupt-driven
+operation. It supports SCCs and SMCs.
+During BSP configuration, various variables can be set to activate a
+certain channels and to specify the console channel:
+
+CONS_SMC1_MODE, CONS_SMC2_MODE, CONS_SCC[1-4]_MODE can be set to
+CONS_MODE_UNUSED, CONS_MODE_POLLED or CONS_MODE_IRQ
+
+The driver always uses termios. 
+
+printk() and debug output
+-----------------------
+<tbd>
+
+Floating-point
+--------------
+
+The MPC8xx do not have floating-point units. All code should
+get compiled with the appropriate -mcpu flag. The nof variants of the gcc
+runtime libraries should be used for linking.
+
+
+
+Miscellaneous
+-------------
+
+All development was based on the mbx8xx and gen68360 port.
+
+Test Configuration
+------------------
+
+Board:                pghplus (
+CPU:                  Motorola MPC866T
+Clock Speed:          133MHz
+RAM:                  64MByte
+Cache Configuration:  Instruction cache on; data cache on, copyback mode.
+
Index: c/src/lib/libbsp/powerpc/tqm8xx/bsp_specs
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/bsp_specs	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/bsp_specs	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,14 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems:  ecrti%O%s rtems_crti%O%s  crtbegin.o%s  \
+%{!qrtems_debug: start.o%s} \
+%{qrtems_debug: start_g.o%s}}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn%O%s}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -N -u start -e start}
Index: c/src/lib/libbsp/powerpc/tqm8xx/configure.ac
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/configure.ac	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/configure.ac	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,113 @@
+## Process this file with autoconf to produce a configure script.
+## 
+## $Id$
+
+AC_PREREQ(2.60)
+AC_INIT([rtems-c-src-lib-libbsp-powerpc-tqm8xx],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
+AC_CONFIG_SRCDIR([bsp_specs])
+RTEMS_TOP(../../../../../..)
+
+RTEMS_CANONICAL_TARGET_CPU
+AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.10])
+RTEMS_BSP_CONFIGURE
+
+RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm])
+RTEMS_CANONICALIZE_TOOLS
+RTEMS_PROG_CCAS
+
+RTEMS_CHECK_NETWORKING
+AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
+
+RTEMS_BSPOPTS_SET([PPC_USE_DATA_CACHE],[*],[1])
+RTEMS_BSPOPTS_HELP([PPC_USE_DATA_CACHE],
+[If defined, then the PowerPC specific code in RTEMS will use
+ data cache instructions to optimize the context switch code.
+ This code can conflict with debuggers or emulators.])
+
+RTEMS_BSPOPTS_SET([DATA_CACHE_ENABLE],[*],[1])
+RTEMS_BSPOPTS_HELP([DATA_CACHE_ENABLE],
+[If defined, the data cache will be enabled after address translation
+ is turned on.])
+
+RTEMS_BSPOPTS_SET([INSTRUCTION_CACHE_ENABLE],[*],[1])
+RTEMS_BSPOPTS_HELP([INSTRUCTION_CACHE_ENABLE],
+[If defined, the instruction cache will be enabled after address translation
+ is turned on.])
+
+RTEMS_BSPOPTS_SET([CONSOLE_CHN],[*],[CONS_CHN_SMC1])
+RTEMS_BSPOPTS_HELP([CONSOLE_CHN],
+[(BSP--console driver) Must be defined to be one of CONS_CHN_SMC1, 
+ CONS_CHN_SMC2, CONS_CHN_SCC1, CONS_CHN_SCC2, CONS_CHN_SCC3, or CONS_CHN_SCC4. 
+ Determines which device will be registered as /dev/console.])
+
+RTEMS_BSPOPTS_SET([PRINTK_CHN],[*],[CONS_CHN_SMC1])
+RTEMS_BSPOPTS_HELP([PRINTK_CHN],
+[(BSP--console driver)
+ Must be defined to be one of CONS_CHN_SMC1, CONS_CHN_SMC2, CONS_CHN_SCC2,
+ CONS_CHN_SCC3, or CONS_CHN_SCC4. Determines which device is used for output
+ by printk(). If the port that printk() uses is also used for other
+ I/O (e.g. if  PRINTK_CHN == CONSOLE_CHN), then both ports should 
+ use the same type of I/O, otherwise the drivers will likely conflict with
+ each other.])
+
+RTEMS_BSPOPTS_SET([CONS_SMC1_MODE],[tqm8xx_stk8xx],[CONS_MODE_POLLED])
+RTEMS_BSPOPTS_SET([CONS_SMC1_MODE],[pghplus],[CONS_MODE_POLLED])
+RTEMS_BSPOPTS_SET([CONS_SMC1_MODE],[*],[CONS_MODE_UNUSED])
+RTEMS_BSPOPTS_HELP([CONS_SMC1_MODE],
+[(BSP--SMC1 UART IF mode) Must be defined if SMC1 is used as a tty (UART) 
+ channel. Set it to CONS_MODE_POLLED for polled operation, CONS_MODE_IRQ for 
+ interrupt driven (spooled) operation. Set it to CONS_MODE_UNUSED, if not used])
+
+RTEMS_BSPOPTS_SET([CONS_SMC2_MODE],[tqm8xx_stk8xx],[CONS_MODE_POLLED])
+RTEMS_BSPOPTS_SET([CONS_SMC2_MODE],[*],[CONS_MODE_UNUSED])
+RTEMS_BSPOPTS_HELP([CONS_SMC2_MODE],
+[(BSP--SMC2 UART IF mode) Must be defined if SMC2 is used as a tty (UART) 
+ channel. Set it to CONS_MODE_POLLED for polled operation, CONS_MODE_IRQ for 
+ interrupt driven (spooled) operation. Set it to CONS_MODE_UNUSED, if not used])
+
+RTEMS_BSPOPTS_SET([CONS_SCC1_MODE],[*],[CONS_MODE_UNUSED])
+RTEMS_BSPOPTS_HELP([CONS_SCC1_MODE],
+[(BSP--SCC1 UART IF mode) Must be defined if SCC1 is used as a tty (UART) 
+ channel. Set it to CONS_MODE_POLLED for polled operation, CONS_MODE_IRQ for 
+ interrupt driven (spooled) operation. Set it to CONS_MODE_UNUSED, if not used])
+
+RTEMS_BSPOPTS_SET([CONS_SCC2_MODE],[*],[CONS_MODE_UNUSED])
+RTEMS_BSPOPTS_HELP([CONS_SCC2_MODE],
+[(BSP--SCC2 UART IF mode) Must be defined if SCC2 is used as a tty (UART) 
+ channel. Set it to CONS_MODE_POLLED for polled operation, CONS_MODE_IRQ for 
+ interrupt driven (spooled) operation. Set it to CONS_MODE_UNUSED, if not used])
+
+RTEMS_BSPOPTS_SET([CONS_SCC3_MODE],[*],[CONS_MODE_UNUSED])
+RTEMS_BSPOPTS_HELP([CONS_SCC3_MODE],
+[(BSP--SCC3 UART IF mode) Must be defined if SCC3 is used as a tty (UART) 
+ channel. Set it to CONS_MODE_POLLED for polled operation, CONS_MODE_IRQ for 
+ interrupt driven (spooled) operation. Set it to CONS_MODE_UNUSED, if not used])
+
+RTEMS_BSPOPTS_SET([CONS_SCC4_MODE],[*],[CONS_MODE_UNUSED])
+RTEMS_BSPOPTS_HELP([CONS_SCC4_MODE],
+[(BSP--SCC4 UART IF mode) Must be defined if SCC4 is used as a tty (UART) 
+ channel. Set it to CONS_MODE_POLLED for polled operation, CONS_MODE_IRQ for 
+ interrupt driven (spooled) operation. Set it to CONS_MODE_UNUSED, if not used])
+
+# add selection of primary network interface
+RTEMS_BSPOPTS_SET([BSP_USE_NETWORK_FEC],[pghplus],[1])
+RTEMS_BSPOPTS_SET([BSP_USE_NETWORK_FEC],[*],[0])
+RTEMS_BSPOPTS_HELP([BSP_USE_NETWORK_FEC],
+[If defined, then the BSP will use the Fast Ethernet Controller
+ for 10/100MBit networking and used as primary networking interface.])
+
+RTEMS_BSPOPTS_SET([BSP_USE_NETWORK_SCC],[pghplus],[0])
+RTEMS_BSPOPTS_SET([BSP_USE_NETWORK_SCC],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_USE_NETWORK_SCC],
+[If defined, then the BSP will use the Serial Communications Controller (SCC1)
+ for 10MBit networking.])
+
+
+# Explicitly list a Makefile here 
+AC_CONFIG_FILES([Makefile])
+
+RTEMS_BSP_BOOTCARD_HANDLES_RAM_ALLOCATION
+
+RTEMS_PPC_EXCEPTIONS
+
+AC_OUTPUT
Index: c/src/lib/libbsp/powerpc/tqm8xx/console/console.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/console/console.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/console/console.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,1112 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: */
+/*
+ *  SMC1/2 SCC1..4 raw console serial I/O.
+ *  adapted to work with up to 4 SCC and 2 SMC
+ *
+ *  This driver is an example of `TASK DRIVEN' `POLLING' or `INTERRUPT' I/O.
+ *
+ *  To run with interrupt-driven I/O, ensure m8xx_smc1_interrupt
+ *  is set before calling the initialization routine.
+ *
+ *  Author:
+ *    W. Eric Norum
+ *    Saskatchewan Accelerator Laboratory
+ *    University of Saskatchewan
+ *    Saskatoon, Saskatchewan, CANADA
+ *    eric@skatter.usask.ca
+ *
+ *  COPYRIGHT (c) 1989-1998.
+ *  On-Line Applications Research Corporation (OAR).
+ *  Copyright assigned to U.S. Government, 1994.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  $Id$
+ */
+
+#include <rtems.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <bsp.h>
+#include <mpc8xx.h>
+#include <rtems/libio.h>
+#include <termios.h>
+#include <unistd.h>
+#include <rtems/termiostypes.h>
+#include <rtems/bspIo.h>
+
+/*
+ * Declare clock speed -- may be overwritten by downloader or debugger
+ */
+int m8xx_clock_rate	= 0;
+
+/*
+ * Interrupt-driven input buffer
+ */
+#define RXBUFSIZE	256
+
+#define M8xx_IVEC_SRC_MASK (0x1f)
+#define M8xx_IVEC_SRC_SCC1  (0x1E)
+#define M8xx_IVEC_SRC_SCC2  (0x1D)
+#define M8xx_IVEC_SRC_SCC3  (0x1C)
+#define M8xx_IVEC_SRC_SCC4  (0x1B)
+#define M8xx_IVEC_SRC_SMC1  (0x04)
+#define M8xx_IVEC_SRC_SMC2  (0x03)
+
+#define M8xx_IREG_MASK(src) (1UL << src)
+#define M8xx_SICR_BRG1 (0)
+#define M8xx_SICR_BRG2 (1)
+#define M8xx_SICR_BRG3 (2)
+#define M8xx_SICR_BRG4 (3)
+
+#define M8xx_SICR_SCCRX_MSK(scc) ((  7) << (((scc))*8+3))
+#define M8xx_SICR_SCCRX(scc,clk) ((clk) << (((scc))*8+3))
+
+#define M8xx_SICR_SCCTX_MSK(scc) ((  7) << (((scc))*8+0))
+#define M8xx_SICR_SCCTX(scc,clk) ((clk) << (((scc))*8+0))
+
+#define M8xx_SIMODE_SMCCS(smc,clk) ((clk) << ((smc)*16+12))
+#define M8xx_SIMODE_SMCCS_MSK(smc) M8xx_SIMODE_SMCCS(smc,7)
+
+#define CONS_CHN_CNT 6
+#define CONS_CHN_SCC1 0
+#define CONS_CHN_SCC2 1
+#define CONS_CHN_SCC3 2
+#define CONS_CHN_SCC4 3
+#define CONS_CHN_SMC1 4
+#define CONS_CHN_SMC2 5
+
+/*
+ * possible identifiers for bspopts.h: CONS_SxCy_MODE
+ */
+#define CONS_MODE_UNUSED -1
+#define CONS_MODE_POLLED TERMIOS_POLLED
+#define CONS_MODE_IRQ    TERMIOS_IRQ_DRIVEN
+
+#define CHN_IS_SCC(chan) ((chan) < CONS_CHN_SMC1)
+
+#define BRG_CNT 4
+
+#define MAX_IDL_DEFAULT 10
+#define DEVICEPREFIX "tty"
+
+/*
+ * printk basic support
+ */
+static void _BSP_null_char( char c ) {return;}
+BSP_output_char_function_type BSP_output_char = _BSP_null_char;
+
+/*
+ * Interrupt-driven callback
+ */
+static int m8xx_scc_mode[CONS_CHN_CNT];
+static void *sccttyp[CONS_CHN_CNT];
+typedef struct m8xx_console_chan_desc_s {
+  bool is_scc;                  /* true for SCC */
+  struct {
+    volatile m8xxSCCparms_t *sccp;
+    volatile m8xxSMCparms_t *smcp;
+  } parms;
+  struct {
+    volatile m8xxSCCRegisters_t *sccr;
+    volatile m8xxSMCRegisters_t *smcr;
+  } regs;
+  int ivec_src;
+  uint32_t ireg_mask;
+  int        cr_chan_code;
+  int        brg_used;
+} m8xx_console_chan_desc_t;
+
+m8xx_console_chan_desc_t m8xx_console_chan_desc[CONS_CHN_CNT] = {
+  /* SCC1 */
+  {TRUE,
+   {(m8xxSCCparms_t *)&(m8xx.scc1p),NULL},
+   {&(m8xx.scc1),NULL},
+   M8xx_IVEC_SRC_SCC1,
+   M8xx_IREG_MASK(M8xx_IVEC_SRC_SCC1),
+   M8xx_CR_CHAN_SCC1,
+   -1},
+  /* SCC2 */
+  {TRUE,
+   {&(m8xx.scc2p),NULL},
+   {&(m8xx.scc2),NULL},
+   M8xx_IVEC_SRC_SCC2,
+   M8xx_IREG_MASK(M8xx_IVEC_SRC_SCC2),
+   M8xx_CR_CHAN_SCC2,
+   -1},
+  /* SCC3 */
+  {TRUE,
+   {&(m8xx.scc3p),NULL},
+   {&(m8xx.scc3),NULL},
+   M8xx_IVEC_SRC_SCC3,
+   M8xx_IREG_MASK(M8xx_IVEC_SRC_SCC3),
+   M8xx_CR_CHAN_SCC3,
+   -1},
+  /* SCC4 */
+  {TRUE,
+   {&(m8xx.scc4p),NULL},
+   {&(m8xx.scc4),NULL},
+   M8xx_IVEC_SRC_SCC4,
+   M8xx_IREG_MASK(M8xx_IVEC_SRC_SCC4),
+   M8xx_CR_CHAN_SCC4,
+   -1},
+  /* SMC1 */
+  {FALSE,
+   {NULL,&(m8xx.smc1p)},
+   {NULL,&(m8xx.smc1)},
+   M8xx_IVEC_SRC_SMC1,
+   M8xx_IREG_MASK(M8xx_IVEC_SRC_SMC1),
+   M8xx_CR_CHAN_SMC1,
+   -1},
+  /* SMC2 */
+  {FALSE,
+   {NULL,&(m8xx.smc2p)},
+   {NULL,&(m8xx.smc2)},
+   M8xx_IVEC_SRC_SMC2,
+   M8xx_IREG_MASK(M8xx_IVEC_SRC_SMC2),
+   M8xx_CR_CHAN_SMC2,
+   -1}};
+
+#define CHN_PARAM_GET(chan,param)			\
+  (m8xx_console_chan_desc[chan].is_scc			\
+   ? m8xx_console_chan_desc[chan].parms.sccp->param	\
+   : m8xx_console_chan_desc[chan].parms.smcp->param)
+
+#define CHN_PARAM_SET(chan,param,value)				\
+  do {if (m8xx_console_chan_desc[chan].is_scc)			\
+      m8xx_console_chan_desc[chan].parms.sccp->param = value;	\
+    else							\
+      m8xx_console_chan_desc[chan].parms.smcp->param = value;	\
+  } while (0)
+
+#define CHN_EVENT_GET(chan)				\
+  (m8xx_console_chan_desc[chan].is_scc			\
+   ? m8xx_console_chan_desc[chan].regs.sccr->scce	\
+   : m8xx_console_chan_desc[chan].regs.smcr->smce)
+
+#define CHN_EVENT_CLR(chan,mask) 				\
+  do {								\
+    if (m8xx_console_chan_desc[chan].is_scc) 			\
+      m8xx_console_chan_desc[chan].regs.sccr->scce = (mask);	\
+    else							\
+      m8xx_console_chan_desc[chan].regs.smcr->smce = (mask);	\
+  }while (0)
+
+#define CHN_MASK_GET(chan)				\
+  (m8xx_console_chan_desc[chan].is_scc			\
+   ? m8xx_console_chan_desc[chan].regs.sccr->sccm	\
+   : m8xx_console_chan_desc[chan].regs.smcr->smcm)
+
+#define CHN_MASK_SET(chan,mask) 				\
+  do {								\
+    if (m8xx_console_chan_desc[chan].is_scc) 			\
+      m8xx_console_chan_desc[chan].regs.sccr->sccm = (mask);	\
+    else							\
+      m8xx_console_chan_desc[chan].regs.smcr->smcm = (mask);	\
+  }while (0)
+
+
+/*
+ * I/O buffers and pointers to buffer descriptors
+ */
+#define SCC_RXBD_CNT 4
+#define SCC_TXBD_CNT 4
+typedef volatile char sccRxBuf_t[SCC_RXBD_CNT][RXBUFSIZE];
+static sccRxBuf_t *rxBuf[CONS_CHN_CNT];
+
+static volatile m8xxBufferDescriptor_t *sccFrstRxBd[CONS_CHN_CNT];
+static volatile m8xxBufferDescriptor_t *sccCurrRxBd[CONS_CHN_CNT];
+static volatile m8xxBufferDescriptor_t *sccFrstTxBd[CONS_CHN_CNT];
+static volatile m8xxBufferDescriptor_t *sccPrepTxBd[CONS_CHN_CNT];
+static volatile m8xxBufferDescriptor_t *sccDequTxBd[CONS_CHN_CNT];
+
+/*
+ * Compute baud-rate-generator configuration register value
+ */
+static uint32_t
+sccBRGval (int baud)
+{
+  int divisor;
+  int div16 = 0;
+
+  divisor = ((m8xx_clock_rate / 16) + (baud / 2)) / baud;
+  if (divisor > 4096) {
+    div16 = 1;
+    divisor = (divisor + 8) / 16;
+  }
+  return M8xx_BRG_EN | M8xx_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16;
+}
+
+typedef struct {
+  uint32_t reg_content;
+  int link_cnt;
+}brg_state_t; 
+brg_state_t scc_brg_state[BRG_CNT];
+
+/*
+ * initialize brg_state 
+ */
+static void sccBRGinit(void)
+{
+  int brg_idx;
+
+  for (brg_idx = 0;brg_idx < BRG_CNT;brg_idx++) {
+    scc_brg_state[brg_idx].reg_content = 0;
+    scc_brg_state[brg_idx].link_cnt    = 0;
+  }
+#ifndef MDE360
+  /*
+   * on ZEM40, init CLK4/5 inputs
+   */
+  m8xx.papar |=  ((1 << 11) | (1 << 12));
+  m8xx.padir &= ~((1 << 11) | (1 << 12));
+#endif
+}
+
+/*
+ * input clock frq for CPM clock inputs
+ */
+static uint32_t clkin_frq[2][4] = {
+#ifdef MDE360
+  {0,0,0,0},
+  {0,0,0,0}
+#else
+  {0,0,0,1843000},
+  {1843000,0,0,0}
+#endif
+};
+
+/*
+ * allocate, set and connect baud rate generators
+ * FIXME: or clock input
+ * FIXME: set pin to be clock input
+ */
+
+static int sccBRGalloc(int chan,int baud)
+{
+  rtems_interrupt_level level;
+  m8xx_console_chan_desc_t *chan_desc = &(m8xx_console_chan_desc[chan]);
+  uint32_t reg_val;
+  int old_brg;
+  int new_brg = -1;
+  int brg_idx;
+#if 0 /* we do not support external clocked console */
+  int clk_group;
+  int clk_sel;
+#endif
+
+  old_brg = chan_desc->brg_used;
+  /* compute brg register contents needed */
+  reg_val = sccBRGval(baud);
+
+#if 0 /* we do not support external clocked console */
+  /* search for clock input with this frq */
+  clk_group = ((chan == CONS_CHN_SCC3) ||
+	       (chan == CONS_CHN_SCC4) ||
+	       (chan == CONS_CHN_SMC2)) ? 1 : 0;
+
+  for (clk_sel = 0, new_brg = -1;
+       (clk_sel < 4) && (new_brg < 0);
+       clk_sel++) {
+    if (baud == (clkin_frq[clk_group][clk_sel] / 16)) {
+      new_brg = clk_sel + 4;
+    }
+  }
+#endif
+
+  rtems_interrupt_disable(level);  
+
+  if (new_brg < 0) {
+    /* search for brg with this settings */
+    for (brg_idx = 0;
+	 (new_brg < 0) && (brg_idx < BRG_CNT);
+	 brg_idx++) {
+      if (scc_brg_state[brg_idx].reg_content == reg_val) {
+	new_brg = brg_idx;
+      }
+    }
+    /* 
+     * if not found: check, whether brg currently in use 
+     * is linked only from our channel  
+     */
+    if ((new_brg < 0) &&
+	(old_brg >= 0) &&
+	(scc_brg_state[old_brg].link_cnt == 1)) {
+      new_brg = old_brg;
+    }
+    /* if not found: search for unused brg, set it  */
+    for (brg_idx = 0;
+	 (new_brg < 0) && (brg_idx < BRG_CNT);
+	 brg_idx++) {
+      if (scc_brg_state[brg_idx].link_cnt == 0) {
+	new_brg = brg_idx;
+      }
+    }
+  }
+
+  /* decrease old link count */
+  if ((old_brg >= 0) && 
+      (old_brg < 4)) {
+    scc_brg_state[old_brg].link_cnt--;
+  }
+  /* increase new brg link count, set brg */
+  if ((new_brg >= 0) && 
+      (new_brg < 4)) {
+    scc_brg_state[new_brg].link_cnt++;
+    scc_brg_state[new_brg].reg_content = reg_val;
+    (&m8xx.brgc1)[new_brg] = reg_val;
+  }  
+  rtems_interrupt_enable(level);
+
+  /* connect to scc/smc */
+  if (new_brg >= 0) {
+    m8xx_console_chan_desc[chan].brg_used = new_brg;
+    /*
+     * Put SCC in NMSI mode, connect SCC to BRG or CLKx
+     */
+    if (m8xx_console_chan_desc[chan].is_scc) {
+      m8xx.sicr = ((m8xx.sicr & ~(M8xx_SICR_SCCRX_MSK(chan) |
+				  M8xx_SICR_SCCTX_MSK(chan))) |
+		   M8xx_SICR_SCCRX(chan,new_brg)|
+		   M8xx_SICR_SCCTX(chan,new_brg));
+    }
+    else {
+      /* connect SMC to BRGx or CLKx... */
+      m8xx.simode = ((m8xx.simode & ~(M8xx_SIMODE_SMCCS_MSK(chan - CONS_CHN_SMC1)))|
+		     M8xx_SIMODE_SMCCS(chan - CONS_CHN_SMC1,new_brg));
+    }
+  }
+  return (new_brg < 0);
+}
+
+
+/*
+ * Hardware-dependent portion of tcsetattr().
+ */
+static int
+sccSetAttributes (int minor, const struct termios *t)
+{
+  int baud;
+
+  switch (t->c_cflag & CBAUD) {
+  default:	baud = -1;	break;
+  case B50:	baud = 50;	break;
+  case B75:	baud = 75;	break;
+  case B110:	baud = 110;	break;
+  case B134:	baud = 134;	break;
+  case B150:	baud = 150;	break;
+  case B200:	baud = 200;	break;
+  case B300:	baud = 300;	break;
+  case B600:	baud = 600;	break;
+  case B1200:	baud = 1200;	break;
+  case B1800:	baud = 1800;	break;
+  case B2400:	baud = 2400;	break;
+  case B4800:	baud = 4800;	break;
+  case B9600:	baud = 9600;	break;
+  case B19200:	baud = 19200;	break;
+  case B38400:	baud = 38400;	break;
+  case B57600:	baud = 57600;	break;
+  case B115200:	baud = 115200;	break;
+  case B230400:	baud = 230400;	break;
+  case B460800:	baud = 460800;	break;
+  }
+  return sccBRGalloc(minor,baud);
+  return 0;
+}
+
+/*
+ * Interrupt handler 
+ */
+static rtems_isr
+sccInterruptHandler (rtems_vector_number v)
+{
+  int chan = 0;
+  /*
+   * calculate channel from vector
+   */
+  switch(v & M8xx_IVEC_SRC_MASK) {
+  case M8xx_IVEC_SRC_SCC1:
+    chan = CONS_CHN_SCC1;
+    break;
+  case M8xx_IVEC_SRC_SCC2:
+    chan = CONS_CHN_SCC2;
+    break;
+  case M8xx_IVEC_SRC_SCC3:
+    chan = CONS_CHN_SCC3;
+    break;
+  case M8xx_IVEC_SRC_SCC4:
+    chan = CONS_CHN_SCC4;
+    break;
+  case M8xx_IVEC_SRC_SMC1:
+    chan = CONS_CHN_SMC1;
+    break;
+  case M8xx_IVEC_SRC_SMC2:
+    chan = CONS_CHN_SMC2;
+    break;
+  }
+
+  /*
+   * Buffer received?
+   */
+  if (CHN_EVENT_GET(chan) & 0x1) {
+    /*
+     * clear SCC event flag 
+     */
+    CHN_EVENT_CLR(chan,0x01);
+    /*
+     * process event
+     */
+    while ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) == 0) {
+      if (sccttyp[chan] != NULL) {
+	rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer,
+						   sccCurrRxBd[chan]->length);
+	rtems_termios_enqueue_raw_characters (sccttyp[chan],
+					      (char *)sccCurrRxBd[chan]->buffer,
+					      sccCurrRxBd[chan]->length);
+      }
+      /*
+       * clear status
+       */
+      sccCurrRxBd[chan]->status = 
+	(sccCurrRxBd[chan]->status 
+	 & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT))
+	| M8xx_BD_EMPTY;
+      /*
+       * advance to next BD
+       */
+      if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) {
+	sccCurrRxBd[chan] = sccFrstRxBd[chan];
+      }
+      else {
+	sccCurrRxBd[chan]++;
+      }
+    }
+  }
+  /*
+   * Buffer transmitted?
+   */
+  if (CHN_EVENT_GET(chan) & 0x2) {
+    /*
+     * then clear interrupt event bit
+     */
+    CHN_EVENT_CLR(chan,0x2);
+    /*
+     * and signal successful transmit to termios
+     */
+    /*
+     * FIXME: multiple dequeue calls for multiple buffers
+     */
+    while((sccDequTxBd[chan] != sccPrepTxBd[chan]) &&
+	  ((sccDequTxBd[chan]->status & M8xx_BD_READY) == 0)) {
+      if (sccttyp[chan] != NULL) {
+	rtems_termios_dequeue_characters (sccttyp[chan], 
+					  sccDequTxBd[chan]->length);
+      }
+      /*
+       * advance to next BD
+       */
+      if ((sccDequTxBd[chan]->status & M8xx_BD_WRAP) != 0) {
+	sccDequTxBd[chan] = sccFrstTxBd[chan];
+      }
+      else {
+	sccDequTxBd[chan]++;
+      }
+    }
+  }
+
+  m8xx.cisr = m8xx_console_chan_desc[chan].ireg_mask;/* Clear interrupt-in-service bit */
+}
+
+static void
+sccInitialize (int chan)
+{
+  int i;
+  /*
+   * allocate buffers
+   * FIXME: use a cache-line size boundary alloc here
+   */
+  rxBuf[chan] = malloc(sizeof(*rxBuf[chan]) + 2*PPC_CACHE_ALIGNMENT);
+  if (rxBuf[chan] == NULL) {
+    BSP_panic("Cannot allocate console rx buffer\n");
+  }
+  else {
+    /*
+     * round up rxBuf[chan] to start at a cache line size
+     */
+    rxBuf[chan] = (sccRxBuf_t *)
+      (((uint32_t)rxBuf[chan]) + 
+       (PPC_CACHE_ALIGNMENT
+	- ((uint32_t)rxBuf[chan]) % PPC_CACHE_ALIGNMENT));
+  }
+  /*
+   * Allocate buffer descriptors 
+   */
+  sccCurrRxBd[chan] = 
+    sccFrstRxBd[chan] = m8xx_bd_allocate(SCC_RXBD_CNT);
+  sccPrepTxBd[chan] = 
+    sccDequTxBd[chan] = 
+    sccFrstTxBd[chan] = m8xx_bd_allocate(SCC_TXBD_CNT);
+  switch(chan) {
+  case CONS_CHN_SCC1:
+    /*
+     * Configure port A pins to enable TXD1 and RXD1 pins
+     * FIXME: add setup for modem control lines....
+     */
+    m8xx.papar |=  0x03;
+    m8xx.padir &= ~0x03;
+
+    /*
+     * Configure port C pins to enable RTS1 pins (static active low)
+     */
+    m8xx.pcpar &= ~0x01;
+    m8xx.pcso  &= ~0x01;
+    m8xx.pcdir |=  0x01;
+    m8xx.pcdat &= ~0x01;
+    break;
+  case CONS_CHN_SCC2:
+    /*
+     * Configure port A pins to enable TXD2 and RXD2 pins
+     * FIXME: add setup for modem control lines....
+     */
+    m8xx.papar |=  0x0C;
+    m8xx.padir &= ~0x0C;
+
+    /*
+     * Configure port C pins to enable RTS2 pins (static active low)
+     */
+    m8xx.pcpar &= ~0x02;
+    m8xx.pcso  &= ~0x02;
+    m8xx.pcdir |=  0x02;
+    m8xx.pcdat &= ~0x02;
+    break;
+  case CONS_CHN_SCC3:
+    /*
+     * Configure port A pins to enable TXD3 and RXD3 pins
+     * FIXME: add setup for modem control lines....
+     */
+    m8xx.papar |=  0x30;
+    m8xx.padir &= ~0x30;
+
+    /*
+     * Configure port C pins to enable RTS3 (static active low)
+     */
+    m8xx.pcpar &= ~0x04;
+    m8xx.pcso  &= ~0x04;
+    m8xx.pcdir |=  0x04;
+    m8xx.pcdat &= ~0x04;
+    break;
+  case CONS_CHN_SCC4:
+    /*
+     * Configure port A pins to enable TXD4 and RXD4 pins
+     * FIXME: add setup for modem control lines....
+     */
+    m8xx.papar |=  0xC0;
+    m8xx.padir &= ~0xC0;
+
+    /*
+     * Configure port C pins to enable RTS4 pins (static active low)
+     */
+    m8xx.pcpar &= ~0x08;
+    m8xx.pcso  &= ~0x08;
+    m8xx.pcdir |=  0x08;
+    m8xx.pcdat &= ~0x08;
+    break;
+  case CONS_CHN_SMC1:
+    /*
+     * Configure port B pins to enable SMTXD1 and SMRXD1 pins
+     */
+    m8xx.pbpar |=  0xC0; 
+    m8xx.pbdir &= ~0xC0;
+    break;
+  case CONS_CHN_SMC2:
+    /*
+     * Configure port B pins to enable SMTXD2 and SMRXD2 pins
+     */
+    m8xx.pbpar |=  0xC00;
+    m8xx.pbdir &= ~0xC00;
+    break;
+  }
+  /*
+   * allocate and connect BRG 
+   */
+  sccBRGalloc(chan,9600);
+  
+  
+  /*
+   * Set up SCCx parameter RAM common to all protocols
+   */
+  CHN_PARAM_SET(chan,rbase,(char *)sccFrstRxBd[chan] - (char *)&m8xx);
+  CHN_PARAM_SET(chan,tbase,(char *)sccFrstTxBd[chan] - (char *)&m8xx);
+  CHN_PARAM_SET(chan,rfcr ,M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0));
+  CHN_PARAM_SET(chan,tfcr ,M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0));
+  if (m8xx_scc_mode[chan] != TERMIOS_POLLED)
+    CHN_PARAM_SET(chan,mrblr,RXBUFSIZE);
+  else
+    CHN_PARAM_SET(chan,mrblr,1);
+  
+  /*
+   * Set up SCCx parameter RAM UART-specific parameters
+   */
+  CHN_PARAM_SET(chan,un.uart.max_idl ,MAX_IDL_DEFAULT);
+  CHN_PARAM_SET(chan,un.uart.brkln   ,0);
+  CHN_PARAM_SET(chan,un.uart.brkec   ,0);
+  CHN_PARAM_SET(chan,un.uart.brkcr   ,0);
+  if (m8xx_console_chan_desc[chan].is_scc) {
+    m8xx_console_chan_desc[chan].parms.sccp->un.uart.character[0]=0x8000; /* no char filter */
+    m8xx_console_chan_desc[chan].parms.sccp->un.uart.rccm=0x80FF; /* control character mask */
+  }
+  
+  /*
+   * Set up the Receive Buffer Descriptors
+   */
+  for (i = 0;i < SCC_RXBD_CNT;i++) {
+    sccFrstRxBd[chan][i].status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
+    if (i == SCC_RXBD_CNT-1) {
+      sccFrstRxBd[chan][i].status |= M8xx_BD_WRAP;
+    }
+    sccFrstRxBd[chan][i].length = 0;
+    sccFrstRxBd[chan][i].buffer = rxBuf[chan][i];
+  }
+  /*
+   * Setup the Transmit Buffer Descriptor
+   */
+  for (i = 0;i < SCC_TXBD_CNT;i++) {
+    sccFrstTxBd[chan][i].status = M8xx_BD_INTERRUPT;
+    if (i == SCC_TXBD_CNT-1) {
+      sccFrstTxBd[chan][i].status |= M8xx_BD_WRAP;
+    }
+    sccFrstTxBd[chan][i].length = 0;
+    sccFrstTxBd[chan][i].buffer = NULL;
+  }
+  
+  /*
+   * Set up SCC general and protocol-specific mode registers
+   */
+  CHN_EVENT_CLR(chan,~0);	/* Clear any pending events */
+  CHN_MASK_SET(chan,0);	        /* Mask all interrupt/event sources */
+	       
+  if (m8xx_console_chan_desc[chan].is_scc) {
+    m8xx_console_chan_desc[chan].regs.sccr->psmr = 0xb000; /* 8N1, CTS flow control */
+    m8xx_console_chan_desc[chan].regs.sccr->gsmr_h = 0x00000000;
+    m8xx_console_chan_desc[chan].regs.sccr->gsmr_l = 0x00028004; /* UART mode */
+  }
+  else {
+    m8xx_console_chan_desc[chan].regs.smcr->smcmr = 0x4820;
+  }
+  /*
+   * Send "Init parameters" command
+   */
+  m8xx_cp_execute_cmd(M8xx_CR_OP_INIT_RX_TX 
+		      | m8xx_console_chan_desc[chan].cr_chan_code);
+  
+  /*
+   * Enable receiver and transmitter
+   */
+  if (m8xx_console_chan_desc[chan].is_scc) {
+    m8xx_console_chan_desc[chan].regs.sccr->gsmr_l |= 0x00000030;
+  }
+  else {
+    m8xx_console_chan_desc[chan].regs.smcr->smcmr |= 0x0003;
+  }
+
+  if (m8xx_scc_mode[chan] != TERMIOS_POLLED) {
+    rtems_isr_entry old_handler;
+    rtems_status_code sc;
+    
+    sc = rtems_interrupt_catch (sccInterruptHandler,
+				m8xx_console_chan_desc[chan].ivec_src 
+				| (m8xx.cicr & 0xE0),
+				&old_handler);
+    CHN_MASK_SET(chan,3);	/* Enable TX and RX interrupts */
+    m8xx.cimr |= m8xx_console_chan_desc[chan].ireg_mask;  /* Enable interrupts */
+  }
+}
+
+/*
+ * polled scc read function
+ */
+static int
+sccPollRead (int minor)
+{
+  unsigned char c;
+  int chan = minor;
+
+  if ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) != 0) {
+    return -1;
+  }
+  rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer,
+					     sccCurrRxBd[chan]->length);
+  c = *((char *)sccCurrRxBd[chan]->buffer);
+  /*
+   * clear status
+   */
+  sccCurrRxBd[chan]->status = 
+    (sccCurrRxBd[chan]->status 
+     & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT))
+    | M8xx_BD_EMPTY;
+  /*
+   * advance to next BD
+   */
+  if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) {
+    sccCurrRxBd[chan] = sccFrstRxBd[chan];
+  }
+  else {
+    sccCurrRxBd[chan]++;
+  }
+  return c;
+}
+
+
+/*
+ * Device-dependent write routine
+ * Interrupt-driven devices:
+ *	Begin transmission of as many characters as possible (minimum is 1).
+ * Polling devices:
+ *	Transmit all characters.
+ */
+static int
+sccInterruptWrite (int minor, const char *buf, int len)
+{
+  int chan = minor;
+
+  if ((sccPrepTxBd[chan]->status & M8xx_BD_READY) == 0) {
+    sccPrepTxBd[chan]->buffer = (char *)buf;
+    sccPrepTxBd[chan]->length = len;
+    rtems_cache_flush_multiple_data_lines((const void *)buf,len);
+    /*
+     * clear status, set ready bit
+     */
+    sccPrepTxBd[chan]->status = 
+      (sccPrepTxBd[chan]->status 
+       & M8xx_BD_WRAP)
+      | M8xx_BD_READY | M8xx_BD_INTERRUPT;
+    if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) {
+      sccPrepTxBd[chan] = sccFrstTxBd[chan];
+    }
+    else {
+      sccPrepTxBd[chan]++;
+    }
+  }
+  return 0;
+}
+
+static int
+sccPollWrite (int minor, const char *buf, int len)
+{
+  int chan = minor;
+  int bd_used;
+
+  while (len--) {
+    static char txBuf[CONS_CHN_CNT][SCC_TXBD_CNT];
+    while (sccPrepTxBd[chan]->status & M8xx_BD_READY)
+      continue;
+    bd_used = sccPrepTxBd[chan]-sccFrstTxBd[chan];
+    txBuf[chan][bd_used] = *buf++;
+      rtems_cache_flush_multiple_data_lines((const void *)&txBuf[chan][bd_used],
+					    sizeof(txBuf[chan][bd_used]));    
+    sccPrepTxBd[chan]->buffer = &(txBuf[chan][bd_used]);
+    sccPrepTxBd[chan]->length = 1;
+    sccPrepTxBd[chan]->status = 
+      (sccPrepTxBd[chan]->status 
+       & M8xx_BD_WRAP)
+      | M8xx_BD_READY;
+    if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) {
+      sccPrepTxBd[chan] = sccFrstTxBd[chan];
+    }
+    else {
+      sccPrepTxBd[chan]++;
+    }
+  }
+  return 0;
+}
+
+/*
+***************
+* BOILERPLATE *
+***************
+*/
+
+struct {
+  rtems_device_minor_number minor;
+  int driver_mode;
+} channel_list[] = {
+  {CONS_CHN_SMC1,CONS_SMC1_MODE},
+  {CONS_CHN_SMC2,CONS_SMC2_MODE},
+  {CONS_CHN_SCC1,CONS_SCC1_MODE},
+  {CONS_CHN_SCC2,CONS_SCC2_MODE},
+  {CONS_CHN_SCC3,CONS_SCC3_MODE},
+  {CONS_CHN_SCC4,CONS_SCC4_MODE}
+};
+
+
+/*
+ * Initialize and register the device
+ */
+rtems_device_driver console_initialize(rtems_device_major_number  major,
+				       rtems_device_minor_number  minor,/* ignored */
+				       void                      *arg
+				       )
+{
+  rtems_status_code status = RTEMS_SUCCESSFUL;
+  int chan,entry,ttynum;
+  char tty_name[] = "/dev/tty00";
+
+  /*
+   * init base clock for BRGs
+   * (if not already set by debugger etc)
+   */
+  if (m8xx_clock_rate == 0) {
+    m8xx_clock_rate = BSP_bus_frequency;
+  }
+  /*
+   * Set up TERMIOS
+   */
+  rtems_termios_initialize ();
+  /*
+   * init BRG allocataion
+   */
+  sccBRGinit();
+  ttynum = 0;
+  for (entry = 0;
+       (entry < sizeof(channel_list)/sizeof(channel_list[0]))
+	 && (status == RTEMS_SUCCESSFUL);
+       entry++) {
+    if (channel_list[entry].driver_mode != CONS_MODE_UNUSED) {
+      /*
+       * Do device-specific initialization
+       */
+      chan = channel_list[entry].minor;
+      m8xx_scc_mode[chan] = channel_list[entry].driver_mode;
+      sccInitialize (chan);
+
+      /*
+       * build device name
+       */
+      tty_name[sizeof(tty_name)-2] = '0'+ttynum;
+      ttynum++;
+      /*
+       * Register the device
+       */
+      status = rtems_io_register_name (tty_name,
+				       major, 
+				       channel_list[entry].minor);
+      if (status != RTEMS_SUCCESSFUL) {
+	rtems_fatal_error_occurred (status);
+      }
+    }	  
+  }
+  /*
+   * register /dev/console
+   */
+  status = rtems_io_register_name ("/dev/console",
+				   major, 
+				   CONSOLE_CHN);
+  if (status != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred (status);
+  }
+  /*
+   * FIXME: enable printk support
+   */
+  return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Open the device
+ */
+rtems_device_driver console_open(
+				 rtems_device_major_number major,
+				 rtems_device_minor_number minor,
+				 void                    * arg
+				 )
+{
+  rtems_status_code status;
+  int chan = minor;
+  rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg;
+  static const rtems_termios_callbacks interruptCallbacks = {
+    NULL,		/* firstOpen */
+    NULL,		/* lastClose */
+    NULL,	        /* pollRead */
+    sccInterruptWrite,	/* write */
+    sccSetAttributes,	/* setAttributes */
+    NULL,		/* stopRemoteTx */
+    NULL,		/* startRemoteTx */
+    TERMIOS_IRQ_DRIVEN	/* outputUsesInterrupts */
+  };
+  static const rtems_termios_callbacks pollCallbacks = {
+    NULL,		/* firstOpen */
+    NULL,		/* lastClose */
+    sccPollRead,	/* pollRead */
+    sccPollWrite,	/* write */
+    sccSetAttributes,	/* setAttributes */
+    NULL,		/* stopRemoteTx */
+    NULL,		/* startRemoteTx */
+    0			/* outputUsesInterrupts */
+  };
+
+  if (m8xx_scc_mode[chan] == TERMIOS_IRQ_DRIVEN) {    
+    status = rtems_termios_open (major, minor, arg, &interruptCallbacks);
+    sccttyp[chan] = args->iop->data1;
+  }
+  else {
+    status = rtems_termios_open (major, minor, arg, &pollCallbacks);
+    sccttyp[chan] = args->iop->data1;
+  }
+  return status;
+}
+ 
+/*
+ * Close the device
+ */
+rtems_device_driver console_close(
+				  rtems_device_major_number major,
+				  rtems_device_minor_number minor,
+				  void                    * arg
+				  )
+{
+  rtems_status_code rc;
+
+  rc = rtems_termios_close (arg);
+  sccttyp[minor] = NULL;
+
+  return rc;
+
+}
+
+/*
+ * Read from the device
+ */
+rtems_device_driver console_read(
+				 rtems_device_major_number major,
+				 rtems_device_minor_number minor,
+				 void                    * arg
+				 )
+{
+  return rtems_termios_read (arg);
+}
+
+/*
+ * Write to the device
+ */
+rtems_device_driver console_write(
+				  rtems_device_major_number major,
+				  rtems_device_minor_number minor,
+				  void                    * arg
+				  )
+{
+  return rtems_termios_write (arg);
+}
+
+#if 0
+static int scc_io_set_trm_char(rtems_device_minor_number minor,
+			       rtems_libio_ioctl_args_t *ioa)
+{
+  rtems_status_code rc                = RTEMS_SUCCESSFUL;
+  con360_io_trm_char_t *trm_char_info = ioa->buffer;
+
+  printf("ioctl called: maxidl=%d\n",trm_char_info->max_idl);
+  printf("ioctl called: char_cnt=%d\n",trm_char_info->char_cnt);
+  /*
+   * check, that parameter is non-NULL
+   */
+  if ((rc == RTEMS_SUCCESSFUL) &&
+      (trm_char_info == NULL)) {
+    rc = RTEMS_INVALID_ADDRESS;
+  }
+  /*
+   * transfer max_idl
+   */
+  if (rc == RTEMS_SUCCESSFUL) {
+    if (trm_char_info->max_idl >= 0x10000) {
+      printf("ioctl called: invalid number for maxidl\n");
+      rc = RTEMS_INVALID_NUMBER;
+    }
+    else if (trm_char_info->max_idl > 0) {
+      CHN_PARAM_SET(minor,un.uart.max_idl ,trm_char_info->max_idl);
+    }
+    else if (trm_char_info->max_idl == 0) {
+      CHN_PARAM_SET(minor,un.uart.max_idl ,MAX_IDL_DEFAULT);
+    }
+  }
+  /*
+   * transfer characters 
+   */
+  if (rc == RTEMS_SUCCESSFUL) {
+    if (trm_char_info->char_cnt > CON8XX_TRM_CHAR_CNT) {
+      printf("ioctl called: invalid number for char_cnt\n");
+      rc = RTEMS_TOO_MANY;
+    }
+    else if (trm_char_info->char_cnt >= 0) {
+      /*
+       * check, whether device is a SCC
+       */
+      if ((rc == RTEMS_SUCCESSFUL) && 
+	  !m8xx_console_chan_desc[minor].is_scc) {
+	printf("ioctl called: not an scc:%d\n",minor);
+	rc = RTEMS_UNSATISFIED;
+      }
+      else {
+	int idx = 0;
+	for(idx = 0;idx < trm_char_info->char_cnt;idx++) {
+	  m8xx_console_chan_desc[minor].parms.sccp->un.uart.character[idx] =
+	    trm_char_info->character[idx] & 0x00ff;
+	}
+	if (trm_char_info->char_cnt < CON8XX_TRM_CHAR_CNT) {
+	  m8xx_console_chan_desc[minor].parms.sccp
+	    ->un.uart.character[trm_char_info->char_cnt] = 0x8000;
+	}
+      }
+    }
+  }
+
+  printf("ioctl called: return code: %d\n",rc);
+  return rc;
+}
+#endif
+
+/*
+ * Handle ioctl request.
+ */
+rtems_device_driver console_control(
+				    rtems_device_major_number major,
+				    rtems_device_minor_number minor,
+				    void                    * arg
+				    )
+{ 
+  rtems_libio_ioctl_args_t *ioa=arg;
+
+  switch (ioa->command) {
+#if 0
+  case CON8XX_IO_SET_TRM_CHAR:
+    return scc_io_set_trm_char(minor, ioa);
+#endif    
+  default:
+    return rtems_termios_ioctl (arg);
+    break;
+  }
+}
+
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/8xx_immap.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/8xx_immap.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/8xx_immap.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,477 @@
+/*===============================================================*\
+| Project: RTEMS BSP support for TQ modules                       |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains definitions to interact with TQC's           |
+|  processor modules                                              |
+\*===============================================================*/
+/* derived from mbx8xx BSP */
+/*
+ * MPC8xx Internal Memory Map
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * The I/O on the MPC860 is comprised of blocks of special registers
+ * and the dual port ram for the Communication Processor Module.
+ * Within this space are functional units such as the SIU, memory
+ * controller, system timers, and other control functions.  It is
+ * a combination that I found difficult to separate into logical
+ * functional files.....but anyone else is welcome to try.  -- Dan
+ */
+#ifndef __IMMAP_8XX__
+#define __IMMAP_8XX__
+
+/* System configuration registers.
+*/
+typedef	struct sys_conf {
+	unsigned int	sc_siumcr;
+	unsigned int	sc_sypcr;
+	unsigned int	sc_swt;
+	char		res1[2];
+	unsigned short	sc_swsr;
+	unsigned int	sc_sipend;
+	unsigned int	sc_simask;
+	unsigned int	sc_siel;
+	unsigned int	sc_sivec;
+	unsigned int	sc_tesr;
+	char		res2[0xc];
+	unsigned int	sc_sdcr;
+	char		res3[0x4c];
+} sysconf8xx_t;
+
+/* PCMCIA configuration registers.
+*/
+typedef struct pcmcia_conf {
+	unsigned int	pcmc_pbr0;
+	unsigned int	pcmc_por0;
+	unsigned int	pcmc_pbr1;
+	unsigned int	pcmc_por1;
+	unsigned int	pcmc_pbr2;
+	unsigned int	pcmc_por2;
+	unsigned int	pcmc_pbr3;
+	unsigned int	pcmc_por3;
+	unsigned int	pcmc_pbr4;
+	unsigned int	pcmc_por4;
+	unsigned int	pcmc_pbr5;
+	unsigned int	pcmc_por5;
+	unsigned int	pcmc_pbr6;
+	unsigned int	pcmc_por6;
+	unsigned int	pcmc_pbr7;
+	unsigned int	pcmc_por7;
+	char		res1[0x20];
+	unsigned int	pcmc_pgcra;
+	unsigned int	pcmc_pgcrb;
+	unsigned int	pcmc_pscr;
+	char		res2[4];
+	unsigned int	pcmc_pipr;
+	char		res3[4];
+	unsigned int	pcmc_per;
+	char		res4[4];
+} pcmconf8xx_t;
+
+/* Memory controller registers.
+*/
+typedef struct	mem_ctlr {
+	unsigned int	memc_br0;
+	unsigned int	memc_or0;
+	unsigned int	memc_br1;
+	unsigned int	memc_or1;
+	unsigned int	memc_br2;
+	unsigned int	memc_or2;
+	unsigned int	memc_br3;
+	unsigned int	memc_or3;
+	unsigned int	memc_br4;
+	unsigned int	memc_or4;
+	unsigned int	memc_br5;
+	unsigned int	memc_or5;
+	unsigned int	memc_br6;
+	unsigned int	memc_or6;
+	unsigned int	memc_br7;
+	unsigned int	memc_or7;
+	char		res1[0x24];
+	unsigned int	memc_mar;
+	unsigned int	memc_mcr;
+	char		res2[4];
+	unsigned int	memc_mamr;
+	unsigned int	memc_mbmr;
+	unsigned short	memc_mstat;
+	unsigned short	memc_mptpr;
+	unsigned int	memc_mdr;
+	char		res3[0x80];
+} memctl8xx_t;
+
+/* System Integration Timers.
+*/
+typedef struct	sys_int_timers {
+	unsigned short	sit_tbscr;
+	unsigned int	sit_tbreff0;
+	unsigned int	sit_tbreff1;
+	char		res1[0x14];
+	unsigned short	sit_rtcsc;
+	unsigned int	sit_rtc;
+	unsigned int	sit_rtsec;
+	unsigned int	sit_rtcal;
+	char		res2[0x10];
+	unsigned short	sit_piscr;
+	char		res3[2];
+	unsigned int	sit_pitc;
+	unsigned int	sit_pitr;
+	char		res4[0x34];
+} sit8xx_t;
+
+#define TBSCR_TBIRQ_MASK	((unsigned short)0xff00)
+#define TBSCR_REFA		((unsigned short)0x0080)
+#define TBSCR_REFB		((unsigned short)0x0040)
+#define TBSCR_REFAE		((unsigned short)0x0008)
+#define TBSCR_REFBE		((unsigned short)0x0004)
+#define TBSCR_TBF		((unsigned short)0x0002)
+#define TBSCR_TBE		((unsigned short)0x0001)
+
+#define RTCSC_RTCIRQ_MASK	((unsigned short)0xff00)
+#define RTCSC_SEC		((unsigned short)0x0080)
+#define RTCSC_ALR		((unsigned short)0x0040)
+#define RTCSC_38K		((unsigned short)0x0010)
+#define RTCSC_SIE		((unsigned short)0x0008)
+#define RTCSC_ALE		((unsigned short)0x0004)
+#define RTCSC_RTF		((unsigned short)0x0002)
+#define RTCSC_RTE		((unsigned short)0x0001)
+
+#define PISCR_PIRQ_MASK		((unsigned short)0xff00)
+#define PISCR_PS		((unsigned short)0x0080)
+#define PISCR_PIE		((unsigned short)0x0004)
+#define PISCR_PTF		((unsigned short)0x0002)
+#define PISCR_PTE		((unsigned short)0x0001)
+
+/* Clocks and Reset.
+*/
+typedef struct clk_and_reset {
+	unsigned int	car_sccr;
+	unsigned int	car_plprcr;
+	unsigned int	car_rsr;
+	char		res[0x74];        /* Reserved area                  */
+} car8xx_t;
+
+/* System Integration Timers keys.
+*/
+typedef struct sitk {
+	unsigned int	sitk_tbscrk;
+	unsigned int	sitk_tbreff0k;
+	unsigned int	sitk_tbreff1k;
+	unsigned int	sitk_tbk;
+	char		res1[0x10];
+	unsigned int	sitk_rtcsck;
+	unsigned int	sitk_rtck;
+	unsigned int	sitk_rtseck;
+	unsigned int	sitk_rtcalk;
+	char		res2[0x10];
+	unsigned int	sitk_piscrk;
+	unsigned int	sitk_pitck;
+	char		res3[0x38];
+} sitk8xx_t;
+
+/* Clocks and reset keys.
+*/
+typedef struct cark {
+	unsigned int	cark_sccrk;
+	unsigned int	cark_plprcrk;
+	unsigned int	cark_rsrk;
+	char		res[0x474];
+} cark8xx_t;
+
+/* The key to unlock registers maintained by keep-alive power.
+*/
+#define KAPWR_KEY	((unsigned int)0x55ccaa33)
+
+/* LCD interface.  MPC821 Only.
+*/
+typedef struct lcd {
+	unsigned short	lcd_lcolr[16];
+	char		res[0x20];
+	unsigned int	lcd_lccr;
+	unsigned int	lcd_lchcr;
+	unsigned int	lcd_lcvcr;
+	char		res2[4];
+	unsigned int	lcd_lcfaa;
+	unsigned int	lcd_lcfba;
+	char		lcd_lcsr;
+	char		res3[0x7];
+} lcd8xx_t;
+
+/* I2C
+*/
+typedef struct i2c {
+	unsigned char	i2c_i2mod;
+	char		res1[3];
+	unsigned char	i2c_i2add;
+	char		res2[3];
+	unsigned char	i2c_i2brg;
+	char		res3[3];
+	unsigned char	i2c_i2com;
+	char		res4[3];
+	unsigned char	i2c_i2cer;
+	char		res5[3];
+	unsigned char	i2c_i2cmr;
+	char		res6[0x8b];
+} i2c8xx_t;
+
+/* DMA control/status registers.
+*/
+typedef struct sdma_csr {
+	char		res1[4];
+	unsigned int	sdma_sdar;
+	unsigned char	sdma_sdsr;
+	char		res3[3];
+	unsigned char	sdma_sdmr;
+	char		res4[3];
+	unsigned char	sdma_idsr1;
+	char		res5[3];
+	unsigned char	sdma_idmr1;
+	char		res6[3];
+	unsigned char	sdma_idsr2;
+	char		res7[3];
+	unsigned char	sdma_idmr2;
+	char		res8[0x13];
+} sdma8xx_t;
+
+/* Communication Processor Module Interrupt Controller.
+*/
+typedef struct cpm_ic {
+	unsigned short	cpic_civr;
+	char		res[0xe];
+	unsigned int	cpic_cicr;
+	unsigned int	cpic_cipr;
+	unsigned int	cpic_cimr;
+	unsigned int	cpic_cisr;
+} cpic8xx_t;
+
+/* Input/Output Port control/status registers.
+*/
+typedef struct io_port {
+	unsigned short	iop_padir;
+	unsigned short	iop_papar;
+	unsigned short	iop_paodr;
+	unsigned short	iop_padat;
+	char		res1[8];
+	unsigned short	iop_pcdir;
+	unsigned short	iop_pcpar;
+	unsigned short	iop_pcso;
+	unsigned short	iop_pcdat;
+	unsigned short	iop_pcint;
+	char		res2[6];
+	unsigned short	iop_pddir;
+	unsigned short	iop_pdpar;
+	char		res3[2];
+	unsigned short	iop_pddat;
+	char		res4[8];
+} iop8xx_t;
+
+/* Communication Processor Module Timers
+*/
+typedef struct cpm_timers {
+	unsigned short	cpmt_tgcr;
+	char		res1[0xe];
+	unsigned short	cpmt_tmr1;
+	unsigned short	cpmt_tmr2;
+	unsigned short	cpmt_trr1;
+	unsigned short	cpmt_trr2;
+	unsigned short	cpmt_tcr1;
+	unsigned short	cpmt_tcr2;
+	unsigned short	cpmt_tcn1;
+	unsigned short	cpmt_tcn2;
+	unsigned short	cpmt_tmr3;
+	unsigned short	cpmt_tmr4;
+	unsigned short	cpmt_trr3;
+	unsigned short	cpmt_trr4;
+	unsigned short	cpmt_tcr3;
+	unsigned short	cpmt_tcr4;
+	unsigned short	cpmt_tcn3;
+	unsigned short	cpmt_tcn4;
+	unsigned short	cpmt_ter1;
+	unsigned short	cpmt_ter2;
+	unsigned short	cpmt_ter3;
+	unsigned short	cpmt_ter4;
+	char		res2[8];
+} cpmtimer8xx_t;
+
+/* Finally, the Communication Processor stuff.....
+*/
+typedef struct scc {		/* Serial communication channels */
+	unsigned int	scc_gsmrl;
+	unsigned int	scc_gsmrh;
+	unsigned short	scc_pmsr;
+	char		res1[2];
+	unsigned short	scc_todr;
+	unsigned short	scc_dsr;
+	unsigned short	scc_scce;
+	char		res2[2];
+	unsigned short	scc_sccm;
+	char		res3;
+	unsigned char	scc_sccs;
+	char		res4[8];
+} scc_t;
+
+typedef struct smc {		/* Serial management channels */
+	char		res1[2];
+	unsigned short	smc_smcmr;
+	char		res2[2];
+	unsigned char	smc_smce;
+	char		res3[3];
+	unsigned char	smc_smcm;
+	char		res4[5];
+} smc_t;
+
+/* MPC860T Fast Ethernet Controller.  It isn't part of the CPM, but
+ * it fits within the address space.
+ */
+typedef struct fec {
+	unsigned int	fec_addr_low;		/* LS 32 bits of station address */
+	unsigned short	fec_addr_high;		/* MS 16 bits of address */
+	unsigned short	res1;
+	unsigned int	fec_hash_table_high;
+	unsigned int	fec_hash_table_low;
+	unsigned int	fec_r_des_start;
+	unsigned int	fec_x_des_start;
+	unsigned int	fec_r_buff_size;
+	unsigned int	res2[9];
+	unsigned int	fec_ecntrl;
+	unsigned int	fec_ievent;
+	unsigned int	fec_imask;
+	unsigned int	fec_ivec;
+	unsigned int	fec_r_des_active;
+	unsigned int	fec_x_des_active;
+	unsigned int	res3[10];
+	unsigned int	fec_mii_data;
+	unsigned int	fec_mii_speed;
+	unsigned int	res4[17];
+	unsigned int	fec_r_bound;
+	unsigned int	fec_r_fstart;
+	unsigned int	res5[6];
+	unsigned int	fec_x_fstart;
+	unsigned int	res6[17];
+	unsigned int	fec_fun_code;
+	unsigned int	res7[3];
+	unsigned int	fec_r_cntrl;
+	unsigned int	fec_r_hash;
+	unsigned int	res8[14];
+	unsigned int	fec_x_cntrl;
+	unsigned int	res9[0x1e];
+} fec_t;
+
+typedef struct comm_proc {
+	/* General control and status registers.
+	*/
+	unsigned short	cp_cpcr;
+	char		res1[2];
+	unsigned short	cp_rccr;
+	char		res2[6];
+	unsigned short	cp_cpmcr1;
+	unsigned short	cp_cpmcr2;
+	unsigned short	cp_cpmcr3;
+	unsigned short	cp_cpmcr4;
+	char		res3[2];
+	unsigned short	cp_rter;
+	char		res4[2];
+	unsigned short	cp_rtmr;
+	char		res5[0x14];
+
+	/* Baud rate generators.
+	*/
+	unsigned int	cp_brgc1;
+	unsigned int	cp_brgc2;
+	unsigned int	cp_brgc3;
+	unsigned int	cp_brgc4;
+
+	/* Serial Communication Channels.
+	*/
+	scc_t	cp_scc[4];
+
+	/* Serial Management Channels.
+	*/
+	smc_t	cp_smc[2];
+
+	/* Serial Peripheral Interface.
+	*/
+	unsigned short	cp_spmode;
+	char		res6[4];
+	unsigned char	cp_spie;
+	char		res7[3];
+	unsigned char	cp_spim;
+	char		res8[2];
+	unsigned char	cp_spcom;
+	char		res9[2];
+
+	/* Parallel Interface Port.
+	*/
+	char		res10[2];
+	unsigned short	cp_pipc;
+	char		res11[2];
+	unsigned short	cp_ptpr;
+	unsigned int	cp_pbdir;
+	unsigned int	cp_pbpar;
+	char		res12[2];
+	unsigned short	cp_pbodr;
+	unsigned int	cp_pbdat;
+	char		res13[0x18];
+
+	/* Serial Interface and Time Slot Assignment.
+	*/
+	unsigned int	cp_simode;
+	unsigned char	cp_sigmr;
+	char		res14;
+	unsigned char	cp_sistr;
+	unsigned char	cp_sicmr;
+	char		res15[4];
+	unsigned int	cp_sicr;
+	unsigned int	cp_sirp;
+	char		res16[0x10c];
+	unsigned char	cp_siram[0x200];
+
+	/* The fast ethernet controller is not really part of the CPM,
+	 * but it resides in the address space.
+	 */
+	fec_t		cp_fec;
+	char		res18[0x1000];
+
+	/* Dual Ported RAM follows.
+	 * There are many different formats for this memory area
+	 * depending upon the devices used and options chosen.
+	 */
+	unsigned char	cp_dpmem[0x1000];	/* BD / Data / ucode */
+	unsigned char	res19[0xc00];
+	unsigned char	cp_dparam[0x400];	/* Parameter RAM */
+} cpm8xx_t;
+
+/* Internal memory map.
+*/
+typedef struct immap {
+	sysconf8xx_t	im_siu_conf;	/* SIU Configuration */
+	pcmconf8xx_t	im_pcmcia;	/* PCMCIA Configuration */
+	memctl8xx_t	im_memctl;	/* Memory Controller */
+	sit8xx_t	im_sit;		/* System integration timers */
+	car8xx_t	im_clkrst;	/* Clocks and reset */
+	sitk8xx_t	im_sitk;	/* Sys int timer keys */
+	cark8xx_t	im_clkrstk;	/* Clocks and reset keys */
+	lcd8xx_t	im_lcd;		/* LCD (821 only) */
+	i2c8xx_t	im_i2c;		/* I2C control/status */
+	sdma8xx_t	im_sdma;	/* SDMA control/status */
+	cpic8xx_t	im_cpic;	/* CPM Interrupt Controller */
+	iop8xx_t	im_ioport;	/* IO Port control/status */
+	cpmtimer8xx_t	im_cpmtimer;	/* CPM timers */
+	cpm8xx_t	im_cpm;		/* Communication processor */
+} immap_t;
+
+#endif /* __IMMAP_8XX__ */
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/bsp.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/bsp.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/bsp.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,172 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from MBX8xx BSP: */
+/*  bsp.h
+ *
+ *  This include file contains all board IO definitions.
+ *
+ *  This file includes definitions for the MBX860 and MBX821.
+ *
+ *  COPYRIGHT (c) 1989-1998.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ *  $Id$
+ */
+
+#ifndef _BSP_H
+#define _BSP_H
+
+/*
+ * indicate, that BSP is booted via TQMMon
+ */
+#define BSP_HAS_TQMMON
+
+LINKER_SYMBOL(TopRamReserved);
+
+LINKER_SYMBOL( bsp_ram_start);
+LINKER_SYMBOL( bsp_ram_end);
+LINKER_SYMBOL( bsp_ram_size);
+
+LINKER_SYMBOL( bsp_rom_start);
+LINKER_SYMBOL( bsp_rom_end);
+LINKER_SYMBOL( bsp_rom_size);
+
+LINKER_SYMBOL( bsp_section_text_start);
+LINKER_SYMBOL( bsp_section_text_end);
+LINKER_SYMBOL( bsp_section_text_size);
+
+LINKER_SYMBOL( bsp_section_data_start);
+LINKER_SYMBOL( bsp_section_data_end);
+LINKER_SYMBOL( bsp_section_data_size);
+
+LINKER_SYMBOL( bsp_section_bss_start);
+LINKER_SYMBOL( bsp_section_bss_end);
+LINKER_SYMBOL( bsp_section_bss_size);
+
+LINKER_SYMBOL( bsp_interrupt_stack_start);
+LINKER_SYMBOL( bsp_interrupt_stack_end);
+LINKER_SYMBOL( bsp_interrupt_stack_size);
+
+LINKER_SYMBOL( bsp_work_area_start);
+
+#ifndef ASM
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bspopts.h>
+
+#include <rtems.h>
+#include <rtems/console.h>
+#include <rtems/clockdrv.h>
+#include <mpc8xx.h>
+#include <mpc8xx/cpm.h>
+#include <mpc8xx/mmu.h>
+#include <mpc8xx/console.h>
+#include <bsp/vectors.h>
+#include <bsp/tqm.h>
+#include <libcpu/powerpc-utility.h> 
+
+/*
+ * Network driver configuration
+ */
+struct rtems_bsdnet_ifconfig;
+
+#if BSP_USE_NETWORK_FEC
+extern int rtems_fec_enet_driver_attach (struct rtems_bsdnet_ifconfig *config, 
+					 int attaching);
+#define RTEMS_BSP_FEC_NETWORK_DRIVER_NAME	"fec1"
+#define RTEMS_BSP_FEC_NETWORK_DRIVER_ATTACH	rtems_fec_enet_driver_attach
+#endif
+
+#if BSP_USE_NETWORK_SCC
+extern int rtems_scc_enet_driver_attach (struct rtems_bsdnet_ifconfig *config, 
+					 int attaching);
+#define RTEMS_BSP_SCC_NETWORK_DRIVER_NAME	"scc1"
+#define RTEMS_BSP_SCC_NETWORK_DRIVER_ATTACH	rtems_scc_enet_driver_attach
+#endif
+
+#if BSP_USE_NETWORK_FEC
+#define RTEMS_BSP_NETWORK_DRIVER_NAME	RTEMS_BSP_FEC_NETWORK_DRIVER_NAME	
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH	RTEMS_BSP_FEC_NETWORK_DRIVER_ATTACH	
+#elif BSP_USE_NETWORK_SCC
+#define RTEMS_BSP_NETWORK_DRIVER_NAME	RTEMS_BSP_SCC_NETWORK_DRIVER_NAME	
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH	RTEMS_BSP_SCC_NETWORK_DRIVER_ATTACH	
+#endif
+/*
+ * We need to decide how much memory will be non-cacheable. This
+ * will mainly be memory that will be used in DMA (network and serial
+ * buffers).
+ */
+#define NOCACHE_MEM_SIZE 512*1024
+
+/* miscellaneous stuff assumed to exist */
+
+/*
+ *  Device Driver Table Entries
+ */
+
+/*
+ * NOTE: Use the standard Console driver entry
+ */
+
+/*
+ * NOTE: Use the standard Clock driver entry
+ */
+
+/*
+ * indicate, that BSP has IDE driver
+ */
+#undef RTEMS_BSP_HAS_IDE_DRIVER
+
+/*
+ * How many libio files we want
+ */
+
+#define BSP_LIBIO_MAX_FDS       20
+
+/*
+ * our bus frequency
+ */
+extern unsigned int BSP_bus_frequency;
+
+/* functions */
+
+void bsp_cleanup( void );
+
+rtems_isr_entry set_vector(                    /* returns old vector */
+  rtems_isr_entry     handler,                  /* isr routine        */
+  rtems_vector_number vector,                   /* vector number      */
+  int                 type                      /* RTEMS or RAW intr  */
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/coverhd.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/coverhd.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/coverhd.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,362 @@
+/*  coverhd.h
+ *
+ *  This include file has defines to represent the overhead associated
+ *  with calling a particular directive from C.  These are used in the
+ *  Timing Test Suite to ignore the overhead required to pass arguments
+ *  to directives.  On some CPUs and/or target boards, this overhead
+ *  is significant and makes it difficult to distinguish internal
+ *  RTEMS execution time from that used to call the directive.
+ *  This file should be updated after running the C overhead timing
+ *  test.  Once this update has been performed, the RTEMS Time Test
+ *  Suite should be rebuilt to account for these overhead times in the
+ *  timing results.
+ *
+ *  NOTE:  If these are all zero, then the times reported include
+ *         all calling overhead including passing of arguments.
+ *
+ *  COPYRIGHT (c) 1989-1998.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ *  $Id$
+ */
+
+#ifndef __COVERHD_h
+#define __COVERHD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
+#if defined( INSTRUCTION_CACHE_ENABLE )
+/*
+ * 50 MHz processor, cache enabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE      0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE        0
+#define CALLING_OVERHEAD_TASK_CREATE               1
+#define CALLING_OVERHEAD_TASK_IDENT                0
+#define CALLING_OVERHEAD_TASK_START                0
+#define CALLING_OVERHEAD_TASK_RESTART              0
+#define CALLING_OVERHEAD_TASK_DELETE               0
+#define CALLING_OVERHEAD_TASK_SUSPEND              0
+#define CALLING_OVERHEAD_TASK_RESUME               0
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY         0
+#define CALLING_OVERHEAD_TASK_MODE                 0
+#define CALLING_OVERHEAD_TASK_GET_NOTE             0
+#define CALLING_OVERHEAD_TASK_SET_NOTE             0
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN            1
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER           0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH           0
+#define CALLING_OVERHEAD_CLOCK_GET                 1
+#define CALLING_OVERHEAD_CLOCK_SET                 1
+#define CALLING_OVERHEAD_CLOCK_TICK                0
+
+#define CALLING_OVERHEAD_TIMER_CREATE              0
+#define CALLING_OVERHEAD_TIMER_IDENT               0
+#define CALLING_OVERHEAD_TIMER_DELETE              0
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER          0
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN           1
+#define CALLING_OVERHEAD_TIMER_RESET               0
+#define CALLING_OVERHEAD_TIMER_CANCEL              0
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE          0
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT           0
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE          0
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN          0
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE         0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT       0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND        0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST   0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE     0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH       0
+
+#define CALLING_OVERHEAD_EVENT_SEND                0
+#define CALLING_OVERHEAD_EVENT_RECEIVE             0
+#define CALLING_OVERHEAD_SIGNAL_CATCH              0
+#define CALLING_OVERHEAD_SIGNAL_SEND               0
+#define CALLING_OVERHEAD_PARTITION_CREATE          1
+#define CALLING_OVERHEAD_PARTITION_IDENT           0
+#define CALLING_OVERHEAD_PARTITION_DELETE          0
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER      0
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER   0
+#define CALLING_OVERHEAD_REGION_CREATE             1
+#define CALLING_OVERHEAD_REGION_IDENT              0
+#define CALLING_OVERHEAD_REGION_DELETE             0
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT        0
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT     0
+#define CALLING_OVERHEAD_PORT_CREATE               0
+#define CALLING_OVERHEAD_PORT_IDENT                0
+#define CALLING_OVERHEAD_PORT_DELETE               0
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
+
+#define CALLING_OVERHEAD_IO_INITIALIZE             0
+#define CALLING_OVERHEAD_IO_OPEN                   0
+#define CALLING_OVERHEAD_IO_CLOSE                  0
+#define CALLING_OVERHEAD_IO_READ                   0
+#define CALLING_OVERHEAD_IO_WRITE                  0
+#define CALLING_OVERHEAD_IO_CONTROL                0
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD     0
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE  0
+
+#else
+/*
+ * 50 MHz processor, cache disabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE      4
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE        4
+#define CALLING_OVERHEAD_TASK_CREATE               7
+#define CALLING_OVERHEAD_TASK_IDENT                6
+#define CALLING_OVERHEAD_TASK_START                5
+#define CALLING_OVERHEAD_TASK_RESTART              5
+#define CALLING_OVERHEAD_TASK_DELETE               4
+#define CALLING_OVERHEAD_TASK_SUSPEND              4
+#define CALLING_OVERHEAD_TASK_RESUME               4
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY         5
+#define CALLING_OVERHEAD_TASK_MODE                 5
+#define CALLING_OVERHEAD_TASK_GET_NOTE             5
+#define CALLING_OVERHEAD_TASK_SET_NOTE             5
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN           19
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER           4
+#define CALLING_OVERHEAD_INTERRUPT_CATCH           5
+#define CALLING_OVERHEAD_CLOCK_GET                20
+#define CALLING_OVERHEAD_CLOCK_SET                19
+#define CALLING_OVERHEAD_CLOCK_TICK                3
+
+#define CALLING_OVERHEAD_TIMER_CREATE              5
+#define CALLING_OVERHEAD_TIMER_IDENT               4
+#define CALLING_OVERHEAD_TIMER_DELETE              5
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER          6
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN          21
+#define CALLING_OVERHEAD_TIMER_RESET               4
+#define CALLING_OVERHEAD_TIMER_CANCEL              4
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE          6
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT           4
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE          6
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN          5
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE         4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE      6
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT       6
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE      4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND        5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT      5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST   5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE     6
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH       5
+
+#define CALLING_OVERHEAD_EVENT_SEND                5
+#define CALLING_OVERHEAD_EVENT_RECEIVE             5
+#define CALLING_OVERHEAD_SIGNAL_CATCH              4
+#define CALLING_OVERHEAD_SIGNAL_SEND               5
+#define CALLING_OVERHEAD_PARTITION_CREATE          7
+#define CALLING_OVERHEAD_PARTITION_IDENT           6
+#define CALLING_OVERHEAD_PARTITION_DELETE          4
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER      5
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER   5
+#define CALLING_OVERHEAD_REGION_CREATE             7
+#define CALLING_OVERHEAD_REGION_IDENT              5
+#define CALLING_OVERHEAD_REGION_DELETE             4
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT        6
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT     5
+#define CALLING_OVERHEAD_PORT_CREATE               6
+#define CALLING_OVERHEAD_PORT_IDENT                5
+#define CALLING_OVERHEAD_PORT_DELETE               4
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 6
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 6
+
+#define CALLING_OVERHEAD_IO_INITIALIZE             6
+#define CALLING_OVERHEAD_IO_OPEN                   6
+#define CALLING_OVERHEAD_IO_CLOSE                  6
+#define CALLING_OVERHEAD_IO_READ                   6
+#define CALLING_OVERHEAD_IO_WRITE                  6
+#define CALLING_OVERHEAD_IO_CONTROL                6
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED      4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE     5
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT      5
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE     4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL     4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD     5
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE  3
+
+#endif /* defined( INSTRUCTION_CACHE_ENABLE ) */
+
+#else
+#if defined( INSTRUCTION_CACHE_ENABLE )
+/*
+ * 40 MHz processor, cache enabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE      0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE        1
+#define CALLING_OVERHEAD_TASK_CREATE               1
+#define CALLING_OVERHEAD_TASK_IDENT                0
+#define CALLING_OVERHEAD_TASK_START                0
+#define CALLING_OVERHEAD_TASK_RESTART              0
+#define CALLING_OVERHEAD_TASK_DELETE               0
+#define CALLING_OVERHEAD_TASK_SUSPEND              0
+#define CALLING_OVERHEAD_TASK_RESUME               0
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY         0
+#define CALLING_OVERHEAD_TASK_MODE                 0
+#define CALLING_OVERHEAD_TASK_GET_NOTE             0
+#define CALLING_OVERHEAD_TASK_SET_NOTE             0
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN            1
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER           0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH           0
+#define CALLING_OVERHEAD_CLOCK_GET                 1
+#define CALLING_OVERHEAD_CLOCK_SET                 1
+#define CALLING_OVERHEAD_CLOCK_TICK                0
+
+#define CALLING_OVERHEAD_TIMER_CREATE              0
+#define CALLING_OVERHEAD_TIMER_IDENT               0
+#define CALLING_OVERHEAD_TIMER_DELETE              0
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER          0
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN           1
+#define CALLING_OVERHEAD_TIMER_RESET               0
+#define CALLING_OVERHEAD_TIMER_CANCEL              0
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE          0
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT           0
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE          0
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN          0
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE         0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT       0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND        0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST   0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE     0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH       0
+
+#define CALLING_OVERHEAD_EVENT_SEND                0
+#define CALLING_OVERHEAD_EVENT_RECEIVE             0
+#define CALLING_OVERHEAD_SIGNAL_CATCH              0
+#define CALLING_OVERHEAD_SIGNAL_SEND               0
+#define CALLING_OVERHEAD_PARTITION_CREATE          1
+#define CALLING_OVERHEAD_PARTITION_IDENT           0
+#define CALLING_OVERHEAD_PARTITION_DELETE          0
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER      0
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER   0
+#define CALLING_OVERHEAD_REGION_CREATE             1
+#define CALLING_OVERHEAD_REGION_IDENT              0
+#define CALLING_OVERHEAD_REGION_DELETE             0
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT        0
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT     0
+#define CALLING_OVERHEAD_PORT_CREATE               2
+#define CALLING_OVERHEAD_PORT_IDENT                0
+#define CALLING_OVERHEAD_PORT_DELETE               0
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
+
+#define CALLING_OVERHEAD_IO_INITIALIZE             0
+#define CALLING_OVERHEAD_IO_OPEN                   0
+#define CALLING_OVERHEAD_IO_CLOSE                  0
+#define CALLING_OVERHEAD_IO_READ                   0
+#define CALLING_OVERHEAD_IO_WRITE                  0
+#define CALLING_OVERHEAD_IO_CONTROL                0
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD     0
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE  0
+
+#else
+/*
+ * 40 MHz processor, cache disabled.
+ */
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE      4
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE        3
+#define CALLING_OVERHEAD_TASK_CREATE               6
+#define CALLING_OVERHEAD_TASK_IDENT                5
+#define CALLING_OVERHEAD_TASK_START                5
+#define CALLING_OVERHEAD_TASK_RESTART              4
+#define CALLING_OVERHEAD_TASK_DELETE               4
+#define CALLING_OVERHEAD_TASK_SUSPEND              4
+#define CALLING_OVERHEAD_TASK_RESUME               4
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY         5
+#define CALLING_OVERHEAD_TASK_MODE                 4
+#define CALLING_OVERHEAD_TASK_GET_NOTE             5
+#define CALLING_OVERHEAD_TASK_SET_NOTE             5
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN           17
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER           3
+#define CALLING_OVERHEAD_INTERRUPT_CATCH           5
+#define CALLING_OVERHEAD_CLOCK_GET                17
+#define CALLING_OVERHEAD_CLOCK_SET                17
+#define CALLING_OVERHEAD_CLOCK_TICK                3
+
+#define CALLING_OVERHEAD_TIMER_CREATE              4
+#define CALLING_OVERHEAD_TIMER_IDENT               4
+#define CALLING_OVERHEAD_TIMER_DELETE              5
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER          5
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN          19
+#define CALLING_OVERHEAD_TIMER_RESET               4
+#define CALLING_OVERHEAD_TIMER_CANCEL              4
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE          6
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT           4
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE          5
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN          5
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE         4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE      5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT       5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE      4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND        4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT      4
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST   5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE     5
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH       4
+
+#define CALLING_OVERHEAD_EVENT_SEND                5
+#define CALLING_OVERHEAD_EVENT_RECEIVE             5
+#define CALLING_OVERHEAD_SIGNAL_CATCH              4
+#define CALLING_OVERHEAD_SIGNAL_SEND               4
+#define CALLING_OVERHEAD_PARTITION_CREATE          6
+#define CALLING_OVERHEAD_PARTITION_IDENT           5
+#define CALLING_OVERHEAD_PARTITION_DELETE          4
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER      5
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER   5
+#define CALLING_OVERHEAD_REGION_CREATE             6
+#define CALLING_OVERHEAD_REGION_IDENT              5
+#define CALLING_OVERHEAD_REGION_DELETE             4
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT        6
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT     5
+#define CALLING_OVERHEAD_PORT_CREATE               6
+#define CALLING_OVERHEAD_PORT_IDENT                5
+#define CALLING_OVERHEAD_PORT_DELETE               4
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 5
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 5
+
+#define CALLING_OVERHEAD_IO_INITIALIZE             5
+#define CALLING_OVERHEAD_IO_OPEN                   5
+#define CALLING_OVERHEAD_IO_CLOSE                  5
+#define CALLING_OVERHEAD_IO_READ                   5
+#define CALLING_OVERHEAD_IO_WRITE                  5
+#define CALLING_OVERHEAD_IO_CONTROL                5
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED      3
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE     4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT      5
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE     4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL     4
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD     4
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE  3
+
+#endif /* defined( INSTRUCTION_CACHE_ENABLE ) */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/irq-config.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/irq-config.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/irq-config.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,101 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief BSP interrupt support configuration.
+ */
+
+/*
+ * Copyright (c) 2008
+ * Embedded Brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * rtems@embedded-brains.de
+ *
+ * The license and distribution terms for this file may be found in the file
+ * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef LIBBSP_POWERPC_TQM8XX_IRQ_CONFIG_H
+#define LIBBSP_POWERPC_TQM8XX_IRQ_CONFIG_H
+
+#include <stdint.h>
+
+#include <bsp/irq.h>
+
+/**
+ * @addtogroup bsp_interrupt
+ *
+ * @{
+ */
+
+/**
+ * @brief Minimum vector number.
+ */
+#define BSP_INTERRUPT_VECTOR_MIN BSP_LOWEST_OFFSET
+
+/**
+ * @brief Maximum vector number.
+ */
+#define BSP_INTERRUPT_VECTOR_MAX BSP_MAX_OFFSET
+
+/**
+ * @brief Enables the index table.
+ *
+ * If you enable the index table, you have to define a size for the handler
+ * table (@ref BSP_INTERRUPT_HANDLER_TABLE_SIZE) and must provide an integer
+ * type capable to index the complete handler table (@ref
+ * bsp_interrupt_handler_index_type).
+ */
+#undef BSP_INTERRUPT_USE_INDEX_TABLE
+
+/**
+ * @brief Disables usage of the heap.
+ *
+ * If you define this, you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as
+ * well.
+ */
+#undef BSP_INTERRUPT_NO_HEAP_USAGE
+
+#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
+
+/**
+ * @brief Size of the handler table.
+ */
+#define BSP_INTERRUPT_HANDLER_TABLE_SIZE 63
+
+/**
+ * @brief Integer type capable to index the complete handler table.
+ */
+typedef uint8_t bsp_interrupt_handler_index_type;
+
+#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
+
+/** @} */
+
+#endif /* LIBBSP_POWERPC_TQM8XX_IRQ_CONFIG_H */
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/irq.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/irq.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/irq.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,154 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+#ifndef TQM8xx_IRQ_IRQ_H
+#define TQM8xx_IRQ_IRQ_H
+
+#include <stdbool.h>
+
+#include <rtems.h>
+#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
+
+/*
+ * the following definitions specify the indices used 
+ * to interface the interrupt handler API
+ */
+
+/*
+ * Peripheral IRQ handlers related definitions
+ */
+#define BSP_SIU_PER_IRQ_NUMBER	 16
+#define BSP_SIU_IRQ_LOWEST_OFFSET 0
+#define BSP_SIU_IRQ_MAX_OFFSET   (BSP_SIU_IRQ_LOWEST_OFFSET\
+                                  +BSP_SIU_PER_IRQ_NUMBER-1)
+
+#define BSP_IS_SIU_IRQ(irqnum)				\
+          (((irqnum) >= BSP_SIU_IRQ_LOWEST_OFFSET) &&	\
+	   ((irqnum) <= BSP_SIU_IRQ_MAX_OFFSET))
+
+#define BSP_CPM_PER_IRQ_NUMBER	 32
+#define BSP_CPM_IRQ_LOWEST_OFFSET (BSP_SIU_IRQ_MAX_OFFSET+1)
+#define BSP_CPM_IRQ_MAX_OFFSET   (BSP_CPM_IRQ_LOWEST_OFFSET\
+                                  +BSP_CPM_PER_IRQ_NUMBER-1)
+
+#define BSP_IS_CPM_IRQ(irqnum)				\
+          (((irqnum) >= BSP_CPM_IRQ_LOWEST_OFFSET) &&	\
+	   ((irqnum) <= BSP_CPM_IRQ_MAX_OFFSET))
+/*
+ * Processor IRQ handlers related definitions
+ */
+#define BSP_PROCESSOR_IRQ_NUMBER        1
+#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET	(BSP_CPM_IRQ_MAX_OFFSET+1)
+#define BSP_PROCESSOR_IRQ_MAX_OFFSET	(BSP_PROCESSOR_IRQ_LOWEST_OFFSET\
+                                         +BSP_PROCESSOR_IRQ_NUMBER-1)
+
+#define BSP_IS_PROCESSOR_IRQ(irqnum)				\
+          (((irqnum) >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET) &&	\
+	   ((irqnum) <= BSP_PROCESSOR_IRQ_MAX_OFFSET))
+/*
+ * Summary
+ */
+#define BSP_IRQ_NUMBER                  (BSP_PROCESSOR_IRQ_MAX_OFFSET+1)
+#define BSP_LOWEST_OFFSET		BSP_SIU_IRQ_LOWEST_OFFSET
+#define BSP_MAX_OFFSET                  BSP_PROCESSOR_IRQ_MAX_OFFSET
+
+#define BSP_IS_VALID_IRQ(irqnum) 	\
+          (BSP_IS_PROCESSOR_IRQ(irqnum)	\
+           || BSP_IS_SIU_IRQ(irqnum)    \
+           || BSP_IS_CPM_IRQ(irqnum))
+
+#ifndef ASM
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * index table for the module specific handlers, a few entries are only placeholders
+ */
+  typedef enum {
+    BSP_SIU_EXT_IRQ_0       = BSP_SIU_IRQ_LOWEST_OFFSET + 0,
+    BSP_SIU_INT_IRQ_0       = BSP_SIU_IRQ_LOWEST_OFFSET + 1,
+    BSP_SIU_EXT_IRQ_1       = BSP_SIU_IRQ_LOWEST_OFFSET + 2,
+    BSP_SIU_INT_IRQ_1       = BSP_SIU_IRQ_LOWEST_OFFSET + 3,
+    BSP_SIU_EXT_IRQ_2       = BSP_SIU_IRQ_LOWEST_OFFSET + 4,
+    BSP_SIU_INT_IRQ_2       = BSP_SIU_IRQ_LOWEST_OFFSET + 5,
+    BSP_SIU_EXT_IRQ_3       = BSP_SIU_IRQ_LOWEST_OFFSET + 6,
+    BSP_SIU_INT_IRQ_3       = BSP_SIU_IRQ_LOWEST_OFFSET + 7,
+    BSP_SIU_EXT_IRQ_4       = BSP_SIU_IRQ_LOWEST_OFFSET + 8,
+    BSP_SIU_INT_IRQ_4       = BSP_SIU_IRQ_LOWEST_OFFSET + 9,
+    BSP_SIU_EXT_IRQ_5       = BSP_SIU_IRQ_LOWEST_OFFSET + 10,
+    BSP_SIU_INT_IRQ_5       = BSP_SIU_IRQ_LOWEST_OFFSET + 11,
+    BSP_SIU_EXT_IRQ_6       = BSP_SIU_IRQ_LOWEST_OFFSET + 12,
+    BSP_SIU_INT_IRQ_6       = BSP_SIU_IRQ_LOWEST_OFFSET + 13,
+    BSP_SIU_EXT_IRQ_7       = BSP_SIU_IRQ_LOWEST_OFFSET + 14,
+    BSP_SIU_INT_IRQ_7       = BSP_SIU_IRQ_LOWEST_OFFSET + 15,
+    BSP_SIU_IRQ_LAST        = BSP_SIU_IRQ_MAX_OFFSET,
+  /*
+     * Some CPM IRQ symbolic name definition
+     */
+    BSP_CPM_IRQ_ERROR		= (BSP_CPM_IRQ_LOWEST_OFFSET),
+    BSP_CPM_IRQ_PARALLEL_IO_PC4	= (BSP_CPM_IRQ_LOWEST_OFFSET + 1),
+    BSP_CPM_IRQ_PARALLEL_IO_PC5	= (BSP_CPM_IRQ_LOWEST_OFFSET + 2),
+    BSP_CPM_IRQ_SMC2_OR_PIP	= (BSP_CPM_IRQ_LOWEST_OFFSET + 3),
+    BSP_CPM_IRQ_SMC1		= (BSP_CPM_IRQ_LOWEST_OFFSET + 4),
+    BSP_CPM_IRQ_SPI		= (BSP_CPM_IRQ_LOWEST_OFFSET + 5),
+    BSP_CPM_IRQ_PARALLEL_IO_PC6	= (BSP_CPM_IRQ_LOWEST_OFFSET + 6),
+    BSP_CPM_IRQ_TIMER_4		= (BSP_CPM_IRQ_LOWEST_OFFSET + 7),
+    BSP_CPM_IRQ_PARALLEL_IO_PC7	= (BSP_CPM_IRQ_LOWEST_OFFSET + 9),
+    BSP_CPM_IRQ_PARALLEL_IO_PC8	= (BSP_CPM_IRQ_LOWEST_OFFSET + 10),
+    BSP_CPM_IRQ_PARALLEL_IO_PC9	= (BSP_CPM_IRQ_LOWEST_OFFSET + 11),
+    BSP_CPM_IRQ_TIMER_3		= (BSP_CPM_IRQ_LOWEST_OFFSET + 12),
+    BSP_CPM_IRQ_PARALLEL_IO_PC10= (BSP_CPM_IRQ_LOWEST_OFFSET + 14),
+    BSP_CPM_IRQ_PARALLEL_IO_PC11= (BSP_CPM_IRQ_LOWEST_OFFSET + 15),
+    BSP_CPM_I2C			= (BSP_CPM_IRQ_LOWEST_OFFSET + 16),
+    BSP_CPM_RISC_TIMER_TABLE	= (BSP_CPM_IRQ_LOWEST_OFFSET + 17),
+    BSP_CPM_IRQ_TIMER_2		= (BSP_CPM_IRQ_LOWEST_OFFSET + 18),
+    BSP_CPM_IDMA2		= (BSP_CPM_IRQ_LOWEST_OFFSET + 20),
+    BSP_CPM_IDMA1		= (BSP_CPM_IRQ_LOWEST_OFFSET + 21),
+    BSP_CPM_SDMA_CHANNEL_BUS_ERR= (BSP_CPM_IRQ_LOWEST_OFFSET + 22),
+    BSP_CPM_IRQ_PARALLEL_IO_PC12= (BSP_CPM_IRQ_LOWEST_OFFSET + 23),
+    BSP_CPM_IRQ_PARALLEL_IO_PC13= (BSP_CPM_IRQ_LOWEST_OFFSET + 24),
+    BSP_CPM_IRQ_TIMER_1		= (BSP_CPM_IRQ_LOWEST_OFFSET + 25),
+    BSP_CPM_IRQ_PARALLEL_IO_PC14= (BSP_CPM_IRQ_LOWEST_OFFSET + 26),
+    BSP_CPM_IRQ_SCC4		= (BSP_CPM_IRQ_LOWEST_OFFSET + 27),
+    BSP_CPM_IRQ_SCC3		= (BSP_CPM_IRQ_LOWEST_OFFSET + 28),
+    BSP_CPM_IRQ_SCC2		= (BSP_CPM_IRQ_LOWEST_OFFSET + 29),
+    BSP_CPM_IRQ_SCC1		= (BSP_CPM_IRQ_LOWEST_OFFSET + 30),
+    BSP_CPM_IRQ_PARALLEL_IO_PC15= (BSP_CPM_IRQ_LOWEST_OFFSET + 31),
+    BSP_CPM_IRQ_LAST     = BSP_CPM_IRQ_MAX_OFFSET,
+  } rtems_irq_symbolic_name;
+
+  /*
+   * Symbolic name for CPM interrupt on SIU Internal level 2
+   */
+#define BSP_CPM_INTERRUPT	BSP_SIU_INT_IRQ_2
+#define BSP_PERIODIC_TIMER	BSP_SIU_INT_IRQ_6
+#define BSP_FAST_ETHERNET_CTRL	BSP_SIU_INT_IRQ_3
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ASM */
+
+#endif /* TQM8XX_IRQ_IRQ_H */
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/tm27.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/tm27.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/tm27.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,32 @@
+/*
+ *  tm27.h
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ *  $Id$
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+/*
+ *  Stuff for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 0
+
+#define Install_tm27_vector( handler ) /* set_vector( (handler), 0, 1 ) */
+
+#define Cause_tm27_intr() /* empty */
+
+#define Clear_tm27_intr() /* empty */
+
+#define Lower_tm27_intr() /* empty */
+
+#endif
Index: c/src/lib/libbsp/powerpc/tqm8xx/include/tqm.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/include/tqm.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/include/tqm.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,51 @@
+/*===============================================================*\
+| Project: RTEMS BSP support for TQ modules                       |
++-----------------------------------------------------------------+
+| Partially based on the code references which are named below.   |
+| Adaptions, modifications, enhancements and any recent parts of  |
+| the code are:                                                   |
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains definitions to interact with TQC's           |
+|  processor modules                                              |
+\*===============================================================*/
+
+#ifndef __TQM_H__
+#define __TQM_H__
+#include <rtems.h>
+
+typedef struct {
+  uint32_t sdram_size;  /* existing SDRAM size */
+  uint32_t flash_base;  /* start address flash */
+  uint32_t flash_size;  /* existing Flash size */
+  uint32_t flash_offset; 
+  uint32_t sram_base;   /* start address sram                */
+  uint32_t sram_size;   /* existing sram size                */
+  uint32_t immr_base;   /* start address internal memory map */
+  uint32_t reboot;      /* reboot flag                       */
+  uint8_t  ip_addr[4];  /* IP address                        */
+  uint8_t  eth_addr[6]; /* ethernet (MAC) address            */
+  uint8_t  gap_42[2];   /* gap for alignment                 */
+  void (*put_char)(int c); /* function to output characters  */
+} tqm_bd_info_t;
+
+#define TQM_BD_INFO_ADDR 0x3400
+#define TQM_BD_INFO (*(tqm_bd_info_t *)TQM_BD_INFO_ADDR)
+
+#define TQM_CONF_INFO_BLOCK_ADDR 0x4001fe00
+
+#define IMAP_ADDR		((unsigned int)0xfa200000)
+#define IMAP_SIZE		((unsigned int)(64 * 1024))
+
+#endif /* __TQM_H__ */
Index: c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,240 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+
+#include <rtems.h>
+#include <mpc8xx.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <libcpu/raw_exception.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/vectors.h>
+#include <bsp/ppc_exc_bspsupp.h>
+#include <bsp/irq-generic.h>
+/*
+ * functions to enable/disable a source at the SIU/CPM irq controller
+ */
+
+rtems_status_code bsp_irq_disable_at_SIU(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
+  m8xx.simask &= ~(1 << (31 - vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code bsp_irq_enable_at_SIU(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
+  m8xx.simask |= (1 << (31 - vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code bsp_irq_disable_at_CPM(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
+  m8xx.cimr &= ~(1 << (31 - vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code bsp_irq_enable_at_CPM(rtems_vector_number irqnum)
+{
+  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
+  m8xx.cimr |= (1 << (31 - vecnum));
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqnum)
+{
+  if (BSP_IS_CPM_IRQ(irqnum)) {
+    bsp_irq_enable_at_CPM(irqnum);
+    return RTEMS_SUCCESSFUL;
+  } 
+  else if (BSP_IS_SIU_IRQ(irqnum)) {
+    bsp_irq_enable_at_SIU(irqnum);
+    return RTEMS_SUCCESSFUL;
+  } 
+  return RTEMS_INVALID_ID;
+}
+
+rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum)
+{
+  if (BSP_IS_CPM_IRQ(irqnum)) {
+    bsp_irq_disable_at_CPM(irqnum);
+    return RTEMS_SUCCESSFUL;
+  } 
+  else if (BSP_IS_SIU_IRQ(irqnum)) {
+    bsp_irq_disable_at_SIU(irqnum);
+    return RTEMS_SUCCESSFUL;
+  } 
+  return RTEMS_INVALID_ID;
+}
+
+/*
+ *  IRQ Handler: this is called from the primary exception dispatcher
+ */
+static int BSP_irq_handle_at_cpm(void)
+{
+  int32_t  cpvecnum;
+  uint32_t msr;
+  rtems_interrupt_level level;
+
+  /* Get vector number: write IACK=1, then read vectir */
+  m8xx.civr = 1;
+  cpvecnum  = (m8xx.civr >> 11) + BSP_CPM_IRQ_LOWEST_OFFSET;
+  
+  /*
+   * Check the vector number, mask lower priority interrupts, enable
+   * exceptions and dispatch the handler.
+   */
+  if (BSP_IS_CPM_IRQ(cpvecnum)) {      
+    /* Enable all interrupts */
+    msr = ppc_external_exceptions_enable();
+    /* Dispatch interrupt handlers */
+    bsp_interrupt_handler_dispatch(cpvecnum);
+    /* Restore machine state */
+    ppc_external_exceptions_disable(msr);
+    /*
+     * clear "in-service" bit
+     */
+    m8xx.cisr = 1 << (cpvecnum - BSP_CPM_IRQ_LOWEST_OFFSET);
+  }
+  else {
+    /* not valid vector */
+    bsp_interrupt_handler_default(cpvecnum);
+  }
+  return 0;
+}
+
+static int BSP_irq_handle_at_siu( unsigned excNum)
+{
+  int32_t  sivecnum;
+  uint32_t msr;
+  rtems_interrupt_level level;
+  bool  is_cpm_irq;
+  uint32_t simask_save;
+  /*
+   * check, if interrupt is pending
+   * and repeat as long as valid interrupts are pending
+   */
+  while (0 != (m8xx.simask & m8xx.sipend)) {
+    /* Get vector number */
+    sivecnum     = (m8xx.sivec >> 26);
+    is_cpm_irq = (sivecnum == BSP_CPM_INTERRUPT);
+    /*
+     * Check the vector number, mask lower priority interrupts, enable
+     * exceptions and dispatch the handler.
+     */
+    if (BSP_IS_SIU_IRQ(sivecnum)) {      
+      simask_save = m8xx.simask;
+      /*
+       * if this is the CPM interrupt, mask lower prio interrupts at SIU
+       * else mask lower and same priority interrupts
+       */
+      m8xx.simask &= ~0 << (32 
+			    - sivecnum
+			    - ((is_cpm_irq) ? 1 : 0)); 
+    
+      if (is_cpm_irq) {
+	BSP_irq_handle_at_cpm();
+      }
+      else {
+	/* Enable all interrupts */
+	msr = ppc_external_exceptions_enable();
+	/* Dispatch interrupt handlers */
+	bsp_interrupt_handler_dispatch(sivecnum + BSP_SIU_IRQ_LOWEST_OFFSET);
+	/* Restore machine state */
+	ppc_external_exceptions_disable(msr);
+	/*
+	 * clear pending bit, if edge triggered interrupt input
+	 */
+	m8xx.sipend = 1 << (31 - sivecnum);
+      }
+      
+    
+      /* Restore initial masks */
+      m8xx.simask = simask_save;
+    } else {
+      /* not valid vector */
+      bsp_interrupt_handler_default(sivecnum);
+    }
+  }
+  return 0;
+}
+
+/*
+ * Activate the CPIC
+ */
+rtems_status_code mpc8xx_cpic_initialize( void)
+{
+  /* 
+   * mask off all interrupts 
+   */
+  m8xx.cimr   = 0;
+  /* 
+   * make sure CPIC request proper level at SIU interrupt controller
+   */
+  m8xx.cicr  = (0x00e41f00 |
+		((BSP_CPM_INTERRUPT/2) << 13));
+
+  return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Activate the SIU interrupt controller
+ */
+rtems_status_code mpc8xx_siu_int_initialize( void)
+{
+  /* 
+   * mask off all interrupts 
+   */
+  m8xx.simask = 0;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+int mpc8xx_exception_handler(BSP_Exception_frame *frame, 
+			     unsigned exception_number)
+{
+  return BSP_irq_handle_at_siu(exception_number);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize()
+{
+  /* Install exception handler */
+  if (ppc_exc_set_handler(ASM_EXT_VECTOR, mpc8xx_exception_handler)) {
+    return RTEMS_IO_ERROR;
+  }
+  /* Initialize the SIU interrupt controller */
+  if (mpc8xx_siu_int_initialize()) {
+    return RTEMS_IO_ERROR;    
+  }
+  /* Initialize the CPIC interrupt controller */
+  return mpc8xx_cpic_initialize();
+}
+
+void bsp_interrupt_handler_default( rtems_vector_number vector)
+{
+	printk( "Spurious interrupt: 0x%08x\n", vector);
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.h
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.h	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,204 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+/* irq.h
+ *
+ *  This include file describe the data structure and the functions implemented
+ *  by rtems to write interrupt handlers.
+ *
+ *  CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ *  This code is heavilly inspired by the public specification of STREAM V2
+ *  that can be found at :
+ *
+ *      <http://www.chorus.com/Documentation/index.html> by following
+ *  the STREAM API Specification Document link.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ *  $Id$
+ */
+
+#ifndef LIBBSP_POWERPC_TQM8XX_IRQ_IRQ_H
+#define LIBBSP_POWERPC_TQM8XX_IRQ_IRQ_H
+
+#include <rtems/irq.h>
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern volatile unsigned int ppc_cached_irq_mask;
+
+/*
+ * Symblolic IRQ names and related definitions.
+ */
+
+  /*
+   * SIU IRQ handler related definitions
+   */
+#define BSP_SIU_IRQ_NUMBER    		16 /* 16 reserved but in the future... */
+#define BSP_SIU_IRQ_LOWEST_OFFSET	0
+#define  BSP_SIU_IRQ_MAX_OFFSET	 	(BSP_SIU_IRQ_LOWEST_OFFSET + BSP_SIU_IRQ_NUMBER - 1)
+  /*
+   * CPM IRQ handlers related definitions
+   * CAUTION : BSP_CPM_IRQ_LOWEST_OFFSET should be equal to OPENPIC_VEC_SOURCE
+   */
+#define BSP_CPM_IRQ_NUMBER		32
+#define BSP_CPM_IRQ_LOWEST_OFFSET	(BSP_SIU_IRQ_NUMBER + BSP_SIU_IRQ_LOWEST_OFFSET)
+#define BSP_CPM_IRQ_MAX_OFFSET	 	(BSP_CPM_IRQ_LOWEST_OFFSET + BSP_CPM_IRQ_NUMBER - 1)
+  /*
+   * PowerPc exceptions handled as interrupt where a rtems managed interrupt
+   * handler might be connected
+   */
+#define BSP_PROCESSOR_IRQ_NUMBER	1
+#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET (BSP_CPM_IRQ_MAX_OFFSET + 1)
+#define BSP_PROCESSOR_IRQ_MAX_OFFSET	(BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1)
+  /*
+   * Summary
+   */
+#define BSP_IRQ_NUMBER		(BSP_PROCESSOR_IRQ_MAX_OFFSET + 1)
+#define BSP_LOWEST_OFFSET	(BSP_SIU_IRQ_LOWEST_OFFSET)
+#define BSP_MAX_OFFSET		(BSP_PROCESSOR_IRQ_MAX_OFFSET)
+    /*
+     * Some SIU IRQ symbolic name definition. Please note that
+     * INT IRQ are defined but a single one will be used to
+     * redirect all CPM interrupt.
+     */
+#define BSP_SIU_EXT_IRQ_0      	0
+#define BSP_SIU_INT_IRQ_0       1
+
+#define BSP_SIU_EXT_IRQ_1      	2
+#define BSP_SIU_INT_IRQ_1       3
+
+#define BSP_SIU_EXT_IRQ_2      	4
+#define BSP_SIU_INT_IRQ_2       5
+
+#define BSP_SIU_EXT_IRQ_3      	6
+#define BSP_SIU_INT_IRQ_3       7
+
+#define BSP_SIU_EXT_IRQ_4      	8
+#define BSP_SIU_INT_IRQ_4       9
+
+#define BSP_SIU_EXT_IRQ_5      	10
+#define BSP_SIU_INT_IRQ_5       11
+
+#define BSP_SIU_EXT_IRQ_6      	12
+#define BSP_SIU_INT_IRQ_6       13
+
+#define BSP_SIU_EXT_IRQ_7      	14
+#define BSP_SIU_INT_IRQ_7       15
+  /*
+   * Symbolic name for CPM interrupt on SIU Internal level 2
+   */
+#define BSP_CPM_INTERRUPT	BSP_SIU_INT_IRQ_2
+#define BSP_PERIODIC_TIMER	BSP_SIU_INT_IRQ_6
+#define BSP_FAST_ETHERNET_CTRL	BSP_SIU_INT_IRQ_3
+  /*
+     * Some CPM IRQ symbolic name definition
+     */
+#define BSP_CPM_IRQ_ERROR		BSP_CPM_IRQ_LOWEST_OFFSET
+#define BSP_CPM_IRQ_PARALLEL_IO_PC4	(BSP_CPM_IRQ_LOWEST_OFFSET + 1)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC5	(BSP_CPM_IRQ_LOWEST_OFFSET + 2)
+#define BSP_CPM_IRQ_SMC2_OR_PIP		(BSP_CPM_IRQ_LOWEST_OFFSET + 3)
+#define BSP_CPM_IRQ_SMC1		(BSP_CPM_IRQ_LOWEST_OFFSET + 4)
+#define BSP_CPM_IRQ_SPI			(BSP_CPM_IRQ_LOWEST_OFFSET + 5)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC6	(BSP_CPM_IRQ_LOWEST_OFFSET + 6)
+#define BSP_CPM_IRQ_TIMER_4		(BSP_CPM_IRQ_LOWEST_OFFSET + 7)
+
+#define BSP_CPM_IRQ_PARALLEL_IO_PC7	(BSP_CPM_IRQ_LOWEST_OFFSET + 9)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC8	(BSP_CPM_IRQ_LOWEST_OFFSET + 10)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC9	(BSP_CPM_IRQ_LOWEST_OFFSET + 11)
+#define BSP_CPM_IRQ_TIMER_3		(BSP_CPM_IRQ_LOWEST_OFFSET + 12)
+
+#define BSP_CPM_IRQ_PARALLEL_IO_PC10	(BSP_CPM_IRQ_LOWEST_OFFSET + 14)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC11	(BSP_CPM_IRQ_LOWEST_OFFSET + 15)
+#define BSP_CPM_I2C			(BSP_CPM_IRQ_LOWEST_OFFSET + 16)
+#define BSP_CPM_RISC_TIMER_TABLE	(BSP_CPM_IRQ_LOWEST_OFFSET + 17)
+#define BSP_CPM_IRQ_TIMER_2		(BSP_CPM_IRQ_LOWEST_OFFSET + 18)
+
+#define BSP_CPM_IDMA2			(BSP_CPM_IRQ_LOWEST_OFFSET + 20)
+#define BSP_CPM_IDMA1			(BSP_CPM_IRQ_LOWEST_OFFSET + 21)
+#define BSP_CPM_SDMA_CHANNEL_BUS_ERR	(BSP_CPM_IRQ_LOWEST_OFFSET + 22)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC12	(BSP_CPM_IRQ_LOWEST_OFFSET + 23)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC13	(BSP_CPM_IRQ_LOWEST_OFFSET + 24)
+#define BSP_CPM_IRQ_TIMER_1		(BSP_CPM_IRQ_LOWEST_OFFSET + 25)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC14	(BSP_CPM_IRQ_LOWEST_OFFSET + 26)
+#define BSP_CPM_IRQ_SCC4		(BSP_CPM_IRQ_LOWEST_OFFSET + 27)
+#define BSP_CPM_IRQ_SCC3		(BSP_CPM_IRQ_LOWEST_OFFSET + 28)
+#define BSP_CPM_IRQ_SCC2		(BSP_CPM_IRQ_LOWEST_OFFSET + 29)
+#define BSP_CPM_IRQ_SCC1		(BSP_CPM_IRQ_LOWEST_OFFSET + 30)
+#define BSP_CPM_IRQ_PARALLEL_IO_PC15	(BSP_CPM_IRQ_LOWEST_OFFSET + 31)
+    /*
+     * Some Processor exception handled as rtems IRQ symbolic name definition
+     */
+#define BSP_DECREMENTER			BSP_PROCESSOR_IRQ_LOWEST_OFFSET
+
+
+#define CPM_INTERRUPT
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+/*
+ * ------------------------ PPC SIU Mngt Routines -------
+ */
+
+/*
+ * function to disable a particular irq at 8259 level. After calling
+ * this function, even if the device asserts the interrupt line it will
+ * not be propagated further to the processor
+ */
+int BSP_irq_disable_at_siu        (const rtems_irq_number irqLine);
+/*
+ * function to enable a particular irq at 8259 level. After calling
+ * this function, if the device asserts the interrupt line it will
+ * be propagated further to the processor
+ */
+int BSP_irq_enable_at_siu		(const rtems_irq_number irqLine);
+/*
+ * function to acknoledge a particular irq at 8259 level. After calling
+ * this function, if a device asserts an enabled interrupt line it will
+ * be propagated further to the processor. Mainly usefull for people
+ * writting raw handlers as this is automagically done for rtems managed
+ * handlers.
+ */
+int BSP_irq_ack_at_siu              	(const rtems_irq_number irqLine);
+/*
+ * function to check if a particular irq is enabled at 8259 level. After calling
+ */
+int BSP_irq_enabled_at_siu     	(const rtems_irq_number irqLine);
+
+extern void BSP_rtems_irq_mng_init(unsigned cpuId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
Index: c/src/lib/libbsp/powerpc/tqm8xx/irq/irq_asm.S
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/irq/irq_asm.S	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/irq/irq_asm.S	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,433 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+/*
+ *  This file contains the assembly code for the PowerPC
+ *  IRQ veneers for RTEMS.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ *  Modified to support the MCP750.
+ *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ *  Till Straumann <strauman@slac.stanford.edu>, 2003/7:
+ *    - store isr nesting level in _ISR_Nest_level rather than
+ *      SPRG0 - RTEMS relies on that variable.
+ *  Till Straumann <strauman@slac.stanford.edu>, 2005/4:
+ *    - DONT enable FP across user ISR since fpregs are never saved!!
+ *
+ * $Id$
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+#include <bsp/vectors.h>
+#include <libcpu/raw_exception.h>
+
+#define SYNC \
+	sync; \
+	isync
+
+	.text
+	.p2align 5
+
+	PUBLIC_VAR(decrementer_exception_vector_prolog_code)
+
+SYM (decrementer_exception_vector_prolog_code):
+	/*
+	 * let room for exception frame
+	 */
+	stwu    r1, - (EXCEPTION_FRAME_END)(r1)
+	stw	r4, GPR4_OFFSET(r1)
+#ifdef THIS_CODE_LINKED_USING_FLASH_ADDR_RANGE
+	/*
+	 * save link register
+	 */
+	mflr	r4
+	stw	r4,  EXC_LR_OFFSET(r1)
+	/*
+	 * make link register contain shared_raw_irq_code_entry
+	 * address
+	 */
+	lis	r4,shared_raw_irq_code_entry@h
+	ori	r4,r4,shared_raw_irq_code_entry@l
+	mtlr	r4
+
+	li	r4, ASM_DEC_VECTOR
+	blr
+#else
+	li	r4, ASM_DEC_VECTOR
+	ba	shared_raw_irq_code_entry
+#endif
+
+	PUBLIC_VAR (decrementer_exception_vector_prolog_code_size)
+
+	decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code
+
+	PUBLIC_VAR(external_exception_vector_prolog_code)
+
+SYM (external_exception_vector_prolog_code):
+	/*
+	 * let room for exception frame
+	 */
+	stwu    r1, - (EXCEPTION_FRAME_END)(r1)
+	stw	r4, GPR4_OFFSET(r1)
+#ifdef THIS_CODE_LINKED_USING_FLASH_ADDR_RANGE
+	/*
+	 * save link register
+	 */
+	mflr	r4
+	stw	r4,  EXC_LR_OFFSET(r1)
+	/*
+	 * make link register contain shared_raw_irq_code_entry
+	 * address
+	 */
+	lis	r4,shared_raw_irq_code_entry@h
+	ori	r4,r4,shared_raw_irq_code_entry@l
+	mtlr	r4
+
+	li	r4, ASM_EXT_VECTOR
+	blr
+#else
+	li	r4, ASM_EXT_VECTOR
+	ba	shared_raw_irq_code_entry
+#endif
+
+	PUBLIC_VAR (external_exception_vector_prolog_code_size)
+
+	external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code
+
+	PUBLIC_VAR(shared_raw_irq_code_entry)
+	PUBLIC_VAR(C_dispatch_irq_handler)
+
+	.p2align 5
+SYM (shared_raw_irq_code_entry):
+	/*
+	 * Entry conditions :
+	 *	Registers already saved : R1, R4
+	 *	R1  :	points to a location with enough room for the
+	 *	        interrupt frame
+	 *	R4  :	vector number
+	 */
+	/*
+	 * Save SRR0/SRR1 As soon As possible as it is the minimal needed
+	 * to reenable exception processing
+	 */
+	stw	r0, GPR0_OFFSET(r1)
+	stw	r2, GPR2_OFFSET(r1)
+	stw	r3, GPR3_OFFSET(r1)
+
+	mfsrr0  r0
+	mfsrr1  r2
+	mfmsr	r3
+
+	stw	r0, SRR0_FRAME_OFFSET(r1)
+	stw	r2, SRR1_FRAME_OFFSET(r1)
+	/*
+	 * Enable data and instruction address translation, exception recovery
+     *
+     * also, on CPUs with FP, enable FP so that FP context can be
+     * saved and restored (using FP instructions)
+	 */
+	ori     r3, r3, MSR_RI | MSR_IR | MSR_DR
+	mtmsr   r3
+	SYNC
+	/*
+	 * Push C scratch registers on the current stack. It may
+	 * actually be the thread stack or the interrupt stack.
+	 * Anyway we have to make it in order to be able to call C/C++
+	 * functions. Depending on the nesting interrupt level, we will
+	 * switch to the right stack later.
+	 */
+	stw	r5, GPR5_OFFSET(r1)
+	stw	r6, GPR6_OFFSET(r1)
+	stw	r7, GPR7_OFFSET(r1)
+	stw	r8, GPR8_OFFSET(r1)
+	stw	r9, GPR9_OFFSET(r1)
+	stw	r10, GPR10_OFFSET(r1)
+	stw	r11, GPR11_OFFSET(r1)
+	stw	r12, GPR12_OFFSET(r1)
+	stw	r13, GPR13_OFFSET(r1)
+
+	mfcr	r5
+	mfctr	r6
+	mfxer	r7
+#ifndef THIS_CODE_LINKED_USING_FLASH_ADDR_RANGE
+	mflr	r8
+#endif
+
+	stw	r5,  EXC_CR_OFFSET(r1)
+	stw	r6,  EXC_CTR_OFFSET(r1)
+	stw	r7,  EXC_XER_OFFSET(r1)
+#ifndef THIS_CODE_LINKED_USING_FLASH_ADDR_RANGE
+	stw	r8,  EXC_LR_OFFSET(r1)
+#endif
+
+	/*
+	 * Add some non volatile registers to store information
+	 * that will be used when returning from C handler
+	 */
+	stw	r14, GPR14_OFFSET(r1)
+	stw	r15, GPR15_OFFSET(r1)
+	/*
+	 * save current stack pointer location in R14
+	 */
+	addi	r14, r1, 0
+	/*
+	 * store part of _Thread_Dispatch_disable_level address in R15
+	 */
+	addis r15,0, _Thread_Dispatch_disable_level@ha
+#if BROKEN_ISR_NEST_LEVEL
+	/*
+	 * Get current nesting level in R2
+	 */
+	mfspr	r2, SPRG0
+#else
+	/*
+	 * Retrieve current nesting level from _ISR_Nest_level
+	 */
+	lis		r7, _ISR_Nest_level@ha
+	lwz		r2, _ISR_Nest_level@l(r7)
+#endif
+	/*
+	 * Check if stack switch is necessary
+	 */
+	cmpwi	r2,0
+	bne	nested
+	mfspr	r1, SPRG1
+
+nested:
+	/*
+	 * Start Incrementing nesting level in R2
+	 */
+	addi	r2,r2,1
+	/*
+	 * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
+	 */
+	lwz	r6,_Thread_Dispatch_disable_level@l(r15)
+#if BROKEN_ISR_NEST_LEVEL
+	/*
+	 * Store new nesting level in SPRG0
+	 */
+	mtspr	SPRG0, r2
+#else
+	/* store new nesting level in _ISR_Nest_level */
+	stw		r2, _ISR_Nest_level@l(r7)
+#endif
+
+	addi	r6, r6, 1
+	mfmsr	r5
+	/*
+	 * store new _Thread_Dispatch_disable_level value
+	 */
+	stw	r6, _Thread_Dispatch_disable_level@l(r15)
+	/*
+	 * We are now running on the interrupt stack. External and decrementer
+	 * exceptions are still disabled. I see no purpose trying to optimize
+	 * further assembler code.
+	 */
+	/*
+	 * Call C exception handler for decrementer Interrupt frame is passed just
+	 * in case...
+	 */
+	addi	r3, r14, 0x8
+	bl	C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */
+	/*
+	 * start decrementing nesting level. Note : do not test result against 0
+	 * value as an easy exit condition because if interrupt nesting level > 1
+	 * then _Thread_Dispatch_disable_level > 1
+	 */
+#if BROKEN_ISR_NEST_LEVEL
+	mfspr	r2, SPRG0
+#else
+	lis		r7, _ISR_Nest_level@ha
+	lwz		r2, _ISR_Nest_level@l(r7)
+#endif
+	/*
+	 * start decrementing _Thread_Dispatch_disable_level
+	 */
+	lwz	r3,_Thread_Dispatch_disable_level@l(r15)
+	addi	r2, r2, -1	/* Continue decrementing nesting level */
+	addi	r3, r3, -1	/* Continue decrementing _Thread_Dispatch_disable_level */
+#if BROKEN_ISR_NEST_LEVEL
+	mtspr	SPRG0, r2	/* End decrementing nesting level */
+#else
+	stw		r2, _ISR_Nest_level@l(r7) /* End decrementing nesting level */
+#endif
+	stw	r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
+	cmpwi	r3, 0
+	/*
+	 * switch back to original stack (done here just optimize registers
+	 * contention. Could have been done before...)
+	 */
+	addi	r1, r14, 0
+	bne	easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
+	/*
+	 * Here we are running again on the thread system stack.
+	 * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
+	 * Interrupt are still disabled. Time to check if scheduler request to
+	 * do something with the current thread...
+	 */
+	addis	r4, 0, _Context_Switch_necessary@ha
+	lwz	r5, _Context_Switch_necessary@l(r4)
+	cmpwi	r5, 0
+	bne	switch
+
+	addis	r6, 0, _ISR_Signals_to_thread_executing@ha
+	lwz	r7, _ISR_Signals_to_thread_executing@l(r6)
+	cmpwi	r7, 0
+	li	r8, 0
+	beq	easy_exit
+	stw	r8, _ISR_Signals_to_thread_executing@l(r6)
+	/*
+	 * going to call _ThreadProcessSignalsFromIrq
+	 * Push a complete exception like frame...
+	 */
+	stmw	r16, GPR16_OFFSET(r1)
+	addi	r3, r1, 0x8
+        /*
+         * compute SP at exception entry
+         */
+        addi    r2, r1, EXCEPTION_FRAME_END
+        /*
+         * store it at the right place
+         */
+        stw     r2, GPR1_OFFSET(r1)
+	/*
+	 * Call High Level signal handling code
+	 */
+	bl	_ThreadProcessSignalsFromIrq
+	/*
+	 * start restoring exception like frame
+	 */
+	lwz	r31,  EXC_CTR_OFFSET(r1)
+	lwz	r30,  EXC_XER_OFFSET(r1)
+	lwz	r29,  EXC_CR_OFFSET(r1)
+	lwz	r28,  EXC_LR_OFFSET(r1)
+
+	mtctr	r31
+	mtxer	r30
+	mtcr	r29
+	mtlr	r28
+
+	lmw	r4, GPR4_OFFSET(r1)
+	lwz	r2, GPR2_OFFSET(r1)
+	lwz	r0, GPR0_OFFSET(r1)
+
+	/*
+	 * Disable data and instruction translation. Make path non recoverable...
+	 */
+	mfmsr	r3
+	xori	r3, r3, MSR_RI | MSR_IR | MSR_DR
+	mtmsr   r3
+	SYNC
+	/*
+	 * Restore rfi related settings
+	 */
+
+	lwz	r3, SRR1_FRAME_OFFSET(r1)
+	mtsrr1	r3
+	lwz	r3, SRR0_FRAME_OFFSET(r1)
+	mtsrr0	r3
+
+	lwz	r3, GPR3_OFFSET(r1)
+	addi 	r1,r1, EXCEPTION_FRAME_END
+	SYNC
+	rfi
+
+switch:
+#if ( PPC_HAS_FPU != 0 )
+#if ! defined( CPU_USE_DEFERRED_FP_SWITCH )
+#error missing include file???
+#endif
+	mfmsr  r4
+#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
+	/* if the executing thread has FP enabled propagate
+	 * this now so _Thread_Dispatch can save/restore the FPREGS
+	 * NOTE: it is *crucial* to disable the FPU across the
+	 *       user ISR [independent of using the 'deferred'
+	 *       strategy or not]. We don't save FP regs across
+	 *       the user ISR and hence we prefer an exception to
+	 *       be raised rather than experiencing corruption.
+	 */
+	lwz    r3, SRR1_FRAME_OFFSET(r1)
+	rlwimi r4, r3, 0, 18, 18 /* MSR_FP */
+#else
+	ori    r4, r4, MSR_FP
+#endif
+	mtmsr  r4
+#endif
+	bl	SYM (_Thread_Dispatch)
+
+easy_exit:
+	/*
+	 * start restoring interrupt frame
+	 */
+	lwz	r3,  EXC_CTR_OFFSET(r1)
+	lwz	r4,  EXC_XER_OFFSET(r1)
+	lwz	r5,  EXC_CR_OFFSET(r1)
+	lwz	r6,  EXC_LR_OFFSET(r1)
+
+	mtctr	r3
+	mtxer	r4
+	mtcr	r5
+	mtlr	r6
+
+	lwz	r15, GPR15_OFFSET(r1)
+	lwz	r14, GPR14_OFFSET(r1)
+	lwz	r13, GPR13_OFFSET(r1)
+	lwz	r12, GPR12_OFFSET(r1)
+	lwz	r11, GPR11_OFFSET(r1)
+	lwz	r10, GPR10_OFFSET(r1)
+	lwz	r9, GPR9_OFFSET(r1)
+	lwz	r8, GPR8_OFFSET(r1)
+	lwz	r7, GPR7_OFFSET(r1)
+	lwz	r6, GPR6_OFFSET(r1)
+	lwz	r5, GPR5_OFFSET(r1)
+
+	/*
+	 * Disable nested exception processing, data and instruction
+	 * translation.
+	 */
+	mfmsr	r3
+	xori	r3, r3, MSR_RI | MSR_IR | MSR_DR
+	mtmsr   r3
+	SYNC
+	/*
+	 * Restore rfi related settings
+	 */
+
+	lwz	r4, SRR1_FRAME_OFFSET(r1)
+	lwz	r2, SRR0_FRAME_OFFSET(r1)
+	lwz	r3, GPR3_OFFSET(r1)
+	lwz	r0, GPR0_OFFSET(r1)
+
+	mtsrr1	r4
+	mtsrr0	r2
+	lwz	r4, GPR4_OFFSET(r1)
+	lwz	r2, GPR2_OFFSET(r1)
+	addi 	r1,r1, EXCEPTION_FRAME_END
+	SYNC
+	rfi
Index: c/src/lib/libbsp/powerpc/tqm8xx/irq/irq_init.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/irq/irq_init.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/irq/irq_init.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,185 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: generic MPC83xx BSP */
+/* irq_init.c
+ *
+ *  This file contains the implementation of rtems initialization
+ *  related to interrupt handling.
+ *
+ *  CopyRight (C) 2001 valette@crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ *
+ *  $Id$
+ */
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/raw_exception.h>
+#include <bsp/8xx_immap.h>
+#include <bsp/mpc8xx.h>
+
+extern unsigned int external_exception_vector_prolog_code_size;
+extern void external_exception_vector_prolog_code();
+extern unsigned int decrementer_exception_vector_prolog_code_size;
+extern void decrementer_exception_vector_prolog_code();
+
+volatile unsigned int ppc_cached_irq_mask;
+
+/*
+ * default on/off function
+ */
+static void nop_func1(void *unused){}
+static void nop_func2(){}
+
+/*
+ * default isOn function
+ */
+static int not_connected() {return 0;}
+/*
+ * default possible isOn function
+ */
+static int connected() {return 1;}
+
+static rtems_irq_connect_data     	rtemsIrq[BSP_IRQ_NUMBER];
+static rtems_irq_global_settings     	initial_config;
+static rtems_irq_connect_data     	defaultIrq = {
+  /* vectorIdex,	 hdl		, handle	, on		, off		, isOn */
+  0, 			 nop_func1	, 0		, nop_func2	, nop_func2	, not_connected
+};
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+  /*
+   * actual rpiorities for interrupt :
+   *	0   means that only current interrupt is masked
+   *	255 means all other interrupts are masked
+   */
+  /*
+   * SIU interrupts.
+   */
+  7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1, 0,0,
+  /*
+   * CPM Interrupts
+   */
+  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
+  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+  /*
+   * Processor exceptions handled as interrupts
+   */
+  0
+};
+
+void BSP_SIU_irq_init()
+{
+  /*
+   * In theory we should initialize two registers at least :
+   * SIMASK, SIEL. SIMASK is reset at 0 value meaning no interrupt. But
+   * we should take care that a monitor may have restoreed to another value.
+   * If someone find a reasonnable value for SIEL, AND THE NEED TO CHANGE IT
+   * please feel free to add it here.
+   */
+  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 0;
+  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 0xffff0000;
+  ppc_cached_irq_mask = 0;
+  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel = ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel;
+}
+
+/*
+ * Initialize CPM interrupt management
+ */
+void
+BSP_CPM_irq_init(void)
+{
+  /*
+   * Initialize the CPM interrupt controller.
+   */
+  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
+#ifdef mpc860
+    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
+#else
+    (CICR_SCB_SCC2 | CICR_SCA_SCC1) |
+#endif
+    ((BSP_CPM_INTERRUPT/2) << 13) | CICR_HP_MASK;
+  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0;
+
+  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
+}
+
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+  rtems_raw_except_connect_data vectorDesc;
+  int i;
+
+  BSP_SIU_irq_init();
+  BSP_CPM_irq_init();
+  /*
+   * Initialize Rtems management interrupt table
+   */
+    /*
+     * re-init the rtemsIrq table
+     */
+    for (i = 0; i < BSP_IRQ_NUMBER; i++) {
+      rtemsIrq[i]      = defaultIrq;
+      rtemsIrq[i].name = i;
+    }
+    /*
+     * Init initial Interrupt management config
+     */
+    initial_config.irqNb 	= BSP_IRQ_NUMBER;
+    initial_config.defaultEntry = defaultIrq;
+    initial_config.irqHdlTbl	= rtemsIrq;
+    initial_config.irqBase	= BSP_LOWEST_OFFSET;
+    initial_config.irqPrioTbl	= irqPrioTable;
+
+    if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+      /*
+       * put something here that will show the failure...
+       */
+      BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
+    }
+
+  /*
+   * We must connect the raw irq handler for the two
+   * expected interrupt sources : decrementer and external interrupts.
+   */
+    vectorDesc.exceptIndex 	=	ASM_DEC_VECTOR;
+    vectorDesc.hdl.vector	=	ASM_DEC_VECTOR;
+    vectorDesc.hdl.raw_hdl	=	decrementer_exception_vector_prolog_code;
+    vectorDesc.hdl.raw_hdl_size	=	(unsigned) &decrementer_exception_vector_prolog_code_size;
+    vectorDesc.on		=	nop_func2;
+    vectorDesc.off		=	nop_func2;
+    vectorDesc.isOn		=	connected;
+    if (!ppc_set_exception (&vectorDesc)) {
+      BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
+    }
+    vectorDesc.exceptIndex	=	ASM_EXT_VECTOR;
+    vectorDesc.hdl.vector	=	ASM_EXT_VECTOR;
+    vectorDesc.hdl.raw_hdl	=	external_exception_vector_prolog_code;
+    vectorDesc.hdl.raw_hdl_size	=	(unsigned) &external_exception_vector_prolog_code_size;
+    if (!ppc_set_exception (&vectorDesc)) {
+      BSP_panic("Unable to initialize RTEMS external raw exception\n");
+    }
+#ifdef TRACE_IRQ_INIT
+    printk("RTEMS IRQ management is now operationnal\n");
+#endif
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/network/network_fec.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/network/network_fec.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/network/network_fec.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,926 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: */
+/*
+ * RTEMS/TCPIP driver for MPC8xx Ethernet
+ *
+ * split into separate driver files for SCC and FEC by
+ * Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ *
+ *  Modified for MPC860 by Jay Monkman (jmonkman@frasca.com)
+ *
+ *  This supports Ethernet on either SCC1 or the FEC of the MPC860T.
+ *  Right now, we only do 10 Mbps, even with the FEC. The function
+ *  rtems_enet_driver_attach determines which one to use. Currently,
+ *  only one may be used at a time.
+ *
+ *  Based on the MC68360 network driver by
+ *  W. Eric Norum
+ *  Saskatchewan Accelerator Laboratory
+ *  University of Saskatchewan
+ *  Saskatoon, Saskatchewan, CANADA
+ *  eric@skatter.usask.ca
+ *
+ *  This supports ethernet on SCC1. Right now, we only do 10 Mbps.
+ *
+ *  Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
+ *  and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
+ *  Copyright (c) 1999, National Research Council of Canada
+ *
+ *  $Id$
+ */
+#include <bsp.h>
+#include <stdio.h>
+#include <errno.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <bsp/irq.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+/*
+ * Number of interfaces supported by this driver
+ */
+#define NIFACES 1
+
+/*
+ * Default number of buffer descriptors set aside for this driver.
+ * The number of transmit buffer descriptors has to be quite large
+ * since a single frame often uses four or more buffer descriptors.
+ */
+#define RX_BUF_COUNT     32
+#define TX_BUF_COUNT     8
+#define TX_BD_PER_BUF    4
+
+#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ * This must *not* be the same event used by the TCP/IP task synchronization.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * RTEMS event used to start transmit daemon.
+ * This must not be the same as INTERRUPT_EVENT.
+ */
+#define START_TRANSMIT_EVENT RTEMS_EVENT_2
+
+/*
+ * Receive buffer size -- Allow for a full ethernet packet plus CRC (1518).
+ * Round off to nearest multiple of RBUF_ALIGN.
+ */
+#define MAX_MTU_SIZE	1518
+#define RBUF_ALIGN		4
+#define RBUF_SIZE       ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
+
+#if (MCLBYTES < RBUF_SIZE)
+# error "Driver must have MCLBYTES > RBUF_SIZE"
+#endif
+
+/*
+ * Per-device data
+ */
+struct m8xx_fec_enet_struct {
+  struct arpcom           arpcom;
+  struct mbuf             **rxMbuf;
+  struct mbuf             **txMbuf;
+  int                     acceptBroadcast;
+  int                     rxBdCount;
+  int                     txBdCount;
+  int                     txBdHead;
+  int                     txBdTail;
+  int                     txBdActiveCount;
+  m8xxBufferDescriptor_t  *rxBdBase;
+  m8xxBufferDescriptor_t  *txBdBase;
+  rtems_id                rxDaemonTid;
+  rtems_id                txDaemonTid;
+
+  /*
+   * Statistics
+   */
+  unsigned long   rxInterrupts;
+  unsigned long   rxNotFirst;
+  unsigned long   rxNotLast;
+  unsigned long   rxGiant;
+  unsigned long   rxNonOctet;
+  unsigned long   rxRunt;
+  unsigned long   rxBadCRC;
+  unsigned long   rxOverrun;
+  unsigned long   rxCollision;
+
+  unsigned long   txInterrupts;
+  unsigned long   txDeferred;
+  unsigned long   txHeartbeat;
+  unsigned long   txLateCollision;
+  unsigned long   txRetryLimit;
+  unsigned long   txUnderrun;
+  unsigned long   txLostCarrier;
+  unsigned long   txRawWait;
+};
+static struct m8xx_fec_enet_struct enet_driver[NIFACES];
+
+/*
+ * FEC interrupt handler
+ */
+static void m8xx_fec_interrupt_handler ()
+{
+  /*
+   * Frame received?
+   */
+  if (m8xx.fec.ievent & M8xx_FEC_IEVENT_RFINT) {
+    m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
+    enet_driver[0].rxInterrupts++;
+    rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
+  }
+
+  /*
+   * Buffer transmitted or transmitter error?
+   */
+  if (m8xx.fec.ievent & M8xx_FEC_IEVENT_TFINT) {
+    m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
+    enet_driver[0].txInterrupts++;
+    rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
+  }
+}
+
+/*
+ * Please organize FEC controller code better by moving code from
+ * m860_fec_initialize_hardware to m8xx_fec_ethernet_on
+ */
+static void m8xx_fec_ethernet_on(){};
+static void m8xx_fec_ethernet_off(){};
+static int m8xx_fec_ethernet_isOn (const rtems_irq_connect_data* ptr)
+{
+  return BSP_irq_enabled_at_siu (ptr->name);
+}
+
+static rtems_irq_connect_data ethernetFECIrqData = {
+  BSP_FAST_ETHERNET_CTRL,
+  (rtems_irq_hdl) m8xx_fec_interrupt_handler,
+  (rtems_irq_enable) m8xx_fec_ethernet_on,
+  (rtems_irq_disable) m8xx_fec_ethernet_off,
+  (rtems_irq_is_enabled)m8xx_fec_ethernet_isOn
+};
+
+static void
+m8xx_fec_initialize_hardware (struct m8xx_fec_enet_struct *sc)
+{
+  int i;
+  unsigned char *hwaddr;
+
+  /*
+   * Issue reset to FEC
+   */
+  m8xx.fec.ecntrl=0x1;
+
+  /*
+   * Put ethernet transciever in reset
+   */
+  m8xx.pgcra |= 0x80;
+
+  /*
+   * Configure I/O ports
+   */
+  m8xx.pdpar = 0x1fff;
+  m8xx.pddir = 0x1c58;
+
+  /*
+   * Take ethernet transciever out of reset
+   */
+  m8xx.pgcra &= ~0x80;
+
+  /*
+   * Set SIU interrupt level to LVL2
+   *
+   */
+  m8xx.fec.ivec = ((((unsigned) BSP_FAST_ETHERNET_CTRL)/2) << 29);
+
+  /*
+   * Set the TX and RX fifo sizes. For now, we'll split it evenly
+   */
+  /* If you uncomment these, the FEC will not work right.
+     m8xx.fec.r_fstart = ((m8xx.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
+     m8xx.fec.x_fstart = 0;
+  */
+
+  /*
+   * Set our physical address
+   */
+  hwaddr = sc->arpcom.ac_enaddr;
+
+  m8xx.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
+    (hwaddr[2] << 8)  | (hwaddr[3] << 0);
+  m8xx.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
+
+  /*
+   * Clear the hash table
+   */
+  m8xx.fec.hash_table_high = 0;
+  m8xx.fec.hash_table_low  = 0;
+
+  /*
+   * Set up receive buffer size
+   */
+  m8xx.fec.r_buf_size = 0x5f0; /* set to 1520 */
+
+  /*
+   * Allocate mbuf pointers
+   */
+  sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
+                       M_MBUF, M_NOWAIT);
+  sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
+                       M_MBUF, M_NOWAIT);
+  if (!sc->rxMbuf || !sc->txMbuf)
+    rtems_panic ("No memory for mbuf pointers");
+
+  /*
+   * Set receiver and transmitter buffer descriptor bases
+   */
+  sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
+  sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
+  m8xx.fec.r_des_start = (int)sc->rxBdBase;
+  m8xx.fec.x_des_start = (int)sc->txBdBase;
+
+  /*
+   * Set up Receive Control Register:
+   *   Not promiscuous mode
+   *   MII mode
+   *   Half duplex
+   *   No loopback
+   */
+  m8xx.fec.r_cntrl = 0x00000006;
+
+  /*
+   * Set up Transmit Control Register:
+   *   Half duplex
+   *   No heartbeat
+   */
+  m8xx.fec.x_cntrl = 0x00000000;
+
+  /*
+   * Set up DMA function code:
+   *   Big-endian
+   *   DMA functino code = 0
+   */
+  m8xx.fec.fun_code = 0x78000000;
+
+  /*
+   * Initialize SDMA configuration register
+   *   SDMA ignores FRZ
+   *   FEC not aggressive
+   *   FEC arbitration ID = 0 => U-bus arbitration = 6
+   *   RISC arbitration ID = 1 => U-bus arbitration = 5
+   */
+  m8xx.sdcr = 1;
+
+  /*
+   * Set MII speed to 2.5 MHz for 25 Mhz system clock
+   */
+  m8xx.fec.mii_speed = 0x0a;
+  m8xx.fec.mii_data = 0x58021000;
+
+  /*
+   * Set up receive buffer descriptors
+   */
+  for (i = 0 ; i < sc->rxBdCount ; i++)
+    (sc->rxBdBase + i)->status = 0;
+
+  /*
+   * Set up transmit buffer descriptors
+   */
+  for (i = 0 ; i < sc->txBdCount ; i++) {
+    (sc->txBdBase + i)->status = 0;
+    sc->txMbuf[i] = NULL;
+  }
+  sc->txBdHead = sc->txBdTail = 0;
+  sc->txBdActiveCount = 0;
+
+  /*
+   * Mask all FEC interrupts and clear events
+   */
+  m8xx.fec.imask = M8xx_FEC_IEVENT_TFINT |
+    M8xx_FEC_IEVENT_RFINT;
+  m8xx.fec.ievent = ~0;
+
+  /*
+   * Set up interrupts
+   */
+  if (!BSP_install_rtems_irq_handler (&ethernetFECIrqData))
+    rtems_panic ("Can't attach M860 FEC interrupt handler\n");
+
+}
+static void fec_rxDaemon (void *arg)
+{
+  struct m8xx_fec_enet_struct *sc = (struct m8xx_fec_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  uint16_t   status;
+  m8xxBufferDescriptor_t *rxBd;
+  int rxBdIndex;
+
+  /*
+   * Allocate space for incoming packets and start reception
+   */
+  for (rxBdIndex = 0 ; ;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+    MGETHDR (m, M_WAIT, MT_DATA);
+    MCLGET (m, M_WAIT);
+    m->m_pkthdr.rcvif = ifp;
+    sc->rxMbuf[rxBdIndex] = m;
+    rxBd->buffer = mtod (m, void *);
+    rxBd->status = M8xx_BD_EMPTY;
+    m8xx.fec.r_des_active = 0x1000000;
+    if (++rxBdIndex == sc->rxBdCount) {
+      rxBd->status |= M8xx_BD_WRAP;
+      break;
+    }
+  }
+
+  /*
+   * Input packet handling loop
+   */
+  rxBdIndex = 0;
+  for (;;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+
+    /*
+     * Wait for packet if there's not one ready
+     */
+    if ((status = rxBd->status) & M8xx_BD_EMPTY) {
+      /*
+       * Clear old events
+       */
+      m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
+
+      /*
+       * Wait for packet
+       * Note that the buffer descriptor is checked
+       * *before* the event wait -- this catches the
+       * possibility that a packet arrived between the
+       * `if' above, and the clearing of the event register.
+       */
+      while ((status = rxBd->status) & M8xx_BD_EMPTY) {
+        rtems_event_set events;
+
+        /*
+         * Unmask RXF (Full frame received) event
+         */
+        m8xx.fec.ievent |= M8xx_FEC_IEVENT_RFINT;
+
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+      }
+    }
+
+    /*
+     * Check that packet is valid
+     */
+    if (status & M8xx_BD_LAST) {
+      /*
+       * Pass the packet up the chain.
+       * FIXME: Packet filtering hook could be done here.
+       */
+      struct ether_header *eh;
+
+      /*
+       * Invalidate the buffer for this descriptor
+       */
+      rtems_cache_invalidate_multiple_data_lines((const void *)rxBd->buffer, rxBd->length);
+
+      m = sc->rxMbuf[rxBdIndex];
+      m->m_len = m->m_pkthdr.len = rxBd->length -
+        sizeof(uint32_t) -
+        sizeof(struct ether_header);
+      eh = mtod (m, struct ether_header *);
+      m->m_data += sizeof(struct ether_header);
+      ether_input (ifp, eh, m);
+
+      /*
+       * Allocate a new mbuf
+       */
+      MGETHDR (m, M_WAIT, MT_DATA);
+      MCLGET (m, M_WAIT);
+      m->m_pkthdr.rcvif = ifp;
+      sc->rxMbuf[rxBdIndex] = m;
+      rxBd->buffer = mtod (m, void *);
+    }
+    else {
+      /*
+       * Something went wrong with the reception
+       */
+      if (!(status & M8xx_BD_LAST))
+        sc->rxNotLast++;
+      if (status & M8xx_BD_LONG)
+        sc->rxGiant++;
+      if (status & M8xx_BD_NONALIGNED)
+        sc->rxNonOctet++;
+      if (status & M8xx_BD_SHORT)
+        sc->rxRunt++;
+      if (status & M8xx_BD_CRC_ERROR)
+        sc->rxBadCRC++;
+      if (status & M8xx_BD_OVERRUN)
+        sc->rxOverrun++;
+      if (status & M8xx_BD_COLLISION)
+        sc->rxCollision++;
+    }
+    /*
+     * Reenable the buffer descriptor
+     */
+    rxBd->status = (status & M8xx_BD_WRAP) |
+      M8xx_BD_EMPTY;
+    m8xx.fec.r_des_active = 0x1000000;
+    /*
+     * Move to next buffer descriptor
+     */
+    if (++rxBdIndex == sc->rxBdCount)
+      rxBdIndex = 0;
+  }
+}
+
+/*
+ * Soak up buffer descriptors that have been sent.
+ * Note that a buffer descriptor can't be retired as soon as it becomes
+ * ready. The MPC860 manual (MPC860UM/AD 07/98 Rev.1) and the MPC821
+ * manual state that, "If an Ethernet frame is made up of multiple
+ * buffers, the user should not reuse the first buffer descriptor until
+ * the last buffer descriptor of the frame has had its ready bit cleared
+ * by the CPM".
+ */
+static void
+m8xx_fec_Enet_retire_tx_bd (struct m8xx_fec_enet_struct *sc)
+{
+  uint16_t   status;
+  int i;
+  int nRetired;
+  struct mbuf *m, *n;
+
+  i = sc->txBdTail;
+  nRetired = 0;
+  while ((sc->txBdActiveCount != 0)
+	 &&  (((status = (sc->txBdBase + i)->status) & M8xx_BD_READY) == 0)) {
+    /*
+     * See if anything went wrong
+     */
+    if (status & (M8xx_BD_DEFER |
+                  M8xx_BD_HEARTBEAT |
+                  M8xx_BD_LATE_COLLISION |
+                  M8xx_BD_RETRY_LIMIT |
+                  M8xx_BD_UNDERRUN |
+                  M8xx_BD_CARRIER_LOST)) {
+      /*
+       * Check for errors which stop the transmitter.
+       */
+      if (status & (M8xx_BD_LATE_COLLISION |
+                    M8xx_BD_RETRY_LIMIT |
+                    M8xx_BD_UNDERRUN)) {
+        if (status & M8xx_BD_LATE_COLLISION)
+          enet_driver[0].txLateCollision++;
+        if (status & M8xx_BD_RETRY_LIMIT)
+          enet_driver[0].txRetryLimit++;
+        if (status & M8xx_BD_UNDERRUN)
+          enet_driver[0].txUnderrun++;
+
+        /*
+         * Restart the transmitter
+         */
+        /* FIXME: this should get executed only if using the SCC */
+        m8xx_cp_execute_cmd (M8xx_CR_OP_RESTART_TX | M8xx_CR_CHAN_SCC1);
+      }
+      if (status & M8xx_BD_DEFER)
+        enet_driver[0].txDeferred++;
+      if (status & M8xx_BD_HEARTBEAT)
+        enet_driver[0].txHeartbeat++;
+      if (status & M8xx_BD_CARRIER_LOST)
+        enet_driver[0].txLostCarrier++;
+    }
+    nRetired++;
+    if (status & M8xx_BD_LAST) {
+      /*
+       * A full frame has been transmitted.
+       * Free all the associated buffer descriptors.
+       */
+      sc->txBdActiveCount -= nRetired;
+      while (nRetired) {
+        nRetired--;
+        m = sc->txMbuf[sc->txBdTail];
+        MFREE (m, n);
+        if (++sc->txBdTail == sc->txBdCount)
+          sc->txBdTail = 0;
+      }
+    }
+    if (++i == sc->txBdCount)
+      i = 0;
+  }
+}
+
+static void fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+  struct m8xx_fec_enet_struct *sc = ifp->if_softc;
+  volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
+  /*  struct mbuf *l = NULL; */
+  uint16_t   status;
+  int nAdded;
+
+  /*
+   * Free up buffer descriptors
+   */
+  m8xx_fec_Enet_retire_tx_bd (sc);
+
+  /*
+   * Set up the transmit buffer descriptors.
+   * No need to pad out short packets since the
+   * hardware takes care of that automatically.
+   * No need to copy the packet to a contiguous buffer
+   * since the hardware is capable of scatter/gather DMA.
+   */
+  nAdded = 0;
+  txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
+  for (;;) {
+    /*
+     * Wait for buffer descriptor to become available.
+     */
+    if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+      /*
+       * Clear old events
+       */
+      m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
+
+      /*
+       * Wait for buffer descriptor to become available.
+       * Note that the buffer descriptors are checked
+       * *before* * entering the wait loop -- this catches
+       * the possibility that a buffer descriptor became
+       * available between the `if' above, and the clearing
+       * of the event register.
+       * This is to catch the case where the transmitter
+       * stops in the middle of a frame -- and only the
+       * last buffer descriptor in a frame can generate
+       * an interrupt.
+       */
+      m8xx_fec_Enet_retire_tx_bd (sc);
+      while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+        rtems_event_set events;
+
+        /*
+         * Unmask TXB (buffer transmitted) and
+         * TXE (transmitter error) events.
+         */
+        m8xx.fec.ievent |= M8xx_FEC_IEVENT_TFINT;
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+        m8xx_fec_Enet_retire_tx_bd (sc);
+      }
+    }
+
+    /*
+     * Don't set the READY flag till the
+     * whole packet has been readied.
+     */
+    status = nAdded ? M8xx_BD_READY : 0;
+
+    /*
+     *  FIXME: Why not deal with empty mbufs at at higher level?
+     * The IP fragmentation routine in ip_output
+     * can produce packet fragments with zero length.
+     * I think that ip_output should be changed to get
+     * rid of these zero-length mbufs, but for now,
+     * I'll deal with them here.
+     */
+    if (m->m_len) {
+      /*
+       * Fill in the buffer descriptor
+       */
+      txBd->buffer = mtod (m, void *);
+      txBd->length = m->m_len;
+
+      /*
+       * Flush the buffer for this descriptor
+       */
+      rtems_cache_flush_multiple_data_lines(txBd->buffer, txBd->length);
+
+      sc->txMbuf[sc->txBdHead] = m;
+      nAdded++;
+      if (++sc->txBdHead == sc->txBdCount) {
+        status |= M8xx_BD_WRAP;
+        sc->txBdHead = 0;
+      }
+      /*      l = m;*/
+      m = m->m_next;
+    }
+    else {
+      /*
+       * Just toss empty mbufs
+       */
+      struct mbuf *n;
+      MFREE (m, n);
+      m = n;
+      /*
+	if (l != NULL)
+        l->m_next = m;
+      */
+    }
+
+    /*
+     * Set the transmit buffer status.
+     * Break out of the loop if this mbuf is the last in the frame.
+     */
+    if (m == NULL) {
+      if (nAdded) {
+        status |= M8xx_BD_LAST | M8xx_BD_TX_CRC;
+        txBd->status = status;
+        firstTxBd->status |= M8xx_BD_READY;
+        m8xx.fec.x_des_active = 0x1000000;
+        sc->txBdActiveCount += nAdded;
+      }
+      break;
+    }
+    txBd->status = status;
+    txBd = sc->txBdBase + sc->txBdHead;
+  }
+}
+void fec_txDaemon (void *arg)
+{
+  struct m8xx_fec_enet_struct *sc = (struct m8xx_fec_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  rtems_event_set events;
+
+  for (;;) {
+    /*
+     * Wait for packet
+     */
+    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
+                                RTEMS_EVENT_ANY | RTEMS_WAIT,
+                                RTEMS_NO_TIMEOUT,
+                                &events);
+
+    /*
+     * Send packets till queue is empty
+     */
+    for (;;) {
+      /*
+       * Get the next mbuf chain to transmit.
+       */
+      IF_DEQUEUE(&ifp->if_snd, m);
+      if (!m)
+        break;
+      fec_sendpacket (ifp, m);
+    }
+    ifp->if_flags &= ~IFF_OACTIVE;
+  }
+}
+static void fec_init (void *arg)
+{
+  struct m8xx_fec_enet_struct *sc = arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+
+  if (sc->txDaemonTid == 0) {
+
+    /*
+     * Set up SCC hardware
+     */
+    m8xx_fec_initialize_hardware (sc);
+
+    /*
+     * Start driver tasks
+     */
+    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, fec_txDaemon, sc);
+    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, fec_rxDaemon, sc);
+
+  }
+
+  /*
+   * Set flags appropriately
+   */
+  if (ifp->if_flags & IFF_PROMISC)
+    m8xx.fec.r_cntrl |= 0x8;
+  else
+    m8xx.fec.r_cntrl &= ~0x8;
+
+  /*
+   * Tell the world that we're running.
+   */
+  ifp->if_flags |= IFF_RUNNING;
+
+  /*
+   * Enable receiver and transmitter
+   */
+  m8xx.fec.ecntrl = 0x2;
+}
+
+/*
+ * Send packet (caller provides header).
+ */
+static void
+m8xx_fec_enet_start (struct ifnet *ifp)
+{
+  struct m8xx_fec_enet_struct *sc = ifp->if_softc;
+
+  rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
+  ifp->if_flags |= IFF_OACTIVE;
+}
+
+static void fec_stop (struct m8xx_fec_enet_struct *sc)
+{
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+
+  ifp->if_flags &= ~IFF_RUNNING;
+
+  /*
+   * Shut down receiver and transmitter
+   */
+  m8xx.fec.ecntrl = 0x0;
+}
+
+/*
+ * Show interface statistics
+ */
+static void fec_enet_stats (struct m8xx_fec_enet_struct *sc)
+{
+  printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
+  printf ("       Not First:%-8lu", sc->rxNotFirst);
+  printf ("        Not Last:%-8lu\n", sc->rxNotLast);
+  printf ("              Giant:%-8lu", sc->rxGiant);
+  printf ("            Runt:%-8lu", sc->rxRunt);
+  printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
+  printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
+  printf ("         Overrun:%-8lu", sc->rxOverrun);
+  printf ("       Collision:%-8lu\n", sc->rxCollision);
+  printf ("          Discarded:%-8lu\n", (unsigned long)m8xx.scc1p.un.ethernet.disfc);
+
+  printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
+  printf ("        Deferred:%-8lu", sc->txDeferred);
+  printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
+  printf ("         No Carrier:%-8lu", sc->txLostCarrier);
+  printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
+  printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
+  printf ("           Underrun:%-8lu", sc->txUnderrun);
+  printf (" Raw output wait:%-8lu\n", sc->txRawWait);
+}
+
+static int fec_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+  struct m8xx_fec_enet_struct *sc = ifp->if_softc;
+  int error = 0;
+
+  switch (command) {
+  case SIOCGIFADDR:
+  case SIOCSIFADDR:
+    ether_ioctl (ifp, command, data);
+    break;
+
+  case SIOCSIFFLAGS:
+    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+    case IFF_RUNNING:
+      fec_stop (sc);
+      break;
+
+    case IFF_UP:
+      fec_init (sc);
+      break;
+
+    case IFF_UP | IFF_RUNNING:
+      fec_stop (sc);
+      fec_init (sc);
+      break;
+
+    default:
+      break;
+    }
+    break;
+
+  case SIO_RTEMS_SHOW_STATS:
+    fec_enet_stats (sc);
+    break;
+
+    /*
+     * FIXME: All sorts of multicast commands need to be added here!
+     */
+  default:
+    error = EINVAL;
+    break;
+  }
+  return error;
+}
+int rtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+  struct m8xx_fec_enet_struct *sc;
+  struct ifnet *ifp;
+  int mtu;
+  int unitNumber;
+  char *unitName;
+  static const uint8_t maczero[] ={0,0,0,0,0,0};
+
+  /*
+   * Parse driver name
+   */
+  if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
+    return 0;
+
+  /*
+   * Is driver free?
+   */
+  if ((unitNumber <= 0) || (unitNumber > NIFACES)) {
+    printf ("Bad SCC unit number.\n");
+    return 0;
+  }
+  sc = &enet_driver[unitNumber - 1];
+  ifp = &sc->arpcom.ac_if;
+  if (ifp->if_softc != NULL) {
+    printf ("Driver already in use.\n");
+    return 0;
+  }
+
+  /*
+   * Process options
+   */
+  if (config->hardware_address) {
+    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+  }
+#ifdef BSP_HAS_TQMMON
+  else if(0 != memcmp(maczero,TQM_BD_INFO.eth_addr,ETHER_ADDR_LEN)) {
+    memcpy (sc->arpcom.ac_enaddr, TQM_BD_INFO.eth_addr, ETHER_ADDR_LEN);
+  }
+#endif
+  else {
+    /* FIXME to read the enaddr from NVRAM */
+  }
+  if (config->mtu)
+    mtu = config->mtu;
+  else
+    mtu = ETHERMTU;
+  if (config->rbuf_count)
+    sc->rxBdCount = config->rbuf_count;
+  else
+    sc->rxBdCount = RX_BUF_COUNT;
+  if (config->xbuf_count)
+    sc->txBdCount = config->xbuf_count;
+  else
+    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+  sc->acceptBroadcast = !config->ignore_broadcast;
+
+  /*
+   * Set up network interface values
+   */
+  ifp->if_softc = sc;
+  ifp->if_unit = unitNumber;
+  ifp->if_name = unitName;
+  ifp->if_mtu = mtu;
+  ifp->if_init = fec_init;
+  ifp->if_ioctl = fec_ioctl;
+  ifp->if_start = m8xx_fec_enet_start;
+  ifp->if_output = ether_output;
+  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+  if (ifp->if_snd.ifq_maxlen == 0)
+    ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+  /*
+   * Attach the interface
+   */
+  if_attach (ifp);
+  ether_ifattach (ifp);
+  return 1;
+};
+
+int rtems_fec_enet_driver_attach(struct rtems_bsdnet_ifconfig *config, 
+				 int attaching)
+{
+  return rtems_fec_driver_attach(config);
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/network/network_scc.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/network/network_scc.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/network/network_scc.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,1047 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: */
+/*
+ * RTEMS/TCPIP driver for MPC8xx SCC1 Ethernet
+ *
+ *  Modified for MPC860 by Jay Monkman (jmonkman@frasca.com)
+ *
+ *  This supports Ethernet on either SCC1 or the FEC of the MPC860T.
+ *  Right now, we only do 10 Mbps, even with the FEC. The function
+ *  rtems_enet_driver_attach determines which one to use. Currently,
+ *  only one may be used at a time.
+ *
+ *  Based on the MC68360 network driver by
+ *  W. Eric Norum
+ *  Saskatchewan Accelerator Laboratory
+ *  University of Saskatchewan
+ *  Saskatoon, Saskatchewan, CANADA
+ *  eric@skatter.usask.ca
+ *
+ *  This supports ethernet on SCC1. Right now, we only do 10 Mbps.
+ *
+ *  Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
+ *  and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
+ *  Copyright (c) 1999, National Research Council of Canada
+ *
+ *  $Id$
+ */
+#include <bsp.h>
+#include <stdio.h>
+#include <errno.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <bsp/irq.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+/*
+ * Number of interfaces supported by this driver
+ */
+#define NIFACES 1
+
+/*
+ * Default number of buffer descriptors set aside for this driver.
+ * The number of transmit buffer descriptors has to be quite large
+ * since a single frame often uses four or more buffer descriptors.
+ */
+#define RX_BUF_COUNT     32
+#define TX_BUF_COUNT     8
+#define TX_BD_PER_BUF    4
+
+#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ * This must *not* be the same event used by the TCP/IP task synchronization.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * RTEMS event used to start transmit daemon.
+ * This must not be the same as INTERRUPT_EVENT.
+ */
+#define START_TRANSMIT_EVENT RTEMS_EVENT_2
+
+/*
+ * Receive buffer size -- Allow for a full ethernet packet plus CRC (1518).
+ * Round off to nearest multiple of RBUF_ALIGN.
+ */
+#define MAX_MTU_SIZE	1518
+#define RBUF_ALIGN		4
+#define RBUF_SIZE       ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
+
+#if (MCLBYTES < RBUF_SIZE)
+# error "Driver must have MCLBYTES > RBUF_SIZE"
+#endif
+
+/*
+ * Per-device data
+ */
+struct m8xx_enet_struct {
+  struct arpcom           arpcom;
+  struct mbuf             **rxMbuf;
+  struct mbuf             **txMbuf;
+  int                     acceptBroadcast;
+  int                     rxBdCount;
+  int                     txBdCount;
+  int                     txBdHead;
+  int                     txBdTail;
+  int                     txBdActiveCount;
+  m8xxBufferDescriptor_t  *rxBdBase;
+  m8xxBufferDescriptor_t  *txBdBase;
+  rtems_id                rxDaemonTid;
+  rtems_id                txDaemonTid;
+
+  /*
+   * Statistics
+   */
+  unsigned long   rxInterrupts;
+  unsigned long   rxNotFirst;
+  unsigned long   rxNotLast;
+  unsigned long   rxGiant;
+  unsigned long   rxNonOctet;
+  unsigned long   rxRunt;
+  unsigned long   rxBadCRC;
+  unsigned long   rxOverrun;
+  unsigned long   rxCollision;
+
+  unsigned long   txInterrupts;
+  unsigned long   txDeferred;
+  unsigned long   txHeartbeat;
+  unsigned long   txLateCollision;
+  unsigned long   txRetryLimit;
+  unsigned long   txUnderrun;
+  unsigned long   txLostCarrier;
+  unsigned long   txRawWait;
+};
+static struct m8xx_enet_struct enet_driver[NIFACES];
+
+static void  m8xx_scc1_ethernet_on(const rtems_irq_connect_data* ptr)
+{
+}
+
+static void  m8xx_scc1_ethernet_off(const rtems_irq_connect_data* ptr)
+{
+  /*
+   * Please put relevant code there
+   */
+}
+
+static void  m8xx_scc1_ethernet_isOn(const rtems_irq_connect_data* ptr)
+{
+  int BSP_irq_enabled_at_cpm(const rtems_irq_number );
+  BSP_irq_enabled_at_cpm (ptr->name);
+}
+
+/*
+ * SCC1 interrupt handler
+ */
+static void m8xx_scc1_interrupt_handler (void *unused)
+{
+  /* Frame received? */
+  if ((m8xx.scc1.sccm & 0x8) && (m8xx.scc1.scce & 0x8)) {
+    m8xx.scc1.scce = 0x8;		/* Clear receive frame int */
+    m8xx.scc1.sccm &= ~0x8; 	/* Disable receive frame ints */
+    enet_driver[0].rxInterrupts++; /* Rx int has occurred */
+    rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
+  }
+
+  /* Buffer transmitted or transmitter error? */
+  if ((m8xx.scc1.sccm & 0x12) && (m8xx.scc1.scce & 0x12)) {
+    m8xx.scc1.scce = 0x12;		/* Clear Tx int */
+    m8xx.scc1.sccm &= ~0x12; 	/* Disable Tx ints */
+    enet_driver[0].txInterrupts++; /* Tx int has occurred */
+    rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
+  }
+}
+
+
+static rtems_irq_connect_data ethernetSCC1IrqData = {
+  BSP_CPM_IRQ_SCC1,
+  (rtems_irq_hdl) m8xx_scc1_interrupt_handler,
+  0,
+  (rtems_irq_enable) m8xx_scc1_ethernet_on,
+  (rtems_irq_disable) m8xx_scc1_ethernet_off,
+  (rtems_irq_is_enabled)m8xx_scc1_ethernet_isOn
+};
+
+/*
+ * Initialize the ethernet hardware
+ */
+static void
+m8xx_enet_initialize (struct m8xx_enet_struct *sc)
+{
+  int i;
+  unsigned char *hwaddr;
+
+  /*
+   * Configure port A
+   * PA15 is enet RxD. Set PAPAR(15) to 1, PADIR(15) to 0.
+   * PA14 is enet TxD. Set PAPAR(14) to 1, PADIR(14) to 0, PAODR(14) to 0.
+   * PA7 is input CLK1. Set PAPAR(7) to 1, PADIR(7) to 0.
+   * PA6 is input CLK2. Set PAPAR(6) to 1, PADIR(6) to 0.
+   */
+  m8xx.papar |=  0x303;
+  m8xx.padir &= ~0x303;
+  m8xx.paodr &= ~0x2;
+
+  /*
+   * Configure port C
+   * PC11 is CTS1*. Set PCPAR(11) to 0, PCDIR(11) to 0, and PCSO(11) to 1.
+   * PC10 is CD1*. Set PCPAR(10) to 0, PCDIR(10) to 0, and PCSO(10) to 1.
+   */
+  m8xx.pcpar &= ~0x30;
+  m8xx.pcdir &= ~0x30;
+  m8xx.pcso  |=  0x30;
+
+  /*
+   * Connect CLK1 and CLK2 to SCC1 in the SICR.
+   * CLK1 is TxClk, CLK2 is RxClk. No grant mechanism, SCC1 is directly
+   * connected to the NMSI pins.
+   * R1CS = 0b101 (CLK2)
+   * T1CS = 0b100 (CLK1)
+   */
+  m8xx.sicr |= 0x2C;
+
+  /*
+   * Initialize SDMA configuration register
+   */
+  m8xx.sdcr = 1;
+
+  /*
+   * Allocate mbuf pointers
+   */
+  sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
+		       M_MBUF, M_NOWAIT);
+  sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
+		       M_MBUF, M_NOWAIT);
+  if (!sc->rxMbuf || !sc->txMbuf)
+    rtems_panic ("No memory for mbuf pointers");
+
+  /*
+   * Set receiver and transmitter buffer descriptor bases
+   */
+  sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
+  sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
+  m8xx.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m8xx;
+  m8xx.scc1p.tbase = (char *)sc->txBdBase - (char *)&m8xx;
+
+  /*
+   * Send "Init parameters" command
+   */
+  m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC1);
+
+  /*
+   * Set receive and transmit function codes
+   */
+  m8xx.scc1p.rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
+  m8xx.scc1p.tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
+
+  /*
+   * Set maximum receive buffer length
+   */
+  m8xx.scc1p.mrblr = RBUF_SIZE;
+
+  /*
+   * Set CRC parameters
+   */
+  m8xx.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
+  m8xx.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
+
+  /*
+   * Clear diagnostic counters
+   */
+  m8xx.scc1p.un.ethernet.crcec = 0;
+  m8xx.scc1p.un.ethernet.alec = 0;
+  m8xx.scc1p.un.ethernet.disfc = 0;
+
+  /*
+   * Set pad value
+   */
+  m8xx.scc1p.un.ethernet.pads = 0x8888;
+
+  /*
+   * Set retry limit
+   */
+  m8xx.scc1p.un.ethernet.ret_lim = 15;
+
+  /*
+   * Set maximum and minimum frame length
+   */
+  m8xx.scc1p.un.ethernet.mflr = 1518;
+  m8xx.scc1p.un.ethernet.minflr = 64;
+  m8xx.scc1p.un.ethernet.maxd1 = MAX_MTU_SIZE;
+  m8xx.scc1p.un.ethernet.maxd2 = MAX_MTU_SIZE;
+
+  /*
+   * Clear group address hash table
+   */
+  m8xx.scc1p.un.ethernet.gaddr1 = 0;
+  m8xx.scc1p.un.ethernet.gaddr2 = 0;
+  m8xx.scc1p.un.ethernet.gaddr3 = 0;
+  m8xx.scc1p.un.ethernet.gaddr4 = 0;
+
+  /*
+   * Set our physical address
+   */
+  hwaddr = sc->arpcom.ac_enaddr;
+
+  m8xx.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
+  m8xx.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
+  m8xx.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
+
+  /*
+   * Aggressive retry
+   */
+  m8xx.scc1p.un.ethernet.p_per = 0;
+
+  /*
+   * Clear individual address hash table
+   */
+  m8xx.scc1p.un.ethernet.iaddr1 = 0;
+  m8xx.scc1p.un.ethernet.iaddr2 = 0;
+  m8xx.scc1p.un.ethernet.iaddr3 = 0;
+  m8xx.scc1p.un.ethernet.iaddr4 = 0;
+
+  /*
+   * Clear temp address
+   */
+  m8xx.scc1p.un.ethernet.taddr_l = 0;
+  m8xx.scc1p.un.ethernet.taddr_m = 0;
+  m8xx.scc1p.un.ethernet.taddr_h = 0;
+
+  /*
+   * Set up receive buffer descriptors
+   */
+  for (i = 0 ; i < sc->rxBdCount ; i++) {
+    (sc->rxBdBase + i)->status = 0;
+  }
+
+  /*
+   * Set up transmit buffer descriptors
+   */
+  for (i = 0 ; i < sc->txBdCount ; i++) {
+    (sc->txBdBase + i)->status = 0;
+    sc->txMbuf[i] = NULL;
+  }
+  sc->txBdHead = sc->txBdTail = 0;
+  sc->txBdActiveCount = 0;
+
+  /*
+   * Clear any outstanding events
+   */
+  m8xx.scc1.scce = 0xFFFF;
+
+  /*
+   * Set up interrupts
+   */
+  if (!BSP_install_rtems_irq_handler (&ethernetSCC1IrqData)) {
+    rtems_panic ("Can't attach M8xx SCC1 interrupt handler\n");
+  }
+  m8xx.scc1.sccm = 0;     /* No interrupts unmasked till necessary */
+
+  /*
+   * Set up General SCC Mode Register
+   * Ethernet configuration
+   */
+  m8xx.scc1.gsmr_h = 0x0;
+  m8xx.scc1.gsmr_l = 0x1088000c;
+
+  /*
+   * Set up data synchronization register
+   * Ethernet synchronization pattern
+   */
+  m8xx.scc1.dsr = 0xd555;
+
+  /*
+   * Set up protocol-specific mode register
+   *      No Heartbeat check
+   *      No force collision
+   *      Discard short frames
+   *      Individual address mode
+   *      Ethernet CRC
+   *      Not promisuous
+   *      Ignore/accept broadcast packets as specified
+   *      Normal backoff timer
+   *      No loopback
+   *      No input sample at end of frame
+   *      64-byte limit for late collision
+   *      Wait 22 bits before looking for start of frame delimiter
+   *      Disable full-duplex operation
+   */
+  m8xx.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
+
+  /*
+   * Enable the TENA (RTS1*) pin
+   */
+  m8xx.pcpar |=  0x1;
+  m8xx.pcdir &= ~0x1;
+
+  /*
+   * Enable receiver and transmitter
+   */
+  m8xx.scc1.gsmr_l = 0x1088003c;
+}
+
+
+/*
+ * Soak up buffer descriptors that have been sent.
+ * Note that a buffer descriptor can't be retired as soon as it becomes
+ * ready. The MPC860 manual (MPC860UM/AD 07/98 Rev.1) and the MPC821
+ * manual state that, "If an Ethernet frame is made up of multiple
+ * buffers, the user should not reuse the first buffer descriptor until
+ * the last buffer descriptor of the frame has had its ready bit cleared
+ * by the CPM".
+ */
+static void
+m8xx_Enet_retire_tx_bd (struct m8xx_enet_struct *sc)
+{
+  uint16_t   status;
+  int i;
+  int nRetired;
+  struct mbuf *m, *n;
+
+  i = sc->txBdTail;
+  nRetired = 0;
+  while ((sc->txBdActiveCount != 0)
+	 &&  (((status = (sc->txBdBase + i)->status) & M8xx_BD_READY) == 0)) {
+    /*
+     * See if anything went wrong
+     */
+    if (status & (M8xx_BD_DEFER |
+                  M8xx_BD_HEARTBEAT |
+                  M8xx_BD_LATE_COLLISION |
+                  M8xx_BD_RETRY_LIMIT |
+                  M8xx_BD_UNDERRUN |
+                  M8xx_BD_CARRIER_LOST)) {
+      /*
+       * Check for errors which stop the transmitter.
+       */
+      if (status & (M8xx_BD_LATE_COLLISION |
+                    M8xx_BD_RETRY_LIMIT |
+                    M8xx_BD_UNDERRUN)) {
+        if (status & M8xx_BD_LATE_COLLISION)
+          enet_driver[0].txLateCollision++;
+        if (status & M8xx_BD_RETRY_LIMIT)
+          enet_driver[0].txRetryLimit++;
+        if (status & M8xx_BD_UNDERRUN)
+          enet_driver[0].txUnderrun++;
+
+        /*
+         * Restart the transmitter
+         */
+        m8xx_cp_execute_cmd (M8xx_CR_OP_RESTART_TX | M8xx_CR_CHAN_SCC1);
+      }
+      if (status & M8xx_BD_DEFER)
+        enet_driver[0].txDeferred++;
+      if (status & M8xx_BD_HEARTBEAT)
+        enet_driver[0].txHeartbeat++;
+      if (status & M8xx_BD_CARRIER_LOST)
+        enet_driver[0].txLostCarrier++;
+    }
+    nRetired++;
+    if (status & M8xx_BD_LAST) {
+      /*
+       * A full frame has been transmitted.
+       * Free all the associated buffer descriptors.
+       */
+      sc->txBdActiveCount -= nRetired;
+      while (nRetired) {
+        nRetired--;
+        m = sc->txMbuf[sc->txBdTail];
+        MFREE (m, n);
+        if (++sc->txBdTail == sc->txBdCount)
+          sc->txBdTail = 0;
+      }
+    }
+    if (++i == sc->txBdCount)
+      i = 0;
+  }
+}
+
+/*
+ * reader task
+ */
+static void
+scc_rxDaemon (void *arg)
+{
+  struct m8xx_enet_struct *sc = (struct m8xx_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  uint16_t   status;
+  m8xxBufferDescriptor_t *rxBd;
+  int rxBdIndex;
+
+  /*
+   * Allocate space for incoming packets and start reception
+   */
+  for (rxBdIndex = 0 ; ;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+    MGETHDR (m, M_WAIT, MT_DATA);
+    MCLGET (m, M_WAIT);
+    m->m_pkthdr.rcvif = ifp;
+    sc->rxMbuf[rxBdIndex] = m;
+    rxBd->buffer = mtod (m, void *);
+    rxBd->status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
+    if (++rxBdIndex == sc->rxBdCount) {
+      rxBd->status |= M8xx_BD_WRAP;
+      break;
+    }
+  }
+
+  /*
+   * Input packet handling loop
+   */
+  rxBdIndex = 0;
+  for (;;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+
+    /*
+     * Wait for packet if there's not one ready
+     */
+    if ((status = rxBd->status) & M8xx_BD_EMPTY) {
+      /*
+       * Clear old events
+       */
+      m8xx.scc1.scce = 0x8;
+
+      /*
+       * Wait for packet
+       * Note that the buffer descriptor is checked
+       * *before* the event wait -- this catches the
+       * possibility that a packet arrived between the
+       * `if' above, and the clearing of the event register.
+       */
+      while ((status = rxBd->status) & M8xx_BD_EMPTY) {
+        rtems_event_set events;
+
+        /*
+         * Unmask RXF (Full frame received) event
+         */
+        m8xx.scc1.sccm |= 0x8;
+
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+      }
+    }
+
+    /*
+     * Check that packet is valid
+     */
+    if ((status & (M8xx_BD_LAST |
+                   M8xx_BD_FIRST_IN_FRAME |
+                   M8xx_BD_LONG |
+                   M8xx_BD_NONALIGNED |
+                   M8xx_BD_SHORT |
+                   M8xx_BD_CRC_ERROR |
+                   M8xx_BD_OVERRUN |
+                   M8xx_BD_COLLISION)) ==
+        (M8xx_BD_LAST |
+         M8xx_BD_FIRST_IN_FRAME)) {
+      /*
+       * Pass the packet up the chain.
+       * FIXME: Packet filtering hook could be done here.
+       */
+      struct ether_header *eh;
+
+      /*
+       * Invalidate the buffer for this descriptor
+       */
+      rtems_cache_invalidate_multiple_data_lines((const void *)rxBd->buffer, rxBd->length);
+
+      m = sc->rxMbuf[rxBdIndex];
+      m->m_len = m->m_pkthdr.len = rxBd->length -
+        sizeof(uint32_t) -
+        sizeof(struct ether_header);
+      eh = mtod (m, struct ether_header *);
+      m->m_data += sizeof(struct ether_header);
+      ether_input (ifp, eh, m);
+
+      /*
+       * Allocate a new mbuf
+       */
+      MGETHDR (m, M_WAIT, MT_DATA);
+      MCLGET (m, M_WAIT);
+      m->m_pkthdr.rcvif = ifp;
+      sc->rxMbuf[rxBdIndex] = m;
+      rxBd->buffer = mtod (m, void *);
+    }
+    else {
+      /*
+       * Something went wrong with the reception
+       */
+      if (!(status & M8xx_BD_LAST))
+        sc->rxNotLast++;
+      if (!(status & M8xx_BD_FIRST_IN_FRAME))
+        sc->rxNotFirst++;
+      if (status & M8xx_BD_LONG)
+        sc->rxGiant++;
+      if (status & M8xx_BD_NONALIGNED)
+        sc->rxNonOctet++;
+      if (status & M8xx_BD_SHORT)
+        sc->rxRunt++;
+      if (status & M8xx_BD_CRC_ERROR)
+        sc->rxBadCRC++;
+      if (status & M8xx_BD_OVERRUN)
+        sc->rxOverrun++;
+      if (status & M8xx_BD_COLLISION)
+        sc->rxCollision++;
+    }
+
+    /*
+     * Reenable the buffer descriptor
+     */
+    rxBd->status = (status & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) |
+      M8xx_BD_EMPTY;
+
+    /*
+     * Move to next buffer descriptor
+     */
+    if (++rxBdIndex == sc->rxBdCount)
+      rxBdIndex = 0;
+  }
+}
+
+
+static void
+scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+  struct m8xx_enet_struct *sc = ifp->if_softc;
+  volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
+  struct mbuf *l = NULL;
+  uint16_t   status;
+  int nAdded;
+
+  /*
+   * Free up buffer descriptors
+   */
+  m8xx_Enet_retire_tx_bd (sc);
+
+  /*
+   * Set up the transmit buffer descriptors.
+   * No need to pad out short packets since the
+   * hardware takes care of that automatically.
+   * No need to copy the packet to a contiguous buffer
+   * since the hardware is capable of scatter/gather DMA.
+   */
+  nAdded = 0;
+  txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
+  for (;;) {
+    /*
+     * Wait for buffer descriptor to become available.
+     */
+    if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+      /*
+       * Clear old events
+       */
+      m8xx.scc1.scce = 0x12;
+
+      /*
+       * Wait for buffer descriptor to become available.
+       * Note that the buffer descriptors are checked
+       * *before* * entering the wait loop -- this catches
+       * the possibility that a buffer descriptor became
+       * available between the `if' above, and the clearing
+       * of the event register.
+       * This is to catch the case where the transmitter
+       * stops in the middle of a frame -- and only the
+       * last buffer descriptor in a frame can generate
+       * an interrupt.
+       */
+      m8xx_Enet_retire_tx_bd (sc);
+      while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+        rtems_event_set events;
+
+	/*
+	 * Unmask TXB (buffer transmitted) and
+	 * TXE (transmitter error) events.
+	 */
+        m8xx.scc1.sccm |= 0x12;
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+        m8xx_Enet_retire_tx_bd (sc);
+      }
+    }
+
+    /*
+     * Don't set the READY flag till the
+     * whole packet has been readied.
+     */
+    status = nAdded ? M8xx_BD_READY : 0;
+
+    /*
+     *  FIXME: Why not deal with empty mbufs at at higher level?
+     * The IP fragmentation routine in ip_output
+     * can produce packet fragments with zero length.
+     * I think that ip_output should be changed to get
+     * rid of these zero-length mbufs, but for now,
+     * I'll deal with them here.
+     */
+    if (m->m_len) {
+      /*
+       * Fill in the buffer descriptor
+       */
+      txBd->buffer = mtod (m, void *);
+      txBd->length = m->m_len;
+
+      /*
+       * Flush the buffer for this descriptor
+       */
+      rtems_cache_flush_multiple_data_lines((const void *)txBd->buffer, txBd->length);
+
+      sc->txMbuf[sc->txBdHead] = m;
+      nAdded++;
+      if (++sc->txBdHead == sc->txBdCount) {
+        status |= M8xx_BD_WRAP;
+        sc->txBdHead = 0;
+      }
+      l = m;
+      m = m->m_next;
+    }
+    else {
+      /*
+       * Just toss empty mbufs
+       */
+      struct mbuf *n;
+      MFREE (m, n);
+      m = n;
+      if (l != NULL)
+        l->m_next = m;
+    }
+
+    /*
+     * Set the transmit buffer status.
+     * Break out of the loop if this mbuf is the last in the frame.
+     */
+    if (m == NULL) {
+      if (nAdded) {
+        status |= M8xx_BD_PAD | M8xx_BD_LAST | M8xx_BD_TX_CRC | M8xx_BD_INTERRUPT;
+        txBd->status = status;
+        firstTxBd->status |= M8xx_BD_READY;
+        sc->txBdActiveCount += nAdded;
+      }
+      break;
+    }
+    txBd->status = status;
+    txBd = sc->txBdBase + sc->txBdHead;
+  }
+}
+
+
+/*
+ * Driver transmit daemon
+ */
+void
+scc_txDaemon (void *arg)
+{
+  struct m8xx_enet_struct *sc = (struct m8xx_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  rtems_event_set events;
+
+  for (;;) {
+    /*
+     * Wait for packet
+     */
+    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
+
+    /*
+     * Send packets till queue is empty
+     */
+    for (;;) {
+      /*
+       * Get the next mbuf chain to transmit.
+       */
+      IF_DEQUEUE(&ifp->if_snd, m);
+      if (!m)
+        break;
+      scc_sendpacket (ifp, m);
+    }
+    ifp->if_flags &= ~IFF_OACTIVE;
+  }
+}
+
+
+/*
+ * Send packet (caller provides header).
+ */
+static void
+m8xx_enet_start (struct ifnet *ifp)
+{
+  struct m8xx_enet_struct *sc = ifp->if_softc;
+
+  rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
+  ifp->if_flags |= IFF_OACTIVE;
+}
+
+/*
+ * Initialize and start the device
+ */
+static void
+scc_init (void *arg)
+{
+  struct m8xx_enet_struct *sc = arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+
+  if (sc->txDaemonTid == 0) {
+
+    /*
+     * Set up SCC hardware
+     */
+    m8xx_enet_initialize (sc);
+
+    /*
+     * Start driver tasks
+     */
+    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, scc_txDaemon, sc);
+    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, scc_rxDaemon, sc);
+
+  }
+
+  /*
+   * Set flags appropriately
+   */
+  if (ifp->if_flags & IFF_PROMISC)
+    m8xx.scc1.psmr |= 0x200;
+  else
+    m8xx.scc1.psmr &= ~0x200;
+
+  /*
+   * Tell the world that we're running.
+   */
+  ifp->if_flags |= IFF_RUNNING;
+
+  /*
+   * Enable receiver and transmitter
+   */
+  m8xx.scc1.gsmr_l |= 0x30;
+}
+
+
+/*
+ * Stop the device
+ */
+static void
+scc_stop (struct m8xx_enet_struct *sc)
+{
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+
+  ifp->if_flags &= ~IFF_RUNNING;
+
+  /*
+   * Shut down receiver and transmitter
+   */
+  m8xx.scc1.gsmr_l &= ~0x30;
+}
+
+
+/*
+ * Show interface statistics
+ */
+static void
+enet_stats (struct m8xx_enet_struct *sc)
+{
+  printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
+  printf ("       Not First:%-8lu", sc->rxNotFirst);
+  printf ("        Not Last:%-8lu\n", sc->rxNotLast);
+  printf ("              Giant:%-8lu", sc->rxGiant);
+  printf ("            Runt:%-8lu", sc->rxRunt);
+  printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
+  printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
+  printf ("         Overrun:%-8lu", sc->rxOverrun);
+  printf ("       Collision:%-8lu\n", sc->rxCollision);
+  printf ("          Discarded:%-8lu\n", (unsigned long)m8xx.scc1p.un.ethernet.disfc);
+
+  printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
+  printf ("        Deferred:%-8lu", sc->txDeferred);
+  printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
+  printf ("         No Carrier:%-8lu", sc->txLostCarrier);
+  printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
+  printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
+  printf ("           Underrun:%-8lu", sc->txUnderrun);
+  printf (" Raw output wait:%-8lu\n", sc->txRawWait);
+}
+
+/*
+ * Driver ioctl handler
+ */
+static int
+scc_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
+{
+  struct m8xx_enet_struct *sc = ifp->if_softc;
+  int error = 0;
+
+  switch (command) {
+  case SIOCGIFADDR:
+  case SIOCSIFADDR:
+    ether_ioctl (ifp, command, data);
+    break;
+
+  case SIOCSIFFLAGS:
+    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+    case IFF_RUNNING:
+      scc_stop (sc);
+      break;
+
+    case IFF_UP:
+      scc_init (sc);
+      break;
+
+    case IFF_UP | IFF_RUNNING:
+      scc_stop (sc);
+      scc_init (sc);
+      break;
+
+    default:
+      break;
+    }
+    break;
+
+  case SIO_RTEMS_SHOW_STATS:
+    enet_stats (sc);
+    break;
+
+    /*
+     * FIXME: All sorts of multicast commands need to be added here!
+     */
+  default:
+    error = EINVAL;
+    break;
+  }
+  return error;
+}
+
+
+/*
+ * Attach an SCC driver to the system
+ */
+int
+rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+  struct m8xx_enet_struct *sc;
+  struct ifnet *ifp;
+  int mtu;
+  int unitNumber;
+  char *unitName;
+  static const uint8_t maczero[] ={0,0,0,0,0,0};
+  /*
+   * Parse driver name
+   */
+  if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
+    return 0;
+
+  /*
+   * Is driver free?
+   */
+  if ((unitNumber <= 0) || (unitNumber > NIFACES)) {
+    printf ("Bad SCC unit number.\n");
+    return 0;
+  }
+  sc = &enet_driver[unitNumber - 1];
+  ifp = &sc->arpcom.ac_if;
+  if (ifp->if_softc != NULL) {
+    printf ("Driver already in use.\n");
+    return 0;
+  }
+
+  /*
+   * Process options
+   */
+
+  /*
+   * MAC address: try to fetch it from config, else from TQMMon, else panic
+   */
+  if (config->hardware_address) {
+    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+  }
+#ifdef BSP_HAS_TQMMON
+  else if(0 != memcmp(maczero,TQM_BD_INFO.eth_addr,ETHER_ADDR_LEN)) {
+    memcpy (sc->arpcom.ac_enaddr, TQM_BD_INFO.eth_addr, ETHER_ADDR_LEN);
+  }
+#endif
+  else {
+    /* There is no ethernet address provided, so it could be read
+     * from the Ethernet protocol block of SCC1 in DPRAM.
+     */
+    rtems_panic("No Ethernet address specified!\n");
+  }
+
+  if (config->mtu)
+    mtu = config->mtu;
+  else
+    mtu = ETHERMTU;
+  if (config->rbuf_count)
+    sc->rxBdCount = config->rbuf_count;
+  else
+    sc->rxBdCount = RX_BUF_COUNT;
+  if (config->xbuf_count)
+    sc->txBdCount = config->xbuf_count;
+  else
+    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+  sc->acceptBroadcast = !config->ignore_broadcast;
+
+  /*
+   * Set up network interface values
+   */
+  ifp->if_softc = sc;
+  ifp->if_unit = unitNumber;
+  ifp->if_name = unitName;
+  ifp->if_mtu = mtu;
+  ifp->if_init = scc_init;
+  ifp->if_ioctl = scc_ioctl;
+  ifp->if_start = m8xx_enet_start;
+  ifp->if_output = ether_output;
+  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+  if (ifp->if_snd.ifq_maxlen == 0)
+    ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+  /*
+   * Attach the interface
+   */
+  if_attach (ifp);
+  ether_ifattach (ifp);
+  return 1;
+};
+
+int
+rtems_scc_enet_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
+{
+  return rtems_scc1_driver_attach(config);
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/preinstall.am
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/preinstall.am	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/preinstall.am	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,104 @@
+## Automatically generated by ampolish3 - Do not edit
+
+if AMPOLISH3
+$(srcdir)/preinstall.am: Makefile.am
+	$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
+endif
+
+PREINSTALL_DIRS =
+DISTCLEANFILES += $(PREINSTALL_DIRS)
+
+all-local: $(TMPINSTALL_FILES)
+
+TMPINSTALL_FILES =
+CLEANFILES = $(TMPINSTALL_FILES)
+
+all-am: $(PREINSTALL_FILES)
+
+PREINSTALL_FILES =
+CLEANFILES += $(PREINSTALL_FILES)
+
+$(PROJECT_LIB)/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_LIB)
+	@: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)
+	@: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
+PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
+
+$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
+
+$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
+
+../../../libcpu/@RTEMS_CPU@/$(dirstamp):
+	@$(MKDIR_P) ../../../libcpu/@RTEMS_CPU@
+	@: > ../../../libcpu/@RTEMS_CPU@/$(dirstamp)
+PREINSTALL_DIRS += ../../../libcpu/@RTEMS_CPU@/$(dirstamp)
+
+$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
+
+$(PROJECT_INCLUDE)/bsp/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
+	@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+
+$(PROJECT_INCLUDE)/coverhd.h: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+
+$(PROJECT_INCLUDE)/bsp/tqm.h: include/tqm.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/tqm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/tqm.h
+
+$(PROJECT_INCLUDE)/bsp/8xx_immap.h: include/8xx_immap.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/8xx_immap.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/8xx_immap.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
+
+$(PROJECT_INCLUDE)/bsp/irq-config.h: include/irq-config.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-config.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-config.h
+
+$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
+
+$(PROJECT_INCLUDE)/bsp/vectors.h: $(libcpudir)/@exceptions@/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
+
+$(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h: $(libcpudir)/@exceptions@/bspsupport/ppc_exc_bspsupp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
+
+$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
+
+$(PROJECT_LIB)/rtems_crti.$(OBJEXT): rtems_crti.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
+
+$(PROJECT_LIB)/linkcmds.base: startup/linkcmds.base $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.base
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
+
+$(PROJECT_LIB)/linkcmds.tqm8xx: startup/linkcmds.tqm8xx $(PROJECT_LIB)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.tqm8xx
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.tqm8xx
+
Index: c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,234 @@
+/**
+ * @file
+ *
+ * @ingroup tqm8xx
+ *
+ * @brief Source for BSP startup code.
+ */
+
+/*
+ * Copyright (c) 2008
+ * Embedded Brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * rtems@embedded-brains.de
+ *
+ * The license and distribution terms for this file may be found in the file
+ * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <rtems/score/thread.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+/* #include <bsp/irq-generic.h>
+   #include <bsp/ppc_exc_bspsupp.h> */
+
+#ifdef BSP_HAS_TQMMON
+/*
+ * FIXME: TQ Monitor structure
+ */
+#endif /* BSP_HAS_TQMMON */
+
+/* Configuration parameters for console driver, ... */
+unsigned int BSP_bus_frequency;
+
+/* Configuration parameters for clock driver, ... */
+uint32_t bsp_clicks_per_usec; /* for PIT driver: OSCCLK */
+uint32_t bsp_clock_speed    ; /* needed for PIT driver  */
+
+/*
+ *  Use the shared implementations of the following routines.
+ *  Look in rtems/c/src/lib/libbsp/shared/bsplibc.c.
+ */
+extern void cpu_init( void);
+
+void BSP_panic( char *s)
+{
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable( level);
+
+  printk( "%s PANIC %s\n", _RTEMS_version, s);
+
+  while (1) {
+    /* Do nothing */
+  }
+}
+
+void _BSP_Fatal_error( unsigned n)
+{
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable( level);
+
+  printk( "%s PANIC ERROR %u\n", _RTEMS_version, n);
+
+  while (1) {
+    /* Do nothing */
+  }
+}
+
+void bsp_pretasking_hook( void)
+{
+  /* Do noting */
+}
+
+const char *bsp_tqm_get_cib_string( const char *cib_id)
+{
+  char srch_pattern[10] = "";
+  char *fnd_str;
+  /* 
+   * create search pattern
+   */
+  strcat(srch_pattern,"-");
+  strncat(srch_pattern,
+	  cib_id,
+	  sizeof(srch_pattern)-1-strlen(srch_pattern));
+  strncat(srch_pattern,
+	  " ",
+	  sizeof(srch_pattern)-1-strlen(srch_pattern));
+  /*
+   * search for pattern in info block (CIB)
+   */
+  fnd_str = strstr(TQM_CONF_INFO_BLOCK_ADDR,srch_pattern);
+
+  if (fnd_str == NULL) {
+    return NULL;
+  }
+  else {
+    /*
+     * found? then advance behind search pattern
+     */
+    return fnd_str + strlen(srch_pattern);
+  }
+}
+
+rtems_status_code  bsp_tqm_get_cib_uint32( const char *cib_id,
+					   uint32_t   *result)
+{
+  const char *item_ptr;
+  const char *end_ptr;
+  item_ptr = bsp_tqm_get_cib_string(cib_id);
+  if (item_ptr == NULL) {
+    return RTEMS_INVALID_ID;
+  }
+  /*
+   * convert string to uint32
+   */
+  *result = strtoul(item_ptr,&end_ptr,10);
+  return RTEMS_SUCCESSFUL;
+}
+
+void bsp_get_work_area( void **work_area_start, size_t *work_area_size, void **heap_start, size_t *heap_size)
+{
+  char *ram_end = (char *) (TQM_BD_INFO.sdram_size - (uint32_t)TopRamReserved);
+
+  *work_area_start = bsp_work_area_start;
+  *work_area_size = ram_end - bsp_work_area_start;
+  *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
+  *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
+}
+
+void bsp_start( void)
+{
+  ppc_cpu_id_t myCpu;
+  ppc_cpu_revision_t myCpuRevision;
+
+  uint32_t interrupt_stack_start = (uint32_t) bsp_interrupt_stack_start;
+  uint32_t interrupt_stack_size = (uint32_t) bsp_interrupt_stack_size;
+
+  /*
+   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
+   * store the result in global variables so that it can be used latter...
+   */
+  myCpu = get_ppc_cpu_type();
+  myCpuRevision = get_ppc_cpu_revision();
+
+  /* Basic CPU initialization */
+  cpu_init();
+
+  /*
+   * Enable instruction and data caches. Do not force writethrough mode.
+   */
+
+#if INSTRUCTION_CACHE_ENABLE
+  rtems_cache_enable_instruction();
+#endif
+
+#if DATA_CACHE_ENABLE
+  rtems_cache_enable_data();
+#endif
+
+  /*
+   * This is evaluated during runtime, so it should be ok to set it
+   * before we initialize the drivers.
+   */
+
+  /* Initialize some device driver parameters */
+  /*
+   * get the (internal) bus frequency
+   * NOTE: the external bus may be clocked at a lower speed
+   * but this does not concern the internal units like PIT, 
+   * DEC, baudrate generator etc)
+   */
+  if (RTEMS_SUCCESSFUL != 
+      bsp_tqm_get_cib_uint32("cu",
+			     &BSP_bus_frequency)) {
+    BSP_panic("Cannot determine BUS frequency\n");
+  }
+
+  bsp_clicks_per_usec = 0; /* force to zero to control 
+			    * PIT clock driver from EXTCLK
+			    */
+  bsp_clock_speed     = BSP_bus_frequency;
+
+  /* Initialize exception handler */
+  ppc_exc_initialize(PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
+		     interrupt_stack_start,
+		     interrupt_stack_size
+		     );
+
+  /* Initalize interrupt support */
+  if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
+    BSP_panic("Cannot intitialize interrupt support\n");
+  }
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+  printk("Exit from bspstart\n");
+#endif
+}
+
+/**
+ * @brief Idle thread body.
+ *
+ * Replaces the one in c/src/exec/score/src/threadidlebody.c
+ * The MSR[POW] bit is set to put the CPU into the low power mode
+ * defined in HID0.  HID0 is set during starup in start.S.
+ */
+Thread _Thread_Idle_body( uint32_t ignored)
+{
+
+  while (1) {
+    asm volatile (
+		  "mfmsr 3;"
+		  "oris 3, 3, 4;"
+		  "sync;"
+		  "mtmsr 3;"
+		  "isync;"
+		  "ori 3, 3, 0;"
+		  "ori 3, 3, 0"
+		  );
+  }
+
+  return NULL;
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/startup/cpuinit.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,134 @@
+/*
+ *  cpuinit.c
+ *
+ *  TQM8xx initialization routines.
+ * derived from MBX8xx BSP
+ * adapted to TQM8xx by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ *
+ *  Copyright (c) 1999, National Research Council of Canada
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/tqm.h>
+
+
+/*
+ *  Initialize TQM8xx
+ */
+void _InitTQM8xx (void)
+{
+  register uint32_t   r1;
+
+  /*
+   * Initialize the Instruction Support Control Register (ICTRL) to a
+   * an appropriate value for normal operation. A different value,
+   * such as 0x0, may be more appropriate for debugging.
+   */
+  r1 = 0x00000007;
+  _mtspr( M8xx_ICTRL, r1 );
+
+  /*
+   * Disable and invalidate the instruction and data caches.
+   */
+  r1 = M8xx_CACHE_CMD_DISABLE;
+  _mtspr( M8xx_IC_CST, r1 );
+  _isync;
+  r1 = M8xx_CACHE_CMD_UNLOCKALL;
+  _mtspr( M8xx_IC_CST, r1 );
+  _isync;
+  r1 = M8xx_CACHE_CMD_INVALIDATE;	/* invalidate all */
+  _mtspr( M8xx_IC_CST, r1 );
+  _isync;
+
+  r1 = M8xx_CACHE_CMD_DISABLE;
+  _mtspr( M8xx_DC_CST, r1 );
+  _isync;
+  r1 = M8xx_CACHE_CMD_UNLOCKALL;
+  _mtspr( M8xx_DC_CST, r1 );
+  _isync;
+  r1 = M8xx_CACHE_CMD_INVALIDATE;	/* invalidate all */
+  _mtspr( M8xx_DC_CST, r1 );
+  _isync;
+
+  /*
+   * Initialize the SIU Module Configuration Register (SIUMCR)
+   * m8xx.siumcr = 0x00602900, the default value.
+   */
+  m8xx.siumcr = M8xx_SIUMCR_EARP0 | M8xx_SIUMCR_DBGC3 | M8xx_SIUMCR_DBPC0 |
+		M8xx_SIUMCR_DPC | M8xx_SIUMCR_MLRC2 | M8xx_SIUMCR_SEME;
+
+  /*
+   * Initialize the System Protection Control Register (SYPCR).
+   * The SYPCR can only be written once after Reset.
+   *	- Enable bus monitor
+   *	- Disable software watchdog timer
+   * m8xx.sypcr = 0xFFFFFF88, the default MBX and firmware value.
+   */
+  m8xx.sypcr = M8xx_SYPCR_SWTC(0xFFFF) | M8xx_SYPCR_BMT(0xFF) |
+		M8xx_SYPCR_BME | M8xx_SYPCR_SWF;
+
+  /* Initialize the SIU Interrupt Edge Level Mask Register (SIEL) */
+  m8xx.siel = 0xAAAA0000;         	/* Default MBX and firmware value. */
+
+  /* Initialize the Transfer Error Status Register (TESR) */
+  m8xx.tesr = 0xFFFFFFFF;         	/* Default firmware value. */
+
+  /* Initialize the SDMA Configuration Register (SDCR) */
+  m8xx.sdcr = 0x00000001;         	/* Default firmware value. */
+
+  /*
+   * Initialize the Timebase Status and Control Register (TBSCR)
+   * m8xx.tbscr = 0x00C3, default MBX and firmware value.
+   */
+  m8xx.tbscrk = M8xx_UNLOCK_KEY;	/* unlock TBSCR */
+  m8xx.tbscr = M8xx_TBSCR_REFA | M8xx_TBSCR_REFB |
+  		M8xx_TBSCR_TBF | M8xx_TBSCR_TBE;
+
+  /* Initialize the Real-Time Clock Status and Control Register (RTCSC) */
+  m8xx.rtcsk = M8xx_UNLOCK_KEY;		/* unlock RTCSC */
+  m8xx.rtcsc = 0x00C3;			/* Default MBX and firmware value. */
+
+  /* Unlock other Real-Time Clock registers */
+  m8xx.rtck = M8xx_UNLOCK_KEY;		/* unlock RTC */
+  m8xx.rtseck = M8xx_UNLOCK_KEY;	/* unlock RTSEC */
+  m8xx.rtcalk = M8xx_UNLOCK_KEY;	/* unlock RTCAL */
+
+  /* Initialize the Periodic Interrupt Status and Control Register (PISCR) */
+  m8xx.piscrk = M8xx_UNLOCK_KEY;	/* unlock PISCR */
+  m8xx.piscr = 0x0083; 			/* Default MBX and firmware value. */
+
+  /* Initialize the System Clock and Reset Control Register (SCCR)
+   * Set the clock sources and division factors:
+   *   Timebase Source is GCLK2 / 16
+   */
+  m8xx.sccrk = M8xx_UNLOCK_KEY;		/* unlock SCCR */
+  m8xx.sccr |= 0x02000000;		
+
+  /* Unlock the timebase and decrementer registers. */
+  m8xx.tbk = M8xx_UNLOCK_KEY;
+  /*
+   * Initialize decrementer register to a large value to
+   * guarantee that a decrementer interrupt will not be
+   * generated before the kernel is fully initialized.
+   */
+  r1 = 0x7FFFFFFF;
+  _mtspr( M8xx_DEC, r1 );
+
+  /* Initialize the timebase register (TB is 64 bits) */
+  r1 = 0x00000000;
+  _mtspr( M8xx_TBU_WR, r1 );
+  _mtspr( M8xx_TBL_WR, r1 );
+}
+/*
+ * further initialization (called from bsp_start) 
+ */
+void cpu_init(void)
+{
+  /*
+   * none up to now
+   */
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.base	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,316 @@
+/**
+ * @file
+ *
+ * Derived from internal linker script of GNU ld (GNU Binutils) 2.18 for elf32ppc emulation.
+ */
+
+OUTPUT_FORMAT ("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH (powerpc)
+ENTRY (start)
+
+bsp_ram_start = ORIGIN (RAM);
+bsp_ram_end = ORIGIN (RAM) + LENGTH (RAM);
+bsp_ram_size = LENGTH (RAM);
+
+bsp_rom_start = ORIGIN (ROM);
+bsp_rom_end = ORIGIN (ROM) + LENGTH (ROM);
+bsp_rom_size = LENGTH (ROM);
+
+bsp_section_align = 32;
+
+SECTIONS {
+
+	dpram : 
+	{	   
+	  m8xx = .;	
+	  _m8xx = .;
+	  /*   . += (16 * 1024); this makes the mbx loader crash */
+        } >immr
+
+	/*
+	 * BSP: Exception vectors
+	 */
+	.vectors 0x100 : {
+		*(.vectors)
+	} > RAM
+
+	/* 
+	 * BSP: The initial stack will live in this area - between the vectors
+	 * and the text section.
+	 */
+
+	.text 0x10000 : {
+		/*
+		 * BSP: Start of text section
+		 */
+		bsp_section_text_start = .;
+
+		/*
+		 * BSP: System startup entry
+		 */
+		KEEP (*(.entry))
+
+		/*
+		 * BSP: Moved into .text from .init
+		 */
+		KEEP (*(.init))
+
+		*(.text .stub .text.* .gnu.linkonce.t.*)
+		KEEP (*(.text.*personality*))
+		/* .gnu.warning sections are handled specially by elf32.em.  */
+		*(.gnu.warning)
+		*(.glink)
+		
+		/*
+		 * BSP: Special FreeBSD sysctl sections
+		 */
+		. = ALIGN (16);
+		__start_set_sysctl_set = .;
+		*(set_sysctl_*);
+		__stop_set_sysctl_set = ABSOLUTE(.);
+		*(set_domain_*);
+		*(set_pseudo_*);
+
+		/*
+		 * BSP: Moved into .text from .*
+		 */
+		*(.rodata .rodata.* .gnu.linkonce.r.*)
+		*(.rodata1)
+		*(.interp)
+		*(.note.gnu.build-id)
+		*(.hash)
+		*(.gnu.hash)
+		*(.dynsym)
+		*(.dynstr)
+		*(.gnu.version)
+		*(.gnu.version_d)
+		*(.gnu.version_r)
+		*(.eh_frame_hdr)
+
+		/*
+		 * BSP: Magic PPC stuff
+		 */
+		*(.PPC.*)
+
+		/*
+		 * BSP: Required by cpukit/score/src/threadhandler.c
+		 */
+		PROVIDE (_fini = .);
+
+		/*
+		 * BSP: Moved into .text from .fini
+		 */
+		KEEP (*(.fini))
+
+		. = ALIGN (bsp_section_align);
+
+		PROVIDE (__etext = .);
+		PROVIDE (_etext = .);
+		PROVIDE (etext = .);
+	} > RAM
+
+	.sdata2 : {
+		PROVIDE (_SDA2_BASE_ = 32768);
+
+		*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+
+		. = ALIGN (bsp_section_align);
+	} > RAM
+
+	.sbss2 : {
+		*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+
+		. = ALIGN (bsp_section_align);
+
+		/*
+		 * BSP: End and size of text section
+		 */
+		bsp_section_text_end = .;
+		bsp_section_text_size = bsp_section_text_end - bsp_section_text_start;
+	} > RAM
+
+	.data : {
+		/*
+		 * BSP: Start of data section
+		 */
+		bsp_section_data_start = .;
+
+		/*
+		 * BSP: Moved into .data from .ctors
+		 */
+		/* gcc uses crtbegin.o to find the start of
+		   the constructors, so we make sure it is
+		   first.  Because this is a wildcard, it
+		   doesn't matter if the user does not
+		   actually link against crtbegin.o; the
+		   linker won't look for a file to match a
+		   wildcard.  The wildcard also means that it
+		   doesn't matter which directory crtbegin.o
+		   is in.  */
+		KEEP (*crtbegin.o(.ctors))
+		KEEP (*crtbegin?.o(.ctors))
+		/* We don't want to include the .ctor section from
+		   the crtend.o file until after the sorted ctors.
+		   The .ctor section from the crtend file contains the
+		   end of ctors marker and it must be last */
+		KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+		KEEP (*(SORT(.ctors.*)))
+		KEEP (*(.ctors))
+
+		/*
+		 * BSP: Moved into .data from .dtors
+		 */
+		KEEP (*crtbegin.o(.dtors))
+		KEEP (*crtbegin?.o(.dtors))
+		KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+		KEEP (*(SORT(.dtors.*)))
+		KEEP (*(.dtors))
+
+		/*
+		 * BSP: Moved into .data from .*
+		 */
+		*(.tdata .tdata.* .gnu.linkonce.td.*)
+		*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+		*(.data1)
+		KEEP (*(.eh_frame))
+		*(.gcc_except_table .gcc_except_table.*)
+		KEEP (*(.jcr))
+		*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
+		*(.fixup)
+		*(.got1)
+		*(.got2)
+		*(.dynamic)
+		*(.got)
+		*(.plt)
+		PROVIDE_HIDDEN (__preinit_array_start = .);
+		KEEP (*(.preinit_array))
+		PROVIDE_HIDDEN (__preinit_array_end = .);
+		PROVIDE_HIDDEN (__init_array_start = .);
+		KEEP (*(SORT(.init_array.*)))
+		KEEP (*(.init_array))
+		PROVIDE_HIDDEN (__init_array_end = .);
+		PROVIDE_HIDDEN (__fini_array_start = .);
+		KEEP (*(.fini_array))
+		KEEP (*(SORT(.fini_array.*)))
+		PROVIDE_HIDDEN (__fini_array_end = .);
+
+		*(.data .data.* .gnu.linkonce.d.*)
+		KEEP (*(.gnu.linkonce.d.*personality*))
+		SORT(CONSTRUCTORS)
+
+		. = ALIGN (bsp_section_align);
+	} > RAM
+
+	.sdata : {
+		PROVIDE (_SDA_BASE_ = 32768);
+		*(.sdata .sdata.* .gnu.linkonce.s.*)
+
+		. = ALIGN (bsp_section_align);
+
+		_edata = .;
+		PROVIDE (edata = .);
+
+		/*
+		 * BSP: End and size of data section
+		 */
+		bsp_section_data_end = .;
+		bsp_section_data_size = bsp_section_data_end - bsp_section_data_start;
+	} > RAM
+
+	.sbss : {
+		/*
+		 * BSP: Start of bss section
+		 */
+		bsp_section_bss_start = .;
+
+		__bss_start = .;
+
+		PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
+		*(.scommon)
+		*(.dynsbss)
+		*(.sbss .sbss.* .gnu.linkonce.sb.*)
+		PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
+
+		. = ALIGN (bsp_section_align);
+	} > RAM
+
+	.bss : {
+		*(COMMON)
+		*(.dynbss)
+		*(.bss .bss.* .gnu.linkonce.b.*)
+
+		. = ALIGN (bsp_section_align);
+
+		__end = .;
+		_end = .;
+		PROVIDE (end = .);
+
+		/*
+		 * BSP: End and size of bss section
+		 */
+		bsp_section_bss_end = .;
+		bsp_section_bss_size = bsp_section_bss_end - bsp_section_bss_start;
+	} > RAM
+
+	/*
+	 * BSP: Interrupt stack
+	 */
+	bsp_interrupt_stack_start = .;
+	bsp_interrupt_stack_end = bsp_interrupt_stack_start + 32k;
+	bsp_interrupt_stack_size = bsp_interrupt_stack_end - bsp_interrupt_stack_start;
+	. = bsp_interrupt_stack_end;
+
+	/*
+	 * BSP: Work area start
+	 */
+	bsp_work_area_start = .;
+	
+	/* Stabs debugging sections.  */
+	.stab          0 : { *(.stab) }
+	.stabstr       0 : { *(.stabstr) }
+	.stab.excl     0 : { *(.stab.excl) }
+	.stab.exclstr  0 : { *(.stab.exclstr) }
+	.stab.index    0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment       0 : { *(.comment) }
+	/* DWARF debug sections.
+	   Symbols in the DWARF debugging sections are relative to the beginning
+	   of the section so we begin them at 0.  */
+	/* DWARF 1 */
+	.debug          0 : { *(.debug) }
+	.line           0 : { *(.line) }
+	/* GNU DWARF 1 extensions */
+	.debug_srcinfo  0 : { *(.debug_srcinfo) }
+	.debug_sfnames  0 : { *(.debug_sfnames) }
+	/* DWARF 1.1 and DWARF 2 */
+	.debug_aranges  0 : { *(.debug_aranges) }
+	.debug_pubnames 0 : { *(.debug_pubnames) }
+	/* DWARF 2 */
+	.debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+	.debug_abbrev   0 : { *(.debug_abbrev) }
+	.debug_line     0 : { *(.debug_line) }
+	.debug_frame    0 : { *(.debug_frame) }
+	.debug_str      0 : { *(.debug_str) }
+	.debug_loc      0 : { *(.debug_loc) }
+	.debug_macinfo  0 : { *(.debug_macinfo) }
+	/* SGI/MIPS DWARF 2 extensions */
+	.debug_weaknames 0 : { *(.debug_weaknames) }
+	.debug_funcnames 0 : { *(.debug_funcnames) }
+	.debug_typenames 0 : { *(.debug_typenames) }
+	.debug_varnames  0 : { *(.debug_varnames) }
+	/* DWARF 3 */
+	.debug_pubtypes 0 : { *(.debug_pubtypes) }
+	.debug_ranges   0 : { *(.debug_ranges) }
+	.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+
+	/DISCARD/ : {
+		*(.note.GNU-stack) *(.gnu_debuglink)
+	}
+
+	/*
+	 * BSP: Catch all unknown sections
+	 */
+	.nirvana : {
+		*(*)
+	} > NIRVANA
+}
Index: c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/startup/linkcmds.tqm8xx	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,15 @@
+/**
+ * @file
+ *
+ * TQM8xx
+ */
+
+TopRamReserved = DEFINED(TopRamReserved) ? TopRamReserved : 0;	
+MEMORY {
+	RAM   : ORIGIN = 0x0, LENGTH = 128M
+	immr  : org = 0xfa200000,  l = 16K
+	ROM : ORIGIN = 0x40000000, LENGTH = 8M
+	NIRVANA : ORIGIN = 0x0, LENGTH = 0
+}
+
+INCLUDE linkcmds.base
Index: c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/startup/mmutlbtab.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,103 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/* derived from: */
+/*
+ * mmutlbtab.c
+ *
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <mpc8xx/mmu.h>
+/*
+ * This MMU_TLB_table is used to statically initialize the Table Lookaside
+ * Buffers in the MMU of the TQM8xx board.
+ *
+ * We initialize the entries in both the instruction and data TLBs
+ * with the same values - a few bits relevant to the data TLB are unused
+ * in the instruction TLB.
+ *
+ * An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
+ * Real Page Number (RPN) value are supplied in the table for each TLB entry.
+ *
+ * The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
+ * not have more than 32 lines in it!
+ *
+ * We set up the virtual memory map so that virtual address of a
+ * location is equal to its real address.
+ */
+MMU_TLB_table_t MMU_TLB_table[] = {
+  /*
+   * DRAM: Start address 0x00000000, 128M,
+   *	ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
+   *	R/W,X for all, no ASID comparison, not cache-inhibited.
+   * EPN		TWC	RPN
+   */
+  { 0x00000200,	0x0D,	0x000009FD },	/* DRAM - PS=8M */
+  { 0x00800200,	0x0D,	0x008009FD },	/* DRAM - PS=8M */
+  { 0x01000200,	0x0D,	0x010009FD },	/* DRAM - PS=8M */
+  { 0x01800200,	0x0D,	0x018009FD },	/* DRAM - PS=8M */
+  { 0x02000200,	0x0D,	0x020009FD },	/* DRAM - PS=8M */
+  { 0x02800200,	0x0D,	0x028009FD },	/* DRAM - PS=8M */
+  { 0x03000200,	0x0D,	0x030009FD },	/* DRAM - PS=8M */
+  { 0x03800200,	0x0D,	0x038009FD },	/* DRAM - PS=8M */
+  { 0x04000200,	0x0D,	0x040009FD },	/* DRAM - PS=8M */
+  { 0x04800200,	0x0D,	0x048009FD },	/* DRAM - PS=8M */
+  { 0x05000200,	0x0D,	0x050009FD },	/* DRAM - PS=8M */
+  { 0x05800200,	0x0D,	0x058009FD },	/* DRAM - PS=8M */
+  { 0x06000200,	0x0D,	0x060009FD },	/* DRAM - PS=8M */
+  { 0x06800200,	0x0D,	0x068009FD },	/* DRAM - PS=8M */
+  { 0x07000200,	0x0D,	0x070009FD },	/* DRAM - PS=8M */
+  { 0x07800200,	0x0D,	0x078009FD },	/* DRAM - PS=8M */
+  /*
+   *
+   * (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
+   *	ASID=0x0, APG=0x0, guarded memory, write-through data cache policy,
+   *	R/W,X for all, no ASID comparison, cache-inhibited.
+   *
+   *	Note: We use the value in MBXA/PG2, which is also the value that
+   *	EPPC-Bug programmed into our boards. The alternative is the value
+   * 	in MBXA/PG1: 0xFFA00000. This value might well depend on the revision
+   *	of the firmware.
+   * EPN		TWC	RPN
+   */
+  { 0xFA200200,	0x13,	0xFA2009FF },	/* IMMR - PS=16K */
+  /*
+   *
+   * Flash: Start address 0x40000000, 8M, 
+   *	ASID=0x0, APG=0x0, not guarded memory,
+   *	R/O,X for all, no ASID comparison, not cache-inhibited.
+   * EPN		TWC	RPN
+   */
+  { 0x40000200,	0x0D,	0x40000CFD } 	/* Flash - PS=8M   */
+};
+
+/*
+ * MMU_N_TLB_Table_Entries is defined here because the size of the
+ * MMU_TLB_table is only known in this file.
+ */
+int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );
Index: c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/startup/start.S	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,287 @@
+/*===============================================================*\
+| Project: RTEMS generic TQM8xx BSP                               |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the startup assembly code                    |
+| it is based on the gen83xx BSP                                  |
+\*===============================================================*/
+/* $Id$ */   
+
+#include <libcpu/powerpc-utility.h> 
+#include <rtems/powerpc/cache.h>
+#include <bsp.h>
+#include <mpc8xx.h>
+
+.extern boot_card
+
+.section ".entry"  
+PUBLIC_VAR (start)
+start:
+
+	/*
+	 * basic CPU setup:	
+	 * init MSR
+	 */
+	mfmsr	r30
+	SETBITS r30, r29, MSR_ME|MSR_RI
+	CLRBITS r30, r29, MSR_IP|MSR_EE
+	mtmsr	r30 				/* Set RI/ME, Clr EE in MSR */
+	/*
+	 * init IMMR
+	 */
+	LA  r30,m8xx
+	mtspr immr,r30
+	/*
+	 * determine current execution address offset
+	 */
+	bl start_1
+start_1:
+	mflr r20
+	LA   r30,start_1
+	sub. r20,r20,r30	
+	/*
+	 * execution address offset == 0?
+	 * then do not relocate code and data
+	 */
+	beq  start_code_in_ram
+	/*
+	 * ROM or relocatable startup: copy startup code to SDRAM
+	 */
+	/* get start address of text section in RAM */
+	LA	r29, bsp_section_text_start  
+	/* get start address of text section in ROM (add reloc offset) */
+	add	r30, r20, r29    
+	/* get size of startup code */
+	LA	r28, end_reloc_startup
+	LA	r31, bsp_section_text_start
+	sub	28,r28,r31
+	/* copy startup code from ROM to RAM location */
+	bl	copy_image      
+	
+	/*
+	 * jump to code copy in  SDRAM
+	 */
+	/* get compile time address of label */
+	LA	r29, copy_rest_of_text 
+	mtlr	r29
+	blr                     /* now further execution RAM */
+copy_rest_of_text:	
+	/*
+	 * ROM or relocatable startup: copy rest of code to SDRAM
+	 */
+	/* get start address of rest of code in RAM */
+	LA	r29, end_reloc_startup
+	/* get start address of text section in ROM (add reloc offset) */
+	add	r30, r20, r29    
+	/* get size of rest of code */
+	LA	r28, bsp_section_text_start
+	LA	r31, bsp_section_text_size
+	add	r28,r28,r31
+	sub	r28,r28,r29
+	bl	copy_image      /* copy text section from ROM to RAM location */
+	
+	/*
+	 * ROM or relocatable startup: copy data to SDRAM
+	 */
+	/* get start address of data section in RAM */
+	LA	r29, bsp_section_data_start 
+	/* get start address of data section in ROM (add reloc offset) */
+	add	r30, r20, r29    
+	/* get size of RAM image */
+	LA	r28, bsp_section_data_size  
+	/* copy initialized data section from ROM to RAM location */
+	bl	copy_image       
+
+start_code_in_ram:	
+
+	/*
+	 * ROM/RAM startup: clear bss in SDRAM
+	 */
+	LA	r3, bsp_section_bss_start  /* get start address of bss section */
+	LWI	r4, bsp_section_bss_size   /* get size of bss section */
+	bl	mpc8xx_zero_4          /* Clear the bss section */
+	/*
+	 * call boot_card
+	 */
+
+	/* Set stack pointer (common for RAM/ROM startup) */
+	LA	r1, bsp_section_text_start  
+        addi    r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */     
+
+	/* Create NULL */
+	li r0, 0
+
+	/* Return address */
+	stw r0, 4(r1)
+
+	/* Back chain */
+	stw r0, 0(r1)
+
+	/* Read-only small data */
+	LA r2, _SDA2_BASE_
+
+	/* Read-write small data */
+	LA r13, _SDA_BASE_
+
+	/*
+	 * init some CPU stuff
+	 */
+	bl SYM (_InitTQM8xx)
+	
+/* clear arguments and do further init. in C (common for RAM/ROM startup) */
+
+        /* Clear argc, argv and envp */
+        xor r3, r3, r3
+        xor r4, r4, r4
+        xor r5, r5, r5
+
+        bl      SYM (boot_card)  /* Call the first C routine */
+	
+twiddle:
+	/* We don't expect to return from boot_card but if we do */
+	/* wait here for watchdog to kick us into hard reset     */
+	b	twiddle          
+						
+copy_with_watchdog:
+     addi    r5,r5,16
+     rlwinm. r5,r5,28,4,31
+     mtctr   r5
+
+copy_loop:
+     lwz     r6,0(r3)
+     lwz     r7,4(r3)
+     lwz     r8,8(r3)
+     lwz     r9,12(r3)
+     stw     r6,0(r4)
+     stw     r7,4(r4)
+     stw     r8,8(r4)
+     stw     r9,12(r4)
+     addi    r3,r3,16
+     addi    r4,r4,16
+     sth     r28,14(r30)
+     sth     r29,14(r30)
+     bdnz+   copy_loop
+     blr
+
+copy_image:
+	/*
+	 * watchdog:
+	 * r26 = immr
+	 * r25 = watchdog magic 1
+	 * r24 = watchdog magic 2
+	 */
+	mfimmr  r26
+	rlwinm. r26,r26,0,0,15
+	li      r25,0x556c
+	li      r24,0xffffaa39
+
+	mr	r27, r28		/* determine number of 4word chunks */
+	srwi	r28, r28, 4
+	mtctr	r28
+
+	slwi	r28, r28, 4
+	sub     r27, r27, r28		/* determine residual bytes */
+copy_image_4word:
+	lwz	r20, 0(r30)		/* fetch data */
+	lwz	r21, 4(r30)
+	lwz	r22, 8(r30)
+	lwz	r23,12(r30)
+	stw	r20, 0(r29)		/* store data */
+	stw	r21, 4(r29)
+	stw	r22, 8(r29)
+	stw	r23,12(r29)
+	
+	addi    r30, r30, 0x10		/* increment source pointer */
+	addi    r29, r29, 0x10		/* increment destination pointer */
+	/*
+	 * trigger watchdog
+	 */
+	sth     r25,14(r26)
+	sth     r24,14(r26)
+	
+	bdnz	copy_image_4word	/* decrement ctr and branch if not 0 */
+
+	cmpwi	r27, 0x00		/* copy image finished ? */
+	beq	copy_image_end;
+	mtctr   r27			/* reload counter for residual bytes */
+copy_image_byte:
+	lswi	r28, r30, 0x01
+	
+	stswi   r28, r29, 0x01		/* do byte copy ROM -> RAM */
+	
+	
+	addi    r30, r30, 0x01		/* increment source pointer */
+	addi    r29, r29, 0x01		/* increment destination pointer */
+	
+	bdnz	copy_image_byte		/* decrement ctr and branch if not 0 */
+	
+copy_image_end:
+	blr
+
+	
+/**
+ * @fn int mpc8xx_zero_4( void *dest, size_t n)
+ *
+ * @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
+ *
+ * The address @a dest has to be aligned on 4 byte boundaries.  The size @a n
+ * must be evenly divisible by 4.
+ */
+GLOBAL_FUNCTION mpc8xx_zero_4
+	/* Create zero */
+	xor	r0, r0, r0
+
+	/* Set offset */
+	xor	r5, r5, r5
+
+	/* Loop counter for the first bytes up to 16 bytes */
+	rlwinm.	r9, r4, 30, 30, 31
+	beq	mpc8xx_zero_4_more
+	mtctr	r9
+
+mpc8xx_zero_4_head:
+
+	stwx	r0, r3, r5
+	addi	r5, r5, 4
+	bdnz	mpc8xx_zero_4_head
+
+mpc8xx_zero_4_more:
+
+	/* More than 16 bytes? */
+	srwi.	r9, r4, 4
+	beqlr
+	mtctr	r9
+
+	/* Set offsets */
+	addi	r6, r5, 4
+	addi	r7, r5, 8
+	addi	r8, r5, 12
+
+mpc8xx_zero_4_tail:
+
+	stwx	r0, r3, r5
+	addi	r5, r5, 16
+	stwx	r0, r3, r6
+	addi	r6, r6, 16
+	stwx	r0, r3, r7
+	addi	r7, r7, 16
+	stwx	r0, r3, r8
+	addi	r8, r8, 16
+	bdnz	mpc8xx_zero_4_tail
+	
+	/* Return */
+	blr
+
+end_reloc_startup:
Index: c/src/lib/libbsp/powerpc/tqm8xx/timer/timer.c
===================================================================
--- c/src/lib/libbsp/powerpc/tqm8xx/timer/timer.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
+++ c/src/lib/libbsp/powerpc/tqm8xx/timer/timer.c	(revision 63de714ce7c0869715687c728f84efd048cba550)
@@ -0,0 +1,110 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.com/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/*
+ * Timer_init()
+ *
+ * Use TIMER 1 and TIMER 2 for Timing Test Suite
+ *
+ * this is derived from "timer.c" available in the m68k/gen68360 BSP
+ * adapted by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ * 
+ *  $Id$
+ */
+
+/*
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <mpc8xx.h>
+
+void
+Timer_initialize (void)
+{
+	/*
+	 * Reset timers 1 and 2
+	 */
+	m8xx.tgcr &= ~0x00FF;
+	m8xx.tcn1 = 0;
+	m8xx.tcn2 = 0;
+	m8xx.ter1 = 0xFFFF;
+	m8xx.ter2 = 0xFFFF;
+
+	/*
+	 * Cascade timers 1 and 2
+	 */
+	m8xx.tgcr |= M8xx_TGCR_CAS2;
+
+	/*
+	 * Configure timers 1 and 2 to a single 32-bit, BUS_clock timer.
+	 */
+	m8xx.tmr2 = (0 << 8) | 0x2;
+	m8xx.tmr1 = 0;
+
+	/*
+	 * Start the timers
+	 */
+	m8xx.tgcr |=  0x0011;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+int
+Read_timer (void)
+{
+  extern unsigned int BSP_bus_frequency;
+  int retval;
+  retval = *(uint32_t*)&m8xx.tcn1;
+  retval = retval * 1000000LL / BSP_bus_frequency;
+  return retval;
+}
+
+/*
+ * Empty function call used in loops to measure basic cost of looping
+ * in Timing Test Suite.
+ */
+rtems_status_code
+Empty_function (void)
+{
+	return RTEMS_SUCCESSFUL;
+}
+
+void
+Set_find_average_overhead(bool find_flag)
+{
+}
