* .cvsignore, ChangeLog, Makefile.am, README, bsp_specs, configure.ac,
	clock/clock.c, console/console.c, include/bsp.h, include/coverhd.h,
	include/tm27.h, network/network.c, start/start.S, startup/bspclean.c,
	startup/bspstart.c, startup/init5235.c, startup/linkcmds,
	startup/linkcmdsflash, startup/linkcmdsram, timer/timer.c: New files.
This commit is contained in:
Joel Sherrill
2005-06-17 14:06:05 +00:00
parent 1469b45b5d
commit 1612af0f62
20 changed files with 3885 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
aclocal.m4
autom4te*.cache
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
Makefile
Makefile.in
missing
mkinstalldirs

View File

@@ -0,0 +1,8 @@
2005-06-17 Mike Bertosh <mbertosh@motioncontrol.org>
* .cvsignore, ChangeLog, Makefile.am, README, bsp_specs, configure.ac,
clock/clock.c, console/console.c, include/bsp.h, include/coverhd.h,
include/tm27.h, network/network.c, start/start.S, startup/bspclean.c,
startup/bspstart.c, startup/init5235.c, startup/linkcmds,
startup/linkcmdsflash, startup/linkcmdsram, timer/timer.c: New files.

View File

@@ -0,0 +1,121 @@
##
## $Id$
##
ACLOCAL_AMFLAGS = -I ../../../../aclocal
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
DISTCLEANFILES = include/bspopts.h
noinst_PROGRAMS =
include_HEADERS += include/coverhd.h
EXTRA_DIST = start/start.S
start.$(OBJEXT): start/start.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
project_lib_DATA = start.$(OBJEXT)
dist_project_lib_DATA += startup/linkcmds
noinst_PROGRAMS += startup.rel
startup_rel_SOURCES = startup/bspclean.c \
../../shared/bsplibc.c ../../shared/bsppost.c \
../../m68k/shared/m68kpretaskinghook.c \
startup/init5235.c startup/bspstart.c \
../../shared/bootcard.c ../../shared/main.c \
../../shared/sbrk.c ../../m68k/shared/setvec.c \
../../shared/gnatinstallhandler.c
startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += clock.rel
clock_rel_SOURCES = clock/clock.c
clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += console.rel
console_rel_SOURCES = console/console.c
console_rel_CPPFLAGS = $(AM_CPPFLAGS)
console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += timer.rel
timer_rel_SOURCES = timer/timer.c
timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
if HAS_NETWORKING
network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
noinst_PROGRAMS += network.rel
network_rel_SOURCES = network/network.c
network_rel_CPPFLAGS = $(AM_CPPFLAGS) \
$(network_CPPFLAGS)
network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
noinst_LIBRARIES = libbsp.a
libbsp_a_SOURCES =
libbsp_a_LIBADD = startup.rel clock.rel console.rel timer.rel
if HAS_NETWORKING
libbsp_a_LIBADD += network.rel
endif
libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
../../../libcpu/@RTEMS_CPU@/shared/misc.rel
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: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(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,454 @@
#
# $Id$
#
Description: Motorola MCF5235EVB
============
CPU: MCF5235, 150MHz
RAM: 16M
ROM: 2M
This is a Motorola evaluation board that uses the MCF5235 Coldfire CPU.
This board is running at 150MHz scaled from a 25MHz oscillator.
ACKNOWLEDGEMENTS:
=================
This BSP is heavily based on the work of:
D. Peter Siddons
Brett Swimley
Jay Monkman
Eric Norum
Mike Bertosh
BSP NAME: mcf5235
BOARD: Motorola MCF5235EVB
CPU FAMILY: ColdFire 5235
CPU: MCF5235
COPROCESSORS: N/A
DEBUG MONITOR: dBUG
PERIPHERALS
===========
TIMERS: Four PIT (RTEMS clock is PIT3), Four Timers
RESOLUTION: 10 microsecond
SERIAL PORTS: Internal UART 1, 2 and 3
REAL-TIME CLOCK: none
DMA: none
VIDEO: none
SCSI: none
NETWORKING: Internal 10/100MHz FEC
DRIVER INFORMATION
==================
CLOCK DRIVER: PIT3
IOSUPP DRIVER: none
SHMSUPP: none
TIMER DRIVER: TIMER3
TTY DRIVER: UART1, 2 and 3
STDIO
=====
PORT: UART0 Terminal
ELECTRICAL: RS-232
BAUD: 19200
BITS PER CHARACTER: 8
PARITY: None
STOP BITS: 1
Memory map as set up by dBUG bootstrap and BSP initialization
+--------------------------------------------------+
0000 0000 | 16 MByte SDRAM | 00FF FFFF
0100 0000 | --------------------------------------------- |
| Address space for future SDRAM expansion |
. .
. .
. .
| | 0FFF FFFF
+--------------------------------------------------+
1000 0000 | |
. .
. .
. .
| | 1FFF FFFF
+--------------------------------------------------+
2000 0000 | 64 kByte on-chip SRAM (RAMBAR) |
. .
. .
. .
| | 2FFF FFFF
+--------------------------------------------------+
3000 0000 | | 30FF FFFF
. .
. .
. .
. .
| | 3FFF FFFF
+--------------------------------------------------+
4000 0000 | Internal peripheral system (IPSBAR) |
. .
| |
. .
. .
. .
| | 4FFF FFFF
+--------------------------------------------------+
. .
. .
. .
+--------------------------------------------------+
FFE0 0000 | External 4 MByte Flash |
. .
. .
. .
| | FFFF FFFF
+--------------------------------------------------+
============================================================================
Interrupt map
+-----+-----------------------------------------------------------------------+
| | PRIORITY |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
|LEVEL| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 7 | | | | | | | | |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 6 | | | | | | | | |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 5 | | | | | | | | |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 4 | FEC RX | FEC TX | | | | | | PIT |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 3 | UART 0 | UART 1 | UART 2 | | | | | |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 2 | | | | | | | | |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
| 1 | | | | | | | | |
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
============================================================================
TIMING TESTS
************************************
*** TIME TEST 1 ***
rtems_semaphore_create 12
rtems_semaphore_delete 11
rtems_semaphore_obtain: available 2
rtems_semaphore_obtain: not available -- NO_WAIT 3
rtems_semaphore_release: no waiting tasks 6
*** END OF TEST 1 ***
*** TIME TEST 2 ***
rtems_semaphore_obtain: not available -- caller blocks 18
*** END OF TEST 2 ***
*** TIME TEST 3 ***
rtems_semaphore_release: task readied -- preempts caller 12
*** END OF TEST 3 ***
*** TIME TEST 4 ***
rtems_task_restart: blocked task -- preempts caller 31
rtems_task_restart: ready task -- preempts caller 30
rtems_semaphore_release: task readied -- returns to caller 8
rtems_task_create 45
rtems_task_start 9
rtems_task_restart: suspended task -- returns to caller 14
rtems_task_delete: suspended task 32
rtems_task_restart: ready task -- returns to caller 14
rtems_task_restart: blocked task -- returns to caller 21
rtems_task_delete: blocked task 32
*** END OF TEST 4 ***
*** TIME TEST 5 ***
rtems_task_suspend: calling task 15
rtems_task_resume: task readied -- preempts caller 9
*** END OF TEST 5 ***
*** TIME TEST 6 ***
rtems_task_restart: calling task 12
rtems_task_suspend: returns to caller 5
rtems_task_resume: task readied -- returns to caller 6
rtems_task_delete: ready task 34
*** END OF TEST 6 ***
*** TIME TEST 7 ***
rtems_task_restart: suspended task -- preempts caller 22
*** END OF TEST 7 ***
*** TIME TEST 8 ***
rtems_task_set_priority: obtain current priority 4
rtems_task_set_priority: returns to caller 9
rtems_task_mode: obtain current mode 1
rtems_task_mode: no reschedule 1
rtems_task_mode: reschedule -- returns to caller 3
rtems_task_mode: reschedule -- preempts caller 11
rtems_task_set_note 3
rtems_task_get_note 3
rtems_clock_set 9
rtems_clock_get 0
*** END OF TEST 8 ***
*** TIME TEST 9 ***
rtems_message_queue_create 37
rtems_message_queue_send: no waiting tasks 11
rtems_message_queue_urgent: no waiting tasks 10
rtems_message_queue_receive: available 10
rtems_message_queue_flush: no messages flushed 3
rtems_message_queue_flush: messages flushed 5
rtems_message_queue_delete 17
*** END OF TEST 9 ***
*** TIME TEST 10 ***
rtems_message_queue_receive: not available -- NO_WAIT 6
rtems_message_queue_receive: not available -- caller blocks 20
*** END OF TEST 10 ***
*** TIME TEST 11 ***
rtems_message_queue_send: task readied -- preempts caller 17
*** END OF TEST 11 ***
*** TIME TEST 12 ***
rtems_message_queue_send: task readied -- returns to caller 12
*** END OF TEST 12 ***
*** TIME TEST 13 ***
rtems_message_queue_urgent: task readied -- preempts caller 20
*** END OF TEST 13 ***
*** TIME TEST 14 ***
rtems_message_queue_urgent: task readied -- returns to caller 14
*** END OF TEST 14 ***
*** TIME TEST 15 ***
rtems_event_receive: obtain current events 0
rtems_event_receive: not available -- NO_WAIT 3
rtems_event_receive: not available -- caller blocks 18
rtems_event_send: no task readied 3
rtems_event_receive: available 5
rtems_event_send: task readied -- returns to caller 7
*** END OF TEST 15 ***
*** TIME TEST 16 ***
rtems_event_send: task readied -- preempts caller 12
*** END OF TEST 16 ***
*** TIME TEST 17 ***
rtems_task_set_priority: preempts caller 21
*** END OF TEST 17 ***
*** TIME TEST 18 ***
rtems_task_delete: calling task 40
*** END OF TEST 18 ***
*** TIME TEST 19 ***
rtems_signal_catch 3
rtems_signal_send: returns to caller 6
rtems_signal_send: signal to self 11
exit ASR overhead: returns to calling task 8
exit ASR overhead: returns to preempting task 10
*** END OF TEST 19 ***
*** TIME TEST 20 ***
rtems_partition_create 13
rtems_region_create 24
rtems_partition_get_buffer: available 6
rtems_partition_get_buffer: not available 4
rtems_partition_return_buffer 6
rtems_partition_delete 6
rtems_region_get_segment: available 12
rtems_region_get_segment: not available -- NO_WAIT 13
rtems_region_return_segment: no waiting tasks 12
rtems_region_get_segment: not available -- caller blocks 30
rtems_region_return_segment: task readied -- preempts caller 40
rtems_region_return_segment: task readied -- returns to caller 25
rtems_region_delete 12
rtems_io_initialize 0
rtems_io_open 0
rtems_io_close 0
rtems_io_read 0
rtems_io_write 0
rtems_io_control 0
*** END OF TEST 20 ***
*** TIME TEST 21 ***
rtems_task_ident 31
rtems_message_queue_ident 30
rtems_semaphore_ident 34
rtems_partition_ident 30
rtems_region_ident 30
rtems_port_ident 29
rtems_timer_ident 30
rtems_rate_monotonic_ident 30
*** END OF TEST 21 ***
*** TIME TEST 22 ***
rtems_message_queue_broadcast: task readied -- returns to caller 19
rtems_message_queue_broadcast: no waiting tasks 6
rtems_message_queue_broadcast: task readied -- preempts caller 20
*** END OF TEST 22 ***
*** TIME TEST 23 ***
rtems_timer_create 4
rtems_timer_fire_after: inactive 6
rtems_timer_fire_after: active 6
rtems_timer_cancel: active 4
rtems_timer_cancel: inactive 3
rtems_timer_reset: inactive 6
rtems_timer_reset: active 6
rtems_timer_fire_when: inactive 8
rtems_timer_fire_when: active 8
rtems_timer_delete: active 5
rtems_timer_delete: inactive 5
rtems_task_wake_when 16
*** END OF TEST 23 ***
*** TIME TEST 24 ***
rtems_task_wake_after: yield -- returns to caller 2
rtems_task_wake_after: yields -- preempts caller 12
*** END OF TEST 24 ***
*** TIME TEST 25 ***
rtems_clock_tick 4
*** END OF TEST 25 ***
*** TIME TEST 26 ***
_ISR_Disable 0
_ISR_Flash 0
_ISR_Enable 0
_Thread_Disable_dispatch 0
_Thread_Enable_dispatch 1
_Thread_Set_state 4
_Thread_Disptach (NO FP) 9
context switch: no floating point contexts 7
context switch: self 1
context switch: to another task 1
fp context switch: restore 1st FP task 6
fp context switch: save idle, restore initialized 2
fp context switch: save idle, restore idle 6
fp context switch: save initialized, restore initialized 1
_Thread_Resume 4
_Thread_Unblock 3
_Thread_Ready 2
_Thread_Get 0
_Semaphore_Get 0
_Thread_Get: invalid id 0
*** END OF TEST 26 ***
*** TIME TEST 27 ***
interrupt entry overhead: returns to interrupted task 2
interrupt exit overhead: returns to interrupted task 1
interrupt entry overhead: returns to nested interrupt 1
interrupt exit overhead: returns to nested interrupt 1
interrupt entry overhead: returns to preempting task 2
interrupt exit overhead: returns to preempting task 12
*** END OF TEST 27 ***
*** TIME TEST 28 ***
rtems_port_create 8
rtems_port_external_to_internal 2
rtems_port_internal_to_external 3
rtems_port_delete 7
*** END OF TEST 28 ***
*** TIME TEST 29 ***
rtems_rate_monotonic_create 8
rtems_rate_monotonic_period: initiate period -- returns to caller 12
rtems_rate_monotonic_period: obtain status 5
rtems_rate_monotonic_cancel 7
rtems_rate_monotonic_delete: inactive 8
rtems_rate_monotonic_delete: active 7
rtems_rate_monotonic_period: conclude periods -- caller blocks 11
*** END OF TEST 29 ***
*** TIME CHECKER ***
Units may not be in microseconds for this test!!!
0 100000
Total time = 0
Average time = 0
<pause>
NULL timer stopped at 0
LOOP (1000) timer stopped at 94
LOOP (10000) timer stopped at 941
LOOP (50000) timer stopped at 4704
LOOP (100000) timer stopped at 9408
*** END OF TIME CHECKER ***
*** TIME TEST OVERHEAD ***
rtems_initialize_executive 0
rtems_shutdown_executive 0
rtems_task_create 0
rtems_task_ident 0
rtems_task_start 0
rtems_task_restart 0
rtems_task_delete 0
rtems_task_suspend 0
rtems_task_resume 0
rtems_task_set_priority 0
rtems_task_mode 0
rtems_task_get_note 0
rtems_task_set_note 0
rtems_task_wake_when 0
rtems_task_wake_after 0
rtems_interrupt_catch 0
rtems_clock_get 0
rtems_clock_set 0
rtems_clock_tick 0
<pause>
rtems_timer_create 0
rtems_timer_delete 0
rtems_timer_ident 0
rtems_timer_fire_after 0
rtems_timer_fire_when 0
rtems_timer_reset 0
rtems_timer_cancel 0
rtems_semaphore_create 0
rtems_semaphore_delete 0
rtems_semaphore_ident 0
rtems_semaphore_obtain 0
rtems_semaphore_release 0
rtems_message_queue_create 0
rtems_message_queue_ident 0
rtems_message_queue_delete 0
rtems_message_queue_send 0
rtems_message_queue_urgent 0
rtems_message_queue_broadcast 0
rtems_message_queue_receive 0
rtems_message_queue_flush 0
<pause>
rtems_event_send 0
rtems_event_receive 0
rtems_signal_catch 0
rtems_signal_send 0
rtems_partition_create 0
rtems_partition_ident 0
rtems_partition_delete 0
rtems_partition_get_buffer 0
rtems_partition_return_buffer 0
rtems_region_create 0
rtems_region_ident 0
rtems_region_delete 0
rtems_region_get_segment 0
rtems_region_return_segment 0
rtems_port_create 0
rtems_port_ident 0
rtems_port_delete 0
rtems_port_external_to_internal 0
rtems_port_internal_to_external 0
<pause>
rtems_io_initialize 0
rtems_io_open 0
rtems_io_close 0
rtems_io_read 0
rtems_io_write 0
rtems_io_control 0
rtems_fatal_error_occurred 0
rtems_rate_monotonic_create 0
rtems_rate_monotonic_ident 0
rtems_rate_monotonic_delete 0
rtems_rate_monotonic_cancel 0
rtems_rate_monotonic_period 0
rtems_multiprocessing_announce 0
*** END OF TIME OVERHEAD ***

View File

@@ -0,0 +1,16 @@
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*startfile:
%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \
%{!qrtems_debug: start.o%s} \
%{qrtems_debug: start_g.o%s} \
crti.o%s crtbegin.o%s}}
*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,63 @@
/*
* Use the last periodic interval timer (PIT3) as the system clock.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <mcf5235/mcf5235.h>
/*
* Use INTC0 base
*/
#define CLOCK_VECTOR (64+39)
/*
* Periodic interval timer interrupt handler
*/
#define Clock_driver_support_at_tick() \
do { \
MCF5235_PIT_PCSR3 |= MCF5235_PIT_PCSR_PIF; \
} while (0) \
/*
* Attach clock interrupt handler
*/
#define Clock_driver_support_install_isr( _new, _old ) \
do { \
_old = (rtems_isr_entry)set_vector(_new, CLOCK_VECTOR, 1); \
} while(0)
/*
* Turn off the clock
*/
#define Clock_driver_support_shutdown_hardware() \
do { \
MCF5235_PIT_PCSR3 &= ~MCF5235_PIT_PCSR_EN; \
} while(0)
/*
* Set up the clock hardware
*
* We need to have 1 interrupt every 10,000 microseconds
* so we need to set prescaler to 64 and the PMR register to 0x2DC6
*/
#define Clock_driver_support_initialize_hardware() \
do { \
int level; \
int preScaleCode = 6; \
MCF5235_INTC0_ICR39 = MCF5235_INTC_ICR_IL(PIT3_IRQ_LEVEL) | \
MCF5235_INTC_ICR_IP(PIT3_IRQ_PRIORITY); \
rtems_interrupt_disable( level ); \
MCF5235_INTC0_IMRH &= ~MCF5235_INTC0_IMRH_INT39; \
MCF5235_PIT_PCSR3 &= ~MCF5235_PIT_PCSR_EN; \
rtems_interrupt_enable( level ); \
MCF5235_PIT_PMR3 = 0x2DC6; \
MCF5235_PIT_PCSR3 = MCF5235_PIT_PCSR_PRE(preScaleCode) | \
MCF5235_PIT_PCSR_PIE | \
MCF5235_PIT_PCSR_RLD | \
MCF5235_PIT_PCSR_EN; \
} while (0)
#include "../../../shared/clockdrv_shell.c"

