summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-05-30 10:09:14 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-05-30 10:09:14 +0000
commitc932d85019761fbafef02fc72119e4bcd4e50978 (patch)
tree20d32f1b768006bfee2385a9cf03a4411373e502 /c/src/lib/libbsp
parentchanged version to 980527 (diff)
downloadrtems-c932d85019761fbafef02fc72119e4bcd4e50978.tar.bz2
New files -- from rtems-LM-980406 which was based on an RTEMS from 12/97.
This was called the dmv170 BSP in that source tree but since the DMV171 is now obsolete, we have transitioned to the DMV177 and have no intention of checking compatibility with any other models.
Diffstat (limited to 'c/src/lib/libbsp')
-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
+