summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/Makefile.in23
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/README50
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/STATUS82
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/bsp_specs18
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/clock/Makefile.in62
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/clock/clock.c251
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/console/Makefile.in56
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/console/console.c479
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/console/duart.c201
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/Makefile.in38
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/bsp.h178
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/chain.h353
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/coverhd.h134
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/dmv170.h215
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/include/tod.h38
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in62
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c1176
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h364
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/start/Makefile.in56
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/start/start.s117
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/Makefile.in68
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/bspclean.s25
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/bspstart.c312
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/genpvec.c184
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/linkcmds173
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/rtems-ctor.cc151
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/sbrk.c61
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/setvec.c71
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/startup/vmeintr.c84
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/timer/Makefile.in61
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/timer/timer.c152
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/tod/Makefile.in59
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/tod/tod.c282
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in57
34 files changed, 5693 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/dmv177/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/Makefile.in
new file mode 100644
index 0000000000..e2cc7c6b24
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/Makefile.in
@@ -0,0 +1,23 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/directory.cfg
+
+SRCS=README
+
+all: $(SRCS)
+
+# wrapup is the one that actually builds and installs the library
+# from the individual .rel files built in other directories
+SUB_DIRS=include clock console startup start timer \
+ tod sonic wrapup
diff --git a/c/src/lib/libbsp/powerpc/dmv177/README b/c/src/lib/libbsp/powerpc/dmv177/README
new file mode 100644
index 0000000000..1625c4a858
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/README
@@ -0,0 +1,50 @@
+#
+# $Id$
+#
+
+BSP NAME: psim
+BOARD: PowerPC Simulator
+BUS: N/A
+CPU FAMILY: ppc
+CPU: PowerPC 603, 603e, 604
+COPROCESSORS: N/A
+MODE: 32 bit mode
+
+DEBUG MONITOR: BUG mode (emulates Motorola debug monitor)
+
+PERIPHERALS
+===========
+TIMERS: PPC internal Timebase register
+ RESOLUTION: ???
+SERIAL PORTS: simulated via bug
+REAL-TIME CLOCK: PPC internal Decrementer register
+DMA: none
+VIDEO: none
+SCSI: none
+NETWORKING: none
+
+DRIVER INFORMATION
+==================
+CLOCK DRIVER: PPC internal
+IOSUPP DRIVER: N/A
+SHMSUPP: N/A
+TIMER DRIVER: PPC internal
+TTY DRIVER: PPC internal
+
+STDIO
+=====
+PORT: Console port 0
+ELECTRICAL: na
+BAUD: na
+BITS PER CHARACTER: na
+PARITY: na
+STOP BITS: na
+
+Notes
+=====
+
+Based on papyrus bsp which only really supports
+the PowerOpen ABI with an ELF assembler.
+
+Need to Modify external_exception_ISR with correct code to read the vector,
+and to clear the interrupt. \ No newline at end of file
diff --git a/c/src/lib/libbsp/powerpc/dmv177/STATUS b/c/src/lib/libbsp/powerpc/dmv177/STATUS
new file mode 100644
index 0000000000..394412421e
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/STATUS
@@ -0,0 +1,82 @@
+#
+# This is a status file for the update effort.
+#
+
+make/custom
+===========
+dmv17x.cfg
+
+TOP
+===
+README
+Makefile.in
+bsp_specs
+
+clock
+=====
+clock.c
+Makefile.in
+
+console
+=======
+Changed console from
+ duart.c
+ console.c
+To
+ consolebsp.h
+ console.c
+ 85c30.c
+ tbl85c30.c
+
+Note: Check the number of serial ports and modify
+ tbl85c30.c values to indicate the correct values.
+
+Makefile.in - Modified with new file names.
+
+timer
+=======
+timer.c
+Makefile.in
+
+include
+=======
+chain.h
+dmv170.h
+bsp.h
+Makefile
+Makefile.in
+coverhd.h
+
+network
+=======
+Eric's problem
+
+startup
+=======
+device-tree - remove
+linkcmds
+setvec.c - Modified to acount for general purpose vector.
+sbrk.c - Ok
+rtems-ctor.cc - Ok
+bspclean.s - Ok
+vmeintr.c
+Makefile.in - Added genpvec.c
+bspstart.c - Modified with changes from vista bsp.
+
+Added:
+genpvec.c
+
+Note: Need to add routine which connects the general purpose interupt with the
+ various interupt handlers. genpvec.c uses this routine and may need
+ to be modified.
+wrapup
+=======
+wrapup/Makefile.in
+
+vectors
+=======
+
+start
+=======
+start/Makefile.in
+start/start.s - Made modifications based upon Score603e mods.
diff --git a/c/src/lib/libbsp/powerpc/dmv177/bsp_specs b/c/src/lib/libbsp/powerpc/dmv177/bsp_specs
new file mode 100644
index 0000000000..6a84054cf5
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/bsp_specs
@@ -0,0 +1,18 @@
+%rename cpp old_cpp
+%rename lib old_lib
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*cpp:
+%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
+
+*lib:
+%{!qrtems: %(old_lib)} %{qrtems: ecrti%O%s ecrtn%O%s --start-group -lrtemsall -lc -lgcc --end-group}
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{qrtems: start.o%s}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -T linkcmds%s -e _start -u __vectors}
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/clock/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/clock/Makefile.in
new file mode 100644
index 0000000000..4c145d2dfc
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/clock/Makefile.in
@@ -0,0 +1,62 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGM=${ARCH}/clock.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=clock
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/dmv177/clock/clock.c b/c/src/lib/libbsp/powerpc/dmv177/clock/clock.c
new file mode 100644
index 0000000000..03059c6cea
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/clock/clock.c
@@ -0,0 +1,251 @@
+/*
+ * Clock Tick Device Driver
+ *
+ * This routine utilizes the Decrementer Register common to the PPC family.
+ *
+ * The tick frequency is directly programmed to the configured number of
+ * microseconds per tick.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <assert.h>
+
+/*
+ * The Real Time Clock Counter Timer uses this trap type.
+ */
+
+#define CLOCK_VECTOR PPC_IRQ_DECREMENTER
+
+/*
+ * Clock ticks since initialization
+ */
+
+volatile rtems_unsigned32 Clock_driver_ticks;
+
+/*
+ * This is the value programmed into the count down timer.
+ */
+
+rtems_unsigned32 Clock_Decrementer_value;
+
+/*
+ * This is the value of the old isr routine.
+ */
+rtems_isr_entry Old_ticker;
+
+
+void Clock_exit( void );
+
+/*
+ * These are set by clock driver during its init
+ */
+
+rtems_device_major_number rtems_clock_major = ~0;
+rtems_device_minor_number rtems_clock_minor;
+
+#define PPC_Set_decrementer( _clicks ) \
+ do { \
+ asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
+ } while (0)
+
+
+/* PAGE
+ *
+ * Clock_isr
+ *
+ * This is the clock tick interrupt handler.
+ *
+ * Input parameters:
+ * vector - vector number
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+rtems_isr Clock_isr(
+ rtems_vector_number vector,
+ CPU_Interrupt_frame *frame
+)
+{
+ /*
+ * Set the decrementer.
+ */
+
+ PPC_Set_decrementer( Clock_Decrementer_value );
+
+ /*
+ * The driver has seen another tick.
+ */
+
+ Clock_driver_ticks += 1;
+
+ /*
+ * Real Time Clock counter/timer is set to automatically reload.
+ */
+
+ rtems_clock_tick();
+}
+
+/* PAGE
+ *
+ * Install_clock
+ *
+ * This routine actually performs the hardware initialization for the clock.
+ *
+ * Input parameters:
+ * clock_isr - clock interrupt service routine entry point
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+extern int CLOCK_SPEED;
+
+void Install_clock(
+ rtems_isr_entry clock_isr
+)
+{
+ Clock_driver_ticks = 0;
+
+ if ( BSP_Configuration.ticks_per_timeslice ) {
+ Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
+
+ PPC_Set_decrementer( Clock_Decrementer_value );
+
+ atexit( Clock_exit );
+ }
+}
+
+/* PAGE
+ *
+ * Clock_exit
+ *
+ * This routine allows the clock driver to exit by masking the interrupt and
+ * disabling the clock's counter.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void Clock_exit( void )
+{
+ if ( BSP_Configuration.ticks_per_timeslice ) {
+
+ /* nothing to do */;
+
+ /* do not restore old vector */
+ }
+}
+
+/* PAGE
+ *
+ * Clock_initialize
+ *
+ * This routine initializes the clock driver.
+ *
+ * Input parameters:
+ * major - clock device major number
+ * minor - clock device minor number
+ * parg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver Clock_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ Clock_Decrementer_value = (int) &CPU_PPC_CLICKS_PER_MS *
+ (BSP_Configuration.microseconds_per_tick / 1000);
+
+ Install_clock( Clock_isr );
+
+ /*
+ * make major/minor avail to others such as shared memory driver
+ */
+
+ rtems_clock_major = major;
+ rtems_clock_minor = minor;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * Clock_control
+ *
+ * This routine is the clock device driver control entry point.
+ *
+ * Input parameters:
+ * major - clock device major number
+ * minor - clock device minor number
+ * parg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver Clock_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ rtems_unsigned32 isrlevel;
+ rtems_libio_ioctl_args_t *args = pargp;
+
+ if (args == 0)
+ goto done;
+
+ /*
+ * This is hokey, but until we get a defined interface
+ * to do this, it will just be this simple...
+ */
+
+ if (args->command == rtems_build_name('I', 'S', 'R', ' '))
+ {
+ Clock_isr( CLOCK_VECTOR, pargp );
+ }
+ else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
+ {
+ rtems_interrupt_disable( isrlevel );
+ (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
+ rtems_interrupt_enable( isrlevel );
+ }
+
+done:
+ return RTEMS_SUCCESSFUL;
+}
+
+
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/console/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/console/Makefile.in
new file mode 100644
index 0000000000..eb8b914e91
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/console/Makefile.in
@@ -0,0 +1,56 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGM=${ARCH}/console.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=console duart
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/dmv177/console/console.c b/c/src/lib/libbsp/powerpc/dmv177/console/console.c
new file mode 100644
index 0000000000..b1fc6f19e9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/console/console.c
@@ -0,0 +1,479 @@
+/*
+ * console.c
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * Currently only polled mode is supported.
+ *
+ * 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: console.c
+ */
+
+#include <stdlib.h>
+#include <motorola/mc68681.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <assert.h>
+
+#define COM1 0
+#define COM2 1
+#define NUM_PORTS 2
+#define USE_FOR_CONSOLE COM1
+
+/*
+ * Define RDB_BREAK_IN if you need to be able to break in to the
+ * program with a ctrl-c during remote target debugging. If so,
+ * UART B will not be accessible from rtems during remote debugging
+ * if interrupt driven console is used. Does not affect UART A, polled
+ * mode or when the program runs without remote debugging.
+ */
+#define RDB_BREAK_IN
+
+/* Proto-types for Duart.C */
+void console_initialize_interrupts( void );
+char console_inbyte_polled( int port );
+void console_outbyte_polled(int port, char ch);
+rtems_isr console_isr (rtems_vector_number vector);
+volatile void init_mc88681();
+
+/* PAGE
+ *
+ * console_initialize
+ *
+ * This routine initializes the console IO driver.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+ int console;
+
+ /*
+ * initialize the termio interface.
+ */
+ rtems_termios_initialize();
+
+ /*
+ * Register Device Names
+ */
+ console = USE_FOR_CONSOLE;
+ status = rtems_io_register_name( "/dev/console", major, console );
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+
+ /*
+ * Initialize Hardware
+ */
+
+ init_mc88681 ();
+
+#if CONSOLE_USE_INTERRUPTS
+ console_initialize_interrupts();
+#endif
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * console_write_support
+ *
+ * This routine is Console Termios output entry point.
+ *
+ * Input parameters:
+ * minor - console device minor number
+ * buf - buffer of data to be written
+ * len - length of data to be written
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * int number of bytes written
+ */
+
+int console_write_support(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int nwrite = 0;
+ int port = minor;
+
+ /*
+ * verify port Number
+ */
+ assert ( port < NUM_PORTS );
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len) {
+#if defined(CONSOLE_USE_INTERRUPTS)
+#else
+ console_outbyte_polled(port, *buf++);
+#endif
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
+
+
+/* PAGE
+ *
+ * DEBUG_puts
+ *
+ * This should be safe in the event of an error. It attempts to insure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * string - pointer to debug output string
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void DEBUG_puts(
+ char *string
+)
+{
+ char *s;
+ rtems_unsigned32 isrlevel;
+
+ rtems_interrupt_disable( isrlevel );
+ for ( s = string ; *s ; s++ )
+ console_outbyte_polled( 0, *s );
+
+ console_outbyte_polled( 0, '\r' );
+ console_outbyte_polled( 0, '\n' );
+ rtems_interrupt_enable( isrlevel );
+}
+
+
+/* PAGE
+ *
+ * console_open
+ *
+ * This routine is the console device driver open entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code sc;
+ int port = minor;
+#if defined(CONSOLE_USE_INTERRUPTS)
+ rtems_libio_open_close_args_t *args = arg;
+#endif
+
+ /*
+ * Verify the minor number is valid.
+ */
+ if (minor < 0)
+ return RTEMS_INVALID_NUMBER;
+
+ if ( port > NUM_PORTS )
+ return RTEMS_INVALID_NUMBER;
+
+ /*
+ * open the port as a termios console driver.
+ */
+#if defined(CONSOLE_USE_INTERRUPTS)
+ sc = rtems_termios_open (major, minor, arg,
+ NULL, NULL, NULL,
+ console_write_support, 0);
+#else
+ sc = rtems_termios_open (major, minor, arg, NULL, NULL,
+ console_inbyte_nonblocking,
+ console_write_support,
+ 0);
+#endif
+
+ return sc;
+}
+
+
+
+/* PAGE
+ *
+ * console_reserve_resources
+ *
+ * This routine reserves resources for each port which may be
+ * used as a console.
+ *
+ * Input parameters:
+ * configuration - rtems configuration table.
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void console_reserve_resources(
+ rtems_configuration_table *configuration
+)
+{
+ rtems_termios_reserve_resources( configuration, NUM_PORTS );
+}
+
+/* PAGE
+ *
+ * console_close
+ *
+ * This routine is the console device driver close entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_close (arg);
+}
+
+/* PAGE
+ *
+ * console_read
+ *
+ * This routine is the console device driver read entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ *
+ */
+ rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read (arg);
+}
+
+/* PAGE
+ *
+ * console_write
+ *
+ * This routine is the console device driver write entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ *
+ */
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write (arg);
+}
+
+/* PAGE
+ *
+ * console_control
+ *
+ * This routine is console device driver control entry point
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ *
+ */
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_ioctl (arg);
+}
+
+
+/*
+ * Interrupt driven console IO
+ */
+
+#if CONSOLE_USE_INTERRUPTS
+
+/*
+ * Buffers between task and ISRs
+ */
+
+#include <ringbuf.h>
+extern Ring_buffer_t TX_Buffer[2];
+extern Ring_buffer_t RX_Buffer[2];
+
+/*
+ * console_inbyte_interrupts
+ *
+ * This routine reads a character from the UART.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * character read from UART
+ */
+
+char console_inbyte_interrupts( int port )
+{
+ char ch;
+
+ while ( Ring_buffer_Is_empty( &RX_Buffer[ port ] ) );
+
+ Ring_buffer_Remove_character( &RX_Buffer[ port ], ch );
+ return ch;
+}
+
+/*
+ * console_outbyte_interrupts
+ *
+ * This routine transmits a character out.
+ *
+ * Input parameters:
+ * port - port to transmit character to
+ * ch - character to be transmitted
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void console_outbyte_interrupts(
+ int port,
+ char ch
+)
+{
+ /*
+ * If this is the first character then we need to prime the pump
+ */
+
+ if ( Is_TX_active[ port ] == FALSE ) {
+ Is_TX_active[ port ] = TRUE;
+ console_outbyte_polled( port, ch );
+ return;
+ }
+
+ while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) );
+
+ Ring_buffer_Add_character( &TX_Buffer[ port ], ch );
+}
+
+/*
+ * console_exit
+ *
+ * This routine allows the console to exit by masking its associated interrupt
+ * vectors.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void console_exit()
+{
+ volatile unsigned char *_addr;
+ int port;
+
+ /*
+ * Although the interrupts for the UART are unmasked, the PIL is set to
+ * disable all external interrupts. So we might as well do this first.
+ */
+
+ /* ??? Mask All UART Interrupts */
+
+ for (port = MC68681_PORT_A; port <= MC68681_PORT_B; port++) {
+ while (!Ring_buffer_Is_empty (&TX_Buffer[port])) {
+ Ring_buffer_Remove_character (&TX_Buffer[port],ch);
+ console_outbyte_polled (port,ch);
+ }
+ }
+
+ /*
+ * Now wait for all the data to actually get out ... the send register
+ * should be empty.
+ */
+ _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_A);
+ while (!(*_addr & MC68681_TX_EMPTY));
+
+ _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_B);
+ while (!(*_addr & MC68681_TX_EMPTY));
+}
+#endif /* CONSOLE_USE_INTERRUPTS */
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/console/duart.c b/c/src/lib/libbsp/powerpc/dmv177/console/duart.c
new file mode 100644
index 0000000000..f72b37a832
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/console/duart.c
@@ -0,0 +1,201 @@
+/*
+ * duart.c
+ *
+ * This code is a modified version of what you will find at the
+ * end of the IDP User's manual. The original code is copyrighted
+ * by Motorola and Motorola Semiconductor Products as well as
+ * Motorola Software products group.
+ *
+ * Modifications to the original IDP code by Doug McBride, Colorado
+ * Space Grant College. Modifications include a means of accessing
+ * port B of the duart as well as port A as well as modifications for
+ * buffering and RTEMS support. Modifications are provided
+ * as is and may not be correct.
+ *
+ * Rob Savoye provided the format for the mc68681 header file
+ *
+ * Joel Sherrill provided inspiration for recoding my original assembly
+ * for this file into C (a good idea)
+ *
+ * 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: duart.c
+ */
+
+#define MC68681_OFFSET_MULTIPLIER 8
+#include <motorola/mc68681.h>
+#include <bsp.h>
+#include <ringbuf.h>
+
+rtems_isr console_isr (rtems_vector_number vector);
+
+Ring_buffer_t TX_Buffer[2];
+Ring_buffer_t RX_Buffer[2];
+
+/* PAGE
+ *
+ * init_mc88681
+ *
+ * volatile routine to initialize duart
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return Values: NONE
+ */
+
+volatile void init_mc88681()
+{
+ /*
+ * Initialize Ring buffers
+ */
+ Ring_buffer_Initialize( &RX_Buffer[ 0 ] );
+ Ring_buffer_Initialize( &RX_Buffer[ 1 ] );
+
+ Ring_buffer_Initialize( &TX_Buffer[ 0 ] );
+ Ring_buffer_Initialize( &TX_Buffer[ 1 ] );
+}
+
+/* PAGE
+ *
+ * console_isr
+ *
+ * interrupt handler for receive of character from duart on ports A & B
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return Values: NONE
+ */
+
+rtems_isr console_isr (rtems_vector_number vector)
+{
+
+ /*
+ * Fill me in later ...
+ */
+
+}
+
+
+/* PAGE
+ *
+ * console_outbyte_polled
+ *
+ * This routine transmits a character out.
+ *
+ * Input parameters:
+ * port - port to transmit character to
+ * ch - character to be transmitted
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void console_outbyte_polled(
+ int port,
+ char ch
+)
+{
+ unsigned char status;
+ unsigned char data;
+ unsigned char t = 0;
+
+ if (port == MC68681_PORT_A) {
+ status = MC68681_STATUS_REG_A;
+ data = MC68681_TRANSMIT_BUFFER_A;
+ } else {
+ status = MC68681_STATUS_REG_B;
+ data = MC68681_TRANSMIT_BUFFER_B;
+ }
+
+ while ( !(MC68681_READ(DUART_ADDR, status) & MC68681_TX_READY) ){
+ if (t == 0) {
+ Debug_Entry( 0x8000 );
+ t++;
+ }
+ }
+
+ Debug_Entry( 0x9000 );
+ MC68681_WRITE(DUART_ADDR, data, ch);
+}
+
+
+/* PAGE
+ *
+ * console_inbyte_polled
+ *
+ * This routine reads a character from the UART.
+ *
+ * Input parameters:
+ * port - port to read character from
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * character read from UART
+ */
+
+#define MC68681_RECEIVE_ERRORS \
+ (MC68681_OVERRUN_ERROR | MC68681_PARITY_ERROR | MC68681_FRAMING_ERROR)
+
+char console_inbyte_polled( int port )
+{
+ char status;
+ char data;
+ char cmd;
+ unsigned char status_info;
+
+ /*
+ * Set Port A or B unique variables.
+ */
+ if (port == MC68681_PORT_A) {
+ status = MC68681_STATUS_REG_A;
+ data = MC68681_RECEIVE_BUFFER_A;
+ cmd = MC68681_COMMAND_REG_A;
+ } else {
+ status = MC68681_STATUS_REG_B;
+ data = MC68681_RECEIVE_BUFFER_B;
+ cmd = MC68681_COMMAND_REG_B;
+ }
+
+ /* Wait for the Ready bit and Clear any errors */
+ for ( ; ; ) {
+ status_info = MC68681_READ(DUART_ADDR, status);
+ if ( status_info & MC68681_RX_READY )
+ break;
+
+ if ( status_info & MC68681_RECEIVE_ERRORS )
+ MC68681_WRITE( DUART_ADDR, cmd, MC68681_MODE_REG_RESET_ERROR );
+ }
+
+ return MC68681_READ(DUART_ADDR, data);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/include/Makefile.in
new file mode 100644
index 0000000000..54f072893c
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/Makefile.in
@@ -0,0 +1,38 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h \
+ $(srcdir)/dmv170.h $(srcdir)/chain.h $(srcdir)/tod.h
+
+#
+# Equate files are for including from assembly preprocessed by
+# gm4 or gasp. No examples are provided except for those for
+# other CPUs. The best way to generate them would be to
+# provide a program which generates the constants used based
+# on the C equivalents.
+#
+# If you add equate files, don't forget to uncomment the install line
+# below.
+#
+
+EQ_FILES =
+
+SRCS=$(H_FILES) $(EQ_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+all: $(SRCS)
+ $(INSTALL) -m 444 $(H_FILES) $(PROJECT_INCLUDE)
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h b/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h
new file mode 100644
index 0000000000..aa4f4df348
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/bsp.h
@@ -0,0 +1,178 @@
+/* bsp.h
+ *
+ * This include file contains all DY-4 DMV170 board IO definitions.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#ifndef __DMV170_BSP_h
+#define __DMV170_BSP_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef ASM
+/* Definition of where to store registers in alignment handler */
+#define ALIGN_REGS 0x0140
+
+#else
+#include <rtems.h>
+#include <console.h>
+#include <clockdrv.h>
+#include <console.h>
+#include <iosupp.h>
+
+#include <dmv170.h>
+
+#define Enable_Debug() \
+ DMV170_WRITE( 0xffffbd0c, 0 )
+
+#define Debug_Entry( num ) \
+ DMV170_WRITE( 0xffffbd06, num )
+
+/*
+ * The following macro calculates the Baud constant. For the Z8530 chip.
+ */
+#define Z8530_Baud( _frequency, _clock_by, _baud_rate ) \
+ ( (_frequency /( _clock_by * 2 * _baud_rate)) - 2)
+
+
+/*
+ * Define the time limits for RTEMS Test Suite test durations.
+ * Long test and short test duration limits are provided. These
+ * values are in seconds and need to be converted to ticks for the
+ * application.
+ *
+ */
+
+#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
+#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
+
+
+/*
+ * Stuff for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+#define Install_tm27_vector( _handler ) \
+ set_vector( (_handler), PPC_IRQ_DECREMENTER, 1 )
+
+#define Cause_tm27_intr() \
+ do { \
+ unsigned32 _clicks = 1; \
+ asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
+ } while (0)
+
+
+#define Clear_tm27_intr() \
+ do { \
+ unsigned32 _clicks = 0xffffffff; \
+ asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
+ } while (0)
+
+#define Lower_tm27_intr() \
+ do { \
+ unsigned32 _msr = 0; \
+ _ISR_Set_level( 0 ); \
+ asm volatile( "mfmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
+ _msr |= 0x8002; \
+ asm volatile( "mtmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
+ } while (0)
+
+/* Constants */
+
+/*
+ * Device Driver Table Entries
+ */
+
+/*
+ * NOTE: Use the standard Console driver entry
+ */
+
+/*
+ * NOTE: Use the standard Clock driver entry
+ */
+
+
+/*
+ * Information placed in the linkcmds file.
+ */
+
+extern int RAM_START;
+extern int RAM_END;
+extern int RAM_SIZE;
+
+extern int PROM_START;
+extern int PROM_END;
+extern int PROM_SIZE;
+
+extern int CLOCK_SPEED;
+
+extern int end; /* last address in the program */
+
+/*
+ * How many libio files we want
+ */
+
+#define BSP_LIBIO_MAX_FDS 20
+
+/* functions */
+
+/*
+ * genvec.c
+ */
+rtems_isr_entry set_EE_vector(
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector /* vector number */
+);
+void initialize_external_exception_vector ();
+
+/*
+ * console.c
+ */
+void DEBUG_puts( char *string );
+
+void BSP_fatal_return( void );
+
+
+
+void bsp_start( void );
+
+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 */
+);
+
+void BSP_fatal_return( void );
+
+void bsp_spurious_initialize( void );
+
+extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
+
+extern rtems_cpu_table Cpu_table; /* owned by BSP */
+
+extern rtems_unsigned32 bsp_isr_level;
+
+extern int CPU_PPC_CLICKS_PER_MS;
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/chain.h b/c/src/lib/libbsp/powerpc/dmv177/include/chain.h
new file mode 100644
index 0000000000..c54df2b4e7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/chain.h
@@ -0,0 +1,353 @@
+/* chain.h
+ *
+ * This include file contains all the constants and structures associated
+ * with doubly linked chains. This file actually just provides an
+ * interface to the chain object in rtems.
+ *
+ */
+
+#ifndef __CHAIN_h
+#define __CHAIN_h
+
+#include <rtems.h>
+
+/*
+ * Chain_Initialize
+ *
+ * This routine initializes the_chain structure to manage the
+ * contiguous array of number_nodes nodes which starts at
+ * starting_address. Each node is of node_size bytes.
+ *
+ * Chain_Control *the_chain, * IN *
+ * void *starting_address, * IN *
+ * rtems_unsigned32 number_nodes, * IN *
+ * rtems_unsigned32 node_size * IN *
+ */
+
+#define Chain_Initialize( the_chain, starting_address, \
+ number_nodes, node_size ) \
+ _Chain_Initialize( the_chain, starting_address, \
+ number_nodes, node_size ) \
+
+
+/*
+ * Chain_Initialize_empty
+ *
+ * This routine initializes the specified chain to contain zero nodes.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Initialize_empty( the_chain ) \
+ _Chain_Initialize_empty( the_chain )
+
+
+/*
+ * Chain_Are_nodes_equal
+ *
+ * This function returns TRUE if LEFT and RIGHT are equal,
+ * and FALSE otherwise.
+ *
+ * Chain_Node *left, * IN *
+ * Chain_Node *right * IN *
+ */
+
+#define Chain_Are_nodes_equal( left, right ) \
+ _Chain_Are_nodes_equal( left, right )
+
+
+/*
+ * Chain_Extract_unprotected
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * extract operation.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Extract_unprotected( the_node ) \
+ _Chain_Extract_unprotected( the_node )
+
+
+/*
+ * Chain_Extract
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It disables interrupts to insure the atomicity of the
+ * extract operation.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Extract( the_node ) \
+ _Chain_Extract( the_node )
+
+
+/*
+ * Chain_Get_unprotected
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * get operation.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Get_unprotected( the_chain ) \
+ _Chain_Get_unprotected( the_chain )
+
+
+/*
+ * Chain_Get
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ * It disables interrupts to insure the atomicity of the
+ * get operation.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Get( the_chain ) \
+ _Chain_Get( the_chain )
+
+
+/*
+ * Chain_Get_first_unprotected
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. It does NOT disable interrupts to insure
+ * the atomicity of the get operation.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Get_first_unprotected( the_chain ) \
+ _Chain_Get_first_unprotected( the_chain )
+
+
+/*
+ * Chain_Insert_unprotected
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node. It does NOT disable interrupts to insure the atomicity
+ * of the extract operation.
+ *
+ * Chain_Node *after_node, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Insert_unprotected( after_node, the_node ) \
+ _Chain_Insert_unprotected( after_node, the_node )
+
+
+/*
+ * Chain_Insert
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node. It disables interrupts to insure the atomicity
+ * of the extract operation.
+ *
+ * Chain_Node *after_node, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Insert( after_node, the_node ) \
+ _Chain_Insert( after_node, the_node )
+
+
+/*
+ * Chain_Append_unprotected
+ *
+ * This routine appends the_node onto the end of the_chain.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * append operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Append_unprotected( the_chain, the_node ) \
+ _Chain_Append_unprotected( the_chain, the_node )
+
+
+/*
+ * Chain_Append
+ *
+ * This routine appends the_node onto the end of the_chain.
+ * It disables interrupts to insure the atomicity of the
+ * append operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Append( the_chain, the_node ) \
+ _Chain_Append( the_chain, the_node )
+
+
+/*
+ * Chain_Prepend_unprotected
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * prepend operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Prepend_unprotected( the_chain, the_node ) \
+ _Chain_Prepend_unprotected( the_chain, the_node )
+
+
+/*
+ * Chain_Prepend
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ * It disables interrupts to insure the atomicity of the
+ * prepend operation.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Prepend( the_chain, the_node ) \
+ _Chain_Prepend( the_chain, the_node )
+
+
+/*
+ * Chain_Head
+ *
+ * This function returns a pointer to the first node on the chain.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Head( the_chain ) \
+ _Chain_Head( the_chain )
+
+
+/*
+ * Chain_Tail
+ *
+ * This function returns a pointer to the last node on the chain.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Tail( the_chain ) \
+ _Chain_Tail( the_chain )
+
+
+/*
+ * Chain_Is_head
+ *
+ * This function returns TRUE if the_node is the head of the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_head( the_chain, the_node ) \
+ _Chain_Is_head( the_chain, the_node )
+
+
+/*
+ * Chain_Is_tail
+ *
+ * This function returns TRUE if the_node is the tail of the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain, * IN *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_tail( the_chain, the_node ) \
+ _Chain_Is_tail( the_chain, the_node )
+
+
+/*
+ * Chain_Is_first
+ *
+ * This function returns TRUE if the_node is the first node on a chain and
+ * FALSE otherwise.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_first( the_node ) \
+ _Chain_Is_first( the_node )
+
+
+/*
+ * Chain_Is_last
+ *
+ * This function returns TRUE if the_node is the last node on a chain and
+ * FALSE otherwise.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_last( the_node ) \
+ _Chain_Is_last( the_node )
+
+
+/*
+ * Chain_Is_empty
+ *
+ * This function returns TRUE if there are no nodes on the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Is_empty( the_chain ) \
+ _Chain_Is_empty( the_chain )
+
+
+/*
+ * Chain_Has_only_one_node
+ *
+ * This function returns TRUE if there is only one node on the_chain and
+ * FALSE otherwise.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Has_only_one_node( the_chain ) \
+ _Chain_Has_only_one_node( the_chain )
+
+
+/*
+ * Chain_Is_null
+ *
+ * This function returns TRUE if the_chain is NULL and FALSE otherwise.
+ *
+ * Chain_Control *the_chain * IN *
+ */
+
+#define Chain_Is_null( the_chain ) \
+ _Chain_Is_null( the_chain )
+
+
+/*
+ * Chain_Is_null_node
+ *
+ * This function returns TRUE if the_node is NULL and FALSE otherwise.
+ *
+ * Chain_Node *the_node * IN *
+ */
+
+#define Chain_Is_null_node( the_node ) \
+ _Chain_Is_null_node( the_node )
+
+
+#undef __RTEMS_APPLICATION__
+#include <rtems/score/chain.inl>
+#define __RTEMS_APPLICATION__
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/coverhd.h b/c/src/lib/libbsp/powerpc/dmv177/include/coverhd.h
new file mode 100644
index 0000000000..451d13b706
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/coverhd.h
@@ -0,0 +1,134 @@
+/* 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
+ * calling overhead including passing of arguments.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+/*
+ *
+ * Units are 100ns.
+ *
+ * These numbers are of questionable use, as they are developed by calling
+ * the routine many times, thus getting its entry veneer into the (small)
+ * cache on the 403GA. This in general is not true of the RTEMS timing
+ * tests, which usually call a routine only once, thus having no cache loaded
+ * advantage.
+ *
+ * Whether the directive times are useful after deducting the function call
+ * overhead is also questionable. The user is more interested generally
+ * in the total cost of a directive, not the cost if the procedure call
+ * is inlined! (In general this is not true).
+ *
+ * Andrew Bray 18/08/1995
+ *
+ */
+
+#ifndef __COVERHD_h
+#define __COVERHD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
+#define CALLING_OVERHEAD_TASK_CREATE 0
+#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 0
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
+#define CALLING_OVERHEAD_CLOCK_GET 0
+#define CALLING_OVERHEAD_CLOCK_SET 0
+#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 0
+#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 0
+#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 0
+#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
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/dmv170.h b/c/src/lib/libbsp/powerpc/dmv177/include/dmv170.h
new file mode 100644
index 0000000000..2c0d8a0b00
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/dmv170.h
@@ -0,0 +1,215 @@
+/* dmv170.h
+ *
+ * This include file contains information pertaining to the DMV170.
+ *
+ * NOTE: Other than where absolutely required, this version currently
+ * supports only the peripherals and bits used by the basic board
+ * support package. This includes at least significant pieces of
+ * the following items:
+ *
+ * + UART Channels A and B
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef _INCLUDE_DMV170_h
+#define _INCLUDE_DMV170_h
+
+
+/*
+ * DY-4 is out of their mind and uses a non-standard clock.
+ */
+
+#undef MC68681_BAUD_RATE_MASK_9600
+#define MC68681_BAUD_RATE_MASK_9600
+
+#define DMV17x_MC68681_BAUD_RATE_MASK_9600
+
+#if 0
+#define MC68681_OFFSET_MULTIPLIER 8
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Note: Move address defs to the linker files. */
+#define DMV170_RTC_ADDRESS 0xf2c00000 /* Real Time clock Base Address*/
+#define DUART_ADDR 0xf2800000 /* base address of the DUART(68681) */
+#define SCC_ADDR 0xfb000000 /* base address for the SCC (85C30) */
+
+#define DMV170_LOCAL_CONTROL_STATUS_REG 0xf2400000
+#define DMV170_TIMER0_COUNT_INTERVAL_REG 0xf2400008
+#define DMV170_TIMER1_COUNT_INTERVAL_REG 0xf2400010
+#define DMV170_TIMER2_COUNT_INTERVAL_REG 0xf2400018
+#define DMV170_TIMER_CONTROL_REG 0xf2400020
+#define DMV170_CARD_RESORCE_REG 0xf2400040
+
+
+#define DMV170_WRITE( reg,data) \
+ *((volatile rtems_unsigned16 *)(reg)) = (data)
+
+#define DMV170_READ( reg, data ) \
+ (data) = *((volatile rtems_unsigned16 *)(reg))
+
+/*
+ * The following defines the bits in the Local Control and Status Register.
+ */
+#define DMV170_IPLx_MASK 0x0007
+#define DMV170_MAXPACK_SENSE_MASK 0x0008
+#define DMV170_MAXPACK_NOT_INSTALLED 0x0008
+#define DMV170_MAXPACK_INSTALLED 0x0000
+
+#define DMV170_MAXPACK_RESET_MASK 0x0010
+#define DMV170_MAXPACK_RESET_NEGATE 0x0010
+#define DMV170_MAXPACK_RESET_ASSERT 0x0000
+#define DMV170_EEPROM_READ_WRITE_MASK 0x0020
+#define DMV170_EEPROM_READ 0x0020
+#define DMV170_EEPROM_WRITE 0x0000
+#define DMV170_EEPROM_CLOCK_CTRL_MASK 0x0040
+#define DMV170_EEPROM_CLOCK_ASSERT 0x0040
+#define DMV170_EEPROM_CLOCK_NEGATE 0x0000
+#define DMV170_EEPROM_DATA_MASK 0x0080
+#define DMV170_EEPROM_DATA_HIGH 0x0080
+#define DMV170_EEPROM_DATA_LOW 0x0000
+
+/* Bits 8:10 68040 Transfer Modifer Codes represent the Transfer Modifier to be used on MAXPack Accesses. */
+/* Bit 11 68040 Transfer Type (TT) 0:TT are both low 1:TT are both high */
+
+#define DMV170_USER_LINK0_STATUS_MASK 0x1000
+#define DMV170_USER_LINK0_OPEN 0x1000
+#define DMV170_USER_LINK0_INSTALLED 0x0000
+#define DMV170_LOWER_STATUS_LED_CONTROL_MASK 0x2000
+#define DMV170_LOWER_STATUS_LED_IS_OFF 0x2000
+#define DMV170_LOWER_STATUS_LED_IS_ON 0x0000
+#ifdef DMV176
+ /* The following are not available for the DMV171 */
+#define DMV170_RAM_TYPE_MASK 0x4000
+#define DMV170_RAM_TYPE_IS_DRAM 0x4000
+#define DMV170_RAM_TYPE_IS_SRAM 0x0000
+#define DMV170_IACK_VECTOR_AUTOVECTOR_MASK 0x8000
+#define DMV170_IACK_VECTOR_AUTOVECTOR_IS_VECTOR 0x8000
+#define DMV170_IACK_VECTOR_AUTOVECTOR_IS_NOT_VECTOR 0x0000
+#endif
+
+/*
+ * The following defines the bits in the Timer Control Register.
+ */
+#define DMV170_TIMER0_ENABLE_MASK 0x0001
+#define DMV170_TIMER0_IS_ENABLED 0x0001
+#define DMV170_TIMER0_IS_DISABLED 0x0000
+#define DMV170_TIMER1_ENABLE_MASK 0x0002
+#define DMV170_TIMER1_IS_ENABLED 0x0002
+#define DMV170_TIMER1_IS_DISABLED 0x0000
+#define DMV170_TIMER2_ENABLE_MASK 0x0004
+#define DMV170_TIMER2_IS_ENABLED 0x0004
+#define DMV170_TIMER2_IS_DISABLED 0x0000
+#define DMV170_TIMER1_CLOCK_MASK 0x0008
+#define DMV170_TIMER1_CLOCK_AT_TIMER0 0x0008
+#define DMV170_TIMER1_CLOCK_AT_1MHZ 0x0000
+
+#define DMV170_TIMER2_CLOCK_MASK 0x0010
+#define DMV170_TIMER2_CLOCK_AT_TIMER0 0x0010
+#define DMV170_TIMER2_CLOCK_AT_1MHZ 0x0000
+#define DMV170_TIMER0_INTERRUPT_MASK 0x0020
+#define DMV170_TIMER0_INTERRUPT_ENABLE 0x0020
+#define DMV170_TIMER0_INTERRUPT_CLEAR 0x0000
+#define DMV170_TIMER1_INTERRUPT_MASK 0x0040
+#define DMV170_TIMER1_INTERRUPT_ENABLE 0x0040
+#define DMV170_TIMER1_INTERRUPT_CLEAR 0x0000
+#define DMV170_TIMER2_INTERRUPT_MASK 0x0080
+#define DMV170_TIMER2_INTERRUPT_ENABLE 0x0080
+#define DMV170_TIMER2_INTERRUPT_CLEAR 0x0000
+
+
+
+/* The Following definethe bits for the Card Resource Register */
+#define DMV170_DUART_INTERRUPT_MASK 0x0001 /* DUART Interrupt Sense Bit */
+#define DMV170_DUART_INTERRUPT_NEGATE 0x0001
+#define DMV170_DUART_INTERRUPT_ASSERT 0x0000
+#define DMV170_SONIC_INTERRUPT_MASK 0x0002 /* SONIC Interrupt Sense Bit */
+#define DMV170_SONIC_INTERRUPT_NEGATE 0x0002
+#define DMV170_SONIC_INTERRUPT_ASSERT 0x0000
+#define DMV170_SCSI_INTERRUPT_MASK 0x0004 /* SCSI Interrupt Sense Bit */
+#define DMV170_SCSI_INTERRUPT_NEGATE 0x0004
+#define DMV170_SCSI_INTERRUPT_ASSERT 0x0000
+#define DMV170_SCC_INTERRUPT_MASK 0x0008 /* SCC Interrupt Sense Bit */
+#define DMV170_SCC_INTERRUPT_NEGATE 0x0008
+#define DMV170_SCC_INTERRUPT_ASSERT 0x0000
+#define DMV170_SNOOP_ENABLE_MASK 0x0010 /* CPU Snoop Enable Bit */
+#define DMV170_SNOOP_DISABLE 0x0010
+#define DMV170_SNOOP_ENABLE 0x0000
+#define DMV170_SONIC_RESET_MASK 0x0020 /* SONIC RESET Control */
+#define DMV170_SONIC_RESET_CLEAR 0x0020
+#define DMV170_SONIC_RESET_HOLD 0x0000
+#define DMV170_NV64_WE_MASK 0x0040 /* 64-bit Non-Volital Memory */
+#define DMV170_NV64_WRITE_ENABLE 0x0040 /* Write Enable */
+#define DMV170_NV64_WRITE_DISABLE 0x0000
+#define DMV170_BOOT_NV16_MASK 0x0080 /* BOOT Device Type */
+#define DMV170_BOOT_64_BIT 0x0080
+#define DMV170_BOOT_16_BIT 0x0000
+#define DMV170_DUART_INST_MASK 0x0100 /* DUART Sense Bit */
+#define DMV170_DUART_INSTALLED 0x0100
+#define DMV170_DUART_NOT_INSTALLED 0x0000
+#define DMV170_SONIC_INST_MASK 0x0200 /* SONIC Sense Bit */
+#define DMV170_SONIC_INSTALLED 0x0200
+#define DMV170_SONIC_NOT_INSTALLED 0x0000
+#define DMV170_16M_NV64_MASK 0x0400 /* 16 Mb of 64bit Flash Sense */
+#define DMV170_16Mb_FLASH_INSTALLED 0x0400
+#define DMV170_8Mb_FLASH_INSTALLED 0x0000
+#define DMV170_SCC_INST_MASK 0x0800 /* SCC Sense Bit */
+#define DMV170_SCC_INSTALLED 0x0800
+#define DMV170_SCC_NOT_INSTALLED 0x0000
+#define DMV170_RTC_INST_MASK 0x1000 /* RTC Sense Bit */
+#define DMV170_RTC_INSTALLED 0x1000
+#define DMV170_RTC_NOT_INSTALLED 0x0000
+#define DMV170_NV64_INST_MASK 0x2000 /* 64bit Non-Volital Mem Sense*/
+
+#define DMV170_64_BIT_NON_VOLITAL_MEM_INSTALLED 0x2000
+#define DMV170_64_BIT_NON_VOLITAL_MEM_NOT_INSTALLED 0x0000
+
+
+/*
+ * DUART Baud Rate Definations.
+ */
+#define DMV170_DUART_9621 MC68681_BAUD_RATE_MASK_600 /* close to 9600 */
+
+#define DMV170_RTC_FREQUENCY 0x0000
+
+
+/*
+ * CPU General Purpose Interrupt definations (PPC_IRQ_EXTERNAL).
+ * Note: For the interrupt level read the lower 3 bits of the
+ * Local Control and Status Register.
+ */
+#define DMV170_IRQ_FIRST ( PPC_IRQ_LAST + 1 )
+
+#define DMV170_LIRQ0 ( DMV170_IRQ_FIRST + 0 )
+#define DMV170_LIRQ1 ( DMV170_IRQ_FIRST + 1 )
+#define DMV170_LIRQ2 ( DMV170_IRQ_FIRST + 2 )
+#define DMV170_LIRQ3 ( DMV170_IRQ_FIRST + 3 )
+#define DMV170_LIRQ4 ( DMV170_IRQ_FIRST + 4 )
+#define DMV170_LIRQ5 ( DMV170_IRQ_FIRST + 5 )
+
+#define MAX_BOARD_IRQS DMV170_LIRQ5
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_INCLUDE_DMV170_h */
+/* end of include file */
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/include/tod.h b/c/src/lib/libbsp/powerpc/dmv177/include/tod.h
new file mode 100644
index 0000000000..d51ceb23b9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/include/tod.h
@@ -0,0 +1,38 @@
+/*
+ * Real Time Clock (MK48T08) for RTEMS on Score603e
+ *
+ * Based on MVME162 TOD by:
+ * COPYRIGHT (C) 1997
+ * by Katsutoshi Shibuya - BU Denken Co.,Ltd. - Sapporo - JAPAN
+ * ALL RIGHTS RESERVED
+ *
+ * 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$
+ */
+
+
+#ifndef TOD_H
+#define TOD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void setRealTimeToRTEMS();
+/* Read real time from RTC and set it to RTEMS' clock manager */
+
+extern void setRealTimeFromRTEMS();
+/* Read time from RTEMS' clock manager and set it to RTC */
+
+extern int checkRealTime();
+/* Return the difference between RTC and RTEMS' clock manager time in minutes.
+ If the difference is greater than 1 day, this returns 9999. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in
new file mode 100644
index 0000000000..dcab232876
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/sonic/Makefile.in
@@ -0,0 +1,62 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGM=${ARCH}/sonic.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=sonic
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c b/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c
new file mode 100644
index 0000000000..cd748d59b7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c
@@ -0,0 +1,1176 @@
+/*
+ *******************************************************************
+ *******************************************************************
+ ** **
+ ** RTEMS/KA9Q DRIVER FOR NATIONAL DP83932 `SONIC' **
+ ** SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER **
+ ** **
+ *******************************************************************
+ *******************************************************************
+ */
+
+/*
+ * $Revision$ $Date$ $Author$
+ * $State$
+ */
+
+/*
+ * References:
+ * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
+ * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
+ * 1995.
+ *
+ * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
+ * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
+ * RRD-B30M75, National Semiconductor, March, 1991.
+ *
+ * 3) SVME/DMV-171 Single Board Computer Documentation Package, #805905,
+ * DY 4 Systems Inc., Kanata, Ontario, September, 1996.
+ */
+#include "sonic.h"
+
+#include <rtems/error.h>
+#include <ka9q/rtems_ka9q.h>
+#include <ka9q/global.h>
+#include <ka9q/domain.h>
+#include <ka9q/enet.h>
+#include <ka9q/iface.h>
+#include <ka9q/netuser.h>
+#include <ka9q/trace.h>
+#include <ka9q/commands.h>
+
+/*
+ * Number of devices supported by this driver
+ */
+#ifndef NSONIC
+# define NSONIC 1
+#endif
+
+/*
+ * Default location of device registers
+ */
+#ifndef SONIC_BASE_ADDRESS
+# define SONIC_BASE_ADDRESS 0xF3000000
+# warning "Using default SONIC_BASE_ADDRESS."
+#endif
+
+/*
+ * Default interrupt vector
+ */
+#ifndef SONIC_VECTOR
+# define SONIC_VECTOR 1
+# warning "Using default SONIC_VECTOR."
+#endif
+
+/*
+ * Default device configuration register values
+ * Conservative, generic values.
+ * DCR:
+ * No extended bus mode
+ * Unlatched bus retry
+ * Programmable outputs unused
+ * Asynchronous bus mode
+ * User definable pins unused
+ * No wait states (access time controlled by DTACK*)
+ * 32-bit DMA
+ * Empty/Fill DMA mode
+ * Maximum Transmit/Receive FIFO
+ * DC2:
+ * Extended programmable outputs unused
+ * Normal HOLD request
+ * Packet compress output unused
+ * No reject on CAM match
+ */
+#ifndef SONIC_DCR
+# define SONIC_DCR (DCR_DW | DCR_TFT1 | DCR_TFT0)
+#endif
+#ifndef SONIC_DC2
+# define SONIC_DC2 (0)
+#endif
+
+/*
+ * Default sizes of transmit and receive descriptor areas
+ */
+#define RDA_COUNT 20
+#define TDA_COUNT 10
+
+/*
+ *
+ * As suggested by National Application Note 746, make the
+ * receive resource area bigger than the receive descriptor area.
+ */
+#define RRA_EXTRA_COUNT 3
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * Largest Ethernet frame.
+ */
+#define MAXIMUM_FRAME_SIZE 1518
+
+/*
+ * Receive buffer size.
+ * Allow for a pointer, plus a full ethernet frame (including Frame
+ * Check Sequence) rounded up to a 4-byte boundary.
+ */
+#define RBUF_SIZE ((sizeof (void *) + (MAXIMUM_FRAME_SIZE) + 3) & ~3)
+#define RBUF_WC ((((MAXIMUM_FRAME_SIZE) + 3) & ~3) / 2)
+
+/*
+ * Macros for manipulating 32-bit pointers as 16-bit fragments
+ */
+#define LSW(p) ((rtems_unsigned16)((rtems_unsigned32)(p)))
+#define MSW(p) ((rtems_unsigned16)((rtems_unsigned32)(p) >> 16))
+#define PTR(m,l) ((void*)(((rtems_unsigned16)(m)<<16)|(rtems_unsigned16)(l)))
+
+/*
+ * Hardware-specific storage
+ */
+struct sonic {
+ /*
+ * Connection to KA9Q
+ */
+ struct iface *iface;
+
+ /*
+ * Default location of device registers
+ * ===CACHE===
+ * This area must be non-cacheable, guarded.
+ */
+ volatile struct SonicRegisters *sonic;
+
+ /*
+ * Interrupt vector
+ */
+ rtems_vector_number vector;
+
+ /*
+ * Task waiting for transmit resources
+ */
+ rtems_id txWaitTid;
+
+ /*
+ * Receive resource area
+ */
+ int rdaCount;
+ ReceiveResourcePointer_t rsa;
+
+ /*
+ * Transmit descriptors
+ */
+ int tdaCount;
+ TransmitDescriptorPointer_t tdaHead; /* Last filled */
+ TransmitDescriptorPointer_t tdaTail; /* Next to retire */
+ int tdaActiveCount;
+
+ /*
+ * Statistics
+ */
+ unsigned long rxInterrupts;
+ unsigned long rxMissed;
+ unsigned long rxGiant;
+ unsigned long rxNonOctet;
+ unsigned long rxBadCRC;
+ unsigned long rxCollision;
+
+ unsigned long txInterrupts;
+ unsigned long txSingleCollision;
+ unsigned long txMultipleCollision;
+ unsigned long txCollision;
+ unsigned long txDeferred;
+ unsigned long txUnderrun;
+ unsigned long txLateCollision;
+ unsigned long txExcessiveCollision;
+ unsigned long txExcessiveDeferral;
+ unsigned long txLostCarrier;
+ unsigned long txRawWait;
+};
+static struct sonic sonic[NSONIC];
+
+/*
+ ******************************************************************
+ * *
+ * Support Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Allocate non-cacheable memory on a single 64k page.
+ * Very simple minded -- just keeps trying till the memory is on a single page.
+ */
+static void *
+sonic_allocate (unsigned int nbytes)
+{
+ void *p;
+ unsigned long a1, a2;
+
+ for (;;) {
+ /*
+ * ===CACHE===
+ * Change malloc to malloc_noncacheable_guarded.
+ */
+ p = malloc (nbytes);
+ if (p == NULL)
+ rtems_panic ("No memory!");
+ a1 = (unsigned long)p;
+ a2 = a1 + nbytes - 1;
+ if ((a1 >> 16) == (a2 >> 16))
+ break;
+ }
+ return p;
+}
+
+/*
+ * Shut down the interface.
+ * This is a pretty simple-minded routine. It doesn't worry
+ * about cleaning up mbufs, shutting down daemons, etc.
+ */
+static int
+sonic_stop (struct iface *iface)
+{
+ int i;
+ struct sonic *dp = &sonic[iface->dev];
+ volatile struct SonicRegisters *rp = dp->sonic;
+
+ /*
+ * Stop the transmitter and receiver.
+ */
+ rp->cr = CR_HTX | CR_RXDIS;
+
+ /*
+ * Wait for things to stop.
+ * For safety's sake, there is an alternate exit.
+ */
+ i = 0;
+ while (rp->cr & (CR_RXEN | CR_TXP)) {
+ if (++i == 10000)
+ break;
+ }
+
+ /*
+ * Reset the device
+ */
+ rp->cr = CR_RST;
+ rp->imr = 0;
+ return 0;
+}
+
+/*
+ * Show interface statistics
+ */
+static void
+sonic_show (struct iface *iface)
+{
+ struct sonic *dp = &sonic[iface->dev];
+
+ printf (" Rx Interrupts:%-8lu", dp->rxInterrupts);
+ printf (" Giant:%-8lu", dp->rxGiant);
+ printf (" Non-octet:%-8lu\n", dp->rxNonOctet);
+ printf (" Bad CRC:%-8lu", dp->rxBadCRC);
+ printf (" Collision:%-8lu", dp->rxCollision);
+ printf (" Missed:%-8lu\n", dp->rxMissed);
+
+ printf ( " Tx Interrupts:%-8lu", dp->txInterrupts);
+ printf ( " Deferred:%-8lu", dp->txDeferred);
+ printf (" Lost Carrier:%-8lu\n", dp->txLostCarrier);
+ printf ( "Single Collisions:%-8lu", dp->txSingleCollision);
+ printf ( "Multiple Collisions:%-8lu", dp->txMultipleCollision);
+ printf ("Excessive Collisions:%-8lu\n", dp->txExcessiveCollision);
+ printf ( " Total Collisions:%-8lu", dp->txCollision);
+ printf ( " Late Collision:%-8lu", dp->txLateCollision);
+ printf (" Underrun:%-8lu\n", dp->txUnderrun);
+ printf ( " Raw output wait:%-8lu\n", dp->txRawWait);
+}
+
+/*
+ ******************************************************************
+ * *
+ * Interrupt Handler *
+ * *
+ ******************************************************************
+ */
+static rtems_isr
+sonic_interrupt_handler (rtems_vector_number v)
+{
+ struct sonic *dp = sonic;
+ volatile struct SonicRegisters *rp;
+
+#if (NSONIC > 1)
+ /*
+ * Find the device which requires service
+ */
+ for (;;) {
+ if (dp->vector == v)
+ break;
+ if (++dp == &sonic[NSONIC])
+ return; /* Spurious interrupt? */
+ }
+#endif /* NSONIC > 1 */
+
+ /*
+ * Get pointer to SONIC registers
+ */
+ rp = dp->sonic;
+
+ /*
+ * Packet received or receive buffer area exceeded?
+ */
+ if ((rp->imr & (IMR_PRXEN | IMR_RBAEEN))
+ && (rp->isr & (ISR_PKTRX | ISR_RBAE))) {
+ rp->imr &= ~(IMR_PRXEN | IMR_RBAEEN);
+ dp->rxInterrupts++;
+ rtems_event_send (dp->iface->rxproc, INTERRUPT_EVENT);
+ }
+
+ /*
+ * Packet started, transmitter done or transmitter error?
+ */
+ if ((rp->imr & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN))
+ && (rp->isr & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
+ rp->imr &= ~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN);
+ dp->txInterrupts++;
+ rtems_event_send (dp->txWaitTid, INTERRUPT_EVENT);
+ }
+}
+
+/*
+ ******************************************************************
+ * *
+ * Transmitter Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Soak up transmit descriptors that have been sent.
+ */
+static void
+sonic_retire_tda (struct sonic *dp)
+{
+ rtems_unsigned16 status;
+ unsigned int collisions;
+
+ /*
+ * Repeat for all completed transmit descriptors.
+ */
+ while ((dp->tdaActiveCount != 0)
+ && ((status = dp->tdaTail->status) != 0)) {
+ /*
+ * Check for errors which stop the transmitter.
+ */
+ if (status & (TDA_STATUS_EXD |
+ TDA_STATUS_EXC |
+ TDA_STATUS_FU |
+ TDA_STATUS_BCM)) {
+ /*
+ * Restart the transmitter if there are
+ * packets waiting to go.
+ */
+ rtems_unsigned16 link;
+ link = *(dp->tdaTail->linkp);
+
+ if ((link & TDA_LINK_EOL) == 0) {
+ volatile struct SonicRegisters *rp = dp->sonic;
+
+ rp->ctda = link;
+ rp->cr = CR_TXP;
+ }
+ }
+
+ /*
+ * Update network statistics
+ */
+ collisions = (status & TDA_STATUS_COLLISION_MASK) >> TDA_STATUS_COLLISION_SHIFT;
+ if (collisions) {
+ if (collisions == 1)
+ dp->txSingleCollision++;
+ else
+ dp->txMultipleCollision++;
+ dp->txCollision += collisions;
+ }
+ if (status & TDA_STATUS_EXC)
+ dp->txExcessiveCollision++;
+ if (status & TDA_STATUS_OWC)
+ dp->txLateCollision++;
+ if (status & TDA_STATUS_EXD)
+ dp->txExcessiveDeferral++;
+ if (status & TDA_STATUS_DEF)
+ dp->txDeferred++;
+ if (status & TDA_STATUS_FU)
+ dp->txUnderrun++;
+ if (status & TDA_STATUS_CRSL)
+ dp->txLostCarrier++;
+
+ /*
+ * Free the packet
+ */
+ dp->tdaActiveCount--;
+ free_p ((struct mbuf **)&dp->tdaTail->mbufp);
+
+ /*
+ * Move to the next transmit descriptor
+ */
+ dp->tdaTail = dp->tdaTail->next;
+ }
+}
+
+/*
+ * Send raw packet (caller provides header).
+ * This code runs in the context of the interface transmit
+ * task (most packets) or in the context of the network
+ * task (for ARP requests).
+ */
+static int
+sonic_raw (struct iface *iface, struct mbuf **bpp)
+{
+ struct sonic *dp = &sonic[iface->dev];
+ volatile struct SonicRegisters *rp = dp->sonic;
+ struct mbuf *bp;
+ TransmitDescriptorPointer_t tdp;
+ volatile struct TransmitDescriptorFragLink *fp;
+ unsigned int packetSize;
+ int i;
+ static char padBuf[64];
+
+ /*
+ * Update the log.
+ */
+ iface->rawsndcnt++;
+ iface->lastsent = secclock ();
+ dump (iface, IF_TRACE_OUT, *bpp);
+
+ /*
+ * It would not do to have two tasks active in the transmit
+ * loop at the same time.
+ * The blocking is simple-minded since the odds of two tasks
+ * simultaneously attempting to use this code are low. The only
+ * way that two tasks can try to run here is:
+ * 1) Task A enters this code and ends up having to
+ * wait for a transmit buffer descriptor.
+ * 2) Task B gains control and tries to transmit a packet.
+ * The RTEMS/KA9Q scheduling semaphore ensures that there
+ * are no race conditions associated with manipulating the
+ * txWaitTid variable.
+ */
+ if (dp->txWaitTid) {
+ dp->txRawWait++;
+ while (dp->txWaitTid)
+ rtems_ka9q_ppause (10);
+ }
+
+ /*
+ * Free up transmit descriptors.
+ */
+ sonic_retire_tda (dp);
+
+ /*
+ * Wait for transmit descriptor to become available.
+ */
+ if (dp->tdaActiveCount == dp->tdaCount) {
+ /*
+ * Find out who we are
+ */
+ if (dp->txWaitTid == 0)
+ rtems_task_ident (RTEMS_SELF, 0, &dp->txWaitTid);
+
+ /*
+ * Clear old events.
+ */
+ rp->isr = ISR_PINT | ISR_TXDN | ISR_TXER;
+
+ /*
+ * Wait for transmit descriptor to become available.
+ * Note that the transmit descriptors are checked
+ * *before* * entering the wait loop -- this catches
+ * the possibility that a transmit descriptor became
+ * available between the `if' the started this block,
+ * and the clearing of the interrupt status register.
+ */
+ sonic_retire_tda (dp);
+ while (dp->tdaActiveCount == dp->tdaCount) {
+ /*
+ * Enable transmitter interrupts.
+ */
+ rp->imr |= (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN);
+
+ /*
+ * Wait for interrupt
+ */
+ rtems_ka9q_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT);
+ rp->isr = ISR_PINT | ISR_TXDN | ISR_TXER;
+ sonic_retire_tda (dp);
+ }
+ }
+
+ /*
+ * Get the head of the packet mbuf chain.
+ */
+ bp = *bpp;
+
+ /*
+ * Fill in the transmit descriptor fragment descriptors.
+ * ===CACHE===
+ * If data cache is operating in write-back mode, flush cached
+ * data to memory.
+ */
+ tdp = dp->tdaHead->next;
+ tdp->mbufp = bp;
+ packetSize = 0;
+ fp = tdp->frag;
+ for (i = 0 ; i < MAXIMUM_FRAGS_PER_DESCRIPTOR ; i++, fp++) {
+ fp->frag_lsw = LSW(bp->data);
+ fp->frag_msw = MSW(bp->data);
+ fp->frag_size = bp->cnt;
+ packetSize += bp->cnt;
+
+ /*
+ * Break out of the loop if this mbuf is the last in the frame.
+ */
+ if ((bp = bp->next) == NULL)
+ break;
+ }
+
+ /*
+ * Pad short packets.
+ */
+ if ((packetSize < 64) && (i < MAXIMUM_FRAGS_PER_DESCRIPTOR)) {
+ int padSize = 64 - packetSize;
+ fp->frag_lsw = LSW(padBuf);
+ fp->frag_msw = MSW(padBuf);
+ fp->frag_size = padSize;
+ packetSize += padSize;
+ i++;
+ fp++;
+ }
+
+ /*
+ * Fill Transmit Descriptor
+ */
+ tdp->pkt_size = packetSize;
+ tdp->frag_count = i;
+ tdp->status = 0;
+
+ /*
+ * Chain onto list and start transmission.
+ */
+ tdp->linkp = &fp->frag_link;
+ *tdp->linkp = LSW(tdp->next) | TDA_LINK_EOL;
+ *dp->tdaHead->linkp &= ~TDA_LINK_EOL;
+ rp->cr = CR_TXP;
+ dp->tdaActiveCount++;
+ dp->tdaHead = tdp;
+
+ /*
+ * Let KA9Q know the packet is on the way.
+ */
+ dp->txWaitTid = 0;
+ *bpp = NULL;
+ return 0;
+}
+
+/*
+ ******************************************************************
+ * *
+ * Receiver Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Wait for SONIC to hand over a Receive Descriptor.
+ */
+static void
+sonic_rda_wait (struct sonic *dp, ReceiveDescriptorPointer_t rdp)
+{
+ int i;
+ volatile struct SonicRegisters *rp = dp->sonic;
+
+ /*
+ * Wait for Receive Descriptor.
+ * The order of the tests is very important.
+ * The RDA is checked after RBAE is detected. This ensures that
+ * the driver processes all RDA entries before reusing the RRA
+ * entry holding the giant packet.
+ * The event wait is done after the RDA and RBAE checks. This
+ * catches the possibility that a Receive Descriptor became ready
+ * between the call to this function and the clearing of the
+ * interrupt status register bit.
+ */
+ for (;;) {
+ /*
+ * Has a giant packet arrived?
+ * The National DP83932C data sheet is very vague on what
+ * happens under this condition. The description of the
+ * Interrupt Status Register (Section 4.3.6) states,
+ * ``Reception is aborted and the SONIC fetches the next
+ * available resource descriptors in the RRA. The buffer
+ * space is not re-used and an RDA is not setup for the
+ * truncated packet.''
+ * I take ``Reception is aborted'' to mean that the RXEN
+ * bit in the Command Register is cleared and must be set
+ * by the driver to begin reception again.
+ * Unfortunately, an alternative interpretation could be
+ * that only reception of the current packet is aborted.
+ * This would be more difficult to recover from....
+ */
+ if (rp->isr & ISR_RBAE) {
+ /*
+ * One more check to soak up any Receive Descriptors
+ * that may already have been handed back to the driver.
+ */
+ if (rdp->in_use == 0)
+ break;
+
+ /*
+ * Check my interpretation of the SONIC manual.
+ */
+ if (rp->cr & CR_RXEN)
+ rtems_panic ("SONIC RBAE/RXEN");
+
+ /*
+ * Update statistics
+ */
+ dp->rxGiant++;
+
+ /*
+ * Reuse receive buffer.
+ * Again, the manual is subject to interpretation. The
+ * RRP register is described as, `the lower address of
+ * the next descriptor the SONIC will read.''
+ * Since, acording to the ISR/RBAE notes, the SONIC has
+ * ``fetched the next available resource descriptor in
+ * the RRA'', I interpret this to mean that that the
+ * driver has to move the RRP back *two* entries to
+ * reuse the receive buffer holding the giant packet.
+ */
+ for (i = 0 ; i < 2 ; i++) {
+ if (rp->rrp == rp->rsa)
+ rp->rrp = rp->rea;
+ rp->rrp -= sizeof (ReceiveResource_t);
+ }
+
+ /*
+ * Restart reception
+ */
+ rp->isr = ISR_RBAE;
+ rp->cr = CR_RXEN;
+ }
+
+ /*
+ * Clear old packet-received events.
+ */
+ rp->isr = ISR_PKTRX;
+
+ /*
+ * Has Receive Descriptor become available?
+ */
+ if (rdp->in_use == 0)
+ break;
+
+ /*
+ * Enable interrupts.
+ */
+ rp->imr |= IMR_PRXEN | IMR_RBAEEN;
+
+ /*
+ * Wait for interrupt.
+ */
+ rtems_ka9q_event_receive (INTERRUPT_EVENT,
+ RTEMS_WAIT|RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT);
+ }
+}
+
+/*
+ * SCC reader task
+ */
+static void
+sonic_rx (int dev, void *p1, void *p2)
+{
+ struct iface *iface = (struct iface *)p1;
+ struct sonic *dp = (struct sonic *)p2;
+ volatile struct SonicRegisters *rp = dp->sonic;
+ struct mbuf *bp;
+ rtems_unsigned16 status;
+ ReceiveDescriptor_t *rda;
+ ReceiveDescriptorPointer_t ordp, rdp;
+ ReceiveResourcePointer_t rwp, rea;
+ rtems_unsigned16 newMissedTally, oldMissedTally;
+ int i;
+ int continuousCount;
+
+ /*
+ * Set up list in Receive Resource Area.
+ * Allocate space for incoming packets.
+ */
+ rwp = dp->rsa;
+ for (i = 0 ; i < (dp->rdaCount + RRA_EXTRA_COUNT) ; i++, rwp++) {
+ struct mbuf **mbp;
+
+ /*
+ * Allocate memory for buffer.
+ * Place a pointer to the mbuf at the beginning of the buffer
+ * so we can find the mbuf when the SONIC returns the buffer
+ * to the driver.
+ */
+ bp = ambufw (RBUF_SIZE);
+ mbp = (struct mbuf **)bp->data;
+ bp->data += sizeof *mbp;
+ *mbp = bp;
+
+ /*
+ * Set up RRA entry
+ */
+ rwp->buff_ptr_lsw = LSW(bp->data);
+ rwp->buff_ptr_msw = MSW(bp->data);
+ rwp->buff_wc_lsw = RBUF_WC;
+ rwp->buff_wc_msw = 0;
+ }
+ rea = rwp;
+
+ /*
+ * Set up remaining Receive Resource Area pointers
+ */
+ rp->rsa = LSW(dp->rsa);
+ rp->rrp = LSW(dp->rsa);
+ rp->rea = LSW(rea);
+ rp->rwp = LSW(rea);
+
+ /*
+ * Set End Of Buffer Count register to the value recommended
+ * in Note 1 of Section 3.4.4.4 of the SONIC data sheet.
+ */
+ rp->eobc = RBUF_WC - 2;
+
+ /*
+ * Set up circular linked list in Receive Descriptor Area.
+ * Leaves ordp pointing at the `end' of the list and
+ * rdp pointing at the `beginning' of the list.
+ */
+ rda = sonic_allocate (dp->rdaCount * sizeof *rda);
+ ordp = rdp = rda;
+ for (i = 0 ; i < dp->rdaCount ; i++) {
+ /*
+ * Set up RDA entry
+ */
+ if (i == (dp->rdaCount - 1))
+ rdp->next = rda;
+ else
+ rdp->next = (ReceiveDescriptor_t *)(rdp + 1);
+ rdp->in_use = 1;
+ ordp = rdp;
+ rdp = rdp->next;
+ ordp->link = LSW(rdp);
+ }
+ ordp->link |= RDA_LINK_EOL;
+ rp->urda = MSW(rdp);
+ rp->crda = LSW(rdp);
+
+ /*
+ * Start the receiver
+ */
+ oldMissedTally = rp->mpt;
+ rp->cr = CR_RRRA;
+ rp->cr = CR_RXEN;
+
+ /*
+ * Input packet handling loop
+ */
+ continuousCount = 0;
+ for (;;) {
+ /*
+ * Wait till SONIC supplies a Receive Descriptor.
+ */
+ if (rdp->in_use) {
+ continuousCount = 0;
+ sonic_rda_wait (dp, rdp);
+ }
+
+ /*
+ * Check that packet is valid
+ */
+ status = rdp->status;
+ if (status & RDA_STATUS_PRX) {
+ struct mbuf **mbp;
+ void *p;
+
+ /*
+ * Get the mbuf pointer
+ */
+ p = PTR(rdp->pkt_msw, rdp->pkt_lsw);
+ mbp = (struct mbuf **)p - 1;
+ bp = *mbp;
+
+ /*
+ * Pass the packet up the chain.
+ * The mbuf count is reduced to remove
+ * the frame check sequence at the end
+ * of the packet.
+ * ===CACHE===
+ * Invalidate cache entries for this memory.
+ */
+ bp->cnt = rdp->byte_count - sizeof (uint32);
+ net_route (iface, &bp);
+
+ /*
+ * Give the network code a chance to digest the
+ * packet. This guards against a flurry of
+ * incoming packets (usually an ARP storm) from
+ * using up all the available memory.
+ */
+ if (++continuousCount >= dp->rdaCount)
+ kwait_null ();
+
+ /*
+ * Sanity check that Receive Resource Area is
+ * still in sync with Receive Descriptor Area
+ * The buffer reported in the Receive Descriptor
+ * should be the same as the buffer in the Receive
+ * Resource we are about to reuse.
+ */
+ if ((LSW(p) != rwp->buff_ptr_lsw)
+ || (MSW(p) != rwp->buff_ptr_msw))
+ rtems_panic ("SONIC RDA/RRA");
+
+ /*
+ * Allocate a new mbuf.
+ */
+ bp = ambufw (RBUF_SIZE);
+ mbp = (struct mbuf **)bp->data;
+ bp->data += sizeof *mbp;
+ *mbp = bp;
+
+ /*
+ * Reuse Receive Resource.
+ */
+ rwp->buff_ptr_lsw = LSW(bp->data);
+ rwp->buff_ptr_msw = MSW(bp->data);
+ rwp++;
+ if (rwp == rea)
+ rwp = dp->rsa;
+ rp->rwp = LSW(rwp);
+
+ /*
+ * Tell the SONIC to reread the RRA.
+ */
+ if (rp->isr & ISR_RBE)
+ rp->isr = ISR_RBE;
+ }
+ else {
+ if (status & RDA_STATUS_COL)
+ dp->rxCollision++;
+ if (status & RDA_STATUS_FAER)
+ dp->rxNonOctet++;
+ else if (status & RDA_STATUS_CRCR)
+ dp->rxBadCRC++;
+ }
+
+ /*
+ * Count missed packets
+ */
+ newMissedTally = rp->mpt;
+ if (newMissedTally != oldMissedTally) {
+ dp->rxMissed += (newMissedTally - oldMissedTally) & 0xFFFF;
+ newMissedTally = oldMissedTally;
+ }
+
+ /*
+ * Move to next receive descriptor
+ */
+ rdp->link |= RDA_LINK_EOL;
+ rdp->in_use = 1;
+ ordp->link &= ~RDA_LINK_EOL;
+ ordp = rdp;
+ rdp = rdp->next;
+ }
+}
+
+/*
+ ******************************************************************
+ * *
+ * Initialization Routines *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Initialize the SONIC hardware
+ */
+static void
+sonic_initialize_hardware (struct sonic *dp, int broadcastFlag)
+{
+ volatile struct SonicRegisters *rp = dp->sonic;
+ int i;
+ unsigned char *hwaddr;
+ rtems_status_code sc;
+ rtems_isr_entry old_handler;
+ TransmitDescriptorPointer_t otdp, tdp;
+ struct CamDescriptor{
+ rtems_unsigned32 cep;
+ rtems_unsigned32 cap0;
+ rtems_unsigned32 cap1;
+ rtems_unsigned32 cap2;
+ rtems_unsigned32 ce;
+ };
+ volatile struct CamDescriptor *cdp;
+
+ /*
+ * Issue a software reset if necessary.
+ */
+ if ((rp->cr & CR_RST) == 0)
+ rp->cr = CR_RST;
+
+ /*
+ * Set up data configuration registers.
+ */
+ rp->dcr = SONIC_DCR;
+ rp->dcr2 = SONIC_DC2;
+
+ /*
+ * Remove device reset
+ */
+ rp->cr = 0;
+
+ /*
+ * Clear outstanding interrupts.
+ */
+ rp->isr = 0x7FFF;
+
+ /*
+ * Allocate the receive resource area.
+ * In accordance with National Application Note 746, make the
+ * receive resource area bigger than the receive descriptor area.
+ * This has the useful side effect of making the receive resource
+ * area big enough to hold the CAM descriptor area.
+ */
+ dp->rsa = sonic_allocate ((dp->rdaCount + RRA_EXTRA_COUNT) * sizeof *dp->rsa);
+ rp->urra = MSW(dp->rsa);
+
+ /*
+ * Set up the SONIC CAM with our hardware address.
+ * Use the Receive Resource Area to hold the CAM Descriptor Area.
+ */
+ hwaddr = dp->iface->hwaddr;
+ cdp = (struct CamDescriptor *)dp->rsa;
+ cdp->cep = 0; /* Fill first entry in CAM */
+ cdp->cap2 = hwaddr[0] << 8 | hwaddr[1];
+ cdp->cap1 = hwaddr[2] << 8 | hwaddr[3];
+ cdp->cap0 = hwaddr[4] << 8 | hwaddr[5];
+ cdp->ce = 0x0001; /* Enable first entry in CAM */
+ rp->cdc = 1; /* One entry in CDA */
+ rp->cdp = LSW(cdp);
+ rp->cr = CR_LCAM; /* Load the CAM */
+ while (rp->cr & CR_LCAM)
+ continue;
+
+ /*
+ * Verify that CAM was properly loaded.
+ */
+ rp->cep = 0; /* Select first entry in CAM */
+ if ((rp->cap2 != cdp->cap2)
+ || (rp->cap1 != cdp->cap1)
+ || (rp->cap0 != cdp->cap0)
+ || (rp->ce != cdp->ce)) {
+ printf ("Failed to load Ethernet address into SONIC CAM.\n"
+ " Wrote %04x%04x%04x - %#x\n"
+ " Read %04x%04x%04x - %#x\n",
+ cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
+ rp->cap2, rp->cap1, rp->cap0, rp->ce);
+ rtems_panic ("SONIC LCAM");
+ }
+
+ /*
+ * Set up circular linked list in Transmit Descriptor Area.
+ * Use the PINT bit in the transmit configuration field to
+ * request an interrupt on every other transmitted packet.
+ */
+ dp->tdaActiveCount = 0;
+ dp->tdaTail = sonic_allocate (dp->tdaCount * sizeof *tdp);
+ otdp = tdp = dp->tdaTail;
+ for (i = 0 ; i < dp->tdaCount ; i++) {
+ if (i & 1)
+ tdp->pkt_config = TDA_CONFIG_PINT;
+ else
+ tdp->pkt_config = 0;
+ if (i == (dp->tdaCount - 1))
+ tdp->next = (TransmitDescriptor_t *)dp->tdaTail;
+ else
+ tdp->next = (TransmitDescriptor_t *)(tdp + 1);
+ otdp = tdp;
+ tdp = tdp->next;
+ }
+ dp->tdaHead = otdp;
+ dp->tdaHead->linkp = &dp->tdaHead->frag[0].frag_link;
+ rp->utda = MSW(dp->tdaTail);
+ rp->ctda = LSW(dp->tdaTail);
+
+ /*
+ * Enable/disable reception of broadcast packets
+ */
+ if (broadcastFlag)
+ rp->rcr = RCR_BRD;
+ else
+ rp->rcr = 0;
+
+ /*
+ * Attach SONIC interrupt handler
+ */
+ rp->imr = 0;
+ sc = rtems_interrupt_catch (sonic_interrupt_handler, dp->vector, &old_handler);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't attach SONIC interrupt handler: %s\n",
+ rtems_status_text (sc));
+
+ /*
+ * Remainder of hardware initialization is
+ * done by the receive and transmit daemons.
+ */
+}
+
+/*
+ * Attach an SONIC driver to the system
+ * This is the only `extern' function in the driver.
+ *
+ * argv[0]: interface label, e.g. "rtems"
+ * The remainder of the arguments are optional key/value pairs:
+ * mtu ## -- maximum transmission unit, default 1500
+ * broadcast y/n -- accept or ignore broadcast packets, default yes
+ * rbuf ## -- Set number of receive descriptor entries
+ * tbuf ## -- Set number of transmit descriptor entries
+ * ip ###.###.###.### -- IP address
+ * ether ##:##:##:##:##:## -- Ethernet address
+ * reg ###### -- Address of SONIC device registers
+ * vector ### -- SONIC interrupt vector
+ */
+int
+rtems_ka9q_driver_attach (int argc, char *argv[], void *p)
+{
+ struct sonic *dp;
+ struct iface *iface;
+ char *cp;
+ int argIndex;
+ int broadcastFlag;
+ char cbuf[30];
+
+ /*
+ * Find an unused entry
+ */
+ dp = sonic;
+ for (;;) {
+ if (dp == &sonic[NSONIC]) {
+ printf ("No more SONIC devices.\n");
+ return -1;
+ }
+ if (dp->iface == NULL)
+ break;
+ dp++;
+ }
+ if (if_lookup (argv[0]) != NULL) {
+ printf ("Interface %s already exists\n", argv[0]);
+ return -1;
+ }
+
+ /*
+ * Create an inteface descriptor
+ */
+ iface = callocw (1, sizeof *iface);
+ iface->name = strdup (argv[0]);
+ iface->dev = dp - sonic;;
+
+ /*
+ * Set default values
+ */
+ broadcastFlag = 1;
+ dp->txWaitTid = 0;
+ dp->rdaCount = RDA_COUNT;
+ dp->tdaCount = TDA_COUNT;
+ iface->mtu = 1500;
+ iface->addr = Ip_addr;
+ iface->hwaddr = mallocw (EADDR_LEN);
+ memset (iface->hwaddr, 0x08, EADDR_LEN);
+ dp->sonic = (struct SonicRegisters *)SONIC_BASE_ADDRESS;
+ dp->vector = SONIC_VECTOR;
+
+ /*
+ * Parse remaining arguments
+ */
+ for (argIndex = 1 ; argIndex < (argc - 1) ; argIndex++) {
+ if (strcmp ("mtu", argv[argIndex]) == 0) {
+ iface->mtu = strtoul (argv[++argIndex], NULL, 0);
+ }
+ else if (strcmp ("broadcast", argv[argIndex]) == 0) {
+ if (*argv[++argIndex] == 'n')
+ broadcastFlag = 0;
+ }
+ else if (strcmp ("rbuf", argv[argIndex]) == 0) {
+ /*
+ * The minimum RDA count is 2. A single-entry RDA
+ * would be difficult to use since the SONIC does
+ * not release (in_use = 0) the RDA that has the
+ * EOL bit set.
+ */
+ dp->rdaCount = strtoul (argv[++argIndex], NULL, 0);
+ if ((dp->rdaCount <= 1) || (dp->rdaCount > 200)) {
+ printf ("RDA option (%d) is invalid.\n", dp->rdaCount);
+ return -1;
+ }
+ }
+ else if (strcmp ("tbuf", argv[argIndex]) == 0) {
+ dp->tdaCount = strtoul (argv[++argIndex], NULL, 0);
+ if ((dp->tdaCount <= 1) || (dp->tdaCount > 200)) {
+ printf ("TDA option (%d) is invalid.\n", dp->tdaCount);
+ return -1;
+ }
+ }
+ else if (strcmp ("ip", argv[argIndex]) == 0) {
+ iface->addr = resolve (argv[++argIndex]);
+ }
+ else if (strcmp ("ether", argv[argIndex]) == 0) {
+ gether (iface->hwaddr, argv[++argIndex]);
+ }
+ else if (strcmp ("reg", argv[argIndex]) == 0) {
+ dp->sonic = (struct SonicRegisters *)strtoul (argv[++argIndex], NULL, 0);
+ }
+ else if (strcmp ("vector", argv[argIndex]) == 0) {
+ dp->vector = strtoul (argv[++argIndex], NULL, 0);
+ }
+ else {
+ printf ("Argument %d (%s) is invalid.\n", argIndex, argv[argIndex]);
+ return -1;
+ }
+ }
+ printf ("Ethernet address: %s\n", pether (cbuf, iface->hwaddr));
+ iface->raw = sonic_raw;
+ iface->stop = sonic_stop;
+ iface->show = sonic_show;
+ dp->iface = iface;
+ setencap (iface, "Ethernet");
+
+ /*
+ * Set up SONIC hardware
+ */
+ sonic_initialize_hardware (dp, broadcastFlag);
+
+ /*
+ * Chain onto list of interfaces
+ */
+ iface->next = Ifaces;
+ Ifaces = iface;
+
+ /*
+ * Start I/O daemons
+ */
+ cp = if_name (iface, " tx");
+ iface->txproc = newproc (cp, 2048, if_tx, iface->dev, iface, NULL, 0);
+ free (cp);
+ cp = if_name (iface, " rx");
+ iface->rxproc = newproc (cp, 2048, sonic_rx, iface->dev, iface, dp, 0);
+ free (cp);
+ return 0;
+}
diff --git a/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h b/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h
new file mode 100644
index 0000000000..2607e2a170
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.h
@@ -0,0 +1,364 @@
+/*
+ *******************************************************************
+ *******************************************************************
+ ** **
+ ** DECLARATIONS FOR NATIONAL DP83932 `SONIC' **
+ ** SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER **
+ ** **
+ *******************************************************************
+ *******************************************************************
+ */
+
+/*
+ * $Revision$ $Date$ $Author$
+ * $State$
+ */
+
+#ifndef _SONIC_DP83932_
+#define _SONIC_DP83932_
+
+#include <bsp.h>
+
+/*
+ ******************************************************************
+ * *
+ * Device Registers *
+ * *
+ ******************************************************************
+ */
+struct SonicRegisters {
+ /*
+ * Command and status registers
+ */
+ rtems_unsigned32 cr; /* Command */
+ rtems_unsigned32 dcr; /* Data configuration */
+ rtems_unsigned32 rcr; /* Receive control */
+ rtems_unsigned32 tcr; /* Transmit control */
+ rtems_unsigned32 imr; /* Interrupt mask */
+ rtems_unsigned32 isr; /* Interrupt status */
+
+ /*
+ * Transmit registers
+ */
+ rtems_unsigned32 utda; /* Upper transmit descriptor address */
+ rtems_unsigned32 ctda; /* Current transmit descriptor address */
+
+ /*
+ * Receive registers
+ */
+ rtems_unsigned32 pad0[5];
+ rtems_unsigned32 urda; /* Upper receive descriptor address */
+ rtems_unsigned32 crda; /* Current receive descriptor address */
+ rtems_unsigned32 pad1[4];
+ rtems_unsigned32 eobc; /* End of buffer word count */
+ rtems_unsigned32 urra; /* Upper receive resource */
+ rtems_unsigned32 rsa; /* Resource start address */
+ rtems_unsigned32 rea; /* Resource end address */
+ rtems_unsigned32 rrp; /* Resouce read pointer */
+ rtems_unsigned32 rwp; /* Resouce read pointer */
+
+ /*
+ * Content-addressable memory registers
+ */
+ rtems_unsigned32 pad2[8];
+ rtems_unsigned32 cep; /* CAM entry pointer */
+ rtems_unsigned32 cap2; /* CAM address port 2 */
+ rtems_unsigned32 cap1; /* CAM address port 1 */
+ rtems_unsigned32 cap0; /* CAM address port 0 */
+ rtems_unsigned32 ce; /* CAM enable */
+ rtems_unsigned32 cdp; /* CAM descriptor pointer */
+ rtems_unsigned32 cdc; /* CAM descriptor count */
+
+ /*
+ * Silicon revision
+ */
+ rtems_unsigned32 sr; /* Silicon revision */
+
+ /*
+ * Watchdog counters
+ */
+ rtems_unsigned32 wt0; /* Watchdog timer 0 */
+ rtems_unsigned32 wt1; /* Watchdog timer 1 */
+
+ /*
+ * Another receive register
+ */
+ rtems_unsigned32 rsc; /* Receive sequence counter */
+
+ /*
+ * Tally counters
+ */
+ rtems_unsigned32 crct; /* CRC error tally */
+ rtems_unsigned32 faet; /* FAE tally */
+ rtems_unsigned32 mpt; /* Missed packet tally */
+
+ /*
+ * Another command and status register
+ */
+ rtems_unsigned32 pad3[16];
+ rtems_unsigned32 dcr2; /* Data configuration 2 */
+};
+
+/*
+ * Command register
+ */
+#define CR_LCAM 0x0200
+#define CR_RRRA 0x0100
+#define CR_RST 0x0080
+#define CR_ST 0x0020
+#define CR_STP 0x0010
+#define CR_RXEN 0x0008
+#define CR_RXDIS 0x0004
+#define CR_TXP 0x0002
+#define CR_HTX 0x0001
+
+/*
+ * Data configuration register
+ */
+#define DCR_EXBUS 0x8000
+#define DCR_LBR 0x2000
+#define DCR_PO1 0x1000
+#define DCR_PO0 0x0800
+#define DCR_SBUS 0x0400
+#define DCR_USR1 0x0200
+#define DCR_USR0 0x0100
+#define DCR_WC1 0x0080
+#define DCR_WC0 0x0040
+#define DCR_DW 0x0020
+#define DCR_BMS 0x0010
+#define DCR_RFT1 0x0008
+#define DCR_RFT0 0x0004
+#define DCR_TFT1 0x0002
+#define DCR_TFT0 0x0001
+
+/*
+ * Receive control register
+ */
+#define RCR_ERR 0x8000
+#define RCR_RNT 0x4000
+#define RCR_BRD 0x2000
+#define RCR_PRO 0x1000
+#define RCR_AMC 0x0800
+#define RCR_LB1 0x0400
+#define RCR_LB0 0x0200
+#define RCR_MC 0x0100
+#define RCR_BC 0x0080
+#define RCR_LPKT 0x0040
+#define RCR_CRS 0x0020
+#define RCR_COL 0x0010
+#define RCR_CRCR 0x0008
+#define RCR_FAER 0x0004
+#define RCR_LBK 0x0002
+#define RCR_PRX 0x0001
+
+/*
+ * Transmit control register
+ */
+#define TCR_PINT 0x8000
+#define TCR_POWC 0x4000
+#define TCR_CRCI 0x2000
+#define TCR_EXDIS 0x1000
+#define TCR_EXD 0x0400
+#define TCR_DEF 0x0200
+#define TCR_NCRS 0x0100
+#define TCR_CRSL 0x0080
+#define TCR_EXC 0x0040
+#define TCR_OWC 0x0020
+#define TCR_PMB 0x0008
+#define TCR_FU 0x0004
+#define TCR_BCM 0x0002
+#define TCR_PTX 0x0001
+
+/*
+ * Interrupt mask register
+ */
+#define IMR_BREN 0x4000
+#define IMR_HBLEN 0x2000
+#define IMR_LCDEN 0x1000
+#define IMR_PINTEN 0x0800
+#define IMR_PRXEN 0x0400
+#define IMR_PTXEN 0x0200
+#define IMR_TXEREN 0x0100
+#define IMR_TCEN 0x0080
+#define IMR_RDEEN 0x0040
+#define IMR_RBEEN 0x0020
+#define IMR_RBAEEN 0x0010
+#define IMR_CRCEN 0x0008
+#define IMR_FAEEN 0x0004
+#define IMR_MPEN 0x0002
+#define IMR_RFOEN 0x0001
+
+/*
+ * Interrupt status register
+ */
+#define ISR_BR 0x4000
+#define ISR_HBL 0x2000
+#define ISR_LCD 0x1000
+#define ISR_PINT 0x0800
+#define ISR_PKTRX 0x0400
+#define ISR_TXDN 0x0200
+#define ISR_TXER 0x0100
+#define ISR_TC 0x0080
+#define ISR_RDE 0x0040
+#define ISR_RBE 0x0020
+#define ISR_RBAE 0x0010
+#define ISR_CRC 0x0008
+#define ISR_FAE 0x0004
+#define ISR_MP 0x0002
+#define ISR_RFO 0x0001
+
+/*
+ * Data configuration register 2
+ */
+#define DCR2_EXPO3 0x8000
+#define DCR2_EXPO2 0x4000
+#define DCR2_EXPO1 0x2000
+#define DCR2_EXPO0 0x1000
+#define DCR2_PH 0x0010
+#define DCR2_PCM 0x0004
+#define DCR2_PCNM 0x0002
+#define DCR2_RJCM 0x0001
+
+/*
+ ******************************************************************
+ * *
+ * Transmit Buffer Management *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Transmit descriptor area entry.
+ * There is one transmit descriptor for each packet to be transmitted.
+ * Statically reserve space for up to MAXIMUM_FRAGS_PER_PACKET fragments
+ * per descriptor.
+ */
+#define MAXIMUM_FRAGS_PER_DESCRIPTOR 6
+struct TransmitDescriptor {
+ rtems_unsigned32 status;
+ rtems_unsigned32 pkt_config;
+ rtems_unsigned32 pkt_size;
+ rtems_unsigned32 frag_count;
+
+ /*
+ * Packet fragment pointers
+ */
+ struct TransmitDescriptorFragLink {
+ rtems_unsigned32 frag_lsw; /* LSW of fragment address */
+#define frag_link frag_lsw
+ rtems_unsigned32 frag_msw; /* MSW of fragment address */
+ rtems_unsigned32 frag_size;
+ } frag[MAXIMUM_FRAGS_PER_DESCRIPTOR];
+
+ /*
+ * Space for link if all fragment pointers are used.
+ */
+ rtems_unsigned32 link_pad;
+
+ /*
+ * Extra RTEMS/KA9Q stuff
+ */
+ struct TransmitDescriptor *next; /* Circularly-linked list */
+ struct mbuf *mbufp; /* First mbuf in packet */
+ volatile rtems_unsigned32 *linkp; /* Pointer to un[xxx].link */
+};
+typedef struct TransmitDescriptor TransmitDescriptor_t;
+typedef volatile TransmitDescriptor_t *TransmitDescriptorPointer_t;
+
+/*
+ * Transmit Configuration.
+ * For standard Ethernet transmission, all bits in the transmit
+ * configuration field are set to 0.
+ */
+#define TDA_CONFIG_PINT 0x8000
+#define TDA_CONFIG_POWC 0x4000
+#define TDA_CONFIG_CRCI 0x2000
+#define TDA_CONFIG_EXDIS 0x1000
+
+/*
+ * Transmit status
+ */
+#define TDA_STATUS_COLLISION_MASK 0xF800
+#define TDA_STATUS_COLLISION_SHIFT 11
+#define TDA_STATUS_EXD 0x0400
+#define TDA_STATUS_DEF 0x0200
+#define TDA_STATUS_NCRS 0x0100
+#define TDA_STATUS_CRSL 0x0080
+#define TDA_STATUS_EXC 0x0040
+#define TDA_STATUS_OWC 0x0020
+#define TDA_STATUS_PMB 0x0008
+#define TDA_STATUS_FU 0x0004
+#define TDA_STATUS_BCM 0x0002
+#define TDA_STATUS_PTX 0x0001
+
+#define TDA_LINK_EOL 0x1
+
+
+
+/*
+ ******************************************************************
+ * *
+ * Receive Buffer Management *
+ * *
+ ******************************************************************
+ */
+
+/*
+ * Receive resource area entry.
+ * There is one receive resource entry for each receive buffer area (RBA).
+ * This driver allows only one packet per receive buffer area, so one
+ * receive resource entry corresponds to one correctly-received packet.
+ */
+struct ReceiveResource {
+ rtems_unsigned32 buff_ptr_lsw; /* LSW of RBA address */
+ rtems_unsigned32 buff_ptr_msw; /* MSW of RBA address */
+ rtems_unsigned32 buff_wc_lsw; /* LSW of RBA size (16-bit words) */
+ rtems_unsigned32 buff_wc_msw; /* MSW of RBA size (16-bit words) */
+};
+typedef struct ReceiveResource ReceiveResource_t;
+typedef volatile ReceiveResource_t *ReceiveResourcePointer_t;
+
+/*
+ * Receive descriptor area entry.
+ * There is one receive descriptor for each packet received.
+ */
+struct ReceiveDescriptor {
+ rtems_unsigned32 status;
+ rtems_unsigned32 byte_count;
+ rtems_unsigned32 pkt_lsw; /* LSW of packet address */
+ rtems_unsigned32 pkt_msw; /* MSW of packet address */
+ rtems_unsigned32 seq_no;
+ rtems_unsigned32 link;
+ rtems_unsigned32 in_use;
+
+ /*
+ * Extra RTEMS/KA9Q stuff
+ */
+ struct ReceiveDescriptor *next; /* Circularly-linked list */
+};
+typedef struct ReceiveDescriptor ReceiveDescriptor_t;
+typedef volatile ReceiveDescriptor_t *ReceiveDescriptorPointer_t;
+
+/*
+ * Receive status
+ */
+#define RDA_STATUS_ERR 0x8800
+#define RDA_STATUS_RNT 0x4000
+#define RDA_STATUS_BRD 0x2000
+#define RDA_STATUS_PRO 0x1000
+#define RDA_STATUS_AMC 0x0800
+#define RDA_STATUS_LB1 0x0400
+#define RDA_STATUS_LB0 0x0200
+#define RDA_STATUS_MC 0x0100
+#define RDA_STATUS_BC 0x0080
+#define RDA_STATUS_LPKT 0x0040
+#define RDA_STATUS_CRS 0x0020
+#define RDA_STATUS_COL 0x0010
+#define RDA_STATUS_CRCR 0x0008
+#define RDA_STATUS_FAER 0x0004
+#define RDA_STATUS_LBK 0x0002
+#define RDA_STATUS_PRX 0x0001
+
+#define RDA_LINK_EOL 0x1
+
+#endif /* _SONIC_DP83932_ */
diff --git a/c/src/lib/libbsp/powerpc/dmv177/start/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/start/Makefile.in
new file mode 100644
index 0000000000..10d2b8a9ea
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/start/Makefile.in
@@ -0,0 +1,56 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGMS=${ARCH}/start.o
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=start
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+all: ${ARCH} $(SRCS) $(OBJS) $(PGM)
+ $(INSTALL_VARIANT) -m 555 ${PGMS} ${PROJECT_RELEASE}/lib
diff --git a/c/src/lib/libbsp/powerpc/dmv177/start/start.s b/c/src/lib/libbsp/powerpc/dmv177/start/start.s
new file mode 100644
index 0000000000..1b471c0d8c
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/start/start.s
@@ -0,0 +1,117 @@
+/*
+ * This is based on the mvme-crt0.S file from libgloss/rs6000.
+ * crt0.S -- startup file for PowerPC systems.
+ *
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * $Id$
+ */
+
+#include <rtems/score/targopts.h>
+#include "ppc-asm.h"
+
+ .file "start.s"
+ .section ".got2","aw"
+ .align 2
+
+.LCTOC1 = .+32768
+
+ .extern FUNC_NAME(atexit)
+ .globl FUNC_NAME(__atexit)
+ .section ".sdata","aw"
+ .align 2
+FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
+ .long FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */
+
+ .section ".fixup","aw"
+ .align 2
+ .long FUNC_NAME(__atexit)
+
+ .section ".got2","aw"
+.Ltable = .-.LCTOC1
+ .long .LCTOC1 /* address we think .LCTOC1 is loaded at */
+
+.Lbss_start = .-.LCTOC1
+ .long __bss_start
+
+.Lend = .-.LCTOC1
+ .long _end
+
+.Lstack = .-.LCTOC1 /* stack address if set by user */
+ .long __stack
+
+ .text
+.Lptr:
+ .long .LCTOC1-.Laddr
+
+ .globl _start
+ .type _start,@function
+_start:
+ lis r5,0
+ mr r4,r5
+ ori r4,r4,0x0000 /* 0x2030 */
+ mtmsr r4
+
+/* Add special purpose register initialization based upon the console driver
+ * initialization of these registers XXXXX
+ */
+
+ bl .Laddr /* get current address */
+
+.Laddr:
+ mflr r4 /* real address of .Laddr */
+ lwz r5,(.Lptr-.Laddr)(r4) /* linker generated address of .LCTOC1 */
+ add r5,r5,r4 /* correct to real pointer */
+ lwz r4,.Ltable(r5) /* get linker's idea of where .Laddr is */
+ subf r4,r4,r5 /* calculate difference between where linked and current */
+
+ /* clear bss */
+ lwz r6,.Lbss_start(r5) /* calculate beginning of the BSS */
+ lwz r7,.Lend(r5) /* calculate end of the BSS */
+ add r6,r6,r4 /* adjust pointers */
+ add r7,r7,r4
+
+ cmplw 1,r6,r7
+ bc 4,4,.Ldone
+
+ subf r8,r6,r7 /* number of bytes to zero */
+ srwi r9,r8,2 /* number of words to zero */
+ mtctr r9
+ li r0,0 /* zero to clear memory */
+ addi r6,r6,-4 /* adjust so we can use stwu */
+.Lloop:
+ stwu r0,4(r6) /* zero bss */
+ bdnz .Lloop
+
+.Ldone:
+
+ lwz r0,.Lstack(r5) /* stack address or 0 */
+ cmplwi 1,r0,0 /* equal to 0? */
+ bc 12,6,.Lnostack /* use default stack if == 0 */
+ mr sp,r0 /* use user defined stack */
+
+.Lnostack:
+ /* set up initial stack frame */
+ addi sp,sp,-4 /* make sure we don't overwrite debug mem */
+ lis r0,0
+ stw r0,0(sp) /* clear back chain */
+ stwu sp,-56(sp) /* push another stack frame */
+
+ /* Let her rip */
+ bl FUNC_NAME(main)
+
+ /* return value from main is argument to exit */
+ bl FUNC_NAME(exit)
+ trap
+.Lstart:
+ .size _start,.Lstart-_start
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/startup/Makefile.in
new file mode 100644
index 0000000000..229bfa3eef
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/Makefile.in
@@ -0,0 +1,68 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGM=${ARCH}/startup.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=bspstart sbrk setvec genpvec vmeintr
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+CC_PIECES=rtems-ctor
+CC_FILES=$(CC_PIECES:%=%.cc)
+CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=bspclean
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=linkcmds $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(S_O_FILES)
+
+# We install the RTEMS constructor as a separate .o
+# so it can be easily place correctly by the compiler config file.
+INSTALLED_O_FILES=$(ARCH)/rtems-ctor.o
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(INSTALLED_O_FILES) $(PGM)
+ $(INSTALL) $(srcdir)/linkcmds ${PROJECT_RELEASE}/lib
+ $(INSTALL_VARIANT) $(INSTALLED_O_FILES) ${PROJECT_RELEASE}/lib
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/bspclean.s b/c/src/lib/libbsp/powerpc/dmv177/startup/bspclean.s
new file mode 100644
index 0000000000..339f9d6eb6
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/bspclean.s
@@ -0,0 +1,25 @@
+/*
+ * bspclean.s -- based on mvme-exit.S from libgloss which was designed to
+ * work for targets using the ppcbug monitor
+ *
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include "ppc-asm.h"
+
+ .file "bspclean.s"
+ .text
+FUNC_START(bsp_cleanup)
+ li r10,0x63
+ sc
+FUNC_END(bsp_cleanup)
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/bspstart.c b/c/src/lib/libbsp/powerpc/dmv177/startup/bspstart.c
new file mode 100644
index 0000000000..fba086515c
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/bspstart.c
@@ -0,0 +1,312 @@
+/* bspstart.c
+ *
+ * This set of routines starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before any of these are invoked.
+ *
+ * Called by RTEMS::RTEMS constructor in rtems-ctor.cc
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994, 1997.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <libcsupport.h>
+
+#include <string.h>
+#include <fcntl.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+/*
+ * The original table from the application and our copy of it with
+ * some changes.
+ */
+
+extern rtems_configuration_table Configuration;
+rtems_configuration_table BSP_Configuration;
+rtems_cpu_table Cpu_table;
+rtems_unsigned32 bsp_isr_level;
+
+/* PAGE
+ *
+ * bsp_libc_init
+ *
+ * Initialize whatever libc we are using called from bsp_postdriver_hook.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void bsp_libc_init(void)
+{
+ extern int end;
+ rtems_unsigned32 heap_start;
+ rtems_unsigned32 heap_size;
+
+ heap_start = (rtems_unsigned32) &end;
+ if (heap_start & (CPU_ALIGNMENT-1))
+ heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+
+ heap_size = BSP_Configuration.work_space_start - (void *)&end;
+ heap_size &= 0xfffffff0; /* keep it as a multiple of 16 bytes */
+
+ RTEMS_Malloc_Initialize((void *) heap_start, heap_size, 0);
+
+ /*
+ * Init the RTEMS libio facility to provide UNIX-like system
+ * calls for use by newlib (ie: provide __rtems_open, __rtems_close, etc)
+ * Uses malloc() to get area for the iops, so must be after malloc init
+ */
+
+ rtems_libio_init();
+
+ /*
+ * Set up for the libc handling.
+ */
+
+ if (BSP_Configuration.ticks_per_timeslice > 0)
+ libc_init(1); /* reentrant if possible */
+ else
+ libc_init(0); /* non-reentrant */
+
+}
+
+
+/* PAGE
+ *
+ * bsp_pretasking_hook
+ *
+ * BSP pretasking hook. Called just before drivers are initialized.
+ * Used to setup libc and install any BSP extensions.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void bsp_pretasking_hook(void)
+{
+ bsp_libc_init();
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Initialize the stack bounds checker
+ * We can either turn it on here or from the app.
+ */
+
+ Stack_check_Initialize();
+#endif
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+
+}
+
+/* PAGE
+ *
+ * bsp_predriver_hook
+ *
+ * Initialization before drivers are setup.
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void bsp_predriver_hook(void)
+{
+ initialize_external_exception_vector();
+}
+
+/* PAGE
+ *
+ * bsp_postdriver_hook
+ *
+ * After drivers are setup, register some "filenames"
+ * and open stdin, stdout, stderr files
+ *
+ * Newlib will automatically associate the files with these
+ * (it hardcodes the numbers)
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void bsp_postdriver_hook(void)
+{
+ int stdin_fd, stdout_fd, stderr_fd;
+ int error_code;
+
+ error_code = 'S' << 24 | 'T' << 16;
+
+ if ((stdin_fd = __rtems_open("/dev/console", O_RDONLY, 0)) == -1)
+ rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
+
+ if ((stdout_fd = __rtems_open("/dev/console", O_WRONLY, 0)) == -1)
+ rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
+
+ if ((stderr_fd = __rtems_open("/dev/console", O_WRONLY, 0)) == -1)
+ rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
+
+ if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
+ rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
+}
+
+/* PAGE
+ *
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void bsp_start( void )
+{
+ unsigned char *work_space_start;
+ unsigned int msr_value = 0x2030;
+
+ /*
+ * Set BSP to initial value. Note: This value is a guess
+ * check how the real board comes up. This is critical to
+ * getting the source to work with the debugger.
+ */
+ _CPU_MSR_SET( msr_value );
+
+ /*
+ * Set up our hooks
+ * Make sure libc_init is done before drivers initialized so that
+ * they can use atexit()
+ */
+
+ Cpu_table.exceptions_in_RAM = TRUE;
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+
+ Cpu_table.predriver_hook = bsp_predriver_hook;
+
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+
+ Cpu_table.idle_task = NULL; /* do not override system IDLE task */
+
+ Cpu_table.clicks_per_usec = 66 / 4; /* XXX get from linkcmds */
+
+
+ /*
+ * SIS does zero out memory BUT only when IT begins execution. Thus
+ * if we want to have a clean slate in the workspace each time we
+ * begin execution of OUR application, then we must zero the workspace.
+ */
+
+ Cpu_table.do_zero_of_workspace = TRUE;
+
+ /*
+ * This should be enough interrupt stack.
+ */
+
+ Cpu_table.interrupt_stack_size = (12 * 1024);
+
+ /*
+ * DMV170 does not support MP configurations so there is really no way
+ * to check this out.
+ */
+
+ Cpu_table.extra_mpci_receive_server_stack = 0;
+
+ /*
+ * Copy the table and allocate memory for the RTEMS Workspace
+ */
+
+ BSP_Configuration = Configuration;
+
+#if defined(RTEMS_POSIX_API)
+ BSP_Configuration.work_space_size *= 3;
+#endif
+
+ work_space_start =
+ (unsigned char *)&RAM_END - BSP_Configuration.work_space_size;
+
+ if ( work_space_start <= (unsigned char *)&end ) {
+ DEBUG_puts( "bspstart: Not enough RAM!!!\n" );
+ bsp_cleanup();
+ }
+
+ BSP_Configuration.work_space_start = work_space_start;
+
+ /*
+ * Add 1 region for RTEMS Malloc
+ */
+
+ BSP_Configuration.RTEMS_api_configuration->maximum_regions++;
+
+ /*
+ * Account for the console's resources
+ */
+
+ console_reserve_resources( &BSP_Configuration );
+
+#ifdef RTEMS_NEWLIB
+ /*
+ * Add 1 extension for newlib libc
+ */
+
+ BSP_Configuration.maximum_extensions++;
+#endif
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Add 1 extension for stack checker
+ */
+
+ BSP_Configuration.maximum_extensions++;
+#endif
+
+ /*
+ * Add 1 extension for MPCI_fatal
+ */
+
+ if (BSP_Configuration.User_multiprocessing_table)
+ BSP_Configuration.maximum_extensions++;
+
+ /*
+ * Initialize RTEMS. main() will finish it up and start multitasking.
+ */
+
+ rtems_libio_config( &BSP_Configuration, BSP_LIBIO_MAX_FDS );
+
+ bsp_isr_level = rtems_initialize_executive_early(
+ &BSP_Configuration,
+ &Cpu_table
+ );
+}
+
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/genpvec.c b/c/src/lib/libbsp/powerpc/dmv177/startup/genpvec.c
new file mode 100644
index 0000000000..98989c2401
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/genpvec.c
@@ -0,0 +1,184 @@
+/* genpvec.c
+ *
+ * These routines handle the external exception. Multiple ISRs occur off
+ * of this one interrupt. This method will allow multiple ISRs to be
+ * called using the same IRQ index. However, removing the ISR routines is
+ * presently not supported.
+ *
+ * The external exception vector numbers begin with DMV170_IRQ_FIRST.
+ * DMV170_IRQ_FIRST is defined to be one greater than the last processor
+ * interrupt.
+ *
+ * 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 in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id:
+ */
+
+#include <bsp.h>
+#include "chain.h"
+#include <assert.h>
+
+#define NUM_LIRQ_HANDLERS 20
+#define NUM_LIRQ ( MAX_BOARD_IRQS - PPC_IRQ_LAST )
+
+/*
+ * Structure to for one of possible multiple interrupt handlers for
+ * a given interrupt.
+ */
+typedef struct
+{
+ Chain_Node Node;
+ rtems_isr_entry handler; /* isr routine */
+ rtems_vector_number vector; /* vector number */
+} EE_ISR_Type;
+
+/*
+ * Note: The following will not work if we add a method to remove
+ * handlers at a later time.
+ */
+EE_ISR_Type ISR_Nodes [NUM_LIRQ_HANDLERS];
+rtems_unsigned16 Nodes_Used;
+Chain_Control ISR_Array [NUM_LIRQ];
+
+
+/* PAGE
+ *
+ * initialize_external_exception_vector
+ *
+ * This routine initializes the external exception vector
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void initialize_external_exception_vector ()
+{
+ int i;
+ rtems_isr_entry previous_isr;
+ rtems_status_code status;
+
+ Nodes_Used = 0;
+
+ for (i=0; i <NUM_LIRQ; i++)
+ Chain_Initialize_empty( &ISR_Array[i] );
+
+ /*
+ * Install external_exception_ISR () as the handler for
+ * the General Purpose Interrupt.
+ */
+
+ status = rtems_interrupt_catch( external_exception_ISR,
+ PPC_IRQ_EXTERNAL , (rtems_isr_entry *) &previous_isr );
+}
+
+/* PAGE
+ *
+ * set_EE_vector
+ *
+ * This routine installs one of multiple ISRs for the general purpose
+ * inerrupt.
+ *
+ * Input parameters:
+ * handler - handler to call at exception
+ * vector - vector number associated with this handler.
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+rtems_isr_entry set_EE_vector(
+ rtems_isr_entry handler, /* isr routine */
+ rtems_vector_number vector /* vector number */
+)
+{
+ rtems_unsigned16 vec_idx = vector - DMV170_IRQ_FIRST;
+ rtems_unsigned32 index;
+
+ /*
+ * Verify that all of the nodes have not been used.
+ */
+ assert (Nodes_Used < NUM_LIRQ_HANDLERS);
+
+ /*
+ * If we have already installed this handler for this vector, then
+ * just reset it.
+ */
+
+ for ( index=0 ; index <= Nodes_Used ; index++ ) {
+ if ( ISR_Nodes[index].vector == vector &&
+ ISR_Nodes[index].handler == handler )
+ return 0;
+ }
+
+ /*
+ * Increment the number of nedes used and set the index for the node
+ * array.
+ */
+
+ Nodes_Used++;
+ index = Nodes_Used - 1;
+
+ /*
+ * Write the values of the handler and the vector to this node.
+ */
+ ISR_Nodes[index].handler = handler;
+ ISR_Nodes[index].vector = vector;
+
+ /*
+ * Connect this node to the chain at the location of the
+ * vector index.
+ */
+ Chain_Append( &ISR_Array[vec_idx], &ISR_Nodes[index].Node );
+
+ /*
+ * No interrupt service routine was removed so return 0
+ */
+ return 0;
+}
+
+/* PAGE
+ *
+ * external_exception_ISR
+ *
+ * This interrupt service routine is called for an External Exception.
+ *
+ * Input parameters:
+ * vector - vector number representing the external exception vector.
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+
+rtems_isr external_exception_ISR (
+ rtems_vector_number vector /* IN */
+)
+{
+ rtems_unsigned16 index;
+ EE_ISR_Type *node;
+
+ /*
+ * Read vector.
+ */
+ index = 0;
+
+ node = ISR_Array[ index ].first;
+ while ( !_Chain_Is_tail( &ISR_Array[ index ], node ) ) {
+ (*node->handler)( node->vector );
+ node = node->Node.next;
+ }
+
+ /*
+ * Clear the interrupt.
+ */
+}
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/linkcmds b/c/src/lib/libbsp/powerpc/dmv177/startup/linkcmds
new file mode 100644
index 0000000000..80b586dbad
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/linkcmds
@@ -0,0 +1,173 @@
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+
+/*
+ * Number of Decrementer countdowns per millisecond
+ *
+ * Calculated by: (66.67 Mhz * 1000) / 4 cycles per click
+ */
+
+PROVIDE(CPU_PPC_CLICKS_PER_MS = 16667);
+
+MEMORY
+ {
+ RAM : ORIGIN = 0, LENGTH = 32M
+ EPROM : ORIGIN = 0xFFF00000, LENGTH = 0x20000
+ }
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ /* . = 0x40000 + SIZEOF_HEADERS; */
+ /* . = 0x1000000;*/
+ . = 0x41000;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rela.text : { *(.rela.text) }
+ .rela.data : { *(.rela.data) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rela.init : { *(.rela.init) }
+ .rela.fini : { *(.rela.fini) }
+ .rela.bss : { *(.rela.bss) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.sdata : { *(.rela.sdata2) }
+ .rela.sbss : { *(.rela.sbss2) }
+ .rela.sdata2 : { *(.rela.sdata2) }
+ .rela.sbss2 : { *(.rela.sbss2) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.descriptors)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ .init : { *(.init) } =0
+ .fini : { *(.fini) } =0
+ .rodata : { *(.rodata) }
+ .rodata1 : { *(.rodata1) }
+ _etext = .;
+ PROVIDE (etext = .);
+ PROVIDE (__SDATA2_START__ = .);
+ .sdata2 : { *(.sdata2) }
+ .sbss2 : { *(.sbss2) }
+ PROVIDE (__SBSS2_END__ = .);
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = ALIGN(0x40000) + (ALIGN(8) & (0x40000 - 1));
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = ALIGN(8) + 0x40000;
+ PROVIDE (sdata = .);
+ .data :
+ {
+ *(.data)
+ CONSTRUCTORS
+ }
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table) }
+ PROVIDE (__EXCEPT_END__ = .);
+
+ .data1 : { *(.data1) }
+ .got1 : { *(.got1) }
+ .dynamic : { *(.dynamic) }
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) }
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (__CTOR_LIST__ = .);
+ .ctors : { *(.ctors) }
+ PROVIDE (__CTOR_END__ = .);
+ PROVIDE (__DTOR_LIST__ = .);
+ .dtors : { *(.dtors) }
+ PROVIDE (__DTOR_END__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) }
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+ PROVIDE (_GOT_START_ = .);
+ s.got = .;
+ .got : { *(.got) }
+ .got.plt : { *(.got.plt) }
+ PROVIDE (_GOT_END_ = .);
+ PROVIDE (__GOT_END__ = .);
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ PROVIDE (__SDATA_START__ = .);
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ PROVIDE (RAM_END = 4M);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ }
+ PROVIDE (__SBSS_END__ = .);
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(8) + 0x8000;
+ PROVIDE (__stack = .);
+ _end = . ;
+ PROVIDE (end = .);
+
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* 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) }
+ .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) }
+ /* These must appear regardless of . */
+}
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/rtems-ctor.cc b/c/src/lib/libbsp/powerpc/dmv177/startup/rtems-ctor.cc
new file mode 100644
index 0000000000..0c7efef592
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/rtems-ctor.cc
@@ -0,0 +1,151 @@
+/*
+ * rtems-ctor.cc
+ *
+ * Description:
+ * This file exists solely to (try to) ensure RTEMS is initialized
+ * before any global constructors are run.
+ *
+ * The problem:
+ * Global constructors might reasonably expect that new() will
+ * work, but since new() uses malloc() which uses RTEMS regions,
+ * it can not be called until after initialize_executive().
+ *
+ * Global constructors are called in GNU systems one of 2 ways:
+ *
+ * an "invisible" call to __main() inserted by compiler
+ * This __main() calls __do_global_ctors() which
+ * walks thru the table and calls all global
+ * constructors.
+ *
+ * or -
+ * A special section is put into the linked binary. The
+ * system startup code knows to run the constructors in
+ * this special section before calling main().
+ *
+ * By making RTEMS initialization a constructor, we avoid having
+ * too much about all this. All we have to guarantee is that
+ * this constructor is the first one run.
+ *
+ *
+ * So for the first case above, this is what happens
+ *
+ * host crt0
+ * main()
+ * __main()
+ * __do_global_ctors()
+ * bsp_start()
+ * init_executive_early()
+ * <<any other constructors>>
+ *
+ * rtems_init_executive_late()
+ * bsp_cleanup()
+ *
+ * TODO:
+ *
+ * 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 in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+
+/*
+ * RTEMS program name
+ * Probably not used by anyone, but it is nice to have it.
+ * Actually the UNIX version of CPU_INVOKE_DEBUGGER will probably
+ * need to use it
+ */
+
+char *rtems_progname;
+char **rtems_environp;
+
+#ifdef USE_CONSTRUCTORS_FOR_INIT_EXEC
+
+class RTEMS {
+ public:
+ RTEMS();
+ ~RTEMS();
+};
+
+RTEMS rtems_constructor;
+
+
+/* PAGE
+ *
+ * RTEMS::RTEMS
+ *
+ * RTEMS constructor routine
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+RTEMS::RTEMS()
+{
+ bsp_start();
+}
+
+/* PAGE
+ *
+ * RTEMS::~RTEMS
+ *
+ * RTEMS distructor routine
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+RTEMS::~RTEMS()
+{
+ bsp_cleanup();
+}
+#endif
+
+extern "C" {
+ int
+ main(int argc,
+ char **argv,
+ char **environp)
+ {
+
+#ifndef USE_CONSTRUCTORS_FOR_INIT_EXEC
+ bsp_start();
+#endif
+
+ if ((argc > 0) && argv && argv[0])
+ rtems_progname = argv[0];
+ else
+ rtems_progname = "RTEMS";
+
+ rtems_environp = environp;
+
+ /*
+ * Start multitasking
+ */
+
+ rtems_initialize_executive_late( bsp_isr_level );
+
+#ifndef USE_CONSTRUCTORS_FOR_INIT_EXEC
+ bsp_cleanup();
+#endif
+
+ /*
+ * Returns when multitasking is stopped
+ * This allows our destructors to get run normally
+ */
+
+ return 0;
+ }
+}
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/sbrk.c b/c/src/lib/libbsp/powerpc/dmv177/startup/sbrk.c
new file mode 100644
index 0000000000..c52224cc35
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/sbrk.c
@@ -0,0 +1,61 @@
+/*
+ * sbrk.c
+ *
+ * If the BSP wants to dynamically allocate the memory for the
+ * C Library heap (malloc) and/or be able to extend the heap,
+ * then this routine must be functional.
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/sbrk.c:
+ *
+ * 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 in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* PAGE
+ *
+ * sbrk
+ *
+ * Routine to allow dynamically allocated memory for the heap.
+ * Note the int may need to be a size_t on some hosts
+ *
+ * Input parameters:
+ * incr
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+void * sbrk(size_t incr)
+{
+ errno = EINVAL;
+ return (void *)-1;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/setvec.c b/c/src/lib/libbsp/powerpc/dmv177/startup/setvec.c
new file mode 100644
index 0000000000..4fb6333da8
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/setvec.c
@@ -0,0 +1,71 @@
+/* set_vector
+ *
+ * This routine installs an interrupt vector on the target Board/CPU.
+ * This routine is allowed to be as board dependent as necessary.
+ *
+ * INPUT:
+ * handler - interrupt handler entry point
+ * vector - vector number
+ * type - 0 indicates raw hardware connect
+ * 1 indicates RTEMS interrupt connect
+ *
+ * RETURNS:
+ * address of previous interrupt handler
+ *
+ * Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c:
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id:
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+
+/* PAGE
+ *
+ * set_vector
+ *
+ * This routine installs vector number vector.
+ *
+ * Input parameters:
+ * handler - routine to call when the interupt occurs
+ * vector - vector id
+ * type - RAW or RTEMS vector
+ *
+ * Output parameters: NONE
+ *
+ * Return values: Removed interupt routine or 0 if none.
+ */
+
+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 */
+)
+{
+ rtems_isr_entry previous_isr;
+ rtems_status_code status;
+
+
+ /*
+ * vectors greater than PPC603e_IRQ_LAST are handled by the General purpose
+ * interupt handler.
+ */
+ if ( vector > PPC_IRQ_LAST ) {
+ set_EE_vector ( handler, vector );
+ }
+ else {
+ status = rtems_interrupt_catch
+ ( handler, vector, (rtems_isr_entry *) &previous_isr );
+ }
+ return previous_isr;
+}
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/startup/vmeintr.c b/c/src/lib/libbsp/powerpc/dmv177/startup/vmeintr.c
new file mode 100644
index 0000000000..212d7eb938
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/startup/vmeintr.c
@@ -0,0 +1,84 @@
+/* vmeintr.c
+ *
+ * VMEbus support routines for the DMV170.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <vmeintr.h>
+
+/* PAGE
+ *
+ * VME_interrupt_Disable
+ *
+ * This routine disables vme interupts
+ *
+ * Input parameters:
+ * mask - interupt mask
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void VME_interrupt_Disable (
+ VME_interrupt_Mask mask /* IN */
+)
+{
+ volatile rtems_unsigned8 *VME_interrupt_enable;
+ rtems_unsigned8 value;
+
+#if 0
+ VME_interrupt_enable = ACC_VIE;
+#else
+ VME_interrupt_enable = 0;
+#endif
+ value = *VME_interrupt_enable;
+
+ value &= ~mask; /* turn off interrupts for all levels in mask */
+
+ *VME_interrupt_enable = value;
+}
+
+/* PAGE
+ *
+ * VME_interrupt_Enable
+ *
+ * This routine enables vme interupts
+ *
+ * Input parameters:
+ * mask - interupt mask
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+
+void VME_interrupt_Enable (
+ VME_interrupt_Mask mask /* IN */
+)
+{
+ volatile rtems_unsigned8 *VME_interrupt_enable;
+ rtems_unsigned8 value;
+
+#if 0
+ VME_interrupt_enable = ACC_VIE;
+#else
+ VME_interrupt_enable = 0;
+#endif
+ value = *VME_interrupt_enable;
+
+ value |= mask; /* turn on interrupts for all levels in mask */
+
+ *VME_interrupt_enable = value;
+}
diff --git a/c/src/lib/libbsp/powerpc/dmv177/timer/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/timer/Makefile.in
new file mode 100644
index 0000000000..35a903e737
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/timer/Makefile.in
@@ -0,0 +1,61 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGM=${ARCH}/timer.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=timer
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/dmv177/timer/timer.c b/c/src/lib/libbsp/powerpc/dmv177/timer/timer.c
new file mode 100644
index 0000000000..72d1bb79a3
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/timer/timer.c
@@ -0,0 +1,152 @@
+/* timer.c
+ *
+ * This file implements a benchmark timer using the General Purpose Timer on
+ * the MEC.
+ *
+ * The license and distribution terms for this file are in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <assert.h>
+
+#include <bsp.h>
+
+rtems_unsigned64 Timer_driver_Start_time;
+
+rtems_boolean Timer_driver_Find_average_overhead;
+
+static inline rtems_unsigned64 PPC_Get_timebase_register( void )
+{
+ rtems_unsigned32 tbr_low;
+ rtems_unsigned32 tbr_high;
+ rtems_unsigned32 tbr_high_old;
+ rtems_unsigned64 tbr;
+
+ do {
+ asm volatile( "mftbu %0" : "=r" (tbr_high_old));
+ asm volatile( "mftb %0" : "=r" (tbr_low));
+ asm volatile( "mftbu %0" : "=r" (tbr_high));
+ } while ( tbr_high_old != tbr_high );
+
+ tbr = tbr_high;
+ tbr <<= 32;
+ tbr |= tbr_low;
+ return tbr;
+}
+
+/* PAGE
+ *
+ * Timer_initialize
+ *
+ * This routine initializes the timer.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void Timer_initialize()
+{
+ /*
+ * Timer runs long and accurate enough not to require an interrupt.
+ */
+
+
+ Timer_driver_Start_time = PPC_Get_timebase_register();
+
+
+}
+
+#define AVG_OVERHEAD 24 /* It typically takes 24 instructions */
+ /* to start/stop the timer. */
+#define LEAST_VALID 1 /* Don't trust a value lower than this */
+ /* psim can count instructions. :) */
+
+/* PAGE
+ *
+ * Read_timer
+ *
+ * This routine reads the timer.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: timer in ms units
+ *
+ */
+
+int Read_timer()
+{
+ rtems_unsigned64 clicks;
+ rtems_unsigned64 total64;
+ rtems_unsigned32 total;
+
+ /* approximately CLOCK_SPEED clicks per microsecond */
+
+ clicks = PPC_Get_timebase_register();
+
+ assert( clicks > Timer_driver_Start_time );
+
+ total64 = clicks - Timer_driver_Start_time;
+
+ assert( total64 <= 0xffffffff ); /* fits into a unsigned32 */
+
+ total = (rtems_unsigned32) total64;
+
+ if ( Timer_driver_Find_average_overhead == 1 )
+ return total; /* in one microsecond units */
+
+ if ( total < LEAST_VALID )
+ return 0; /* below timer resolution */
+
+ return total - AVG_OVERHEAD;
+}
+
+/* PAGE
+ *
+ * Empty_function
+ *
+ * This routine is called during the idle loop.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters:
+ * status code of successful
+ *
+ * Return values: NONE
+ *
+ */
+
+rtems_status_code Empty_function( void )
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * Set_find_average_overhead
+ *
+ * This routine sets a global boolean to the value passed in.
+ *
+ * Input parameters:
+ * find_flag - flag to indicate to find the average overhead.
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ *
+ */
+
+void Set_find_average_overhead(
+ rtems_boolean find_flag
+)
+{
+ Timer_driver_Find_average_overhead = find_flag;
+}
diff --git a/c/src/lib/libbsp/powerpc/dmv177/tod/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/tod/Makefile.in
new file mode 100644
index 0000000000..dfad6613f4
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/tod/Makefile.in
@@ -0,0 +1,59 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+PGM=${ARCH}/tod.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=$(TOD_PIECES)
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+# First and second generation use different RTC chips :(
+TOD_PIECES=tod
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/dmv177/tod/tod.c b/c/src/lib/libbsp/powerpc/dmv177/tod/tod.c
new file mode 100644
index 0000000000..800f342cf1
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/tod/tod.c
@@ -0,0 +1,282 @@
+/*
+ * Real Time Clock (Harris ICM7170) for RTEMS
+ *
+ * This part is found on the second generation of this board.
+ *
+ * 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 <tod.h>
+#include <bsp.h>
+
+/*
+ * These values are programed into a register and must not be changed.
+ */
+
+#define ICM1770_CRYSTAL_FREQ_32K 0x00
+#define ICM1770_CRYSTAL_FREQ_1M 0x01
+#define ICM1770_CRYSTAL_FREQ_2M 0x02
+#define ICM1770_CRYSTAL_FREQ_4M 0x03
+
+void ICM7170_GetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+);
+void ICM7170_SetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+);
+
+/*
+ * This code is dependent on the boards use of the ICM7170 RTC/NVRAM
+ * and should remain in this file.
+ */
+
+/* PAGE
+ *
+ * This routine copies the time from the real time clock to RTEMS
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void setRealTimeToRTEMS()
+{
+ rtems_time_of_day rtc_tod;
+
+ ICM7170_GetTOD( DMV170_RTC_ADDRESS, DMV170_RTC_FREQUENCY, &rtc_tod );
+ rtems_clock_set( &rtc_tod );
+}
+
+/* PAGE
+ *
+ * setRealTimeFromRTEMS
+ *
+ * This routine copies the time from RTEMS to the real time clock
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void setRealTimeFromRTEMS()
+{
+ rtems_time_of_day rtems_tod;
+
+ rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
+ ICM7170_SetTOD( DMV170_RTC_ADDRESS, DMV170_RTC_FREQUENCY, &rtems_tod );
+}
+
+/* PAGE
+ *
+ * checkRealTime
+ *
+ * This routine reads the returns the variance betweent the real time and
+ * rtems time.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * int The differance between the real time clock and rtems time or
+ * 9999 in the event of an error.
+ */
+
+int checkRealTime()
+{
+ rtems_time_of_day rtems_tod;
+ rtems_time_of_day rtc_tod;
+
+ ICM7170_GetTOD( DMV170_RTC_ADDRESS, DMV170_RTC_FREQUENCY, &rtc_tod );
+ rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
+
+ if( rtems_tod.year == rtc_tod.year &&
+ rtems_tod.month == rtc_tod.month &&
+ rtems_tod.day == rtc_tod.day ) {
+ return ((rtems_tod.hour - rtc_tod.hour) * 3600) +
+ ((rtems_tod.minute - rtc_tod.minute) * 60) +
+ (rtems_tod.second - rtc_tod.second);
+ }
+ return 9999;
+}
+
+/*
+ * These routines are ICM7170 should be in
+ * a separate support library. When the chiplib
+ * is created for RTEMS these routines will be moved.
+ */
+
+/* PAGE
+ *
+ * ICM7170_GetField
+ *
+ * This routine gets a field
+ *
+ * Input parameters:
+ * imc1770_regs - pointer to the register base address.
+ * reg - register id
+ *
+ * Output parameters: NONE
+ *
+ * Return values: value of register
+ */
+
+static int ICM7170_GetField(
+ volatile unsigned char *imc1770_regs,
+ int reg
+)
+{
+ unsigned char x;
+
+ x = imc1770_regs[reg*4];
+
+ return x;
+}
+
+/* PAGE
+ *
+ * ICM7170_SetField
+ *
+ * This routine sets a field
+ *
+ * Input parameters:
+ * imc1770_regs - pointer to the register base address.
+ * reg - register id
+ * d - data to write
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+static void ICM7170_SetField(
+ volatile unsigned char *imc1770_regs,
+ int reg,
+ unsigned char d
+)
+{
+ imc1770_regs[reg*4] = d;
+}
+
+/* PAGE
+ *
+ * ICM7170_GetTOD
+ *
+ * This routine gets the real time clock time of day in rtems
+ * time of day format.
+ *
+ * Input parameters:
+ * imc1770_regs - pointer to the register base address.
+ * icm1770_freq - oscillator frequency
+ *
+ * Output parameters:
+ * rtc_tod - time of day by the real time clock
+ *
+ * Return values: NONE
+ */
+
+void ICM7170_GetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+)
+{
+ int year;
+ int usec;
+ static rtems_boolean init = TRUE;
+
+ /* Initialize the clock at once prior to reading */
+ if (init ) {
+ ICM7170_SetField( imc1770_regs, 0x11, (0x0c | icm1770_freq) );
+ init = FALSE;
+ }
+
+ usec = ICM7170_GetField( imc1770_regs, 0x00 );
+
+ year = ICM7170_GetField( imc1770_regs, 0x06 );
+ if ( year >= 88 )
+ year += 1900;
+ else
+ year += 2000;
+
+ rtc_tod->year = year;
+ rtc_tod->month = ICM7170_GetField( imc1770_regs, 0x04 );
+ rtc_tod->day = ICM7170_GetField( imc1770_regs, 0x05 );
+ rtc_tod->hour = ICM7170_GetField( imc1770_regs, 0x01 );
+ rtc_tod->minute = ICM7170_GetField( imc1770_regs, 0x02 );
+ rtc_tod->second = ICM7170_GetField( imc1770_regs, 0x03 );
+ rtc_tod->ticks = ICM7170_GetField( imc1770_regs, 0x00 );
+}
+
+/* PAGE
+ *
+ * ICM7170_SetTOD
+ *
+ * This routine sets the real time clock
+ *
+ * Input parameters:
+ * imc1770_regs - pointer to the register base address.
+ * icm1770_freq - oscillator frequency
+ * rtc_tod - time of day to set
+ *
+ * Output parameters:
+ *
+ * Return values:
+ */
+
+void ICM7170_SetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+)
+{
+ int ticks;
+ int year;
+
+ year = rtc_tod->year;
+ if ( year >= 2088 ) /* plan ahead :) */
+ rtems_fatal_error_occurred( 0xBAD0BAD0 );
+
+ if ( year >= 2000 )
+ year -= 2000;
+ else
+ year -= 1900;
+
+ ICM7170_SetField( imc1770_regs, 0x11, (0x04 |icm1770_freq ) );
+
+ ICM7170_SetField( imc1770_regs, 0x06, year );
+ ICM7170_SetField( imc1770_regs, 0x04, rtc_tod->month );
+ ICM7170_SetField( imc1770_regs, 0x05, rtc_tod->day );
+ ICM7170_SetField( imc1770_regs, 0x01, rtc_tod->hour );
+ ICM7170_SetField( imc1770_regs, 0x02, rtc_tod->minute );
+ ICM7170_SetField( imc1770_regs, 0x03, rtc_tod->second );
+
+ /*
+ * I don't know which day of week is
+ *
+ */
+ ICM7170_SetField( imc1770_regs, 0x07, 1 );
+
+ ICM7170_SetField( imc1770_regs, 0x11, (0x0c | icm1770_freq) );
+}
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in b/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in
new file mode 100644
index 0000000000..285b8e0356
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/wrapup/Makefile.in
@@ -0,0 +1,57 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @RTEMS_ROOT@
+PROJECT_ROOT = @PROJECT_ROOT@
+RTEMS_CUSTOM = $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+
+#BSP_PIECES=startup clock console timer tod vectors
+BSP_PIECES=startup clock console sonic timer tod #vectors
+# pieces to pick up out of libcpu/$(RTEMS_CPU)
+CPU_PIECES=
+GENERIC_PIECES=
+
+# bummer; have to use $foreach since % pattern subst rules only replace 1x
+OBJS=$(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/$(piece).rel) \
+ $(foreach piece, $(CPU_PIECES), \
+ ../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/$(piece).rel) \
+ $(foreach piece, $(GENERIC_PIECES), \
+ ../../../$(piece)/$(ARCH)/$(piece).rel)
+LIB=$(ARCH)/libbsp.a
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/lib.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+$(LIB): ${OBJS}
+ $(make-library)
+
+all: ${ARCH} $(SRCS) $(LIB)
+ $(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib
+