View File

@@ -0,0 +1,24 @@
## Process this file with autoconf to produce a configure script.
##
## $Id$
AC_PREREQ(2.59)
AC_INIT([rtems-c-src-lib-libbsp-m68k-mcf5235],[_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.9])
RTEMS_BSP_CONFIGURE
RTEMS_PROG_CC_FOR_TARGET
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,799 @@
/*
* Multi UART console serial I/O.
*
* TO DO: Add DMA input/output
*/
#include <stdio.h>
#include <fcntl.h>
#include <rtems/libio.h>
#include <rtems/termiostypes.h>
#include <termios.h>
#include <bsp.h>
#include <malloc.h>
#include <rtems/mw_uid.h>
#include <rtems/bspIo.h>
#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x))
#define MCF5235_UART_USR_ERROR ( MCF5235_UART_USR_RB | \
MCF5235_UART_USR_FE | \
MCF5235_UART_USR_PE | \
MCF5235_UART_USR_OE )
static int IntUartPollWrite(int minor, const char *buf, int len);
static int IntUartInterruptWrite (int minor, const char *buf, int len);
static void
_BSP_null_char( char c )
{
int level;
if (c == '\n')
_BSP_null_char('\r');
rtems_interrupt_disable(level);
while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 )
continue;
MCF5235_UART_UTB(CONSOLE_PORT) = c;
while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 )
continue;
rtems_interrupt_enable(level);
}
BSP_output_char_function_type BSP_output_char = _BSP_null_char;
#define MAX_UART_INFO 3
#define RX_BUFFER_SIZE 512
struct IntUartInfoStruct
{
int iomode;
volatile int uimr;
int baud;
int databits;
int parity;
int stopbits;
int hwflow;
int rx_in;
int rx_out;
char rx_buffer[RX_BUFFER_SIZE];
void *ttyp;
};
struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
static int GetBaud( int baudHandle )
{
int baud = 9600;
switch ( baudHandle )
{
case B0:
baud = (int)0;
break;
case B1200:
baud = (int)1200;
break;
case B2400:
baud = (int)2400;
break;
case B4800:
baud = (int)4800;
break;
case B9600:
baud = (int)9600;
break;
case B19200:
baud = (int)19200;
break;
case B38400:
baud = (int)38400;
break;
case B57600:
baud = (int)57600;
break;
case B115200:
baud = (int)115200;
break;
}
return ( baud );
}
/***************************************************************************
Function : IntUartSet
Description : This updates the hardware UART settings.
***************************************************************************/
static void
IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow)
{
int divisor;
unsigned32 clock_speed;
unsigned8 umr1 = 0;
unsigned8 umr2 = 0;
struct IntUartInfoStruct *info = &IntUartInfo[minor];
int level;
rtems_interrupt_disable(level);
/* disable interrupts, clear RTS line, and disable the UARTS */
MCF5235_UART_UIMR(minor) = 0;
MCF5235_UART_UOP0(minor) = 1;
MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED);
/* save the current values */
info->uimr = 0;
info->baud = baud;
info->databits = databits;
info->parity = parity;
info->stopbits = stopbits;
info->hwflow = hwflow;
clock_speed = get_CPU_clock_speed();
/* determine the baud divisor value */
divisor = ((clock_speed/2) / ( 32 * baud ));
if ( divisor < 2 )
divisor = 2;
/* check to see if doing hardware flow control */
if ( hwflow )
{
/* set hardware flow options */
umr1 |= MCF5235_UART_UMR_RXRTS;
umr2 |= MCF5235_UART_UMR_TXCTS;
}
/* determine the new umr values */
umr1 |= (parity | databits);
umr2 |= (stopbits);
/* reset the uart */
MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_ERROR;
MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_RX;
MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_TX;
/* reset the uart mode register and update values */
MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_MR;
MCF5235_UART_UMR(minor) = umr1;
MCF5235_UART_UMR(minor) = umr2;
/* set the baud rate values */
MCF5235_UART_UCSR(minor) = (MCF5235_UART_UCSR_RCS_SYS_CLK | MCF5235_UART_UCSR_TCS_SYS_CLK);
MCF5235_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
MCF5235_UART_UBG2(minor) = (divisor & 0x00ff);
/* enable the uart */
MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED);
/* check to see if interrupts need to be enabled */
if ( info->iomode != TERMIOS_POLLED )
{
/* enable rx interrupts */
info->uimr |= MCF5235_UART_UIMR_FFULL;
MCF5235_UART_UIMR(minor) = info->uimr;
}
/* check to see if doing hardware flow control */
if ( hwflow )
{
/* assert the RTS line */
MCF5235_UART_UOP1(minor) = 1;
}
rtems_interrupt_enable(level);
}
/***************************************************************************
Function : IntUartSetAttributes
Description : This provides the hardware-dependent portion of tcsetattr().
value and sets it. At the moment this just sets the baud rate.
Note: The highest baudrate is 115200 as this stays within
an error of +/- 5% at 25MHz processor clock
***************************************************************************/
static int
IntUartSetAttributes(int minor, const struct termios *t)
{
/* set default index values */
int baud = (int)19200;
int databits = (int)MCF5235_UART_UMR_BC_8;
int parity = (int)MCF5235_UART_UMR_PM_NONE;
int stopbits = (int)MCF5235_UART_UMR_STOP_BITS_1;
int hwflow = (int)0;
struct IntUartInfoStruct *info = &IntUartInfo[minor];
/* check to see if input is valid */
if ( t != (const struct termios *)0 )
{
/* determine baud rate index */
baud = GetBaud( t->c_cflag & CBAUD );
/* determine data bits */
switch ( t->c_cflag & CSIZE )
{
case CS5:
databits = (int)MCF5235_UART_UMR_BC_5;
break;
case CS6:
databits = (int)MCF5235_UART_UMR_BC_6;
break;
case CS7:
databits = (int)MCF5235_UART_UMR_BC_7;
break;
case CS8:
databits = (int)MCF5235_UART_UMR_BC_8;
break;
}
/* determine if parity is enabled */
if ( t->c_cflag & PARENB )
{
if ( t->c_cflag & PARODD )
{
/* odd parity */
parity = (int)MCF5235_UART_UMR_PM_ODD;
}
else
{
/* even parity */
parity = (int)MCF5235_UART_UMR_PM_EVEN;
}
}
/* determine stop bits */
if ( t->c_cflag & CSTOPB )
{
/* two stop bits */
stopbits = (int)MCF5235_UART_UMR_STOP_BITS_2;
}
/* check to see if hardware flow control */
if ( t->c_cflag & CRTSCTS )
{
hwflow = 1;
}
}
/* check to see if values have changed */
if ( ( baud != info->baud ) ||
( databits != info->databits ) ||
( parity != info->parity ) ||
( stopbits != info->stopbits ) ||
( hwflow != info->hwflow ) )
{
/* call function to set values */
IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
}
return( RTEMS_SUCCESSFUL );
}
/***************************************************************************
Function : IntUartInterruptHandler
Description : This is the interrupt handler for the internal uart. It
determines which channel caused the interrupt before queueing any received
chars and dequeueing chars waiting for transmission.
***************************************************************************/
static rtems_isr
IntUartInterruptHandler(rtems_vector_number v)
{
unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0);
struct IntUartInfoStruct *info = &IntUartInfo[chan];
/* check to see if received data */
if ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_RXRDY )
{
/* read data and put into the receive buffer */
while ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_RXRDY )
{
if ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_ERROR )
{
/* clear the error */
MCF5235_UART_UCR(chan) = MCF5235_UART_UCR_RESET_ERROR;
}
/* put data in rx buffer and check for errors */
info->rx_buffer[info->rx_in] = MCF5235_UART_URB(chan);
/* update buffer values */
info->rx_in++;
if ( info->rx_in >= RX_BUFFER_SIZE )
{
info->rx_in = 0;
}
}
/* Make sure the port has been opened */
if ( info->ttyp )
{
/* check to see if task driven */
if ( info->iomode == TERMIOS_TASK_DRIVEN )
{
/* notify rx task that rx buffer has data */
rtems_termios_rxirq_occured(info->ttyp);
}
else
{
/* Push up the received data */
rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
info->rx_in = 0;
}
}
}
/* check to see if data needs to be transmitted */
if ( ( info->uimr & MCF5235_UART_UIMR_TXRDY ) &&
( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_TXRDY ) )
{
/* disable tx interrupts */
info->uimr &= ~MCF5235_UART_UIMR_TXRDY;
MCF5235_UART_UIMR(chan) = info->uimr;
/* tell upper level that character has been sent */
if ( info->ttyp )
rtems_termios_dequeue_characters(info->ttyp, 1);
}
}
/***************************************************************************
Function : IntUartInitialize
Description : This initialises the internal uart hardware for all
internal uarts. If the internal uart is to be interrupt driven then the
interrupt vectors are hooked.
***************************************************************************/
static void
IntUartInitialize(void)
{
unsigned int chan;
struct IntUartInfoStruct *info;
rtems_isr_entry old_handler;
int level;
for ( chan = 0; chan < MAX_UART_INFO; chan++ )
{
info = &IntUartInfo[chan];
info->ttyp = NULL;
info->rx_in = 0;
info->rx_out = 0;
info->baud = -1;
info->databits = -1;
info->parity = -1;
info->stopbits = -1;
info->hwflow = -1;
info->iomode = TERMIOS_POLLED; //polled console io
MCF5235_UART_UACR(chan) = 0;
MCF5235_UART_UIMR(chan) = 0;
if ( info->iomode != TERMIOS_POLLED )
{
rtems_interrupt_catch (IntUartInterruptHandler,
UART_INTC0_IRQ_VECTOR(chan),
&old_handler);
}
/* set uart default values */
IntUartSetAttributes(chan, NULL);
/* unmask interrupt */
rtems_interrupt_disable(level);
switch(chan) {
case 0:
MCF5235_INTC0_ICR13 = MCF5235_INTC_ICR_IL(UART0_IRQ_LEVEL) |
MCF5235_INTC_ICR_IP(UART0_IRQ_PRIORITY);
MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT13 |
MCF5235_INTC0_IMRL_MASKALL);
break;
case 1:
MCF5235_INTC0_ICR14 = MCF5235_INTC_ICR_IL(UART1_IRQ_LEVEL) |
MCF5235_INTC_ICR_IP(UART1_IRQ_PRIORITY);
MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT14 |
MCF5235_INTC0_IMRL_MASKALL);
break;
case 2:
MCF5235_INTC0_ICR15 = MCF5235_INTC_ICR_IL(UART2_IRQ_LEVEL) |
MCF5235_INTC_ICR_IP(UART2_IRQ_PRIORITY);
MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT15 |
MCF5235_INTC0_IMRL_MASKALL);
break;
}
rtems_interrupt_enable(level);
} /* of chan loop */
} /* IntUartInitialise */
/***************************************************************************
Function : IntUartInterruptWrite
Description : This writes a single character to the appropriate uart
channel. This is either called during an interrupt or in the user's task
to initiate a transmit sequence. Calling this routine enables Tx
interrupts.
***************************************************************************/
static int
IntUartInterruptWrite (int minor, const char *buf, int len)
{
int level;
rtems_interrupt_disable(level);
/* write out character */
MCF5235_UART_UTB(minor) = *buf;
/* enable tx interrupt */
IntUartInfo[minor].uimr |= MCF5235_UART_UIMR_TXRDY;
MCF5235_UART_UIMR(minor) = IntUartInfo[minor].uimr;
rtems_interrupt_enable(level);
return( 0 );
}
/***************************************************************************
Function : IntUartInterruptOpen
Description : This enables interrupts when the tty is opened.
***************************************************************************/
static int
IntUartInterruptOpen(int major, int minor, void *arg)
{
struct IntUartInfoStruct *info = &IntUartInfo[minor];
/* enable the uart */
MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED);
/* check to see if interrupts need to be enabled */
if ( info->iomode != TERMIOS_POLLED )
{
/* enable rx interrupts */
info->uimr |= MCF5235_UART_UIMR_FFULL;
MCF5235_UART_UIMR(minor) = info->uimr;
}
/* check to see if doing hardware flow control */
if ( info->hwflow )
{
/* assert the RTS line */
MCF5235_UART_UOP1(minor) = 1;
}
return( 0 );
}
/***************************************************************************
Function : IntUartInterruptClose
Description : This disables interrupts when the tty is closed.
***************************************************************************/
static int
IntUartInterruptClose(int major, int minor, void *arg)
{
struct IntUartInfoStruct *info = &IntUartInfo[minor];
/* disable the interrupts and the uart */
MCF5235_UART_UIMR(minor) = 0;
MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED);
/* reset values */
info->ttyp = NULL;
info->uimr = 0;
info->rx_in = 0;
info->rx_out = 0;
return( 0 );
}
/***************************************************************************
Function : IntUartTaskRead
Description : This reads all available characters from the internal uart
and places them into the termios buffer. The rx interrupts will be
re-enabled after all data has been read.
***************************************************************************/
static int
IntUartTaskRead(int minor)
{
char buffer[RX_BUFFER_SIZE];
int count;
int rx_in;
int index = 0;
struct IntUartInfoStruct *info = &IntUartInfo[minor];
/* determine number of values to copy out */
rx_in = info->rx_in;
if ( info->rx_out <= rx_in )
{
count = rx_in - info->rx_out;
}
else
{
count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
}
/* copy data into local buffer from rx buffer */
while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) )
{
/* copy data byte */
buffer[index] = info->rx_buffer[info->rx_out];
index++;
/* increment rx buffer values */
info->rx_out++;
if ( info->rx_out >= RX_BUFFER_SIZE )
{
info->rx_out = 0;
}
}
/* check to see if buffer is not empty */
if ( count > 0 )
{
/* set characters into termios buffer */
rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
}
return( EOF );
}
/***************************************************************************
Function : IntUartPollRead
Description : This reads a character from the internal uart. It returns
to the caller without blocking if not character is waiting.
***************************************************************************/
static int
IntUartPollRead (int minor)
{
if ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_RXRDY) == 0 )
return(-1);
return(MCF5235_UART_URB(minor));
}
/***************************************************************************
Function : IntUartPollWrite
Description : This writes out each character in the buffer to the
appropriate internal uart channel waiting till each one is sucessfully
transmitted.
***************************************************************************/
static int
IntUartPollWrite (int minor, const char *buf, int len)
{
/* loop over buffer */
while ( len-- )
{
/* block until we can transmit */
while ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_TXRDY) == 0 )
continue;
/* transmit data byte */
MCF5235_UART_UTB(minor) = *buf++;
}
return(0);
}
/***************************************************************************
Function : console_reserve_resources
Description : This reserves resources consumed by this driver. It passes
the request on to the termios subsystem.
***************************************************************************/
void console_reserve_resources( rtems_configuration_table *configuration )
{
rtems_termios_reserve_resources (configuration, 1);
}
/***************************************************************************
Function : console_initialize
Description : This initialises termios, both sets of uart hardware before
registering /dev/tty devices for each channel and the system /dev/console.
***************************************************************************/
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg )
{
rtems_status_code status;
/* Set up TERMIOS */
rtems_termios_initialize ();
/* set io modes for the different channels and initialize device */
IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN;
IntUartInitialize();
/* Register the console port */
status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT);
if ( status != RTEMS_SUCCESSFUL )
{
rtems_fatal_error_occurred (status);
}
/* Register the other port */
if ( CONSOLE_PORT != 0 )
{
status = rtems_io_register_name ("/dev/tty00", major, 0);
if ( status != RTEMS_SUCCESSFUL )
{
rtems_fatal_error_occurred (status);
}
}
if ( CONSOLE_PORT != 1 )
{
status = rtems_io_register_name ("/dev/tty01", major, 1);
if ( status != RTEMS_SUCCESSFUL )
{
rtems_fatal_error_occurred (status);
}
}
return(RTEMS_SUCCESSFUL);
}
/***************************************************************************
Function : console_open
Description : This actually opens the device depending on the minor
number set during initialisation. The device specific access routines are
passed to termios when the devices is opened depending on whether it is
polled or not.
***************************************************************************/
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_status_code status = RTEMS_INVALID_NUMBER;
rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg;
struct IntUartInfoStruct *info;
static const rtems_termios_callbacks IntUartPollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
IntUartPollRead, /* pollRead */
IntUartPollWrite, /* write */
IntUartSetAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
TERMIOS_POLLED /* mode */
};
static const rtems_termios_callbacks IntUartIntrCallbacks = {
IntUartInterruptOpen, /* firstOpen */
IntUartInterruptClose, /* lastClose */
NULL, /* pollRead */
IntUartInterruptWrite, /* write */
IntUartSetAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
TERMIOS_IRQ_DRIVEN /* mode */
};
static const rtems_termios_callbacks IntUartTaskCallbacks = {
IntUartInterruptOpen, /* firstOpen */
IntUartInterruptClose, /* lastClose */
IntUartTaskRead, /* pollRead */
IntUartInterruptWrite, /* write */
IntUartSetAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
TERMIOS_TASK_DRIVEN /* mode */
};
/* open the port depending on the minor device number */
if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) )
{
info = &IntUartInfo[minor];
switch ( info->iomode )
{
case TERMIOS_POLLED:
status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
break;
case TERMIOS_IRQ_DRIVEN:
status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
info->ttyp = args->iop->data1;
break;
case TERMIOS_TASK_DRIVEN:
status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
info->ttyp = args->iop->data1;
break;
}
}
return( status );
}
/***************************************************************************
Function : console_close
Description : This closes the device via termios
***************************************************************************/
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
return(rtems_termios_close (arg));
}
/******************
*********************************************************
Function : console_read
Description : Read from the device via termios
***************************************************************************/
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
return(rtems_termios_read (arg));
}
/***************************************************************************
Function : console_write
Description : Write to the device via termios
***************************************************************************/
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
return(rtems_termios_write (arg));
}
/***************************************************************************
Function : console_ioctl
Description : Pass the IOCtl call to termios
***************************************************************************/
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
return( rtems_termios_ioctl (arg) );
}
int DEBUG_OUTCHAR(int c)
{
if(c == '\n')
DEBUG_OUTCHAR('\r');
_BSP_null_char(c);
return c;
}
void DEBUG_OUTSTR(const char *msg)
{
while (*msg)
DEBUG_OUTCHAR(*msg++);
}
void DEBUG_OUTNUM(int i)
{
int n;
static const char map[] = "0123456789ABCDEF";
DEBUG_OUTCHAR(' ');
for (n = 28 ; n >= 0 ; n -= 4)
DEBUG_OUTCHAR(map[(i >> n) & 0xF]);
}

