summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Monkman <jtm@smoothsmoothie.com>2005-02-25 05:18:07 +0000
committerJay Monkman <jtm@smoothsmoothie.com>2005-02-25 05:18:07 +0000
commit7cde240ce85e3f5ffd69e970e36dd722a87c02c5 (patch)
treebf10fa3feefe87805981929c5a05a6a66c86567b
parent2005-02-24 Jay Monkman (diff)
downloadrtems-7cde240ce85e3f5ffd69e970e36dd722a87c02c5.tar.bz2
2005-02-24 Jay Monkman <jtm@lopingdog.com>
* acinclude.m4: Added csb350 to list of BSPs. * csb350/Makefile.am, csb350/README, csb350/bsp_specs, csb350/configure.ac, csb350/times, csb350/clock/clockdrv.c, csb350/console/console-io.c, csb350/include/bsp.h, csb350/include/tm27.h, csb350/network/network.c, csb350/start/regs.S, csb350/start/start.S, csb350/startup/bspclean.c, csb350/startup/bspstart.c, csb350/startup/linkcmds, csb350/timer/timer.c: New BSP.
-rw-r--r--c/src/lib/libbsp/mips/ChangeLog11
-rw-r--r--c/src/lib/libbsp/mips/acinclude.m42
-rw-r--r--c/src/lib/libbsp/mips/csb350/Makefile.am178
-rw-r--r--c/src/lib/libbsp/mips/csb350/README6
-rw-r--r--c/src/lib/libbsp/mips/csb350/bsp_specs26
-rw-r--r--c/src/lib/libbsp/mips/csb350/clock/clockdrv.c81
-rw-r--r--c/src/lib/libbsp/mips/csb350/configure.ac23
-rw-r--r--c/src/lib/libbsp/mips/csb350/console/console-io.c89
-rw-r--r--c/src/lib/libbsp/mips/csb350/include/bsp.h113
-rw-r--r--c/src/lib/libbsp/mips/csb350/include/tm27.h63
-rw-r--r--c/src/lib/libbsp/mips/csb350/network/network.c889
-rw-r--r--c/src/lib/libbsp/mips/csb350/start/regs.S138
-rw-r--r--c/src/lib/libbsp/mips/csb350/start/start.S125
-rw-r--r--c/src/lib/libbsp/mips/csb350/startup/bspclean.c30
-rw-r--r--c/src/lib/libbsp/mips/csb350/startup/bspstart.c128
-rw-r--r--c/src/lib/libbsp/mips/csb350/startup/linkcmds212
-rw-r--r--c/src/lib/libbsp/mips/csb350/timer/timer.c63
-rw-r--r--c/src/lib/libbsp/mips/csb350/times189
18 files changed, 2366 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/mips/ChangeLog b/c/src/lib/libbsp/mips/ChangeLog
index 8bd5bbeedc..621e595865 100644
--- a/c/src/lib/libbsp/mips/ChangeLog
+++ b/c/src/lib/libbsp/mips/ChangeLog
@@ -1,3 +1,14 @@
+2005-02-24 Jay Monkman <jtm@lopingdog.com>
+
+ * acinclude.m4: Added csb350 to list of BSPs.
+ * csb350/Makefile.am, csb350/README, csb350/bsp_specs,
+ csb350/configure.ac, csb350/times, csb350/clock/clockdrv.c,
+ csb350/console/console-io.c, csb350/include/bsp.h,
+ csb350/include/tm27.h, csb350/network/network.c, csb350/start/regs.S,
+ csb350/start/start.S, csb350/startup/bspclean.c,
+ csb350/startup/bspstart.c, csb350/startup/linkcmds,
+ csb350/timer/timer.c: New BSP.
+
2004-09-24 Ralf Corsepius <ralf_corsepius@rtems.org>
* configure.ac: Require automake > 1.9.
diff --git a/c/src/lib/libbsp/mips/acinclude.m4 b/c/src/lib/libbsp/mips/acinclude.m4
index 3b6196426e..3704dafe5b 100644
--- a/c/src/lib/libbsp/mips/acinclude.m4
+++ b/c/src/lib/libbsp/mips/acinclude.m4
@@ -2,6 +2,8 @@
AC_DEFUN([RTEMS_CHECK_BSPDIR],
[
case "$1" in
+ csb350 )
+ AC_CONFIG_SUBDIRS([csb350]);;
genmongoosev )
AC_CONFIG_SUBDIRS([genmongoosev]);;
jmr3904 )
diff --git a/c/src/lib/libbsp/mips/csb350/Makefile.am b/c/src/lib/libbsp/mips/csb350/Makefile.am
new file mode 100644
index 0000000000..25bd304e88
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/Makefile.am
@@ -0,0 +1,178 @@
+##
+## $Id$
+##
+
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+# wrapup is the one that actually builds and installs the library
+# from the individual .rel files built in other directories
+SUBDIRS = .
+
+include $(top_srcdir)/../../../../automake/compile.am
+include $(top_srcdir)/../../bsp.am
+
+dist_project_lib_DATA = bsp_specs
+
+include_HEADERS = include/bsp.h
+include_HEADERS += include/tm27.h
+nodist_include_HEADERS = include/bspopts.h
+
+EXTRA_PROGRAMS =
+CLEANFILES =
+noinst_DATA =
+
+nodist_include_HEADERS += ../../shared/include/coverhd.h
+
+EXTRA_DIST = start/start.S start/regs.S
+start$(LIB_VARIANT).$(OBJEXT): start/start.S
+ $(CPPASCOMPILE) -DASM -o $@ -c $<
+project_lib_DATA = start$(LIB_VARIANT).$(OBJEXT)
+
+dist_project_lib_DATA += startup/linkcmds
+
+EXTRA_PROGRAMS += clock.rel
+CLEANFILES += clock.rel
+clock_rel_SOURCES = clock/clockdrv.c
+clock_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += clock_g.rel
+CLEANFILES += clock_g.rel
+clock_g_rel_SOURCES = $(clock_rel_SOURCES)
+clock_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+clock_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += clock$(LIB_VARIANT).rel
+
+EXTRA_PROGRAMS += console.rel
+CLEANFILES += console.rel
+console_rel_SOURCES = console/console-io.c ../../shared/console-polled.c
+console_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += console_g.rel
+CLEANFILES += console_g.rel
+console_g_rel_SOURCES = $(console_rel_SOURCES)
+console_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+console_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += console$(LIB_VARIANT).rel
+
+EXTRA_PROGRAMS += startup.rel
+CLEANFILES += startup.rel
+startup_rel_SOURCES = startup/bspclean.c ../../shared/bsplibc.c \
+ ../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
+ ../../shared/main.c ../../shared/sbrk.c \
+ ../../shared/gnatinstallhandler.c ../../shared/setvec.c
+startup_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += startup_g.rel
+CLEANFILES += startup_g.rel
+startup_g_rel_SOURCES = $(startup_rel_SOURCES)
+startup_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+startup_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += startup$(LIB_VARIANT).rel
+
+EXTRA_PROGRAMS += timer.rel
+CLEANFILES += timer.rel
+timer_rel_SOURCES = timer/timer.c
+timer_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += timer_g.rel
+CLEANFILES += timer_g.rel
+timer_g_rel_SOURCES = $(timer_rel_SOURCES)
+timer_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+timer_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += timer$(LIB_VARIANT).rel
+
+if HAS_NETWORKING
+network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
+EXTRA_PROGRAMS += network.rel
+CLEANFILES += network.rel
+network_rel_SOURCES = network/network.c
+network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V) \
+ $(network_CPPFLAGS)
+network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += network_g.rel
+CLEANFILES += network_g.rel
+network_g_rel_SOURCES = $(network_rel_SOURCES)
+network_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V) \
+ $(network_CPPFLAGS)
+network_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += network$(LIB_VARIANT).rel
+endif
+
+EXTRA_LIBRARIES = libbsp.a
+CLEANFILES += libbsp.a
+libbsp_a_SOURCES =
+libbsp_a_LIBADD = startup$(LIB_VARIANT).rel clock$(LIB_VARIANT).rel \
+ console$(LIB_VARIANT).rel timer$(LIB_VARIANT).rel
+if HAS_NETWORKING
+libbsp_a_LIBADD += network$(LIB_VARIANT).rel
+endif
+libbsp_a_LIBADD += ../../../libcpu/mips/shared/cache$(LIB_VARIANT).rel \
+ ../../../libcpu/mips/shared/interrupts$(LIB_VARIANT).rel \
+ ../../../libcpu/mips/au1x00/vectorisrs$(LIB_VARIANT).rel
+
+EXTRA_LIBRARIES += libbsp_g.a
+CLEANFILES += libbsp_g.a
+libbsp_g_a_SOURCES = $(libbsp_a_SOURCES)
+libbsp_g_a_LIBADD = $(libbsp_a_LIBADD)
+
+noinst_DATA += libbsp$(LIB_VARIANT).a
+
+all-local: $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
+
+PREINSTALL_DIRS =
+PREINSTALL_FILES =
+TMPINSTALL_FILES =
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
+
+$(PROJECT_LIB)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_LIB)
+ @: > $(PROJECT_LIB)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
+
+$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
+PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
+
+$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
+
+$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
+
+$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
+
+$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+
+$(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT): start$(LIB_VARIANT).$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT)
+
+$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
+
+CLEANFILES += $(PREINSTALL_FILES)
+DISTCLEANFILES = $(PREINSTALL_DIRS)
+CLEANFILES += $(TMPINSTALL_FILES)
+
+include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/lib/libbsp/mips/csb350/README b/c/src/lib/libbsp/mips/csb350/README
new file mode 100644
index 0000000000..85b1664cb4
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/README
@@ -0,0 +1,6 @@
+#
+# README,v 1.4 2000/12/13 22:16:27 joel Exp
+#
+
+BSP for the Cogent CSB350 Au1500 based board
+
diff --git a/c/src/lib/libbsp/mips/csb350/bsp_specs b/c/src/lib/libbsp/mips/csb350/bsp_specs
new file mode 100644
index 0000000000..1e47aa66c3
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/bsp_specs
@@ -0,0 +1,26 @@
+%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__ -D__USE_INIT_FINI__ } -Asystem(embedded)
+
+*lib:
+%{!qrtems: %(old_lib)} %{!nostdlibs: %{qrtems: --start-group \
+%{!qrtems_debug: -lrtemsbsp -lrtemscpu} \
+ %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
+-lc -lgcc --end-group \
+%{!qnolinkcmds: -T linkcmds%s}}}
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{!nostdlibs: %{qrtems: \
+ %{!qrtems_debug: start.o%s} \
+ %{qrtems_debug: start_g.o%s} crtbegin.o%s }}
+
+*link:
+%(old_link) %{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e _start}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s crtn.o%s }
diff --git a/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c b/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
new file mode 100644
index 0000000000..71c844095e
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
@@ -0,0 +1,81 @@
+/*
+ * Instantiate the clock driver shell.
+ *
+ * This usese the TOY (Time of Year) timer to implement the clock.
+ *
+ * Copyright (c) 2005 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <libcpu/au1x00.h>
+
+
+unsigned32 tick_interval;
+unsigned32 last_match;
+
+#define CLOCK_VECTOR AU1X00_IRQ_TOY_MATCH2
+
+#define Clock_driver_support_at_tick() \
+ do { \
+ while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TM0); \
+ last_match = AU1X00_SYS_TOYREAD(AU1X00_SYS_ADDR); \
+ AU1X00_SYS_TOYMATCH2(AU1X00_SYS_ADDR) = last_match + tick_interval; \
+ au_sync(); \
+ } while(0)
+
+/* Set for rising edge interrupt */
+#define Clock_driver_support_install_isr( _new, _old ) \
+ do { \
+ _old = set_vector( _new, AU1X00_IRQ_TOY_MATCH2, 1 ); \
+ AU1X00_IC_MASKCLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+ AU1X00_IC_SRCSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+ AU1X00_IC_CFG0SET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+ AU1X00_IC_CFG1CLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+ AU1X00_IC_CFG2CLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+ AU1X00_IC_ASSIGNSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+ } while(0)
+
+void au1x00_clock_init(void)
+{
+ unsigned32 wakemask;
+ /* Clear the trim register */
+ AU1X00_SYS_TOYTRIM(AU1X00_SYS_ADDR) = 0;
+
+ /* Clear the TOY counter */
+ while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TS);
+ AU1X00_SYS_TOYWRITE(AU1X00_SYS_ADDR) = 0;
+ while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TS);
+
+ wakemask = AU1X00_SYS_WAKEMSK(AU1X00_SYS_ADDR);
+ wakemask |= AU1X00_SYS_WAKEMSK_M20;
+ AU1X00_SYS_WAKEMSK(AU1X00_SYS_ADDR) = wakemask;
+ AU1X00_IC_WAKESET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2;
+
+ tick_interval = 32768 * rtems_configuration_get_microseconds_per_tick();
+ tick_interval = tick_interval / 1000000;
+ printk("tick_interval = %d\n", tick_interval);
+
+ last_match = AU1X00_SYS_TOYREAD(AU1X00_SYS_ADDR);
+ AU1X00_SYS_TOYMATCH2(AU1X00_SYS_ADDR) = last_match + (50*tick_interval);
+ AU1X00_IC_MASKSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2;
+ while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TM0);
+}
+
+#define Clock_driver_support_initialize_hardware() \
+ do { \
+ au1x00_clock_init(); \
+ } while(0)
+
+
+
+#define Clock_driver_support_shutdown_hardware()
+
+#include "../../../shared/clockdrv_shell.c"
diff --git a/c/src/lib/libbsp/mips/csb350/configure.ac b/c/src/lib/libbsp/mips/csb350/configure.ac
new file mode 100644
index 0000000000..49a56e6552
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/configure.ac
@@ -0,0 +1,23 @@
+## Process this file with autoconf to produce a configure script.
+##
+## $Id$
+
+AC_PREREQ(2.59)
+AC_INIT([rtems-c-src-lib-libbsp-mips-csb350],[_RTEMS_VERSION],[rtems-bugs@rtems.com])
+AC_CONFIG_SRCDIR([bsp_specs])
+RTEMS_TOP(../../../../../..)
+
+RTEMS_CANONICAL_TARGET_CPU
+AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.8])
+RTEMS_BSP_CONFIGURE
+
+RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm])
+RTEMS_CANONICALIZE_TOOLS
+RTEMS_PROG_CCAS
+
+RTEMS_CHECK_NETWORKING
+AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
+
+# Explicitly list all Makefiles here
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/c/src/lib/libbsp/mips/csb350/console/console-io.c b/c/src/lib/libbsp/mips/csb350/console/console-io.c
new file mode 100644
index 0000000000..4474a220f7
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/console/console-io.c
@@ -0,0 +1,89 @@
+/*
+ * This file contains the hardware specific portions of the TTY driver
+ * for the serial ports on the csb350.
+ *
+ * Logic based on the jmr3904-io.c file in newlib 1.8.2
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <libcpu/au1x00.h>
+
+/*
+ * console_initialize_hardware
+ *
+ * This routine initializes the console hardware.
+ *
+ */
+
+void console_initialize_hardware(void)
+{
+ uart0->fifoctrl = 0xf1; /* enable fifo, max sizes */
+ au_sync();
+}
+
+
+/*
+ * console_outbyte_polled
+ *
+ * This routine transmits a character using polling.
+ */
+
+void console_outbyte_polled(
+ int port,
+ char ch
+)
+{
+ volatile int i;
+
+ /* wait for the fifo to make room */
+ while ((uart0->linestat & 0x20) == 0) {
+ continue;
+ }
+
+ uart0->txdata = ch;
+ au_sync();
+}
+
+/*
+ * console_inbyte_nonblocking
+ *
+ * This routine polls for a character.
+ */
+
+int console_inbyte_nonblocking(
+ int port
+)
+{
+ unsigned char c;
+
+ if (uart0->linestat & 1) {
+ c = (char)uart0->rxdata;
+ return c;
+ } else {
+ return -1;
+ }
+}
+
+#include <rtems/bspIo.h>
+
+void csb250_output_char(char c)
+{
+ console_outbyte_polled( 0, c );
+ if (c == '\n') {
+ console_outbyte_polled( 0, '\r' );
+ }
+}
+
+BSP_output_char_function_type BSP_output_char = csb250_output_char;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
diff --git a/c/src/lib/libbsp/mips/csb350/include/bsp.h b/c/src/lib/libbsp/mips/csb350/include/bsp.h
new file mode 100644
index 0000000000..0118d3aec8
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/include/bsp.h
@@ -0,0 +1,113 @@
+/* bsp.h
+ *
+ * This include file contains some definitions specific to the
+ * Cogent CSB350 Board.
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef __BSP_H__
+#define __BSP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bspopts.h>
+
+#include <rtems.h>
+#include <rtems/iosupp.h>
+#include <rtems/console.h>
+#include <rtems/clockdrv.h>
+#include <libcpu/au1x00.h>
+
+/*
+ * 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 */
+
+/*
+ * Define the interrupt mechanism for Time Test 27
+ */
+int assert_sw_irw(unsigned32 irqnum);
+int negate_sw_irw(unsigned32 irqnum);
+
+#define MUST_WAIT_FOR_INTERRUPT 0
+
+#define Install_tm27_vector( handler ) \
+ (void) set_vector(handler, AU1X00_IRQ_SW0, 1);
+
+#define Cause_tm27_intr() \
+ do { \
+ assert_sw_irq(0); \
+ } while(0)
+
+#define Clear_tm27_intr() \
+ do { \
+ negate_sw_irq(0); \
+ } while(0)
+
+#if 0
+#define Lower_tm27_intr() \
+ mips_enable_in_interrupt_mask( 0xff01 );
+#else
+#define Lower_tm27_intr() \
+ do { \
+ continue;\
+ } while(0)
+#endif
+
+/* Constants */
+
+/* miscellaneous stuff assumed to exist */
+
+extern rtems_configuration_table BSP_Configuration;
+
+/*
+ * Device Driver Table Entries
+ */
+
+/*
+ * NOTE: Use the standard Console driver entry
+ */
+
+/*
+ * NOTE: Use the standard Clock driver entry
+ */
+
+/*
+ * Network driver configuration
+ */
+extern struct rtems_bsdnet_ifconfig *config;
+
+int rtems_au1x00_emac_attach(struct rtems_bsdnet_ifconfig *config,
+ int attaching);
+#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_au1x00_emac_attach
+
+/* functions */
+
+void bsp_cleanup( void );
+
+rtems_isr_entry set_vector(
+ rtems_isr_entry, rtems_vector_number, int );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/mips/csb350/include/tm27.h b/c/src/lib/libbsp/mips/csb350/include/tm27.h
new file mode 100644
index 0000000000..34149a35b4
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/include/tm27.h
@@ -0,0 +1,63 @@
+/*
+ * tm27.h
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+/*
+ * Define the interrupt mechanism for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+#if 0
+#define Install_tm27_vector( handler ) \
+ (void) set_vector( handler, TX3904_IRQ_SOFTWARE_1, 1 ); \
+
+#define Cause_tm27_intr() \
+ asm volatile ( "syscall 0x01" : : );
+
+#define CLOCK_VECTOR TX3904_IRQ_TMR0
+
+#define Clear_tm27_intr() /* empty */
+
+#define Lower_tm27_intr() /* empty */
+#else
+#define Install_tm27_vector( handler ) \
+ (void) set_vector( handler, TX3904_IRQ_TMR0, 1 ); \
+
+#define Cause_tm27_intr() \
+ do { \
+ uint32_t _clicks = 20; \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CCDR, 0x3 ); \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CPRA, _clicks ); \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TISR, 0x00 ); \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_ITMR, 0x8001 ); \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TCR, 0xC0 ); \
+ *((volatile uint32_t*) 0xFFFFC01C) = 0x00000700; \
+ } while(0)
+
+#define Clear_tm27_intr() \
+ do { \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_ITMR, 0x0001 ); \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CCDR, 0x3 ); \
+ TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TISR, 0x00 ); \
+ } while(0)
+
+#define Lower_tm27_intr() \
+ mips_enable_in_interrupt_mask( 0xff01 );
+
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/mips/csb350/network/network.c b/c/src/lib/libbsp/mips/csb350/network/network.c
new file mode 100644
index 0000000000..7bf2cc65d4
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/network/network.c
@@ -0,0 +1,889 @@
+/*
+ * Au1x00 ethernet driver
+ *
+ * Copyright (c) 2005 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <bsp.h>
+#include <libcpu/au1x00.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <errno.h>
+#include <rtems/error.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <assert.h>
+
+#define NUM_IFACES 1
+#define NUM_TX_DMA_BUFS 4
+#define NUM_RX_DMA_BUFS 4
+
+/* RTEMS event used to start tx daemon. */
+#define START_TX_EVENT RTEMS_EVENT_1
+/* RTEMS event used to start rx daemon. */
+#define START_RX_EVENT RTEMS_EVENT_2
+
+rtems_isr au1x00_emac_isr(rtems_vector_number vector);
+
+#define TX_BUF_SIZE 2048
+
+char tx_buf_base[(4 * TX_BUF_SIZE) + 32];
+
+volatile int wait_count;
+/*
+ * Hardware-specific storage
+ */
+typedef struct
+{
+ /*
+ * Connection to networking code
+ * This entry *must* be the first in the sonic_softc structure.
+ */
+ struct arpcom arpcom;
+
+ /*
+ * Interrupt vector
+ */
+ rtems_vector_number vector;
+
+ /*
+ * Indicates configuration
+ */
+ int acceptBroadcast;
+
+ /*
+ * Tasks waiting for interrupts
+ */
+ rtems_id rx_daemon_tid;
+ rtems_id tx_daemon_tid;
+
+ /*
+ * Buffers
+ */
+ au1x00_macdma_rx_t *rx_dma;
+ au1x00_macdma_tx_t *tx_dma;
+ int rx_head;
+ int rx_tail;
+ int tx_head;
+ int tx_tail;
+ struct mbuf *rx_mbuf[NUM_RX_DMA_BUFS];
+
+ unsigned char *tx_buf[4];
+
+ /*
+ * register addresses
+ */
+ unsigned32 ctrl_regs;
+ unsigned32 *en_reg;
+ unsigned32 int_mask;
+ unsigned32 int_ctrlr;
+
+ /*
+ * device
+ */
+ int unitnumber;
+
+ /*
+ * Statistics
+ */
+ unsigned long interrupts;
+ unsigned long rx_interrupts;
+ unsigned long tx_interrupts;
+ unsigned long rx_missed;
+ unsigned long rx_bcast;
+ unsigned long rx_mcast;
+ unsigned long rx_unsupp;
+ unsigned long rx_ctrl;
+ unsigned long rx_len_err;
+ unsigned long rx_crc_err;
+ unsigned long rx_dribble;
+ unsigned long rx_mii_err;
+ unsigned long rx_collision;
+ unsigned long rx_too_long;
+ unsigned long rx_runt;
+ unsigned long rx_watchdog;
+ unsigned long rx_pkts;
+ unsigned long rx_dropped;
+
+ unsigned long tx_deferred;
+ unsigned long tx_underrun;
+ unsigned long tx_aborted;
+ unsigned long tx_pkts;
+} au1x00_emac_softc_t;
+
+static volatile au1x00_emac_softc_t softc[NUM_IFACES];
+
+
+/* function prototypes */
+int rtems_au1x00_emac_attach (struct rtems_bsdnet_ifconfig *config,
+ int attaching);
+void au1x00_emac_init(void *arg);
+void au1x00_emac_init_hw(au1x00_emac_softc_t *sc);
+void au1x00_emac_start(struct ifnet *ifp);
+void au1x00_emac_stop (au1x00_emac_softc_t *sc);
+void au1x00_emac_tx_daemon (void *arg);
+void au1x00_emac_rx_daemon (void *arg);
+void au1x00_emac_sendpacket (struct ifnet *ifp, struct mbuf *m);
+void au1x00_emac_stats (au1x00_emac_softc_t *sc);
+static int au1x00_emac_ioctl (struct ifnet *ifp, int command, caddr_t data);
+static void mii_write(au1x00_emac_softc_t *sc, unsigned8 reg, unsigned16 val);
+static void mii_read(au1x00_emac_softc_t *sc, unsigned8 reg, unsigned16 *val);
+static void mii_init(au1x00_emac_softc_t *sc);
+
+static void mii_write(au1x00_emac_softc_t *sc, unsigned8 reg, unsigned16 val)
+{
+ /* wait for the interface to get unbusy */
+ while (AU1X00_MAC_MIICTRL(sc->ctrl_regs) & AU1X00_MAC_MIICTRL_MB) {
+ continue;
+ }
+
+ /* write to address 0 - we only support address 0 */
+ AU1X00_MAC_MIIDATA(sc->ctrl_regs) = val;
+ AU1X00_MAC_MIICTRL(sc->ctrl_regs) = (((reg & 0x1f) << 6) |
+ AU1X00_MAC_MIICTRL_MW);
+ au_sync();
+
+ /* wait for it to complete */
+ while (AU1X00_MAC_MIICTRL(sc->ctrl_regs) & AU1X00_MAC_MIICTRL_MB) {
+ continue;
+ }
+}
+
+static void mii_read(au1x00_emac_softc_t *sc, unsigned8 reg, unsigned16 *val)
+{
+ /* wait for the interface to get unbusy */
+ while (AU1X00_MAC_MIICTRL(sc->ctrl_regs) & AU1X00_MAC_MIICTRL_MB) {
+ continue;
+ }
+
+ /* write to address 0 - we only support address 0 */
+ AU1X00_MAC_MIICTRL(sc->ctrl_regs) = ((reg & 0x1f) << 6);
+ au_sync();
+
+ /* wait for it to complete */
+ while (AU1X00_MAC_MIICTRL(sc->ctrl_regs) & AU1X00_MAC_MIICTRL_MB) {
+ continue;
+ }
+ *val = AU1X00_MAC_MIIDATA(sc->ctrl_regs);
+}
+
+static void mii_init(au1x00_emac_softc_t *sc)
+{
+ unsigned16 data;
+
+ mii_write(sc, 0, 0x8000); /* reset */
+ do {
+ mii_read(sc, 0, &data);
+ } while (data & 0x8000);
+
+ mii_write(sc, 0, 0x3200); /* reset autonegotiation */
+ mii_write(sc, 17, 0xffc0); /* setup LEDs */
+
+}
+
+
+
+int rtems_au1x00_emac_attach (
+ struct rtems_bsdnet_ifconfig *config,
+ int attaching
+ )
+{
+ struct ifnet *ifp;
+ int mtu;
+ int unitnumber;
+ char *unitname;
+ static au1x00_emac_softc_t *sc;
+
+ /*
+ * Parse driver name
+ */
+ if ((unitnumber = rtems_bsdnet_parse_driver_name (config, &unitname)) < 0)
+ return 0;
+
+ /*
+ * Is driver free?
+ */
+ if (unitnumber > NUM_IFACES) {
+ printf ("Bad AU1X00 EMAC unit number.\n");
+ return 0;
+ }
+
+ sc = &softc[unitnumber];
+
+ ifp = &sc->arpcom.ac_if;
+ if (ifp->if_softc != NULL) {
+ printf ("Driver already in use.\n");
+ return 0;
+ }
+
+ /*
+ * zero out the control structure
+ */
+
+ memset(sc, 0, sizeof(*sc));
+
+ sc->unitnumber = unitnumber;
+ sc->int_ctrlr = AU1X00_IC0_ADDR;
+
+ if (unitnumber == 0) {
+ sc->ctrl_regs = AU1100_MAC0_ADDR;
+ sc->en_reg = (void *)(AU1100_MACEN_ADDR + 0);
+
+ sc->tx_dma = (void *)(AU1X00_MACDMA0_ADDR + 0x000);
+ sc->rx_dma = (void *)(AU1X00_MACDMA0_ADDR + 0x100);
+ sc->int_mask = AU1X00_IC_IRQ_MAC0;
+ } else {
+ printk("Unknown network device: %d\n", unitnumber);
+ return 0;
+ }
+
+ /* If the ethernet controller is already set up, read the MAC address */
+ if ((*sc->en_reg & 0x33) == 0x33) {
+ sc->arpcom.ac_enaddr[5] = ((AU1X00_MAC_ADDRHIGH(sc->ctrl_regs) >> 8) &
+ 0xff);
+ sc->arpcom.ac_enaddr[4] = ((AU1X00_MAC_ADDRHIGH(sc->ctrl_regs) >> 0) &
+ 0xff);
+ sc->arpcom.ac_enaddr[3] = ((AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 24) &
+ 0xff);
+ sc->arpcom.ac_enaddr[2] = ((AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 16) &
+ 0xff);
+ sc->arpcom.ac_enaddr[1] = ((AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 8) &
+ 0xff);
+ sc->arpcom.ac_enaddr[0] = ((AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 0) &
+ 0xff);
+ } else {
+ /* It's not set up yet, so we set a MAC address */
+ sc->arpcom.ac_enaddr[5] = 0x05;
+ sc->arpcom.ac_enaddr[4] = 0xc0;
+ sc->arpcom.ac_enaddr[3] = 0x50;
+ sc->arpcom.ac_enaddr[2] = 0x31;
+ sc->arpcom.ac_enaddr[1] = 0x23;
+ sc->arpcom.ac_enaddr[0] = 0x00;
+ }
+
+
+ if (config->mtu) {
+ mtu = config->mtu;
+ } else {
+ mtu = ETHERMTU;
+ }
+
+ sc->acceptBroadcast = !config->ignore_broadcast;
+
+ /*
+ * Set up network interface values
+ */
+ ifp->if_softc = sc;
+ ifp->if_unit = unitnumber;
+ ifp->if_name = unitname;
+ ifp->if_mtu = mtu;
+ ifp->if_init = au1x00_emac_init;
+ ifp->if_ioctl = au1x00_emac_ioctl;
+ ifp->if_start = au1x00_emac_start;
+ ifp->if_output = ether_output;
+ ifp->if_flags = IFF_BROADCAST;
+ if (ifp->if_snd.ifq_maxlen == 0) {
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ }
+
+ /*
+ * Attach the interface
+ */
+ if_attach (ifp);
+ ether_ifattach (ifp);
+ return 1;
+}
+
+void au1x00_emac_init(void *arg)
+{
+ au1x00_emac_softc_t *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ /*
+ *This is for stuff that only gets done once (au1x00_emac_init()
+ * gets called multiple times
+ */
+ if (sc->tx_daemon_tid == 0)
+ {
+ /* Set up EMAC hardware */
+ au1x00_emac_init_hw(sc);
+
+
+ /* install the interrupt handler */
+ if (sc->unitnumber == 0) {
+ set_vector(au1x00_emac_isr, AU1X00_IRQ_MAC0, 1);
+ } else {
+ set_vector(au1x00_emac_isr, AU1X00_IRQ_MAC1, 1);
+ }
+ AU1X00_IC_MASKCLR(sc->int_ctrlr) = sc->int_mask;
+ au_sync();
+
+ /* set src bit */
+ AU1X00_IC_SRCSET(sc->int_ctrlr) = sc->int_mask;
+
+ /* high level */
+ AU1X00_IC_CFG0SET(sc->int_ctrlr) = sc->int_mask;
+ AU1X00_IC_CFG1CLR(sc->int_ctrlr) = sc->int_mask;
+ AU1X00_IC_CFG2SET(sc->int_ctrlr) = sc->int_mask;
+
+ /* assign to request 0 - negative logic */
+ AU1X00_IC_ASSIGNSET(sc->int_ctrlr) = sc->int_mask;
+ au_sync();
+
+ /* Start driver tasks */
+ sc->tx_daemon_tid = rtems_bsdnet_newproc("ENTx",
+ 4096,
+ au1x00_emac_tx_daemon,
+ sc);
+
+ sc->rx_daemon_tid = rtems_bsdnet_newproc("ENRx",
+ 4096,
+ au1x00_emac_rx_daemon,
+ sc);
+
+
+ }
+ /* EMAC doesn't support promiscuous, so ignore requests */
+ if (ifp->if_flags & IFF_PROMISC)
+ printf ("Warning - AU1X00 EMAC doesn't support Promiscuous Mode!\n");
+
+ /*
+ * Tell the world that we're running.
+ */
+ ifp->if_flags |= IFF_RUNNING;
+
+ /*
+ * start tx, rx
+ */
+ AU1X00_MAC_CONTROL(sc->ctrl_regs) |= (AU1X00_MAC_CTRL_TE |
+ AU1X00_MAC_CTRL_RE);
+ au_sync();
+
+
+} /* au1x00_emac_init() */
+
+void au1x00_emac_init_hw(au1x00_emac_softc_t *sc)
+{
+ int i;
+ struct mbuf *m;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ /* reset the MAC */
+ *sc->en_reg = 0x40;
+ au_sync();
+ for (i = 0; i < 10000; i++) {
+ continue;
+ }
+
+/* *sc->en_reg = AU1X00_MAC_EN_CE; */
+ *sc->en_reg = 41;
+ au_sync();
+ for (i = 0; i < 10000; i++) {
+ continue;
+ }
+
+/*
+ *sc->en_reg = (AU1X00_MAC_EN_CE |
+ AU1X00_MAC_EN_E2 |
+ AU1X00_MAC_EN_E1 |
+ AU1X00_MAC_EN_E0);
+*/
+ *sc->en_reg = 0x33;
+ au_sync();
+ mii_init(sc);
+
+ /* set the mac address */
+ AU1X00_MAC_ADDRHIGH(sc->ctrl_regs) = ((sc->arpcom.ac_enaddr[5] << 8) |
+ (sc->arpcom.ac_enaddr[4] << 0));
+ AU1X00_MAC_ADDRLOW(sc->ctrl_regs) = ((sc->arpcom.ac_enaddr[3] << 24) |
+ (sc->arpcom.ac_enaddr[2] << 16) |
+ (sc->arpcom.ac_enaddr[1] << 8) |
+ (sc->arpcom.ac_enaddr[0] << 0));
+
+
+ /* get the MAC address from the chip */
+ sc->arpcom.ac_enaddr[5] = (AU1X00_MAC_ADDRHIGH(sc->ctrl_regs) >> 8) & 0xff;
+ sc->arpcom.ac_enaddr[4] = (AU1X00_MAC_ADDRHIGH(sc->ctrl_regs) >> 0) & 0xff;
+ sc->arpcom.ac_enaddr[3] = (AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 24) & 0xff;
+ sc->arpcom.ac_enaddr[2] = (AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 16) & 0xff;
+ sc->arpcom.ac_enaddr[1] = (AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 8) & 0xff;
+ sc->arpcom.ac_enaddr[0] = (AU1X00_MAC_ADDRLOW(sc->ctrl_regs) >> 0) & 0xff;
+
+ printk("Setting mac_control to 0x%x\n",
+ (AU1X00_MAC_CTRL_F |
+ AU1X00_MAC_CTRL_PM |
+ AU1X00_MAC_CTRL_RA |
+ AU1X00_MAC_CTRL_DO |
+ AU1X00_MAC_CTRL_EM));
+
+ AU1X00_MAC_CONTROL(sc->ctrl_regs) = (AU1X00_MAC_CTRL_F | /* full duplex */
+ AU1X00_MAC_CTRL_PM | /* pass mcast */
+ AU1X00_MAC_CTRL_RA | /* recv all */
+ AU1X00_MAC_CTRL_DO | /* disable own */
+ AU1X00_MAC_CTRL_EM); /* Big endian */
+ au_sync();
+ printk("mac_control was set to 0x%x\n", AU1X00_MAC_CONTROL(sc->ctrl_regs));
+ printk("mac_control addr is 0x%x\n", &AU1X00_MAC_CONTROL(sc->ctrl_regs));
+
+ /* initialize our receive buffer descriptors */
+ for (i = 0; i < NUM_RX_DMA_BUFS; i++) {
+ MGETHDR(m, M_WAIT, MT_DATA);
+ MCLGET(m, M_WAIT);
+
+ m->m_pkthdr.rcvif = ifp;
+ m->m_nextpkt = 0;
+
+ /*
+ * The receive buffer must be aligned with a cache line
+ * boundary.
+ */
+ if (mtod(m, unsigned32) & 0x1f) {
+ mtod(m, unsigned32) = (mtod(m, unsigned32) + 0x1f) & 0x1f;
+ }
+ sc->rx_dma[i].addr = (mtod(m, unsigned32) & ~0xe0000000);
+ sc->rx_mbuf[i] = m;
+ }
+
+ /* Initialize transmit buffer descriptors */
+ for (i = 0; i < NUM_TX_DMA_BUFS; i++) {
+ sc->tx_dma[i].addr = 0;
+ }
+
+ /* initialize the transmit buffers */
+ sc->tx_buf[0] = (void *)((((int)&tx_buf_base[0]) + 0x1f) & ~0x1f);
+ sc->tx_buf[1] = (void *)(((int)sc->tx_buf[0]) + TX_BUF_SIZE);
+ sc->tx_buf[2] = (void *)(((int)sc->tx_buf[1]) + TX_BUF_SIZE);
+ sc->tx_buf[3] = (void *)(((int)sc->tx_buf[2]) + TX_BUF_SIZE);
+
+ sc->rx_head = (sc->rx_dma[0].addr >> 2) & 0x3;
+ sc->rx_tail = (sc->rx_dma[0].addr >> 2) & 0x3;
+ sc->tx_head = (sc->tx_dma[0].addr >> 2) & 0x3;
+ sc->tx_tail = (sc->tx_dma[0].addr >> 2) & 0x3;
+
+ for (i = 0; i < NUM_RX_DMA_BUFS; i++) {
+ sc->rx_dma[i].addr |= AU1X00_MAC_DMA_RXADDR_EN;
+ }
+
+} /* au1x00_emac_init_hw() */
+
+void au1x00_emac_start(struct ifnet *ifp)
+{
+ au1x00_emac_softc_t *sc = ifp->if_softc;
+
+ rtems_event_send(sc->tx_daemon_tid, START_TX_EVENT);
+ ifp->if_flags |= IFF_OACTIVE;
+}
+
+void au1x00_emac_stop (au1x00_emac_softc_t *sc)
+{
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ ifp->if_flags &= ~IFF_RUNNING;
+
+ /*
+ * Stop the transmitter and receiver.
+ */
+
+ /* Disable TX/RX */
+ AU1X00_MAC_CONTROL(sc->ctrl_regs) &= ~(AU1X00_MAC_CTRL_TE |
+ AU1X00_MAC_CTRL_RE);
+ au_sync();
+}
+
+/*
+ * Driver tx daemon
+ */
+void au1x00_emac_tx_daemon (void *arg)
+{
+ au1x00_emac_softc_t *sc = (au1x00_emac_softc_t *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ rtems_event_set events;
+ unsigned32 ic_base; /* interrupt controller */
+
+ ic_base = AU1X00_IC0_ADDR;
+
+ /* turn on interrupt, then wait for one */
+ if (sc->unitnumber == 0) {
+ AU1X00_IC_MASKSET(ic_base) = AU1X00_IC_IRQ_MAC0;
+ } else {
+ AU1X00_IC_MASKSET(ic_base) = AU1X00_IC_IRQ_MAC1;
+ }
+ au_sync();
+
+ for (;;)
+ {
+ rtems_bsdnet_event_receive(
+ START_TX_EVENT,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events);
+
+ /* Send packets till queue is empty */
+ for (;;)
+ {
+ /* Get the next mbuf chain to transmit. */
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (!m)
+ break;
+
+ sc->tx_pkts++;
+ au1x00_emac_sendpacket (ifp, m);
+ }
+ ifp->if_flags &= ~IFF_OACTIVE;
+ }
+}
+
+/*
+ * Driver rx daemon
+ */
+void au1x00_emac_rx_daemon (void *arg)
+{
+ au1x00_emac_softc_t *sc = (au1x00_emac_softc_t *)arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+ struct ether_header *eh;
+ rtems_event_set events;
+ unsigned32 status;
+
+ while (1) {
+ rtems_bsdnet_event_receive(
+ START_RX_EVENT,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events);
+
+ /* while there are packets to receive */
+
+ while (!(sc->rx_dma[sc->rx_head].addr & (AU1X00_MAC_DMA_RXADDR_DN |
+ AU1X00_MAC_DMA_RXADDR_EN))) {
+ status = sc->rx_dma[sc->rx_head].stat;
+ if (status & AU1X00_MAC_DMA_RXSTAT_MI) {
+ sc->rx_missed++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_BF) {
+ sc->rx_bcast++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_MF) {
+ sc->rx_mcast++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_UC) {
+ sc->rx_unsupp++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_CF) {
+ sc->rx_ctrl++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_LE) {
+ sc->rx_len_err++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_CR) {
+ sc->rx_crc_err++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_DB) {
+ sc->rx_dribble++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_ME) {
+ sc->rx_mii_err++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_CS) {
+ sc->rx_collision++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_FL) {
+ sc->rx_too_long++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_RF) {
+ sc->rx_runt++;
+ }
+ if (status & AU1X00_MAC_DMA_RXSTAT_WT) {
+ sc->rx_watchdog++;
+ }
+
+ /* If no errrors, accept packet */
+ if ((status & (AU1X00_MAC_DMA_RXSTAT_CR |
+ AU1X00_MAC_DMA_RXSTAT_DB |
+ AU1X00_MAC_DMA_RXSTAT_RF)) == 0) {
+
+ sc->rx_pkts++;
+
+ /* find the start of the mbuf */
+ m = sc->rx_mbuf[sc->rx_head];
+
+ /* set the length of the mbuf */
+ m->m_len = AU1X00_MAC_DMA_RXSTAT_LEN(sc->rx_dma[sc->rx_head].stat);
+ m->m_len -= 4; /* remove ethernet CRC */
+
+ m->m_pkthdr.len = m->m_len;
+
+ /* strip off the ethernet header from the mbuf */
+ /* but save the pointer to it */
+ eh = mtod (m, struct ether_header *);
+ m->m_data += sizeof(struct ether_header);
+
+ /* give the received packet to the stack */
+ ether_input(ifp, eh, m);
+ /* get a new buf and make it ready for the MAC */
+ MGETHDR(m, M_WAIT, MT_DATA);
+ MCLGET(m, M_WAIT);
+
+ m->m_pkthdr.rcvif = ifp;
+ m->m_nextpkt = 0;
+
+ /*
+ * The receive buffer must be aligned with a cache line
+ * boundary.
+ */
+ mtod(m, unsigned32) = (mtod(m, unsigned32) + 0x1f) & ~0x1f;
+
+ } else {
+ sc->rx_dropped++;
+
+ /* find the mbuf so we can reuse it*/
+ m = sc->rx_mbuf[sc->rx_head];
+ }
+
+ /* set up the receive dma to use the mbuf's cluster */
+ sc->rx_dma[sc->rx_head].addr = (mtod(m, unsigned32) & ~0xe0000000);
+ au_sync();
+ sc->rx_mbuf[sc->rx_head] = m;
+
+ sc->rx_dma[sc->rx_head].addr |= AU1X00_MAC_DMA_RXADDR_EN;
+ au_sync();
+
+
+ /* increment the buffer index */
+ sc->rx_head++;
+ if (sc->rx_head >= NUM_RX_DMA_BUFS) {
+ sc->rx_head = 0;
+ }
+ }
+ }
+}
+
+/* Send packet */
+void au1x00_emac_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+ struct mbuf *l = NULL;
+ unsigned int pkt_offset = 0;
+ au1x00_emac_softc_t *sc = (au1x00_emac_softc_t *)ifp->if_softc;
+ unsigned32 txbuf;
+
+ /* Wait for EMAC Transmit Queue to become available. */
+ while((sc->tx_dma[sc->tx_head].addr & (AU1X00_MAC_DMA_TXADDR_EN ||
+ AU1X00_MAC_DMA_TXADDR_DN)) != 0) {
+ continue;
+ }
+
+ /* copy the mbuf chain into the transmit buffer */
+ l = m;
+
+ txbuf = (unsigned32)sc->tx_buf[sc->tx_head];
+ while (l != NULL)
+ {
+
+ memcpy(((char *)txbuf + pkt_offset), /* offset into pkt for mbuf */
+ (char *)mtod(l, void *), /* cast to void */
+ l->m_len); /* length of this mbuf */
+
+ pkt_offset += l->m_len; /* update offset */
+ l = l->m_next; /* get next mbuf, if any */
+ }
+
+ /* Pad if necessary */
+ if (pkt_offset < 60) {
+ memset((char *)(txbuf + pkt_offset), 0, (60 - pkt_offset));
+ pkt_offset = 60;
+ }
+
+ /* send it off */
+ sc->tx_dma[sc->tx_head].stat = 0;
+ sc->tx_dma[sc->tx_head].len = pkt_offset;
+ sc->tx_dma[sc->tx_head].addr = ((txbuf & ~0xe0000000) |
+ AU1X00_MAC_DMA_TXADDR_EN);
+ au_sync();
+
+
+ /*
+ *Without this delay, some outgoing packets never
+ * make it out the device. Nothing in the documentation
+ * explains this.
+ */
+ for (wait_count = 0; wait_count < 5000; wait_count++){
+ continue;
+ }
+
+ /* free the mbuf chain we just copied */
+ m_freem(m);
+
+ sc->tx_head++;
+ if (sc->tx_head >= NUM_TX_DMA_BUFS) {
+ sc->tx_head = 0;
+ }
+
+} /* au1x00_emac_sendpacket () */
+
+
+
+/* Show interface statistics */
+void au1x00_emac_stats (au1x00_emac_softc_t *sc)
+{
+ printf("Interrupts:%-8lu", sc->interrupts);
+ printf(" RX Interrupts:%-8lu", sc->rx_interrupts);
+ printf(" TX Interrupts:%-8lu\n", sc->tx_interrupts);
+ printf("RX Packets:%-8lu", sc->rx_pkts);
+ printf(" RX Control:%-8lu", sc->rx_ctrl);
+ printf(" RX broadcast:%-8lu\n", sc->rx_bcast);
+ printf("RX Mcast:%-8lu", sc->rx_mcast);
+ printf(" RX missed:%-8lu", sc->rx_missed);
+ printf(" RX Unsupported ctrl:%-8lu\n", sc->rx_unsupp);
+ printf("RX Len err:%-8lu", sc->rx_len_err);
+ printf(" RX CRC err:%-8lu", sc->rx_crc_err);
+ printf(" RX dribble:%-8lu\n", sc->rx_dribble);
+ printf("RX MII err:%-8lu", sc->rx_mii_err);
+ printf(" RX collision:%-8lu", sc->rx_collision);
+ printf(" RX too long:%-8lu\n", sc->rx_too_long);
+ printf("RX runt:%-8lu", sc->rx_runt);
+ printf(" RX watchdog:%-8lu", sc->rx_watchdog);
+ printf(" RX dropped:%-8lu\n", sc->rx_dropped);
+
+ printf("TX Packets:%-8lu", sc->tx_pkts);
+ printf(" TX Deferred:%-8lu", sc->tx_deferred);
+ printf(" TX Underrun:%-8lu\n", sc->tx_underrun);
+ printf("TX Aborted:%-8lu\n", sc->tx_aborted);
+
+}
+
+
+/* Driver ioctl handler */
+static int
+au1x00_emac_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+ au1x00_emac_softc_t *sc = ifp->if_softc;
+ int error = 0;
+
+ switch (command) {
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+ ether_ioctl (ifp, command, data);
+ break;
+
+ case SIOCSIFFLAGS:
+ switch (ifp->if_flags & (IFF_UP | IFF_RUNNING))
+ {
+ case IFF_RUNNING:
+ au1x00_emac_stop (sc);
+ break;
+
+ case IFF_UP:
+ au1x00_emac_init (sc);
+ break;
+
+ case IFF_UP | IFF_RUNNING:
+ au1x00_emac_stop (sc);
+ au1x00_emac_init (sc);
+ break;
+
+ default:
+ break;
+ } /* switch (if_flags) */
+ break;
+
+ case SIO_RTEMS_SHOW_STATS:
+ au1x00_emac_stats (sc);
+ break;
+
+ /*
+ * FIXME: All sorts of multicast commands need to be added here!
+ */
+ default:
+ error = EINVAL;
+ break;
+ } /* switch (command) */
+ return error;
+}
+
+/* interrupt handler */
+rtems_isr au1x00_emac_isr (rtems_vector_number v)
+{
+ au1x00_emac_softc_t *sc;
+ int index;
+ int tx_flag = 0;
+ int rx_flag = 0;
+
+ if (v == AU1X00_IRQ_MAC0) {
+ sc = &softc[0];
+ } else {
+ assert(v == AU1X00_IRQ_MAC0);
+ }
+
+ sc->interrupts++;
+
+ /*
+ * Since there's no easy way to find out the source of the
+ * interrupt, we have to look at the tx and rx dma buffers
+ */
+ /* receive interrupt */
+ while(sc->rx_dma[sc->rx_tail].addr & AU1X00_MAC_DMA_RXADDR_DN) {
+ rx_flag = 1;
+ sc->rx_interrupts++;
+ sc->rx_dma[sc->rx_tail].addr &= ~AU1X00_MAC_DMA_RXADDR_DN;
+ au_sync();
+
+ sc->rx_tail++;
+ if (sc->rx_tail >= NUM_RX_DMA_BUFS) {
+ sc->rx_tail = 0;
+ }
+ }
+ if (rx_flag != 0) {
+ rtems_event_send(sc->rx_daemon_tid, START_RX_EVENT);
+ }
+
+ /* transmit interrupt */
+ while (sc->tx_dma[sc->tx_tail].addr & AU1X00_MAC_DMA_TXADDR_DN) {
+ unsigned32 status;
+ tx_flag = 1;
+ sc->tx_interrupts++;
+
+ status = sc->tx_dma[sc->tx_tail].stat;
+ if (status & AU1X00_MAC_DMA_TXSTAT_DF) {
+ sc->tx_deferred++;
+ }
+ if (status & AU1X00_MAC_DMA_TXSTAT_UR) {
+ sc->tx_underrun++;
+ }
+ if (status & AU1X00_MAC_DMA_TXSTAT_FA) {
+ sc->tx_aborted++;
+ }
+
+ sc->tx_dma[sc->tx_tail].addr = 0;
+ au_sync();
+
+ sc->tx_tail++;
+ if (sc->tx_tail >= NUM_TX_DMA_BUFS) {
+ sc->tx_tail = 0;
+ }
+ }
+ if (tx_flag != 0) {
+ rtems_event_send(sc->tx_daemon_tid, START_TX_EVENT);
+ }
+}
+
diff --git a/c/src/lib/libbsp/mips/csb350/start/regs.S b/c/src/lib/libbsp/mips/csb350/start/regs.S
new file mode 100644
index 0000000000..07ab06ad92
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/start/regs.S
@@ -0,0 +1,138 @@
+/*
+ * regs.S -- standard MIPS register names from
+ * newlib-1.8.2/libgloss/mips and adapted.
+ *
+ * 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.
+ */
+
+/* Standard MIPS register names: */
+#define zero $0
+#define z0 $0
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24
+#define t9 $25
+#define k0 $26 /* kernel private register 0 */
+#define k1 $27 /* kernel private register 1 */
+#define gp $28 /* global data pointer */
+#define sp $29 /* stack-pointer */
+#define fp $30 /* frame-pointer */
+#define ra $31 /* return address */
+#define pc $pc /* pc, used on mips16 */
+
+#define fp0 $f0
+#define fp1 $f1
+
+/* Useful memory constants: */
+#define K0BASE 0x80000000
+#ifndef __mips64
+#define K1BASE 0xA0000000
+#else
+#define K1BASE 0xFFFFFFFFA0000000LL
+#endif
+
+#define PHYS_TO_K1(a) ((unsigned)(a) | K1BASE)
+
+/* Standard Co-Processor 0 register numbers: */
+#define C0_COUNT $9 /* Count Register */
+#define C0_SR $12 /* Status Register */
+#define C0_CAUSE $13 /* last exception description */
+#define C0_EPC $14 /* Exception error address */
+#define C0_CONFIG $16 /* CPU configuration */
+
+/* Standard Status Register bitmasks: */
+#define SR_CU1 0x20000000 /* Mark CP1 as usable */
+#define SR_FR 0x04000000 /* Enable MIPS III FP registers */
+#define SR_BEV 0x00400000 /* Controls location of exception vectors */
+#define SR_PE 0x00100000 /* Mark soft reset (clear parity error) */
+
+#define SR_KX 0x00000080 /* Kernel extended addressing enabled */
+#define SR_SX 0x00000040 /* Supervisor extended addressing enabled */
+#define SR_UX 0x00000020 /* User extended addressing enabled */
+
+/* Standard (R4000) cache operations. Taken from "MIPS R4000
+ Microprocessor User's Manual" 2nd edition: */
+
+#define CACHE_I (0) /* primary instruction */
+#define CACHE_D (1) /* primary data */
+#define CACHE_SI (2) /* secondary instruction */
+#define CACHE_SD (3) /* secondary data (or combined instruction/data) */
+
+#define INDEX_INVALIDATE (0) /* also encodes WRITEBACK if CACHE_D or CACHE_SD */
+#define INDEX_LOAD_TAG (1)
+#define INDEX_STORE_TAG (2)
+#define CREATE_DIRTY_EXCLUSIVE (3) /* CACHE_D and CACHE_SD only */
+#define HIT_INVALIDATE (4)
+#define CACHE_FILL (5) /* CACHE_I only */
+#define HIT_WRITEBACK_INVALIDATE (5) /* CACHE_D and CACHE_SD only */
+#define HIT_WRITEBACK (6) /* CACHE_I, CACHE_D and CACHE_SD only */
+#define HIT_SET_VIRTUAL (7) /* CACHE_SI and CACHE_SD only */
+
+#define BUILD_CACHE_OP(o,c) (((o) << 2) | (c))
+
+/* Individual cache operations: */
+#define INDEX_INVALIDATE_I BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_I)
+#define INDEX_WRITEBACK_INVALIDATE_D BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_D)
+#define INDEX_INVALIDATE_SI BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_SI)
+#define INDEX_WRITEBACK_INVALIDATE_SD BUILD_CACHE_OP(INDEX_INVALIDATE,CACHE_SD)
+
+#define INDEX_LOAD_TAG_I BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_I)
+#define INDEX_LOAD_TAG_D BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_D)
+#define INDEX_LOAD_TAG_SI BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_SI)
+#define INDEX_LOAD_TAG_SD BUILD_CACHE_OP(INDEX_LOAD_TAG,CACHE_SD)
+
+#define INDEX_STORE_TAG_I BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_I)
+#define INDEX_STORE_TAG_D BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_D)
+#define INDEX_STORE_TAG_SI BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_SI)
+#define INDEX_STORE_TAG_SD BUILD_CACHE_OP(INDEX_STORE_TAG,CACHE_SD)
+
+#define CREATE_DIRTY_EXCLUSIVE_D BUILD_CACHE_OP(CREATE_DIRTY_EXCLUSIVE,CACHE_D)
+#define CREATE_DIRTY_EXCLUSIVE_SD BUILD_CACHE_OP(CREATE_DIRTY_EXCLUSIVE,CACHE_SD)
+
+#define HIT_INVALIDATE_I BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_I)
+#define HIT_INVALIDATE_D BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_D)
+#define HIT_INVALIDATE_SI BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_SI)
+#define HIT_INVALIDATE_SD BUILD_CACHE_OP(HIT_INVALIDATE,CACHE_SD)
+
+#define CACHE_FILL_I BUILD_CACHE_OP(CACHE_FILL,CACHE_I)
+#define HIT_WRITEBACK_INVALIDATE_D BUILD_CACHE_OP(HIT_WRITEBACK_INVALIDATE,CACHE_D)
+#define HIT_WRITEBACK_INVALIDATE_SD BUILD_CACHE_OP(HIT_WRITEBACK_INVALIDATE,CACHE_SD)
+
+#define HIT_WRITEBACK_I BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_I)
+#define HIT_WRITEBACK_D BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_D)
+#define HIT_WRITEBACK_SD BUILD_CACHE_OP(HIT_WRITEBACK,CACHE_SD)
+
+#define HIT_SET_VIRTUAL_SI BUILD_CACHE_OP(HIT_SET_VIRTUAL,CACHE_SI)
+#define HIT_SET_VIRTUAL_SD BUILD_CACHE_OP(HIT_SET_VIRTUAL,CACHE_SD)
+
+/*> EOF regs.S <*/
diff --git a/c/src/lib/libbsp/mips/csb350/start/start.S b/c/src/lib/libbsp/mips/csb350/start/start.S
new file mode 100644
index 0000000000..f40e56f912
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/start/start.S
@@ -0,0 +1,125 @@
+/*
+ * start.S -- startup file for Cogent CSB350 Au1100 based board
+ *
+ * Copyright (c) 2005 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ *
+ */
+
+#include <rtems/asm.h>
+#include "regs.S"
+
+ .text
+ .align 2
+
+/* Without the following nop, GDB thinks _start is a data variable.
+ * This is probably a bug in GDB in handling a symbol that is at the
+ * start of the .text section.
+ */
+ nop
+
+ .globl _start
+ .ent _start
+_start:
+ .set noreorder
+
+ /* Get the address of start into $5 in a position independent
+ * fashion. This lets us know whether we have been relocated or not.
+ */
+ $LF1 = . + 8
+ bal $LF1
+ nop
+_branch:
+ move $5, $31 /* $5 == where are we */
+ li $6, 0x8800000c /* $6 == where we want to be */
+
+ li v0, SR_CU1|SR_PE|SR_FR|SR_KX|SR_SX|SR_UX
+ mtc0 v0, C0_SR
+ mtc0 zero, C0_CAUSE
+
+1:
+ li v0, SR_PE|SR_FR|SR_KX|SR_SX|SR_UX
+ mtc0 v0, C0_SR
+2:
+/* Fix high bits, if any, of the PC so that exception handling
+ doesn't get confused. */
+ la v0, 3f
+ jr v0
+ nop
+3:
+ la gp, _gp /* set the global data pointer */
+ .end _start
+
+/*
+ * zero out the bss section.
+ */
+ .globl __memsize
+ .globl zerobss
+ .ent zerobss
+zerobss:
+ la v0, _fbss
+ la v1, _end
+3:
+ sw zero,0(v0)
+ bltu v0,v1,3b
+ addiu v0,v0,4 /* executed in delay slot */
+
+ la t0, _stack_init /* initialize stack so we */
+ /* We must subtract 24 bytes for the 3 8 byte arguments to main, in
+ case main wants to write them back to the stack. The caller is
+ supposed to allocate stack space for parameters in registers in
+ the old MIPS ABIs. We must do this even though we aren't passing
+ arguments, because main might be declared to have them.
+
+ Some ports need a larger alignment for the stack, so we subtract
+ 32, which satisifes the stack for the arguments and keeps the
+ stack pointer better aligned. */
+ subu t0,t0,32
+ move sp,t0 /* set stack pointer */
+ .end zerobss
+
+ .globl exit .text
+ .globl init
+ .ent init
+init:
+
+ move a0,zero /* set argc to 0 */
+ jal boot_card /* call the program start function */
+ nop
+
+ /* fall through to the "exit" routine */
+ jal _sys_exit /* call libc exit to run the G++ */
+ /* destructors */
+ move a0,v0 /* pass through the exit code */
+ .end init
+
+/*
+ * _sys_exit -- Exit from the application. Normally we cause a user trap
+ * to return to the ROM monitor for another run. NOTE: This is
+ * the only other routine we provide in the crt0.o object, since
+ * it may be tied to the "_start" routine. It also allows
+ * executables that contain a complete world to be linked with
+ * just the crt0.o object.
+ */
+ .globl _sys_exit
+ .ent _sys_exit
+_sys_exit:
+7:
+#ifdef GCRT0
+ jal _mcleanup
+ nop
+#endif
+ /* break inst. can cope with 0xfffff, but GAS limits the range: */
+ break 1023
+ nop
+ b 7b /* but loop back just in-case */
+ nop
+ .end _sys_exit
+
+/* EOF crt0.S */
diff --git a/c/src/lib/libbsp/mips/csb350/startup/bspclean.c b/c/src/lib/libbsp/mips/csb350/startup/bspclean.c
new file mode 100644
index 0000000000..783c60f92c
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/startup/bspclean.c
@@ -0,0 +1,30 @@
+/*
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+#include <rtems.h>
+#include <libcpu/au1x00.h>
+
+void bsp_cleanup( void )
+{
+ void (*reset_func)(void);
+
+ reset_func = (void *)0xbfc00000;
+
+ mips_set_sr( 0x00200000 ); /* all interrupts off, boot exception vectors */
+
+ printk("\nEXECUTIVE SHUTDOWN! Any key to reboot...");
+ while (console_inbyte_nonblocking(0) < 0) {
+ continue;
+ }
+
+ /* Try to restart bootloader */
+ reset_func();
+
+}
diff --git a/c/src/lib/libbsp/mips/csb350/startup/bspstart.c b/c/src/lib/libbsp/mips/csb350/startup/bspstart.c
new file mode 100644
index 0000000000..d17cf943b0
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/startup/bspstart.c
@@ -0,0 +1,128 @@
+/*
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include <bsp.h>
+#include <libcpu/au1x00.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+
+/*
+ * The original table from the application and our copy of it with
+ * some changes.
+ */
+
+extern void *_sdram_size;
+extern void *_sdram_base;
+extern void *_bss_free_start;
+
+unsigned long free_mem_start;
+unsigned long free_mem_end;
+
+extern rtems_configuration_table Configuration;
+
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+au1x00_uart_t *uart0 = (au1x00_uart_t *)AU1X00_UART0_ADDR;
+au1x00_uart_t *uart3 = (au1x00_uart_t *)AU1X00_UART3_ADDR;
+
+/*
+ * Use the shared implementations of the following routines
+ */
+
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * Function: bsp_pretasking_hook
+ * Created: 95/03/10
+ *
+ * Description:
+ * BSP pretasking hook. Called just before drivers are initialized.
+ * Used to setup libc and install any BSP extensions.
+ *
+ * NOTES:
+ * Must not use libc (to do io) from here, since drivers are
+ * not yet initialized.
+ *
+ */
+
+void bsp_pretasking_hook(void)
+{
+ unsigned32 heap_start;
+ unsigned32 heap_size;
+
+ /*
+ * Set up the heap.
+ */
+ heap_start = free_mem_start;
+ heap_size = free_mem_end - free_mem_start;
+
+ /* call rtems lib init - malloc stuff */
+ bsp_libc_init((void *)heap_start, heap_size, 0);
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+void bsp_start( void )
+{
+ extern void mips_install_isr_entries(void);
+ unsigned int compare = 0;
+ /* Configure Number of Register Caches */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ Cpu_table.interrupt_stack_size = 8192;
+
+ /* Place RTEMS workspace at beginning of free memory. */
+ BSP_Configuration.work_space_start = (void *)&_bss_free_start;
+
+ free_mem_start = ((unsigned32)&_bss_free_start +
+ BSP_Configuration.work_space_size);
+
+ free_mem_end = ((unsigned32)&_sdram_base + (unsigned32)&_sdram_size);
+
+ mips_set_sr( 0x7f00 ); /* all interrupts unmasked but globally off */
+ /* depend on the IRC to take care of things */
+ asm volatile ("mtc0 %0, $11\n" :: "r" (compare));
+ mips_install_isr_entries();
+}
+
+
+/* These replace the ones in newlib. I'm not sure why the newlib ones
+ * don't work.
+ */
+void _init(void)
+{
+}
+
+void _fini(void)
+{
+}
diff --git a/c/src/lib/libbsp/mips/csb350/startup/linkcmds b/c/src/lib/libbsp/mips/csb350/startup/linkcmds
new file mode 100644
index 0000000000..4d598a2684
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/startup/linkcmds
@@ -0,0 +1,212 @@
+/*
+ * Linker script for CSB350 AU1100 based board
+ *
+ * $Id$
+ */
+
+/* . = 0x80020000; */
+
+/*
+ * Declare some sizes.
+ */
+
+_StackSize = DEFINED(_StackSize) ? _StackSize : 0x4000;
+
+_sdram_base = DEFINED(_sdram_base) ? _sdram_base : 0x80400000;
+_sdram_size = DEFINED(_sdram_size) ? _sdram_size : 12M;
+
+
+MEMORY
+{
+ ram : ORIGIN = 0x80400000, LENGTH = 4M
+}
+
+SECTIONS
+{
+ .text :
+ {
+ _ftext = . ;
+
+ */start.o(.text)
+
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t*)
+ *(.mips16.fn.*)
+ *(.mips16.call.*)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ *(.rel.dyn)
+ PROVIDE (__runtime_reloc_stop = .);
+
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+ } >ram
+
+ .init :
+ {
+ KEEP(*(.init))
+
+ } > ram
+
+ .fini :
+ {
+ KEEP(*(.fini))
+
+ } >ram
+
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+
+ KEEP (*crtbegin.o(.ctors))
+
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >ram
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+
+ etext = .;
+ _etext = .;
+ } >ram
+
+
+
+ .rdata :
+ {
+ *(.rdata)
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r*)
+ } >ram
+
+ .data :
+ {
+ _fdata = ALIGN(16);
+
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ } >ram
+
+ .jcr :
+ {
+ . = ALIGN(8);
+ KEEP (*(.jcr))
+
+ _gp = ALIGN(16) + 0x7440;
+ __global = _gp;
+ } >ram
+
+ .lit8 :
+ {
+ *(.lit8)
+ } >ram
+
+ .lit4 :
+ {
+ *(.lit4)
+ } >ram
+
+ .sdata :
+ {
+ *(.sdata)
+ *(.sdata.*)
+ *(.gnu.linkonce.s*)
+ } >ram
+
+ .sbss :
+ {
+ edata = .;
+ _edata = .;
+ _fbss = .;
+ *(.sbss)
+ *(.scommon)
+ } >ram
+
+
+ .bss :
+ {
+ _bss_start = . ;
+ *(.bss)
+ *(.reginfo)
+ *(COMMON)
+ . = ALIGN (64);
+ _stack_limit = .;
+ . += _StackSize;
+ __stack = .;
+ _stack_init = .;
+ _clear_end = .;
+ end = .;
+ _end = .;
+ . = ALIGN (1024);
+ _bss_free_start = .;
+
+ } >ram
+
+
+/*
+** 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) }
+}
diff --git a/c/src/lib/libbsp/mips/csb350/timer/timer.c b/c/src/lib/libbsp/mips/csb350/timer/timer.c
new file mode 100644
index 0000000000..7dd684db1a
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/timer/timer.c
@@ -0,0 +1,63 @@
+/*
+ * This file implements a benchmark timer using the count/compare
+ * CP0 registers.
+ *
+ * Copyright (c) 2005 by Cogent Computer Systems
+ * Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <assert.h>
+
+#include <bsp.h>
+
+rtems_boolean Timer_driver_Find_average_overhead;
+unsigned32 tstart;
+
+void Timer_initialize()
+{
+ asm volatile ("mfc0 %0, $9\n" : "=r" (tstart));
+ /* tick time in picooseconds */
+}
+
+#define AVG_OVERHEAD 0 /* It typically takes N instructions */
+ /* to start/stop the timer. */
+#define LEAST_VALID 1 /* Don't trust a value lower than this */
+ /* tx39 simulator can count instructions. :) */
+
+int Read_timer()
+{
+ unsigned32 total;
+ unsigned32 cnt;
+
+ asm volatile ("mfc0 %0, $9\n" : "=r" (cnt));
+
+ total = cnt - tstart;
+ total = (total * 1000) / 396; /* convert to nanoseconds */
+
+
+ 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;
+}
+
+rtems_status_code Empty_function( void )
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+void Set_find_average_overhead(
+ rtems_boolean find_flag
+)
+{
+ Timer_driver_Find_average_overhead = find_flag;
+}
diff --git a/c/src/lib/libbsp/mips/csb350/times b/c/src/lib/libbsp/mips/csb350/times
new file mode 100644
index 0000000000..a677a7d660
--- /dev/null
+++ b/c/src/lib/libbsp/mips/csb350/times
@@ -0,0 +1,189 @@
+#
+# Timing Test Suite Results for the Cogent CSB350 Au1100 board
+#
+#
+#
+
+Board: Cogent CSB350
+CPU: AMD Au1500 - MIPS32
+Clock Speed: 396 MHz
+Memory Configuration: SDRAM, 32 bits wide
+Cache: Data and Instruction caches enabled
+Times Reported in: nanoseconds
+Timer Source: Count/Compare registers - 2.5 ns resolution
+
+All tests were compiled with VARIANT=DEBUG
+
+
+
+== =================================================================== =======
+ 1 rtems_semaphore_create 22494
+ 1 rtems_semaphore_delete 13202
+ 1 rtems_semaphore_obtain: available 739
+ 1 rtems_semaphore_obtain: not available -- NO_WAIT 740
+ 1 rtems_semaphore_release: no waiting tasks 1361
+
+ 2 rtems_semaphore_obtain: not available -- caller blocks 14576
+
+ 3 rtems_semaphore_release: task readied -- preempts caller 9856
+
+ 4 rtems_task_restart: blocked task -- preempts caller 43186
+ 4 rtems_task_restart: ready task -- preempts caller 35931
+ 4 rtems_semaphore_release: task readied -- returns to caller 3459
+ 4 rtems_task_create 11992
+ 4 rtems_task_start 10280
+ 4 rtems_task_restart: suspended task -- returns to caller 5449
+ 4 rtems_task_delete: suspended task 19273
+ 4 rtems_task_restart: ready task -- returns to caller 5791
+ 4 rtems_task_restart: blocked task -- returns to caller 11807
+ 4 rtems_task_delete: blocked task 19716
+
+ 5 rtems_task_suspend: calling task 8541
+ 5 rtems_task_resume: task readied -- preempts caller 5892
+
+ 6 rtems_task_restart: calling task 7337
+ 6 rtems_task_suspend: returns to caller 2658
+ 6 rtems_task_resume: task readied -- returns to caller 2370
+ 6 rtems_task_delete: ready task 13881
+
+ 7 rtems_task_restart: suspended task -- preempts caller 10148
+
+ 8 rtems_task_set_priority: obtain current priority 966
+ 8 rtems_task_set_priority: returns to caller 2861
+ 8 rtems_task_mode: obtain current mode 610
+ 8 rtems_task_mode: no reschedule 847
+ 8 rtems_task_mode: reschedule -- returns to caller 7803
+ 8 rtems_task_mode: reschedule -- preempts caller 18542
+ 8 rtems_task_set_note 1044
+ 8 rtems_task_get_note 1046
+ 8 rtems_clock_set 2777
+ 8 rtems_clock_get 161
+
+ 9 rtems_message_queue_create 42141
+ 9 rtems_message_queue_send: no waiting tasks 2130
+ 9 rtems_message_queue_urgent: no waiting tasks 2158
+ 9 rtems_message_queue_receive: available 2306
+ 9 rtems_message_queue_flush: no messages flushed 767
+ 9 rtems_message_queue_flush: messages flushed 1418
+ 9 rtems_message_queue_delete 22095
+
+10 rtems_message_queue_receive: not available -- NO_WAIT 1077
+10 rtems_message_queue_receive: not available -- caller blocks 11449
+
+11 rtems_message_queue_send: task readied -- preempts caller 11392
+
+12 rtems_message_queue_send: task readied -- returns to caller 3897
+
+13 rtems_message_queue_urgent: task readied -- preempts caller 11398
+
+14 rtems_message_queue_urgent: task readied -- returns to caller 3914
+
+15 rtems_event_receive: obtain current events 148
+15 rtems_event_receive: not available -- NO_WAIT 881
+15 rtems_event_receive: not available -- caller blocks 10325
+15 rtems_event_send: no task readied 1112
+15 rtems_event_receive: available 3929
+15 rtems_event_send: task readied -- returns to caller 4129
+
+16 rtems_event_send: task readied -- preempts caller 9755
+
+17 rtems_task_set_priority: preempts caller 10202
+
+18 rtems_task_delete: calling task 20853
+
+19 rtems_signal_catch 2055
+19 rtems_signal_send: returns to caller 9116
+19 rtems_signal_send: signal to self 21898
+19 exit ASR overhead: returns to calling task 14128
+19 exit ASR overhead: returns to preempting task 10184
+
+20 rtems_partition_create 21095
+20 rtems_region_create 31772
+20 rtems_partition_get_buffer: available 7457
+20 rtems_partition_get_buffer: not available 1558
+20 rtems_partition_return_buffer 8669
+20 rtems_partition_delete 6838
+20 rtems_region_get_segment: available 4560
+20 rtems_region_get_segment: not available -- NO_WAIT 10515
+20 rtems_region_return_segment: no waiting tasks 4535
+20 rtems_region_get_segment: not available -- caller blocks 42441
+20 rtems_region_return_segment: task readied -- preempts caller 54260
+20 rtems_region_return_segment: task readied -- returns to caller 32868
+20 rtems_region_delete 13815
+20 rtems_io_initialize 1571
+20 rtems_io_open 121
+20 rtems_io_close 122
+20 rtems_io_read 119
+20 rtems_io_write 108
+20 rtems_io_control 217
+
+21 rtems_task_ident 10887
+21 rtems_message_queue_ident 9201
+21 rtems_semaphore_ident 10578
+21 rtems_partition_ident 9186
+21 rtems_region_ident 9401
+21 rtems_port_ident 9287
+21 rtems_timer_ident 9212
+21 rtems_rate_monotonic_ident 9207
+
+22 rtems_message_queue_broadcast: task readied -- returns to caller 24479
+22 rtems_message_queue_broadcast: no waiting tasks 1310
+22 rtems_message_queue_broadcast: task readied -- preempts caller 25436
+
+23 rtems_timer_create 1572
+23 rtems_timer_fire_after: inactive 2391
+23 rtems_timer_fire_after: active 17664
+23 rtems_timer_cancel: active 1145
+23 rtems_timer_cancel: inactive 894
+23 rtems_timer_reset: inactive 2035
+23 rtems_timer_reset: active 17515
+23 rtems_timer_fire_when: inactive 2684
+23 rtems_timer_fire_when: active 2707
+23 rtems_timer_delete: active 1794
+23 rtems_timer_delete: inactive 1530
+23 rtems_task_wake_when 10682
+
+24 rtems_task_wake_after: yield -- returns to caller 702
+24 rtems_task_wake_after: yields -- preempts caller 7552
+
+25 rtems_clock_tick 10512
+26 _ISR_Disable 858
+26 _ISR_Flash 833
+26 _ISR_Enable 318
+26 _Thread_Disable_dispatch 633
+26 _Thread_Enable_dispatch 507
+26 _Thread_Set_state 7666
+26 _Thread_Disptach (NO FP) 9098
+26 context switch: no floating point contexts 6181
+26 context switch: self 568
+26 context switch: to another task 997
+26 fp context switch: restore 1st FP task - NA
+26 fp context switch: save idle, restore initialized - NA
+26 fp context switch: save idle, restore idle - NA
+26 fp context switch: save initialized, restore initialized - NA
+26 _Thread_Resume 10434
+26 _Thread_Unblock 7911
+26 _Thread_Ready 1911
+26 _Thread_Get 545
+26 _Semaphore_Get 289
+26 _Thread_Get: invalid id 272
+
+27 interrupt entry overhead: returns to interrupted task 7713
+27 interrupt exit overhead: returns to interrupted task 3905
+27 interrupt entry overhead: returns to nested interrupt 861
+27 interrupt exit overhead: returns to nested interrupt 401
+27 interrupt entry overhead: returns to preempting task 1503
+27 interrupt exit overhead: returns to preempting task 15285
+
+28 rtems_port_create 15335
+28 rtems_port_external_to_internal 779
+28 rtems_port_internal_to_external 773
+28 rtems_port_delete 9310
+
+29 rtems_rate_monotonic_create 11171
+29 rtems_rate_monotonic_period: initiate period -- returns to caller 15247
+29 rtems_rate_monotonic_period: obtain status 4222
+29 rtems_rate_monotonic_cancel 7868
+29 rtems_rate_monotonic_delete: inactive 11133
+29 rtems_rate_monotonic_delete: active 7848
+29 rtems_rate_monotonic_period: conclude periods -- caller blocks 8082