* 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:
Joel Sherrill
2008-06-20 14:58:34 +00:00
parent 8d26950fca
commit 6b56ec3327
22 changed files with 3661 additions and 0 deletions

View 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.

View 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

View 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

View 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}

View 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"

View 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

View 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]);
}

View 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

View 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

View 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

View 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

View File

@@ -0,0 +1,29 @@
/*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef _RTEMS_TMTEST27
#error "This is an RTEMS internal file you must not include directly."
#endif
#ifndef __tm27_h
#define __tm27_h
/*
* Stuff for Time Test 27
* Don't bother with hardware -- just use a software-interrupt
*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) set_vector( (handler), 35, 1 )
#define Cause_tm27_intr() asm volatile ("trap #3");
#define Clear_tm27_intr() /* empty */
#define Lower_tm27_intr() /* empty */
#endif

View File

@@ -0,0 +1,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;
};

View 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

View 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

View 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 ");
}
}

View 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;
}

View 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;
}

View 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 (;;) ;
}

View 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 = .);
}

View 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 = .);
}

View 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)
{
}