View File

@@ -0,0 +1,101 @@
/*
* mcf5235 BSP header file
*/
#ifndef _BSP_H
#define _BSP_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <rtems/iosupp.h>
#include <rtems/console.h>
#include <rtems/clockdrv.h>
#include <rtems/iosupp.h>
#include <rtems/bspIo.h>
/***************************************************************************/
/** Hardware data structure headers **/
#include <mcf5235/mcf5235.h> /* internal MCF5235 modules */
/***************************************************************************/
/** Network driver configuration **/
struct rtems_bsdnet_ifconfig;
extern int rtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching );
#define RTEMS_BSP_NETWORK_DRIVER_NAME "fs1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_fec_driver_attach
/***************************************************************************/
/** User Definable configuration **/
/* define which port the console should use - all other ports are then defined as general purpose */
#define CONSOLE_PORT 0
/*
* 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 */
/* externals */
/* 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
*/
/* functions */
unsigned32 get_CPU_clock_speed(void);
void bsp_cleanup(void);
m68k_isr_entry set_vector(
rtems_isr_entry handler,
rtems_vector_number vector,
int type
);
/*
* Interrupt assignments
* Highest-priority listed first
*/
#define FEC_IRQ_LEVEL 4
#define FEC_IRQ_RX_PRIORITY 7
#define FEC_IRQ_TX_PRIORITY 6
#define PIT3_IRQ_LEVEL 4
#define PIT3_IRQ_PRIORITY 0
#define UART0_IRQ_LEVEL 3
#define UART0_IRQ_PRIORITY 7
#define UART1_IRQ_LEVEL 3
#define UART1_IRQ_PRIORITY 6
#define UART2_IRQ_LEVEL 3
#define UART2_IRQ_PRIORITY 5
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,106 @@
/* coverhd.h
*
* This include file has defines to represent the overhead associated
* with calling a particular directive from C. These are used in the
* Timing Test Suite to ignore the overhead required to pass arguments
* to directives. On some CPUs and/or target boards, this overhead
* is significant and makes it difficult to distinguish internal
* RTEMS execution time from that used to call the directive.
* This file should be updated after running the C overhead timing
* test. Once this update has been performed, the RTEMS Time Test
* Suite should be rebuilt to account for these overhead times in the
* timing results.
*
* NOTE: If these are all zero, then the times reported include
* all calling overhead including passing of arguments.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __COVERHD_h
#define __COVERHD_h
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
#define CALLING_OVERHEAD_TASK_CREATE 0
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 1
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 1
#define CALLING_OVERHEAD_CLOCK_SET 1
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 1
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 1
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 0
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 0
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 0
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#endif

View File

@@ -0,0 +1,29 @@
/*
* 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.
*/
#ifndef _RTEMS_TMTEST27
#error "This is an RTEMS internal file you must not include directly."
#endif
#ifndef __tm27_h
#define __tm27_h
/*
* Stuff for Time Test 27
* Don't bother with hardware -- just use a software-interrupt
*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) set_vector( (handler), 35, 1 )
#define Cause_tm27_intr() asm volatile ("trap #3");
#define Clear_tm27_intr() /* empty */
#define Lower_tm27_intr() /* empty */
#endif

