forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
AC_DEFUN([RTEMS_CHECK_BSPDIR],
|
||||
[
|
||||
case "$1" in
|
||||
csb350 )
|
||||
AC_CONFIG_SUBDIRS([csb350]);;
|
||||
genmongoosev )
|
||||
AC_CONFIG_SUBDIRS([genmongoosev]);;
|
||||
jmr3904 )
|
||||
|
||||
178
c/src/lib/libbsp/mips/csb350/Makefile.am
Normal file
178
c/src/lib/libbsp/mips/csb350/Makefile.am
Normal file
@@ -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
|
||||
6
c/src/lib/libbsp/mips/csb350/README
Normal file
6
c/src/lib/libbsp/mips/csb350/README
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# README,v 1.4 2000/12/13 22:16:27 joel Exp
|
||||
#
|
||||
|
||||
BSP for the Cogent CSB350 Au1500 based board
|
||||
|
||||
26
c/src/lib/libbsp/mips/csb350/bsp_specs
Normal file
26
c/src/lib/libbsp/mips/csb350/bsp_specs
Normal file
@@ -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 }
|
||||
81
c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
Normal file
81
c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
Normal file
@@ -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"
|
||||
23
c/src/lib/libbsp/mips/csb350/configure.ac
Normal file
23
c/src/lib/libbsp/mips/csb350/configure.ac
Normal file
@@ -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
|
||||
89
c/src/lib/libbsp/mips/csb350/console/console-io.c
Normal file
89
c/src/lib/libbsp/mips/csb350/console/console-io.c
Normal file
@@ -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;
|
||||
|
||||
113
c/src/lib/libbsp/mips/csb350/include/bsp.h
Normal file
113
c/src/lib/libbsp/mips/csb350/include/bsp.h
Normal file
@@ -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 */
|
||||
63
c/src/lib/libbsp/mips/csb350/include/tm27.h
Normal file
63
c/src/lib/libbsp/mips/csb350/include/tm27.h
Normal file
@@ -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
|
||||
889
c/src/lib/libbsp/mips/csb350/network/network.c
Normal file
889
c/src/lib/libbsp/mips/csb350/network/network.c
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
138
c/src/lib/libbsp/mips/csb350/start/regs.S
Normal file
138
c/src/lib/libbsp/mips/csb350/start/regs.S
Normal file
@@ -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 <*/
|
||||
125
c/src/lib/libbsp/mips/csb350/start/start.S
Normal file
125
c/src/lib/libbsp/mips/csb350/start/start.S
Normal file
@@ -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 */
|
||||
30
c/src/lib/libbsp/mips/csb350/startup/bspclean.c
Normal file
30
c/src/lib/libbsp/mips/csb350/startup/bspclean.c
Normal file
@@ -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();
|
||||
|
||||
}
|
||||
128
c/src/lib/libbsp/mips/csb350/startup/bspstart.c
Normal file
128
c/src/lib/libbsp/mips/csb350/startup/bspstart.c
Normal file
@@ -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)
|
||||
{
|
||||
}
|
||||
212
c/src/lib/libbsp/mips/csb350/startup/linkcmds
Normal file
212
c/src/lib/libbsp/mips/csb350/startup/linkcmds
Normal file
@@ -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) }
|
||||
}
|
||||
63
c/src/lib/libbsp/mips/csb350/timer/timer.c
Normal file
63
c/src/lib/libbsp/mips/csb350/timer/timer.c
Normal file
@@ -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;
|
||||
}
|
||||
189
c/src/lib/libbsp/mips/csb350/times
Normal file
189
c/src/lib/libbsp/mips/csb350/times
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user