summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Norum <WENorum@lbl.gov>2005-01-28 19:35:23 +0000
committerEric Norum <WENorum@lbl.gov>2005-01-28 19:35:23 +0000
commit572484f1aef2d9544b2b3db98362737a597bf093 (patch)
tree7b2b0eef034f4dd98551f1707aec9014b07e0b1c
parent2005-01-28 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-572484f1aef2d9544b2b3db98362737a597bf093.tar.bz2
New BSP for Arcturus uCDIMM ColdFire 5282.
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/m68k/ChangeLog5
-rw-r--r--c/src/lib/libbsp/m68k/acinclude.m42
-rw-r--r--c/src/lib/libbsp/m68k/shared/m68kpretaskinghook.c18
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/Makefile.am121
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/README461
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/bsp_specs27
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/clock/clock.c68
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/configure.ac24
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/console/console.c801
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/include/bsp.h102
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/include/bspopts.h.in16
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/include/coverhd.h106
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/include/tm27.h29
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/network/network.c837
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/start/start.S411
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/startup/bspclean.c35
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/startup/bspstart.c243
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/startup/init5282.c31
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/startup/linkcmds208
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/timer/timer.c47
20 files changed, 3585 insertions, 7 deletions
diff --git a/c/src/lib/libbsp/m68k/ChangeLog b/c/src/lib/libbsp/m68k/ChangeLog
index b18e25d095..bbf1d65eed 100644
--- a/c/src/lib/libbsp/m68k/ChangeLog
+++ b/c/src/lib/libbsp/m68k/ChangeLog
@@ -1,3 +1,8 @@
+2005-01-28 Eric Norum <norume@aps.anl.gov>
+ * uC5282: New BSP
+ acinclude.m4: uC5282 BSP
+ shared/m68kpretaskinghook.c: Work around agressive optimizing compilers
+
2004-09-24 Ralf Corsepius <ralf_corsepius@rtems.org>
* configure.ac: Require automake > 1.9.
diff --git a/c/src/lib/libbsp/m68k/acinclude.m4 b/c/src/lib/libbsp/m68k/acinclude.m4
index 2e80f1098e..3b6797e92a 100644
--- a/c/src/lib/libbsp/m68k/acinclude.m4
+++ b/c/src/lib/libbsp/m68k/acinclude.m4
@@ -32,6 +32,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
AC_CONFIG_SUBDIRS([ods68302]);;
sim68000 )
AC_CONFIG_SUBDIRS([sim68000]);;
+ uC5282 )
+ AC_CONFIG_SUBDIRS([uC5282]);;
*)
AC_MSG_ERROR([Invalid BSP]);;
esac
diff --git a/c/src/lib/libbsp/m68k/shared/m68kpretaskinghook.c b/c/src/lib/libbsp/m68k/shared/m68kpretaskinghook.c
index 55d12334d7..61588f93b1 100644
--- a/c/src/lib/libbsp/m68k/shared/m68kpretaskinghook.c
+++ b/c/src/lib/libbsp/m68k/shared/m68kpretaskinghook.c
@@ -34,23 +34,27 @@
extern void bsp_libc_init( void *, unsigned long, int );
extern rtems_configuration_table BSP_Configuration;
-extern void *_RamBase;
-extern void *_WorkspaceBase;
-extern void *_HeapSize;
+extern char _RamBase[];
+extern char _WorkspaceBase[];
+extern char _HeapSize[];
unsigned long _M68k_Ramsize;
void bsp_pretasking_hook(void)
{
void *heapStart;
- unsigned long heapSize = (unsigned long)&_HeapSize;
+ unsigned long heapSize = (unsigned long)_HeapSize;
unsigned long ramSpace;
heapStart = (void *)
- ((unsigned long)&_WorkspaceBase + BSP_Configuration.work_space_size);
- ramSpace = (unsigned long) &_RamBase + _M68k_Ramsize - (unsigned long) heapStart;
+ ((unsigned long)_WorkspaceBase + BSP_Configuration.work_space_size);
+ ramSpace = (unsigned long)_RamBase + _M68k_Ramsize - (unsigned long)heapStart;
- if (heapSize == 0)
+ /*
+ * Can't use 'if(heapSize==0)' because the compiler "knows" that nothing
+ * can have an address of 0 and proceeds to optimize-away the test.
+ */
+ if (heapSize < 10)
heapSize = ramSpace;
else if (heapSize > ramSpace)
rtems_fatal_error_occurred (('H'<<24) | ('E'<<16) | ('A'<<8) | 'P');
diff --git a/c/src/lib/libbsp/m68k/uC5282/Makefile.am b/c/src/lib/libbsp/m68k/uC5282/Makefile.am
new file mode 100644
index 0000000000..d3c2fb6141
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/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/init5282.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/uC5282/README b/c/src/lib/libbsp/m68k/uC5282/README
new file mode 100644
index 0000000000..94bd8b5005
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/README
@@ -0,0 +1,461 @@
+#
+# $Id$
+#
+
+Description: Arcturus Networks uC DIMM ColdFire 5282
+============
+CPU: MCF5282 @64MHz
+RAM: 16M
+ROM: 4M
+
+This is a credit-card sized board in a DIMM format. It is part of a family which
+includes Dragonball and Coldfire CPUs, with a standardized DIMM-based bus.
+
+ACKNOWLEDGEMENTS:
+=================
+This BSP is based on the work of:
+ D. Peter Siddons
+ Brett Swimley
+ Jay Monkman
+
+TODO:
+=====
+Make a clean exit routine to return to Arcturus monitor
+
+Make a real kprintf which doesn't rely on interrupts being operational
+
+The bsp relies on the Arcturus monitor to set up DRAM and all chip selects.
+This seems OK to me, but others may find it lame.....
+
+
+BSP NAME: uC5282
+BOARD: Arcturus Netrworks uCdimm 5282
+BUS: Arcturus DIMM bus, A24/D16, plus peripherals.
+CPU FAMILY: ColdFire 5282
+CPU: MCF5282
+COPROCESSORS: N/A
+MODE: 16 bit mode
+
+DEBUG MONITOR: Arcturus bootloader
+
+PERIPHERALS
+===========
+TIMERS: Four PIT (RTEMS clock is PIT3), Four Timers
+ RESOLUTION: 1 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: UART1 Terminal
+ELECTRICAL: RS-232
+BAUD: 9600
+BITS PER CHARACTER: 8
+PARITY: None
+STOP BITS: 1
+
+Downloading the image to the board.
+===================================
+
+The bootable image is generated by the make-exe target in the bsp makefile. It
+generates a simple stripped binary file which is downloaded over the ethernet
+port into RAM then executed or programmed into flash memory.
+
+1) Power up the uC5282 board. A dump of some memory map is produced
+ followed by a prompt.
+
+2) type 'tftp<CR>'
+
+3) Run 'tftp' on your host machine:
+ tftp> binary
+ tftp> connect www.xxx.yyy.zzz (You're ucDIMM's address)
+ tftp> put someFile.exe
+
+4) When the file has downloaded press the <ESC> key to terminate
+ the uCDIMM tftp command.
+
+5) Type 'goram<CR>' to start the downloaded program, or type 'program<CR>'
+to burn the code onto the uCDIMM flash.
+
+============================================================================
+
+ 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 | External 4 MByte flash memory |
+ . .
+ . .
+ . .
+ | | 1FFF FFFF
+ +--------------------------------------------------+
+2000 0000 | 64 kByte on-chip SRAM (RAMBAR) |
+ . .
+ . .
+ . .
+ | | 2FFF FFFF
+ +--------------------------------------------------+
+3000 0000 | CS1* space (First 'VME' A24/D16 space) | 30FF FFFF
+3100 0000 | CS2* space (Second 'VME' A24/D16 space) | 31FF FFFF
+ . .
+ . .
+ . .
+ | | 3FFF FFFF
+ +--------------------------------------------------+
+4000 0000 | Internal peripheral system (IPSBAR) |
+ . .
+4400 0000 | Backdoor access to on-chip flash |
+ . .
+ . .
+ . .
+ | | 4FFF FFFF
+ +--------------------------------------------------+
+ . .
+ . .
+ . .
+ +--------------------------------------------------+
+f000 0000 | 512 kByte on-chip flash (FLASHBAR) |
+ . .
+ . .
+ . .
+ | | fFFF FFFF
+ +--------------------------------------------------+
+
+
+TIMING TESTS 2005-01-28
+========================
+
+*** TIME TEST 1 ***
+rtems_semaphore_create 19
+rtems_semaphore_delete 21
+rtems_semaphore_obtain: available 4
+rtems_semaphore_obtain: not available -- NO_WAIT 5
+rtems_semaphore_release: no waiting tasks 12
+*** END OF TEST 1 ***
+
+*** TIME TEST 2 ***
+rtems_semaphore_obtain: not available -- caller blocks 34
+*** END OF TEST 2 ***
+
+*** TIME TEST 3 ***
+rtems_semaphore_release: task readied -- preempts caller 27
+*** END OF TEST 3 ***
+
+*** TIME TEST 4 ***
+rtems_task_restart: blocked task -- preempts caller 54
+rtems_task_restart: ready task -- preempts caller 52
+rtems_semaphore_release: task readied -- returns to caller 18
+rtems_task_create 87
+rtems_task_start 24
+rtems_task_restart: suspended task -- returns to caller 27
+rtems_task_delete: suspended task 66
+rtems_task_restart: ready task -- returns to caller 28
+rtems_task_restart: blocked task -- returns to caller 38
+rtems_task_delete: blocked task 69
+*** END OF TEST 4 ***
+
+*** TIME TEST 5 ***
+rtems_task_suspend: calling task 23
+rtems_task_resume: task readied -- preempts caller 22
+*** END OF TEST 5 ***
+
+*** TIME TEST 6 ***
+rtems_task_restart: calling task 30
+rtems_task_suspend: returns to caller 9
+rtems_task_resume: task readied -- returns to caller 12
+rtems_task_delete: ready task 69
+*** END OF TEST 6 ***
+
+*** TIME TEST 7 ***
+rtems_task_restart: suspended task -- preempts caller 44
+*** END OF TEST 7 ***
+
+*** TIME TEST 8 ***
+rtems_task_set_priority: obtain current priority 6
+rtems_task_set_priority: returns to caller 17
+rtems_task_mode: obtain current mode 3
+rtems_task_mode: no reschedule 3
+rtems_task_mode: reschedule -- returns to caller 8
+rtems_task_mode: reschedule -- preempts caller 22
+rtems_task_set_note 6
+rtems_task_get_note 6
+rtems_clock_set 22
+rtems_clock_get 1
+*** END OF TEST 8 ***
+
+*** TIME TEST 9 ***
+rtems_message_queue_create 55
+rtems_message_queue_send: no waiting tasks 20
+rtems_message_queue_urgent: no waiting tasks 21
+rtems_message_queue_receive: available 20
+rtems_message_queue_flush: no messages flushed 8
+rtems_message_queue_flush: messages flushed 12
+rtems_message_queue_delete 29
+*** END OF TEST 9 ***
+
+*** TIME TEST 10 ***
+rtems_message_queue_receive: not available -- NO_WAIT 10
+rtems_message_queue_receive: not available -- caller blocks 38
+*** END OF TEST 10 ***
+
+*** TIME TEST 11 ***
+rtems_message_queue_send: task readied -- preempts caller 37
+*** END OF TEST 11 ***
+
+*** TIME TEST 12 ***
+rtems_message_queue_send: task readied -- returns to caller 23
+*** END OF TEST 12 ***
+
+*** TIME TEST 13 ***
+rtems_message_queue_urgent: task readied -- preempts caller 35
+*** END OF TEST 13 ***
+
+*** TIME TEST 14 ***
+rtems_message_queue_urgent: task readied -- returns to caller 24
+*** END OF TEST 14 ***
+
+*** TIME TEST 15 ***
+rtems_event_receive: obtain current events 0
+rtems_event_receive: not available -- NO_WAIT 5
+rtems_event_receive: not available -- caller blocks 28
+rtems_event_send: no task readied 5
+rtems_event_receive: available 9
+rtems_event_send: task readied -- returns to caller 16
+*** END OF TEST 15 ***
+
+*** TIME TEST 16 ***
+rtems_event_send: task readied -- preempts caller 27
+*** END OF TEST 16 ***
+
+*** TIME TEST 17 ***
+rtems_task_set_priority: preempts caller 39
+*** END OF TEST 17 ***
+
+*** TIME TEST 18 ***
+rtems_task_delete: calling task 83
+*** END OF TEST 18 ***
+
+*** TIME TEST 19 ***
+rtems_signal_catch 5
+rtems_signal_send: returns to caller 12
+rtems_signal_send: signal to self 20
+exit ASR overhead: returns to calling task 15
+exit ASR overhead: returns to preempting task 18
+*** END OF TEST 19 ***
+
+*** TIME TEST 20 ***
+rtems_partition_create 20
+rtems_region_create 40
+rtems_partition_get_buffer: available 11
+rtems_partition_get_buffer: not available 7
+rtems_partition_return_buffer 12
+rtems_partition_delete 11
+rtems_region_get_segment: available 28
+rtems_region_get_segment: not available -- NO_WAIT 29
+rtems_region_return_segment: no waiting tasks 29
+rtems_region_get_segment: not available -- caller blocks 55
+rtems_region_return_segment: task readied -- preempts caller 72
+rtems_region_return_segment: task readied -- returns to caller 58
+rtems_region_delete 25
+rtems_io_initialize 1
+rtems_io_open 1
+rtems_io_close 1
+rtems_io_read 1
+rtems_io_write 1
+rtems_io_control 1
+*** END OF TEST 20 ***
+
+*** TIME TEST 21 ***
+rtems_task_ident 60
+rtems_message_queue_ident 60
+rtems_semaphore_ident 69
+rtems_partition_ident 59
+rtems_region_ident 60
+rtems_port_ident 59
+rtems_timer_ident 61
+rtems_rate_monotonic_ident 60
+*** END OF TEST 21 ***
+
+*** TIME TEST 22 ***
+rtems_message_queue_broadcast: task readied -- returns to caller 32
+rtems_message_queue_broadcast: no waiting tasks 14
+rtems_message_queue_broadcast: task readied -- preempts caller 39
+*** END OF TEST 22 ***
+
+*** TIME TEST 23 ***
+rtems_timer_create 8
+rtems_timer_fire_after: inactive 12
+rtems_timer_fire_after: active 12
+rtems_timer_cancel: active 9
+rtems_timer_cancel: inactive 8
+rtems_timer_reset: inactive 14
+rtems_timer_reset: active 15
+rtems_timer_fire_when: inactive 21
+rtems_timer_fire_when: active 21
+rtems_timer_delete: active 12
+rtems_timer_delete: inactive 11
+rtems_task_wake_when 35
+*** END OF TEST 23 ***
+
+*** TIME TEST 24 ***
+rtems_task_wake_after: yield -- returns to caller 3
+rtems_task_wake_after: yields -- preempts caller 18
+*** END OF TEST 24 ***
+
+*** TIME TEST 25 ***
+rtems_clock_tick 7
+*** END OF TEST 25 ***
+
+*** TIME TEST 26 ***
+_ISR_Disable 1
+_ISR_Flash 0
+_ISR_Enable 0
+_Thread_Disable_dispatch 1
+_Thread_Enable_dispatch 3
+_Thread_Set_state 7
+_Thread_Disptach (NO FP) 16
+context switch: no floating point contexts 12
+context switch: self 2
+context switch: to another task 1
+fp context switch: restore 1st FP task 14
+fp context switch: save idle, restore initialized 3
+fp context switch: save idle, restore idle 13
+fp context switch: save initialized, restore initialized 2
+_Thread_Resume 7
+_Thread_Unblock 6
+_Thread_Ready 5
+_Thread_Get 1
+_Semaphore_Get 1
+_Thread_Get: invalid id 0
+*** END OF TEST 26 ***
+
+*** TIME TEST 27 ***
+interrupt entry overhead: returns to interrupted task 3
+interrupt exit overhead: returns to interrupted task 3
+interrupt entry overhead: returns to nested interrupt 2
+interrupt exit overhead: returns to nested interrupt 2
+interrupt entry overhead: returns to preempting task 4
+interrupt exit overhead: returns to preempting task 20
+*** END OF TEST 27 ***
+
+*** TIME TEST 28 ***
+rtems_port_create 12
+rtems_port_external_to_internal 5
+rtems_port_internal_to_external 6
+rtems_port_delete 12
+*** END OF TEST 28 ***
+
+*** TIME TEST 29 ***
+rtems_rate_monotonic_create 13
+rtems_rate_monotonic_period: initiate period -- returns to caller 20
+rtems_rate_monotonic_period: obtain status 10
+rtems_rate_monotonic_cancel 13
+rtems_rate_monotonic_delete: inactive 17
+rtems_rate_monotonic_delete: active 16
+rtems_rate_monotonic_period: conclude periods -- caller blocks 24
+*** END OF TEST 29 ***
+
+*** TIME CHECKER ***
+Units may not be in microseconds for this test!!!
+0 100000
+Total time = 0
+Average time = 0
+NULL timer stopped at 0
+LOOP (1000) timer stopped at 188
+LOOP (10000) timer stopped at 1875
+LOOP (50000) timer stopped at 9375
+LOOP (100000) timer stopped at 18750
+*** 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 1
+rtems_task_wake_after 0
+rtems_interrupt_catch 0
+rtems_clock_get 1
+rtems_clock_set 1
+rtems_clock_tick 0
+rtems_timer_create 0
+rtems_timer_delete 0
+rtems_timer_ident 0
+rtems_timer_fire_after 1
+rtems_timer_fire_when 1
+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
+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
+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/uC5282/bsp_specs b/c/src/lib/libbsp/m68k/uC5282/bsp_specs
new file mode 100644
index 0000000000..2c6a9757e2
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/bsp_specs
@@ -0,0 +1,27 @@
+%rename cpp old_cpp
+%rename lib old_lib
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*cpp:
+%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
+
+*lib:
+%{!qrtems: %(old_lib)} %{!nostdlib: %{qrtems: --start-group \
+%{!qrtems_debug: -lrtemsbsp -lrtemscpu} %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
+-lc -lgcc --end-group \
+%{!qnolinkcmds: -T linkcmds%s}}}
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{!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/uC5282/clock/clock.c b/c/src/lib/libbsp/m68k/uC5282/clock/clock.c
new file mode 100644
index 0000000000..8b10dbfd28
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/clock/clock.c
@@ -0,0 +1,68 @@
+/*
+ * Use the last periodic interval timer (PIT3) as the system clock.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <mcf5282/mcf5282.h>
+
+/*
+ * Use INTC0 base
+ */
+#define CLOCK_VECTOR (64+58)
+
+/*
+ * Periodic interval timer interrupt handler
+ */
+#define Clock_driver_support_at_tick() \
+ do { \
+ MCF5282_PIT3_PCSR |= MCF5282_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 { \
+ MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN; \
+ } while(0)
+
+/*
+ * Set up the clock hardware
+ *
+ * Prescale so that it counts in microseconds
+ * System clock frequency better be 2**n (1<=n<=16) MHz!
+ */
+#define Clock_driver_support_initialize_hardware() \
+ do { \
+ int level; \
+ int preScaleCode = -2; \
+ int preScaleDivisor = get_CPU_clock_speed() / 1000000; \
+ while (preScaleDivisor) { \
+ preScaleDivisor >>= 1; \
+ preScaleCode++; \
+ } \
+ MCF5282_INTC0_ICR58 = MCF5282_INTC_ICR_IL(PIT3_IRQ_LEVEL) | \
+ MCF5282_INTC_ICR_IP(PIT3_IRQ_PRIORITY); \
+ rtems_interrupt_disable( level ); \
+ MCF5282_INTC0_IMRH &= ~MCF5282_INTC_IMRH_INT58; \
+ MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN; \
+ rtems_interrupt_enable( level ); \
+ MCF5282_PIT3_PMR = BSP_Configuration.microseconds_per_tick - 1; \
+ MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \
+ MCF5282_PIT_PCSR_PIE | \
+ MCF5282_PIT_PCSR_RLD | \
+ MCF5282_PIT_PCSR_EN; \
+ } while (0)
+
+#include "../../../shared/clockdrv_shell.c"
diff --git a/c/src/lib/libbsp/m68k/uC5282/configure.ac b/c/src/lib/libbsp/m68k/uC5282/configure.ac
new file mode 100644
index 0000000000..53b349f0ee
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/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-uC5282],[_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/uC5282/console/console.c b/c/src/lib/libbsp/m68k/uC5282/console/console.c
new file mode 100644
index 0000000000..f651309fb4
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/console/console.c
@@ -0,0 +1,801 @@
+ /*
+ * 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 MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \
+ MCF5282_UART_USR_FE | \
+ MCF5282_UART_USR_PE | \
+ MCF5282_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 ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 )
+ continue;
+ MCF5282_UART_UTB(CONSOLE_PORT) = c;
+ while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_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;
+/* case B576000:
+ baud = (int)576000; */
+ 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 */
+ MCF5282_UART_UIMR(minor) = 0;
+ MCF5282_UART_UOP0(minor) = 1;
+ MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_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 / ( 32 * baud ));
+ if ( divisor < 2 )
+ divisor = 2;
+
+ /* check to see if doing hardware flow control */
+ if ( hwflow )
+ {
+ /* set hardware flow options */
+ umr1 |= MCF5282_UART_UMR1_RXRTS;
+ umr2 |= MCF5282_UART_UMR2_TXCTS;
+ }
+
+ /* determine the new umr values */
+ umr1 |= (parity | databits);
+ umr2 |= (stopbits);
+
+ /* reset the uart */
+ MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR;
+ MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX;
+ MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX;
+
+ /* reset the uart mode register and update values */
+ MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR;
+ MCF5282_UART_UMR(minor) = umr1;
+ MCF5282_UART_UMR(minor) = umr2;
+
+ /* set the baud rate values */
+ MCF5282_UART_UCSR(minor) = (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK);
+ MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
+ MCF5282_UART_UBG2(minor) = (divisor & 0x00ff);
+
+ /* enable the uart */
+ MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED);
+
+ /* check to see if interrupts need to be enabled */
+ if ( info->iomode != TERMIOS_POLLED )
+ {
+ /* enable rx interrupts */
+ info->uimr |= MCF5282_UART_UIMR_FFULL;
+ MCF5282_UART_UIMR(minor) = info->uimr;
+ }
+
+ /* check to see if doing hardware flow control */
+ if ( hwflow )
+ {
+ /* assert the RTS line */
+ MCF5282_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)9600;
+ int databits = (int)MCF5282_UART_UMR1_BC_8;
+ int parity = (int)MCF5282_UART_UMR1_PM_NONE;
+ int stopbits = (int)MCF5282_UART_UMR2_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)MCF5282_UART_UMR1_BC_5;
+ break;
+ case CS6:
+ databits = (int)MCF5282_UART_UMR1_BC_6;
+ break;
+ case CS7:
+ databits = (int)MCF5282_UART_UMR1_BC_7;
+ break;
+ case CS8:
+ databits = (int)MCF5282_UART_UMR1_BC_8;
+ break;
+ }
+
+ /* determine if parity is enabled */
+ if ( t->c_cflag & PARENB )
+ {
+ if ( t->c_cflag & PARODD )
+ {
+ /* odd parity */
+ parity = (int)MCF5282_UART_UMR1_PM_ODD;
+ }
+ else
+ {
+ /* even parity */
+ parity = (int)MCF5282_UART_UMR1_PM_EVEN;
+ }
+ }
+
+ /* determine stop bits */
+ if ( t->c_cflag & CSTOPB )
+ {
+ /* two stop bits */
+ stopbits = (int)MCF5282_UART_UMR2_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 ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY )
+ {
+ /* read data and put into the receive buffer */
+ while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY )
+ {
+
+ if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR )
+ {
+ /* clear the error */
+ MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR;
+ }
+ /* put data in rx buffer and check for errors */
+ info->rx_buffer[info->rx_in] = MCF5282_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 & MCF5282_UART_UIMR_TXRDY ) &&
+ ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) )
+ {
+
+ /* disable tx interrupts */
+ info->uimr &= ~MCF5282_UART_UIMR_TXRDY;
+ MCF5282_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;
+
+ MCF5282_UART_UACR(chan) = 0;
+ MCF5282_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:
+ MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) |
+ MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY);
+ MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 |
+ MCF5282_INTC_IMRL_MASKALL);
+ break;
+
+ case 1:
+ MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) |
+ MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY);
+ MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 |
+ MCF5282_INTC_IMRL_MASKALL);
+ break;
+
+ case 2:
+ MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) |
+ MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY);
+ MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 |
+ MCF5282_INTC_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 */
+ MCF5282_UART_UTB(minor) = *buf;
+
+ /* enable tx interrupt */
+ IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY;
+ MCF5282_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 */
+ MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED);
+
+ /* check to see if interrupts need to be enabled */
+ if ( info->iomode != TERMIOS_POLLED )
+ {
+ /* enable rx interrupts */
+ info->uimr |= MCF5282_UART_UIMR_FFULL;
+ MCF5282_UART_UIMR(minor) = info->uimr;
+ }
+
+ /* check to see if doing hardware flow control */
+ if ( info->hwflow )
+ {
+ /* assert the RTS line */
+ MCF5282_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 */
+ MCF5282_UART_UIMR(minor) = 0;
+ MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_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 ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 )
+ return(-1);
+
+ return(MCF5282_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 ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 )
+ continue;
+ /* transmit data byte */
+ MCF5282_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/uC5282/include/bsp.h b/c/src/lib/libbsp/m68k/uC5282/include/bsp.h
new file mode 100644
index 0000000000..adebee3fc8
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/include/bsp.h
@@ -0,0 +1,102 @@
+/*
+ * uC5282 BSP header file
+ */
+
+#ifndef __SBC5282_BSP_H
+#define __SBC5282_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 <mcf5282/mcf5282.h> /* internal MCF5282 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/uC5282/include/bspopts.h.in b/c/src/lib/libbsp/m68k/uC5282/include/bspopts.h.in
new file mode 100644
index 0000000000..f11cf7efbb
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/include/bspopts.h.in
@@ -0,0 +1,16 @@
+/* include/bspopts.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
diff --git a/c/src/lib/libbsp/m68k/uC5282/include/coverhd.h b/c/src/lib/libbsp/m68k/uC5282/include/coverhd.h
new file mode 100644
index 0000000000..f838c5895c
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/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/uC5282/include/tm27.h b/c/src/lib/libbsp/m68k/uC5282/include/tm27.h
new file mode 100644
index 0000000000..f8fe447335
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/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/uC5282/network/network.c b/c/src/lib/libbsp/m68k/uC5282/network/network.c
new file mode 100644
index 0000000000..72685f6a09
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/network/network.c
@@ -0,0 +1,837 @@
+/*
+ * RTEMS/TCPIP driver for MCF5282 Fast Ethernet Controller
+ *
+ * TO DO: MII communications to set speed, full/half duplex, etc.
+ * 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/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 mcf5282BufferDescriptor_ {
+ volatile rtems_unsigned16 status;
+ rtems_unsigned16 length;
+ volatile void *buffer;
+} mcf5282BufferDescriptor_t;
+
+/*
+ * Per-device data
+ */
+struct mcf5282_enet_struct {
+ struct arpcom arpcom;
+ struct mbuf **rxMbuf;
+ struct mbuf **txMbuf;
+ int acceptBroadcast;
+ int rxBdCount;
+ int txBdCount;
+ int txBdHead;
+ int txBdTail;
+ int txBdActiveCount;
+ mcf5282BufferDescriptor_t *rxBdBase;
+ mcf5282BufferDescriptor_t *txBdBase;
+ rtems_id rxDaemonTid;
+ rtems_id txDaemonTid;
+
+ /*
+ * Statistics
+ */
+ unsigned long rxInterrupts;
+ unsigned long txInterrupts;
+ unsigned long txRawWait;
+ unsigned long txRealign;
+};
+static struct mcf5282_enet_struct enet_driver[NIFACES];
+
+static rtems_isr
+mcf5282_fec_rx_interrupt_handler( rtems_vector_number v )
+{
+ MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
+ MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_RXF;
+ enet_driver[0].rxInterrupts++;
+ rtems_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
+}
+
+static rtems_isr
+mcf5282_fec_tx_interrupt_handler( rtems_vector_number v )
+{
+ MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
+ MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_TXF;
+ enet_driver[0].txInterrupts++;
+ rtems_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
+}
+
+/*
+ * Allocate buffer descriptors from SRAM
+ * Ensure 128-bit (16-byte)alignment
+ */
+static void *
+mcf5282_bd_allocate(unsigned int count)
+{
+ char *p;
+
+ p = malloc((count * sizeof(mcf5282BufferDescriptor_t)) + 15, 0, M_NOWAIT);
+ if (!p)
+ rtems_panic("FEC BD");
+ if ((int)p & 0xF)
+ p += 16 - ((int)p & 0xF);
+printf("Allocate %d at %p\n", count, p);
+ return p;
+}
+
+/*
+ * Retrieve MAC address from bootloader environment variable area.
+ * Parameter is interface number (0 or 1).
+ */
+static unsigned char *
+gethwaddr(int a)
+{
+ register long __res __asm__ ("%d2") = 12;
+ register long __a __asm__ ("%d1") = (long)a;
+ __asm__ __volatile__ ("trap #2" \
+ : "=g" (__res) \
+ : "0" (__res), "d" (__a) \
+ : "%d0");
+ return (unsigned char *)(__res);
+}
+
+static void
+mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc)
+{
+ int i;
+ unsigned char *hwaddr;
+ rtems_status_code status;
+ rtems_isr_entry old_handler;
+ unsigned32 clock_speed = get_CPU_clock_speed();
+
+/* extern struct rtems_bsdnet_ifconfig netdriver_config; */
+
+
+ /*
+ * Issue reset to FEC
+ */
+ MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET;
+ rtems_task_wake_after( 1 );
+ /*
+ * Configuration of I/O ports is done outside of this function
+ */
+#if 0
+ imm->gpio.pbcnt |= MCF5282_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
+#endif
+
+ /*
+ * Set our physical address
+ */
+ hwaddr = sc->arpcom.ac_enaddr;
+ MCF5282_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
+ (hwaddr[2] << 8) | (hwaddr[3] << 0);
+ MCF5282_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
+
+
+ /*
+ * Clear the hash table
+ */
+ MCF5282_FEC_GAUR = 0;
+ MCF5282_FEC_GALR = 0;
+
+ /*
+ * Set up receive buffer size
+ */
+ MCF5282_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 = mcf5282_bd_allocate(sc->rxBdCount);
+ sc->txBdBase = mcf5282_bd_allocate(sc->txBdCount);
+ MCF5282_FEC_ERDSR = (int)sc->rxBdBase;
+ MCF5282_FEC_ETDSR = (int)sc->txBdBase;
+
+ /*
+ * Set up Receive Control Register:
+ * Not promiscuous
+ * MII mode
+ * Half duplex
+ * No loopback
+ */
+ MCF5282_FEC_RCR = MCF5282_FEC_RCR_MAX_FL(MAX_MTU_SIZE) |
+ MCF5282_FEC_RCR_MII_MODE |
+ MCF5282_FEC_RCR_DRT;
+
+ /*
+ * Set up Transmit Control Register:
+ * Half duplex
+ * No heartbeat
+ */
+ MCF5282_FEC_TCR = 0;
+
+ /*
+ * Initialize statistic counters
+ */
+ MCF5282_FEC_MIBC = MCF5282_FEC_MIBC_MIB_DISABLE;
+ {
+ vuint32 *vuip = &MCF5282_FEC_RMON_T_DROP;
+ while (vuip <= &MCF5282_FEC_IEEE_R_OCTETS_OK)
+ *vuip++ = 0;
+ }
+ MCF5282_FEC_MIBC = 0;
+
+ /*
+ * Set MII speed to <2.5 MHz
+ */
+ if (clock_speed <= 25000000)
+ MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(0x5);
+ else if (clock_speed <= 33000000)
+ MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(0x7);
+ else if (clock_speed <= 40000000)
+ MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(0x8);
+ else if (clock_speed <= 50000000)
+ MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(0xA);
+ else if (clock_speed <= 66000000)
+ MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(0xD);
+ else
+ MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(0xF);
+
+ /*
+ * 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( mcf5282_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler );
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't attach MCF5282 FEC TX interrupt handler: %s\n",
+ rtems_status_text(status));
+ status = rtems_interrupt_catch(mcf5282_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_panic ("Can't attach MCF5282 FEC RX interrupt handler: %s\n",
+ rtems_status_text(status));
+ MCF5282_INTC0_ICR23 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) |
+ MCF5282_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY);
+ MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT23 | MCF5282_INTC_IMRL_MASKALL);
+ MCF5282_INTC0_ICR27 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) |
+ MCF5282_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY);
+ MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT27 | MCF5282_INTC_IMRL_MASKALL);
+}
+
+/*
+ * Soak up buffer descriptors that have been sent.
+ */
+static void
+fec_retire_tx_bd(volatile struct mcf5282_enet_struct *sc )
+{
+ struct mbuf *m, *n;
+
+ while ((sc->txBdActiveCount != 0)
+ && ((sc->txBdBase[sc->txBdTail].status & MCF5282_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 mcf5282_enet_struct *sc = (volatile struct mcf5282_enet_struct *)arg;
+ struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
+ struct mbuf *m;
+ volatile rtems_unsigned16 status;
+ volatile mcf5282BufferDescriptor_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 = MCF5282_FEC_RxBD_E;
+ if (++rxBdIndex == sc->rxBdCount) {
+ rxBd->status |= MCF5282_FEC_RxBD_W;
+ break;
+ }
+ }
+
+ /*
+ * Input packet handling loop
+ */
+ /* Indicate we have some ready buffers available */
+ MCF5282_FEC_RDAR = MCF5282_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) & MCF5282_FEC_RxBD_E) {
+ /*
+ * Clear old events.
+ */
+ MCF5282_FEC_EIR = MCF5282_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) & MCF5282_FEC_RxBD_E) {
+ rtems_event_set events;
+ int level;
+
+ rtems_interrupt_disable(level);
+ MCF5282_FEC_EIMR |= MCF5282_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 & MCF5282_FEC_RxBD_L) {
+ /*
+ * Pass the packet up the chain.
+ * FIXME: Packet filtering hook could be done here.
+ */
+ struct ether_header *eh;
+
+ /*
+ * Invalidate the buffer for this descriptor
+ */
+ m = sc->rxMbuf[rxBdIndex];
+ m->m_len = m->m_pkthdr.len = rxBd->length -
+ sizeof(rtems_unsigned32) -
+ 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 & MCF5282_FEC_RxBD_W) | MCF5282_FEC_RxBD_E;
+ MCF5282_FEC_RDAR = MCF5282_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 mcf5282_enet_struct *sc = ifp->if_softc;
+ volatile mcf5282BufferDescriptor_t *firstTxBd, *txBd;
+ rtems_unsigned16 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.
+ */
+ MCF5282_FEC_EIR = MCF5282_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);
+ MCF5282_FEC_EIMR |= MCF5282_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 ? MCF5282_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);
+ unsigned16 *o = (unsigned16 *)dest, *i = (unsigned16 *)p;
+ while (l > 0) {
+ *o++ = *i++;
+ l -= sizeof(unsigned16);
+ }
+ p = dest;
+ sc->txRealign++;
+ }
+ txBd->buffer = p;
+ txBd->length = m->m_len;
+ sc->txMbuf[sc->txBdHead] = m;
+ nAdded++;
+ if (++sc->txBdHead == sc->txBdCount) {
+ status |= MCF5282_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 | MCF5282_FEC_TxBD_R
+ | MCF5282_FEC_TxBD_L
+ | MCF5282_FEC_TxBD_TC;
+ if (nAdded > 1)
+ firstTxBd->status |= MCF5282_FEC_TxBD_R;
+ MCF5282_FEC_TDAR = MCF5282_FEC_TDAR_X_DES_ACTIVE;
+ sc->txBdActiveCount += nAdded;
+ }
+ break;
+ }
+ txBd->status = status;
+ }
+}
+
+void
+fec_txDaemon(void *arg)
+{
+ struct mcf5282_enet_struct *sc = (struct mcf5282_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
+mcf5282_enet_start(struct ifnet *ifp)
+{
+ struct mcf5282_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 mcf5282_enet_struct *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ if (sc->txDaemonTid == 0) {
+ /*
+ * Set up hardware
+ */
+ mcf5282_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)
+ MCF5282_FEC_RCR |= MCF5282_FEC_RCR_PROM;
+ else
+ MCF5282_FEC_RCR &= ~MCF5282_FEC_RCR_PROM;
+
+ /*
+ * Tell the world that we're running.
+ */
+ ifp->if_flags |= IFF_RUNNING;
+
+ /*
+ * Enable receiver and transmitter
+ */
+ MCF5282_FEC_ECR = MCF5282_FEC_ECR_ETHER_EN;
+}
+
+
+static void
+fec_stop(struct mcf5282_enet_struct *sc)
+{
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ ifp->if_flags &= ~IFF_RUNNING;
+
+ /*
+ * Shut down receiver and transmitter
+ */
+ MCF5282_FEC_ECR = 0x0;
+}
+
+/*
+ * Show interface statistics
+ */
+static void
+enet_stats(struct mcf5282_enet_struct *sc)
+{
+ printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
+ printf("Rx Packet Count:%-10lu", MCF5282_FEC_RMON_R_PACKETS);
+ printf(" Rx Broadcast:%-10lu\n", MCF5282_FEC_RMON_R_BC_PKT);
+ printf(" Rx Multicast:%-10lu", MCF5282_FEC_RMON_R_MC_PKT);
+ printf("CRC/Align error:%-10lu", MCF5282_FEC_RMON_R_CRC_ALIGN);
+ printf(" Rx Undersize:%-10lu\n", MCF5282_FEC_RMON_R_UNDERSIZE);
+ printf(" Rx Oversize:%-10lu", MCF5282_FEC_RMON_R_OVERSIZE);
+ printf(" Rx Fragment:%-10lu", MCF5282_FEC_RMON_R_FRAG);
+ printf(" Rx Jabber:%-10lu\n", MCF5282_FEC_RMON_R_JAB);
+ printf(" Rx 64:%-10lu", MCF5282_FEC_RMON_R_P64);
+ printf(" Rx 65-127:%-10lu", MCF5282_FEC_RMON_R_P65T0127);
+ printf(" Rx 128-255:%-10lu\n", MCF5282_FEC_RMON_R_P128TO255);
+ printf(" Rx 256-511:%-10lu", MCF5282_FEC_RMON_R_P256TO511);
+ printf(" Rx 511-1023:%-10lu", MCF5282_FEC_RMON_R_P512TO1023);
+ printf(" Rx 1024-2047:%-10lu\n", MCF5282_FEC_RMON_R_P1024TO2047);
+ printf(" Rx >=2048:%-10lu", MCF5282_FEC_RMON_R_GTE2048);
+ printf(" Rx Octets:%-10lu", MCF5282_FEC_RMON_R_OCTETS);
+ printf(" Rx Dropped:%-10lu\n", MCF5282_FEC_IEEE_R_DROP);
+ printf(" Rx frame OK:%-10lu", MCF5282_FEC_IEEE_R_FRAME_OK);
+ printf(" Rx CRC error:%-10lu", MCF5282_FEC_IEEE_R_CRC);
+ printf(" Rx Align error:%-10lu\n", MCF5282_FEC_IEEE_R_ALIGN);
+ printf(" FIFO Overflow:%-10lu", MCF5282_FEC_IEEE_R_MACERR);
+ printf("Rx Pause Frames:%-10lu", MCF5282_FEC_IEEE_R_FDXFC);
+ printf(" Rx Octets OK:%-10lu\n", MCF5282_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", MCF5282_FEC_RMON_T_DROP);
+ printf("Tx Packet Count:%-10lu", MCF5282_FEC_RMON_T_PACKETS);
+ printf(" Tx Broadcast:%-10lu\n", MCF5282_FEC_RMON_T_BC_PKT);
+ printf(" Tx Multicast:%-10lu", MCF5282_FEC_RMON_T_MC_PKT);
+ printf("CRC/Align error:%-10lu", MCF5282_FEC_RMON_T_CRC_ALIGN);
+ printf(" Tx Undersize:%-10lu\n", MCF5282_FEC_RMON_T_UNDERSIZE);
+ printf(" Tx Oversize:%-10lu", MCF5282_FEC_RMON_T_OVERSIZE);
+ printf(" Tx Fragment:%-10lu", MCF5282_FEC_RMON_T_FRAG);
+ printf(" Tx Jabber:%-10lu\n", MCF5282_FEC_RMON_T_JAB);
+ printf(" Tx Collisions:%-10lu", MCF5282_FEC_RMON_T_COL);
+ printf(" Tx 64:%-10lu", MCF5282_FEC_RMON_T_P64);
+ printf(" Tx 65-127:%-10lu\n", MCF5282_FEC_RMON_T_P65TO127);
+ printf(" Tx 128-255:%-10lu", MCF5282_FEC_RMON_T_P128TO255);
+ printf(" Tx 256-511:%-10lu", MCF5282_FEC_RMON_T_P256TO511);
+ printf(" Tx 511-1023:%-10lu\n", MCF5282_FEC_RMON_T_P512TO1023);
+ printf(" Tx 1024-2047:%-10lu", MCF5282_FEC_RMON_T_P1024TO2047);
+ printf(" Tx >=2048:%-10lu", MCF5282_FEC_RMON_T_P_GTE2048);
+ printf(" Tx Octets:%-10lu\n", MCF5282_FEC_RMON_T_OCTETS);
+ printf(" Tx Dropped:%-10lu", MCF5282_FEC_IEEE_T_DROP);
+ printf(" Tx Frame OK:%-10lu", MCF5282_FEC_IEEE_T_FRAME_OK);
+ printf(" Tx 1 Collision:%-10lu\n", MCF5282_FEC_IEEE_T_1COL);
+ printf("Tx >1 Collision:%-10lu", MCF5282_FEC_IEEE_T_MCOL);
+ printf(" Tx Deferred:%-10lu", MCF5282_FEC_IEEE_T_DEF);
+ printf(" Late Collision:%-10lu\n", MCF5282_FEC_IEEE_T_LCOL);
+ printf(" Excessive Coll:%-10lu", MCF5282_FEC_IEEE_T_EXCOL);
+ printf(" FIFO Underrun:%-10lu", MCF5282_FEC_IEEE_T_MACERR);
+ printf(" Carrier Error:%-10lu\n", MCF5282_FEC_IEEE_T_CSERR);
+ printf(" Tx SQE Error:%-10lu", MCF5282_FEC_IEEE_T_SQE);
+ printf("Tx Pause Frames:%-10lu", MCF5282_FEC_IEEE_T_FDXFC);
+ printf(" Tx Octets OK:%-10lu\n", MCF5282_FEC_IEEE_T_OCTETS_OK);
+}
+
+static int
+fec_ioctl(struct ifnet *ifp, int command, caddr_t data)
+{
+ struct mcf5282_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 mcf5282_enet_struct *sc;
+ struct ifnet *ifp;
+ int mtu;
+ int unitNumber;
+ char *unitName;
+ unsigned char *hwaddr;
+
+printf("attaching\n"); rtems_task_wake_after(10);
+ /*
+ * 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 FECC 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
+ */
+ if (config->hardware_address)
+ hwaddr = config->hardware_address;
+ else
+ hwaddr = gethwaddr(unitNumber - 1);
+ 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 = mcf5282_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/uC5282/start/start.S b/c/src/lib/libbsp/m68k/uC5282/start/start.S
new file mode 100644
index 0000000000..1adb1fb5eb
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/start/start.S
@@ -0,0 +1,411 @@
+/*
+ * uC5282 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
+
+/***************************************************************************
+ Function : Entry
+
+ Description : Entry point to the system. In a raw system we would have
+ put the initial stack pointer as the first 4 bytes. Instead we have to
+ provide a real instruction at the first location since we might be getting
+ started by dBUG after downloading from TFTP or FLASH. Hack in an
+ 'initial stack pointer' that actually is a jump to the start address!
+ ***************************************************************************/
+Entry:
+
+
+ nop ; jmp SYM(start) | 0: Initial 'SSP' 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
+
+.align 4
+ PUBLIC (start)
+SYM(start):
+ move.w #0x2700,sr | Disable interrupts
+
+ move.l #__SRAMBASE+1,d0 | Enable the MCF5282 internal SRAM
+ movec d0,%rambar | ...so we have a stack
+ move.l #__SRAMBASE+SRAM_SIZE-4,sp | Overwrite the fake stack pointer
+
+ /*
+ * If we're being started by the debugger, and the debugger has
+ * moved the IPSBAR, we're doomed........
+ */
+ move.l #__IPSBAR+1,d0 | Enable the MCF5282 internal peripherals
+ move.l d0,DEFAULT_IPSBAR
+
+ /*
+ * Copy the vector table to address 0 (VBR must be 0 mod 2^20)
+ * Leave the dBUG vectors (0-63) alone
+ */
+ lea.l (64*4)+Entry,a0
+ lea.l (64*4),a1
+ move.l #(256-64)-1,d0
+vectcpy:
+ move.l a0@+,a1@+ | Copy the vector table
+ sub.l #1,d0
+ bne.s vectcpy
+
+ /*
+ * Remainder of the startup code is handled by C code
+ */
+ jmp SYM(Init5282) | 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
+ sub.l #SYM(_header_offset),a2 | Change source by the amount of the header offset
+ 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/uC5282/startup/bspclean.c b/c/src/lib/libbsp/m68k/uC5282/startup/bspclean.c
new file mode 100644
index 0000000000..b3a8536f4f
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/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/uC5282/startup/bspstart.c b/c/src/lib/libbsp/m68k/uC5282/startup/bspstart.c
new file mode 100644
index 0000000000..2b050a0276
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/startup/bspstart.c
@@ -0,0 +1,243 @@
+/*
+ * 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;
+
+/*
+ * Location of 'VME' access
+ */
+#define VME_ONE_BASE 0x30000000
+#define VME_TWO_BASE 0x31000000
+
+/*
+ * Cacheable areas
+ */
+#define SDRAM_BASE 0
+#define SDRAM_SIZE (16*1024*1024)
+#define FLASH_BASE 0x10C10000
+#define FLASH_SIZE (4*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)
+{
+ asm volatile ("cpushl %%ic,(%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);
+ 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)
+{
+ asm volatile ("cpushl %%dc,(%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 and FLASH
+ */
+ m68k_set_acr0(MCF5XXX_ACR_AB(SDRAM_BASE) |
+ MCF5XXX_ACR_AM(SDRAM_SIZE-1) |
+ MCF5XXX_ACR_EN |
+ MCF5XXX_ACR_BWE |
+ MCF5XXX_ACR_SM_IGNORE);
+ m68k_set_acr1(MCF5XXX_ACR_AB(FLASH_BASE) |
+ MCF5XXX_ACR_AM(FLASH_SIZE-1) |
+ MCF5XXX_ACR_EN |
+ MCF5XXX_ACR_BWE |
+ MCF5XXX_ACR_SM_IGNORE);
+
+ /*
+ * Enable the cache
+ */
+ m68k_set_cacr(cacr_mode);
+
+ /*
+ * Set up CS* space (fake 'VME')
+ * Two A24/D16 spaces, supervisor data acces
+ */
+ MCF5282_CS1_CSAR = MCF5282_CS_CSAR_BA(VME_ONE_BASE);
+ MCF5282_CS1_CSMR = MCF5282_CS_CSMR_BAM_16M |
+ MCF5282_CS_CSMR_CI |
+ MCF5282_CS_CSMR_SC |
+ MCF5282_CS_CSMR_UC |
+ MCF5282_CS_CSMR_UD |
+ MCF5282_CS_CSMR_V;
+ MCF5282_CS1_CSCR = MCF5282_CS_CSCR_PS_16;
+ MCF5282_CS2_CSAR = MCF5282_CS_CSAR_BA(VME_TWO_BASE);
+ MCF5282_CS2_CSMR = MCF5282_CS_CSMR_BAM_16M |
+ MCF5282_CS_CSMR_CI |
+ MCF5282_CS_CSMR_SC |
+ MCF5282_CS_CSMR_UC |
+ MCF5282_CS_CSMR_UD |
+ MCF5282_CS_CSMR_V;
+ MCF5282_CS2_CSCR = MCF5282_CS_CSCR_PS_16;
+}
+
+unsigned32 get_CPU_clock_speed(void)
+{
+ extern char _CPUClockSpeed[];
+ return( (unsigned32)_CPUClockSpeed);
+}
diff --git a/c/src/lib/libbsp/m68k/uC5282/startup/init5282.c b/c/src/lib/libbsp/m68k/uC5282/startup/init5282.c
new file mode 100644
index 0000000000..969e5f24a8
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/startup/init5282.c
@@ -0,0 +1,31 @@
+/*
+ * 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 uC5282 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))
+void *_ColdFire_VBR;
+
+void Init5282 (void)
+{
+ extern void CopyDataClearBSSAndStart (void);
+
+ /*
+ * Set the VBR to point to where the assembly code copied it
+ */
+ m68k_set_vbr(0);
+
+ /*
+ * Copy data, clear BSS and call boot_card()
+ */
+ CopyDataClearBSSAndStart ();
+}
diff --git a/c/src/lib/libbsp/m68k/uC5282/startup/linkcmds b/c/src/lib/libbsp/m68k/uC5282/startup/linkcmds
new file mode 100644
index 0000000000..9dfbc8eff2
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/startup/linkcmds
@@ -0,0 +1,208 @@
+/*
+ * 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 ;
+
+/*
+ * Location of downloaded (from TFTP or flash) file
+ */
+_DownloadLocation = 0x40000;
+
+/*
+ * System clock speed
+ */
+_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 64000000 ;
+
+/*
+ * Location of on-chip devices
+ */
+__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ;
+__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ;
+
+ENTRY(start)
+MEMORY
+{
+ ram : ORIGIN = 0, LENGTH = 16M
+ sram : ORIGIN = 0x20000000, LENGTH = 64k
+}
+
+SECTIONS
+{
+
+ _header_offset = 0;
+
+ /*
+ * Text, data and bss segments
+ */
+ .text _DownloadLocation : {
+
+ *(.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 = LOADADDR(.data);
+ _data_src_end = _data_src_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) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+
+PROVIDE (end_of_all = .);
+}
diff --git a/c/src/lib/libbsp/m68k/uC5282/timer/timer.c b/c/src/lib/libbsp/m68k/uC5282/timer/timer.c
new file mode 100644
index 0000000000..3c76c94285
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/uC5282/timer/timer.c
@@ -0,0 +1,47 @@
+/*
+ * Timer Init
+ *
+ * Use the last DMA timer (DTIM3) as the diagnostic timer.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+void
+Timer_initialize(void)
+{
+ int preScaleDivisor = get_CPU_clock_speed() / 1000000;
+ int div = MCF5282_TIMER_DTMR_CLK_DIV1;
+
+ if (preScaleDivisor > 256) {
+ preScaleDivisor /= 16;
+ div = MCF5282_TIMER_DTMR_CLK_DIV16;
+ }
+ MCF5282_TIMER3_DTMR = 0;
+ MCF5282_TIMER3_DTMR = MCF5282_TIMER_DTMR_PS(preScaleDivisor - 1) | div |
+ MCF5282_TIMER_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+int
+Read_timer(void)
+{
+ return MCF5282_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)
+{
+}