View File

@@ -0,0 +1,850 @@
/*
* RTEMS/TCPIP driver for MCF5235 Fast Ethernet Controller
*
* TO DO: Check network stack code -- force longword alignment of all tx mbufs?
*/
#include <bsp.h>
#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <rtems.h>
#include <rtems/error.h>
#include <rtems/rtems_bsdnet.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
/*
* Number of interfaces supported by this driver
*/
#define NIFACES 1
#define FEC_INTC0_TX_VECTOR (64+23)
#define FEC_INTC0_RX_VECTOR (64+27)
/*
* Default number of buffer descriptors set aside for this driver.
* The number of transmit buffer descriptors has to be quite large
* since a single frame often uses three or more buffer descriptors.
*/
#define RX_BUF_COUNT 32
#define TX_BUF_COUNT 20
#define TX_BD_PER_BUF 3
#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
/*
* RTEMS event used by interrupt handler to signal daemons.
* This must *not* be the same event used by the TCP/IP task synchronization.
*/
#define TX_INTERRUPT_EVENT RTEMS_EVENT_1
#define RX_INTERRUPT_EVENT RTEMS_EVENT_1
/*
* RTEMS event used to start transmit daemon.
* This must not be the same as INTERRUPT_EVENT.
*/
#define START_TRANSMIT_EVENT RTEMS_EVENT_2
/*
* Receive buffer size -- Allow for a full ethernet packet plus CRC (1518).
* Round off to nearest multiple of RBUF_ALIGN.
*/
#define MAX_MTU_SIZE 1518
#define RBUF_ALIGN 4
#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
#if (MCLBYTES < RBUF_SIZE)
#error "Driver must have MCLBYTES > RBUF_SIZE"
#endif
typedef struct mcf5235BufferDescriptor_ {
volatile uint16_t status;
uint16_t length;
volatile void *buffer;
} mcf5235BufferDescriptor_t;
/*
* Per-device data
*/
struct mcf5235_enet_struct {
struct arpcom arpcom;
struct mbuf **rxMbuf;
struct mbuf **txMbuf;
int acceptBroadcast;
int rxBdCount;
int txBdCount;
int txBdHead;
int txBdTail;
int txBdActiveCount;
mcf5235BufferDescriptor_t *rxBdBase;
mcf5235BufferDescriptor_t *txBdBase;
rtems_id rxDaemonTid;
rtems_id txDaemonTid;
/*
* Statistics
*/
unsigned long rxInterrupts;
unsigned long txInterrupts;
unsigned long txRawWait;
unsigned long txRealign;
};
static struct mcf5235_enet_struct enet_driver[NIFACES];
static rtems_isr
mcf5235_fec_rx_interrupt_handler( rtems_vector_number v )
{
MCF5235_FEC_EIR = MCF5235_FEC_EIR_RXF;
MCF5235_FEC_EIMR &= ~MCF5235_FEC_EIMR_RXF;
enet_driver[0].rxInterrupts++;
rtems_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
}
static rtems_isr
mcf5235_fec_tx_interrupt_handler( rtems_vector_number v )
{
MCF5235_FEC_EIR = MCF5235_FEC_EIR_TXF;
MCF5235_FEC_EIMR &= ~MCF5235_FEC_EIMR_TXF;
enet_driver[0].txInterrupts++;
rtems_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
}
/*
* Allocate buffer descriptors from (non-cached) on-chip static RAM
* Ensure 128-bit (16-byte) alignment
*/
static mcf5235BufferDescriptor_t *
mcf5235_bd_allocate(unsigned int count)
{
extern char __SRAMBASE[];
static mcf5235BufferDescriptor_t *bdp = (mcf5235BufferDescriptor_t *)__SRAMBASE;
mcf5235BufferDescriptor_t *p = bdp;
bdp += count;
if ((int)bdp & 0xF)
bdp = (mcf5235BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF)));
return p;
}
#if UNUSED
/*
* Read MII register
* Busy-waits, but transfer time should be short!
*/
static int
getMII(int phyNumber, int regNumber)
{
MCF5235_FEC_MMFR = (0x1 << 30) |
(0x2 << 28) |
(phyNumber << 23) |
(regNumber << 18) |
(0x2 << 16);
while ((MCF5235_FEC_EIR & MCF5235_FEC_EIR_MII) == 0);
MCF5235_FEC_EIR = MCF5235_FEC_EIR_MII;
return MCF5235_FEC_MMFR & 0xFFFF;
}
#endif
/*
* Write MII register
* Busy-waits, but transfer time should be short!
*/
static void
setMII(int phyNumber, int regNumber, int value)
{
MCF5235_FEC_MMFR = (0x1 << 30) |
(0x1 << 28) |
(phyNumber << 23) |
(regNumber << 18) |
(0x2 << 16) |
(value & 0xFFFF);
while ((MCF5235_FEC_EIR & MCF5235_FEC_EIR_MII) == 0);
MCF5235_FEC_EIR = MCF5235_FEC_EIR_MII;
}
static void
mcf5235_fec_initialize_hardware(struct mcf5235_enet_struct *sc)
{
int i;
const unsigned char *hwaddr = 0;
rtems_status_code status;
rtems_isr_entry old_handler;
uint32_t clock_speed = get_CPU_clock_speed();
/*
* Issue reset to FEC
*/
MCF5235_FEC_ECR = MCF5235_FEC_ECR_RESET;
rtems_task_wake_after(1);
MCF5235_FEC_ECR = 0;
/*
* Configuration of I/O ports is done outside of this function
*/
#if 0
imm->gpio.pbcnt |= MCF5235_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
#endif
/*
* Set our physical address
*/
hwaddr = sc->arpcom.ac_enaddr;
MCF5235_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
(hwaddr[2] << 8) | (hwaddr[3] << 0);
MCF5235_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
/*
* Clear the hash table
*/
MCF5235_FEC_GAUR = 0;
MCF5235_FEC_GALR = 0;
/*
* Set up receive buffer size
*/
MCF5235_FEC_EMRBR = 1520; /* Standard Ethernet */
/*
* Allocate mbuf pointers
*/
sc->rxMbuf = malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
sc->txMbuf = malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
if (!sc->rxMbuf || !sc->txMbuf)
rtems_panic("No memory for mbuf pointers");
/*
* Set receiver and transmitter buffer descriptor bases
*/
sc->rxBdBase = mcf5235_bd_allocate(sc->rxBdCount);
sc->txBdBase = mcf5235_bd_allocate(sc->txBdCount);
MCF5235_FEC_ERDSR = (int)sc->rxBdBase;
MCF5235_FEC_ETDSR = (int)sc->txBdBase;
/*
* Set up Receive Control Register:
* Not promiscuous
* MII mode
* Full duplex
* No loopback
*/
MCF5235_FEC_RCR = MCF5235_FEC_RCR_MAX_FL(MAX_MTU_SIZE) |
MCF5235_FEC_RCR_MII_MODE;
/*
* Set up Transmit Control Register:
* Full duplex
* No heartbeat
*/
MCF5235_FEC_TCR = MCF5235_FEC_TCR_FDEN;
/*
* Initialize statistic counters
*/
MCF5235_FEC_MIBC = MCF5235_FEC_MIBC_MIB_DISABLE;
{
vuint32 *vuip = &MCF5235_FEC_RMON_T_DROP;
while (vuip <= &MCF5235_FEC_IEEE_R_OCTETS_OK)
*vuip++ = 0;
}
MCF5235_FEC_MIBC = 0;
/*
* Set MII speed to <= 2.5 MHz
*/
i = (clock_speed + 5000000 - 1) / 5000000;
MCF5235_FEC_MSCR = MCF5235_FEC_MSCR_MII_SPEED(i);
/*
* Set PHYS to 100 Mb/s, full duplex
*/
setMII(1, 0, 0x2100);
/*
* Set up receive buffer descriptors
*/
for (i = 0 ; i < sc->rxBdCount ; i++)
(sc->rxBdBase + i)->status = 0;
/*
* Set up transmit buffer descriptors
*/
for (i = 0 ; i < sc->txBdCount ; i++) {
sc->txBdBase[i].status = 0;
sc->txMbuf[i] = NULL;
}
sc->txBdHead = sc->txBdTail = 0;
sc->txBdActiveCount = 0;
/*
* Set up interrupts
*/
status = rtems_interrupt_catch( mcf5235_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler );
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't attach MCF5235 FEC TX interrupt handler: %s\n",
rtems_status_text(status));
status = rtems_interrupt_catch(mcf5235_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't attach MCF5235 FEC RX interrupt handler: %s\n",
rtems_status_text(status));
MCF5235_INTC0_ICR23 = MCF5235_INTC_ICR_IL(FEC_IRQ_LEVEL) |
MCF5235_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY);
MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT23 | MCF5235_INTC0_IMRL_MASKALL);
MCF5235_INTC0_ICR27 = MCF5235_INTC_ICR_IL(FEC_IRQ_LEVEL) |
MCF5235_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY);
MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT27 | MCF5235_INTC0_IMRL_MASKALL);
}
/*
* Soak up buffer descriptors that have been sent.
*/
static void
fec_retire_tx_bd(volatile struct mcf5235_enet_struct *sc )
{
struct mbuf *m, *n;
while ((sc->txBdActiveCount != 0)
&& ((sc->txBdBase[sc->txBdTail].status & MCF5235_FEC_TxBD_R) == 0)) {
m = sc->txMbuf[sc->txBdTail];
MFREE(m, n);
if (++sc->txBdTail == sc->txBdCount)
sc->txBdTail = 0;
sc->txBdActiveCount--;
}
}
static void
fec_rxDaemon (void *arg)
{
volatile struct mcf5235_enet_struct *sc = (volatile struct mcf5235_enet_struct *)arg;
struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
struct mbuf *m;
volatile uint16_t status;
volatile mcf5235BufferDescriptor_t *rxBd;
int rxBdIndex;
/*
* Allocate space for incoming packets and start reception
*/
for (rxBdIndex = 0 ; ;) {
rxBd = sc->rxBdBase + rxBdIndex;
MGETHDR(m, M_WAIT, MT_DATA);
MCLGET(m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod(m, void *);
rxBd->status = MCF5235_FEC_RxBD_E;
if (++rxBdIndex == sc->rxBdCount) {
rxBd->status |= MCF5235_FEC_RxBD_W;
break;
}
}
/*
* Input packet handling loop
*/
/* Indicate we have some ready buffers available */
MCF5235_FEC_RDAR = MCF5235_FEC_RDAR_R_DES_ACTIVE;
rxBdIndex = 0;
for (;;) {
rxBd = sc->rxBdBase + rxBdIndex;
/*
* Wait for packet if there's not one ready
*/
if ((status = rxBd->status) & MCF5235_FEC_RxBD_E) {
/*
* Clear old events.
*/
MCF5235_FEC_EIR = MCF5235_FEC_EIR_RXF;
/*
* Wait for packet to arrive.
* Check the buffer descriptor before waiting for the event.
* This catches the case when a packet arrives between the
* `if' above, and the clearing of the RXF bit in the EIR.
*/
while ((status = rxBd->status) & MCF5235_FEC_RxBD_E) {
rtems_event_set events;
int level;
rtems_interrupt_disable(level);
MCF5235_FEC_EIMR |= MCF5235_FEC_EIMR_RXF;
rtems_interrupt_enable(level);
rtems_bsdnet_event_receive (RX_INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&events);
}
}
/*
* Check that packet is valid
*/
if (status & MCF5235_FEC_RxBD_L) {
/*
* Pass the packet up the chain.
* FIXME: Packet filtering hook could be done here.
*/
struct ether_header *eh;
int len = rxBd->length - sizeof(uint32_t);;
/*
* Invalidate the cache and push the packet up.
* The cache is so small that it's more efficient to just
* invalidate the whole thing unless the packet is very small.
*/
m = sc->rxMbuf[rxBdIndex];
if (len < 128)
rtems_cache_invalidate_multiple_data_lines(m->m_data, len);
else
rtems_cache_invalidate_entire_data();
m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
eh = mtod(m, struct ether_header *);
m->m_data += sizeof(struct ether_header);
ether_input(ifp, eh, m);
/*
* Allocate a new mbuf
*/
MGETHDR(m, M_WAIT, MT_DATA);
MCLGET(m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod(m, void *);
}
/*
* Reenable the buffer descriptor
*/
rxBd->status = (status & MCF5235_FEC_RxBD_W) | MCF5235_FEC_RxBD_E;
MCF5235_FEC_RDAR = MCF5235_FEC_RDAR_R_DES_ACTIVE;
/*
* Move to next buffer descriptor
*/
if (++rxBdIndex == sc->rxBdCount)
rxBdIndex = 0;
}
}
static void
fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
{
struct mcf5235_enet_struct *sc = ifp->if_softc;
volatile mcf5235BufferDescriptor_t *firstTxBd, *txBd;
uint16_t status;
int nAdded;
/*
* Free up buffer descriptors
*/
fec_retire_tx_bd(sc);
/*
* Set up the transmit buffer descriptors.
* No need to pad out short packets since the
* hardware takes care of that automatically.
* No need to copy the packet to a contiguous buffer
* since the hardware is capable of scatter/gather DMA.
*/
nAdded = 0;
firstTxBd = sc->txBdBase + sc->txBdHead;
for (;;) {
/*
* Wait for buffer descriptor to become available
*/
if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
/*
* Clear old events.
*/
MCF5235_FEC_EIR = MCF5235_FEC_EIR_TXF;
/*
* Wait for buffer descriptor to become available.
* Check for buffer descriptors before waiting for the event.
* This catches the case when a buffer became available between
* the `if' above, and the clearing of the TXF bit in the EIR.
*/
fec_retire_tx_bd(sc);
while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
rtems_event_set events;
int level;
rtems_interrupt_disable(level);
MCF5235_FEC_EIMR |= MCF5235_FEC_EIMR_TXF;
rtems_interrupt_enable(level);
sc->txRawWait++;
rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&events);
fec_retire_tx_bd(sc);
}
}
/*
* Don't set the READY flag on the first fragment
* until the whole packet has been readied.
*/
status = nAdded ? MCF5235_FEC_TxBD_R : 0;
/*
* The IP fragmentation routine in ip_output
* can produce fragments with zero length.
*/
txBd = sc->txBdBase + sc->txBdHead;
if (m->m_len) {
char *p = mtod(m, char *);
/*
* Stupid FEC can't handle misaligned data!
* Given the way that mbuf's are layed out it should be
* safe to shuffle the data down like this.....
* Perhaps this code could be improved with a "Duff's Device".
*/
if ((int)p & 0x3) {
int l = m->m_len;
char *dest = p - ((int)p & 0x3);
uint16_t *o = (uint16_t *)dest, *i = (uint16_t *)p;
while (l > 0) {
*o++ = *i++;
l -= sizeof(uint16_t);
}
p = dest;
sc->txRealign++;
}
txBd->buffer = p;
txBd->length = m->m_len;
sc->txMbuf[sc->txBdHead] = m;
nAdded++;
if (++sc->txBdHead == sc->txBdCount) {
status |= MCF5235_FEC_TxBD_W;
sc->txBdHead = 0;
}
m = m->m_next;
}
else {
/*
* Just toss empty mbufs
*/
struct mbuf *n;
MFREE(m, n);
m = n;
}
if (m == NULL) {
if (nAdded) {
txBd->status = status | MCF5235_FEC_TxBD_R
| MCF5235_FEC_TxBD_L
| MCF5235_FEC_TxBD_TC;
if (nAdded > 1)
firstTxBd->status |= MCF5235_FEC_TxBD_R;
MCF5235_FEC_TDAR = MCF5235_FEC_TDAR_X_DES_ACTIVE;
sc->txBdActiveCount += nAdded;
}
break;
}
txBd->status = status;
}
}
void
fec_txDaemon(void *arg)
{
struct mcf5235_enet_struct *sc = (struct mcf5235_enet_struct *)arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
rtems_event_set events;
for (;;) {
/*
* Wait for packet
*/
rtems_bsdnet_event_receive(START_TRANSMIT_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;
fec_sendpacket(ifp, m);
}
ifp->if_flags &= ~IFF_OACTIVE;
}
}
/*
* Send packet (caller provides header).
*/
static void
mcf5235_enet_start(struct ifnet *ifp)
{
struct mcf5235_enet_struct *sc = ifp->if_softc;
rtems_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
ifp->if_flags |= IFF_OACTIVE;
}
static void
fec_init(void *arg)
{
struct mcf5235_enet_struct *sc = arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
if (sc->txDaemonTid == 0) {
/*
* Set up hardware
*/
mcf5235_fec_initialize_hardware(sc);
/*
* Start driver tasks
*/
sc->txDaemonTid = rtems_bsdnet_newproc("FECtx", 4096, fec_txDaemon, sc);
sc->rxDaemonTid = rtems_bsdnet_newproc("FECrx", 4096, fec_rxDaemon, sc);
}
/*
* Set flags appropriately
*/
if (ifp->if_flags & IFF_PROMISC)
MCF5235_FEC_RCR |= MCF5235_FEC_RCR_PROM;
else
MCF5235_FEC_RCR &= ~MCF5235_FEC_RCR_PROM;
/*
* Tell the world that we're running.
*/
ifp->if_flags |= IFF_RUNNING;
/*
* Enable receiver and transmitter
*/
MCF5235_FEC_ECR = MCF5235_FEC_ECR_ETHER_EN;
}
static void
fec_stop(struct mcf5235_enet_struct *sc)
{
struct ifnet *ifp = &sc->arpcom.ac_if;
ifp->if_flags &= ~IFF_RUNNING;
/*
* Shut down receiver and transmitter
*/
MCF5235_FEC_ECR = 0x0;
}
/*
* Show interface statistics
*/
static void
enet_stats(struct mcf5235_enet_struct *sc)
{
printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
printf("Rx Packet Count:%-10lu", MCF5235_FEC_RMON_R_PACKETS);
printf(" Rx Broadcast:%-10lu\n", MCF5235_FEC_RMON_R_BC_PKT);
printf(" Rx Multicast:%-10lu", MCF5235_FEC_RMON_R_MC_PKT);
printf("CRC/Align error:%-10lu", MCF5235_FEC_RMON_R_CRC_ALIGN);
printf(" Rx Undersize:%-10lu\n", MCF5235_FEC_RMON_R_UNDERSIZE);
printf(" Rx Oversize:%-10lu", MCF5235_FEC_RMON_R_OVERSIZE);
printf(" Rx Fragment:%-10lu", MCF5235_FEC_RMON_R_FRAG);
printf(" Rx Jabber:%-10lu\n", MCF5235_FEC_RMON_R_JAB);
printf(" Rx 64:%-10lu", MCF5235_FEC_RMON_R_P64);
printf(" Rx 65-127:%-10lu", MCF5235_FEC_RMON_R_P65T0127);
printf(" Rx 128-255:%-10lu\n", MCF5235_FEC_RMON_R_P128TO255);
printf(" Rx 256-511:%-10lu", MCF5235_FEC_RMON_R_P256TO511);
printf(" Rx 511-1023:%-10lu", MCF5235_FEC_RMON_R_P512TO1023);
printf(" Rx 1024-2047:%-10lu\n", MCF5235_FEC_RMON_R_P1024TO2047);
printf(" Rx >=2048:%-10lu", MCF5235_FEC_RMON_R_GTE2048);
printf(" Rx Octets:%-10lu", MCF5235_FEC_RMON_R_OCTETS);
printf(" Rx Dropped:%-10lu\n", MCF5235_FEC_IEEE_R_DROP);
printf(" Rx frame OK:%-10lu", MCF5235_FEC_IEEE_R_FRAME_OK);
printf(" Rx CRC error:%-10lu", MCF5235_FEC_IEEE_R_CRC);
printf(" Rx Align error:%-10lu\n", MCF5235_FEC_IEEE_R_ALIGN);
printf(" FIFO Overflow:%-10lu", MCF5235_FEC_IEEE_R_MACERR);
printf("Rx Pause Frames:%-10lu", MCF5235_FEC_IEEE_R_FDXFC);
printf(" Rx Octets OK:%-10lu\n", MCF5235_FEC_IEEE_R_OCTETS_OK);
printf(" Tx Interrupts:%-10lu", sc->txInterrupts);
printf("Tx Output Waits:%-10lu", sc->txRawWait);
printf("Tx Realignments:%-10lu\n", sc->txRealign);
printf(" Tx Unaccounted:%-10lu", MCF5235_FEC_RMON_T_DROP);
printf("Tx Packet Count:%-10lu", MCF5235_FEC_RMON_T_PACKETS);
printf(" Tx Broadcast:%-10lu\n", MCF5235_FEC_RMON_T_BC_PKT);
printf(" Tx Multicast:%-10lu", MCF5235_FEC_RMON_T_MC_PKT);
printf("CRC/Align error:%-10lu", MCF5235_FEC_RMON_T_CRC_ALIGN);
printf(" Tx Undersize:%-10lu\n", MCF5235_FEC_RMON_T_UNDERSIZE);
printf(" Tx Oversize:%-10lu", MCF5235_FEC_RMON_T_OVERSIZE);
printf(" Tx Fragment:%-10lu", MCF5235_FEC_RMON_T_FRAG);
printf(" Tx Jabber:%-10lu\n", MCF5235_FEC_RMON_T_JAB);
printf(" Tx Collisions:%-10lu", MCF5235_FEC_RMON_T_COL);
printf(" Tx 64:%-10lu", MCF5235_FEC_RMON_T_P64);
printf(" Tx 65-127:%-10lu\n", MCF5235_FEC_RMON_T_P65TO127);
printf(" Tx 128-255:%-10lu", MCF5235_FEC_RMON_T_P128TO255);
printf(" Tx 256-511:%-10lu", MCF5235_FEC_RMON_T_P256TO511);
printf(" Tx 511-1023:%-10lu\n", MCF5235_FEC_RMON_T_P512TO1023);
printf(" Tx 1024-2047:%-10lu", MCF5235_FEC_RMON_T_P1024TO2047);
printf(" Tx >=2048:%-10lu", MCF5235_FEC_RMON_T_P_GTE2048);
printf(" Tx Octets:%-10lu\n", MCF5235_FEC_RMON_T_OCTETS);
printf(" Tx Dropped:%-10lu", MCF5235_FEC_IEEE_T_DROP);
printf(" Tx Frame OK:%-10lu", MCF5235_FEC_IEEE_T_FRAME_OK);
printf(" Tx 1 Collision:%-10lu\n", MCF5235_FEC_IEEE_T_1COL);
printf("Tx >1 Collision:%-10lu", MCF5235_FEC_IEEE_T_MCOL);
printf(" Tx Deferred:%-10lu", MCF5235_FEC_IEEE_T_DEF);
printf(" Late Collision:%-10lu\n", MCF5235_FEC_IEEE_T_LCOL);
printf(" Excessive Coll:%-10lu", MCF5235_FEC_IEEE_T_EXCOL);
printf(" FIFO Underrun:%-10lu", MCF5235_FEC_IEEE_T_MACERR);
printf(" Carrier Error:%-10lu\n", MCF5235_FEC_IEEE_T_CSERR);
printf(" Tx SQE Error:%-10lu", MCF5235_FEC_IEEE_T_SQE);
printf("Tx Pause Frames:%-10lu", MCF5235_FEC_IEEE_T_FDXFC);
printf(" Tx Octets OK:%-10lu\n", MCF5235_FEC_IEEE_T_OCTETS_OK);
}
static int
fec_ioctl(struct ifnet *ifp, int command, caddr_t data)
{
struct mcf5235_enet_struct *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:
fec_stop(sc);
break;
case IFF_UP:
fec_init(sc);
break;
case IFF_UP | IFF_RUNNING:
fec_stop(sc);
fec_init(sc);
break;
default:
break;
}
break;
case SIO_RTEMS_SHOW_STATS:
enet_stats(sc);
break;
/*
* FIXME: All sorts of multicast commands need to be added here!
*/
default:
error = EINVAL;
break;
}
return error;
}
int
rtems_fec_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching )
{
struct mcf5235_enet_struct *sc;
struct ifnet *ifp;
int mtu;
int unitNumber;
char *unitName;
unsigned char *hwaddr;
/*
* Parse driver name
*/
if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
return 0;
/*
* Is driver free?
*/
if ((unitNumber <= 0) || (unitNumber > NIFACES)) {
printf("Bad FEC unit number.\n");
return 0;
}
sc = &enet_driver[unitNumber - 1];
ifp = &sc->arpcom.ac_if;
if (ifp->if_softc != NULL) {
printf("Driver already in use.\n");
return 0;
}
/*
* Process options
*/
hwaddr = config->hardware_address;
printf("%s%d: Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n",
unitName, unitNumber,
hwaddr[0], hwaddr[1], hwaddr[2],
hwaddr[3], hwaddr[4], hwaddr[5]);
memcpy(sc->arpcom.ac_enaddr, hwaddr, ETHER_ADDR_LEN);
if (config->mtu)
mtu = config->mtu;
else
mtu = ETHERMTU;
if (config->rbuf_count)
sc->rxBdCount = config->rbuf_count;
else
sc->rxBdCount = RX_BUF_COUNT;
if (config->xbuf_count)
sc->txBdCount = config->xbuf_count;
else
sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
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 = fec_init;
ifp->if_ioctl = fec_ioctl;
ifp->if_start = mcf5235_enet_start;
ifp->if_output = ether_output;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
if (ifp->if_snd.ifq_maxlen == 0)
ifp->if_snd.ifq_maxlen = ifqmaxlen;
/*
* Attach the interface
*/
if_attach(ifp);
ether_ifattach(ifp);
return 1;
};

