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:
Jay Monkman
2005-02-25 05:18:07 +00:00
parent fe36adfe8c
commit 7cde240ce8
18 changed files with 2366 additions and 0 deletions

View File

@@ -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.

View File

@@ -2,6 +2,8 @@
AC_DEFUN([RTEMS_CHECK_BSPDIR],
[
case "$1" in
csb350 )
AC_CONFIG_SUBDIRS([csb350]);;
genmongoosev )
AC_CONFIG_SUBDIRS([genmongoosev]);;
jmr3904 )

View 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

View 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

View 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 }

View 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"

View 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

View 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;

View 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 */

View 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

View 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);
}
}

View 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 <*/

View 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 */

View 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();
}

View 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)
{
}

View 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) }
}

View 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;
}

View 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