summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2005-06-17 14:06:05 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2005-06-17 14:06:05 +0000
commit1612af0f62aff5f0f077af77c44203cfa2f7603e (patch)
treeef72b7295687729ced88425a7736ce0ac814b9fb
parent2005-06-17 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-1612af0f62aff5f0f077af77c44203cfa2f7603e.tar.bz2
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.
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/.cvsignore14
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/ChangeLog8
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/Makefile.am121
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/README454
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/bsp_specs16
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/clock/clock.c63
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/configure.ac24
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/console/console.c799
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/include/bsp.h101
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h106
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/include/tm27.h29
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/network/network.c850
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/start/start.S392
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c35
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c220
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c80
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds175
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash180
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram175
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/timer/timer.c43
20 files changed, 3885 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/m68k/mcf5235/.cvsignore b/c/src/lib/libbsp/m68k/mcf5235/.cvsignore
new file mode 100644
index 0000000000..bfdfd995be
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/.cvsignore
@@ -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
diff --git a/c/src/lib/libbsp/m68k/mcf5235/ChangeLog b/c/src/lib/libbsp/m68k/mcf5235/ChangeLog
new file mode 100644
index 0000000000..e4a57741de
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/ChangeLog
@@ -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.
+
diff --git a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am
new file mode 100644
index 0000000000..3c069162ae
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am
@@ -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
diff --git a/c/src/lib/libbsp/m68k/mcf5235/README b/c/src/lib/libbsp/m68k/mcf5235/README
new file mode 100644
index 0000000000..c8897ea829
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/README
@@ -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 ***
diff --git a/c/src/lib/libbsp/m68k/mcf5235/bsp_specs b/c/src/lib/libbsp/m68k/mcf5235/bsp_specs
new file mode 100644
index 0000000000..6480bbd1b5
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/bsp_specs
@@ -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}
+
diff --git a/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c b/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c
new file mode 100644
index 0000000000..844be227e1
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c
@@ -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"
diff --git a/c/src/lib/libbsp/m68k/mcf5235/configure.ac b/c/src/lib/libbsp/m68k/mcf5235/configure.ac
new file mode 100644
index 0000000000..7c6366ad96
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/configure.ac
@@ -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
diff --git a/c/src/lib/libbsp/m68k/mcf5235/console/console.c b/c/src/lib/libbsp/m68k/mcf5235/console/console.c
new file mode 100644
index 0000000000..48f4179055
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/console/console.c
@@ -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]);
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/include/bsp.h b/c/src/lib/libbsp/m68k/mcf5235/include/bsp.h
new file mode 100644
index 0000000000..122be187fa
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/include/bsp.h
@@ -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 */
diff --git a/c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h b/c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h
new file mode 100644
index 0000000000..f838c5895c
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h
@@ -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
diff --git a/c/src/lib/libbsp/m68k/mcf5235/include/tm27.h b/c/src/lib/libbsp/m68k/mcf5235/include/tm27.h
new file mode 100644
index 0000000000..f8fe447335
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/include/tm27.h
@@ -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
diff --git a/c/src/lib/libbsp/m68k/mcf5235/network/network.c b/c/src/lib/libbsp/m68k/mcf5235/network/network.c
new file mode 100644
index 0000000000..fe78033e26
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/network/network.c
@@ -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;
+};
+
diff --git a/c/src/lib/libbsp/m68k/mcf5235/start/start.S b/c/src/lib/libbsp/m68k/mcf5235/start/start.S
new file mode 100644
index 0000000000..e72be12cbb
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/start/start.S
@@ -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
+
diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c b/c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c
new file mode 100644
index 0000000000..b3a8536f4f
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c
@@ -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 " );
+ }
+
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c b/c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c
new file mode 100644
index 0000000000..e16d4c0ee0
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c
@@ -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);
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c b/c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c
new file mode 100644
index 0000000000..47de7f6d3a
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c
@@ -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 ();
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds
new file mode 100644
index 0000000000..11b25c0861
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds
@@ -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 = .);
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash
new file mode 100644
index 0000000000..41f64665f7
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash
@@ -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 = .);
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram
new file mode 100644
index 0000000000..11b25c0861
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram
@@ -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 = .);
+}
diff --git a/c/src/lib/libbsp/m68k/mcf5235/timer/timer.c b/c/src/lib/libbsp/m68k/mcf5235/timer/timer.c
new file mode 100644
index 0000000000..f266afa712
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mcf5235/timer/timer.c
@@ -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)
+{
+}