View File

@@ -0,0 +1,392 @@
/*
* mcf5235 startup code
*
* This file contains the entry point for the application.
* The name of this entry point is compiler dependent.
* It jumps to the BSP which is responsible for performing
* all initialization.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/asm.h>
#define SRAM_SIZE (64*1024)
#define DEFAULT_IPSBAR 0x40000000
BEGIN_CODE
#define INITIAL_STACK __SRAMBASE+SRAM_SIZE-4
PUBLIC (INTERRUPT_VECTOR)
SYM(INTERRUPT_VECTOR):
.long INITIAL_STACK | 0: Initial 'SSP'
.long start | 1: Initial PC
.long SYM(_uhoh) | 2: Bus error
.long SYM(_uhoh) | 3: Address error
.long SYM(_uhoh) | 4: Illegal instruction
.long SYM(_uhoh) | 5: Zero division
.long SYM(_uhoh) | 6: CHK, CHK2 instruction
.long SYM(_uhoh) | 7: TRAPcc, TRAPV instructions
.long SYM(_uhoh) | 8: Privilege violation
.long SYM(_uhoh) | 9: Trace
.long SYM(_uhoh) | 10: Line 1010 emulator
.long SYM(_uhoh) | 11: Line 1111 emulator
.long SYM(_uhoh) | 12: Hardware breakpoint
.long SYM(_uhoh) | 13: Reserved for coprocessor violation
.long SYM(_uhoh) | 14: Format error
.long SYM(_uhoh) | 15: Uninitialized interrupt
.long SYM(_uhoh) | 16: Unassigned, reserved
.long SYM(_uhoh) | 17:
.long SYM(_uhoh) | 18:
.long SYM(_uhoh) | 19:
.long SYM(_uhoh) | 20:
.long SYM(_uhoh) | 21:
.long SYM(_uhoh) | 22:
.long SYM(_uhoh) | 23:
.long SYM(_spuriousInterrupt) | 24: Spurious interrupt
.long SYM(_uhoh) | 25: Level 1 interrupt autovector
.long SYM(_uhoh) | 26: Level 2 interrupt autovector
.long SYM(_uhoh) | 27: Level 3 interrupt autovector
.long SYM(_uhoh) | 28: Level 4 interrupt autovector
.long SYM(_uhoh) | 29: Level 5 interrupt autovector
.long SYM(_uhoh) | 30: Level 6 interrupt autovector
.long SYM(_uhoh) | 31: Level 7 interrupt autovector
.long SYM(_uhoh) | 32: Trap instruction (0-15)
.long SYM(_uhoh) | 33:
.long SYM(_uhoh) | 34:
.long SYM(_uhoh) | 35:
.long SYM(_uhoh) | 36:
.long SYM(_uhoh) | 37:
.long SYM(_uhoh) | 38:
.long SYM(_uhoh) | 39:
.long SYM(_uhoh) | 40:
.long SYM(_uhoh) | 41:
.long SYM(_uhoh) | 42:
.long SYM(_uhoh) | 43:
.long SYM(_uhoh) | 44:
.long SYM(_uhoh) | 45:
.long SYM(_uhoh) | 46:
.long SYM(_uhoh) | 47:
.long SYM(_uhoh) | 48: Reserved for coprocessor
.long SYM(_uhoh) | 49:
.long SYM(_uhoh) | 50:
.long SYM(_uhoh) | 51:
.long SYM(_uhoh) | 52:
.long SYM(_uhoh) | 53:
.long SYM(_uhoh) | 54:
.long SYM(_uhoh) | 55:
.long SYM(_uhoh) | 56:
.long SYM(_uhoh) | 57:
.long SYM(_uhoh) | 58:
.long SYM(_uhoh) | 59: Unassigned, reserved
.long SYM(_uhoh) | 60:
.long SYM(_uhoh) | 61:
.long SYM(_uhoh) | 62:
.long SYM(_uhoh) | 63:
.long SYM(_spuriousInterrupt) | 64: User spurious handler
.long SYM(_uhoh) | 65:
.long SYM(_uhoh) | 66:
.long SYM(_uhoh) | 67:
.long SYM(_uhoh) | 68:
.long SYM(_uhoh) | 69:
.long SYM(_uhoh) | 70:
.long SYM(_uhoh) | 71:
.long SYM(_uhoh) | 72:
.long SYM(_uhoh) | 73:
.long SYM(_uhoh) | 74:
.long SYM(_uhoh) | 75:
.long SYM(_uhoh) | 76:
.long SYM(_uhoh) | 77:
.long SYM(_uhoh) | 78:
.long SYM(_uhoh) | 79:
.long SYM(_uhoh) | 80:
.long SYM(_uhoh) | 81:
.long SYM(_uhoh) | 82:
.long SYM(_uhoh) | 83:
.long SYM(_uhoh) | 84:
.long SYM(_uhoh) | 85:
.long SYM(_uhoh) | 86:
.long SYM(_uhoh) | 87:
.long SYM(_uhoh) | 88:
.long SYM(_uhoh) | 89:
.long SYM(_uhoh) | 90:
.long SYM(_uhoh) | 91:
.long SYM(_uhoh) | 92:
.long SYM(_uhoh) | 93:
.long SYM(_uhoh) | 94:
.long SYM(_uhoh) | 95:
.long SYM(_uhoh) | 96:
.long SYM(_uhoh) | 97:
.long SYM(_uhoh) | 98:
.long SYM(_uhoh) | 99:
.long SYM(_uhoh) | 100:
.long SYM(_uhoh) | 101:
.long SYM(_uhoh) | 102:
.long SYM(_uhoh) | 103:
.long SYM(_uhoh) | 104:
.long SYM(_uhoh) | 105:
.long SYM(_uhoh) | 106:
.long SYM(_uhoh) | 107:
.long SYM(_uhoh) | 108:
.long SYM(_uhoh) | 109:
.long SYM(_uhoh) | 110:
.long SYM(_uhoh) | 111:
.long SYM(_uhoh) | 112:
.long SYM(_uhoh) | 113:
.long SYM(_uhoh) | 114:
.long SYM(_uhoh) | 115:
.long SYM(_uhoh) | 116:
.long SYM(_uhoh) | 117:
.long SYM(_uhoh) | 118:
.long SYM(_uhoh) | 119:
.long SYM(_uhoh) | 120:
.long SYM(_uhoh) | 121:
.long SYM(_uhoh) | 122:
.long SYM(_uhoh) | 123:
.long SYM(_uhoh) | 124:
.long SYM(_uhoh) | 125:
.long SYM(_uhoh) | 126:
.long SYM(_uhoh) | 127:
.long SYM(_uhoh) | 128:
.long SYM(_uhoh) | 129:
.long SYM(_uhoh) | 130:
.long SYM(_uhoh) | 131:
.long SYM(_uhoh) | 132:
.long SYM(_uhoh) | 133:
.long SYM(_uhoh) | 134:
.long SYM(_uhoh) | 135:
.long SYM(_uhoh) | 136:
.long SYM(_uhoh) | 137:
.long SYM(_uhoh) | 138:
.long SYM(_uhoh) | 139:
.long SYM(_uhoh) | 140:
.long SYM(_uhoh) | 141:
.long SYM(_uhoh) | 142:
.long SYM(_uhoh) | 143:
.long SYM(_uhoh) | 144:
.long SYM(_uhoh) | 145:
.long SYM(_uhoh) | 146:
.long SYM(_uhoh) | 147:
.long SYM(_uhoh) | 148:
.long SYM(_uhoh) | 149:
.long SYM(_uhoh) | 150:
.long SYM(_uhoh) | 151:
.long SYM(_uhoh) | 152:
.long SYM(_uhoh) | 153:
.long SYM(_uhoh) | 154:
.long SYM(_uhoh) | 155:
.long SYM(_uhoh) | 156:
.long SYM(_uhoh) | 157:
.long SYM(_uhoh) | 158:
.long SYM(_uhoh) | 159:
.long SYM(_uhoh) | 160:
.long SYM(_uhoh) | 161:
.long SYM(_uhoh) | 162:
.long SYM(_uhoh) | 163:
.long SYM(_uhoh) | 164:
.long SYM(_uhoh) | 165:
.long SYM(_uhoh) | 166:
.long SYM(_uhoh) | 167:
.long SYM(_uhoh) | 168:
.long SYM(_uhoh) | 169:
.long SYM(_uhoh) | 170:
.long SYM(_uhoh) | 171:
.long SYM(_uhoh) | 172:
.long SYM(_uhoh) | 173:
.long SYM(_uhoh) | 174:
.long SYM(_uhoh) | 175:
.long SYM(_uhoh) | 176:
.long SYM(_uhoh) | 177:
.long SYM(_uhoh) | 178:
.long SYM(_uhoh) | 179:
.long SYM(_uhoh) | 180:
.long SYM(_uhoh) | 181:
.long SYM(_uhoh) | 182:
.long SYM(_uhoh) | 183:
.long SYM(_uhoh) | 184:
.long SYM(_uhoh) | 185:
.long SYM(_uhoh) | 186:
.long SYM(_uhoh) | 187:
.long SYM(_uhoh) | 188:
.long SYM(_uhoh) | 189:
.long SYM(_uhoh) | 190:
.long SYM(_uhoh) | 191:
.long SYM(_uhoh) | 192:
.long SYM(_uhoh) | 193:
.long SYM(_uhoh) | 194:
.long SYM(_uhoh) | 195:
.long SYM(_uhoh) | 196:
.long SYM(_uhoh) | 197:
.long SYM(_uhoh) | 198:
.long SYM(_uhoh) | 199:
.long SYM(_uhoh) | 200:
.long SYM(_uhoh) | 201:
.long SYM(_uhoh) | 202:
.long SYM(_uhoh) | 203:
.long SYM(_uhoh) | 204:
.long SYM(_uhoh) | 205:
.long SYM(_uhoh) | 206:
.long SYM(_uhoh) | 207:
.long SYM(_uhoh) | 208:
.long SYM(_uhoh) | 209:
.long SYM(_uhoh) | 210:
.long SYM(_uhoh) | 211:
.long SYM(_uhoh) | 212:
.long SYM(_uhoh) | 213:
.long SYM(_uhoh) | 214:
.long SYM(_uhoh) | 215:
.long SYM(_uhoh) | 216:
.long SYM(_uhoh) | 217:
.long SYM(_uhoh) | 218:
.long SYM(_uhoh) | 219:
.long SYM(_uhoh) | 220:
.long SYM(_uhoh) | 221:
.long SYM(_uhoh) | 222:
.long SYM(_uhoh) | 223:
.long SYM(_uhoh) | 224:
.long SYM(_uhoh) | 225:
.long SYM(_uhoh) | 226:
.long SYM(_uhoh) | 227:
.long SYM(_uhoh) | 228:
.long SYM(_uhoh) | 229:
.long SYM(_uhoh) | 230:
.long SYM(_uhoh) | 231:
.long SYM(_uhoh) | 232:
.long SYM(_uhoh) | 233:
.long SYM(_uhoh) | 234:
.long SYM(_uhoh) | 235:
.long SYM(_uhoh) | 236:
.long SYM(_uhoh) | 237:
.long SYM(_uhoh) | 238:
.long SYM(_uhoh) | 239:
.long SYM(_uhoh) | 240:
.long SYM(_uhoh) | 241:
.long SYM(_uhoh) | 242:
.long SYM(_uhoh) | 243:
.long SYM(_uhoh) | 244:
.long SYM(_uhoh) | 245:
.long SYM(_uhoh) | 246:
.long SYM(_uhoh) | 247:
.long SYM(_uhoh) | 248:
.long SYM(_uhoh) | 249:
.long SYM(_uhoh) | 250:
.long SYM(_uhoh) | 251:
.long SYM(_uhoh) | 252:
.long SYM(_uhoh) | 253:
.long SYM(_uhoh) | 254:
.long SYM(_uhoh) | 255:
/*
* Default trap handler
* With an oscilloscope you can see AS* stop
*/
.align 4
PUBLIC (_uhoh)
SYM(_uhoh):
nop | Leave spot for breakpoint
stop #0x2700 | Stop with interrupts disabled
bra.w SYM(_uhoh) | Stuck forever
.align 4
PUBLIC (_spuriousInterrupt)
SYM(_spuriousInterrupt):
addql #1,SYM(_M68kSpuriousInterruptCount)
rte
/***************************************************************************
Function : start
Description : setup the internal SRAM for use and setup the INITIAL STACK ptr.
Also enable the internal peripherals
***************************************************************************/
.align 4
PUBLIC (start)
SYM(start):
move.w #0x0000,d0 | Turn off watchdog timer
move.w d0, (0x40140000)
move.l #0x01000000,d0 | Set system frequency to 150 MHz
move.l d0, (0x40120000)
move.w #0x2700,sr | Disable interrupts
move.l #__SRAMBASE+1,d0 | Enable the MCF5235 internal SRAM
movec d0,%rambar | ...so we have a stack
move.l #__IPSBAR+1,d0 | Enable the MCF5235 internal peripherals
move.l d0,DEFAULT_IPSBAR
/*
* Remainder of the startup code is handled by C code
*/
jmp SYM(Init5235) | Start C code (which never returns)
/***************************************************************************
Function : CopyDataClearBSSAndStart
Description : Copy DATA segment, Copy SRAM segment, clear BSS segment,
start C program. Assume that DATA and BSS sizes are multiples of 4.
***************************************************************************/
.align 4
PUBLIC (CopyDataClearBSSAndStart)
SYM(CopyDataClearBSSAndStart):
lea SYM(_data_dest_start),a0 | Get start of DATA in RAM
lea SYM(_data_src_start),a2 | Get start of DATA in ROM
cmpl a0,a2 | Are they the same?
beq.s NODATACOPY | Yes, no copy necessary
lea SYM(_data_dest_end),a1 | Get end of DATA in RAM
bra.s DATACOPYLOOPTEST | Branch into copy loop
DATACOPYLOOP:
movel a2@+,a0@+ | Copy word from ROM to RAM
DATACOPYLOOPTEST:
cmpl a1,a0 | Done?
bcs.s DATACOPYLOOP | No, skip
NODATACOPY:
/* Now, clear BSS */
lea _clear_start,a0 | Get start of BSS
lea _clear_end,a1 | Get end of BSS
clrl d0 | Value to set
bra.s ZEROLOOPTEST | Branch into clear loop
ZEROLOOP:
movel d0,a0@+ | Clear a word
ZEROLOOPTEST:
cmpl a1,a0 | Done?
bcs.s ZEROLOOP | No, skip
/*
* Right : Now we're ready to boot RTEMS
*/
clrl d0 | Pass in null to all boot_card() params
movel d0,a7@- | environp
movel d0,a7@- | argv
movel d0,a7@- | argc
jsr SYM(boot_card) | Call C boot_card function to startup RTEMS
movel a7@+,d0
movel a7@+,d0
movel a7@+,d0
MULTI_TASK_EXIT:
nop
nop
trap #14
bra MULTI_TASK_EXIT
END_CODE
.align 2
BEGIN_DATA_DCL
.align 2
PUBLIC (_M68kSpuriousInterruptCount)
SYM (_M68kSpuriousInterruptCount):
.long 0
END_DATA_DCL
END

