forked from Imagelibrary/rtems
2008-06-20 Matthew Riek <matthew.riek@ibiscomputer.com.au>
* ChangeLog, Makefile.am, README, bsp_specs, configure.ac, gdb-init, preinstall.am, clock/clock.c, console/console.c, include/bsp.h, include/bspopts.h.in, include/coverhd.h, include/tm27.h, network/network.c, start/start.S, startup/bspclean.c, startup/bspstart.c, startup/cfinit.c, startup/init5329.c, startup/linkcmds, startup/linkcmdsflash, timer/timer.c: New files.
This commit is contained in:
9
c/src/lib/libbsp/m68k/mcf5329/ChangeLog
Normal file
9
c/src/lib/libbsp/m68k/mcf5329/ChangeLog
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
2008-06-20 Matthew Riek <matthew.riek@ibiscomputer.com.au>
|
||||||
|
|
||||||
|
* ChangeLog, Makefile.am, README, bsp_specs, configure.ac, gdb-init,
|
||||||
|
preinstall.am, clock/clock.c, console/console.c, include/bsp.h,
|
||||||
|
include/bspopts.h.in, include/coverhd.h, include/tm27.h,
|
||||||
|
network/network.c, start/start.S, startup/bspclean.c,
|
||||||
|
startup/bspstart.c, startup/cfinit.c, startup/init5329.c,
|
||||||
|
startup/linkcmds, startup/linkcmdsflash, timer/timer.c: New files.
|
||||||
|
|
||||||
61
c/src/lib/libbsp/m68k/mcf5329/Makefile.am
Normal file
61
c/src/lib/libbsp/m68k/mcf5329/Makefile.am
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
##
|
||||||
|
## $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) -o $@ -c $<
|
||||||
|
project_lib_DATA = start.$(OBJEXT)
|
||||||
|
|
||||||
|
dist_project_lib_DATA += startup/linkcmds startup/linkcmdsflash
|
||||||
|
|
||||||
|
startup_SOURCES = startup/bspclean.c ../../shared/bsppredriverhook.c \
|
||||||
|
../../shared/bsplibc.c ../../shared/bsppost.c \
|
||||||
|
../../m68k/shared/m68kpretaskinghook.c \
|
||||||
|
../../m68k/shared/m68kbspgetworkarea.c \
|
||||||
|
startup/init5329.c startup/bspstart.c startup/cfinit.c\
|
||||||
|
../../shared/bootcard.c \
|
||||||
|
../../shared/sbrk.c ../../m68k/shared/setvec.c \
|
||||||
|
../../shared/gnatinstallhandler.c
|
||||||
|
clock_SOURCES = clock/clock.c
|
||||||
|
console_SOURCES = console/console.c
|
||||||
|
timer_SOURCES = timer/timer.c
|
||||||
|
|
||||||
|
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 = $(startup_SOURCES) $(clock_SOURCES) $(console_SOURCES) \
|
||||||
|
$(timer_SOURCES)
|
||||||
|
|
||||||
|
libbsp_a_LIBADD = \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/shared/misc.rel
|
||||||
|
if HAS_NETWORKING
|
||||||
|
libbsp_a_LIBADD += network.rel
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(srcdir)/preinstall.am
|
||||||
|
include $(top_srcdir)/../../../../automake/local.am
|
||||||
51
c/src/lib/libbsp/m68k/mcf5329/README
Normal file
51
c/src/lib/libbsp/m68k/mcf5329/README
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#
|
||||||
|
# $Id:
|
||||||
|
#
|
||||||
|
|
||||||
|
Description: Motorola MCF5329EVB Zoom + (LogicPD)
|
||||||
|
============
|
||||||
|
CPU: MCF5329, 240MHz
|
||||||
|
CORESRAM: 32K
|
||||||
|
FLASH: 2M
|
||||||
|
DRAM: 32M
|
||||||
|
|
||||||
|
This is a Motorola Zoom evaluation board that uses the MCF5329 Coldfire CPU on
|
||||||
|
a logicPD card. This board is running at 240MHz with DRAM clocking at 80MHz.
|
||||||
|
|
||||||
|
The bsp is configured for the MT46V16M16TG-75:F DRAM.
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
======
|
||||||
|
|
||||||
|
This BSP is based heavily off the 5235 BSP.
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
======
|
||||||
|
|
||||||
|
Add other drivers for can, i2c, lcd (fb), qspi etc.
|
||||||
|
|
||||||
|
============================================================================
|
||||||
|
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 | | | | | | | | |
|
||||||
|
+-----+--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
|
||||||
|
============================================================================
|
||||||
|
Timings
|
||||||
13
c/src/lib/libbsp/m68k/mcf5329/bsp_specs
Normal file
13
c/src/lib/libbsp/m68k/mcf5329/bsp_specs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
%rename endfile old_endfile
|
||||||
|
%rename startfile old_startfile
|
||||||
|
%rename link old_link
|
||||||
|
|
||||||
|
*startfile:
|
||||||
|
%{!qrtems: %(old_startfile)} \
|
||||||
|
%{!nostdlib: %{qrtems: start.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}
|
||||||
98
c/src/lib/libbsp/m68k/mcf5329/clock/clock.c
Normal file
98
c/src/lib/libbsp/m68k/mcf5329/clock/clock.c
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Use the last periodic interval timer (PIT2) as the system clock.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use INTC1 base
|
||||||
|
*/
|
||||||
|
#define CLOCK_VECTOR (128+46)
|
||||||
|
|
||||||
|
static uint32_t s_pcntrAtTick = 0;
|
||||||
|
static uint32_t s_nanoScale = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide nanosecond extension
|
||||||
|
*/
|
||||||
|
static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (MCF_PIT3_PCSR & MCF_PIT_PCSR_PIF) {
|
||||||
|
i = s_pcntrAtTick + (MCF_PIT3_PMR - MCF_PIT3_PCNTR);
|
||||||
|
} else {
|
||||||
|
i = s_pcntrAtTick - MCF_PIT3_PCNTR;
|
||||||
|
}
|
||||||
|
return i * s_nanoScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Periodic interval timer interrupt handler
|
||||||
|
*/
|
||||||
|
#define Clock_driver_support_at_tick() \
|
||||||
|
do { \
|
||||||
|
s_pcntrAtTick = MCF_PIT3_PCNTR; \
|
||||||
|
MCF_PIT3_PCSR |= MCF_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
|
||||||
|
*/
|
||||||
|
static void Clock_driver_support_shutdown_hardware()
|
||||||
|
{
|
||||||
|
MCF_PIT3_PCSR &= ~MCF_PIT_PCSR_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the clock hardware
|
||||||
|
*
|
||||||
|
* We need to have 1 interrupt every BSP_Configuration.microseconds_per_tick
|
||||||
|
*/
|
||||||
|
static void Clock_driver_support_initialize_hardware()
|
||||||
|
{
|
||||||
|
int level;
|
||||||
|
uint32_t pmr;
|
||||||
|
uint32_t preScaleCode = 0;
|
||||||
|
uint32_t clk = bsp_get_BUS_clock_speed();
|
||||||
|
uint32_t tps = 1000000 / Configuration.microseconds_per_tick;
|
||||||
|
|
||||||
|
while (preScaleCode < 15) {
|
||||||
|
pmr = (clk >> preScaleCode) / tps;
|
||||||
|
if (pmr < (1 << 15))
|
||||||
|
break;
|
||||||
|
preScaleCode++;
|
||||||
|
}
|
||||||
|
s_nanoScale = 1000000000 / (clk >> preScaleCode);
|
||||||
|
|
||||||
|
MCF_INTC1_ICR46 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL);
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
MCF_INTC1_IMRH &= ~MCF_INTC_IMRH_INT_MASK46;
|
||||||
|
MCF_PIT3_PCSR &= ~MCF_PIT_PCSR_EN;
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
|
|
||||||
|
MCF_PIT3_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
|
||||||
|
MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD;
|
||||||
|
MCF_PIT3_PMR = pmr;
|
||||||
|
MCF_PIT3_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
|
||||||
|
MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
|
||||||
|
s_pcntrAtTick = MCF_PIT3_PCNTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../../../shared/clockdrv_shell.c"
|
||||||
25
c/src/lib/libbsp/m68k/mcf5329/configure.ac
Normal file
25
c/src/lib/libbsp/m68k/mcf5329/configure.ac
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
## Process this file with autoconf to produce a configure script.
|
||||||
|
##
|
||||||
|
## $Id$
|
||||||
|
|
||||||
|
AC_PREREQ(2.60)
|
||||||
|
AC_INIT([rtems-c-src-lib-libbsp-m68k-mcf52235],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
|
||||||
|
AC_CONFIG_SRCDIR([bsp_specs])
|
||||||
|
RTEMS_TOP(../../../../../..)
|
||||||
|
|
||||||
|
RTEMS_CANONICAL_TARGET_CPU
|
||||||
|
AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.10])
|
||||||
|
RTEMS_BSP_CONFIGURE
|
||||||
|
|
||||||
|
RTEMS_PROG_CC_FOR_TARGET
|
||||||
|
RTEMS_CANONICALIZE_TOOLS
|
||||||
|
RTEMS_PROG_CCAS
|
||||||
|
|
||||||
|
RTEMS_BSP_BOOTCARD_HANDLES_RAM_ALLOCATION
|
||||||
|
|
||||||
|
RTEMS_CHECK_NETWORKING
|
||||||
|
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
|
||||||
|
|
||||||
|
# Explicitly list all Makefiles here
|
||||||
|
AC_CONFIG_FILES([Makefile])
|
||||||
|
AC_OUTPUT
|
||||||
690
c/src/lib/libbsp/m68k/mcf5329/console/console.c
Normal file
690
c/src/lib/libbsp/m68k/mcf5329/console/console.c
Normal file
@@ -0,0 +1,690 @@
|
|||||||
|
/*
|
||||||
|
* Multi UART console serial I/O.
|
||||||
|
*
|
||||||
|
* TO DO: Add DMA input/output
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
#include <rtems/termiostypes.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <rtems/mw_uid.h>
|
||||||
|
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
|
#define UART_INTC0_IRQ_VECTOR(x) (64+26+(x))
|
||||||
|
|
||||||
|
#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \
|
||||||
|
MCF_UART_USR_FE | \
|
||||||
|
MCF_UART_USR_PE | \
|
||||||
|
MCF_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 ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0)
|
||||||
|
continue;
|
||||||
|
MCF_UART_UTB(CONSOLE_PORT) = c;
|
||||||
|
while ((MCF_UART_USR(CONSOLE_PORT) & MCF_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];
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
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;
|
||||||
|
uint32_t clock_speed;
|
||||||
|
uint8_t umr1 = 0;
|
||||||
|
uint8_t umr2 = 0;
|
||||||
|
struct IntUartInfoStruct *info = &IntUartInfo[minor];
|
||||||
|
int level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
|
||||||
|
/* disable interrupts, clear RTS line, and disable the UARTS */
|
||||||
|
MCF_UART_UIMR(minor) = 0;
|
||||||
|
MCF_UART_UOP0(minor) = 1;
|
||||||
|
MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_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 = bsp_get_BUS_clock_speed();
|
||||||
|
/* determine the baud divisor value */
|
||||||
|
divisor = ((clock_speed) / (32 * baud));
|
||||||
|
if (divisor < 2)
|
||||||
|
divisor = 2;
|
||||||
|
|
||||||
|
/* check to see if doing hardware flow control */
|
||||||
|
if (hwflow) {
|
||||||
|
/* set hardware flow options */
|
||||||
|
umr1 |= MCF_UART_UMR_RXRTS;
|
||||||
|
umr2 |= MCF_UART_UMR_TXCTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine the new umr values */
|
||||||
|
umr1 |= (parity | databits);
|
||||||
|
umr2 |= (stopbits);
|
||||||
|
|
||||||
|
/* reset the uart */
|
||||||
|
MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR;
|
||||||
|
MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX;
|
||||||
|
MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX;
|
||||||
|
|
||||||
|
/* reset the uart mode register and update values */
|
||||||
|
MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR;
|
||||||
|
MCF_UART_UMR(minor) = umr1;
|
||||||
|
MCF_UART_UMR(minor) = umr2;
|
||||||
|
|
||||||
|
/* set the baud rate values */
|
||||||
|
MCF_UART_UCSR(minor) =
|
||||||
|
(MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK);
|
||||||
|
MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
|
||||||
|
MCF_UART_UBG2(minor) = (divisor & 0x00ff);
|
||||||
|
|
||||||
|
/* enable the uart */
|
||||||
|
MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
|
||||||
|
|
||||||
|
/* check to see if interrupts need to be enabled */
|
||||||
|
if (info->iomode != TERMIOS_POLLED) {
|
||||||
|
/* enable rx interrupts */
|
||||||
|
info->uimr |= MCF_UART_UIMR_RXRDY_FU;
|
||||||
|
MCF_UART_UIMR(minor) = info->uimr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check to see if doing hardware flow control */
|
||||||
|
if (hwflow) {
|
||||||
|
/* assert the RTS line */
|
||||||
|
MCF_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) MCF_UART_UMR_BC_8;
|
||||||
|
int parity = (int) MCF_UART_UMR_PM_NONE;
|
||||||
|
int stopbits = (int) MCF_UART_UMR_SB_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 = termios_baud_to_number(t->c_cflag & CBAUD);
|
||||||
|
|
||||||
|
/* determine data bits */
|
||||||
|
switch (t->c_cflag & CSIZE) {
|
||||||
|
case CS5:
|
||||||
|
databits = (int) MCF_UART_UMR_BC_5;
|
||||||
|
break;
|
||||||
|
case CS6:
|
||||||
|
databits = (int) MCF_UART_UMR_BC_6;
|
||||||
|
break;
|
||||||
|
case CS7:
|
||||||
|
databits = (int) MCF_UART_UMR_BC_7;
|
||||||
|
break;
|
||||||
|
case CS8:
|
||||||
|
databits = (int) MCF_UART_UMR_BC_8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine if parity is enabled */
|
||||||
|
if (t->c_cflag & PARENB) {
|
||||||
|
if (t->c_cflag & PARODD) {
|
||||||
|
/* odd parity */
|
||||||
|
parity = (int) MCF_UART_UMR_PM_ODD;
|
||||||
|
} else {
|
||||||
|
/* even parity */
|
||||||
|
parity = (int) MCF_UART_UMR_PM_EVEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine stop bits */
|
||||||
|
if (t->c_cflag & CSTOPB) {
|
||||||
|
/* two stop bits */
|
||||||
|
stopbits = (int) MCF_UART_UMR_SB_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 (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) {
|
||||||
|
/* read data and put into the receive buffer */
|
||||||
|
while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) {
|
||||||
|
|
||||||
|
if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) {
|
||||||
|
/* clear the error */
|
||||||
|
MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR;
|
||||||
|
}
|
||||||
|
/* put data in rx buffer and check for errors */
|
||||||
|
info->rx_buffer[info->rx_in] = MCF_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 & MCF_UART_UIMR_TXRDY) &&
|
||||||
|
(MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) {
|
||||||
|
|
||||||
|
/* disable tx interrupts */
|
||||||
|
info->uimr &= ~MCF_UART_UIMR_TXRDY;
|
||||||
|
MCF_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 */
|
||||||
|
|
||||||
|
MCF_UART_UACR(chan) = 0;
|
||||||
|
MCF_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:
|
||||||
|
MCF_INTC0_ICR26 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL);
|
||||||
|
MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK26);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
MCF_INTC0_ICR27 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL);
|
||||||
|
MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK27);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
MCF_INTC0_ICR28 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL);
|
||||||
|
MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK28);
|
||||||
|
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 */
|
||||||
|
MCF_UART_UTB(minor) = *buf;
|
||||||
|
|
||||||
|
/* enable tx interrupt */
|
||||||
|
IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY;
|
||||||
|
MCF_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 */
|
||||||
|
MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
|
||||||
|
|
||||||
|
/* check to see if interrupts need to be enabled */
|
||||||
|
if (info->iomode != TERMIOS_POLLED) {
|
||||||
|
/* enable rx interrupts */
|
||||||
|
info->uimr |= MCF_UART_UIMR_RXRDY_FU;
|
||||||
|
MCF_UART_UIMR(minor) = info->uimr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check to see if doing hardware flow control */
|
||||||
|
if (info->hwflow) {
|
||||||
|
/* assert the RTS line */
|
||||||
|
MCF_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 */
|
||||||
|
MCF_UART_UIMR(minor) = 0;
|
||||||
|
MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_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 ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (MCF_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 ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0)
|
||||||
|
continue;
|
||||||
|
/* transmit data byte */
|
||||||
|
MCF_UART_UTB(minor) = *buf++;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == RTEMS_SUCCESSFUL) {
|
||||||
|
/*
|
||||||
|
* Reset the default baudrate.
|
||||||
|
*/
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
if (tcgetattr(STDIN_FILENO, &term) >= 0) {
|
||||||
|
term.c_cflag &= ~(CBAUD | CSIZE);
|
||||||
|
term.c_cflag |= CS8 | B19200;
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
104
c/src/lib/libbsp/m68k/mcf5329/gdb-init
Normal file
104
c/src/lib/libbsp/m68k/mcf5329/gdb-init
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#target remote | m68k-bdm-gdbserver pipe /dev/bdmcf0 -v -d
|
||||||
|
target remote | m68k-bdm-gdbserver pipe /dev/bdmcf0
|
||||||
|
|
||||||
|
#monitor set remote-debug 1
|
||||||
|
#monitor set debug 1
|
||||||
|
monitor bdm-reset
|
||||||
|
|
||||||
|
#
|
||||||
|
# Show the exception stack frame.
|
||||||
|
#
|
||||||
|
define show-exception-sframe
|
||||||
|
set $frsr = *(unsigned short *)((unsigned long)$sp + 2)
|
||||||
|
set $frpc = *(unsigned long *)((unsigned long)$sp + 4)
|
||||||
|
set $frfvo = *(unsigned short *)((unsigned long)$sp + 0)
|
||||||
|
set $frcode = $frfvo >> 12
|
||||||
|
set $frvect = ($frfvo & 0xFFF) >> 2
|
||||||
|
set $frstatus = ((($frfvo >> 10) & 3) << 2) | ($frfvo & 3)
|
||||||
|
printf "EXCEPTION -- SR:0x%X PC:0x%X FRAME:0x%x VECTOR:%d STATUS:%d\n", $frsr, $frpc, $frcode, $frvect, $frstatus
|
||||||
|
if $frstatus == 4
|
||||||
|
printf " Fault Type: Error on instruction fetch"
|
||||||
|
end
|
||||||
|
if $frstatus == 8
|
||||||
|
printf " Fault Type: Error on operand write"
|
||||||
|
end
|
||||||
|
if $frstatus == 12
|
||||||
|
printf " Fault Type: Error on operand read"
|
||||||
|
end
|
||||||
|
if $frstatus == 9
|
||||||
|
printf " Fault Type: Attempted write to write-protected space"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# I have to do this as there seems to be a problem with me setting up the
|
||||||
|
# chip selects. As far as I can tell, gdb is probing whats at the program
|
||||||
|
# counter. It issues a 2 byte read (smallest instruction) followed by a
|
||||||
|
# 4 byte read (depending on the result of the 2 byte read). gdb issues these
|
||||||
|
# reads after each and every write that the .gdbinit script issues. This means
|
||||||
|
# that as I'm initializing the chip selects the gdb reads can happen in an
|
||||||
|
# invalid memory address and this causes a target bus error. For now I'm just
|
||||||
|
# setting pc to 0, which seems to stop gdb from probing around to read
|
||||||
|
# assembler. This lets me setup chip selects without error.
|
||||||
|
|
||||||
|
set $pc = 0x00000000
|
||||||
|
|
||||||
|
# Turn on RAMBAR1 at address 80000000
|
||||||
|
monitor bdm-ctl-set 0x0C05 0x80000221
|
||||||
|
|
||||||
|
# Set VBR to the beginning of what will be SDRAM
|
||||||
|
# VBR is an absolute CPU register
|
||||||
|
monitor bdm-ctl-set 0x0801 0x40000000
|
||||||
|
|
||||||
|
# Disable watchdog timer
|
||||||
|
set *((short*) 0xFC098000) = 0x0000
|
||||||
|
|
||||||
|
#Init CS0
|
||||||
|
set *((long*) 0xFC008000) = 0x00000000
|
||||||
|
set *((long*) 0xFC008008) = 0x00001FA0
|
||||||
|
set *((long*) 0xFC008004) = 0x001F0001
|
||||||
|
|
||||||
|
# SDRAM Initialization
|
||||||
|
|
||||||
|
monitor delay-ms 100
|
||||||
|
|
||||||
|
# SDCS0
|
||||||
|
set *((long*) 0xFC0B8110) = 0x40000018
|
||||||
|
# SDCFG1
|
||||||
|
set *((long*) 0xFC0B8008) = 0x53722730
|
||||||
|
# SDCFG2
|
||||||
|
set *((long*) 0xFC0B800C) = 0x56670000
|
||||||
|
|
||||||
|
# Issue PALL
|
||||||
|
# SDCR
|
||||||
|
set *((long*) 0xFC0B8004) = 0xE1092002
|
||||||
|
|
||||||
|
# Issue LEMR
|
||||||
|
# SDMR
|
||||||
|
set *((long*) 0xFC0B8000) = 0x40010000
|
||||||
|
|
||||||
|
# Write mode register
|
||||||
|
# SDMR
|
||||||
|
set *((long*) 0xFC0B8000) = 0x058D0000
|
||||||
|
|
||||||
|
# Wait a bit
|
||||||
|
monitor delay-ms 600
|
||||||
|
|
||||||
|
# Issue PALL
|
||||||
|
# SDCR
|
||||||
|
set *((long*) 0xFC0B8004) = 0xE1092002
|
||||||
|
|
||||||
|
# Perform two refresh cycles
|
||||||
|
# SDCR
|
||||||
|
set *((long*) 0xFC0B8004) = 0xE1092004
|
||||||
|
# SDCR
|
||||||
|
set *((long*) 0xFC0B8004) = 0xE1092004
|
||||||
|
|
||||||
|
# SDMR
|
||||||
|
set *((long*) 0xFC0B8000) = 0x018D0000
|
||||||
|
# SDCR
|
||||||
|
set *((long*) 0xFC0B8004) = 0x71092C00
|
||||||
|
|
||||||
|
# Wait a bit
|
||||||
|
monitor delay-ms 100
|
||||||
|
|
||||||
|
load
|
||||||
88
c/src/lib/libbsp/m68k/mcf5329/include/bsp.h
Normal file
88
c/src/lib/libbsp/m68k/mcf5329/include/bsp.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* mcf52235 BSP header file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BSP_H
|
||||||
|
#define _BSP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <bspopts.h>
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/iosupp.h>
|
||||||
|
#include <rtems/console.h>
|
||||||
|
#include <rtems/clockdrv.h>
|
||||||
|
#include <rtems/iosupp.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/** Hardware data structure headers **/
|
||||||
|
#include <mcf532x/mcf532x.h>
|
||||||
|
|
||||||
|
typedef volatile unsigned char vuint8;
|
||||||
|
typedef volatile unsigned short vuint16;
|
||||||
|
typedef volatile unsigned long vuint32;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/** 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 "fec0"
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* externals */
|
||||||
|
|
||||||
|
/* constants */
|
||||||
|
|
||||||
|
/* miscellaneous stuff assumed to exist */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device Driver Table Entries
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Use the standard Console driver entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Use the standard Clock driver entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* functions */
|
||||||
|
|
||||||
|
uint32_t bsp_get_CPU_clock_speed(void);
|
||||||
|
uint32_t bsp_get_BUS_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 PIT3_IRQ_LEVEL 4
|
||||||
|
|
||||||
|
#define UART0_IRQ_LEVEL 3
|
||||||
|
#define UART1_IRQ_LEVEL 3
|
||||||
|
#define UART2_IRQ_LEVEL 3
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
24
c/src/lib/libbsp/m68k/mcf5329/include/bspopts.h.in
Normal file
24
c/src/lib/libbsp/m68k/mcf5329/include/bspopts.h.in
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* include/bspopts.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* BSP uses shared logic in bootcard.c */
|
||||||
|
#undef BSP_BOOTCARD_HANDLES_RAM_ALLOCATION
|
||||||
|
|
||||||
|
/* If defined, then PSIM will put a non-zero pattern into the RTEMS Workspace
|
||||||
|
and C program heap. This should assist in finding code that assumes memory
|
||||||
|
starts set to zero. */
|
||||||
|
#undef BSP_DIRTY_MEMORY
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
105
c/src/lib/libbsp/m68k/mcf5329/include/coverhd.h
Normal file
105
c/src/lib/libbsp/m68k/mcf5329/include/coverhd.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/* 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).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __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
|
||||||
29
c/src/lib/libbsp/m68k/mcf5329/include/tm27.h
Normal file
29
c/src/lib/libbsp/m68k/mcf5329/include/tm27.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTEMS_TMTEST27
|
||||||
|
#error "This is an RTEMS internal file you must not include directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __tm27_h
|
||||||
|
#define __tm27_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stuff for Time Test 27
|
||||||
|
* Don't bother with hardware -- just use a software-interrupt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MUST_WAIT_FOR_INTERRUPT 0
|
||||||
|
|
||||||
|
#define Install_tm27_vector( handler ) set_vector( (handler), 35, 1 )
|
||||||
|
|
||||||
|
#define Cause_tm27_intr() asm volatile ("trap #3");
|
||||||
|
|
||||||
|
#define Clear_tm27_intr() /* empty */
|
||||||
|
|
||||||
|
#define Lower_tm27_intr() /* empty */
|
||||||
|
|
||||||
|
#endif
|
||||||
857
c/src/lib/libbsp/m68k/mcf5329/network/network.c
Normal file
857
c/src/lib/libbsp/m68k/mcf5329/network/network.c
Normal file
@@ -0,0 +1,857 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* RTEMS/TCPIP driver for MCF5329 Fast Ethernet Controller
|
||||||
|
*
|
||||||
|
* TO DO: Check network stack code -- force longword alignment of all tx mbufs?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/error.h>
|
||||||
|
#include <rtems/rtems_bsdnet.h>
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/mbuf.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of interfaces supported by this driver
|
||||||
|
*/
|
||||||
|
#define NIFACES 1
|
||||||
|
|
||||||
|
#define FEC_INTC0_TX_VECTOR (64+36)
|
||||||
|
#define FEC_INTC0_RX_VECTOR (64+40)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 mcf5329BufferDescriptor_
|
||||||
|
{
|
||||||
|
volatile uint16_t status;
|
||||||
|
uint16_t length;
|
||||||
|
volatile void *buffer;
|
||||||
|
} mcf5329BufferDescriptor_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per-device data
|
||||||
|
*/
|
||||||
|
struct mcf5329_enet_struct
|
||||||
|
{
|
||||||
|
struct arpcom arpcom;
|
||||||
|
struct mbuf **rxMbuf;
|
||||||
|
struct mbuf **txMbuf;
|
||||||
|
int acceptBroadcast;
|
||||||
|
int rxBdCount;
|
||||||
|
int txBdCount;
|
||||||
|
int txBdHead;
|
||||||
|
int txBdTail;
|
||||||
|
int txBdActiveCount;
|
||||||
|
mcf5329BufferDescriptor_t *rxBdBase;
|
||||||
|
mcf5329BufferDescriptor_t *txBdBase;
|
||||||
|
rtems_id rxDaemonTid;
|
||||||
|
rtems_id txDaemonTid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Statistics
|
||||||
|
*/
|
||||||
|
unsigned long rxInterrupts;
|
||||||
|
unsigned long txInterrupts;
|
||||||
|
unsigned long txRawWait;
|
||||||
|
unsigned long txRealign;
|
||||||
|
};
|
||||||
|
static struct mcf5329_enet_struct enet_driver[NIFACES];
|
||||||
|
|
||||||
|
static rtems_isr mcf5329_fec_rx_interrupt_handler(rtems_vector_number v)
|
||||||
|
{
|
||||||
|
MCF_FEC_EIR = MCF_FEC_EIR_RXF;
|
||||||
|
MCF_FEC_EIMR &= ~MCF_FEC_EIMR_RXF;
|
||||||
|
enet_driver[0].rxInterrupts++;
|
||||||
|
rtems_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtems_isr mcf5329_fec_tx_interrupt_handler(rtems_vector_number v)
|
||||||
|
{
|
||||||
|
MCF_FEC_EIR = MCF_FEC_EIR_TXF;
|
||||||
|
MCF_FEC_EIMR &= ~MCF_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 mcf5329BufferDescriptor_t *mcf5329_bd_allocate(unsigned int count)
|
||||||
|
{
|
||||||
|
extern char _CoreSRamBase[];
|
||||||
|
static mcf5329BufferDescriptor_t *bdp =
|
||||||
|
(mcf5329BufferDescriptor_t *) _CoreSRamBase;
|
||||||
|
mcf5329BufferDescriptor_t *p = bdp;
|
||||||
|
|
||||||
|
bdp += count;
|
||||||
|
if ((int) bdp & 0xF)
|
||||||
|
bdp =
|
||||||
|
(mcf5329BufferDescriptor_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)
|
||||||
|
{
|
||||||
|
MCF_FEC_MMFR = (0x1 << 30) |
|
||||||
|
(0x2 << 28) | (phyNumber << 23) | (regNumber << 18) | (0x2 << 16);
|
||||||
|
while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) ;
|
||||||
|
MCF_FEC_EIR = MCF_FEC_EIR_MII;
|
||||||
|
return MCF_FEC_MMFR & 0xFFFF;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write MII register
|
||||||
|
* Busy-waits, but transfer time should be short!
|
||||||
|
*/
|
||||||
|
static void setMII(int phyNumber, int regNumber, int value)
|
||||||
|
{
|
||||||
|
MCF_FEC_MMFR = (0x1 << 30) |
|
||||||
|
(0x1 << 28) |
|
||||||
|
(phyNumber << 23) | (regNumber << 18) | (0x2 << 16) | (value & 0xFFFF);
|
||||||
|
while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) ;
|
||||||
|
MCF_FEC_EIR = MCF_FEC_EIR_MII;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcf5329_fec_initialize_hardware(struct mcf5329_enet_struct *sc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const unsigned char *hwaddr = 0;
|
||||||
|
rtems_status_code status;
|
||||||
|
rtems_isr_entry old_handler;
|
||||||
|
uint32_t clock_speed = bsp_get_BUS_clock_speed();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Issue reset to FEC
|
||||||
|
*/
|
||||||
|
MCF_FEC_ECR = MCF_FEC_ECR_RESET;
|
||||||
|
rtems_task_wake_after(1);
|
||||||
|
MCF_FEC_ECR = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration of I/O ports is done outside of this function
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
imm->gpio.pbcnt |= MCF_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set our physical address
|
||||||
|
*/
|
||||||
|
hwaddr = sc->arpcom.ac_enaddr;
|
||||||
|
MCF_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
|
||||||
|
(hwaddr[2] << 8) | (hwaddr[3] << 0);
|
||||||
|
MCF_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the hash table
|
||||||
|
*/
|
||||||
|
MCF_FEC_GAUR = 0;
|
||||||
|
MCF_FEC_GALR = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up receive buffer size
|
||||||
|
*/
|
||||||
|
MCF_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 = mcf5329_bd_allocate(sc->rxBdCount);
|
||||||
|
sc->txBdBase = mcf5329_bd_allocate(sc->txBdCount);
|
||||||
|
MCF_FEC_ERDSR = (int) sc->rxBdBase;
|
||||||
|
MCF_FEC_ETDSR = (int) sc->txBdBase;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up Receive Control Register:
|
||||||
|
* Not promiscuous
|
||||||
|
* MII mode
|
||||||
|
* Full duplex
|
||||||
|
* No loopback
|
||||||
|
*/
|
||||||
|
MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL(MAX_MTU_SIZE) | MCF_FEC_RCR_MII_MODE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up Transmit Control Register:
|
||||||
|
* Full duplex
|
||||||
|
* No heartbeat
|
||||||
|
*/
|
||||||
|
MCF_FEC_TCR = MCF_FEC_TCR_FDEN;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize statistic counters
|
||||||
|
*/
|
||||||
|
MCF_FEC_MIBC = MCF_FEC_MIBC_MIB_DISABLE;
|
||||||
|
{
|
||||||
|
vuint32 *vuip = &MCF_FEC_RMON_T_DROP;
|
||||||
|
|
||||||
|
while (vuip <= &MCF_FEC_IEEE_R_OCTETS_OK)
|
||||||
|
*vuip++ = 0;
|
||||||
|
}
|
||||||
|
MCF_FEC_MIBC = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set MII speed to <= 2.5 MHz
|
||||||
|
*/
|
||||||
|
i = (clock_speed + 5000000 - 1) / 5000000;
|
||||||
|
MCF_FEC_MSCR = MCF_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(mcf5329_fec_tx_interrupt_handler,
|
||||||
|
FEC_INTC0_TX_VECTOR, &old_handler);
|
||||||
|
if (status != RTEMS_SUCCESSFUL)
|
||||||
|
rtems_panic("Can't attach MCF FEC TX interrupt handler: %s\n",
|
||||||
|
rtems_status_text(status));
|
||||||
|
status =
|
||||||
|
rtems_interrupt_catch(mcf5329_fec_rx_interrupt_handler,
|
||||||
|
FEC_INTC0_RX_VECTOR, &old_handler);
|
||||||
|
if (status != RTEMS_SUCCESSFUL)
|
||||||
|
rtems_panic("Can't attach MCF FEC RX interrupt handler: %s\n",
|
||||||
|
rtems_status_text(status));
|
||||||
|
MCF_INTC0_ICR36 = MCF_INTC_ICR_IL(FEC_IRQ_LEVEL);
|
||||||
|
MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36);
|
||||||
|
MCF_INTC0_ICR40 = MCF_INTC_ICR_IL(FEC_IRQ_LEVEL);
|
||||||
|
MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK40);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the MAC address from the hardware.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
fec_get_mac_address(volatile struct mcf5329_enet_struct *sc,
|
||||||
|
unsigned char *hwaddr)
|
||||||
|
{
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
addr = MCF_FEC_PALR;
|
||||||
|
|
||||||
|
hwaddr[0] = (addr >> 24) & 0xff;
|
||||||
|
hwaddr[1] = (addr >> 16) & 0xff;
|
||||||
|
hwaddr[2] = (addr >> 8) & 0xff;
|
||||||
|
hwaddr[3] = (addr >> 0) & 0xff;
|
||||||
|
|
||||||
|
addr = MCF_FEC_PAUR;
|
||||||
|
|
||||||
|
hwaddr[4] = (addr >> 24) & 0xff;
|
||||||
|
hwaddr[5] = (addr >> 16) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Soak up buffer descriptors that have been sent.
|
||||||
|
*/
|
||||||
|
static void fec_retire_tx_bd(volatile struct mcf5329_enet_struct *sc)
|
||||||
|
{
|
||||||
|
struct mbuf *m, *n;
|
||||||
|
|
||||||
|
while ((sc->txBdActiveCount != 0)
|
||||||
|
&& ((sc->txBdBase[sc->txBdTail].status & MCF_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 mcf5329_enet_struct *sc =
|
||||||
|
(volatile struct mcf5329_enet_struct *) arg;
|
||||||
|
struct ifnet *ifp = (struct ifnet *) &sc->arpcom.ac_if;
|
||||||
|
struct mbuf *m;
|
||||||
|
volatile uint16_t status;
|
||||||
|
volatile mcf5329BufferDescriptor_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 = MCF_FEC_RxBD_E;
|
||||||
|
if (++rxBdIndex == sc->rxBdCount) {
|
||||||
|
rxBd->status |= MCF_FEC_RxBD_W;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input packet handling loop
|
||||||
|
*/
|
||||||
|
/* Indicate we have some ready buffers available */
|
||||||
|
MCF_FEC_RDAR = MCF_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) & MCF_FEC_RxBD_E) {
|
||||||
|
/*
|
||||||
|
* Clear old events.
|
||||||
|
*/
|
||||||
|
MCF_FEC_EIR = MCF_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) & MCF_FEC_RxBD_E) {
|
||||||
|
rtems_event_set events;
|
||||||
|
int level;
|
||||||
|
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
|
MCF_FEC_EIMR |= MCF_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 & MCF_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 & MCF_FEC_RxBD_W) | MCF_FEC_RxBD_E;
|
||||||
|
MCF_FEC_RDAR = MCF_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 mcf5329_enet_struct *sc = ifp->if_softc;
|
||||||
|
volatile mcf5329BufferDescriptor_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.
|
||||||
|
*/
|
||||||
|
MCF_FEC_EIR = MCF_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);
|
||||||
|
MCF_FEC_EIMR |= MCF_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 ? MCF_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 |= MCF_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 | MCF_FEC_TxBD_R
|
||||||
|
| MCF_FEC_TxBD_L | MCF_FEC_TxBD_TC;
|
||||||
|
if (nAdded > 1)
|
||||||
|
firstTxBd->status |= MCF_FEC_TxBD_R;
|
||||||
|
MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
|
||||||
|
sc->txBdActiveCount += nAdded;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
txBd->status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fec_txDaemon(void *arg)
|
||||||
|
{
|
||||||
|
struct mcf5329_enet_struct *sc = (struct mcf5329_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 mcf5329_enet_start(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
struct mcf5329_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 mcf5329_enet_struct *sc = arg;
|
||||||
|
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
|
if (sc->txDaemonTid == 0) {
|
||||||
|
/*
|
||||||
|
* Set up hardware
|
||||||
|
*/
|
||||||
|
mcf5329_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)
|
||||||
|
MCF_FEC_RCR |= MCF_FEC_RCR_PROM;
|
||||||
|
else
|
||||||
|
MCF_FEC_RCR &= ~MCF_FEC_RCR_PROM;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tell the world that we're running.
|
||||||
|
*/
|
||||||
|
ifp->if_flags |= IFF_RUNNING;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable receiver and transmitter
|
||||||
|
*/
|
||||||
|
MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fec_stop(struct mcf5329_enet_struct *sc)
|
||||||
|
{
|
||||||
|
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
|
ifp->if_flags &= ~IFF_RUNNING;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shut down receiver and transmitter
|
||||||
|
*/
|
||||||
|
MCF_FEC_ECR = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show interface statistics
|
||||||
|
*/
|
||||||
|
static void enet_stats(struct mcf5329_enet_struct *sc)
|
||||||
|
{
|
||||||
|
printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
|
||||||
|
printf("Rx Packet Count:%-10lu", MCF_FEC_RMON_R_PACKETS);
|
||||||
|
printf(" Rx Broadcast:%-10lu\n", MCF_FEC_RMON_R_BC_PKT);
|
||||||
|
printf(" Rx Multicast:%-10lu", MCF_FEC_RMON_R_MC_PKT);
|
||||||
|
printf("CRC/Align error:%-10lu", MCF_FEC_RMON_R_CRC_ALIGN);
|
||||||
|
printf(" Rx Undersize:%-10lu\n", MCF_FEC_RMON_R_UNDERSIZE);
|
||||||
|
printf(" Rx Oversize:%-10lu", MCF_FEC_RMON_R_OVERSIZE);
|
||||||
|
printf(" Rx Fragment:%-10lu", MCF_FEC_RMON_R_FRAG);
|
||||||
|
printf(" Rx Jabber:%-10lu\n", MCF_FEC_RMON_R_JAB);
|
||||||
|
printf(" Rx 64:%-10lu", MCF_FEC_RMON_R_P64);
|
||||||
|
printf(" Rx 65-127:%-10lu", MCF_FEC_RMON_R_P65TO127);
|
||||||
|
printf(" Rx 128-255:%-10lu\n", MCF_FEC_RMON_R_P128TO255);
|
||||||
|
printf(" Rx 256-511:%-10lu", MCF_FEC_RMON_R_P256TO511);
|
||||||
|
printf(" Rx 511-1023:%-10lu", MCF_FEC_RMON_R_512TO1023);
|
||||||
|
printf(" Rx 1024-2047:%-10lu\n", MCF_FEC_RMON_R_1024TO2047);
|
||||||
|
printf(" Rx >=2048:%-10lu", MCF_FEC_RMON_R_P_GTE2048);
|
||||||
|
printf(" Rx Octets:%-10lu", MCF_FEC_RMON_R_OCTETS);
|
||||||
|
printf(" Rx Dropped:%-10lu\n", MCF_FEC_IEEE_R_DROP);
|
||||||
|
printf(" Rx frame OK:%-10lu", MCF_FEC_IEEE_R_FRAME_OK);
|
||||||
|
printf(" Rx CRC error:%-10lu", MCF_FEC_IEEE_R_CRC);
|
||||||
|
printf(" Rx Align error:%-10lu\n", MCF_FEC_IEEE_R_ALIGN);
|
||||||
|
printf(" FIFO Overflow:%-10lu", MCF_FEC_IEEE_R_MACERR);
|
||||||
|
printf("Rx Pause Frames:%-10lu", MCF_FEC_IEEE_R_FDXFC);
|
||||||
|
printf(" Rx Octets OK:%-10lu\n", MCF_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", MCF_FEC_RMON_T_DROP);
|
||||||
|
printf("Tx Packet Count:%-10lu", MCF_FEC_RMON_T_PACKETS);
|
||||||
|
printf(" Tx Broadcast:%-10lu\n", MCF_FEC_RMON_T_BC_PKT);
|
||||||
|
printf(" Tx Multicast:%-10lu", MCF_FEC_RMON_T_MC_PKT);
|
||||||
|
printf("CRC/Align error:%-10lu", MCF_FEC_RMON_T_CRC_ALIGN);
|
||||||
|
printf(" Tx Undersize:%-10lu\n", MCF_FEC_RMON_T_UNDERSIZE);
|
||||||
|
printf(" Tx Oversize:%-10lu", MCF_FEC_RMON_T_OVERSIZE);
|
||||||
|
printf(" Tx Fragment:%-10lu", MCF_FEC_RMON_T_FRAG);
|
||||||
|
printf(" Tx Jabber:%-10lu\n", MCF_FEC_RMON_T_JAB);
|
||||||
|
printf(" Tx Collisions:%-10lu", MCF_FEC_RMON_T_COL);
|
||||||
|
printf(" Tx 64:%-10lu", MCF_FEC_RMON_T_P64);
|
||||||
|
printf(" Tx 65-127:%-10lu\n", MCF_FEC_RMON_T_P65TO127);
|
||||||
|
printf(" Tx 128-255:%-10lu", MCF_FEC_RMON_T_P128TO255);
|
||||||
|
printf(" Tx 256-511:%-10lu", MCF_FEC_RMON_T_P256TO511);
|
||||||
|
printf(" Tx 511-1023:%-10lu\n", MCF_FEC_RMON_T_P512TO1023);
|
||||||
|
printf(" Tx 1024-2047:%-10lu", MCF_FEC_RMON_T_P1024TO2047);
|
||||||
|
printf(" Tx >=2048:%-10lu", MCF_FEC_RMON_T_P_GTE2048);
|
||||||
|
printf(" Tx Octets:%-10lu\n", MCF_FEC_RMON_T_OCTETS);
|
||||||
|
printf(" Tx Dropped:%-10lu", MCF_FEC_IEEE_T_DROP);
|
||||||
|
printf(" Tx Frame OK:%-10lu", MCF_FEC_IEEE_T_FRAME_OK);
|
||||||
|
printf(" Tx 1 Collision:%-10lu\n", MCF_FEC_IEEE_T_1COL);
|
||||||
|
printf("Tx >1 Collision:%-10lu", MCF_FEC_IEEE_T_MCOL);
|
||||||
|
printf(" Tx Deferred:%-10lu", MCF_FEC_IEEE_T_DEF);
|
||||||
|
printf(" Late Collision:%-10lu\n", MCF_FEC_IEEE_T_LCOL);
|
||||||
|
printf(" Excessive Coll:%-10lu", MCF_FEC_IEEE_T_EXCOL);
|
||||||
|
printf(" FIFO Underrun:%-10lu", MCF_FEC_IEEE_T_MACERR);
|
||||||
|
printf(" Carrier Error:%-10lu\n", MCF_FEC_IEEE_T_CSERR);
|
||||||
|
printf(" Tx SQE Error:%-10lu", MCF_FEC_IEEE_T_SQE);
|
||||||
|
printf("Tx Pause Frames:%-10lu", MCF_FEC_IEEE_T_FDXFC);
|
||||||
|
printf(" Tx Octets OK:%-10lu\n", MCF_FEC_IEEE_T_OCTETS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fec_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
|
||||||
|
{
|
||||||
|
struct mcf5329_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 mcf5329_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("mcf5329: bad FEC unit number.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sc = &enet_driver[unitNumber];
|
||||||
|
ifp = &sc->arpcom.ac_if;
|
||||||
|
if (ifp->if_softc != NULL) {
|
||||||
|
printf("mcf5329: driver already in use.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process options
|
||||||
|
*/
|
||||||
|
if (config->hardware_address)
|
||||||
|
memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
|
||||||
|
else
|
||||||
|
fec_get_mac_address(sc, sc->arpcom.ac_enaddr);
|
||||||
|
|
||||||
|
hwaddr = config->hardware_address;
|
||||||
|
printf("%s%d: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
|
unitName, unitNumber,
|
||||||
|
hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
|
||||||
|
|
||||||
|
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 = mcf5329_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;
|
||||||
|
};
|
||||||
62
c/src/lib/libbsp/m68k/mcf5329/preinstall.am
Normal file
62
c/src/lib/libbsp/m68k/mcf5329/preinstall.am
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
## Automatically generated by ampolish3 - Do not edit
|
||||||
|
|
||||||
|
if AMPOLISH3
|
||||||
|
$(srcdir)/preinstall.am: Makefile.am
|
||||||
|
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
|
||||||
|
endif
|
||||||
|
|
||||||
|
PREINSTALL_DIRS =
|
||||||
|
DISTCLEANFILES += $(PREINSTALL_DIRS)
|
||||||
|
|
||||||
|
all-local: $(TMPINSTALL_FILES)
|
||||||
|
|
||||||
|
TMPINSTALL_FILES =
|
||||||
|
CLEANFILES = $(TMPINSTALL_FILES)
|
||||||
|
|
||||||
|
all-am: $(PREINSTALL_FILES)
|
||||||
|
|
||||||
|
PREINSTALL_FILES =
|
||||||
|
CLEANFILES += $(PREINSTALL_FILES)
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/$(dirstamp):
|
||||||
|
@$(MKDIR_P) $(PROJECT_LIB)
|
||||||
|
@: > $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/$(dirstamp):
|
||||||
|
@$(MKDIR_P) $(PROJECT_INCLUDE)
|
||||||
|
@: > $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(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
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/linkcmdsflash: startup/linkcmdsflash $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmdsflash
|
||||||
|
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmdsflash
|
||||||
|
|
||||||
382
c/src/lib/libbsp/m68k/mcf5329/start/start.S
Normal file
382
c/src/lib/libbsp/m68k/mcf5329/start/start.S
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
/*
|
||||||
|
* mcf52235 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).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
*
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems/asm.h>
|
||||||
|
|
||||||
|
.extern _StackInit
|
||||||
|
|
||||||
|
BEGIN_CODE
|
||||||
|
|
||||||
|
PUBLIC (_INTERRUPT_VECTOR)
|
||||||
|
SYM(_INTERRUPT_VECTOR):
|
||||||
|
|
||||||
|
.long _StackInit /* 00 Initial 'SSP' */
|
||||||
|
.long SYM(start) /* 01 Initial PC */
|
||||||
|
.long SYM(_uhoh) /* 02 Access Error */
|
||||||
|
.long SYM(_uhoh) /* 03 Address Error */
|
||||||
|
.long SYM(_uhoh) /* 04 Illegal Instruction */
|
||||||
|
.long SYM(_uhoh) /* 05 Divide by Zero */
|
||||||
|
.long SYM(_uhoh) /* 06 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 07 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 08 Privilege Violation */
|
||||||
|
.long SYM(_uhoh) /* 09 Trace */
|
||||||
|
.long SYM(_uhoh) /* 10 Unimplemented A-Line */
|
||||||
|
.long SYM(_uhoh) /* 11 Unimplemented F-Line */
|
||||||
|
.long SYM(_uhoh) /* 12 Debug Interrupt */
|
||||||
|
.long SYM(_uhoh) /* 13 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 14 Format Error */
|
||||||
|
.long SYM(_uhoh) /* 15 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 16 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 17 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 18 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 19 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 20 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 21 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 22 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 23 Reserved */
|
||||||
|
.long SYM(_spuriousInterrupt) /* 24 Spurious Interrupt */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* Reserved */
|
||||||
|
.long SYM(_uhoh) /* 32 TRAP #0 */
|
||||||
|
.long SYM(_uhoh) /* 33 TRAP #1 */
|
||||||
|
.long SYM(_uhoh) /* 34 TRAP #2 */
|
||||||
|
.long SYM(_uhoh) /* 35 TRAP #3 */
|
||||||
|
.long SYM(_uhoh) /* 36 TRAP #4 */
|
||||||
|
.long SYM(_uhoh) /* 37 TRAP #5 */
|
||||||
|
.long SYM(_uhoh) /* 38 TRAP #6 */
|
||||||
|
.long SYM(_uhoh) /* 39 TRAP #7 */
|
||||||
|
.long SYM(_uhoh) /* 40 TRAP #8 */
|
||||||
|
.long SYM(_uhoh) /* 41 TRAP #9 */
|
||||||
|
.long SYM(_uhoh) /* 42 TRAP #10 */
|
||||||
|
.long SYM(_uhoh) /* 43 TRAP #11 */
|
||||||
|
.long SYM(_uhoh) /* 44 TRAP #12 */
|
||||||
|
.long SYM(_uhoh) /* 45 TRAP #13 */
|
||||||
|
.long SYM(_uhoh) /* 46 TRAP #14 */
|
||||||
|
.long SYM(_uhoh) /* 47 TRAP #15 */
|
||||||
|
.long SYM(_uhoh) /* 48 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 49 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 50 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 51 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 52 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 53 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 54 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 55 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 56 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 57 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 58 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 59 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 60 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 61 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 62 Reserved */
|
||||||
|
.long SYM(_uhoh) /* 63 Reserved */
|
||||||
|
|
||||||
|
/* INTC0 */
|
||||||
|
|
||||||
|
.long SYM(_uhoh) /* 64*/
|
||||||
|
.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*/
|
||||||
|
|
||||||
|
/* INTC1 */
|
||||||
|
|
||||||
|
.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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Spurious Interrupt Handler
|
||||||
|
*/
|
||||||
|
.align 4
|
||||||
|
PUBLIC (_spuriousInterrupt)
|
||||||
|
SYM(_spuriousInterrupt):
|
||||||
|
addql #1, SYM(_M68kSpuriousInterruptCount)
|
||||||
|
rte
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write VBR Register
|
||||||
|
*/
|
||||||
|
.align 4
|
||||||
|
PUBLIC (_wr_vbr)
|
||||||
|
SYM(_wr_vbr):
|
||||||
|
move.l 4(sp), d0
|
||||||
|
movec d0, vbr
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Board startup
|
||||||
|
* Disable watchdog, interrupts
|
||||||
|
* Enable sram
|
||||||
|
*/
|
||||||
|
.align 4
|
||||||
|
PUBLIC (start)
|
||||||
|
SYM(start):
|
||||||
|
|
||||||
|
/* Mask off interupts */
|
||||||
|
move.w #0x2700,sr
|
||||||
|
|
||||||
|
/* Save off reset values of D0 and D1 */
|
||||||
|
move.l d0,d6
|
||||||
|
move.l d1,d7
|
||||||
|
|
||||||
|
/* Initialize RAMBAR1: locate SRAM and validate it */
|
||||||
|
move.l #_CoreSRamBase,d0
|
||||||
|
add.l #0x221,d0
|
||||||
|
movec d0,%rambar
|
||||||
|
|
||||||
|
/* Save off intial D0 and D1 to RAM */
|
||||||
|
move.l d6, SYM(_d0_reset)
|
||||||
|
move.l d7, SYM(_d1_reset)
|
||||||
|
|
||||||
|
/* Locate Stack Pointer */
|
||||||
|
move.l #_StackInit,sp
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remainder of the startup code is handled by C code
|
||||||
|
* This never returns
|
||||||
|
*/
|
||||||
|
jmp SYM(Init5329)
|
||||||
|
|
||||||
|
END_CODE
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_DATA_DCL
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
PUBLIC (_M68kSpuriousInterruptCount)
|
||||||
|
SYM (_M68kSpuriousInterruptCount):
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
PUBLIC (_d0_reset)
|
||||||
|
SYM (_d0_reset):
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
PUBLIC (_d1_reset)
|
||||||
|
SYM (_d1_reset):
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
END_DATA_DCL
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
33
c/src/lib/libbsp/m68k/mcf5329/startup/bspclean.c
Normal file
33
c/src/lib/libbsp/m68k/mcf5329/startup/bspclean.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
*
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
|
void bsp_cleanup(void)
|
||||||
|
{
|
||||||
|
printk("\nRTEMS exited!\n");
|
||||||
|
for (;;) {
|
||||||
|
asm volatile (" nop ");
|
||||||
|
asm volatile (" nop ");
|
||||||
|
}
|
||||||
|
}
|
||||||
97
c/src/lib/libbsp/m68k/mcf5329/startup/bspstart.c
Normal file
97
c/src/lib/libbsp/m68k/mcf5329/startup/bspstart.c
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
#include <rtems/libcsupport.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void _CPU_cache_disable_instruction(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void _CPU_cache_invalidate_entire_instruction(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void _CPU_cache_invalidate_1_instruction_line(const void *addr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _CPU_cache_enable_data(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void _CPU_cache_disable_data(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void _CPU_cache_invalidate_entire_data(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void _CPU_cache_invalidate_1_data_line(const void *addr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bsp_start
|
||||||
|
*
|
||||||
|
* This routine does the bulk of the system initialisation.
|
||||||
|
*/
|
||||||
|
void bsp_start(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t bsp_get_CPU_clock_speed(void)
|
||||||
|
{
|
||||||
|
return 240000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t bsp_get_BUS_clock_speed(void)
|
||||||
|
{
|
||||||
|
return 80000000;
|
||||||
|
}
|
||||||
435
c/src/lib/libbsp/m68k/mcf5329/startup/cfinit.c
Normal file
435
c/src/lib/libbsp/m68k/mcf5329/startup/cfinit.c
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* Initialisation Code for ColdFire MCF5329 Processor *
|
||||||
|
**********************************************************************
|
||||||
|
Generated by ColdFire Initialisation Utility 2.10.8
|
||||||
|
Mon Jun 16 10:41:41 2008
|
||||||
|
|
||||||
|
MicroAPL Ltd makes no warranties in respect of the suitability
|
||||||
|
of this code for any particular purpose, and accepts
|
||||||
|
no liability for any loss arising out of its use. The person or
|
||||||
|
persons making use of this file must make the final evaluation
|
||||||
|
as to its suitability and correctness for a particular application.
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* External reference frequency is 16.0000 MHz
|
||||||
|
Internal bus clock frequency = 80.00 MHz
|
||||||
|
Processor core frequency = 240.00 MHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
/* eDMA Transfer Control Descriptor definitions */
|
||||||
|
#define MCF_EDMA_TCD_W0(channel) (*(vuint32 *)(0xFC045000+((channel)*0x20))) /* Transfer Control Descriptor Word 0 */
|
||||||
|
#define MCF_EDMA_TCD_W1(channel) (*(vuint32 *)(0xFC045004+((channel)*0x20))) /* Transfer Control Descriptor Word 1 */
|
||||||
|
#define MCF_EDMA_TCD_W2(channel) (*(vuint32 *)(0xFC045008+((channel)*0x20))) /* Transfer Control Descriptor Word 2 */
|
||||||
|
#define MCF_EDMA_TCD_W3(channel) (*(vuint32 *)(0xFC04500C+((channel)*0x20))) /* Transfer Control Descriptor Word 3 */
|
||||||
|
#define MCF_EDMA_TCD_W4(channel) (*(vuint32 *)(0xFC045010+((channel)*0x20))) /* Transfer Control Descriptor Word 4 */
|
||||||
|
#define MCF_EDMA_TCD_W5(channel) (*(vuint32 *)(0xFC045014+((channel)*0x20))) /* Transfer Control Descriptor Word 5 */
|
||||||
|
#define MCF_EDMA_TCD_W6(channel) (*(vuint32 *)(0xFC045018+((channel)*0x20))) /* Transfer Control Descriptor Word 6 */
|
||||||
|
#define MCF_EDMA_TCD_W7(channel) (*(vuint32 *)(0xFC04501C+((channel)*0x20))) /* Transfer Control Descriptor Word 7 */
|
||||||
|
|
||||||
|
/* Function prototypes */
|
||||||
|
void init_main(void);
|
||||||
|
static void disable_interrupts(void);
|
||||||
|
static void disable_watchdog_timer(void);
|
||||||
|
static void disable_cache(void);
|
||||||
|
extern void init_clock_config(void) __attribute__ ((section(".ram_code")));
|
||||||
|
extern void init_chip_selects(void) __attribute__ ((section(".ram_code")));
|
||||||
|
static void init_real_time_clock(void);
|
||||||
|
static void init_watchdog_timers(void);
|
||||||
|
static void init_pin_assignments(void);
|
||||||
|
extern void init_sdram_controller(void)
|
||||||
|
__attribute__ ((section(".ram_code")));
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_main - Main entry point for initialisation code *
|
||||||
|
**********************************************************************/
|
||||||
|
void init_main(void)
|
||||||
|
{
|
||||||
|
/* Mask all interrupts */
|
||||||
|
init_clock_config();
|
||||||
|
|
||||||
|
/* Disable interrupts, watchdog timer, cache */
|
||||||
|
disable_interrupts();
|
||||||
|
disable_watchdog_timer();
|
||||||
|
disable_cache();
|
||||||
|
|
||||||
|
/* Initialise individual modules */
|
||||||
|
init_chip_selects();
|
||||||
|
init_real_time_clock();
|
||||||
|
init_watchdog_timers();
|
||||||
|
init_pin_assignments();
|
||||||
|
|
||||||
|
/* Initialise SDRAM controller (must be done after pin assignments) */
|
||||||
|
init_sdram_controller();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* disable_interrupts - Disable all interrupt sources *
|
||||||
|
**********************************************************************/
|
||||||
|
static void disable_interrupts(void)
|
||||||
|
{
|
||||||
|
vuint8 *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Set ICR001-ICR063 to 0x0 */
|
||||||
|
p = (vuint8 *) & MCF_INTC0_ICR1;
|
||||||
|
for (i = 1; i <= 63; i++)
|
||||||
|
*p++ = 0x0;
|
||||||
|
|
||||||
|
/* Set ICR100-ICR163 to 0x0 */
|
||||||
|
p = (vuint8 *) & MCF_INTC1_ICR0;
|
||||||
|
for (i = 100; i <= 163; i++)
|
||||||
|
*p++ = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* disable_watchdog_timer - Disable system watchdog timer *
|
||||||
|
**********************************************************************/
|
||||||
|
static void disable_watchdog_timer(void)
|
||||||
|
{
|
||||||
|
/* Disable Core Watchdog Timer */
|
||||||
|
MCF_SCM_CWCR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* disable_cache - Disable and invalidate cache *
|
||||||
|
**********************************************************************/
|
||||||
|
static void disable_cache(void)
|
||||||
|
{
|
||||||
|
asm("move.l #0x01000000,%d0");
|
||||||
|
asm("movec %d0,%CACR");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_clock_config - Clock Module *
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
void init_clock_config(void)
|
||||||
|
{
|
||||||
|
/* Clock module uses normal PLL mode with 16.0000 MHz external reference
|
||||||
|
Bus clock frequency = 80.00 MHz
|
||||||
|
Processor clock frequency = 3 x bus clock = 240.00 MHz
|
||||||
|
Dithering disabled
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Check to see if the SDRAM has already been initialized
|
||||||
|
by a run control tool. If it has, put SDRAM into self-refresh mode before
|
||||||
|
initializing the PLL
|
||||||
|
*/
|
||||||
|
if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
|
||||||
|
MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
|
||||||
|
|
||||||
|
/* Temporarily switch to LIMP mode
|
||||||
|
NOTE: Ensure that this code is not executing from SDRAM, since the
|
||||||
|
SDRAM Controller is disabled in LIMP mode
|
||||||
|
*/
|
||||||
|
MCF_CCM_CDR = (MCF_CCM_CDR & 0xf0ff) | MCF_CCM_CDR_LPDIV(0x2);
|
||||||
|
MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
|
||||||
|
|
||||||
|
/* Configure the PLL settings */
|
||||||
|
MCF_PLL_PODR = MCF_PLL_PODR_CPUDIV(0x2) | MCF_PLL_PODR_BUSDIV(0x6);
|
||||||
|
MCF_PLL_PFDR = MCF_PLL_PFDR_MFD(0x78);
|
||||||
|
MCF_PLL_PLLCR = 0;
|
||||||
|
MCF_PLL_PMDR = 0;
|
||||||
|
|
||||||
|
/* Enable PLL and wait for lock */
|
||||||
|
MCF_CCM_MISCCR &= ~MCF_CCM_MISCCR_LIMP;
|
||||||
|
while ((MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK) == 0) ;
|
||||||
|
|
||||||
|
/* From the Device Errata:
|
||||||
|
|
||||||
|
"After exiting LIMP mode, the value of 0x40000000 should be written
|
||||||
|
to address 0xFC0B8080 before attempting to initialize the SDRAMC
|
||||||
|
or exit the SDRAM from self-refresh mode."
|
||||||
|
*/
|
||||||
|
*(vuint32 *) 0xfc0b8080 = 0x40000000;
|
||||||
|
|
||||||
|
/* If we put the SDRAM into self-refresh mode earlier, restore mode now */
|
||||||
|
if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
|
||||||
|
MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_chip_selects - Chip Select Module (FlexBus) *
|
||||||
|
**********************************************************************/
|
||||||
|
void init_chip_selects(void)
|
||||||
|
{
|
||||||
|
/* Chip Select 0: 2 MB of Flash at base address $00000000
|
||||||
|
Port size = 16 bits
|
||||||
|
Assert chip select on first rising clock edge after address is asserted
|
||||||
|
Generate internal transfer acknowledge after 7 wait states
|
||||||
|
Address is held for 1 clock at end of read and write cycles
|
||||||
|
*/
|
||||||
|
MCF_FBCS0_CSCR = MCF_FBCS_CSCR_WS(0x7) |
|
||||||
|
(0x1 << 9) | MCF_FBCS_CSCR_AA | MCF_FBCS_CSCR_PS(0x2) | MCF_FBCS_CSCR_BEM;
|
||||||
|
MCF_FBCS0_CSMR = MCF_FBCS_CSMR_BAM(0x1f) | MCF_FBCS_CSMR_V;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_sdram_controller - SDRAM Controller *
|
||||||
|
**********************************************************************/
|
||||||
|
void init_sdram_controller(void)
|
||||||
|
{
|
||||||
|
/* Check to see if the SDRAM has already been initialized
|
||||||
|
by a run control tool and skip if so
|
||||||
|
*/
|
||||||
|
if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Ensure that there is a delay from processor reset of the time recommended in
|
||||||
|
the SDRAM data sheet (typically 100-200 microseconds) until the following
|
||||||
|
code so that the SDRAM is ready for commands...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* SDRAM controller configured for Double-data rate (DDR) SDRAM
|
||||||
|
Bus width = 16 bits
|
||||||
|
SDRAM specification:
|
||||||
|
SDRAM clock frequency = 80.00 MHz
|
||||||
|
CASL = 2.5
|
||||||
|
ACTV-to-read/write delay, tRCD = 20.0 nanoseconds
|
||||||
|
Write recovery time, tWR = 15.0 nanoseconds
|
||||||
|
Precharge comand to ACTV command, tRP = 20.0 nanoseconds
|
||||||
|
Auto refresh command period, tRFC = 75.0 nanoseconds
|
||||||
|
Average periodic refresh interval, tREFI = 7.8 microseconds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory block 0 enabled - 32 MBytes at address $40000000
|
||||||
|
Block consists of 1 device x 256 MBits (13 rows x 9 columns x 4 banks)
|
||||||
|
*/
|
||||||
|
MCF_SDRAMC_SDCS0 = MCF_SDRAMC_SDCS_BASE(0x400) | MCF_SDRAMC_SDCS_CSSZ(0x18);
|
||||||
|
|
||||||
|
/* Memory block 1 disabled */
|
||||||
|
MCF_SDRAMC_SDCS1 = 0;
|
||||||
|
|
||||||
|
/* Initialise SDCFG1 register with delay and timing values
|
||||||
|
SRD2RWP = 4, SWT2RWP = 3, RD_LAT = 7, ACT2RW = 2
|
||||||
|
PRE2ACT = 2, REF2ACT = 6, WT_LAT = 3
|
||||||
|
*/
|
||||||
|
MCF_SDRAMC_SDCFG1 = MCF_SDRAMC_SDCFG1_SRD2RW(0x4) |
|
||||||
|
MCF_SDRAMC_SDCFG1_SWT2RD(0x3) |
|
||||||
|
MCF_SDRAMC_SDCFG1_RDLAT(0x7) |
|
||||||
|
MCF_SDRAMC_SDCFG1_ACT2RW(0x2) |
|
||||||
|
MCF_SDRAMC_SDCFG1_PRE2ACT(0x2) |
|
||||||
|
MCF_SDRAMC_SDCFG1_REF2ACT(0x6) | MCF_SDRAMC_SDCFG1_WTLAT(0x3);
|
||||||
|
|
||||||
|
/* Initialise SDCFG2 register with delay and timing values
|
||||||
|
BRD2RP = 5, BWT2RWP = 6, BRD2W = 6, BL = 7
|
||||||
|
*/
|
||||||
|
MCF_SDRAMC_SDCFG2 = MCF_SDRAMC_SDCFG2_BRD2PRE(0x5) |
|
||||||
|
MCF_SDRAMC_SDCFG2_BWT2RW(0x6) |
|
||||||
|
MCF_SDRAMC_SDCFG2_BRD2WT(0x6) | MCF_SDRAMC_SDCFG2_BL(0x7);
|
||||||
|
|
||||||
|
/* Issue a Precharge All command */
|
||||||
|
MCF_SDRAMC_SDCR = MCF_SDRAMC_SDCR_MODE_EN |
|
||||||
|
MCF_SDRAMC_SDCR_CKE |
|
||||||
|
MCF_SDRAMC_SDCR_DDR |
|
||||||
|
MCF_SDRAMC_SDCR_MUX(0x1) |
|
||||||
|
MCF_SDRAMC_SDCR_RCNT(0x8) | MCF_SDRAMC_SDCR_PS_16 | MCF_SDRAMC_SDCR_IPALL;
|
||||||
|
|
||||||
|
/* Write Extended Mode Register */
|
||||||
|
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_BNKAD_LEMR | MCF_SDRAMC_SDMR_CMD;
|
||||||
|
|
||||||
|
/* Write Mode Register and Reset DLL */
|
||||||
|
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_BNKAD_LMR |
|
||||||
|
MCF_SDRAMC_SDMR_AD(0x163) | MCF_SDRAMC_SDMR_CMD;
|
||||||
|
|
||||||
|
/* Insert code here to pause for DLL lock time specified by memory... */
|
||||||
|
|
||||||
|
/* Issue a second Precharge All command */
|
||||||
|
MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
|
||||||
|
|
||||||
|
/* Refresh sequence...
|
||||||
|
(check the number of refreshes required by the SDRAM manufacturer)
|
||||||
|
*/
|
||||||
|
MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
|
||||||
|
MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
|
||||||
|
|
||||||
|
/* Write Mode Register and clear the Reset DLL bit */
|
||||||
|
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_BNKAD_LMR |
|
||||||
|
MCF_SDRAMC_SDMR_AD(0x63) | MCF_SDRAMC_SDMR_CMD;
|
||||||
|
|
||||||
|
/* Enable automatic refresh and lock SDMR */
|
||||||
|
MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
|
||||||
|
MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_REF |
|
||||||
|
MCF_SDRAMC_SDCR_DQS_OE(0x8) | MCF_SDRAMC_SDCR_DQS_OE(0x4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_real_time_clock - Real-Time Clock (RTC) *
|
||||||
|
**********************************************************************/
|
||||||
|
static void init_real_time_clock(void)
|
||||||
|
{
|
||||||
|
/* Disable the RTC */
|
||||||
|
MCF_RTC_CR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_watchdog_timers - Watchdog Timers *
|
||||||
|
**********************************************************************/
|
||||||
|
static void init_watchdog_timers(void)
|
||||||
|
{
|
||||||
|
/* Watchdog Timer disabled (WCR[EN]=0)
|
||||||
|
NOTE: WCR and WMR cannot be written again until after the
|
||||||
|
processor is reset.
|
||||||
|
*/
|
||||||
|
MCF_WTM_WCR = MCF_WTM_WCR_WAIT | MCF_WTM_WCR_DOZE | MCF_WTM_WCR_HALTED;
|
||||||
|
|
||||||
|
/* Core watchdog timer disabled */
|
||||||
|
MCF_SCM_CWCR = MCF_SCM_CWCR_CWT(0x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* init_pin_assignments - Pin Assignment and General Purpose I/O *
|
||||||
|
**********************************************************************/
|
||||||
|
static void init_pin_assignments(void)
|
||||||
|
{
|
||||||
|
/* Pin assignments for port BUSCTL
|
||||||
|
Pin BUSCTL3 : External bus output enable, /OE
|
||||||
|
Pin BUSCTL2 : External bus transfer acknowledge, /TA
|
||||||
|
Pin BUSCTL1 : External bus read/write, R/W
|
||||||
|
Pin BUSCTL0 : External bus transfer start, /TS
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_BUSCTL = 0;
|
||||||
|
MCF_GPIO_PAR_BUSCTL = MCF_GPIO_PAR_BUSCTL_PAR_OE |
|
||||||
|
MCF_GPIO_PAR_BUSCTL_PAR_TA |
|
||||||
|
MCF_GPIO_PAR_BUSCTL_PAR_RWB | MCF_GPIO_PAR_BUSCTL_PAR_TS(0x3);
|
||||||
|
|
||||||
|
/* Pin assignments for port BE
|
||||||
|
Pin BE3 : External bus byte enable BW/BWE3
|
||||||
|
Pin BE2 : External bus byte enable BW/BWE2
|
||||||
|
Pin BE1 : External bus byte enable BW/BWE1
|
||||||
|
Pin BE0 : External bus byte enable BW/BWE0
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_BE = 0;
|
||||||
|
MCF_GPIO_PAR_BE = MCF_GPIO_PAR_BE_PAR_BE3 |
|
||||||
|
MCF_GPIO_PAR_BE_PAR_BE2 |
|
||||||
|
MCF_GPIO_PAR_BE_PAR_BE1 | MCF_GPIO_PAR_BE_PAR_BE0;
|
||||||
|
|
||||||
|
/* Pin assignments for port CS
|
||||||
|
Pin CS5 : Flex bus chip select /FB_CS5
|
||||||
|
Pin CS4 : Flex bus chip select /FB_CS4
|
||||||
|
Pin CS3 : Flex bus chip select /FB_CS3
|
||||||
|
Pin CS2 : Flex bus chip select /FB_CS2
|
||||||
|
Pin CS1 : Flex bus chip select /FB_CS1
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_CS = 0;
|
||||||
|
MCF_GPIO_PAR_CS = MCF_GPIO_PAR_CS_PAR_CS5 |
|
||||||
|
MCF_GPIO_PAR_CS_PAR_CS4 |
|
||||||
|
MCF_GPIO_PAR_CS_PAR_CS3 |
|
||||||
|
MCF_GPIO_PAR_CS_PAR_CS2 | MCF_GPIO_PAR_CS_PAR_CS1;
|
||||||
|
|
||||||
|
/* Pin assignments for port FECI2C
|
||||||
|
Pin FECI2C3 : FEC management data clock, FEC_MDC
|
||||||
|
Pin FECI2C2 : FEC management data, FEC_MDIO
|
||||||
|
Pin FECI2C1 : GPIO input
|
||||||
|
Pin FECI2C0 : GPIO input
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_FECI2C = 0;
|
||||||
|
MCF_GPIO_PAR_FECI2C = MCF_GPIO_PAR_FECI2C_PAR_MDC(0x3) |
|
||||||
|
MCF_GPIO_PAR_FECI2C_PAR_MDIO(0x3);
|
||||||
|
|
||||||
|
/* Pin assignments for ports FECH and FECL
|
||||||
|
Pin FECH7 : FEC transmit clock, FEC_TXCLK
|
||||||
|
Pin FECH6 : FEC transmit enable, FEC_TXEN
|
||||||
|
Pin FECH5 : FEC transmit data 0, FEC_TXD0
|
||||||
|
Pin FECH4 : FEC collision, FEC_COL
|
||||||
|
Pin FECH3 : FEC receive clock, FEC_RXCLK
|
||||||
|
Pin FECH2 : FEC receive data valid, FEC_RXDV
|
||||||
|
Pin FECH1 : FEC receive data 0, FEC_RXD0
|
||||||
|
Pin FECH0 : FEC carrier receive sense, FEC_CRS
|
||||||
|
Pin FECL7 : FEC transmit data 3, FEC_TXD3
|
||||||
|
Pin FECL6 : FEC transmit data 2, FEC_TXD2
|
||||||
|
Pin FECL5 : FEC transmit data 1, FEC_TXD1
|
||||||
|
Pin FECL4 : FEC transmit error, FEC_TXER
|
||||||
|
Pin FECL3 : FEC receive data 3, FEX_RXD3
|
||||||
|
Pin FECL2 : FEC receive data 2, FEX_RXD2
|
||||||
|
Pin FECL1 : FEC receive data 1, FEX_RXD1
|
||||||
|
Pin FECL0 : FEC receive error, FEC_RXER
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_FECH = 0;
|
||||||
|
MCF_GPIO_PDDR_FECL = 0;
|
||||||
|
MCF_GPIO_PAR_FEC = MCF_GPIO_PAR_FEC_PAR_FEC_7W(0x3) |
|
||||||
|
MCF_GPIO_PAR_FEC_PAR_FEC_MII(0x3);
|
||||||
|
|
||||||
|
/* Pin assignments for port IRQ
|
||||||
|
Pins are all used for EdgePort GPIO/IRQ
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PAR_IRQ = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port LCDDATAH
|
||||||
|
Pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_LCDDATAH = 0;
|
||||||
|
MCF_GPIO_PAR_LCDDATA = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port LCDDATAM
|
||||||
|
Port LCDDATAM pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_LCDDATAM = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port LCDDATAL
|
||||||
|
Port LCDDATAL pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_LCDDATAL = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port LCDCTLH
|
||||||
|
Pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_LCDCTLH = 0;
|
||||||
|
MCF_GPIO_PAR_LCDCTL = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port LCDCTLL
|
||||||
|
Pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_LCDCTLL = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port PWM
|
||||||
|
Pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_PWM = 0;
|
||||||
|
MCF_GPIO_PAR_PWM = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port QSPI
|
||||||
|
Pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_QSPI = 0;
|
||||||
|
MCF_GPIO_PAR_QSPI = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port SSI
|
||||||
|
Pins are all GPIO inputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_SSI = 0;
|
||||||
|
MCF_GPIO_PAR_SSI = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port TIMER
|
||||||
|
Pins are all GPIO outputs
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_TIMER = MCF_GPIO_PDDR_TIMER_PDDR_TIMER3 |
|
||||||
|
MCF_GPIO_PDDR_TIMER_PDDR_TIMER2 |
|
||||||
|
MCF_GPIO_PDDR_TIMER_PDDR_TIMER1 | MCF_GPIO_PDDR_TIMER_PDDR_TIMER0;
|
||||||
|
MCF_GPIO_PAR_TIMER = 0;
|
||||||
|
|
||||||
|
/* Pin assignments for port UART
|
||||||
|
Pin UART7 : UART 1 clear-to-send, /U1CTS
|
||||||
|
Pin UART6 : UART 1 request-to-send, /U1RTS
|
||||||
|
Pin UART5 : UART 1 transmit data, U1TXD
|
||||||
|
Pin UART4 : UART 1 receive data, U1RXD
|
||||||
|
Pin UART3 : UART 0 clear-to-send, /U0CTS
|
||||||
|
Pin UART2 : UART 0 request-to-send, /U0RTS
|
||||||
|
Pin UART1 : UART 0 transmit data, U0TXD
|
||||||
|
Pin UART0 : UART 0 receive data, U0RXD
|
||||||
|
*/
|
||||||
|
MCF_GPIO_PDDR_UART = 0;
|
||||||
|
MCF_GPIO_PAR_UART = MCF_GPIO_PAR_UART_PAR_UCTS1(0x3) |
|
||||||
|
MCF_GPIO_PAR_UART_PAR_URTS1(0x3) |
|
||||||
|
MCF_GPIO_PAR_UART_PAR_URXD1(0x3) |
|
||||||
|
MCF_GPIO_PAR_UART_PAR_UTXD1(0x3) |
|
||||||
|
MCF_GPIO_PAR_UART_PAR_UCTS0 |
|
||||||
|
MCF_GPIO_PAR_UART_PAR_URTS0 |
|
||||||
|
MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0;
|
||||||
|
}
|
||||||
82
c/src/lib/libbsp/m68k/mcf5329/startup/init5329.c
Normal file
82
c/src/lib/libbsp/m68k/mcf5329/startup/init5329.c
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void _wr_vbr(uint32_t);
|
||||||
|
extern void init_main();
|
||||||
|
extern int boot_card(int, char **, char **);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From linkcmds
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern uint8_t _VBR[];
|
||||||
|
extern uint8_t _INTERRUPT_VECTOR[];
|
||||||
|
|
||||||
|
extern uint8_t _clear_start[];
|
||||||
|
extern uint8_t _clear_end[];
|
||||||
|
|
||||||
|
extern uint8_t _data_src_start[];
|
||||||
|
extern uint8_t _data_dest_start[];
|
||||||
|
extern uint8_t _data_dest_end[];
|
||||||
|
|
||||||
|
void Init5329(void)
|
||||||
|
{
|
||||||
|
register uint32_t i;
|
||||||
|
register uint8_t *dbp, *sbp;
|
||||||
|
register uint32_t *dp, *sp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the hardware
|
||||||
|
*/
|
||||||
|
init_main();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the vector table to RAM
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_VBR != _INTERRUPT_VECTOR) {
|
||||||
|
sp = (uint32_t *) _INTERRUPT_VECTOR;
|
||||||
|
dp = (uint32_t *) _VBR;
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
*dp++ = *sp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_wr_vbr((uint32_t) _VBR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move initialized data from ROM to RAM.
|
||||||
|
*/
|
||||||
|
if (_data_src_start != _data_dest_start) {
|
||||||
|
dbp = (uint8_t *) _data_dest_start;
|
||||||
|
sbp = (uint8_t *) _data_src_start;
|
||||||
|
i = _data_dest_end - _data_dest_start;
|
||||||
|
while (i--)
|
||||||
|
*dbp++ = *sbp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zero uninitialized data
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_clear_start != _clear_end) {
|
||||||
|
sbp = _clear_start;
|
||||||
|
dbp = _clear_end;
|
||||||
|
i = dbp - sbp;
|
||||||
|
while (i--)
|
||||||
|
*sbp++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to call some kind of RTEMS function here!
|
||||||
|
*/
|
||||||
|
|
||||||
|
boot_card(0, 0, 0);
|
||||||
|
for (;;) ;
|
||||||
|
}
|
||||||
186
c/src/lib/libbsp/m68k/mcf5329/startup/linkcmds
Normal file
186
c/src/lib/libbsp/m68k/mcf5329/startup/linkcmds
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* This file contains directives for the GNU linker which are specific
|
||||||
|
* to the Freescale ColdFire mcf52235
|
||||||
|
*
|
||||||
|
* 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.rtems.com/license/LICENSE.e
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Declare some sizes.
|
||||||
|
*/
|
||||||
|
_CoreSRamBase = DEFINED(_RamBase) ? _RamBase : 0x80000000;
|
||||||
|
_CoreSRamSize = DEFINED(_RamSize) ? _RamSize : 32K;
|
||||||
|
|
||||||
|
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x40000000;
|
||||||
|
_RamSize = DEFINED(_RamSize) ? _RamSize : 32M;
|
||||||
|
|
||||||
|
_BootFlashBase = DEFINED(_FlashBase) ? _FlashBase : 0x00000000;
|
||||||
|
_BootFlashSize = DEFINED(_FlashBase) ? _FlashBase : 2M;
|
||||||
|
|
||||||
|
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0;
|
||||||
|
_StackSize = DEFINED(_StackSize) ? _StackSize : 0x400;
|
||||||
|
|
||||||
|
_VBR = 0x40000000;
|
||||||
|
|
||||||
|
ENTRY(start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
core_sram : ORIGIN = 0x80000000, LENGTH = 32K
|
||||||
|
boot_flash : ORIGIN = 0x00000000, LENGTH = 2M
|
||||||
|
dram : ORIGIN = 0x40000000, LENGTH = 32M
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.ram_code :
|
||||||
|
{
|
||||||
|
*(.ram_code)
|
||||||
|
} > core_sram
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Text, data and bss segments
|
||||||
|
*/
|
||||||
|
.text 0x40000500 : {
|
||||||
|
|
||||||
|
*(.text*)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = .);
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
.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 = . );
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
_data_src_start = _estuff;
|
||||||
|
_data_src_end = _data_dest_start + SIZEOF(.data);
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
_clear_start = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (16);
|
||||||
|
PROVIDE (_end = .);
|
||||||
|
|
||||||
|
_clear_end = .;
|
||||||
|
_WorkspaceBase = .;
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
.start_stack :
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Starting Stack
|
||||||
|
*/
|
||||||
|
. += _StackSize;
|
||||||
|
. = ALIGN (16);
|
||||||
|
PROVIDE(_StackInit = .);
|
||||||
|
} > core_sram
|
||||||
|
|
||||||
|
/* 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 = .);
|
||||||
|
}
|
||||||
182
c/src/lib/libbsp/m68k/mcf5329/startup/linkcmdsflash
Normal file
182
c/src/lib/libbsp/m68k/mcf5329/startup/linkcmdsflash
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* This file contains directives for the GNU linker which are specific
|
||||||
|
* to the Freescale ColdFire mcf52235
|
||||||
|
*
|
||||||
|
* 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.rtems.com/license/LICENSE.e
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Declare some sizes.
|
||||||
|
*/
|
||||||
|
_CoreSRamBase = DEFINED(_RamBase) ? _RamBase : 0x80000000;
|
||||||
|
_CoreSRamSize = DEFINED(_RamSize) ? _RamSize : 32K;
|
||||||
|
|
||||||
|
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x40000000;
|
||||||
|
_RamSize = DEFINED(_RamSize) ? _RamSize : 32M;
|
||||||
|
|
||||||
|
_BootFlashBase = DEFINED(_FlashBase) ? _FlashBase : 0x00000000;
|
||||||
|
_BootFlashSize = DEFINED(_FlashBase) ? _FlashBase : 2M;
|
||||||
|
|
||||||
|
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0;
|
||||||
|
_StackSize = DEFINED(_StackSize) ? _StackSize : 0x400;
|
||||||
|
|
||||||
|
_VBR = 0x40000000;
|
||||||
|
|
||||||
|
ENTRY(start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
core_sram : ORIGIN = 0x80000000, LENGTH = 32K
|
||||||
|
boot_flash : ORIGIN = 0x00000000, LENGTH = 2M
|
||||||
|
dram : ORIGIN = 0x40000000, LENGTH = 32M
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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 = .);
|
||||||
|
} > boot_flash
|
||||||
|
|
||||||
|
.data 0x40000500 : AT (_estuff)
|
||||||
|
{
|
||||||
|
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 = . );
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
_data_src_start = _estuff;
|
||||||
|
_data_src_end = _data_dest_start + SIZEOF(.data);
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
_clear_start = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (16);
|
||||||
|
PROVIDE (_end = .);
|
||||||
|
|
||||||
|
_clear_end = .;
|
||||||
|
_WorkspaceBase = .;
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
.start_stack :
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Starting Stack
|
||||||
|
*/
|
||||||
|
. += _StackSize;
|
||||||
|
. = ALIGN (16);
|
||||||
|
PROVIDE(_StackInit = .);
|
||||||
|
} > core_sram
|
||||||
|
|
||||||
|
/* 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 = .);
|
||||||
|
}
|
||||||
48
c/src/lib/libbsp/m68k/mcf5329/timer/timer.c
Normal file
48
c/src/lib/libbsp/m68k/mcf5329/timer/timer.c
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Timer Init
|
||||||
|
*
|
||||||
|
* Use the last DMA timer (DTIM3) as the diagnostic timer.
|
||||||
|
*
|
||||||
|
* Author: W. Eric Norum <norume@aps.anl.gov>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 2005.
|
||||||
|
* 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.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
void Timer_initialize(void)
|
||||||
|
{
|
||||||
|
uint32_t preScaleDivisor = bsp_get_BUS_clock_speed() / 1000000;
|
||||||
|
|
||||||
|
MCF_DTIM3_DTMR = 0;
|
||||||
|
MCF_DTIM3_DTMR = MCF_DTIM_DTMR_PS(preScaleDivisor - 1) |
|
||||||
|
MCF_DTIM_DTMR_CLK_DIV1 | MCF_DTIM_DTMR_RST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return timer value in microsecond units
|
||||||
|
*/
|
||||||
|
int Read_timer(void)
|
||||||
|
{
|
||||||
|
return MCF_DTIM3_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)
|
||||||
|
{
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user