From 1612af0f62aff5f0f077af77c44203cfa2f7603e Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 17 Jun 2005 14:06:05 +0000 Subject: 2005-06-17 Mike Bertosh * .cvsignore, ChangeLog, Makefile.am, README, bsp_specs, configure.ac, clock/clock.c, console/console.c, include/bsp.h, include/coverhd.h, include/tm27.h, network/network.c, start/start.S, startup/bspclean.c, startup/bspstart.c, startup/init5235.c, startup/linkcmds, startup/linkcmdsflash, startup/linkcmdsram, timer/timer.c: New files. --- c/src/lib/libbsp/m68k/mcf5235/.cvsignore | 14 + c/src/lib/libbsp/m68k/mcf5235/ChangeLog | 8 + c/src/lib/libbsp/m68k/mcf5235/Makefile.am | 121 +++ c/src/lib/libbsp/m68k/mcf5235/README | 454 +++++++++++ c/src/lib/libbsp/m68k/mcf5235/bsp_specs | 16 + c/src/lib/libbsp/m68k/mcf5235/clock/clock.c | 63 ++ c/src/lib/libbsp/m68k/mcf5235/configure.ac | 24 + c/src/lib/libbsp/m68k/mcf5235/console/console.c | 799 +++++++++++++++++++ c/src/lib/libbsp/m68k/mcf5235/include/bsp.h | 101 +++ c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h | 106 +++ c/src/lib/libbsp/m68k/mcf5235/include/tm27.h | 29 + c/src/lib/libbsp/m68k/mcf5235/network/network.c | 850 +++++++++++++++++++++ c/src/lib/libbsp/m68k/mcf5235/start/start.S | 392 ++++++++++ c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c | 35 + c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c | 220 ++++++ c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c | 80 ++ c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds | 175 +++++ .../lib/libbsp/m68k/mcf5235/startup/linkcmdsflash | 180 +++++ c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram | 175 +++++ c/src/lib/libbsp/m68k/mcf5235/timer/timer.c | 43 ++ 20 files changed, 3885 insertions(+) create mode 100644 c/src/lib/libbsp/m68k/mcf5235/.cvsignore create mode 100644 c/src/lib/libbsp/m68k/mcf5235/ChangeLog create mode 100644 c/src/lib/libbsp/m68k/mcf5235/Makefile.am create mode 100644 c/src/lib/libbsp/m68k/mcf5235/README create mode 100644 c/src/lib/libbsp/m68k/mcf5235/bsp_specs create mode 100644 c/src/lib/libbsp/m68k/mcf5235/clock/clock.c create mode 100644 c/src/lib/libbsp/m68k/mcf5235/configure.ac create mode 100644 c/src/lib/libbsp/m68k/mcf5235/console/console.c create mode 100644 c/src/lib/libbsp/m68k/mcf5235/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/mcf5235/include/tm27.h create mode 100644 c/src/lib/libbsp/m68k/mcf5235/network/network.c create mode 100644 c/src/lib/libbsp/m68k/mcf5235/start/start.S create mode 100644 c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c create mode 100644 c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash create mode 100644 c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram create mode 100644 c/src/lib/libbsp/m68k/mcf5235/timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf5235/.cvsignore b/c/src/lib/libbsp/m68k/mcf5235/.cvsignore new file mode 100644 index 0000000000..bfdfd995be --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/.cvsignore @@ -0,0 +1,14 @@ +aclocal.m4 +autom4te*.cache +config.cache +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +Makefile +Makefile.in +missing +mkinstalldirs diff --git a/c/src/lib/libbsp/m68k/mcf5235/ChangeLog b/c/src/lib/libbsp/m68k/mcf5235/ChangeLog new file mode 100644 index 0000000000..e4a57741de --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/ChangeLog @@ -0,0 +1,8 @@ +2005-06-17 Mike Bertosh + + * .cvsignore, ChangeLog, Makefile.am, README, bsp_specs, configure.ac, + clock/clock.c, console/console.c, include/bsp.h, include/coverhd.h, + include/tm27.h, network/network.c, start/start.S, startup/bspclean.c, + startup/bspstart.c, startup/init5235.c, startup/linkcmds, + startup/linkcmdsflash, startup/linkcmdsram, timer/timer.c: New files. + diff --git a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am new file mode 100644 index 0000000000..3c069162ae --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am @@ -0,0 +1,121 @@ +## +## $Id$ +## + +ACLOCAL_AMFLAGS = -I ../../../../aclocal + +include $(top_srcdir)/../../../../automake/compile.am +include $(top_srcdir)/../../bsp.am + +dist_project_lib_DATA = bsp_specs + +include_HEADERS = include/bsp.h +include_HEADERS += include/tm27.h + +nodist_include_HEADERS = include/bspopts.h +DISTCLEANFILES = include/bspopts.h + +noinst_PROGRAMS = + +include_HEADERS += include/coverhd.h + +EXTRA_DIST = start/start.S +start.$(OBJEXT): start/start.S + $(CPPASCOMPILE) -DASM -o $@ -c $< +project_lib_DATA = start.$(OBJEXT) + +dist_project_lib_DATA += startup/linkcmds + +noinst_PROGRAMS += startup.rel +startup_rel_SOURCES = startup/bspclean.c \ + ../../shared/bsplibc.c ../../shared/bsppost.c \ + ../../m68k/shared/m68kpretaskinghook.c \ + startup/init5235.c startup/bspstart.c \ + ../../shared/bootcard.c ../../shared/main.c \ + ../../shared/sbrk.c ../../m68k/shared/setvec.c \ + ../../shared/gnatinstallhandler.c +startup_rel_CPPFLAGS = $(AM_CPPFLAGS) +startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += clock.rel +clock_rel_SOURCES = clock/clock.c +clock_rel_CPPFLAGS = $(AM_CPPFLAGS) +clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += console.rel +console_rel_SOURCES = console/console.c +console_rel_CPPFLAGS = $(AM_CPPFLAGS) +console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += timer.rel +timer_rel_SOURCES = timer/timer.c +timer_rel_CPPFLAGS = $(AM_CPPFLAGS) +timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +if HAS_NETWORKING +network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ +noinst_PROGRAMS += network.rel +network_rel_SOURCES = network/network.c +network_rel_CPPFLAGS = $(AM_CPPFLAGS) \ + $(network_CPPFLAGS) +network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +endif + +noinst_LIBRARIES = libbsp.a +libbsp_a_SOURCES = +libbsp_a_LIBADD = startup.rel clock.rel console.rel timer.rel +if HAS_NETWORKING +libbsp_a_LIBADD += network.rel +endif +libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cache.rel \ + ../../../libcpu/@RTEMS_CPU@/shared/misc.rel + +all-local: $(PREINSTALL_FILES) $(TMPINSTALL_FILES) + +PREINSTALL_DIRS = +PREINSTALL_FILES = +TMPINSTALL_FILES = + +$(PROJECT_INCLUDE)/$(dirstamp): + @$(mkdir_p) $(PROJECT_INCLUDE) + @: > $(PROJECT_INCLUDE)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) + +$(PROJECT_LIB)/$(dirstamp): + @$(mkdir_p) $(PROJECT_LIB) + @: > $(PROJECT_LIB)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp) + +$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs +PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs + +$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h + +$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h + +$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h + +$(PROJECT_INCLUDE)/coverhd.h: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h + +$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT) +TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT) + +$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds +PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds + +CLEANFILES = $(PREINSTALL_FILES) +DISTCLEANFILES += $(PREINSTALL_DIRS) +CLEANFILES += $(TMPINSTALL_FILES) + +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/m68k/mcf5235/README b/c/src/lib/libbsp/m68k/mcf5235/README new file mode 100644 index 0000000000..c8897ea829 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/README @@ -0,0 +1,454 @@ +# +# $Id$ +# + +Description: Motorola MCF5235EVB +============ +CPU: MCF5235, 150MHz +RAM: 16M +ROM: 2M + +This is a Motorola evaluation board that uses the MCF5235 Coldfire CPU. +This board is running at 150MHz scaled from a 25MHz oscillator. + +ACKNOWLEDGEMENTS: +================= +This BSP is heavily based on the work of: + D. Peter Siddons + Brett Swimley + Jay Monkman + Eric Norum + Mike Bertosh + +BSP NAME: mcf5235 +BOARD: Motorola MCF5235EVB +CPU FAMILY: ColdFire 5235 +CPU: MCF5235 +COPROCESSORS: N/A + +DEBUG MONITOR: dBUG + +PERIPHERALS +=========== +TIMERS: Four PIT (RTEMS clock is PIT3), Four Timers +RESOLUTION: 10 microsecond +SERIAL PORTS: Internal UART 1, 2 and 3 +REAL-TIME CLOCK: none +DMA: none +VIDEO: none +SCSI: none +NETWORKING: Internal 10/100MHz FEC + +DRIVER INFORMATION +================== +CLOCK DRIVER: PIT3 +IOSUPP DRIVER: none +SHMSUPP: none +TIMER DRIVER: TIMER3 +TTY DRIVER: UART1, 2 and 3 + +STDIO +===== +PORT: UART0 Terminal +ELECTRICAL: RS-232 +BAUD: 19200 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 + + + + Memory map as set up by dBUG bootstrap and BSP initialization + + +--------------------------------------------------+ +0000 0000 | 16 MByte SDRAM | 00FF FFFF +0100 0000 | --------------------------------------------- | + | Address space for future SDRAM expansion | + . . + . . + . . + | | 0FFF FFFF + +--------------------------------------------------+ +1000 0000 | | + . . + . . + . . + | | 1FFF FFFF + +--------------------------------------------------+ +2000 0000 | 64 kByte on-chip SRAM (RAMBAR) | + . . + . . + . . + | | 2FFF FFFF + +--------------------------------------------------+ +3000 0000 | | 30FF FFFF + . . + . . + . . + . . + | | 3FFF FFFF + +--------------------------------------------------+ +4000 0000 | Internal peripheral system (IPSBAR) | + . . + | | + . . + . . + . . + | | 4FFF FFFF + +--------------------------------------------------+ + . . + . . + . . + +--------------------------------------------------+ +FFE0 0000 | External 4 MByte Flash | + . . + . . + . . + | | FFFF FFFF + +--------------------------------------------------+ + +============================================================================ + Interrupt map + ++-----+-----------------------------------------------------------------------+ +| | PRIORITY | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +|LEVEL| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 7 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 6 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 5 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 4 | FEC RX | FEC TX | | | | | | PIT | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 3 | UART 0 | UART 1 | UART 2 | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 2 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 1 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ + +============================================================================ +TIMING TESTS +************************************ +*** TIME TEST 1 *** +rtems_semaphore_create 12 +rtems_semaphore_delete 11 +rtems_semaphore_obtain: available 2 +rtems_semaphore_obtain: not available -- NO_WAIT 3 +rtems_semaphore_release: no waiting tasks 6 +*** END OF TEST 1 *** + +*** TIME TEST 2 *** +rtems_semaphore_obtain: not available -- caller blocks 18 +*** END OF TEST 2 *** + +*** TIME TEST 3 *** +rtems_semaphore_release: task readied -- preempts caller 12 +*** END OF TEST 3 *** + +*** TIME TEST 4 *** +rtems_task_restart: blocked task -- preempts caller 31 +rtems_task_restart: ready task -- preempts caller 30 +rtems_semaphore_release: task readied -- returns to caller 8 +rtems_task_create 45 +rtems_task_start 9 +rtems_task_restart: suspended task -- returns to caller 14 +rtems_task_delete: suspended task 32 +rtems_task_restart: ready task -- returns to caller 14 +rtems_task_restart: blocked task -- returns to caller 21 +rtems_task_delete: blocked task 32 +*** END OF TEST 4 *** + +*** TIME TEST 5 *** +rtems_task_suspend: calling task 15 +rtems_task_resume: task readied -- preempts caller 9 +*** END OF TEST 5 *** + +*** TIME TEST 6 *** +rtems_task_restart: calling task 12 +rtems_task_suspend: returns to caller 5 +rtems_task_resume: task readied -- returns to caller 6 +rtems_task_delete: ready task 34 +*** END OF TEST 6 *** + +*** TIME TEST 7 *** +rtems_task_restart: suspended task -- preempts caller 22 +*** END OF TEST 7 *** + +*** TIME TEST 8 *** +rtems_task_set_priority: obtain current priority 4 +rtems_task_set_priority: returns to caller 9 +rtems_task_mode: obtain current mode 1 +rtems_task_mode: no reschedule 1 +rtems_task_mode: reschedule -- returns to caller 3 +rtems_task_mode: reschedule -- preempts caller 11 +rtems_task_set_note 3 +rtems_task_get_note 3 +rtems_clock_set 9 +rtems_clock_get 0 +*** END OF TEST 8 *** + +*** TIME TEST 9 *** +rtems_message_queue_create 37 +rtems_message_queue_send: no waiting tasks 11 +rtems_message_queue_urgent: no waiting tasks 10 +rtems_message_queue_receive: available 10 +rtems_message_queue_flush: no messages flushed 3 +rtems_message_queue_flush: messages flushed 5 +rtems_message_queue_delete 17 +*** END OF TEST 9 *** + +*** TIME TEST 10 *** +rtems_message_queue_receive: not available -- NO_WAIT 6 +rtems_message_queue_receive: not available -- caller blocks 20 +*** END OF TEST 10 *** + +*** TIME TEST 11 *** +rtems_message_queue_send: task readied -- preempts caller 17 +*** END OF TEST 11 *** + +*** TIME TEST 12 *** +rtems_message_queue_send: task readied -- returns to caller 12 +*** END OF TEST 12 *** + +*** TIME TEST 13 *** +rtems_message_queue_urgent: task readied -- preempts caller 20 +*** END OF TEST 13 *** + +*** TIME TEST 14 *** +rtems_message_queue_urgent: task readied -- returns to caller 14 +*** END OF TEST 14 *** + +*** TIME TEST 15 *** +rtems_event_receive: obtain current events 0 +rtems_event_receive: not available -- NO_WAIT 3 +rtems_event_receive: not available -- caller blocks 18 +rtems_event_send: no task readied 3 +rtems_event_receive: available 5 +rtems_event_send: task readied -- returns to caller 7 +*** END OF TEST 15 *** + +*** TIME TEST 16 *** +rtems_event_send: task readied -- preempts caller 12 +*** END OF TEST 16 *** + +*** TIME TEST 17 *** +rtems_task_set_priority: preempts caller 21 +*** END OF TEST 17 *** + +*** TIME TEST 18 *** +rtems_task_delete: calling task 40 +*** END OF TEST 18 *** + +*** TIME TEST 19 *** +rtems_signal_catch 3 +rtems_signal_send: returns to caller 6 +rtems_signal_send: signal to self 11 +exit ASR overhead: returns to calling task 8 +exit ASR overhead: returns to preempting task 10 +*** END OF TEST 19 *** + +*** TIME TEST 20 *** +rtems_partition_create 13 +rtems_region_create 24 +rtems_partition_get_buffer: available 6 +rtems_partition_get_buffer: not available 4 +rtems_partition_return_buffer 6 +rtems_partition_delete 6 +rtems_region_get_segment: available 12 +rtems_region_get_segment: not available -- NO_WAIT 13 +rtems_region_return_segment: no waiting tasks 12 +rtems_region_get_segment: not available -- caller blocks 30 +rtems_region_return_segment: task readied -- preempts caller 40 +rtems_region_return_segment: task readied -- returns to caller 25 +rtems_region_delete 12 +rtems_io_initialize 0 +rtems_io_open 0 +rtems_io_close 0 +rtems_io_read 0 +rtems_io_write 0 +rtems_io_control 0 +*** END OF TEST 20 *** + +*** TIME TEST 21 *** +rtems_task_ident 31 +rtems_message_queue_ident 30 +rtems_semaphore_ident 34 +rtems_partition_ident 30 +rtems_region_ident 30 +rtems_port_ident 29 +rtems_timer_ident 30 +rtems_rate_monotonic_ident 30 +*** END OF TEST 21 *** + +*** TIME TEST 22 *** +rtems_message_queue_broadcast: task readied -- returns to caller 19 +rtems_message_queue_broadcast: no waiting tasks 6 +rtems_message_queue_broadcast: task readied -- preempts caller 20 +*** END OF TEST 22 *** + +*** TIME TEST 23 *** +rtems_timer_create 4 +rtems_timer_fire_after: inactive 6 +rtems_timer_fire_after: active 6 +rtems_timer_cancel: active 4 +rtems_timer_cancel: inactive 3 +rtems_timer_reset: inactive 6 +rtems_timer_reset: active 6 +rtems_timer_fire_when: inactive 8 +rtems_timer_fire_when: active 8 +rtems_timer_delete: active 5 +rtems_timer_delete: inactive 5 +rtems_task_wake_when 16 +*** END OF TEST 23 *** + +*** TIME TEST 24 *** +rtems_task_wake_after: yield -- returns to caller 2 +rtems_task_wake_after: yields -- preempts caller 12 +*** END OF TEST 24 *** + +*** TIME TEST 25 *** +rtems_clock_tick 4 +*** END OF TEST 25 *** + +*** TIME TEST 26 *** +_ISR_Disable 0 +_ISR_Flash 0 +_ISR_Enable 0 +_Thread_Disable_dispatch 0 +_Thread_Enable_dispatch 1 +_Thread_Set_state 4 +_Thread_Disptach (NO FP) 9 +context switch: no floating point contexts 7 +context switch: self 1 +context switch: to another task 1 +fp context switch: restore 1st FP task 6 +fp context switch: save idle, restore initialized 2 +fp context switch: save idle, restore idle 6 +fp context switch: save initialized, restore initialized 1 +_Thread_Resume 4 +_Thread_Unblock 3 +_Thread_Ready 2 +_Thread_Get 0 +_Semaphore_Get 0 +_Thread_Get: invalid id 0 +*** END OF TEST 26 *** + +*** TIME TEST 27 *** +interrupt entry overhead: returns to interrupted task 2 +interrupt exit overhead: returns to interrupted task 1 +interrupt entry overhead: returns to nested interrupt 1 +interrupt exit overhead: returns to nested interrupt 1 +interrupt entry overhead: returns to preempting task 2 +interrupt exit overhead: returns to preempting task 12 +*** END OF TEST 27 *** + +*** TIME TEST 28 *** +rtems_port_create 8 +rtems_port_external_to_internal 2 +rtems_port_internal_to_external 3 +rtems_port_delete 7 +*** END OF TEST 28 *** + +*** TIME TEST 29 *** +rtems_rate_monotonic_create 8 +rtems_rate_monotonic_period: initiate period -- returns to caller 12 +rtems_rate_monotonic_period: obtain status 5 +rtems_rate_monotonic_cancel 7 +rtems_rate_monotonic_delete: inactive 8 +rtems_rate_monotonic_delete: active 7 +rtems_rate_monotonic_period: conclude periods -- caller blocks 11 +*** END OF TEST 29 *** + +*** TIME CHECKER *** +Units may not be in microseconds for this test!!! +0 100000 +Total time = 0 +Average time = 0 + +NULL timer stopped at 0 +LOOP (1000) timer stopped at 94 +LOOP (10000) timer stopped at 941 +LOOP (50000) timer stopped at 4704 +LOOP (100000) timer stopped at 9408 +*** END OF TIME CHECKER *** + +*** TIME TEST OVERHEAD *** +rtems_initialize_executive 0 +rtems_shutdown_executive 0 +rtems_task_create 0 +rtems_task_ident 0 +rtems_task_start 0 +rtems_task_restart 0 +rtems_task_delete 0 +rtems_task_suspend 0 +rtems_task_resume 0 +rtems_task_set_priority 0 +rtems_task_mode 0 +rtems_task_get_note 0 +rtems_task_set_note 0 +rtems_task_wake_when 0 +rtems_task_wake_after 0 +rtems_interrupt_catch 0 +rtems_clock_get 0 +rtems_clock_set 0 +rtems_clock_tick 0 + +rtems_timer_create 0 +rtems_timer_delete 0 +rtems_timer_ident 0 +rtems_timer_fire_after 0 +rtems_timer_fire_when 0 +rtems_timer_reset 0 +rtems_timer_cancel 0 +rtems_semaphore_create 0 +rtems_semaphore_delete 0 +rtems_semaphore_ident 0 +rtems_semaphore_obtain 0 +rtems_semaphore_release 0 +rtems_message_queue_create 0 +rtems_message_queue_ident 0 +rtems_message_queue_delete 0 +rtems_message_queue_send 0 +rtems_message_queue_urgent 0 +rtems_message_queue_broadcast 0 +rtems_message_queue_receive 0 +rtems_message_queue_flush 0 + +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/mcf5235/bsp_specs b/c/src/lib/libbsp/m68k/mcf5235/bsp_specs new file mode 100644 index 0000000000..6480bbd1b5 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/bsp_specs @@ -0,0 +1,16 @@ +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*startfile: +%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \ +%{!qrtems_debug: start.o%s} \ +%{qrtems_debug: start_g.o%s} \ +crti.o%s crtbegin.o%s}} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e start} + +*endfile: +%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s crtn.o%s} + diff --git a/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c b/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c new file mode 100644 index 0000000000..844be227e1 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c @@ -0,0 +1,63 @@ +/* + * Use the last periodic interval timer (PIT3) as the system clock. + * + * $Id$ + */ + +#include +#include +#include + +/* + * Use INTC0 base + */ +#define CLOCK_VECTOR (64+39) + +/* + * Periodic interval timer interrupt handler + */ +#define Clock_driver_support_at_tick() \ + do { \ + MCF5235_PIT_PCSR3 |= MCF5235_PIT_PCSR_PIF; \ + } while (0) \ + +/* + * Attach clock interrupt handler + */ +#define Clock_driver_support_install_isr( _new, _old ) \ + do { \ + _old = (rtems_isr_entry)set_vector(_new, CLOCK_VECTOR, 1); \ + } while(0) + +/* + * Turn off the clock + */ +#define Clock_driver_support_shutdown_hardware() \ + do { \ + MCF5235_PIT_PCSR3 &= ~MCF5235_PIT_PCSR_EN; \ + } while(0) + +/* + * Set up the clock hardware + * + * We need to have 1 interrupt every 10,000 microseconds + * so we need to set prescaler to 64 and the PMR register to 0x2DC6 + */ +#define Clock_driver_support_initialize_hardware() \ + do { \ + int level; \ + int preScaleCode = 6; \ + MCF5235_INTC0_ICR39 = MCF5235_INTC_ICR_IL(PIT3_IRQ_LEVEL) | \ + MCF5235_INTC_ICR_IP(PIT3_IRQ_PRIORITY); \ + rtems_interrupt_disable( level ); \ + MCF5235_INTC0_IMRH &= ~MCF5235_INTC0_IMRH_INT39; \ + MCF5235_PIT_PCSR3 &= ~MCF5235_PIT_PCSR_EN; \ + rtems_interrupt_enable( level ); \ + MCF5235_PIT_PMR3 = 0x2DC6; \ + MCF5235_PIT_PCSR3 = MCF5235_PIT_PCSR_PRE(preScaleCode) | \ + MCF5235_PIT_PCSR_PIE | \ + MCF5235_PIT_PCSR_RLD | \ + MCF5235_PIT_PCSR_EN; \ + } while (0) + +#include "../../../shared/clockdrv_shell.c" diff --git a/c/src/lib/libbsp/m68k/mcf5235/configure.ac b/c/src/lib/libbsp/m68k/mcf5235/configure.ac new file mode 100644 index 0000000000..7c6366ad96 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/configure.ac @@ -0,0 +1,24 @@ +## Process this file with autoconf to produce a configure script. +## +## $Id$ + +AC_PREREQ(2.59) +AC_INIT([rtems-c-src-lib-libbsp-m68k-mcf5235],[_RTEMS_VERSION],[rtems-bugs@rtems.com]) +AC_CONFIG_SRCDIR([bsp_specs]) +RTEMS_TOP(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU +AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.9]) +RTEMS_BSP_CONFIGURE + +RTEMS_PROG_CC_FOR_TARGET +RTEMS_CANONICALIZE_TOOLS +RTEMS_PROG_CCAS + +RTEMS_CHECK_NETWORKING + +AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/c/src/lib/libbsp/m68k/mcf5235/console/console.c b/c/src/lib/libbsp/m68k/mcf5235/console/console.c new file mode 100644 index 0000000000..48f4179055 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/console/console.c @@ -0,0 +1,799 @@ + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) + +#define MCF5235_UART_USR_ERROR ( MCF5235_UART_USR_RB | \ + MCF5235_UART_USR_FE | \ + MCF5235_UART_USR_PE | \ + MCF5235_UART_USR_OE ) + +static int IntUartPollWrite(int minor, const char *buf, int len); +static int IntUartInterruptWrite (int minor, const char *buf, int len); + +static void +_BSP_null_char( char c ) +{ + int level; + + if (c == '\n') + _BSP_null_char('\r'); + rtems_interrupt_disable(level); + while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) + continue; + MCF5235_UART_UTB(CONSOLE_PORT) = c; + while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) + continue; + rtems_interrupt_enable(level); +} +BSP_output_char_function_type BSP_output_char = _BSP_null_char; + +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +static int GetBaud( int baudHandle ) +{ + int baud = 9600; + switch ( baudHandle ) + { + case B0: + baud = (int)0; + break; + case B1200: + baud = (int)1200; + break; + case B2400: + baud = (int)2400; + break; + case B4800: + baud = (int)4800; + break; + case B9600: + baud = (int)9600; + break; + case B19200: + baud = (int)19200; + break; + case B38400: + baud = (int)38400; + break; + case B57600: + baud = (int)57600; + break; + case B115200: + baud = (int)115200; + break; + } + return ( baud ); +} + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) +{ + int divisor; + unsigned32 clock_speed; + unsigned8 umr1 = 0; + unsigned8 umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + int level; + + rtems_interrupt_disable(level); + + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF5235_UART_UIMR(minor) = 0; + MCF5235_UART_UOP0(minor) = 1; + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = get_CPU_clock_speed(); + /* determine the baud divisor value */ + divisor = ((clock_speed/2) / ( 32 * baud )); + if ( divisor < 2 ) + divisor = 2; + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* set hardware flow options */ + umr1 |= MCF5235_UART_UMR_RXRTS; + umr2 |= MCF5235_UART_UMR_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + umr2 |= (stopbits); + + /* reset the uart */ + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_ERROR; + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_RX; + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_MR; + MCF5235_UART_UMR(minor) = umr1; + MCF5235_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF5235_UART_UCSR(minor) = (MCF5235_UART_UCSR_RCS_SYS_CLK | MCF5235_UART_UCSR_TCS_SYS_CLK); + MCF5235_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF5235_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->uimr |= MCF5235_UART_UIMR_FFULL; + MCF5235_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* assert the RTS line */ + MCF5235_UART_UOP1(minor) = 1; + } + + rtems_interrupt_enable(level); + +} + + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int +IntUartSetAttributes(int minor, const struct termios *t) +{ + /* set default index values */ + int baud = (int)19200; + int databits = (int)MCF5235_UART_UMR_BC_8; + int parity = (int)MCF5235_UART_UMR_PM_NONE; + int stopbits = (int)MCF5235_UART_UMR_STOP_BITS_1; + int hwflow = (int)0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if ( t != (const struct termios *)0 ) + { + /* determine baud rate index */ + baud = GetBaud( t->c_cflag & CBAUD ); + + /* determine data bits */ + switch ( t->c_cflag & CSIZE ) + { + case CS5: + databits = (int)MCF5235_UART_UMR_BC_5; + break; + case CS6: + databits = (int)MCF5235_UART_UMR_BC_6; + break; + case CS7: + databits = (int)MCF5235_UART_UMR_BC_7; + break; + case CS8: + databits = (int)MCF5235_UART_UMR_BC_8; + break; + } + + /* determine if parity is enabled */ + if ( t->c_cflag & PARENB ) + { + if ( t->c_cflag & PARODD ) + { + /* odd parity */ + parity = (int)MCF5235_UART_UMR_PM_ODD; + } + else + { + /* even parity */ + parity = (int)MCF5235_UART_UMR_PM_EVEN; + } + } + + /* determine stop bits */ + if ( t->c_cflag & CSTOPB ) + { + /* two stop bits */ + stopbits = (int)MCF5235_UART_UMR_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if ( t->c_cflag & CRTSCTS ) + { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ( ( baud != info->baud ) || + ( databits != info->databits ) || + ( parity != info->parity ) || + ( stopbits != info->stopbits ) || + ( hwflow != info->hwflow ) ) + { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return( RTEMS_SUCCESSFUL ); + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr +IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_RXRDY ) + { + /* read data and put into the receive buffer */ + while ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_RXRDY ) + { + + if ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_ERROR ) + { + /* clear the error */ + MCF5235_UART_UCR(chan) = MCF5235_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF5235_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if ( info->rx_in >= RX_BUFFER_SIZE ) + { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if ( info->ttyp ) + { + + /* check to see if task driven */ + if ( info->iomode == TERMIOS_TASK_DRIVEN ) + { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } + else + { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ( ( info->uimr & MCF5235_UART_UIMR_TXRDY ) && + ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_TXRDY ) ) + { + + /* disable tx interrupts */ + info->uimr &= ~MCF5235_UART_UIMR_TXRDY; + MCF5235_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if ( info->ttyp ) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + + + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void +IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + int level; + + for ( chan = 0; chan < MAX_UART_INFO; chan++ ) + { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + info->iomode = TERMIOS_POLLED; //polled console io + + MCF5235_UART_UACR(chan) = 0; + MCF5235_UART_UIMR(chan) = 0; + if ( info->iomode != TERMIOS_POLLED ) + { + rtems_interrupt_catch (IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), + &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch(chan) { + case 0: + MCF5235_INTC0_ICR13 = MCF5235_INTC_ICR_IL(UART0_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(UART0_IRQ_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT13 | + MCF5235_INTC0_IMRL_MASKALL); + break; + + case 1: + MCF5235_INTC0_ICR14 = MCF5235_INTC_ICR_IL(UART1_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(UART1_IRQ_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT14 | + MCF5235_INTC0_IMRL_MASKALL); + break; + + case 2: + MCF5235_INTC0_ICR15 = MCF5235_INTC_ICR_IL(UART2_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(UART2_IRQ_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT15 | + MCF5235_INTC0_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + + +} /* IntUartInitialise */ + + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static int +IntUartInterruptWrite (int minor, const char *buf, int len) +{ + int level; + + rtems_interrupt_disable(level); + + /* write out character */ + MCF5235_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF5235_UART_UIMR_TXRDY; + MCF5235_UART_UIMR(minor) = IntUartInfo[minor].uimr; + + rtems_interrupt_enable(level); + return( 0 ); +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int +IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->uimr |= MCF5235_UART_UIMR_FFULL; + MCF5235_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( info->hwflow ) + { + /* assert the RTS line */ + MCF5235_UART_UOP1(minor) = 1; + } + + return( 0 ); +} + + + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int +IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF5235_UART_UIMR(minor) = 0; + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return( 0 ); +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int +IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if ( info->rx_out <= rx_in ) + { + count = rx_in - info->rx_out; + } + else + { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) + { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if ( info->rx_out >= RX_BUFFER_SIZE ) + { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if ( count > 0 ) + { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return( EOF ); +} + + + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static int +IntUartPollRead (int minor) +{ + if ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_RXRDY) == 0 ) + return(-1); + + return(MCF5235_UART_URB(minor)); +} + + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static int +IntUartPollWrite (int minor, const char *buf, int len) +{ + /* loop over buffer */ + while ( len-- ) + { + /* block until we can transmit */ + while ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_TXRDY) == 0 ) + continue; + /* transmit data byte */ + MCF5235_UART_UTB(minor) = *buf++; + } + return(0); +} + +/*************************************************************************** + Function : console_reserve_resources + + Description : This reserves resources consumed by this driver. It passes + the request on to the termios subsystem. + ***************************************************************************/ +void console_reserve_resources( rtems_configuration_table *configuration ) +{ + rtems_termios_reserve_resources (configuration, 1); +} + + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, both sets of uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) +{ + rtems_status_code status; + + + /* Set up TERMIOS */ + rtems_termios_initialize (); + + /* set io modes for the different channels and initialize device */ + IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + + /* Register the other port */ + if ( CONSOLE_PORT != 0 ) + { + status = rtems_io_register_name ("/dev/tty00", major, 0); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + if ( CONSOLE_PORT != 1 ) + { + status = rtems_io_register_name ("/dev/tty01", major, 1); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + + return(RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) + { + info = &IntUartInfo[minor]; + switch ( info->iomode ) + { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + return( status ); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_close (arg)); +} + +/****************** +********************************************************* + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_read (arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_write (arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return( rtems_termios_ioctl (arg) ); +} +int DEBUG_OUTCHAR(int c) +{ + if(c == '\n') + DEBUG_OUTCHAR('\r'); + _BSP_null_char(c); + return c; +} +void DEBUG_OUTSTR(const char *msg) +{ + while (*msg) + DEBUG_OUTCHAR(*msg++); +} +void DEBUG_OUTNUM(int i) +{ + int n; + static const char map[] = "0123456789ABCDEF"; + DEBUG_OUTCHAR(' '); + for (n = 28 ; n >= 0 ; n -= 4) + DEBUG_OUTCHAR(map[(i >> n) & 0xF]); +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/include/bsp.h b/c/src/lib/libbsp/m68k/mcf5235/include/bsp.h new file mode 100644 index 0000000000..122be187fa --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/include/bsp.h @@ -0,0 +1,101 @@ +/* + * mcf5235 BSP header file + */ + +#ifndef _BSP_H +#define _BSP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +/***************************************************************************/ +/** Hardware data structure headers **/ +#include /* internal MCF5235 modules */ + +/***************************************************************************/ +/** Network driver configuration **/ +struct rtems_bsdnet_ifconfig; +extern int rtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching ); +#define RTEMS_BSP_NETWORK_DRIVER_NAME "fs1" +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_fec_driver_attach + +/***************************************************************************/ +/** User Definable configuration **/ + +/* define which port the console should use - all other ports are then defined as general purpose */ +#define CONSOLE_PORT 0 + + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* externals */ + +/* constants */ + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + + +/* functions */ + +unsigned32 get_CPU_clock_speed(void); +void bsp_cleanup(void); +m68k_isr_entry set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +/* + * Interrupt assignments + * Highest-priority listed first + */ +#define FEC_IRQ_LEVEL 4 +#define FEC_IRQ_RX_PRIORITY 7 +#define FEC_IRQ_TX_PRIORITY 6 + +#define PIT3_IRQ_LEVEL 4 +#define PIT3_IRQ_PRIORITY 0 + +#define UART0_IRQ_LEVEL 3 +#define UART0_IRQ_PRIORITY 7 +#define UART1_IRQ_LEVEL 3 +#define UART1_IRQ_PRIORITY 6 +#define UART2_IRQ_LEVEL 3 +#define UART2_IRQ_PRIORITY 5 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h b/c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h new file mode 100644 index 0000000000..f838c5895c --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/include/coverhd.h @@ -0,0 +1,106 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include + * all calling overhead including passing of arguments. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 1 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 1 +#define CALLING_OVERHEAD_CLOCK_SET 1 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 1 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 1 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#endif diff --git a/c/src/lib/libbsp/m68k/mcf5235/include/tm27.h b/c/src/lib/libbsp/m68k/mcf5235/include/tm27.h new file mode 100644 index 0000000000..f8fe447335 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/include/tm27.h @@ -0,0 +1,29 @@ +/* + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef _RTEMS_TMTEST27 +#error "This is an RTEMS internal file you must not include directly." +#endif + +#ifndef __tm27_h +#define __tm27_h + +/* + * Stuff for Time Test 27 + * Don't bother with hardware -- just use a software-interrupt + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 35, 1 ) + +#define Cause_tm27_intr() asm volatile ("trap #3"); + +#define Clear_tm27_intr() /* empty */ + +#define Lower_tm27_intr() /* empty */ + +#endif diff --git a/c/src/lib/libbsp/m68k/mcf5235/network/network.c b/c/src/lib/libbsp/m68k/mcf5235/network/network.c new file mode 100644 index 0000000000..fe78033e26 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/network/network.c @@ -0,0 +1,850 @@ +/* + * RTEMS/TCPIP driver for MCF5235 Fast Ethernet Controller + * + * TO DO: Check network stack code -- force longword alignment of all tx mbufs? + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + + +/* + * Number of interfaces supported by this driver + */ +#define NIFACES 1 + +#define FEC_INTC0_TX_VECTOR (64+23) +#define FEC_INTC0_RX_VECTOR (64+27) + +/* + * Default number of buffer descriptors set aside for this driver. + * The number of transmit buffer descriptors has to be quite large + * since a single frame often uses three or more buffer descriptors. + */ +#define RX_BUF_COUNT 32 +#define TX_BUF_COUNT 20 +#define TX_BD_PER_BUF 3 + +#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255") + +/* + * RTEMS event used by interrupt handler to signal daemons. + * This must *not* be the same event used by the TCP/IP task synchronization. + */ +#define TX_INTERRUPT_EVENT RTEMS_EVENT_1 +#define RX_INTERRUPT_EVENT RTEMS_EVENT_1 + +/* + * RTEMS event used to start transmit daemon. + * This must not be the same as INTERRUPT_EVENT. + */ +#define START_TRANSMIT_EVENT RTEMS_EVENT_2 + +/* + * Receive buffer size -- Allow for a full ethernet packet plus CRC (1518). + * Round off to nearest multiple of RBUF_ALIGN. + */ +#define MAX_MTU_SIZE 1518 +#define RBUF_ALIGN 4 +#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN) + +#if (MCLBYTES < RBUF_SIZE) + #error "Driver must have MCLBYTES > RBUF_SIZE" +#endif + +typedef struct mcf5235BufferDescriptor_ { + volatile uint16_t status; + uint16_t length; + volatile void *buffer; +} mcf5235BufferDescriptor_t; + +/* + * Per-device data + */ +struct mcf5235_enet_struct { + struct arpcom arpcom; + struct mbuf **rxMbuf; + struct mbuf **txMbuf; + int acceptBroadcast; + int rxBdCount; + int txBdCount; + int txBdHead; + int txBdTail; + int txBdActiveCount; + mcf5235BufferDescriptor_t *rxBdBase; + mcf5235BufferDescriptor_t *txBdBase; + rtems_id rxDaemonTid; + rtems_id txDaemonTid; + + /* + * Statistics + */ + unsigned long rxInterrupts; + unsigned long txInterrupts; + unsigned long txRawWait; + unsigned long txRealign; +}; +static struct mcf5235_enet_struct enet_driver[NIFACES]; + +static rtems_isr +mcf5235_fec_rx_interrupt_handler( rtems_vector_number v ) +{ + MCF5235_FEC_EIR = MCF5235_FEC_EIR_RXF; + MCF5235_FEC_EIMR &= ~MCF5235_FEC_EIMR_RXF; + enet_driver[0].rxInterrupts++; + rtems_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT); +} + +static rtems_isr +mcf5235_fec_tx_interrupt_handler( rtems_vector_number v ) +{ + MCF5235_FEC_EIR = MCF5235_FEC_EIR_TXF; + MCF5235_FEC_EIMR &= ~MCF5235_FEC_EIMR_TXF; + enet_driver[0].txInterrupts++; + rtems_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT); +} + +/* + * Allocate buffer descriptors from (non-cached) on-chip static RAM + * Ensure 128-bit (16-byte) alignment + */ +static mcf5235BufferDescriptor_t * +mcf5235_bd_allocate(unsigned int count) +{ + extern char __SRAMBASE[]; + static mcf5235BufferDescriptor_t *bdp = (mcf5235BufferDescriptor_t *)__SRAMBASE; + mcf5235BufferDescriptor_t *p = bdp; + + bdp += count; + if ((int)bdp & 0xF) + bdp = (mcf5235BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF))); + return p; +} + +#if UNUSED +/* + * Read MII register + * Busy-waits, but transfer time should be short! + */ +static int +getMII(int phyNumber, int regNumber) +{ + MCF5235_FEC_MMFR = (0x1 << 30) | + (0x2 << 28) | + (phyNumber << 23) | + (regNumber << 18) | + (0x2 << 16); + while ((MCF5235_FEC_EIR & MCF5235_FEC_EIR_MII) == 0); + MCF5235_FEC_EIR = MCF5235_FEC_EIR_MII; + return MCF5235_FEC_MMFR & 0xFFFF; +} +#endif + +/* + * Write MII register + * Busy-waits, but transfer time should be short! + */ +static void +setMII(int phyNumber, int regNumber, int value) +{ + MCF5235_FEC_MMFR = (0x1 << 30) | + (0x1 << 28) | + (phyNumber << 23) | + (regNumber << 18) | + (0x2 << 16) | + (value & 0xFFFF); + while ((MCF5235_FEC_EIR & MCF5235_FEC_EIR_MII) == 0); + MCF5235_FEC_EIR = MCF5235_FEC_EIR_MII; +} + +static void +mcf5235_fec_initialize_hardware(struct mcf5235_enet_struct *sc) +{ + int i; + const unsigned char *hwaddr = 0; + rtems_status_code status; + rtems_isr_entry old_handler; + uint32_t clock_speed = get_CPU_clock_speed(); + + /* + * Issue reset to FEC + */ + MCF5235_FEC_ECR = MCF5235_FEC_ECR_RESET; + rtems_task_wake_after(1); + MCF5235_FEC_ECR = 0; + + /* + * Configuration of I/O ports is done outside of this function + */ +#if 0 + imm->gpio.pbcnt |= MCF5235_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */ +#endif + + /* + * Set our physical address + */ + hwaddr = sc->arpcom.ac_enaddr; + MCF5235_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) | + (hwaddr[2] << 8) | (hwaddr[3] << 0); + MCF5235_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16); + + + /* + * Clear the hash table + */ + MCF5235_FEC_GAUR = 0; + MCF5235_FEC_GALR = 0; + + /* + * Set up receive buffer size + */ + MCF5235_FEC_EMRBR = 1520; /* Standard Ethernet */ + + /* + * Allocate mbuf pointers + */ + sc->rxMbuf = malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT); + sc->txMbuf = malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT); + if (!sc->rxMbuf || !sc->txMbuf) + rtems_panic("No memory for mbuf pointers"); + + /* + * Set receiver and transmitter buffer descriptor bases + */ + sc->rxBdBase = mcf5235_bd_allocate(sc->rxBdCount); + sc->txBdBase = mcf5235_bd_allocate(sc->txBdCount); + MCF5235_FEC_ERDSR = (int)sc->rxBdBase; + MCF5235_FEC_ETDSR = (int)sc->txBdBase; + + /* + * Set up Receive Control Register: + * Not promiscuous + * MII mode + * Full duplex + * No loopback + */ + MCF5235_FEC_RCR = MCF5235_FEC_RCR_MAX_FL(MAX_MTU_SIZE) | + MCF5235_FEC_RCR_MII_MODE; + + /* + * Set up Transmit Control Register: + * Full duplex + * No heartbeat + */ + MCF5235_FEC_TCR = MCF5235_FEC_TCR_FDEN; + + /* + * Initialize statistic counters + */ + MCF5235_FEC_MIBC = MCF5235_FEC_MIBC_MIB_DISABLE; + { + vuint32 *vuip = &MCF5235_FEC_RMON_T_DROP; + while (vuip <= &MCF5235_FEC_IEEE_R_OCTETS_OK) + *vuip++ = 0; + } + MCF5235_FEC_MIBC = 0; + + /* + * Set MII speed to <= 2.5 MHz + */ + i = (clock_speed + 5000000 - 1) / 5000000; + MCF5235_FEC_MSCR = MCF5235_FEC_MSCR_MII_SPEED(i); + + /* + * Set PHYS to 100 Mb/s, full duplex + */ + setMII(1, 0, 0x2100); + + /* + * Set up receive buffer descriptors + */ + for (i = 0 ; i < sc->rxBdCount ; i++) + (sc->rxBdBase + i)->status = 0; + + /* + * Set up transmit buffer descriptors + */ + for (i = 0 ; i < sc->txBdCount ; i++) { + sc->txBdBase[i].status = 0; + sc->txMbuf[i] = NULL; + } + sc->txBdHead = sc->txBdTail = 0; + sc->txBdActiveCount = 0; + + /* + * Set up interrupts + */ + status = rtems_interrupt_catch( mcf5235_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler ); + if (status != RTEMS_SUCCESSFUL) + rtems_panic ("Can't attach MCF5235 FEC TX interrupt handler: %s\n", + rtems_status_text(status)); + status = rtems_interrupt_catch(mcf5235_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler); + if (status != RTEMS_SUCCESSFUL) + rtems_panic ("Can't attach MCF5235 FEC RX interrupt handler: %s\n", + rtems_status_text(status)); + MCF5235_INTC0_ICR23 = MCF5235_INTC_ICR_IL(FEC_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT23 | MCF5235_INTC0_IMRL_MASKALL); + MCF5235_INTC0_ICR27 = MCF5235_INTC_ICR_IL(FEC_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT27 | MCF5235_INTC0_IMRL_MASKALL); +} + +/* + * Soak up buffer descriptors that have been sent. + */ +static void +fec_retire_tx_bd(volatile struct mcf5235_enet_struct *sc ) +{ + struct mbuf *m, *n; + + while ((sc->txBdActiveCount != 0) + && ((sc->txBdBase[sc->txBdTail].status & MCF5235_FEC_TxBD_R) == 0)) { + m = sc->txMbuf[sc->txBdTail]; + MFREE(m, n); + if (++sc->txBdTail == sc->txBdCount) + sc->txBdTail = 0; + sc->txBdActiveCount--; + } +} + +static void +fec_rxDaemon (void *arg) +{ + volatile struct mcf5235_enet_struct *sc = (volatile struct mcf5235_enet_struct *)arg; + struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if; + struct mbuf *m; + volatile uint16_t status; + volatile mcf5235BufferDescriptor_t *rxBd; + int rxBdIndex; + + /* + * Allocate space for incoming packets and start reception + */ + for (rxBdIndex = 0 ; ;) { + rxBd = sc->rxBdBase + rxBdIndex; + MGETHDR(m, M_WAIT, MT_DATA); + MCLGET(m, M_WAIT); + m->m_pkthdr.rcvif = ifp; + sc->rxMbuf[rxBdIndex] = m; + rxBd->buffer = mtod(m, void *); + rxBd->status = MCF5235_FEC_RxBD_E; + if (++rxBdIndex == sc->rxBdCount) { + rxBd->status |= MCF5235_FEC_RxBD_W; + break; + } + } + + /* + * Input packet handling loop + */ + /* Indicate we have some ready buffers available */ + MCF5235_FEC_RDAR = MCF5235_FEC_RDAR_R_DES_ACTIVE; + + rxBdIndex = 0; + for (;;) { + rxBd = sc->rxBdBase + rxBdIndex; + + /* + * Wait for packet if there's not one ready + */ + if ((status = rxBd->status) & MCF5235_FEC_RxBD_E) { + /* + * Clear old events. + */ + MCF5235_FEC_EIR = MCF5235_FEC_EIR_RXF; + + /* + * Wait for packet to arrive. + * Check the buffer descriptor before waiting for the event. + * This catches the case when a packet arrives between the + * `if' above, and the clearing of the RXF bit in the EIR. + */ + while ((status = rxBd->status) & MCF5235_FEC_RxBD_E) { + rtems_event_set events; + int level; + + rtems_interrupt_disable(level); + MCF5235_FEC_EIMR |= MCF5235_FEC_EIMR_RXF; + rtems_interrupt_enable(level); + rtems_bsdnet_event_receive (RX_INTERRUPT_EVENT, + RTEMS_WAIT|RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, + &events); + } + } + + /* + * Check that packet is valid + */ + if (status & MCF5235_FEC_RxBD_L) { + /* + * Pass the packet up the chain. + * FIXME: Packet filtering hook could be done here. + */ + struct ether_header *eh; + int len = rxBd->length - sizeof(uint32_t);; + + /* + * Invalidate the cache and push the packet up. + * The cache is so small that it's more efficient to just + * invalidate the whole thing unless the packet is very small. + */ + m = sc->rxMbuf[rxBdIndex]; + if (len < 128) + rtems_cache_invalidate_multiple_data_lines(m->m_data, len); + else + rtems_cache_invalidate_entire_data(); + m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header); + eh = mtod(m, struct ether_header *); + m->m_data += sizeof(struct ether_header); + ether_input(ifp, eh, m); + + /* + * Allocate a new mbuf + */ + MGETHDR(m, M_WAIT, MT_DATA); + MCLGET(m, M_WAIT); + m->m_pkthdr.rcvif = ifp; + sc->rxMbuf[rxBdIndex] = m; + rxBd->buffer = mtod(m, void *); + } + + /* + * Reenable the buffer descriptor + */ + rxBd->status = (status & MCF5235_FEC_RxBD_W) | MCF5235_FEC_RxBD_E; + MCF5235_FEC_RDAR = MCF5235_FEC_RDAR_R_DES_ACTIVE; + + /* + * Move to next buffer descriptor + */ + if (++rxBdIndex == sc->rxBdCount) + rxBdIndex = 0; + } +} + +static void +fec_sendpacket(struct ifnet *ifp, struct mbuf *m) +{ + struct mcf5235_enet_struct *sc = ifp->if_softc; + volatile mcf5235BufferDescriptor_t *firstTxBd, *txBd; + uint16_t status; + int nAdded; + + /* + * Free up buffer descriptors + */ + fec_retire_tx_bd(sc); + + /* + * Set up the transmit buffer descriptors. + * No need to pad out short packets since the + * hardware takes care of that automatically. + * No need to copy the packet to a contiguous buffer + * since the hardware is capable of scatter/gather DMA. + */ + nAdded = 0; + firstTxBd = sc->txBdBase + sc->txBdHead; + + for (;;) { + /* + * Wait for buffer descriptor to become available + */ + if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) { + /* + * Clear old events. + */ + MCF5235_FEC_EIR = MCF5235_FEC_EIR_TXF; + + /* + * Wait for buffer descriptor to become available. + * Check for buffer descriptors before waiting for the event. + * This catches the case when a buffer became available between + * the `if' above, and the clearing of the TXF bit in the EIR. + */ + fec_retire_tx_bd(sc); + while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) { + rtems_event_set events; + int level; + + rtems_interrupt_disable(level); + MCF5235_FEC_EIMR |= MCF5235_FEC_EIMR_TXF; + rtems_interrupt_enable(level); + sc->txRawWait++; + rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT, + RTEMS_WAIT|RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, + &events); + fec_retire_tx_bd(sc); + } + } + + /* + * Don't set the READY flag on the first fragment + * until the whole packet has been readied. + */ + status = nAdded ? MCF5235_FEC_TxBD_R : 0; + + /* + * The IP fragmentation routine in ip_output + * can produce fragments with zero length. + */ + txBd = sc->txBdBase + sc->txBdHead; + if (m->m_len) { + char *p = mtod(m, char *); + /* + * Stupid FEC can't handle misaligned data! + * Given the way that mbuf's are layed out it should be + * safe to shuffle the data down like this..... + * Perhaps this code could be improved with a "Duff's Device". + */ + if ((int)p & 0x3) { + int l = m->m_len; + char *dest = p - ((int)p & 0x3); + uint16_t *o = (uint16_t *)dest, *i = (uint16_t *)p; + while (l > 0) { + *o++ = *i++; + l -= sizeof(uint16_t); + } + p = dest; + sc->txRealign++; + } + txBd->buffer = p; + txBd->length = m->m_len; + sc->txMbuf[sc->txBdHead] = m; + nAdded++; + if (++sc->txBdHead == sc->txBdCount) { + status |= MCF5235_FEC_TxBD_W; + sc->txBdHead = 0; + } + m = m->m_next; + } + else { + /* + * Just toss empty mbufs + */ + struct mbuf *n; + MFREE(m, n); + m = n; + } + if (m == NULL) { + if (nAdded) { + txBd->status = status | MCF5235_FEC_TxBD_R + | MCF5235_FEC_TxBD_L + | MCF5235_FEC_TxBD_TC; + if (nAdded > 1) + firstTxBd->status |= MCF5235_FEC_TxBD_R; + MCF5235_FEC_TDAR = MCF5235_FEC_TDAR_X_DES_ACTIVE; + sc->txBdActiveCount += nAdded; + } + break; + } + txBd->status = status; + } +} + +void +fec_txDaemon(void *arg) +{ + struct mcf5235_enet_struct *sc = (struct mcf5235_enet_struct *)arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + struct mbuf *m; + rtems_event_set events; + + for (;;) { + /* + * Wait for packet + */ + rtems_bsdnet_event_receive(START_TRANSMIT_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events); + + /* + * Send packets till queue is empty + */ + for (;;) { + /* + * Get the next mbuf chain to transmit. + */ + IF_DEQUEUE(&ifp->if_snd, m); + if (!m) + break; + fec_sendpacket(ifp, m); + } + ifp->if_flags &= ~IFF_OACTIVE; + } +} + + +/* + * Send packet (caller provides header). + */ +static void +mcf5235_enet_start(struct ifnet *ifp) +{ + struct mcf5235_enet_struct *sc = ifp->if_softc; + + rtems_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT); + ifp->if_flags |= IFF_OACTIVE; +} + +static void +fec_init(void *arg) +{ + struct mcf5235_enet_struct *sc = arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + + if (sc->txDaemonTid == 0) { + /* + * Set up hardware + */ + mcf5235_fec_initialize_hardware(sc); + + /* + * Start driver tasks + */ + sc->txDaemonTid = rtems_bsdnet_newproc("FECtx", 4096, fec_txDaemon, sc); + sc->rxDaemonTid = rtems_bsdnet_newproc("FECrx", 4096, fec_rxDaemon, sc); + } + + /* + * Set flags appropriately + */ + if (ifp->if_flags & IFF_PROMISC) + MCF5235_FEC_RCR |= MCF5235_FEC_RCR_PROM; + else + MCF5235_FEC_RCR &= ~MCF5235_FEC_RCR_PROM; + + /* + * Tell the world that we're running. + */ + ifp->if_flags |= IFF_RUNNING; + + /* + * Enable receiver and transmitter + */ + MCF5235_FEC_ECR = MCF5235_FEC_ECR_ETHER_EN; +} + + +static void +fec_stop(struct mcf5235_enet_struct *sc) +{ + struct ifnet *ifp = &sc->arpcom.ac_if; + + ifp->if_flags &= ~IFF_RUNNING; + + /* + * Shut down receiver and transmitter + */ + MCF5235_FEC_ECR = 0x0; +} + +/* + * Show interface statistics + */ +static void +enet_stats(struct mcf5235_enet_struct *sc) +{ + printf(" Rx Interrupts:%-10lu", sc->rxInterrupts); + printf("Rx Packet Count:%-10lu", MCF5235_FEC_RMON_R_PACKETS); + printf(" Rx Broadcast:%-10lu\n", MCF5235_FEC_RMON_R_BC_PKT); + printf(" Rx Multicast:%-10lu", MCF5235_FEC_RMON_R_MC_PKT); + printf("CRC/Align error:%-10lu", MCF5235_FEC_RMON_R_CRC_ALIGN); + printf(" Rx Undersize:%-10lu\n", MCF5235_FEC_RMON_R_UNDERSIZE); + printf(" Rx Oversize:%-10lu", MCF5235_FEC_RMON_R_OVERSIZE); + printf(" Rx Fragment:%-10lu", MCF5235_FEC_RMON_R_FRAG); + printf(" Rx Jabber:%-10lu\n", MCF5235_FEC_RMON_R_JAB); + printf(" Rx 64:%-10lu", MCF5235_FEC_RMON_R_P64); + printf(" Rx 65-127:%-10lu", MCF5235_FEC_RMON_R_P65T0127); + printf(" Rx 128-255:%-10lu\n", MCF5235_FEC_RMON_R_P128TO255); + printf(" Rx 256-511:%-10lu", MCF5235_FEC_RMON_R_P256TO511); + printf(" Rx 511-1023:%-10lu", MCF5235_FEC_RMON_R_P512TO1023); + printf(" Rx 1024-2047:%-10lu\n", MCF5235_FEC_RMON_R_P1024TO2047); + printf(" Rx >=2048:%-10lu", MCF5235_FEC_RMON_R_GTE2048); + printf(" Rx Octets:%-10lu", MCF5235_FEC_RMON_R_OCTETS); + printf(" Rx Dropped:%-10lu\n", MCF5235_FEC_IEEE_R_DROP); + printf(" Rx frame OK:%-10lu", MCF5235_FEC_IEEE_R_FRAME_OK); + printf(" Rx CRC error:%-10lu", MCF5235_FEC_IEEE_R_CRC); + printf(" Rx Align error:%-10lu\n", MCF5235_FEC_IEEE_R_ALIGN); + printf(" FIFO Overflow:%-10lu", MCF5235_FEC_IEEE_R_MACERR); + printf("Rx Pause Frames:%-10lu", MCF5235_FEC_IEEE_R_FDXFC); + printf(" Rx Octets OK:%-10lu\n", MCF5235_FEC_IEEE_R_OCTETS_OK); + printf(" Tx Interrupts:%-10lu", sc->txInterrupts); + printf("Tx Output Waits:%-10lu", sc->txRawWait); + printf("Tx Realignments:%-10lu\n", sc->txRealign); + printf(" Tx Unaccounted:%-10lu", MCF5235_FEC_RMON_T_DROP); + printf("Tx Packet Count:%-10lu", MCF5235_FEC_RMON_T_PACKETS); + printf(" Tx Broadcast:%-10lu\n", MCF5235_FEC_RMON_T_BC_PKT); + printf(" Tx Multicast:%-10lu", MCF5235_FEC_RMON_T_MC_PKT); + printf("CRC/Align error:%-10lu", MCF5235_FEC_RMON_T_CRC_ALIGN); + printf(" Tx Undersize:%-10lu\n", MCF5235_FEC_RMON_T_UNDERSIZE); + printf(" Tx Oversize:%-10lu", MCF5235_FEC_RMON_T_OVERSIZE); + printf(" Tx Fragment:%-10lu", MCF5235_FEC_RMON_T_FRAG); + printf(" Tx Jabber:%-10lu\n", MCF5235_FEC_RMON_T_JAB); + printf(" Tx Collisions:%-10lu", MCF5235_FEC_RMON_T_COL); + printf(" Tx 64:%-10lu", MCF5235_FEC_RMON_T_P64); + printf(" Tx 65-127:%-10lu\n", MCF5235_FEC_RMON_T_P65TO127); + printf(" Tx 128-255:%-10lu", MCF5235_FEC_RMON_T_P128TO255); + printf(" Tx 256-511:%-10lu", MCF5235_FEC_RMON_T_P256TO511); + printf(" Tx 511-1023:%-10lu\n", MCF5235_FEC_RMON_T_P512TO1023); + printf(" Tx 1024-2047:%-10lu", MCF5235_FEC_RMON_T_P1024TO2047); + printf(" Tx >=2048:%-10lu", MCF5235_FEC_RMON_T_P_GTE2048); + printf(" Tx Octets:%-10lu\n", MCF5235_FEC_RMON_T_OCTETS); + printf(" Tx Dropped:%-10lu", MCF5235_FEC_IEEE_T_DROP); + printf(" Tx Frame OK:%-10lu", MCF5235_FEC_IEEE_T_FRAME_OK); + printf(" Tx 1 Collision:%-10lu\n", MCF5235_FEC_IEEE_T_1COL); + printf("Tx >1 Collision:%-10lu", MCF5235_FEC_IEEE_T_MCOL); + printf(" Tx Deferred:%-10lu", MCF5235_FEC_IEEE_T_DEF); + printf(" Late Collision:%-10lu\n", MCF5235_FEC_IEEE_T_LCOL); + printf(" Excessive Coll:%-10lu", MCF5235_FEC_IEEE_T_EXCOL); + printf(" FIFO Underrun:%-10lu", MCF5235_FEC_IEEE_T_MACERR); + printf(" Carrier Error:%-10lu\n", MCF5235_FEC_IEEE_T_CSERR); + printf(" Tx SQE Error:%-10lu", MCF5235_FEC_IEEE_T_SQE); + printf("Tx Pause Frames:%-10lu", MCF5235_FEC_IEEE_T_FDXFC); + printf(" Tx Octets OK:%-10lu\n", MCF5235_FEC_IEEE_T_OCTETS_OK); +} + +static int +fec_ioctl(struct ifnet *ifp, int command, caddr_t data) +{ + struct mcf5235_enet_struct *sc = ifp->if_softc; + int error = 0; + + switch (command) { + case SIOCGIFADDR: + case SIOCSIFADDR: + ether_ioctl(ifp, command, data); + break; + + case SIOCSIFFLAGS: + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + case IFF_RUNNING: + fec_stop(sc); + break; + + case IFF_UP: + fec_init(sc); + break; + + case IFF_UP | IFF_RUNNING: + fec_stop(sc); + fec_init(sc); + break; + + default: + break; + } + break; + + case SIO_RTEMS_SHOW_STATS: + enet_stats(sc); + break; + + /* + * FIXME: All sorts of multicast commands need to be added here! + */ + default: + error = EINVAL; + break; + } + return error; +} + +int +rtems_fec_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching ) +{ + struct mcf5235_enet_struct *sc; + struct ifnet *ifp; + int mtu; + int unitNumber; + char *unitName; + unsigned char *hwaddr; + + /* + * Parse driver name + */ + if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0) + return 0; + + /* + * Is driver free? + */ + if ((unitNumber <= 0) || (unitNumber > NIFACES)) { + printf("Bad FEC unit number.\n"); + return 0; + } + sc = &enet_driver[unitNumber - 1]; + ifp = &sc->arpcom.ac_if; + if (ifp->if_softc != NULL) { + printf("Driver already in use.\n"); + return 0; + } + + /* + * Process options + */ + hwaddr = config->hardware_address; + printf("%s%d: Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n", + unitName, unitNumber, + hwaddr[0], hwaddr[1], hwaddr[2], + hwaddr[3], hwaddr[4], hwaddr[5]); + memcpy(sc->arpcom.ac_enaddr, hwaddr, ETHER_ADDR_LEN); + + if (config->mtu) + mtu = config->mtu; + else + mtu = ETHERMTU; + if (config->rbuf_count) + sc->rxBdCount = config->rbuf_count; + else + sc->rxBdCount = RX_BUF_COUNT; + if (config->xbuf_count) + sc->txBdCount = config->xbuf_count; + else + sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF; + + sc->acceptBroadcast = !config->ignore_broadcast; + + /* + * Set up network interface values + */ + ifp->if_softc = sc; + ifp->if_unit = unitNumber; + ifp->if_name = unitName; + ifp->if_mtu = mtu; + ifp->if_init = fec_init; + ifp->if_ioctl = fec_ioctl; + ifp->if_start = mcf5235_enet_start; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; + if (ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + /* + * Attach the interface + */ + if_attach(ifp); + ether_ifattach(ifp); + return 1; +}; + diff --git a/c/src/lib/libbsp/m68k/mcf5235/start/start.S b/c/src/lib/libbsp/m68k/mcf5235/start/start.S new file mode 100644 index 0000000000..e72be12cbb --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/start/start.S @@ -0,0 +1,392 @@ +/* + * mcf5235 startup code + * + * This file contains the entry point for the application. + * The name of this entry point is compiler dependent. + * It jumps to the BSP which is responsible for performing + * all initialization. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +#define SRAM_SIZE (64*1024) +#define DEFAULT_IPSBAR 0x40000000 + +BEGIN_CODE +#define INITIAL_STACK __SRAMBASE+SRAM_SIZE-4 + + PUBLIC (INTERRUPT_VECTOR) +SYM(INTERRUPT_VECTOR): + .long INITIAL_STACK | 0: Initial 'SSP' + .long start | 1: Initial PC + .long SYM(_uhoh) | 2: Bus error + .long SYM(_uhoh) | 3: Address error + .long SYM(_uhoh) | 4: Illegal instruction + .long SYM(_uhoh) | 5: Zero division + .long SYM(_uhoh) | 6: CHK, CHK2 instruction + .long SYM(_uhoh) | 7: TRAPcc, TRAPV instructions + .long SYM(_uhoh) | 8: Privilege violation + .long SYM(_uhoh) | 9: Trace + .long SYM(_uhoh) | 10: Line 1010 emulator + .long SYM(_uhoh) | 11: Line 1111 emulator + .long SYM(_uhoh) | 12: Hardware breakpoint + .long SYM(_uhoh) | 13: Reserved for coprocessor violation + .long SYM(_uhoh) | 14: Format error + .long SYM(_uhoh) | 15: Uninitialized interrupt + .long SYM(_uhoh) | 16: Unassigned, reserved + .long SYM(_uhoh) | 17: + .long SYM(_uhoh) | 18: + .long SYM(_uhoh) | 19: + .long SYM(_uhoh) | 20: + .long SYM(_uhoh) | 21: + .long SYM(_uhoh) | 22: + .long SYM(_uhoh) | 23: + .long SYM(_spuriousInterrupt) | 24: Spurious interrupt + .long SYM(_uhoh) | 25: Level 1 interrupt autovector + .long SYM(_uhoh) | 26: Level 2 interrupt autovector + .long SYM(_uhoh) | 27: Level 3 interrupt autovector + .long SYM(_uhoh) | 28: Level 4 interrupt autovector + .long SYM(_uhoh) | 29: Level 5 interrupt autovector + .long SYM(_uhoh) | 30: Level 6 interrupt autovector + .long SYM(_uhoh) | 31: Level 7 interrupt autovector + .long SYM(_uhoh) | 32: Trap instruction (0-15) + .long SYM(_uhoh) | 33: + .long SYM(_uhoh) | 34: + .long SYM(_uhoh) | 35: + .long SYM(_uhoh) | 36: + .long SYM(_uhoh) | 37: + .long SYM(_uhoh) | 38: + .long SYM(_uhoh) | 39: + .long SYM(_uhoh) | 40: + .long SYM(_uhoh) | 41: + .long SYM(_uhoh) | 42: + .long SYM(_uhoh) | 43: + .long SYM(_uhoh) | 44: + .long SYM(_uhoh) | 45: + .long SYM(_uhoh) | 46: + .long SYM(_uhoh) | 47: + .long SYM(_uhoh) | 48: Reserved for coprocessor + .long SYM(_uhoh) | 49: + .long SYM(_uhoh) | 50: + .long SYM(_uhoh) | 51: + .long SYM(_uhoh) | 52: + .long SYM(_uhoh) | 53: + .long SYM(_uhoh) | 54: + .long SYM(_uhoh) | 55: + .long SYM(_uhoh) | 56: + .long SYM(_uhoh) | 57: + .long SYM(_uhoh) | 58: + .long SYM(_uhoh) | 59: Unassigned, reserved + .long SYM(_uhoh) | 60: + .long SYM(_uhoh) | 61: + .long SYM(_uhoh) | 62: + .long SYM(_uhoh) | 63: + .long SYM(_spuriousInterrupt) | 64: User spurious handler + .long SYM(_uhoh) | 65: + .long SYM(_uhoh) | 66: + .long SYM(_uhoh) | 67: + .long SYM(_uhoh) | 68: + .long SYM(_uhoh) | 69: + .long SYM(_uhoh) | 70: + .long SYM(_uhoh) | 71: + .long SYM(_uhoh) | 72: + .long SYM(_uhoh) | 73: + .long SYM(_uhoh) | 74: + .long SYM(_uhoh) | 75: + .long SYM(_uhoh) | 76: + .long SYM(_uhoh) | 77: + .long SYM(_uhoh) | 78: + .long SYM(_uhoh) | 79: + .long SYM(_uhoh) | 80: + .long SYM(_uhoh) | 81: + .long SYM(_uhoh) | 82: + .long SYM(_uhoh) | 83: + .long SYM(_uhoh) | 84: + .long SYM(_uhoh) | 85: + .long SYM(_uhoh) | 86: + .long SYM(_uhoh) | 87: + .long SYM(_uhoh) | 88: + .long SYM(_uhoh) | 89: + .long SYM(_uhoh) | 90: + .long SYM(_uhoh) | 91: + .long SYM(_uhoh) | 92: + .long SYM(_uhoh) | 93: + .long SYM(_uhoh) | 94: + .long SYM(_uhoh) | 95: + .long SYM(_uhoh) | 96: + .long SYM(_uhoh) | 97: + .long SYM(_uhoh) | 98: + .long SYM(_uhoh) | 99: + .long SYM(_uhoh) | 100: + .long SYM(_uhoh) | 101: + .long SYM(_uhoh) | 102: + .long SYM(_uhoh) | 103: + .long SYM(_uhoh) | 104: + .long SYM(_uhoh) | 105: + .long SYM(_uhoh) | 106: + .long SYM(_uhoh) | 107: + .long SYM(_uhoh) | 108: + .long SYM(_uhoh) | 109: + .long SYM(_uhoh) | 110: + .long SYM(_uhoh) | 111: + .long SYM(_uhoh) | 112: + .long SYM(_uhoh) | 113: + .long SYM(_uhoh) | 114: + .long SYM(_uhoh) | 115: + .long SYM(_uhoh) | 116: + .long SYM(_uhoh) | 117: + .long SYM(_uhoh) | 118: + .long SYM(_uhoh) | 119: + .long SYM(_uhoh) | 120: + .long SYM(_uhoh) | 121: + .long SYM(_uhoh) | 122: + .long SYM(_uhoh) | 123: + .long SYM(_uhoh) | 124: + .long SYM(_uhoh) | 125: + .long SYM(_uhoh) | 126: + .long SYM(_uhoh) | 127: + .long SYM(_uhoh) | 128: + .long SYM(_uhoh) | 129: + .long SYM(_uhoh) | 130: + .long SYM(_uhoh) | 131: + .long SYM(_uhoh) | 132: + .long SYM(_uhoh) | 133: + .long SYM(_uhoh) | 134: + .long SYM(_uhoh) | 135: + .long SYM(_uhoh) | 136: + .long SYM(_uhoh) | 137: + .long SYM(_uhoh) | 138: + .long SYM(_uhoh) | 139: + .long SYM(_uhoh) | 140: + .long SYM(_uhoh) | 141: + .long SYM(_uhoh) | 142: + .long SYM(_uhoh) | 143: + .long SYM(_uhoh) | 144: + .long SYM(_uhoh) | 145: + .long SYM(_uhoh) | 146: + .long SYM(_uhoh) | 147: + .long SYM(_uhoh) | 148: + .long SYM(_uhoh) | 149: + .long SYM(_uhoh) | 150: + .long SYM(_uhoh) | 151: + .long SYM(_uhoh) | 152: + .long SYM(_uhoh) | 153: + .long SYM(_uhoh) | 154: + .long SYM(_uhoh) | 155: + .long SYM(_uhoh) | 156: + .long SYM(_uhoh) | 157: + .long SYM(_uhoh) | 158: + .long SYM(_uhoh) | 159: + .long SYM(_uhoh) | 160: + .long SYM(_uhoh) | 161: + .long SYM(_uhoh) | 162: + .long SYM(_uhoh) | 163: + .long SYM(_uhoh) | 164: + .long SYM(_uhoh) | 165: + .long SYM(_uhoh) | 166: + .long SYM(_uhoh) | 167: + .long SYM(_uhoh) | 168: + .long SYM(_uhoh) | 169: + .long SYM(_uhoh) | 170: + .long SYM(_uhoh) | 171: + .long SYM(_uhoh) | 172: + .long SYM(_uhoh) | 173: + .long SYM(_uhoh) | 174: + .long SYM(_uhoh) | 175: + .long SYM(_uhoh) | 176: + .long SYM(_uhoh) | 177: + .long SYM(_uhoh) | 178: + .long SYM(_uhoh) | 179: + .long SYM(_uhoh) | 180: + .long SYM(_uhoh) | 181: + .long SYM(_uhoh) | 182: + .long SYM(_uhoh) | 183: + .long SYM(_uhoh) | 184: + .long SYM(_uhoh) | 185: + .long SYM(_uhoh) | 186: + .long SYM(_uhoh) | 187: + .long SYM(_uhoh) | 188: + .long SYM(_uhoh) | 189: + .long SYM(_uhoh) | 190: + .long SYM(_uhoh) | 191: + .long SYM(_uhoh) | 192: + .long SYM(_uhoh) | 193: + .long SYM(_uhoh) | 194: + .long SYM(_uhoh) | 195: + .long SYM(_uhoh) | 196: + .long SYM(_uhoh) | 197: + .long SYM(_uhoh) | 198: + .long SYM(_uhoh) | 199: + .long SYM(_uhoh) | 200: + .long SYM(_uhoh) | 201: + .long SYM(_uhoh) | 202: + .long SYM(_uhoh) | 203: + .long SYM(_uhoh) | 204: + .long SYM(_uhoh) | 205: + .long SYM(_uhoh) | 206: + .long SYM(_uhoh) | 207: + .long SYM(_uhoh) | 208: + .long SYM(_uhoh) | 209: + .long SYM(_uhoh) | 210: + .long SYM(_uhoh) | 211: + .long SYM(_uhoh) | 212: + .long SYM(_uhoh) | 213: + .long SYM(_uhoh) | 214: + .long SYM(_uhoh) | 215: + .long SYM(_uhoh) | 216: + .long SYM(_uhoh) | 217: + .long SYM(_uhoh) | 218: + .long SYM(_uhoh) | 219: + .long SYM(_uhoh) | 220: + .long SYM(_uhoh) | 221: + .long SYM(_uhoh) | 222: + .long SYM(_uhoh) | 223: + .long SYM(_uhoh) | 224: + .long SYM(_uhoh) | 225: + .long SYM(_uhoh) | 226: + .long SYM(_uhoh) | 227: + .long SYM(_uhoh) | 228: + .long SYM(_uhoh) | 229: + .long SYM(_uhoh) | 230: + .long SYM(_uhoh) | 231: + .long SYM(_uhoh) | 232: + .long SYM(_uhoh) | 233: + .long SYM(_uhoh) | 234: + .long SYM(_uhoh) | 235: + .long SYM(_uhoh) | 236: + .long SYM(_uhoh) | 237: + .long SYM(_uhoh) | 238: + .long SYM(_uhoh) | 239: + .long SYM(_uhoh) | 240: + .long SYM(_uhoh) | 241: + .long SYM(_uhoh) | 242: + .long SYM(_uhoh) | 243: + .long SYM(_uhoh) | 244: + .long SYM(_uhoh) | 245: + .long SYM(_uhoh) | 246: + .long SYM(_uhoh) | 247: + .long SYM(_uhoh) | 248: + .long SYM(_uhoh) | 249: + .long SYM(_uhoh) | 250: + .long SYM(_uhoh) | 251: + .long SYM(_uhoh) | 252: + .long SYM(_uhoh) | 253: + .long SYM(_uhoh) | 254: + .long SYM(_uhoh) | 255: + +/* + * Default trap handler + * With an oscilloscope you can see AS* stop + */ +.align 4 + PUBLIC (_uhoh) +SYM(_uhoh): + nop | Leave spot for breakpoint + stop #0x2700 | Stop with interrupts disabled + bra.w SYM(_uhoh) | Stuck forever + +.align 4 + PUBLIC (_spuriousInterrupt) +SYM(_spuriousInterrupt): + addql #1,SYM(_M68kSpuriousInterruptCount) + rte +/*************************************************************************** + Function : start + + Description : setup the internal SRAM for use and setup the INITIAL STACK ptr. + Also enable the internal peripherals + ***************************************************************************/ +.align 4 + PUBLIC (start) +SYM(start): + move.w #0x0000,d0 | Turn off watchdog timer + move.w d0, (0x40140000) + move.l #0x01000000,d0 | Set system frequency to 150 MHz + move.l d0, (0x40120000) + move.w #0x2700,sr | Disable interrupts + + move.l #__SRAMBASE+1,d0 | Enable the MCF5235 internal SRAM + movec d0,%rambar | ...so we have a stack + move.l #__IPSBAR+1,d0 | Enable the MCF5235 internal peripherals + move.l d0,DEFAULT_IPSBAR + + /* + * Remainder of the startup code is handled by C code + */ + jmp SYM(Init5235) | Start C code (which never returns) + +/*************************************************************************** + Function : CopyDataClearBSSAndStart + + Description : Copy DATA segment, Copy SRAM segment, clear BSS segment, + start C program. Assume that DATA and BSS sizes are multiples of 4. + ***************************************************************************/ +.align 4 + + PUBLIC (CopyDataClearBSSAndStart) +SYM(CopyDataClearBSSAndStart): + lea SYM(_data_dest_start),a0 | Get start of DATA in RAM + lea SYM(_data_src_start),a2 | Get start of DATA in ROM + cmpl a0,a2 | Are they the same? + beq.s NODATACOPY | Yes, no copy necessary + lea SYM(_data_dest_end),a1 | Get end of DATA in RAM + bra.s DATACOPYLOOPTEST | Branch into copy loop +DATACOPYLOOP: + movel a2@+,a0@+ | Copy word from ROM to RAM +DATACOPYLOOPTEST: + cmpl a1,a0 | Done? + bcs.s DATACOPYLOOP | No, skip +NODATACOPY: + +/* Now, clear BSS */ + lea _clear_start,a0 | Get start of BSS + lea _clear_end,a1 | Get end of BSS + clrl d0 | Value to set + bra.s ZEROLOOPTEST | Branch into clear loop +ZEROLOOP: + movel d0,a0@+ | Clear a word +ZEROLOOPTEST: + cmpl a1,a0 | Done? + bcs.s ZEROLOOP | No, skip + + + /* + * Right : Now we're ready to boot RTEMS + */ + clrl d0 | Pass in null to all boot_card() params + movel d0,a7@- | environp + movel d0,a7@- | argv + movel d0,a7@- | argc + jsr SYM(boot_card) | Call C boot_card function to startup RTEMS + movel a7@+,d0 + movel a7@+,d0 + movel a7@+,d0 +MULTI_TASK_EXIT: + nop + nop + trap #14 + bra MULTI_TASK_EXIT + +END_CODE + + .align 2 +BEGIN_DATA_DCL + .align 2 + PUBLIC (_M68kSpuriousInterruptCount) +SYM (_M68kSpuriousInterruptCount): + .long 0 +END_DATA_DCL + +END + diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c b/c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c new file mode 100644 index 0000000000..b3a8536f4f --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/startup/bspclean.c @@ -0,0 +1,35 @@ +/* + * SBC5206 bsp_cleanup + * + * This routine returns control from RTEMS to the monitor. + * + * Author: + * David Fiddes, D.J@fiddes.surfaid.org + * http://www.calm.hw.ac.uk/davidf/coldfire/ + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include + +void bsp_cleanup( void ) +{ + printk("\nRTEMS exited!\n"); + for ( ;; ) + { + asm volatile ( " nop " ); + asm volatile ( " nop " ); + } + +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c b/c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c new file mode 100644 index 0000000000..e16d4c0ee0 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/startup/bspstart.c @@ -0,0 +1,220 @@ +/* + * BSP startup + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * Author: + * David Fiddes, D.J@fiddes.surfaid.org + * http://www.calm.hw.ac.uk/davidf/coldfire/ + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* + * The original table from the application and our copy of it with + * some changes. + */ +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; +rtems_cpu_table Cpu_table; +char *rtems_progname; + + +/* + * Cacheable areas + */ +#define SDRAM_BASE 0 +#define SDRAM_SIZE (16*1024*1024) + +/* + * CPU-space access + */ +#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr" : : "d" (_cacr)) +#define m68k_set_acr0(_acr0) asm volatile ("movec %0,%%acr0" : : "d" (_acr0)) +#define m68k_set_acr1(_acr1) asm volatile ("movec %0,%%acr1" : : "d" (_acr1)) + +/* + * Read/write copy of common cache + * Split I/D cache + * Allow CPUSHL to invalidate a cache line + * Enable buffered writes + * No burst transfers on non-cacheable accesses + * Default cache mode is *disabled* (cache only ACRx areas) + */ +static unsigned32 cacr_mode = MCF5XXX_CACR_CENB | + MCF5XXX_CACR_DBWE | + MCF5XXX_CACR_DCM; +/* + * Cannot be frozen + */ +void _CPU_cache_freeze_data(void) {} +void _CPU_cache_unfreeze_data(void) {} +void _CPU_cache_freeze_instruction(void) {} +void _CPU_cache_unfreeze_instruction(void) {} + +/* + * Write-through data cache -- flushes are unnecessary + */ +void _CPU_cache_flush_1_data_line(const void *d_addr) {} +void _CPU_cache_flush_entire_data(void) {} + +void _CPU_cache_enable_instruction(void) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + cacr_mode &= ~MCF5XXX_CACR_DIDI; + m68k_set_cacr(cacr_mode); + rtems_interrupt_enable(level); +} + +void _CPU_cache_disable_instruction(void) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + cacr_mode |= MCF5XXX_CACR_DIDI; + m68k_set_cacr(cacr_mode); + rtems_interrupt_enable(level); +} + +void _CPU_cache_invalidate_entire_instruction(void) +{ + m68k_set_cacr(cacr_mode | MCF5XXX_CACR_CINV | MCF5XXX_CACR_INVI); +} + +void _CPU_cache_invalidate_1_instruction_line(const void *addr) +{ + /* + * Top half of cache is I-space + */ + addr = (void *)((int)addr | 0x400); + asm volatile ("cpushl %%bc,(%0)" :: "a" (addr)); +} + +void _CPU_cache_enable_data(void) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + cacr_mode &= ~MCF5XXX_CACR_DISD; + m68k_set_cacr(cacr_mode); + rtems_interrupt_enable(level); +} + +void _CPU_cache_disable_data(void) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + rtems_interrupt_disable(level); + cacr_mode |= MCF5XXX_CACR_DISD; + m68k_set_cacr(cacr_mode); + rtems_interrupt_enable(level); +} + +void _CPU_cache_invalidate_entire_data(void) +{ + m68k_set_cacr(cacr_mode | MCF5XXX_CACR_CINV | MCF5XXX_CACR_INVD); +} + +void _CPU_cache_invalidate_1_data_line(const void *addr) +{ + /* + * Bottom half of cache is D-space + */ + addr = (void *)((int)addr & ~0x400); + asm volatile ("cpushl %%bc,(%0)" :: "a" (addr)); +} + +/* + * Use the shared implementations of the following routines + */ +void bsp_postdriver_hook(void); +void bsp_libc_init( void *, unsigned32, int ); +void bsp_pretasking_hook(void); /* m68k version */ + +/* + * bsp_start + * + * This routine does the bulk of the system initialisation. + */ +void bsp_start( void ) +{ + extern char _WorkspaceBase[]; + extern char _RamSize[]; + extern unsigned long _M68k_Ramsize; + + _M68k_Ramsize = (unsigned long)_RamSize; /* RAM size set in linker script */ + + /* + * Allocate the memory for the RTEMS Work Space. This can come from + * a variety of places: hard coded address, malloc'ed from outside + * RTEMS world (e.g. simulator or primitive memory manager), or (as + * typically done by stock BSPs) by subtracting the required amount + * of work space from the last physical address on the CPU board. + */ + + /* + * Need to "allocate" the memory for the RTEMS Workspace and + * tell the RTEMS configuration where it is. This memory is + * not malloc'ed. It is just "pulled from the air". + */ + + BSP_Configuration.work_space_start = (void *)_WorkspaceBase; + + /* + * initialize the CPU table for this BSP + */ + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + Cpu_table.postdriver_hook = bsp_postdriver_hook; + Cpu_table.do_zero_of_workspace = TRUE; + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.interrupt_vector_table = (m68k_isr *)0; /* vectors at start of RAM */ + + /* + * Invalidate the cache and disable it + */ + m68k_set_acr0(0); + m68k_set_acr1(0); + m68k_set_cacr(MCF5XXX_CACR_CINV); + + /* + * Cache SDRAM + */ + m68k_set_acr0(MCF5XXX_ACR_AB(SDRAM_BASE) | + MCF5XXX_ACR_AM(SDRAM_SIZE-1) | + MCF5XXX_ACR_EN | + MCF5XXX_ACR_BWE | + MCF5XXX_ACR_SM_IGNORE); + + /* + * Enable the cache + */ + m68k_set_cacr(cacr_mode); + +} + +unsigned32 get_CPU_clock_speed(void) +{ + extern char _CPUClockSpeed[]; + return( (unsigned32)_CPUClockSpeed); +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c b/c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c new file mode 100644 index 0000000000..47de7f6d3a --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/startup/init5235.c @@ -0,0 +1,80 @@ +/* + * This is where the real hardware setup is done. A minimal stack + * has been provided by the start.S code. No normal C or RTEMS + * functions can be called from here. + * + * This routine is pretty simple for the uC5235 because all the hard + * work has been done by the bootstrap dBUG code. + */ + +#include +#include +#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr" : : "d" (_cacr)) +#define m68k_set_acr0(_acr0) asm volatile ("movec %0,%%acr0" : : "d" (_acr0)) +#define m68k_set_acr1(_acr1) asm volatile ("movec %0,%%acr1" : : "d" (_acr1)) +#define MM_SDRAM_BASE (0x00000000) + +void Init5235 (void) +{ + extern void CopyDataClearBSSAndStart (void); + int x; + int temp = 0; + + //Setup the GPIO Registers + MCF5235_GPIO_UART=0x3FFF; + MCF5235_GPIO_PAR_AD=0xE1; + + //Setup the Chip Selects so CS0 is flash + MCF5235_CS_CSAR0 =(0xFFE00000 & 0xffff0000)>>16; + MCF5235_CS_CSMR0 = 0x001f0001; + MCF5235_CS_CSCR0 = 0x1980; + + //Setup the SDRAM + for(x=0; x<20000; x++) + { + temp +=1; + } + MCF5235_SDRAMC_DCR = 0x042E; + MCF5235_SDRAMC_DACR0 = 0x00001300; + MCF5235_SDRAMC_DMR0 = (0x00FC0000) | (0x00000001); + for(x=0; x<20000; x++) + { + temp +=1; + } + // set ip ( bit 3 ) in dacr + MCF5235_SDRAMC_DACR0 |= (0x00000008) ; + // init precharge + *((unsigned long *)MM_SDRAM_BASE) = 0xDEADBEEF; + // set RE in dacr + MCF5235_SDRAMC_DACR0 |= (0x00008000); + // wait + for(x=0; x<20000; x++) + { + temp +=1; + } + // issue IMRS + MCF5235_SDRAMC_DACR0 |= (0x00000040); + *((short *)MM_SDRAM_BASE) = 0; + for(x=0; x<60000; x++) + { + temp +=1; + } + *((unsigned long*)MM_SDRAM_BASE)=0x12345678; + + /* Copy the interrupt vector table to address 0x0 in SDRAM */ + { + extern void INTERRUPT_VECTOR(); + uint32_t *inttab = (uint32_t *)&INTERRUPT_VECTOR; + uint32_t *intvec = (uint32_t *)0x0; + register int i; + for (i = 0; i < 256; i++) + { + *(intvec++) = *(inttab++); + } + } + + /* + * Copy data, clear BSS and call boot_card() + */ + CopyDataClearBSSAndStart (); +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds new file mode 100644 index 0000000000..11b25c0861 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmds @@ -0,0 +1,175 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Arcturus uC DIMM ColdFire 5282 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +/* + * Declare some sizes. + */ +_RamBase = DEFINED(_RamBase) ? _RamBase : 0x0 ; +_RamSize = DEFINED(_RamSize) ? _RamSize : 16M ; +_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0 ; + + +/* + * System clock speed + */ +_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 150000000 ; + +/* + * Location of on-chip devices + */ +__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ; +__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ; +_VBR = 0x0; + +ENTRY(start) +MEMORY +{ + ram : ORIGIN = 0, LENGTH = 16M + sram : ORIGIN = 0x20000000, LENGTH = 64K + flash : ORIGIN = 0xFFE00000, LENGTH = 2M +} + +SECTIONS +{ + + _header_offset = 0; + + /* + * Text, data and bss segments + */ + .text 0x40000 : { + + *(.text) + *(.ram_code) + + /* + * C++ constructors/destructors + */ + *(.gnu.linkonce.t.*) + + /* + * Initialization and finalization code. + * + * Various files can provide initialization and finalization + * functions. crtbegin.o and crtend.o are two instances. The + * body of these functions are in .init and .fini sections. We + * accumulate the bodies here, and prepend function prologues + * from crti.o and function epilogues from crtn.o. crti.o must + * be linked first; crtn.o must be linked last. Because these + * are wildcards, it doesn't matter if the user does not + * actually link against crti.o and crtn.o; the linker won't + * look for a file to match a wildcard. The wildcard also + * means that it doesn't matter which directory crti.o and + * crtn.o are in. + */ + PROVIDE (_init = .); + *crti.o(.init) + *(.init) + *crtn.o(.init) + PROVIDE (_fini = .); + *crti.o(.fini) + *(.fini) + *crtn.o(.fini) + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + + /* + * C++ constructors/destructors + * + * gcc uses crtbegin.o to find the start of the constructors + * and destructors so we make sure it is first. Because this + * is a wildcard, it doesn't matter if the user does not + * actually link against crtbegin.o; the linker won't look for + * a file to match a wildcard. The wildcard also means that + * it doesn't matter which directory crtbegin.o is in. The + * constructor and destructor list are terminated in + * crtend.o. The same comments apply to it. + */ + . = ALIGN (16); + *crtbegin.o(.ctors) + *(.ctors) + *crtend.o(.ctors) + *crtbegin.o(.dtors) + *(.dtors) + *crtend.o(.dtors) + + /* + * Exception frame info + */ + . = ALIGN (16); + *(.eh_frame) + + /* + * Read-only data + */ + . = ALIGN (16); + _rodata_start = . ; + *(.rodata*) + *(.gnu.linkonce.r*) + + . = ALIGN (16); + + *(.console_gdb_xfer) + *(.bootstrap_data) + . = ALIGN(16); + _estuff = .; + PROVIDE (_etext = .); + } >ram + + .data : { + PROVIDE( _data_dest_start = . ); + PROVIDE( _copy_start = .); + *(.data) + *(.gnu.linkonce.d*) + *(.gcc_except_table) + *(.jcr) + . = ALIGN (16); + PROVIDE (_edata = .); + PROVIDE (_copy_end = .); + PROVIDE (_data_dest_end = . ); + } >ram + + _data_src_start = _estuff; + _data_src_end = _data_dest_start + SIZEOF(.data); + + .bss : { + _clear_start = .; + *(.bss) + *(COMMON) + . = ALIGN (16); + PROVIDE (end = .); + _clear_end = .; + + _WorkspaceBase = .; + } >ram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + +PROVIDE (end_of_all = .); +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash new file mode 100644 index 0000000000..41f64665f7 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsflash @@ -0,0 +1,180 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Arcturus uC DIMM ColdFire 5282 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +/* + * Declare some sizes. + */ +_RamBase = DEFINED(_RamBase) ? _RamBase : 0x0 ; +_RamSize = DEFINED(_RamSize) ? _RamSize : 16M ; +_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0 ; + + +/* + * System clock speed + */ +_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 150000000 ; + +/* + * Location of on-chip devices + */ +__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ; +__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ; +_VBR = 0x0; + +ENTRY(start) +/* + * NOTE: If loading to flash with dBUG remember to change the origin to 0xFFF00000 because that's where user flash is + * located. + */ +MEMORY +{ + ram : ORIGIN = 0, LENGTH = 16M + sram : ORIGIN = 0x20000000, LENGTH = 64K + flash : ORIGIN = 0xFFE00000, LENGTH = 2M +} + +SECTIONS +{ + + _header_offset = 0; + + /* + * Text, data and bss segments + */ + .text : { + + *(.text) + *(.ram_code) + + /* + * C++ constructors/destructors + */ + *(.gnu.linkonce.t.*) + + /* + * Initialization and finalization code. + * + * Various files can provide initialization and finalization + * functions. crtbegin.o and crtend.o are two instances. The + * body of these functions are in .init and .fini sections. We + * accumulate the bodies here, and prepend function prologues + * from crti.o and function epilogues from crtn.o. crti.o must + * be linked first; crtn.o must be linked last. Because these + * are wildcards, it doesn't matter if the user does not + * actually link against crti.o and crtn.o; the linker won't + * look for a file to match a wildcard. The wildcard also + * means that it doesn't matter which directory crti.o and + * crtn.o are in. + */ + PROVIDE (_init = .); + *crti.o(.init) + *(.init) + *crtn.o(.init) + PROVIDE (_fini = .); + *crti.o(.fini) + *(.fini) + *crtn.o(.fini) + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + + /* + * C++ constructors/destructors + * + * gcc uses crtbegin.o to find the start of the constructors + * and destructors so we make sure it is first. Because this + * is a wildcard, it doesn't matter if the user does not + * actually link against crtbegin.o; the linker won't look for + * a file to match a wildcard. The wildcard also means that + * it doesn't matter which directory crtbegin.o is in. The + * constructor and destructor list are terminated in + * crtend.o. The same comments apply to it. + */ + . = ALIGN (16); + *crtbegin.o(.ctors) + *(.ctors) + *crtend.o(.ctors) + *crtbegin.o(.dtors) + *(.dtors) + *crtend.o(.dtors) + + /* + * Exception frame info + */ + . = ALIGN (16); + *(.eh_frame) + + /* + * Read-only data + */ + . = ALIGN (16); + _rodata_start = . ; + *(.rodata*) + *(.gnu.linkonce.r*) + + . = ALIGN (16); + + *(.console_gdb_xfer) + *(.bootstrap_data) + . = ALIGN(16); + _estuff = .; + PROVIDE (_etext = .); + } >flash + + .data 0x4000 : AT ( ADDR(.text) + SIZEOF ( .text ) ) + { + PROVIDE( _data_dest_start = . ); + PROVIDE( _copy_start = .); + *(.data) + *(.gnu.linkonce.d*) + *(.gcc_except_table) + *(.jcr) + . = ALIGN (16); + PROVIDE (_edata = .); + PROVIDE (_copy_end = .); + PROVIDE (_data_dest_end = . ); + } >ram + + _data_src_start = _estuff; + _data_src_end = _data_dest_start + SIZEOF(.data); + + .bss : { + _clear_start = .; + *(.bss) + *(COMMON) + . = ALIGN (16); + PROVIDE (end = .); + _clear_end = .; + + _WorkspaceBase = .; + } >ram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + +PROVIDE (end_of_all = .); +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram new file mode 100644 index 0000000000..11b25c0861 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/startup/linkcmdsram @@ -0,0 +1,175 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Arcturus uC DIMM ColdFire 5282 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +/* + * Declare some sizes. + */ +_RamBase = DEFINED(_RamBase) ? _RamBase : 0x0 ; +_RamSize = DEFINED(_RamSize) ? _RamSize : 16M ; +_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0 ; + + +/* + * System clock speed + */ +_CPUClockSpeed = DEFINED(_CPUClockSpeed) ? _CPUClockSpeed : 150000000 ; + +/* + * Location of on-chip devices + */ +__IPSBAR = DEFINED(__IPSBAR) ? __IPSBAR : 0x40000000 ; +__SRAMBASE = DEFINED(__SRAMBASE) ? __SRAMBASE : 0x20000000 ; +_VBR = 0x0; + +ENTRY(start) +MEMORY +{ + ram : ORIGIN = 0, LENGTH = 16M + sram : ORIGIN = 0x20000000, LENGTH = 64K + flash : ORIGIN = 0xFFE00000, LENGTH = 2M +} + +SECTIONS +{ + + _header_offset = 0; + + /* + * Text, data and bss segments + */ + .text 0x40000 : { + + *(.text) + *(.ram_code) + + /* + * C++ constructors/destructors + */ + *(.gnu.linkonce.t.*) + + /* + * Initialization and finalization code. + * + * Various files can provide initialization and finalization + * functions. crtbegin.o and crtend.o are two instances. The + * body of these functions are in .init and .fini sections. We + * accumulate the bodies here, and prepend function prologues + * from crti.o and function epilogues from crtn.o. crti.o must + * be linked first; crtn.o must be linked last. Because these + * are wildcards, it doesn't matter if the user does not + * actually link against crti.o and crtn.o; the linker won't + * look for a file to match a wildcard. The wildcard also + * means that it doesn't matter which directory crti.o and + * crtn.o are in. + */ + PROVIDE (_init = .); + *crti.o(.init) + *(.init) + *crtn.o(.init) + PROVIDE (_fini = .); + *crti.o(.fini) + *(.fini) + *crtn.o(.fini) + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + + /* + * C++ constructors/destructors + * + * gcc uses crtbegin.o to find the start of the constructors + * and destructors so we make sure it is first. Because this + * is a wildcard, it doesn't matter if the user does not + * actually link against crtbegin.o; the linker won't look for + * a file to match a wildcard. The wildcard also means that + * it doesn't matter which directory crtbegin.o is in. The + * constructor and destructor list are terminated in + * crtend.o. The same comments apply to it. + */ + . = ALIGN (16); + *crtbegin.o(.ctors) + *(.ctors) + *crtend.o(.ctors) + *crtbegin.o(.dtors) + *(.dtors) + *crtend.o(.dtors) + + /* + * Exception frame info + */ + . = ALIGN (16); + *(.eh_frame) + + /* + * Read-only data + */ + . = ALIGN (16); + _rodata_start = . ; + *(.rodata*) + *(.gnu.linkonce.r*) + + . = ALIGN (16); + + *(.console_gdb_xfer) + *(.bootstrap_data) + . = ALIGN(16); + _estuff = .; + PROVIDE (_etext = .); + } >ram + + .data : { + PROVIDE( _data_dest_start = . ); + PROVIDE( _copy_start = .); + *(.data) + *(.gnu.linkonce.d*) + *(.gcc_except_table) + *(.jcr) + . = ALIGN (16); + PROVIDE (_edata = .); + PROVIDE (_copy_end = .); + PROVIDE (_data_dest_end = . ); + } >ram + + _data_src_start = _estuff; + _data_src_end = _data_dest_start + SIZEOF(.data); + + .bss : { + _clear_start = .; + *(.bss) + *(COMMON) + . = ALIGN (16); + PROVIDE (end = .); + _clear_end = .; + + _WorkspaceBase = .; + } >ram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + +PROVIDE (end_of_all = .); +} diff --git a/c/src/lib/libbsp/m68k/mcf5235/timer/timer.c b/c/src/lib/libbsp/m68k/mcf5235/timer/timer.c new file mode 100644 index 0000000000..f266afa712 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mcf5235/timer/timer.c @@ -0,0 +1,43 @@ +/* + * Timer Init + * + * Use the last DMA timer (DTIM3) as the diagnostic timer. + */ + +#include +#include + +void +Timer_initialize(void) +{ + int preScaleDivisor = 0x4A; + int div = MCF5235_TIMER_DTMR_CLK_DIV1; + MCF5235_TIMER_DTRR3 = 0x2710; + MCF5235_TIMER3_DTMR = 0; + MCF5235_TIMER3_DTMR = MCF5235_TIMER_DTMR_PS(preScaleDivisor) | div | + MCF5235_TIMER_DTMR_RST; +} + +/* + * Return timer value in microsecond units + */ +int +Read_timer(void) +{ + return MCF5235_TIMER3_DTCN; +} + +/* + * Empty function call used in loops to measure basic cost of looping + * in Timing Test Suite. + */ +rtems_status_code +Empty_function(void) +{ + return RTEMS_SUCCESSFUL; +} + +void +Set_find_average_overhead(rtems_boolean find_flag) +{ +} -- cgit v1.2.3