View File

@@ -0,0 +1,35 @@
/*
* SBC5206 bsp_cleanup
*
* This routine returns control from RTEMS to the monitor.
*
* Author:
* David Fiddes, D.J@fiddes.surfaid.org
* http://www.calm.hw.ac.uk/davidf/coldfire/
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <rtems/bspIo.h>
void bsp_cleanup( void )
{
printk("\nRTEMS exited!\n");
for ( ;; )
{
asm volatile ( " nop " );
asm volatile ( " nop " );
}
}

View File

@@ -0,0 +1,220 @@
/*
* BSP startup
*
* 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.
*
* Author:
* David Fiddes, D.J@fiddes.surfaid.org
* http://www.calm.hw.ac.uk/davidf/coldfire/
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <string.h>
/*
* The original table from the application and our copy of it with
* some changes.
*/
extern rtems_configuration_table Configuration;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
char *rtems_progname;
/*
* Cacheable areas
*/
#define SDRAM_BASE 0
#define SDRAM_SIZE (16*1024*1024)
/*
* CPU-space access
*/
#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr" : : "d" (_cacr))
#define m68k_set_acr0(_acr0) asm volatile ("movec %0,%%acr0" : : "d" (_acr0))
#define m68k_set_acr1(_acr1) asm volatile ("movec %0,%%acr1" : : "d" (_acr1))
/*
* Read/write copy of common cache
* Split I/D cache
* Allow CPUSHL to invalidate a cache line
* Enable buffered writes
* No burst transfers on non-cacheable accesses
* Default cache mode is *disabled* (cache only ACRx areas)
*/
static unsigned32 cacr_mode = MCF5XXX_CACR_CENB |
MCF5XXX_CACR_DBWE |
MCF5XXX_CACR_DCM;
/*
* Cannot be frozen
*/
void _CPU_cache_freeze_data(void) {}
void _CPU_cache_unfreeze_data(void) {}
void _CPU_cache_freeze_instruction(void) {}
void _CPU_cache_unfreeze_instruction(void) {}
/*
* Write-through data cache -- flushes are unnecessary
*/
void _CPU_cache_flush_1_data_line(const void *d_addr) {}
void _CPU_cache_flush_entire_data(void) {}
void _CPU_cache_enable_instruction(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable(level);
cacr_mode &= ~MCF5XXX_CACR_DIDI;
m68k_set_cacr(cacr_mode);
rtems_interrupt_enable(level);
}
void _CPU_cache_disable_instruction(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable(level);
cacr_mode |= MCF5XXX_CACR_DIDI;
m68k_set_cacr(cacr_mode);
rtems_interrupt_enable(level);
}
void _CPU_cache_invalidate_entire_instruction(void)
{
m68k_set_cacr(cacr_mode | MCF5XXX_CACR_CINV | MCF5XXX_CACR_INVI);
}
void _CPU_cache_invalidate_1_instruction_line(const void *addr)
{
/*
* Top half of cache is I-space
*/
addr = (void *)((int)addr | 0x400);
asm volatile ("cpushl %%bc,(%0)" :: "a" (addr));
}
void _CPU_cache_enable_data(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable(level);
cacr_mode &= ~MCF5XXX_CACR_DISD;
m68k_set_cacr(cacr_mode);
rtems_interrupt_enable(level);
}
void _CPU_cache_disable_data(void)
{
rtems_interrupt_level level;
rtems_interrupt_disable(level);
rtems_interrupt_disable(level);
cacr_mode |= MCF5XXX_CACR_DISD;
m68k_set_cacr(cacr_mode);
rtems_interrupt_enable(level);
}
void _CPU_cache_invalidate_entire_data(void)
{
m68k_set_cacr(cacr_mode | MCF5XXX_CACR_CINV | MCF5XXX_CACR_INVD);
}
void _CPU_cache_invalidate_1_data_line(const void *addr)
{
/*
* Bottom half of cache is D-space
*/
addr = (void *)((int)addr & ~0x400);
asm volatile ("cpushl %%bc,(%0)" :: "a" (addr));
}
/*
* Use the shared implementations of the following routines
*/
void bsp_postdriver_hook(void);
void bsp_libc_init( void *, unsigned32, int );
void bsp_pretasking_hook(void); /* m68k version */
/*
* bsp_start
*
* This routine does the bulk of the system initialisation.
*/
void bsp_start( void )
{
extern char _WorkspaceBase[];
extern char _RamSize[];
extern unsigned long _M68k_Ramsize;
_M68k_Ramsize = (unsigned long)_RamSize; /* RAM size set in linker script */
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
* RTEMS world (e.g. simulator or primitive memory manager), or (as
* typically done by stock BSPs) by subtracting the required amount
* of work space from the last physical address on the CPU board.
*/
/*
* Need to "allocate" the memory for the RTEMS Workspace and
* tell the RTEMS configuration where it is. This memory is
* not malloc'ed. It is just "pulled from the air".
*/
BSP_Configuration.work_space_start = (void *)_WorkspaceBase;
/*
* initialize the CPU table for this BSP
*/
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
Cpu_table.do_zero_of_workspace = TRUE;
Cpu_table.interrupt_stack_size = 4096;
Cpu_table.interrupt_vector_table = (m68k_isr *)0; /* vectors at start of RAM */
/*
* Invalidate the cache and disable it
*/
m68k_set_acr0(0);
m68k_set_acr1(0);
m68k_set_cacr(MCF5XXX_CACR_CINV);
/*
* Cache SDRAM
*/
m68k_set_acr0(MCF5XXX_ACR_AB(SDRAM_BASE) |
MCF5XXX_ACR_AM(SDRAM_SIZE-1) |
MCF5XXX_ACR_EN |
MCF5XXX_ACR_BWE |
MCF5XXX_ACR_SM_IGNORE);
/*
* Enable the cache
*/
m68k_set_cacr(cacr_mode);
}
unsigned32 get_CPU_clock_speed(void)
{
extern char _CPUClockSpeed[];
return( (unsigned32)_CPUClockSpeed);
}

View File

@@ -0,0 +1,80 @@
/*
* This is where the real hardware setup is done. A minimal stack
* has been provided by the start.S code. No normal C or RTEMS
* functions can be called from here.
*
* This routine is pretty simple for the uC5235 because all the hard
* work has been done by the bootstrap dBUG code.
*/
#include <rtems.h>
#include <bsp.h>
#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr" : : "d" (_cacr))
#define m68k_set_acr0(_acr0) asm volatile ("movec %0,%%acr0" : : "d" (_acr0))
#define m68k_set_acr1(_acr1) asm volatile ("movec %0,%%acr1" : : "d" (_acr1))
#define MM_SDRAM_BASE (0x00000000)
void Init5235 (void)
{
extern void CopyDataClearBSSAndStart (void);
int x;
int temp = 0;
//Setup the GPIO Registers
MCF5235_GPIO_UART=0x3FFF;
MCF5235_GPIO_PAR_AD=0xE1;
//Setup the Chip Selects so CS0 is flash
MCF5235_CS_CSAR0 =(0xFFE00000 & 0xffff0000)>>16;
MCF5235_CS_CSMR0 = 0x001f0001;
MCF5235_CS_CSCR0 = 0x1980;
//Setup the SDRAM
for(x=0; x<20000; x++)
{
temp +=1;
}
MCF5235_SDRAMC_DCR = 0x042E;
MCF5235_SDRAMC_DACR0 = 0x00001300;
MCF5235_SDRAMC_DMR0 = (0x00FC0000) | (0x00000001);
for(x=0; x<20000; x++)
{
temp +=1;
}
// set ip ( bit 3 ) in dacr
MCF5235_SDRAMC_DACR0 |= (0x00000008) ;
// init precharge
*((unsigned long *)MM_SDRAM_BASE) = 0xDEADBEEF;
// set RE in dacr
MCF5235_SDRAMC_DACR0 |= (0x00008000);
// wait
for(x=0; x<20000; x++)
{
temp +=1;
}
// issue IMRS
MCF5235_SDRAMC_DACR0 |= (0x00000040);
*((short *)MM_SDRAM_BASE) = 0;
for(x=0; x<60000; x++)
{
temp +=1;
}
*((unsigned long*)MM_SDRAM_BASE)=0x12345678;
/* Copy the interrupt vector table to address 0x0 in SDRAM */
{
extern void INTERRUPT_VECTOR();
uint32_t *inttab = (uint32_t *)&INTERRUPT_VECTOR;
uint32_t *intvec = (uint32_t *)0x0;
register int i;
for (i = 0; i < 256; i++)
{
*(intvec++) = *(inttab++);
}
}
/*
* Copy data, clear BSS and call boot_card()
*/
CopyDataClearBSSAndStart ();
}

View File

@@ -0,0 +1,175 @@
/*
* This file contains directives for the GNU linker which are specific
* to the Arcturus uC DIMM ColdFire 5282
*
* 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$
*/
/*
* Declare some sizes.
*/
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x0 ;
_RamSize = DEFINED(_RamSize) ? _RamSize : 16M ;
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0 ;
/*
* System clock speed
*/
_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 150000000 ;
/*
* Location of on-chip devices
*/
__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ;
__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ;
_VBR = 0x0;
ENTRY(start)
MEMORY
{
ram : ORIGIN = 0, LENGTH = 16M
sram : ORIGIN = 0x20000000, LENGTH = 64K
flash : ORIGIN = 0xFFE00000, LENGTH = 2M
}
SECTIONS
{
_header_offset = 0;
/*
* Text, data and bss segments
*/
.text 0x40000 : {
*(.text)
*(.ram_code)
/*
* C++ constructors/destructors
*/
*(.gnu.linkonce.t.*)
/*
* Initialization and finalization code.
*
* Various files can provide initialization and finalization
* functions. crtbegin.o and crtend.o are two instances. The
* body of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues
* from crti.o and function epilogues from crtn.o. crti.o must
* be linked first; crtn.o must be linked last. Because these
* are wildcards, it doesn't matter if the user does not
* actually link against crti.o and crtn.o; the linker won't
* look for a file to match a wildcard. The wildcard also
* means that it doesn't matter which directory crti.o and
* crtn.o are in.
*/
PROVIDE (_init = .);
*crti.o(.init)
*(.init)
*crtn.o(.init)
PROVIDE (_fini = .);
*crti.o(.fini)
*(.fini)
*crtn.o(.fini)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/*
* C++ constructors/destructors
*
* gcc uses crtbegin.o to find the start of the constructors
* and destructors 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. The
* constructor and destructor list are terminated in
* crtend.o. The same comments apply to it.
*/
. = ALIGN (16);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
/*
* Exception frame info
*/
. = ALIGN (16);
*(.eh_frame)
/*
* Read-only data
*/
. = ALIGN (16);
_rodata_start = . ;
*(.rodata*)
*(.gnu.linkonce.r*)
. = ALIGN (16);
*(.console_gdb_xfer)
*(.bootstrap_data)
. = ALIGN(16);
_estuff = .;
PROVIDE (_etext = .);
} >ram
.data : {
PROVIDE( _data_dest_start = . );
PROVIDE( _copy_start = .);
*(.data)
*(.gnu.linkonce.d*)
*(.gcc_except_table)
*(.jcr)
. = ALIGN (16);
PROVIDE (_edata = .);
PROVIDE (_copy_end = .);
PROVIDE (_data_dest_end = . );
} >ram
_data_src_start = _estuff;
_data_src_end = _data_dest_start + SIZEOF(.data);
.bss : {
_clear_start = .;
*(.bss)
*(COMMON)
. = ALIGN (16);
PROVIDE (end = .);
_clear_end = .;
_WorkspaceBase = .;
} >ram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
PROVIDE (end_of_all = .);
}

View File

@@ -0,0 +1,180 @@
/*
* This file contains directives for the GNU linker which are specific
* to the Arcturus uC DIMM ColdFire 5282
*
* 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$
*/
/*
* Declare some sizes.
*/
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x0 ;
_RamSize = DEFINED(_RamSize) ? _RamSize : 16M ;
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0 ;
/*
* System clock speed
*/
_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 150000000 ;
/*
* Location of on-chip devices
*/
__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ;
__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ;
_VBR = 0x0;
ENTRY(start)
/*
* NOTE: If loading to flash with dBUG remember to change the origin to 0xFFF00000 because that's where user flash is
* located.
*/
MEMORY
{
ram : ORIGIN = 0, LENGTH = 16M
sram : ORIGIN = 0x20000000, LENGTH = 64K
flash : ORIGIN = 0xFFE00000, LENGTH = 2M
}
SECTIONS
{
_header_offset = 0;
/*
* Text, data and bss segments
*/
.text : {
*(.text)
*(.ram_code)
/*
* C++ constructors/destructors
*/
*(.gnu.linkonce.t.*)
/*
* Initialization and finalization code.
*
* Various files can provide initialization and finalization
* functions. crtbegin.o and crtend.o are two instances. The
* body of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues
* from crti.o and function epilogues from crtn.o. crti.o must
* be linked first; crtn.o must be linked last. Because these
* are wildcards, it doesn't matter if the user does not
* actually link against crti.o and crtn.o; the linker won't
* look for a file to match a wildcard. The wildcard also
* means that it doesn't matter which directory crti.o and
* crtn.o are in.
*/
PROVIDE (_init = .);
*crti.o(.init)
*(.init)
*crtn.o(.init)
PROVIDE (_fini = .);
*crti.o(.fini)
*(.fini)
*crtn.o(.fini)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/*
* C++ constructors/destructors
*
* gcc uses crtbegin.o to find the start of the constructors
* and destructors 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. The
* constructor and destructor list are terminated in
* crtend.o. The same comments apply to it.
*/
. = ALIGN (16);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
/*
* Exception frame info
*/
. = ALIGN (16);
*(.eh_frame)
/*
* Read-only data
*/
. = ALIGN (16);
_rodata_start = . ;
*(.rodata*)
*(.gnu.linkonce.r*)
. = ALIGN (16);
*(.console_gdb_xfer)
*(.bootstrap_data)
. = ALIGN(16);
_estuff = .;
PROVIDE (_etext = .);
} >flash
.data 0x4000 : AT ( ADDR(.text) + SIZEOF ( .text ) )
{
PROVIDE( _data_dest_start = . );
PROVIDE( _copy_start = .);
*(.data)
*(.gnu.linkonce.d*)
*(.gcc_except_table)
*(.jcr)
. = ALIGN (16);
PROVIDE (_edata = .);
PROVIDE (_copy_end = .);
PROVIDE (_data_dest_end = . );
} >ram
_data_src_start = _estuff;
_data_src_end = _data_dest_start + SIZEOF(.data);
.bss : {
_clear_start = .;
*(.bss)
*(COMMON)
. = ALIGN (16);
PROVIDE (end = .);
_clear_end = .;
_WorkspaceBase = .;
} >ram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
PROVIDE (end_of_all = .);
}

View File

@@ -0,0 +1,175 @@
/*
* This file contains directives for the GNU linker which are specific
* to the Arcturus uC DIMM ColdFire 5282
*
* 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$
*/
/*
* Declare some sizes.
*/
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x0 ;
_RamSize = DEFINED(_RamSize) ? _RamSize : 16M ;
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0 ;
/*
* System clock speed
*/
_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 150000000 ;
/*
* Location of on-chip devices
*/
__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ;
__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ;
_VBR = 0x0;
ENTRY(start)
MEMORY
{
ram : ORIGIN = 0, LENGTH = 16M
sram : ORIGIN = 0x20000000, LENGTH = 64K
flash : ORIGIN = 0xFFE00000, LENGTH = 2M
}
SECTIONS
{
_header_offset = 0;
/*
* Text, data and bss segments
*/
.text 0x40000 : {
*(.text)
*(.ram_code)
/*
* C++ constructors/destructors
*/
*(.gnu.linkonce.t.*)
/*
* Initialization and finalization code.
*
* Various files can provide initialization and finalization
* functions. crtbegin.o and crtend.o are two instances. The
* body of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues
* from crti.o and function epilogues from crtn.o. crti.o must
* be linked first; crtn.o must be linked last. Because these
* are wildcards, it doesn't matter if the user does not
* actually link against crti.o and crtn.o; the linker won't
* look for a file to match a wildcard. The wildcard also
* means that it doesn't matter which directory crti.o and
* crtn.o are in.
*/
PROVIDE (_init = .);
*crti.o(.init)
*(.init)
*crtn.o(.init)
PROVIDE (_fini = .);
*crti.o(.fini)
*(.fini)
*crtn.o(.fini)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/*
* C++ constructors/destructors
*
* gcc uses crtbegin.o to find the start of the constructors
* and destructors 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. The
* constructor and destructor list are terminated in
* crtend.o. The same comments apply to it.
*/
. = ALIGN (16);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
/*
* Exception frame info
*/
. = ALIGN (16);
*(.eh_frame)
/*
* Read-only data
*/
. = ALIGN (16);
_rodata_start = . ;
*(.rodata*)
*(.gnu.linkonce.r*)
. = ALIGN (16);
*(.console_gdb_xfer)
*(.bootstrap_data)
. = ALIGN(16);
_estuff = .;
PROVIDE (_etext = .);
} >ram
.data : {
PROVIDE( _data_dest_start = . );
PROVIDE( _copy_start = .);
*(.data)
*(.gnu.linkonce.d*)
*(.gcc_except_table)
*(.jcr)
. = ALIGN (16);
PROVIDE (_edata = .);
PROVIDE (_copy_end = .);
PROVIDE (_data_dest_end = . );
} >ram
_data_src_start = _estuff;
_data_src_end = _data_dest_start + SIZEOF(.data);
.bss : {
_clear_start = .;
*(.bss)
*(COMMON)
. = ALIGN (16);
PROVIDE (end = .);
_clear_end = .;
_WorkspaceBase = .;
} >ram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
PROVIDE (end_of_all = .);
}

View File

@@ -0,0 +1,43 @@
/*
* Timer Init
*
* Use the last DMA timer (DTIM3) as the diagnostic timer.
*/
#include <rtems.h>
#include <bsp.h>
void
Timer_initialize(void)
{
int preScaleDivisor = 0x4A;
int div = MCF5235_TIMER_DTMR_CLK_DIV1;
MCF5235_TIMER_DTRR3 = 0x2710;
MCF5235_TIMER3_DTMR = 0;
MCF5235_TIMER3_DTMR = MCF5235_TIMER_DTMR_PS(preScaleDivisor) | div |
MCF5235_TIMER_DTMR_RST;
}
/*
* Return timer value in microsecond units
*/
int
Read_timer(void)
{
return MCF5235_TIMER3_DTCN;
}
/*
* Empty function call used in loops to measure basic cost of looping
* in Timing Test Suite.
*/
rtems_status_code
Empty_function(void)
{
return RTEMS_SUCCESSFUL;
}
void
Set_find_average_overhead(rtems_boolean find_flag)
{
}