From 69effbb4e16db7e6c85cd9b2bb8ad648c700b0a6 Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Fri, 11 Jul 2008 10:00:41 +0000 Subject: added variant to gen68360 BSP added genmcf548x BSP --- c/src/lib/libbsp/m68k/ChangeLog | 4 + c/src/lib/libbsp/m68k/acinclude.m4 | 2 + c/src/lib/libbsp/m68k/gen68360/ChangeLog | 10 + c/src/lib/libbsp/m68k/gen68360/Makefile.am | 1 - c/src/lib/libbsp/m68k/gen68360/README | 11 + c/src/lib/libbsp/m68k/gen68360/include/bsp.h | 23 + c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.c | 852 +++++++++++++++++++ c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.h | 146 ++++ .../lib/libbsp/m68k/gen68360/spi/mc68360_spidrv.c | 627 ++++++++++++++ c/src/lib/libbsp/m68k/gen68360/startup/init68360.c | 175 ++++ c/src/lib/libbsp/m68k/genmcf548x/ChangeLog | 14 + c/src/lib/libbsp/m68k/genmcf548x/Makefile.am | 73 ++ c/src/lib/libbsp/m68k/genmcf548x/README | 180 ++++ c/src/lib/libbsp/m68k/genmcf548x/aclocal.m4 | 940 +++++++++++++++++++++ c/src/lib/libbsp/m68k/genmcf548x/bsp_specs | 13 + c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c | 104 +++ c/src/lib/libbsp/m68k/genmcf548x/configure.ac | 29 + c/src/lib/libbsp/m68k/genmcf548x/console/console.c | 886 +++++++++++++++++++ c/src/lib/libbsp/m68k/genmcf548x/include/bsp.h | 136 +++ .../libbsp/m68k/genmcf548x/include/bspopts.h.in | 19 + c/src/lib/libbsp/m68k/genmcf548x/include/coverhd.h | 105 +++ c/src/lib/libbsp/m68k/genmcf548x/include/tm27.h | 29 + c/src/lib/libbsp/m68k/genmcf548x/network/network.c | 20 + c/src/lib/libbsp/m68k/genmcf548x/preinstall.am | 58 ++ c/src/lib/libbsp/m68k/genmcf548x/start/start.S | 436 ++++++++++ .../lib/libbsp/m68k/genmcf548x/startup/bspclean.c | 60 ++ .../lib/libbsp/m68k/genmcf548x/startup/bspstart.c | 323 +++++++ .../lib/libbsp/m68k/genmcf548x/startup/init548x.c | 317 +++++++ c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds | 232 +++++ .../startup/linkcmds.m5484FireEngine.flash | 232 +++++ c/src/lib/libbsp/m68k/genmcf548x/timer/timer.c | 94 +++ 31 files changed, 6150 insertions(+), 1 deletion(-) create mode 100644 c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.c create mode 100644 c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.h create mode 100644 c/src/lib/libbsp/m68k/gen68360/spi/mc68360_spidrv.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/ChangeLog create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/Makefile.am create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/README create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/aclocal.m4 create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/bsp_specs create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/configure.ac create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/console/console.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/include/bspopts.h.in create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/include/tm27.h create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/network/network.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/preinstall.am create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/start/start.S create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/startup/init548x.c create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds.m5484FireEngine.flash create mode 100644 c/src/lib/libbsp/m68k/genmcf548x/timer/timer.c diff --git a/c/src/lib/libbsp/m68k/ChangeLog b/c/src/lib/libbsp/m68k/ChangeLog index ceafb1b029..4ba841fc0d 100644 --- a/c/src/lib/libbsp/m68k/ChangeLog +++ b/c/src/lib/libbsp/m68k/ChangeLog @@ -1,3 +1,7 @@ +2008-07-11 Thomas Doerfler + + * genmcf548x: added BSP + 2008-06-27 Joel Sherrill * acinclude.m4: Regenerated. diff --git a/c/src/lib/libbsp/m68k/acinclude.m4 b/c/src/lib/libbsp/m68k/acinclude.m4 index d171d30047..8c7650d4ec 100644 --- a/c/src/lib/libbsp/m68k/acinclude.m4 +++ b/c/src/lib/libbsp/m68k/acinclude.m4 @@ -12,6 +12,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR], AC_CONFIG_SUBDIRS([gen68340]);; gen68360 ) AC_CONFIG_SUBDIRS([gen68360]);; + genmcf548x ) + AC_CONFIG_SUBDIRS([genmcf548x]);; idp ) AC_CONFIG_SUBDIRS([idp]);; mcf5206elite ) diff --git a/c/src/lib/libbsp/m68k/gen68360/ChangeLog b/c/src/lib/libbsp/m68k/gen68360/ChangeLog index 6bcdbed1ee..0853aa3311 100644 --- a/c/src/lib/libbsp/m68k/gen68360/ChangeLog +++ b/c/src/lib/libbsp/m68k/gen68360/ChangeLog @@ -1,3 +1,13 @@ +2008-07-09 Thomas Doerfler + + * Makefile.am, spi/m360_spidrv.c, spi/m360_spidrv.h: + added SPI driver + +2008-07-09 Thomas Doerfler + + * README: + added pgh360 BSP variant + 2008-05-23 Joel Sherrill * console/console.c: Eliminate copies of switches to convert termios diff --git a/c/src/lib/libbsp/m68k/gen68360/Makefile.am b/c/src/lib/libbsp/m68k/gen68360/Makefile.am index 93f1ee2061..e2c17fb2f3 100644 --- a/c/src/lib/libbsp/m68k/gen68360/Makefile.am +++ b/c/src/lib/libbsp/m68k/gen68360/Makefile.am @@ -11,7 +11,6 @@ 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 = diff --git a/c/src/lib/libbsp/m68k/gen68360/README b/c/src/lib/libbsp/m68k/gen68360/README index 471e55581f..c48fb20b84 100644 --- a/c/src/lib/libbsp/m68k/gen68360/README +++ b/c/src/lib/libbsp/m68k/gen68360/README @@ -29,6 +29,8 @@ # can be used with the Arnewsh SBC360 card. # - If the preprocessor symbol M68360_ATLAS_HSB is defined, # the BSP is compiled for an Atlas HSB card. +# - If the preprocessor symbol M68360_IMD_PGH is defined, +# the BSP is compiled for an IMD PGH360 card. # - Otherwise, the BSP is compiled for a generic 68360 system # as described in Chapter 9 of the MC68360 User's Manual. This # version works with the Atlas ACE360 card. @@ -39,6 +41,7 @@ BOARD: Generic 68360 as described in Motorola MC68360 User's Manual BOARD: Atlas Computer Equipment Inc. High Speed Bridge (HSB) BOARD: Atlas Computer Equipment Inc. Advanced Communication Engine (ACE) BOARD: Arnewsh SBC360 68040/68360 card +BOARD: IMD PGH Board (custom) BUS: none CPU FAMILY: Motorola CPU32+, Motorola 68040 COPROCESSORS: none @@ -83,6 +86,13 @@ bus width: 8-bit PROM/FLASH, 32-bit DRAM ROM: To 1 MByte, 180 nsec (3 wait states), chip select 0 RAM: 4 or 16 MBytes of 60 nsec parity DRAM (1Mx36) to RAS1*/CAS1* +Board description (IMD PGH) +--------------------------- +clock rate: 25 MHz +bus width: 8-bit PROM/FLASH, 32-bit DRAM +ROM: 512KByte, 180 nsec (3 wait states), chip select 0 +RAM: 16 MBytes of 60 nsec no-parity DRAM (1Mx32) to RAS1*/CAS1* + Host System ----------- OPENSTEP 4.2 (Intel and Motorola), Solaris 2.5, Linux 2.0.29 @@ -292,3 +302,4 @@ The board support package has been tested with: Arnewsh Inc. P.O. Box 270352 Fort Collins, CO 80527-0352 + A custom 68360 board (PGH360) produced by IMD diff --git a/c/src/lib/libbsp/m68k/gen68360/include/bsp.h b/c/src/lib/libbsp/m68k/gen68360/include/bsp.h index 7f84e5b26a..5f30586daa 100644 --- a/c/src/lib/libbsp/m68k/gen68360/include/bsp.h +++ b/c/src/lib/libbsp/m68k/gen68360/include/bsp.h @@ -90,6 +90,8 @@ void *M360AllocateBufferDescriptors( int count ); void *M360AllocateRiscTimers( int count ); extern char M360DefaultWatchdogFeeder; +extern int m360_clock_rate; /* BRG clock rate, defined in console.c */ + m68k_isr_entry set_vector( rtems_isr_entry handler, rtems_vector_number vector, @@ -102,6 +104,7 @@ m68k_isr_entry set_vector( extern char _RamBase[]; extern char _HeapSize[]; + /* * Definitions for Atlas Computer Equipment Inc. High Speed Bridge (HSB) */ @@ -111,6 +114,26 @@ extern char _HeapSize[]; #define ATLASHSB_LED4 0x20010004L #define ATLASHSB_ROM_U6 0xFF080000L /* U6 flash ROM socket */ + + /* + * definitions for PGH360 board + */ +#if defined(PGH360) +/* + * logical SPI addresses of SPI slaves available + */ +#define PGH360_SPI_ADDR_EEPROM 0 +#define PGH360_SPI_ADDR_DISP4_DATA 1 +#define PGH360_SPI_ADDR_DISP4_CTRL 2 + +/* + * Port B bit locations of SPI slave selects + */ +#define PGH360_PB_SPI_DISP4_RS_MSK (1<<15) +#define PGH360_PB_SPI_DISP4_CE_MSK (1<<14) +#define PGH360_PB_SPI_EEP_CE_MSK (1<< 0) +#endif /* defined(PGH360) */ + #ifdef __cplusplus } #endif diff --git a/c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.c b/c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.c new file mode 100644 index 0000000000..38f80a5789 --- /dev/null +++ b/c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.c @@ -0,0 +1,852 @@ +/*===============================================================*\ +| Project: RTEMS support for PGH360 | ++-----------------------------------------------------------------+ +| Copyright (c) 2008 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| 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. | +| | ++-----------------------------------------------------------------+ +| this file contains the M360 SPI driver | +\*===============================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG +static m360_spi_softc_t *m360_spi_softc_ptr; +/* + * this is a dummy receive buffer for sequences, + * where only send data are available + */ +uint8_t m360_spi_dummy_rxbuf[2]; +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code m360_spi_baud_to_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| determine proper divider value | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + uint32_t baudrate, /* desired baudrate */ + uint32_t *spimode /* result value */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + uint32_t divider; + uint16_t tmpmode = 0; + /* + * determine clock divider and DIV16 bit + */ + divider = m360_clock_rate/baudrate; + if (divider > 64) { + tmpmode = M360_SPMODE_DIV16; + divider /= 16; + } + if ((divider < 1) || + (divider > 64)) { + return RTEMS_INVALID_NUMBER; + } + else { + tmpmode |= M360_SPMODE_PM(divider/4-1); + } + *spimode = tmpmode; + return RTEMS_SUCCESSFUL; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code m360_spi_char_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| determine proper value for character size | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + m360_spi_softc_t *softc_ptr, /* handle */ + uint32_t bits_per_char, /* bits per character */ + boolean lsb_first, /* TRUE: send LSB first */ + uint16_t *spimode /* result value */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + uint16_t tmpmode; + + /* + * calculate data format + */ + if ((bits_per_char >= 4) && + (bits_per_char <= 16)) { + tmpmode = M360_SPMODE_CLEN( bits_per_char-1); + } + else { + return RTEMS_INVALID_NUMBER; + } + + *spimode = tmpmode; + return 0; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static int m360_spi_wait +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| wait for spi to become idle | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + m360_spi_softc_t *softc_ptr /* handle */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + uint16_t act_status; + rtems_status_code rc; + uint32_t tout; + +#if defined(DEBUG) + printk("m360_spi_wait called... "); +#endif + if (softc_ptr->initialized) { + /* + * allow interrupts, when receiver is not empty + */ + m360.spim = (M360_SPIE_TXE | M360_SPIE_TXB | + M360_SPIE_BSY | M360_SPIE_MME); + + rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id, + RTEMS_WAIT, + RTEMS_NO_TIMEOUT); + if (rc != RTEMS_SUCCESSFUL) { + return rc; + } + } + else { + tout = 0; + do { + if (tout++ > 1000000) { +#if defined(DEBUG) + printk("... exit with RTEMS_TIMEOUT\r\n"); +#endif + return RTEMS_TIMEOUT; + } + /* + * wait for SPI to terminate + */ + } while (!(m360.spie & M360_SPIE_TXB)); + } + + act_status = m360.spie; + if ((act_status & (M360_SPIE_TXE | M360_SPIE_TXB | + M360_SPIE_BSY | M360_SPIE_MME))!= M360_SPIE_TXB) { +#if defined(DEBUG) + printk("... exit with RTEMS_IO_ERROR," + "act_status=0x%04x,mask=0x%04x,desired_status=0x%04x\r\n", + act_status,status_mask,desired_status); +#endif + return RTEMS_IO_ERROR; + } +#if defined(DEBUG) + printk("... exit OK\r\n"); +#endif + return RTEMS_SUCCESSFUL; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_isr m360_spi_irq_handler +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| handle interrupts | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_vector_number v /* vector number */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = m360_spi_softc_ptr; + + /* + * disable interrupt mask + */ + m360.spim = 0; + if (softc_ptr->initialized) { + rtems_semaphore_release(softc_ptr->irq_sema_id); + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static void m360_spi_install_irq_handler +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| (un-)install the interrupt handler | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + m360_spi_softc_t *softc_ptr, /* ptr to control structure */ + int install /* TRUE: install, FALSE: remove */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| | +\*=========================================================================*/ +{ + rtems_status_code rc = RTEMS_SUCCESSFUL; + + /* + * (un-)install handler for SPI device + */ + if (install) { + /* + * create semaphore for IRQ synchronization + */ + rc = rtems_semaphore_create(rtems_build_name('s','p','i','s'), + 0, + RTEMS_FIFO + | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &softc_ptr->irq_sema_id); + if (rc != RTEMS_SUCCESSFUL) { + rtems_panic("SPI: cannot create semaphore"); + } + if (rc == RTEMS_SUCCESSFUL) { + rc = rtems_interrupt_catch (m360_spi_irq_handler, + (m360.cicr & 0xE0) | 0x05, + &softc_ptr->old_handler); + if (rc != RTEMS_SUCCESSFUL) { + rtems_panic("SPI: cannot install IRQ handler"); + } + } + /* + * enable IRQ in CPIC + */ + if (rc == RTEMS_SUCCESSFUL) { + m360.cimr |= (1 << 5); + } + } + else { + rtems_isr_entry old_handler; + /* + * disable IRQ in CPIC + */ + if (rc == RTEMS_SUCCESSFUL) { + m360.cimr &= ~(1 << 5); + } + rc = rtems_interrupt_catch (softc_ptr->old_handler, + (m360.cicr & 0xE0) | 0x05, + &old_handler); + if (rc != RTEMS_SUCCESSFUL) { + rtems_panic("SPI: cannot uninstall IRQ handler"); + } + /* + * delete sync semaphore + */ + if (softc_ptr->irq_sema_id != 0) { + rc = rtems_semaphore_delete(softc_ptr->irq_sema_id); + if (rc != RTEMS_SUCCESSFUL) { + rtems_panic("SPI: cannot delete semaphore"); + } + } + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code m360_spi_init +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| initialize the driver | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh /* bus specifier structure */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); + rtems_status_code rc = RTEMS_SUCCESSFUL; + +#if defined(DEBUG) + printk("m360_spi_init called... "); +#endif + /* + * init HW registers: + */ + /* + * FIXME: set default mode in SPMODE + */ + + /* + * allocate BDs (1x RX, 1x TX) + */ + if (rc == RTEMS_SUCCESSFUL) { + softc_ptr->rx_bd = M360AllocateBufferDescriptors (1); + softc_ptr->tx_bd = M360AllocateBufferDescriptors (1); + if ((softc_ptr->rx_bd == NULL) || + (softc_ptr->tx_bd == NULL)) { + rc = RTEMS_NO_MEMORY; + } + } + /* + * set parameter RAM + */ + m360.spip.rbase = (char *)softc_ptr->rx_bd - (char *)&m360; + m360.spip.tbase = (char *)softc_ptr->tx_bd - (char *)&m360; + m360.spip.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; + m360.spip.tfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; + m360.spip.mrblr = 2; + + /* + * issue "InitRxTx" Command to CP + */ + M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SPI); + + /* + * init interrupt stuff + */ + if (rc == RTEMS_SUCCESSFUL) { + m360_spi_install_irq_handler(softc_ptr,TRUE); + } + if (rc == RTEMS_SUCCESSFUL) { + /* + * set up ports + * LINE PAR DIR DAT + * ----------------------- + * MOSI 1 1 x + * MISO 1 1 x + * CLK 1 1 x + */ + + /* set Port B Pin Assignment Register... */ + m360.pbpar = + m360.pbpar + | M360_PB_SPI_MISO_MSK + | M360_PB_SPI_MOSI_MSK + | M360_PB_SPI_CLK_MSK; + + /* set Port B Data Direction Register... */ + m360.pbdir = + m360.pbdir + | M360_PB_SPI_MISO_MSK + | M360_PB_SPI_MOSI_MSK + | M360_PB_SPI_CLK_MSK; + } + /* + * mark, that we have initialized + */ + if (rc == RTEMS_SUCCESSFUL) { + softc_ptr->initialized = TRUE; + } +#if defined(DEBUG) + printk("... exit OK\r\n"); +#endif + return rc; +} + + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static int m360_spi_read_write_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| transmit/receive some bytes from SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *rbuf, /* buffer to store bytes */ + const unsigned char *tbuf, /* buffer to send bytes */ + int len /* number of bytes to transceive */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes received or (negative) error code | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); + rtems_status_code rc = RTEMS_SUCCESSFUL; + int bc = 0; + +#if defined(DEBUG) + printk("m360_spi_read_write_bytes called... "); +#endif + + /* + * prepare RxBD + */ + if (rc == RTEMS_SUCCESSFUL) { + if (rbuf == NULL) { + /* + * no Tx buffer: receive to dummy buffer + */ + m360.spip.mrblr = sizeof(m360_spi_dummy_rxbuf); + softc_ptr->rx_bd->buffer = m360_spi_dummy_rxbuf; + softc_ptr->rx_bd->length = 0; + softc_ptr->rx_bd->status = (M360_BD_EMPTY | M360_BD_WRAP | + M360_BD_CONTINUOUS); + } + else { + m360.spip.mrblr = len; + softc_ptr->rx_bd->buffer = rbuf; + softc_ptr->rx_bd->length = 0; + softc_ptr->rx_bd->status = (M360_BD_EMPTY | M360_BD_WRAP); + } + } + /* + * prepare TxBD + */ + if (rc == RTEMS_SUCCESSFUL) { + if (tbuf == NULL) { + /* + * FIXME: no Tx buffer: transmit from dummy buffer + */ + softc_ptr->tx_bd->buffer = m360_spi_dummy_rxbuf; + softc_ptr->tx_bd->length = len; + softc_ptr->tx_bd->status = (M360_BD_READY | M360_BD_WRAP | + M360_BD_CONTINUOUS); + } + else { + softc_ptr->tx_bd->buffer = tbuf; + softc_ptr->tx_bd->length = len; + softc_ptr->tx_bd->status = (M360_BD_READY | M360_BD_WRAP); + } + } + + if (rc == RTEMS_SUCCESSFUL) { + /* + * set START command + */ + m360.spcom = M360_SPCOM_STR; + /* + * wait for SPI to finish + */ + rc = m360_spi_wait(softc_ptr); + } +#if defined(DEBUG) + printk("... exit OK, rc=%d\r\n",bc); +#endif + return (rc == RTEMS_SUCCESSFUL) ? bc : -rc; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_read_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| receive some bytes from SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *buf, /* buffer to store bytes */ + int len /* number of bytes to receive */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes received or (negative) error code | +\*=========================================================================*/ +{ + return m360_spi_read_write_bytes(bh,buf,NULL,len); +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_write_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| send some bytes to SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *buf, /* buffer to send */ + int len /* number of bytes to send */ + +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes sent or (negative) error code | +\*=========================================================================*/ +{ + return m360_spi_read_write_bytes(bh,NULL,buf,len); +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code m360_spi_set_tfr_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| set SPI to desired baudrate/clock mode/character mode | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| rtems_status_code | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); + uint32_t spimode_baud,spimode; + rtems_status_code rc = RTEMS_SUCCESSFUL; + /* + * FIXME: set proper mode + */ + if (rc == RTEMS_SUCCESSFUL) { + rc = m360_spi_baud_to_mode(tfr_mode->baudrate,&spimode_baud); + } + if (rc == RTEMS_SUCCESSFUL) { + rc = m360_spi_char_mode(softc_ptr, + tfr_mode->bits_per_char, + tfr_mode->lsb_first, + &spimode); + } + if (rc == RTEMS_SUCCESSFUL) { + spimode |= spimode_baud; + spimode |= M360_SPMODE_MASTER; /* set master mode */ + if (!tfr_mode->lsb_first) { + spimode |= M360_SPMODE_REV; + } + if (tfr_mode->clock_inv) { + spimode |= M360_SPMODE_CI; + } + if (tfr_mode->clock_phs) { + spimode |= M360_SPMODE_CP; + } + } + + if (rc == RTEMS_SUCCESSFUL) { + /* + * disable SPI + */ + m360.spmode &= ~M360_SPMODE_EN; + /* + * set new mode and reenable SPI + */ + m360.spmode = spimode | M360_SPMODE_EN; + } + return rc; +} + + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_ioctl +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| perform selected ioctl function for SPI | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + int cmd, /* ioctl command code */ + void *arg /* additional argument array */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| rtems_status_code | +\*=========================================================================*/ +{ + int ret_val = -1; + + switch(cmd) { + case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: + ret_val = + -m360_spi_set_tfr_mode(bh, + (const rtems_libi2c_tfr_mode_t *)arg); + break; + case RTEMS_LIBI2C_IOCTL_READ_WRITE: + ret_val = + m360_spi_read_write_bytes(bh, + ((rtems_libi2c_read_write_t *)arg)->rd_buf, + ((rtems_libi2c_read_write_t *)arg)->wr_buf, + ((rtems_libi2c_read_write_t *)arg)->byte_cnt); + break; + default: + ret_val = -RTEMS_NOT_DEFINED; + break; + } + return ret_val; +} + +/*=========================================================================*\ +| Board-specific adaptation functions | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code bsp_spi_sel_addr +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| address a slave device on the bus | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + uint32_t addr, /* address to send on bus */ + int rw /* 0=write,1=read */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ +#if defined(PGH360) + /* + * select given device + */ + /* + * GPIO1[24] is SPI_A0 + * GPIO1[25] is SPI_A1 + * GPIO1[26] is SPI_A2 + * set pins to address + */ + switch(addr) { + case PGH360_SPI_ADDR_EEPROM: + m360.pbdat &= ~PGH360_PB_SPI_EEP_CE_MSK; + break; + case PGH360_SPI_ADDR_DISP4_DATA: + m360.pbdat = (m360.pbdat + & ~(PGH360_PB_SPI_DISP4_CE_MSK | + PGH360_PB_SPI_DISP4_RS_MSK)); + break; + case PGH360_SPI_ADDR_DISP4_CTRL: + m360.pbdat = (m360.pbdat + & ~(PGH360_PB_SPI_DISP4_CE_MSK) + | PGH360_PB_SPI_DISP4_RS_MSK); + break; + default: + return RTEMS_INVALID_NUMBER; + } +#endif /* PGH360 */ + return RTEMS_SUCCESSFUL; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code bsp_spi_send_start_dummy +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| dummy function, SPI has no start condition | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh /* bus specifier structure */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + return 0; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code bsp_spi_send_stop +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| deselect SPI | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh /* bus specifier structure */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ +#if defined(DEBUG) + printk("bsp_spi_send_stop called... "); +#endif +#if defined(PGH360) + m360.pbdat = (m360.pbdat + | PGH360_PB_SPI_DISP4_CE_MSK + | PGH360_PB_SPI_EEP_CE_MSK); +#endif +#if defined(DEBUG) + printk("... exit OK\r\n"); +#endif + return 0; +} + +/*=========================================================================*\ +| list of handlers | +\*=========================================================================*/ + +rtems_libi2c_bus_ops_t bsp_spi_ops = { + init: m360_spi_init, + send_start: bsp_spi_send_start_dummy, + send_stop: bsp_spi_send_stop, + send_addr: bsp_spi_sel_addr, + read_bytes: m360_spi_read_bytes, + write_bytes: m360_spi_write_bytes, + ioctl: m360_spi_ioctl +}; + +static m360_spi_desc_t bsp_spi_bus_desc = { + {/* public fields */ + ops: &bsp_spi_ops, + size: sizeof(bsp_spi_bus_desc) + }, + { /* our private fields */ + initialized: FALSE + } +}; + +/*=========================================================================*\ +| initialization | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code bsp_register_spi +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| register SPI bus and devices | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + void /* */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| 0 or error code | +\*=========================================================================*/ +{ + int ret_code; + int spi_busno; + + /* + * init I2C library (if not already done) + */ + rtems_libi2c_initialize (); + + /* + * init port pins used to address/select SPI devices + */ + +#if defined(PGH360) + + /* + * set up ports + * LINE PAR DIR DAT + * ----------------------- + * EEP_CE 0 1 act-high + * DISP4_CS 0 1 act-high + * DISP4_RS 0 1 active + */ + + /* set Port B Pin Assignment Register... */ + m360.pbpar = + (m360.pbpar + & ~(PGH360_PB_SPI_EEP_CE_MSK + | PGH360_PB_SPI_DISP4_CE_MSK + | PGH360_PB_SPI_DISP4_RS_MSK)); + + /* set Port B Data Direction Register... */ + m360.pbdir = + m360.pbdir + | PGH360_PB_SPI_EEP_CE_MSK + | PGH360_PB_SPI_DISP4_CE_MSK + | PGH360_PB_SPI_DISP4_RS_MSK; + + /* set Port B Data Register to inactive CE state */ + m360.pbdat = + m360.pbdat + | PGH360_PB_SPI_DISP4_CE_MSK + | PGH360_PB_SPI_DISP4_RS_MSK; +#endif + + /* + * register SPI bus + */ + ret_code = rtems_libi2c_register_bus("/dev/spi", + &(bsp_spi_bus_desc.bus_desc)); + if (ret_code < 0) { + return -ret_code; + } + spi_busno = ret_code; +#if defined(PGH360) + /* + * register devices + */ +#if 0 + ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FLASH_DEVICE_NAME, + spi_flash_m25p40_rw_driver_descriptor, + spi_busno,0x00); + if (ret_code < 0) { + return -ret_code; + } +#endif +#endif /* defined(PGH360) */ + /* + * FIXME: further drivers, when available + */ + return 0; +} + + diff --git a/c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.h b/c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.h new file mode 100644 index 0000000000..6974002364 --- /dev/null +++ b/c/src/lib/libbsp/m68k/gen68360/spi/m360_spi.h @@ -0,0 +1,146 @@ +/*===============================================================*\ +| Project: RTEMS support for MC68360 | ++-----------------------------------------------------------------+ +| Copyright (c) 2008 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| 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. | +| | ++-----------------------------------------------------------------+ +| this file contains the MC68360 SPI driver declarations | +\*===============================================================*/ +#ifndef _M360_SPIDRV_H +#define _M360_SPIDRV_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct m360_spi_softc { + int initialized; + rtems_id irq_sema_id; + rtems_isr_entry old_handler; + m360BufferDescriptor_t *rx_bd; + m360BufferDescriptor_t *tx_bd; +} m360_spi_softc_t ; + +typedef struct { + rtems_libi2c_bus_t bus_desc; + m360_spi_softc_t softc; +} m360_spi_desc_t; + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code m360_spi_init +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| initialize the driver | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh /* bus specifier structure */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_read_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| receive some bytes from SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *buf, /* buffer to store bytes */ + int len /* number of bytes to receive */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes received or (negative) error code | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_write_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| send some bytes to SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *buf, /* buffer to send */ + int len /* number of bytes to send */ + + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes sent or (negative) error code | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code m360_spi_set_tfr_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| set SPI to desired baudrate/clock mode/character mode | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| rtems_status_code | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_ioctl +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| perform selected ioctl function for SPI | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + int cmd, /* ioctl command code */ + void *arg /* additional argument array */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| rtems_status_code | +\*=========================================================================*/ + +#ifdef __cplusplus +} +#endif + + +#endif /* _M360_SPIDRV_H */ diff --git a/c/src/lib/libbsp/m68k/gen68360/spi/mc68360_spidrv.c b/c/src/lib/libbsp/m68k/gen68360/spi/mc68360_spidrv.c new file mode 100644 index 0000000000..9a6b01ce27 --- /dev/null +++ b/c/src/lib/libbsp/m68k/gen68360/spi/mc68360_spidrv.c @@ -0,0 +1,627 @@ +/*===============================================================*\ +| Project: RTEMS support for PGH360 | ++-----------------------------------------------------------------+ +| Copyright (c) 2008 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| 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. | +| | ++-----------------------------------------------------------------+ +| this file contains the M360 SPI driver | +\*===============================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code m360_spi_baud_to_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| determine proper divider value | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + uint32_t baudrate, /* desired baudrate */ + uint32_t *spimode /* result value */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + uint32_t divider; + uint16_t tmpmode = 0; + /* + * determine clock divider and DIV16 bit + */ + divider = m360_clock_rate/baudrate; + if (divider > 64) { + tmpmode = M360_SPMODE_DIV16; + divider /= 16; + } + if ((divider < 1) || + (divider > 64)) { + return RTEMS_INVALID_NUMBER; + } + else { + tmpmode |= M360_SPMODE_PM(divider/4-1); + } + *spimode = tmpmode; + return RTEMS_SUCCESSFUL; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static rtems_status_code m360_spi_char_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| determine proper value for character size | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + m360_spi_softc_t *softc_ptr, /* handle */ + uint32_t bits_per_char, /* bits per character */ + boolean lsb_first, /* TRUE: send LSB first */ + uint16_t *spimode /* result value */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + uint32_t tmpmode; + + if (bits_per_char == 32) { + tmpmode = 0; + softc_ptr->bytes_per_char = 4; + softc_ptr->bit_shift = 0; + } + else { + if (lsb_first) { + /* + * non-reversed data (LSB first): 4..16 bits valid + * always aligned to bit 16 of data register + */ + if ((bits_per_char >= 4) && + (bits_per_char <= 16)) { + tmpmode = M360_SPIMODE_LEN( bits_per_char-1); + softc_ptr->bytes_per_char = (bits_per_char > 8) ? 2 : 1; + softc_ptr->bit_shift = 16-bits_per_char; + } + else { + return RTEMS_INVALID_NUMBER; + } + } + else { + /* + * reversed data (MSB first): only 8/16/32 bits valid, + * always in lowest bits of data register + */ + if (bits_per_char == 8) { + tmpmode = M360_SPIMODE_LEN(8-1); + softc_ptr->bytes_per_char = 1; + softc_ptr->bit_shift = 0; + } + else if (bits_per_char == 16) { + tmpmode = M360_SPIMODE_LEN(16-1); + softc_ptr->bytes_per_char = 2; + softc_ptr->bit_shift = 0; + } + else { + return RTEMS_INVALID_NUMBER; + } + } + } + + *spimode = tmpmode; + return 0; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static int m360_spi_wait +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| wait for spi to become idle | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + m360_spi_softc_t *softc_ptr, /* handle */ + uint32_t irq_mask, /* irq mask to use */ + uint32_t desired_status, /* desired status word */ + uint32_t status_mask /* status word mask */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + uint32_t act_status; + rtems_status_code rc; + uint32_t tout; + +#if defined(DEBUG) + printk("m360_spi_wait called... "); +#endif + if (softc_ptr->initialized) { + /* + * allow interrupts, when receiver is not empty + */ + softc_ptr->reg_ptr->spim = irq_mask; + rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,RTEMS_WAIT,100); + if (rc != RTEMS_SUCCESSFUL) { + return rc; + } + } + else { + tout = 0; + do { + if (tout++ > 1000000) { +#if defined(DEBUG) + printk("... exit with RTEMS_TIMEOUT\r\n"); +#endif + return RTEMS_TIMEOUT; + } + /* + * wait for SPI to terminate + */ + } while (!(softc_ptr->reg_ptr->spie & M360_SPIE_NE)); + } + + act_status = softc_ptr->reg_ptr->spie; + if ((act_status & status_mask)!= desired_status) { +#if defined(DEBUG) + printk("... exit with RTEMS_IO_ERROR," + "act_status=0x%04x,mask=0x%04x,desired_status=0x%04x\r\n", + act_status,status_mask,desired_status); +#endif + return RTEMS_IO_ERROR; + } +#if defined(DEBUG) + printk("... exit OK\r\n"); +#endif + return RTEMS_SUCCESSFUL; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static void m360_spi_irq_handler +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| handle interrupts | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_irq_hdl_param handle /* handle, is softc_ptr structure */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = (m360_spi_softc_t *)handle; + + /* + * disable interrupt mask + */ + softc_ptr->reg_ptr->spim = 0; + if (softc_ptr->initialized) { + rtems_semaphore_release(softc_ptr->irq_sema_id); + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +static void m360_spi_install_irq_handler +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| (un-)install the interrupt handler | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + m360_spi_softc_t *softc_ptr, /* ptr to control structure */ + int install /* TRUE: install, FALSE: remove */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| | +\*=========================================================================*/ +{ + rtems_status_code rc = RTEMS_SUCCESSFUL; + + rtems_irq_connect_data irq_conn_data = { + softc_ptr->irq_number, + m360_spi_irq_handler, /* rtems_irq_hdl */ + (rtems_irq_hdl_param)softc_ptr, /* (rtems_irq_hdl_param) */ + m360_spi_irq_on_off, /* (rtems_irq_enable) */ + m360_spi_irq_on_off, /* (rtems_irq_disable) */ + m360_spi_irq_isOn /* (rtems_irq_is_enabled) */ + }; + + /* + * (un-)install handler for SPI device + */ + if (install) { + /* + * create semaphore for IRQ synchronization + */ + rc = rtems_semaphore_create(rtems_build_name('s','p','i','s'), + 0, + RTEMS_FIFO + | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &softc_ptr->irq_sema_id); + if (rc != RTEMS_SUCCESSFUL) { + rtems_panic("SPI: cannot create semaphore"); + } + if (!BSP_install_rtems_irq_handler (&irq_conn_data)) { + rtems_panic("SPI: cannot install IRQ handler"); + } + } + else { + if (!BSP_remove_rtems_irq_handler (&irq_conn_data)) { + rtems_panic("SPI: cannot uninstall IRQ handler"); + } + /* + * delete sync semaphore + */ + if (softc_ptr->irq_sema_id != 0) { + rc = rtems_semaphore_delete(softc_ptr->irq_sema_id); + if (rc != RTEMS_SUCCESSFUL) { + rtems_panic("SPI: cannot delete semaphore"); + } + } + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code m360_spi_init +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| initialize the driver | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh /* bus specifier structure */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| o = ok or error code | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); +#if defined(DEBUG) + printk("m360_spi_init called... "); +#endif + /* + * init HW registers: + */ + /* + * FIXME: set default mode in SPIM + */ + + /* + * FIXME: allocate BDs (1x RX, 1x TX) + */ + + /* + * init interrupt stuff + */ + m360_spi_install_irq_handler(softc_ptr,TRUE); + + /* + * mark, that we have initialized + */ + softc_ptr->initialized = TRUE; +#if defined(DEBUG) + printk("... exit OK\r\n"); +#endif + return RTEMS_SUCCESSFUL; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_read_write_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| transmit/receive some bytes from SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *rbuf, /* buffer to store bytes */ + const unsigned char *tbuf, /* buffer to send bytes */ + int len /* number of bytes to transceive */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes received or (negative) error code | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); + rtems_status_code rc; + int bc = 0; + int bytes_per_char = softc_ptr->bytes_per_char; + int bit_shift = softc_ptr->bit_shift; + uint32_t spird_val; + +#if defined(DEBUG) + printk("m360_spi_read_write_bytes called... "); +#endif + + while (len > bytes_per_char-1) { + len -= bytes_per_char; + /* + * mark last byte in SPCOM + */ +#if defined(USE_LAST_BIT) + softc_ptr->reg_ptr->spcom = (len < bytes_per_char) ? M360_SPCOM_LST : 0; +#else + softc_ptr->reg_ptr->spcom = 0; +#endif + if (tbuf == NULL) { + /* + * perform dummy write to read byte + */ + softc_ptr->reg_ptr->spitd = 0; + } + else { + switch(bytes_per_char) { + case 1: + softc_ptr->reg_ptr->spitd = (*(uint8_t *)tbuf) << bit_shift; + break; + case 2: + softc_ptr->reg_ptr->spitd = (*(uint16_t *)tbuf) << bit_shift; + break; + case 4: + softc_ptr->reg_ptr->spitd = (*(uint32_t *)tbuf) << bit_shift; + break; + } + tbuf += softc_ptr->bytes_per_char; + } + /* + * wait 'til end of transfer + */ +#if defined(USE_LAST_BIT) + rc = m360_spi_wait(softc_ptr, + ((len == 0) + ? M360_SPIE_LT + : M360_SPIE_NE), + ((len == 0) + ? M360_SPIE_LT + : M360_SPIE_NF) + | M360_SPIE_NE, + M360_SPIE_LT + | M360_SPIE_OV + | M360_SPIE_UN + | M360_SPIE_NE + | M360_SPIE_NF); + if (len == 0) { + /* + * clear the "last transfer complete" event + */ + softc_ptr->reg_ptr->spie = M360_SPIE_LT; + } +#else + rc = m360_spi_wait(softc_ptr, + M360_SPIE_NE, + M360_SPIE_NF + | M360_SPIE_NE, + M360_SPIE_OV + | M360_SPIE_UN + | M360_SPIE_NE + | M360_SPIE_NF); +#endif + if (rc != RTEMS_SUCCESSFUL) { +#if defined(DEBUG) + printk("... exit rc=%d\r\n",-rc); +#endif + return -rc; + } + spird_val = softc_ptr->reg_ptr->spird; + if (rbuf != NULL) { + switch(bytes_per_char) { + case 1: + (*(uint8_t *)rbuf) = spird_val >> bit_shift; + break; + case 2: + (*(uint16_t *)rbuf) = spird_val >> bit_shift; + break; + case 4: + (*(uint32_t *)rbuf) = spird_val >> bit_shift; + break; + } + rbuf += bytes_per_char; + } + bc += bytes_per_char; + } +#if defined(DEBUG) + printk("... exit OK, rc=%d\r\n",bc); +#endif + return bc; +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_read_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| receive some bytes from SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *buf, /* buffer to store bytes */ + int len /* number of bytes to receive */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes received or (negative) error code | +\*=========================================================================*/ +{ + return m360_spi_read_write_bytes(bh,buf,NULL,len); +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_write_bytes +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| send some bytes to SPI device | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + unsigned char *buf, /* buffer to send */ + int len /* number of bytes to send */ + +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| number of bytes sent or (negative) error code | +\*=========================================================================*/ +{ + return m360_spi_read_write_bytes(bh,NULL,buf,len); +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +rtems_status_code m360_spi_set_tfr_mode +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| set SPI to desired baudrate/clock mode/character mode | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + const rtems_libi2c_tfr_mode_t *tfr_mode /* transfer mode info */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| rtems_status_code | +\*=========================================================================*/ +{ + m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); + uint32_t spimode_baud,spimode; + rtems_status_code rc = RTEMS_SUCCESSFUL; + /* + * FIXME: set proper mode + */ + if (rc == RTEMS_SUCCESSFUL) { + rc = m360_spi_baud_to_mode(tfr_mode->baudrate,&spimode_baud); + } + if (rc == RTEMS_SUCCESSFUL) { + rc = m360_spi_char_mode(softc_ptr, + tfr_mode->bits_per_char, + tfr_mode->lsb_first, + &spimode); + } + if (rc == RTEMS_SUCCESSFUL) { + spimode |= spimode_baud; + spimode |= M360_SPIMODE_M_S; /* set master mode */ + if (!tfr_mode->lsb_first) { + spimode |= M360_SPIMODE_REV; + } + if (tfr_mode->clock_inv) { + spimode |= M360_SPIMODE_CI; + } + if (tfr_mode->clock_phs) { + spimode |= M360_SPIMODE_CP; + } + } + + if (rc == RTEMS_SUCCESSFUL) { + /* + * disable SPI + */ + softc_ptr->reg_ptr->spmode &= ~M360_SPIMODE_EN; + /* + * set new mode and reenable SPI + */ + softc_ptr->reg_ptr->spmode = spimode | M360_SPIMODE_EN; + } + return rc; +} + + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int m360_spi_ioctl +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| perform selected ioctl function for SPI | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_libi2c_bus_t *bh, /* bus specifier structure */ + int cmd, /* ioctl command code */ + void *arg /* additional argument array */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| rtems_status_code | +\*=========================================================================*/ +{ + int ret_val = -1; + + switch(cmd) { + case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: + ret_val = + -m360_spi_set_tfr_mode(bh, + (const rtems_libi2c_tfr_mode_t *)arg); + break; + case RTEMS_LIBI2C_IOCTL_READ_WRITE: + ret_val = + m360_spi_read_write_bytes(bh, + ((rtems_libi2c_read_write_t *)arg)->rd_buf, + ((rtems_libi2c_read_write_t *)arg)->wr_buf, + ((rtems_libi2c_read_write_t *)arg)->byte_cnt); + break; + default: + ret_val = -RTEMS_NOT_DEFINED; + break; + } + return ret_val; +} + + + diff --git a/c/src/lib/libbsp/m68k/gen68360/startup/init68360.c b/c/src/lib/libbsp/m68k/gen68360/startup/init68360.c index 37fd35f5e2..f1f0f26dce 100644 --- a/c/src/lib/libbsp/m68k/gen68360/startup/init68360.c +++ b/c/src/lib/libbsp/m68k/gen68360/startup/init68360.c @@ -14,6 +14,13 @@ #include #include + +/* + * Declare the m360 structure here for the benefit of the debugger + */ + +volatile m360_t m360; + /* * Send a command to the CPM RISC processer */ @@ -335,6 +342,174 @@ void _Init68360 (void) * BCLRO* arbitration level 3 */ +#elif defined(PGH360) + /* + * Step 6: Is this a power-up reset? + * For now we just ignore this and do *all* the steps + * Someday we might want to: + * if (Hard, Loss of Clock, Power-up) + * Do all steps + * else if (Double bus fault, watchdog or soft reset) + * Skip to step 12 + * else (must be a CPU32+ reset command) + * Skip to step 14 + */ + + /* + * Step 7: Deal with clock synthesizer + * HARDWARE: + * Change if you're not using an external 25 MHz oscillator. + */ + m360.clkocr = 0x8e; /* No more writes, CLKO1=1/3, CLKO2=off */ + /* + * adjust crystal to average between 4.19 MHz and 4.00 MHz + * reprogram pll + */ + m360.pllcr = 0xA000+(24576000/((4000000+4194304)/2/128))-1; + /* LPSTOP slowdown, PLL /128*??? */ + m360.cdvcr = 0x8000; /* No more writes, no clock division */ + + /* + * Step 8: Initialize system protection + * Enable watchdog + * Watchdog causes system reset + * 128 sec. watchdog timeout + * Enable double bus fault monitor + * Enable bus monitor external + * 128 clocks for external timeout + */ + m360.sypcr = 0xEF; + /* + * also initialize the SWP bit in PITR to 1 + */ + m360.pitr |= 0x0200; + /* + * and trigger SWSR twice to ensure, that interval starts right now + */ + m360.swsr = 0x55; + m360.swsr = 0xAA; + m360.swsr = 0x55; + m360.swsr = 0xAA; + /* + * Step 9: Clear parameter RAM and reset communication processor module + */ + for (i = 0 ; i < 192 ; i += sizeof (long)) { + *((long *)((char *)&m360 + 0xC00 + i)) = 0; + *((long *)((char *)&m360 + 0xD00 + i)) = 0; + *((long *)((char *)&m360 + 0xE00 + i)) = 0; + *((long *)((char *)&m360 + 0xF00 + i)) = 0; + } + M360ExecuteRISC (M360_CR_RST); + + /* + * Step 10: Write PEPAR + * SINTOUT not used (CPU32+ mode) + * CF1MODE=00 (CONFIG1 input) + * IPIPE1 + * WE0-3 + * OE* output + * CAS2* / CAS3* + * CAS0* / CAS1* + * CS7* + * AVEC* + * HARDWARE: + * Change if you are using a different memory configuration + * (static RAM, external address multiplexing, etc). + */ + m360.pepar = 0x0080; + /* + * Step 11: Remap Chip Select 0 (CS0*), set up GMR + * no DRAM support + * HARDWARE: + * Change if you are using a different memory configuration + */ + m360.gmr = M360_GMR_RCNT(23) | M360_GMR_RFEN | M360_GMR_RCYC(0) | + M360_GMR_PGS(6) | M360_GMR_DPS_32BIT | M360_GMR_DWQ | + M360_GMR_GAMX; + + m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP | + M360_MEMC_BR_V; + m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_512KB | + M360_MEMC_OR_8BIT; + + /* + * Step 12: Initialize the system RAM + * Set up option/base registers + * 16 MB DRAM + * 1 wait state + * HARDWARE: + * Change if you are using a different memory configuration + * NOTE: no Page mode possible for EDO RAMs (?) + */ + ramSize = 16 * 1024 * 1024; + m360.memc[7].or = M360_MEMC_OR_TCYC(1) | M360_MEMC_OR_16MB | + M360_MEMC_OR_FCMC(0) | /* M360_MEMC_OR_PGME | */ + M360_MEMC_OR_32BIT | M360_MEMC_OR_DRAM; + m360.memc[7].br = (unsigned long)&_RamBase | M360_MEMC_BR_V; + + /* + * FIXME: here we should wait for 8 refresh cycles... + */ + /* + * Step 12a: test the ram, if wanted + * FIXME: when do we call this? + * -> only during firmware execution + * -> perform intesive test only on request + * -> ensure, that results are stored properly + */ +#if 0 /* FIXME: activate RAM tests again */ + { + void *ram_base, *ram_end, *code_loc; + extern char ramtest_start,ramtest_end; + ram_base = &ramtest_start; + ram_end = &ramtest_end; + code_loc = (void *)ramtest_exec; + if ((ram_base < ram_end) && + !((ram_base <= code_loc) && (code_loc < ram_end))) { + ramtest_exec(ram_base,ram_end); + } + } +#endif + /* + * Step 13: Copy the exception vector table to system RAM + */ + m68k_get_vbr (vbr); + for (i = 0; i < 256; ++i) + M68Kvec[i] = vbr[i]; + m68k_set_vbr (M68Kvec); + + /* + * Step 14: More system initialization + * SDCR (Serial DMA configuration register) + * Disable SDMA during FREEZE + * Give SDMA priority over all interrupt handlers + * Set DMA arbiration level to 4 + * CICR (CPM interrupt configuration register): + * SCC1 requests at SCCa position + * SCC2 requests at SCCb position + * SCC3 requests at SCCc position + * SCC4 requests at SCCd position + * Interrupt request level 4 + * Maintain original priority order + * Vector base 128 + * SCCs priority grouped at top of table + */ + m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4; + m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) | + (4 << 13) | (0x1F << 8) | (128); + + /* + * Step 15: Set module configuration register + * Disable timers during FREEZE + * Enable bus monitor during FREEZE + * BCLRO* arbitration level 3 + * No show cycles + * User/supervisor access + * Bus clear interupt service level 7 + * SIM60 interrupt sources higher priority than CPM + */ + m360.mcr = 0x4C7F; + #elif (defined (GEN68360_WITH_SRAM)) /* *************************************************** diff --git a/c/src/lib/libbsp/m68k/genmcf548x/ChangeLog b/c/src/lib/libbsp/m68k/genmcf548x/ChangeLog new file mode 100644 index 0000000000..7e83e88ad8 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/ChangeLog @@ -0,0 +1,14 @@ +2008-07-10 Peter Rasmussen + + * Makefile.am, preinstall.am, + bsp_specs, ChangeLog, + README, + clock/clock.c, + console/console.c, + include/bsp.h, + include/coverhd.h, include/tm27.h, + network/network.c, + start/start.S, + startup/bspclean.c, + startup/bspstart.c, startup/init548x.c, + startup/linkcmds, startup/linkcmds.m5484FireEngine.flash: New files. diff --git a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am new file mode 100644 index 0000000000..d869a8dd71 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am @@ -0,0 +1,73 @@ +## +## $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 + +noinst_PROGRAMS += startup.rel +startup_rel_SOURCES = startup/bspclean.c \ + ../../shared/bsplibc.c ../../shared/bsppost.c \ + ../../m68k/shared/m68kpretaskinghook.c \ + startup/init548x.c startup/bspstart.c \ + ../../shared/bootcard.c \ + ../../shared/sbrk.c ../../m68k/shared/setvec.c \ + ../../shared/gnatinstallhandler.c +startup_rel_CPPFLAGS = $(AM_CPPFLAGS) +startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += clock.rel +clock_rel_SOURCES = clock/clock.c +clock_rel_CPPFLAGS = $(AM_CPPFLAGS) +clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += console.rel +console_rel_SOURCES = console/console.c +console_rel_CPPFLAGS = $(AM_CPPFLAGS) +console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += timer.rel +timer_rel_SOURCES = timer/timer.c +timer_rel_CPPFLAGS = $(AM_CPPFLAGS) +timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +if HAS_NETWORKING +network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ +noinst_PROGRAMS += network.rel +network_rel_SOURCES = network/network.c +network_rel_CPPFLAGS = $(AM_CPPFLAGS) \ + $(network_CPPFLAGS) +network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +endif + +noinst_LIBRARIES = libbsp.a +libbsp_a_SOURCES = +libbsp_a_LIBADD = startup.rel clock.rel console.rel timer.rel +if HAS_NETWORKING +libbsp_a_LIBADD += network.rel +endif +libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cache.rel \ + ../../../libcpu/@RTEMS_CPU@/shared/misc.rel + +include $(srcdir)/preinstall.am +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/m68k/genmcf548x/README b/c/src/lib/libbsp/m68k/genmcf548x/README new file mode 100644 index 0000000000..0d4fce064f --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/README @@ -0,0 +1,180 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: README | ++-----------------------------------------------------------------+ +| This is the README for the generic MCF548x BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + + +Description: Generic mcf548x BSP +============ +CPU: MCF548x, 200MHz +XLB: 100 MHz, which is the main clock for all onchip peripherals +RAM: 64M (m5484FireEngine) +Boot-Flash: 2M (m5484FireEngine) +Code-Flash: 16M (m5484FireEngine) +Core-SRAM: 8K +Core-SysRAM: 32K + + +The genmcf548x supports the Fresscale m5484FireEngine EVB. + +ACKNOWLEDGEMENTS: +================= +This BSP is based on the + + av5282 BSP + +and the work of + + D. Peter Siddons + Brett Swimley + Jay Monkman + Eric Norum + Mike Bertosh + +BSP INFO: +========= +BSP NAME: genmcf548x +BOARD: m5484FireEngine (freescale), +CPU FAMILY: ColdFire 548x +CPU: MCF5484 +FPU: MCF548x FPU, context switch supported by RTEMS multitasking +EMAC: MCF548x EMAC context switch supported by RTEMS multitasking (handeld together with FPU context) + +PERIPHERALS +=========== +TIMERS: 2 slice timers, 4 general purpose timers (SLT0 is used for RTEMS clock, SLT1 is used for diagnostic pupose) +RESOLUTION: System tick 10 millieconds (via SLT0) +SERIAL PORTS: Internal PSC 0-3 +NETWORKING: Internal 10/100MHz FEC (not supported yet) + +DRIVER INFORMATION +================== +CLOCK DRIVER: SLT0 +TIMER DRIVER: SLT1 (diagnostics) +TTY DRIVER: PSC0-3 + +STDIO +===== +PORT: PSC0 (UART mode) terminal +ELECTRICAL: RS-232 +BAUD: 9600 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 +MODES: Interrupt driven (polled mode alternatively) + + + Memory map as set up by BSP initialization + +m5484FireEngine: + + +--------------------------------------------------+ +0000 0000 | 64 MByte SDRAM (external) | 03FF FFFF + . . + . . + . . + + +m5484FireEngine: + + + | | 0FFF FFFF + +--------------------------------------------------+ +1000 0000 | internal per. registers via MBAR | 1003 FFFF + . . + . . + . . + | | + +--------------------------------------------------+ +2000 0000 | 8K core SRAM (internal) | 2000 1FFF + . . + . . + . . + +m5484FireEngine: + + | | + +--------------------------------------------------+ +E000 0000 | 16M code flash (external) | E0FF FFFF + . . + . . + . . + | | + +--------------------------------------------------+ +FF80 0000 | External 8 MByte Flash memory | FF9F FFFF + . . + . . + . . + | | FFFF FFFF + +--------------------------------------------------+ + +============================================================================ + + Interrupt map + ++-----+-----------------------------------------------------------------------+ +| | PRIORITY | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +|LEVEL| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 7 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 6 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 5 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 4 | | | | | | | | SLT0 | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 3 | PSC 0 | PSC 1 | PSC 2 | PSC 3 | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 2 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ +| 1 | | | | | | | | | ++-----+--------+--------+--------+--------+--------+--------+--------+--------+ + +============================================================================ + +TIMING TESTS +************************** + +tbd. diff --git a/c/src/lib/libbsp/m68k/genmcf548x/aclocal.m4 b/c/src/lib/libbsp/m68k/genmcf548x/aclocal.m4 new file mode 100644 index 0000000000..59fd247975 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/aclocal.m4 @@ -0,0 +1,940 @@ +# generated automatically by aclocal 1.10.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(AC_AUTOCONF_VERSION, [2.62],, +[m4_warning([this file was generated for autoconf 2.62. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.10.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) + +# Figure out how to run the assembler. -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_PROG_AS +# ---------- +AC_DEFUN([AM_PROG_AS], +[# By default we simply use the C compiler to build assembly code. +AC_REQUIRE([AC_PROG_CC]) +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS +AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)]) +AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)]) +_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 13 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.60])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([../../../../aclocal/bsp-configure.m4]) +m4_include([../../../../aclocal/bspopts.m4]) +m4_include([../../../../aclocal/canonical-target-name.m4]) +m4_include([../../../../aclocal/canonicalize-tools.m4]) +m4_include([../../../../aclocal/check-custom-bsp.m4]) +m4_include([../../../../aclocal/check-multiprocessing.m4]) +m4_include([../../../../aclocal/check-networking.m4]) +m4_include([../../../../aclocal/check-tool.m4]) +m4_include([../../../../aclocal/enable-multiprocessing.m4]) +m4_include([../../../../aclocal/enable-networking.m4]) +m4_include([../../../../aclocal/env-rtemsbsp.m4]) +m4_include([../../../../aclocal/gcc-isystem.m4]) +m4_include([../../../../aclocal/gcc-pipe.m4]) +m4_include([../../../../aclocal/gcc-specs.m4]) +m4_include([../../../../aclocal/multilib.m4]) +m4_include([../../../../aclocal/prog-cc.m4]) +m4_include([../../../../aclocal/prog-ccas.m4]) +m4_include([../../../../aclocal/project-root.m4]) +m4_include([../../../../aclocal/rtems-ampolish.m4]) +m4_include([../../../../aclocal/rtems-top.m4]) +m4_include([../../../../aclocal/version.m4]) diff --git a/c/src/lib/libbsp/m68k/genmcf548x/bsp_specs b/c/src/lib/libbsp/m68k/genmcf548x/bsp_specs new file mode 100644 index 0000000000..4a5560b651 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/bsp_specs @@ -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} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c b/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c new file mode 100644 index 0000000000..47738b5cc2 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c @@ -0,0 +1,104 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: clock.c | ++-----------------------------------------------------------------+ +| The file contains the clock driver code of generic MCF548x BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +/* + * Use first slice timer (SLT0) as the system clock. + * + */ + +#include +#include +#include + +/* + * Use SLT 0 + */ +#define CLOCK_VECTOR (64+54) + +/* + * Periodic interval timer interrupt handler + */ +#define Clock_driver_support_at_tick() \ + do { \ + MCF548X_SLT_SSR0 = MCF548X_SLT_SSR_ST; \ + } while (0) \ + +/* + * Attach clock interrupt handler + */ +#define Clock_driver_support_install_isr( _new, _old ) \ + do { \ + _old = (rtems_isr_entry)set_vector(_new, CLOCK_VECTOR, 1); \ + } while(0) + +/* + * Turn off the clock + */ +#define Clock_driver_support_shutdown_hardware() \ + do { \ + MCF548X_SLT_SCR0 &= ~(MCF548X_SLT_SCR_TEN | MCF548X_SLT_SCR_RUN | MCF548X_SLT_SCR_IEN); \ + } while(0) + +/* + * Set up the clock hardware + * + * We need to have 1 interrupt every 10,000 microseconds + * XLB clock 100 MHz / MCF548X_SLT_SLTCNT0 = XLB clock/100 + */ +#define Clock_driver_support_initialize_hardware() \ + do { \ + int level; \ + MCF548X_INTC_ICR54 = MCF548X_INTC_ICRn_IL(SLT0_IRQ_LEVEL) | \ + MCF548X_INTC_ICRn_IP(SLT0_IRQ_PRIORITY); \ + rtems_interrupt_disable( level ); \ + MCF548X_INTC_IMRH &= ~(MCF548X_INTC_IMRH_INT_MASK54 | \ + MCF548X_INTC_IMRL_MASKALL); \ + rtems_interrupt_enable( level ); \ + MCF548X_SLT_SLTCNT0 = get_CPU_clock_speed()/100; \ + MCF548X_SLT_SCR0 |= (MCF548X_SLT_SCR_TEN | MCF548X_SLT_SCR_RUN | MCF548X_SLT_SCR_IEN); \ + } while (0) + +#include "../../../shared/clockdrv_shell.c" + diff --git a/c/src/lib/libbsp/m68k/genmcf548x/configure.ac b/c/src/lib/libbsp/m68k/genmcf548x/configure.ac new file mode 100644 index 0000000000..9c332f9ede --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/configure.ac @@ -0,0 +1,29 @@ +## Process this file with autoconf to produce a configure script. +## +## $Id$ + +AC_PREREQ(2.60) +AC_INIT([rtems-c-src-lib-libbsp-m68k-genmcf548x],[_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_CHECK_NETWORKING + +AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") + +RTEMS_BSPOPTS_SET([BSP_CPU_CLOCK_SPEED],[m5484FireEngine],[100000000]) +RTEMS_BSPOPTS_SET([BSP_CPU_CLOCK_SPEED],[*],[100000000]) +RTEMS_BSPOPTS_HELP([BSP_CPU_CLOCK_SPEED], +[Use a clock speed of 100000000 for the m5484FireEngine board]) + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/c/src/lib/libbsp/m68k/genmcf548x/console/console.c b/c/src/lib/libbsp/m68k/genmcf548x/console/console.c new file mode 100644 index 0000000000..600641eab2 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/console/console.c @@ -0,0 +1,886 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: console.c | ++-----------------------------------------------------------------+ +| The file contains the console driver code of generic MCF548x | +| BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+35-(x)) + +#define MCF548X_PSC_SR_ERROR ( MCF548X_PSC_SR_RB_NEOF | \ + MCF548X_PSC_SR_FE_PHYERR | \ + MCF548X_PSC_SR_PE_CRCERR | \ + MCF548X_PSC_SR_OE ) + +static int IntUartPollWrite(int minor, const char *buf, int len); +static int IntUartPollRead (int minor); + +static void +_BSP_null_char( char c ) +{ + int level; + + if (c == '\n') + _BSP_null_char('\r'); + rtems_interrupt_disable(level); + while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) + continue; + *((uint8_t *) &MCF548X_PSC_TB(CONSOLE_PORT)) = c; + while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) + continue; + rtems_interrupt_enable(level); +} +BSP_output_char_function_type BSP_output_char = _BSP_null_char; + +#define MAX_UART_INFO 4 +#define RX_BUFFER_SIZE 248 + + +struct IntUartInfoStruct +{ + int iomode; + volatile int imr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +static int GetBaud( int baudHandle ) +{ + int baud = 9600; + switch(baudHandle) + { + case B0: + baud = (int)0; + break; + case B1200: + baud = (int)1200; + break; + case B2400: + baud = (int)2400; + break; + case B4800: + baud = (int)4800; + break; + case B9600: + baud = (int)9600; + break; + case B19200: + baud = (int)19200; + break; + case B38400: + baud = (int)38400; + break; + case B57600: + baud = (int)57600; + break; + case B115200: + baud = (int)115200; + break; + } + return baud; +} + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) +{ + uint8_t psc_mode_1 = 0, psc_mode_2 = 0; + uint16_t divider; + int level; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + rtems_interrupt_disable(level); + + /* disable interrupts, clear RTS line, and disable the UARTS */ + /* Mask all psc interrupts */ + MCF548X_PSC_IMR(minor) = 0x0000; + + /* Clear RTS to send */ + MCF548X_PSC_OPSET(minor) &= ~(MCF548X_PSC_OPSET_RTS); + + /* Disable receiver and transmitter */ + MCF548X_PSC_CR(minor) &= ~(MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); + + /* provide gpio settings */ + switch (minor) + { + case 0: + MCF548X_GPIO_PAR_PSC0 = (0 | MCF548X_GPIO_PAR_PSC0_PAR_TXD0 | MCF548X_GPIO_PAR_PSC0_PAR_RXD0); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC0 |= (0 | MCF548X_GPIO_PAR_PSC0_PAR_CTS0_CTS | MCF548X_GPIO_PAR_PSC0_PAR_RTS0_RTS); + } + break; + case 1: + MCF548X_GPIO_PAR_PSC1 = (0 | MCF548X_GPIO_PAR_PSC1_PAR_TXD1 | MCF548X_GPIO_PAR_PSC1_PAR_RXD1); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC1 |= (0 | MCF548X_GPIO_PAR_PSC1_PAR_CTS1_CTS | MCF548X_GPIO_PAR_PSC1_PAR_RTS1_RTS); + } + break; + case 2: + MCF548X_GPIO_PAR_PSC2 = (0 | MCF548X_GPIO_PAR_PSC2_PAR_TXD2 | MCF548X_GPIO_PAR_PSC2_PAR_RXD2); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC2 |= (0 | MCF548X_GPIO_PAR_PSC2_PAR_CTS2_CTS | MCF548X_GPIO_PAR_PSC2_PAR_RTS2_RTS); + } + break; + case 3: + MCF548X_GPIO_PAR_PSC3 = (0 | MCF548X_GPIO_PAR_PSC3_PAR_TXD3 | MCF548X_GPIO_PAR_PSC3_PAR_RXD3); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC3 |= (0 | MCF548X_GPIO_PAR_PSC3_PAR_CTS3_CTS | MCF548X_GPIO_PAR_PSC3_PAR_RTS3_RTS); + } + break; + default: + break; + } + + /* save the current values */ + info->imr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + /* Put PSC in UART mode */ + MCF548X_PSC_SICR(minor) = MCF548X_PSC_SICR_SIM_UART; + + /* set the baud rate values */ + MCF548X_PSC_CSR(minor) = (0 | MCF548X_PSC_CSR_RCSEL_SYS_CLK | MCF548X_PSC_CSR_TCSEL_SYS_CLK); + + /* Calculate baud settings */ + divider = (uint16_t)((get_CPU_clock_speed())/(baud * 32)); + MCF548X_PSC_CTUR(minor) = (uint8_t) ((divider >> 8) & 0xFF); + MCF548X_PSC_CTLR(minor) = (uint8_t) (divider & 0xFF); + + /* Reset transmitter, receiver, mode register, and error conditions */ + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_RX; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_TX; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_ERROR; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_BKCHGINT; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_MR; + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* set hardware flow options */ + psc_mode_1 = MCF548X_PSC_MR_RXRTS; + psc_mode_2 = MCF548X_PSC_MR_TXCTS; + } + + /* set mode registers */ + psc_mode_1 |= (uint8_t)(parity | databits); + psc_mode_2 |= (uint8_t)(stopbits); + + /* set mode registers */ + MCF548X_PSC_MR(minor) = psc_mode_1; + MCF548X_PSC_MR(minor) = psc_mode_2; + + /* Setup FIFO Alarms */ + MCF548X_PSC_RFAR(minor) = MCF548X_PSC_RFAR_ALARM(248); + MCF548X_PSC_TFAR(minor) = MCF548X_PSC_TFAR_ALARM(248); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->imr |= MCF548X_PSC_IMR_RXRDY_FU; + MCF548X_PSC_IMR(minor) = info->imr; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* assert the RTS line */ + MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; + } + + rtems_interrupt_enable(level); + + /* Enable receiver and transmitter */ + MCF548X_PSC_CR(minor) =(0 | MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); + + +} + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int +IntUartSetAttributes(int minor, const struct termios *t) +{ +/* set default index values */ + int baud = (int)9600; + int databits = (int)MCF548X_PSC_MR_BC_8; + int parity = (int)MCF548X_PSC_MR_PM_NONE; + int stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_1; + int hwflow = (int)1; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if ( t != (const struct termios *)0 ) + { + /* determine baud rate index */ + baud = GetBaud( t->c_cflag & CBAUD ); + + /* determine data bits */ + switch ( t->c_cflag & CSIZE ) + { + case CS5: + databits = (int)MCF548X_PSC_MR_BC_5; + break; + case CS6: + databits = (int)MCF548X_PSC_MR_BC_6; + break; + case CS7: + databits = (int)MCF548X_PSC_MR_BC_7; + break; + case CS8: + databits = (int)MCF548X_PSC_MR_BC_8; + break; + } + + /* determine if parity is enabled */ + if ( t->c_cflag & PARENB ) + { + if ( t->c_cflag & PARODD ) + { + /* odd parity */ + parity = (int)MCF548X_PSC_MR_PM_ODD; + } + else + { + /* even parity */ + parity = (int)MCF548X_PSC_MR_PM_EVEN; + } + } + + /* determine stop bits */ + if ( t->c_cflag & CSTOPB ) + { + /* two stop bits */ + stopbits = (int)MCF548X_PSC_MR_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 ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_RXRDY_FU ) + { + /* read data and put into the receive buffer */ + while ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_RXRDY ) + { + + /* put data in rx buffer */ + info->rx_buffer[info->rx_in] = *((uint8_t *)&MCF548X_PSC_RB(chan)); + + /* check for errors */ + if ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_ERROR ) + { + /* clear the error */ + MCF548X_PSC_CR(chan) = MCF548X_PSC_CR_RESET_ERROR; + } + + /* 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->imr & MCF548X_PSC_IMR_TXRDY ) && + ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_TXRDY ) ) + { + + /* disable tx interrupts */ + info->imr &= ~MCF548X_PSC_IMR_TXRDY; + MCF548X_PSC_IMR(chan) = info->imr; + + /* 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; + + MCF548X_PSC_ACR(chan) = 0; + MCF548X_PSC_IMR(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: + MCF548X_INTC_ICR35 = MCF548X_INTC_ICRn_IL(PSC0_IRQ_LEVEL) | + MCF548X_INTC_ICRn_IP(PSC0_IRQ_PRIORITY); + MCF548X_INTC_IMRH &= ~(MCF548X_INTC_IMRH_INT_MASK35 | + MCF548X_INTC_IMRL_MASKALL); + break; + + case 1: + MCF548X_INTC_ICR34 = MCF548X_INTC_ICRn_IL(PSC1_IRQ_LEVEL) | + MCF548X_INTC_ICRn_IP(PSC1_IRQ_PRIORITY); + MCF548X_INTC_IMRH &= ~(MCF548X_INTC_IMRH_INT_MASK34 | + MCF548X_INTC_IMRL_MASKALL); + break; + + case 2: + MCF548X_INTC_ICR33 = MCF548X_INTC_ICRn_IL(PSC2_IRQ_LEVEL) | + MCF548X_INTC_ICRn_IP(PSC2_IRQ_PRIORITY); + MCF548X_INTC_IMRH &= ~(MCF548X_INTC_IMRH_INT_MASK33 | + MCF548X_INTC_IMRL_MASKALL); + break; + + case 3: + MCF548X_INTC_ICR32 = MCF548X_INTC_ICRn_IL(PSC3_IRQ_LEVEL) | + MCF548X_INTC_ICRn_IP(PSC3_IRQ_PRIORITY); + MCF548X_INTC_IMRH &= ~(MCF548X_INTC_IMRH_INT_MASK32 | + MCF548X_INTC_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + + +} /* IntUartInitialise */ + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static int +IntUartInterruptWrite (int minor, const char *buf, int len) +{ + int level; + + rtems_interrupt_disable(level); + + /* write out character */ + MCF548X_PSC_TB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].imr |= MCF548X_PSC_IMR_TXRDY; + MCF548X_PSC_IMR(minor) = IntUartInfo[minor].imr; + + 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 */ + MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->imr |= MCF548X_PSC_IMR_RXRDY_FU; + MCF548X_PSC_IMR(minor) = info->imr; + } + + /* check to see if doing hardware flow control */ + if ( info->hwflow ) + { + /* assert the RTS line */ + MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; + } + + 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 */ + MCF548X_PSC_IMR(minor) = 0; + MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); + + /* reset values */ + info->ttyp = NULL; + info->imr = 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 (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_RXRDY))) + return(-1); + + return *((uint8_t *)&MCF548X_PSC_RB(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 (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_TXRDY))) + continue; + /* transmit data byte */ + *((uint8_t *)&MCF548X_PSC_TB(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; //TERMIOS_POLLED; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + + /* Register the other port */ + if ( CONSOLE_PORT != 0 ) + { + status = rtems_io_register_name ("/dev/tty00", major, 0); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + if ( CONSOLE_PORT != 1 ) + { + status = rtems_io_register_name ("/dev/tty01", major, 1); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + + return(RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) + { + info = &IntUartInfo[minor]; + switch ( info->iomode ) + { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + return( status ); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_close (arg)); +} + +/*************************************************************************** + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_read (arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_write (arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return( rtems_termios_ioctl (arg) ); +} + + +int DEBUG_OUTCHAR(int c) +{ + if(c == '\n') + DEBUG_OUTCHAR('\r'); + _BSP_null_char(c); + return c; +} +void DEBUG_OUTSTR(const char *msg) +{ + while (*msg) + DEBUG_OUTCHAR(*msg++); +} +void DEBUG_OUTNUM(int i) +{ + int n; + static const char map[] = "0123456789ABCDEF"; + DEBUG_OUTCHAR(' '); + for (n = 28 ; n >= 0 ; n -= 4) + DEBUG_OUTCHAR(map[(i >> n) & 0xF]); +} + diff --git a/c/src/lib/libbsp/m68k/genmcf548x/include/bsp.h b/c/src/lib/libbsp/m68k/genmcf548x/include/bsp.h new file mode 100644 index 0000000000..c23b91554f --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/include/bsp.h @@ -0,0 +1,136 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: bsp.h | ++-----------------------------------------------------------------+ +| The file contains the BSP header of generic MCF548x BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +#ifndef __GENMCF548X_BSP_H +#define __GENMCF548X_BSP_H + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#include +#include +#include +#include +#include +#include + +/***************************************************************************/ +/** Hardware data structure headers **/ +#include + +/***************************************************************************/ +/** Network driver configuration **/ +struct rtems_bsdnet_ifconfig; +extern int rtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching ); +#define RTEMS_BSP_NETWORK_DRIVER_NAME "fs1" +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_fec_driver_attach + +/***************************************************************************/ +/** User Definable configuration **/ + +/* define which port the console should use - all other ports are then defined as general purpose */ +#define CONSOLE_PORT 0 + +#define RAM_END 0x4000000 /* 64 MB */ + +/* externals */ + +/* constants */ + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + + +/* functions */ + +uint32_t get_CPU_clock_speed(void); +void bsp_cleanup(void); + +m68k_isr_entry set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +/* + * Interrupt assignments + * Highest-priority listed first + */ +#define FEC_IRQ_LEVEL 4 +#define FEC_IRQ_RX_PRIORITY 7 +#define FEC_IRQ_TX_PRIORITY 6 + +#define SLT0_IRQ_LEVEL 4 +#define SLT0_IRQ_PRIORITY 0 + +#define PSC0_IRQ_LEVEL 3 +#define PSC0_IRQ_PRIORITY 7 +#define PSC1_IRQ_LEVEL 3 +#define PSC1_IRQ_PRIORITY 6 +#define PSC2_IRQ_LEVEL 3 +#define PSC2_IRQ_PRIORITY 5 +#define PSC3_IRQ_LEVEL 3 +#define PSC3_IRQ_PRIORITY 4 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/m68k/genmcf548x/include/bspopts.h.in b/c/src/lib/libbsp/m68k/genmcf548x/include/bspopts.h.in new file mode 100644 index 0000000000..65492dfa5e --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/include/bspopts.h.in @@ -0,0 +1,19 @@ +/* include/bspopts.h.in. Generated from configure.ac by autoheader. */ + +/* Use a clock speed of 100000000 for the m5484FireEngine board */ +#undef BSP_CPU_CLOCK_SPEED + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION diff --git a/c/src/lib/libbsp/m68k/genmcf548x/include/coverhd.h b/c/src/lib/libbsp/m68k/genmcf548x/include/coverhd.h new file mode 100644 index 0000000000..a0aaa20535 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/include/coverhd.h @@ -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 diff --git a/c/src/lib/libbsp/m68k/genmcf548x/include/tm27.h b/c/src/lib/libbsp/m68k/genmcf548x/include/tm27.h new file mode 100644 index 0000000000..f8fe447335 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/include/tm27.h @@ -0,0 +1,29 @@ +/* + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef _RTEMS_TMTEST27 +#error "This is an RTEMS internal file you must not include directly." +#endif + +#ifndef __tm27_h +#define __tm27_h + +/* + * Stuff for Time Test 27 + * Don't bother with hardware -- just use a software-interrupt + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 35, 1 ) + +#define Cause_tm27_intr() asm volatile ("trap #3"); + +#define Clear_tm27_intr() /* empty */ + +#define Lower_tm27_intr() /* empty */ + +#endif diff --git a/c/src/lib/libbsp/m68k/genmcf548x/network/network.c b/c/src/lib/libbsp/m68k/genmcf548x/network/network.c new file mode 100644 index 0000000000..ad26e2ca78 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/network/network.c @@ -0,0 +1,20 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include diff --git a/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am b/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am new file mode 100644 index 0000000000..48b2c6e3f3 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/preinstall.am @@ -0,0 +1,58 @@ +## 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 + diff --git a/c/src/lib/libbsp/m68k/genmcf548x/start/start.S b/c/src/lib/libbsp/m68k/genmcf548x/start/start.S new file mode 100644 index 0000000000..6be143be8e --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/start/start.S @@ -0,0 +1,436 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: start.S | ++-----------------------------------------------------------------+ +| The file contains the assembly part of MCF548x init code | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +/*===============================================================*\ +| Includes | +\*===============================================================*/ +#include + +/*===============================================================*\ +| External references | +\*===============================================================*/ +.extern __MBAR +.extern _CoreSramBase0 +.extern _CoreSramBase1 +.extern _CoreSramSize1 +.extern mcf548x_init +.extern boot_card +.extern _SpInit +.extern _InitPc + +/*===============================================================*\ +| Global symbols | +\*===============================================================*/ + +.global interrupt_vector_table +.global spurious_int_count +.global start + + +/*===============================================================*\ +| Exception Table | +\*===============================================================*/ + +.section ".vectors","ax" /* begin of vectors section */ +PUBLIC (InterruptVectorTable) +SYM(InterruptVectorTable): +INITSP: .long _SpInit /* Initial SP */ +INITPC: .long _InitPc /* Initial PC */ +vector002: .long asm_default_interrupt /* Access Error */ +vector003: .long asm_default_interrupt /* Address Error */ +vector004: .long asm_default_interrupt /* Illegal Instruction */ +vector005: .long asm_default_interrupt /* Reserved */ +vector006: .long asm_default_interrupt /* Reserved */ +vector007: .long asm_default_interrupt /* Reserved */ +vector008: .long asm_default_interrupt /* Privilege Violation */ +vector009: .long asm_default_interrupt /* Trace */ +vector010: .long asm_default_interrupt /* Unimplemented A-Line */ +vector011: .long asm_default_interrupt /* Unimplemented F-Line */ +vector012: .long asm_default_interrupt /* Debug Interrupt */ +vector013: .long asm_default_interrupt /* Reserved */ +vector014: .long asm_default_interrupt /* Format Error */ +vector015: .long asm_default_interrupt /* Unitialized Int. */ +vector016: .long asm_default_interrupt /* Reserved */ +vector017: .long asm_default_interrupt /* Reserved */ +vector018: .long asm_default_interrupt /* Reserved */ +vector019: .long asm_default_interrupt /* Reserved */ +vector020: .long asm_default_interrupt /* Reserved */ +vector021: .long asm_default_interrupt /* Reserved */ +vector022: .long asm_default_interrupt /* Reserved */ +vector023: .long asm_default_interrupt /* Reserved */ +vector024: .long asm_spurious_interrupt /* Spurious Interrupt */ +vector025: .long asm_default_interrupt /* Autovector Level 1 */ +vector026: .long asm_default_interrupt /* Autovector Level 2 */ +vector027: .long asm_default_interrupt /* Autovector Level 3 */ +vector028: .long asm_default_interrupt /* Autovector Level 4 */ +vector029: .long asm_default_interrupt /* Autovector Level 5 */ +vector030: .long asm_default_interrupt /* Autovector Level 6 */ +vector031: .long asm_default_interrupt /* Autovector Level 7 */ +vector032: .long asm_default_interrupt /* TRAP #0 */ +vector033: .long asm_default_interrupt /* TRAP #1 */ +vector034: .long asm_default_interrupt /* TRAP #2 */ +vector035: .long asm_default_interrupt /* TRAP #3 */ +vector036: .long asm_default_interrupt /* TRAP #4 */ +vector037: .long asm_default_interrupt /* TRAP #5 */ +vector038: .long asm_default_interrupt /* TRAP #6 */ +vector039: .long asm_default_interrupt /* TRAP #7 */ +vector040: .long asm_default_interrupt /* TRAP #8 */ +vector041: .long asm_default_interrupt /* TRAP #9 */ +vector042: .long asm_default_interrupt /* TRAP #10 */ +vector043: .long asm_default_interrupt /* TRAP #11 */ +vector044: .long asm_default_interrupt /* TRAP #12 */ +vector045: .long asm_default_interrupt /* TRAP #13 */ +vector046: .long asm_default_interrupt /* TRAP #14 */ +vector047: .long asm_default_interrupt /* TRAP #15 */ +vector048: .long asm_default_interrupt /* Reserved */ +vector049: .long asm_default_interrupt /* Reserved */ +vector050: .long asm_default_interrupt /* Reserved */ +vector051: .long asm_default_interrupt /* Reserved */ +vector052: .long asm_default_interrupt /* Reserved */ +vector053: .long asm_default_interrupt /* Reserved */ +vector054: .long asm_default_interrupt /* Reserved */ +vector055: .long asm_default_interrupt /* Reserved */ +vector056: .long asm_default_interrupt /* Reserved */ +vector057: .long asm_default_interrupt /* Reserved */ +vector058: .long asm_default_interrupt /* Reserved */ +vector059: .long asm_default_interrupt /* Reserved */ +vector060: .long asm_default_interrupt /* Reserved */ +vector061: .long asm_default_interrupt /* Reserved */ +vector062: .long asm_default_interrupt /* Reserved */ +vector063: .long asm_default_interrupt /* Reserved */ +vector064: .long asm_default_interrupt +vector065: .long asm_default_interrupt +vector066: .long asm_default_interrupt +vector067: .long asm_default_interrupt +vector068: .long asm_default_interrupt +vector069: .long asm_default_interrupt +vector070: .long asm_default_interrupt +vector071: .long asm_default_interrupt +vector072: .long asm_default_interrupt +vector073: .long asm_default_interrupt +vector074: .long asm_default_interrupt +vector075: .long asm_default_interrupt +vector076: .long asm_default_interrupt +vector077: .long asm_default_interrupt +vector078: .long asm_default_interrupt +vector079: .long asm_default_interrupt +vector080: .long asm_default_interrupt +vector081: .long asm_default_interrupt +vector082: .long asm_default_interrupt +vector083: .long asm_default_interrupt +vector084: .long asm_default_interrupt +vector085: .long asm_default_interrupt +vector086: .long asm_default_interrupt +vector087: .long asm_default_interrupt +vector088: .long asm_default_interrupt +vector089: .long asm_default_interrupt +vector090: .long asm_default_interrupt +vector091: .long asm_default_interrupt +vector092: .long asm_default_interrupt +vector093: .long asm_default_interrupt +vector094: .long asm_default_interrupt +vector095: .long asm_default_interrupt +vector096: .long asm_default_interrupt +vector097: .long asm_default_interrupt +vector098: .long asm_default_interrupt +vector099: .long asm_default_interrupt +vector100: .long asm_default_interrupt +vector101: .long asm_default_interrupt +vector102: .long asm_default_interrupt +vector103: .long asm_default_interrupt +vector104: .long asm_default_interrupt +vector105: .long asm_default_interrupt +vector106: .long asm_default_interrupt +vector107: .long asm_default_interrupt +vector108: .long asm_default_interrupt +vector109: .long asm_default_interrupt +vector110: .long asm_default_interrupt +vector111: .long asm_default_interrupt +vector112: .long asm_default_interrupt +vector113: .long asm_default_interrupt +vector114: .long asm_default_interrupt +vector115: .long asm_default_interrupt +vector116: .long asm_default_interrupt +vector117: .long asm_default_interrupt +vector118: .long asm_default_interrupt +vector119: .long asm_default_interrupt +vector120: .long asm_default_interrupt +vector121: .long asm_default_interrupt +vector122: .long asm_default_interrupt +vector123: .long asm_default_interrupt +vector124: .long asm_default_interrupt +vector125: .long asm_default_interrupt +vector126: .long asm_default_interrupt +vector127: .long asm_default_interrupt +vector128: .long asm_default_interrupt +vector129: .long asm_default_interrupt +vector130: .long asm_default_interrupt +vector131: .long asm_default_interrupt +vector132: .long asm_default_interrupt +vector133: .long asm_default_interrupt +vector134: .long asm_default_interrupt +vector135: .long asm_default_interrupt +vector136: .long asm_default_interrupt +vector137: .long asm_default_interrupt +vector138: .long asm_default_interrupt +vector139: .long asm_default_interrupt +vector140: .long asm_default_interrupt +vector141: .long asm_default_interrupt +vector142: .long asm_default_interrupt +vector143: .long asm_default_interrupt +vector144: .long asm_default_interrupt +vector145: .long asm_default_interrupt +vector146: .long asm_default_interrupt +vector147: .long asm_default_interrupt +vector148: .long asm_default_interrupt +vector149: .long asm_default_interrupt +vector150: .long asm_default_interrupt +vector151: .long asm_default_interrupt +vector152: .long asm_default_interrupt +vector153: .long asm_default_interrupt +vector154: .long asm_default_interrupt +vector155: .long asm_default_interrupt +vector156: .long asm_default_interrupt +vector157: .long asm_default_interrupt +vector158: .long asm_default_interrupt +vector159: .long asm_default_interrupt +vector160: .long asm_default_interrupt +vector161: .long asm_default_interrupt +vector162: .long asm_default_interrupt +vector163: .long asm_default_interrupt +vector164: .long asm_default_interrupt +vector165: .long asm_default_interrupt +vector166: .long asm_default_interrupt +vector167: .long asm_default_interrupt +vector168: .long asm_default_interrupt +vector169: .long asm_default_interrupt +vector170: .long asm_default_interrupt +vector171: .long asm_default_interrupt +vector172: .long asm_default_interrupt +vector173: .long asm_default_interrupt +vector174: .long asm_default_interrupt +vector175: .long asm_default_interrupt +vector176: .long asm_default_interrupt +vector177: .long asm_default_interrupt +vector178: .long asm_default_interrupt +vector179: .long asm_default_interrupt +vector180: .long asm_default_interrupt +vector181: .long asm_default_interrupt +vector182: .long asm_default_interrupt +vector183: .long asm_default_interrupt +vector184: .long asm_default_interrupt +vector185: .long asm_default_interrupt +vector186: .long asm_default_interrupt +vector187: .long asm_default_interrupt +vector188: .long asm_default_interrupt +vector189: .long asm_default_interrupt +vector190: .long asm_default_interrupt +vector191: .long asm_default_interrupt +vector192: .long asm_default_interrupt +vector193: .long asm_default_interrupt +vector194: .long asm_default_interrupt +vector195: .long asm_default_interrupt +vector196: .long asm_default_interrupt +vector197: .long asm_default_interrupt +vector198: .long asm_default_interrupt +vector199: .long asm_default_interrupt +vector200: .long asm_default_interrupt +vector201: .long asm_default_interrupt +vector202: .long asm_default_interrupt +vector203: .long asm_default_interrupt +vector204: .long asm_default_interrupt +vector205: .long asm_default_interrupt +vector206: .long asm_default_interrupt +vector207: .long asm_default_interrupt +vector208: .long asm_default_interrupt +vector209: .long asm_default_interrupt +vector210: .long asm_default_interrupt +vector211: .long asm_default_interrupt +vector212: .long asm_default_interrupt +vector213: .long asm_default_interrupt +vector214: .long asm_default_interrupt +vector215: .long asm_default_interrupt +vector216: .long asm_default_interrupt +vector217: .long asm_default_interrupt +vector218: .long asm_default_interrupt +vector219: .long asm_default_interrupt +vector220: .long asm_default_interrupt +vector221: .long asm_default_interrupt +vector222: .long asm_default_interrupt +vector223: .long asm_default_interrupt +vector224: .long asm_default_interrupt +vector225: .long asm_default_interrupt +vector226: .long asm_default_interrupt +vector227: .long asm_default_interrupt +vector228: .long asm_default_interrupt +vector229: .long asm_default_interrupt +vector230: .long asm_default_interrupt +vector231: .long asm_default_interrupt +vector232: .long asm_default_interrupt +vector233: .long asm_default_interrupt +vector234: .long asm_default_interrupt +vector235: .long asm_default_interrupt +vector236: .long asm_default_interrupt +vector237: .long asm_default_interrupt +vector238: .long asm_default_interrupt +vector239: .long asm_default_interrupt +vector240: .long asm_default_interrupt +vector241: .long asm_default_interrupt +vector242: .long asm_default_interrupt +vector243: .long asm_default_interrupt +vector244: .long asm_default_interrupt +vector245: .long asm_default_interrupt +vector246: .long asm_default_interrupt +vector247: .long asm_default_interrupt +vector248: .long asm_default_interrupt +vector249: .long asm_default_interrupt +vector250: .long asm_default_interrupt +vector251: .long asm_default_interrupt +vector252: .long asm_default_interrupt +vector253: .long asm_default_interrupt +vector254: .long asm_default_interrupt +vector255: .long asm_default_interrupt + +/*===============================================================*\ +| Start of code | +\*===============================================================*/ +PUBLIC (start) +SYM(start): + move.w #0x3700,sr /* disable interrupts */ + jmp start_init + +/*===============================================================*\ +| Sspurious interrupt counter | +\*===============================================================*/ +.align 4 +.data /* begin of data section */ +PUBLIC (spurious_int_count) +SYM(spurious_int_count): + .long 0 /* spurious interrupt counter */ + +/*===============================================================*\ +| Function: Default exception handler | ++-----------------------------------------------------------------+ +| - stop and disable all interrupts | +| - loop forever | +\*===============================================================*/ +.text /* start of text section */ +.align 4 +PUBLIC (asm_default_interrupt) +SYM(asm_default_interrupt): + nop + stop #0x3700 /* stop */ + bra.w asm_default_interrupt /* loop forever */ + +/*===============================================================*\ +| Function: Exception handler for spurious interrupts | ++-----------------------------------------------------------------+ +| - count spurious interrupts | +\*===============================================================*/ +.align 4 +PUBLIC (asm_spurious_interrupt) +SYM(asm_spurious_interrupt): + add.l #1,spurious_int_count + rte + +/*===============================================================*\ +| Function: start_init | ++-----------------------------------------------------------------+ +| - Disable all intterupts | +| - Setup the internal SRAM | +| - Initialize mcf548x peripherals | +| - Set initial stack pointer | +| - Boot RTEMS +\*===============================================================*/ +.align 4 +PUBLIC (start_init) +SYM(start_init): + + move.l #0x01040100,d0 /* invalidate instruction/data/branch cache, disable all caches */ + movec d0,cacr + + move.l #_CoreSramBase0,d0 /* initialize RAMBAR0 */ + add.l #0x21,d0 /* for code & data */ + movec d0,rambar0 + + move.l #_CoreSramBase1,d0 /* initialize RAMBAR1 */ + add.l #0x21,d0 /* for code & data */ + movec d0,rambar1 /* movec d0,RAMBAR1 */ + + move.l #__MBAR,d0 /* initialize MBAR */ + movec d0,mbar + + move.l #_CoreSramBase1,d0 /* set sp to end of Core SRAM temporarily */ + add.l #_CoreSramSize1,d0 + move.l d0,sp + + move.l #0,d0 /* initialize frame pointer */ + movea.l d0,a6 + + jsr mcf548x_init /* Initialize mcf548x peripherals */ + + move.l #_SpInit,sp /* relocate sp */ + + clrl d0 /* clear d0 */ + movel d0,a7@- /* environp == NULL */ + movel d0,a7@- /* argv == NULL */ + movel d0,a7@- /* argc == 0 */ + + jsr boot_card /* boot rtems */ + + movel a7@+,d0 + movel a7@+,d0 + movel a7@+,d0 + +exit_multitasking: + nop + nop + halt + bra exit_multitasking + +.end /* end of start.S module */ + + + diff --git a/c/src/lib/libbsp/m68k/genmcf548x/startup/bspclean.c b/c/src/lib/libbsp/m68k/genmcf548x/startup/bspclean.c new file mode 100644 index 0000000000..87aeef194c --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/startup/bspclean.c @@ -0,0 +1,60 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: bspclean.c | ++-----------------------------------------------------------------+ +| The file contains the BSP cleanup code of the generic MCF548x | +| BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +#include +#include +#include + +void bsp_cleanup( void ) +{ + printk("\nRTEMS exited!\n"); + for ( ;; ) + { + asm volatile ( " nop " ); + asm volatile ( " nop " ); + } + +} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/startup/bspstart.c b/c/src/lib/libbsp/m68k/genmcf548x/startup/bspstart.c new file mode 100644 index 0000000000..32c5f53439 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/startup/bspstart.c @@ -0,0 +1,323 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: bspstart.c | ++-----------------------------------------------------------------+ +| The file contains the startup code of generic MCF548x BSP | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +#include +#include +#include +#include + +char *HeapStart, *HeapEnd; +unsigned long _HeapSize; + +extern uint32_t _CPU_cacr_shadow; + +extern char _SdramBase[]; +extern char _BootFlashBase[]; +extern char _CodeFlashBase[]; +extern char _SdramSize[]; +extern char _BootFlashSize[]; +extern char _CodeFlashSize[]; + +/* + * CPU-space access + */ +#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr\n\tnop" : : "d" (_cacr)) +#define m68k_set_acr0(_acr0) asm volatile ("movec %0,#0x0004" : : "d" (_acr0)) +#define m68k_set_acr1(_acr1) asm volatile ("movec %0,#0x0005" : : "d" (_acr1)) +#define m68k_set_acr2(_acr2) asm volatile ("movec %0,#0x0005" : : "d" (_acr2)) +#define m68k_set_acr3(_acr3) asm volatile ("movec %0,#0x0007" : : "d" (_acr3)) + +/* + * Set initial cacr mode, mainly enables branch/intruction/data cache and switch off FPU. + */ +static uint32_t cacr_mode = (0 | + MCF548X_CACR_DEC | /* enable data cache */ + MCF548X_CACR_BEC | /* enable branch cache */ + MCF548X_CACR_IEC | /* enable instruction cache */ + MCF548X_CACR_DDCM(DCACHE_ON_WRIGHTTHROUGH) | /* set data cache mode to write-through */ + MCF548X_CACR_DESB | /* enable data store buffer */ + MCF548X_CACR_DDSP | /* data access only in supv. mode */ + MCF548X_CACR_IDSP | /* instr. access only in supv. mode */ + MCF548X_CACR_DF); /* disable FPU */ + + +/* + * Coldfire cacr maintenance functions + */ +void _CPU_cacr_set_mode(uint32_t new_cacr_mode) +{ +rtems_interrupt_level level; + +rtems_interrupt_disable(level); +cacr_mode = new_cacr_mode; +m68k_set_cacr(new_cacr_mode); +rtems_interrupt_enable(level); +} + +/* + * There is no complete cache lock (only 2 ways of 4 can be locked) + */ +void _CPU_cache_freeze_data(void) +{ +} + +void _CPU_cache_unfreeze_data(void) +{ +} + +void _CPU_cache_freeze_instruction(void) +{ +} + +void _CPU_cache_unfreeze_instruction(void) +{ +} + +void _CPU_cache_enable_instruction(void) +{ + cacr_mode &= ~(MCF548X_CACR_IDCM); + _CPU_cacr_set_mode(cacr_mode); +} + +void _CPU_cache_disable_instruction(void) +{ + cacr_mode |= MCF548X_CACR_IDCM; + _CPU_cacr_set_mode(cacr_mode); +} + +void _CPU_cache_invalidate_entire_instruction(void) +{ + cacr_mode |= MCF548X_CACR_ICINVA; + _CPU_cacr_set_mode(cacr_mode); +} + +void _CPU_cache_invalidate_1_instruction_line(const void *addr) +{ + + asm volatile ("cpushl %%ic,(%0)" :: "a" (addr)); +} + +void _CPU_cache_enable_data(void) +{ + cacr_mode &= ~MCF548X_CACR_DDCM(DCACHE_OFF_IMPRECISE); + _CPU_cacr_set_mode(cacr_mode); +} + +void _CPU_cache_disable_data(void) +{ + cacr_mode |= MCF548X_CACR_DDCM(DCACHE_OFF_IMPRECISE); + _CPU_cacr_set_mode(cacr_mode); +} + +void _CPU_cache_invalidate_entire_data(void) +{ + cacr_mode |= MCF548X_CACR_DCINVA; + _CPU_cacr_set_mode(cacr_mode); +} + +void _CPU_cache_invalidate_1_data_line(const void *addr) +{ + + asm volatile ("cpushl %%dc,(%0)" :: "a" (addr)); +} + +void _CPU_cache_flush_1_data_line(const void *addr) +{ + asm volatile ("cpushl %%dc,(%0)" :: "a" (addr)); +} + +void _CPU_cache_flush_entire_data(void) +{ +register uint32_t way_cnt, set_cnt, addr; + +asm volatile("nop"); + +for(way_cnt=0; way_cnt<4; way_cnt++) + { + for(addr=0,set_cnt=0; set_cnt<512; set_cnt++,addr+=0x10) + { + asm volatile ("cpushl %%dc,(%0)" :: "a" (addr)); + } + addr=way_cnt; + } +} + +/* + * Use the shared implementations of the following routines + */ + +void bsp_predriver_hook() +{ + /* Do nothing */ +} + +void bsp_postdriver_hook(void); +void bsp_libc_init( void *, uint32_t, int ); +void bsp_pretasking_hook(void); /* m68k version */ + +void bsp_calc_mem_layout() +{ + /* + * these labels (!) are defined in the linker command file + * or when the linker is invoked + * NOTE: the information(size) is the address of the object, + * not the object otself + */ + extern char _TopRamReserved []; + extern char _WorkspaceBase []; + + /* + * compute the memory layout: + * - first unused address is Workspace start + * - Heap starts at end of workspace + * - Heap ends at end of memory - reserved memory area + */ + Configuration.work_space_start = _WorkspaceBase; + + HeapStart = ((char *)Configuration.work_space_start + + Configuration.work_space_size); + + HeapEnd = (void *)(RAM_END - (uint32_t)_TopRamReserved); + + _HeapSize = HeapEnd - HeapStart; +} + + +/* + * Coldfire acr and mmu settings + */ + void acr_mmu_mapping(void) + { + + /* + * Cache disabled for internal register area (256 kB). + * Choose the smallest maskable size of 1MB. + */ + m68k_set_acr0(MCF548X_ACR_BA((uint32_t)(__MBAR)) | + MCF548X_ACR_ADMSK_AMM((uint32_t)(0xFFFFF)) | + MCF548X_ACR_E | + MCF548X_ACR_SP /* supervisor protection */ | + MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ | + MCF548X_ACR_CM(CM_OFF_PRECISE)); + +#ifdef M5484FIREENGINE + + + /* + * Cache enabled for entire SDRAM (64 MB) + */ + m68k_set_acr1(MCF548X_ACR_BA((uint32_t)(_SdramBase)) | + MCF548X_ACR_ADMSK_AMM((uint32_t)(_SdramSize - 1)) | + MCF548X_ACR_E | + MCF548X_ACR_SP /* supervisor protection */ | + MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ | + MCF548X_ACR_CM(CM_ON_WRIGHTTHROUGH)); + + /* + * Cache enabled for entire boot flash (2 MB) + */ + m68k_set_acr2(MCF548X_ACR_BA((uint32_t)(_BootFlashBase)) | + MCF548X_ACR_ADMSK_AMM((uint32_t)(_BootFlashSize - 1)) | + MCF548X_ACR_E | + MCF548X_ACR_SP /* supervisor protection */ | + MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ | + MCF548X_ACR_CM(CM_ON_COPYBACK)); + + /* + * Cache enabled for entire code flash (16 MB) + */ + m68k_set_acr3(MCF548X_ACR_BA((uint32_t)(_CodeFlashBase)) | + MCF548X_ACR_ADMSK_AMM((uint32_t)(_CodeFlashSize - 1)) | + MCF548X_ACR_E | + MCF548X_ACR_SP /* supervisor protection */ | + MCF548X_ACR_S(S_ACCESS_SUPV) /* always in supervisor mode */ | + MCF548X_ACR_CM(CM_ON_COPYBACK)); +#endif + + } + +/* + * bsp_start + * + * This routine does the bulk of the system initialisation. + */ +void bsp_start( void ) +{ + extern char _RamSize[]; + extern unsigned long _M68k_Ramsize; + + _M68k_Ramsize = (unsigned long)_RamSize; /* RAM size set in linker script */ + + /* + * Allocate the memory for the RTEMS Work Space and Heap. This can come from + * a variety of places: hard coded address, malloc'ed from outside + * RTEMS world (e.g. simulator or primitive memory manager), or (as + * typically done by stock BSPs) by subtracting the required amount + * of work space from the last physical address on the CPU board. + */ + bsp_calc_mem_layout(); + + /* + * do mapping of acr's and/or mmu + */ + acr_mmu_mapping(); + + /* + * Load the shadow variable of cacr with initial mode and write it to the cacr. + * Interrupts are still disabled, so there is no need for surrounding rtems_interrupt_enable()/rtems_interrupt_disable() + */ + _CPU_cacr_shadow = cacr_mode; + m68k_set_cacr(_CPU_cacr_shadow); + +} + + +/* + * Get the XLB clock speed + */ +uint32_t get_CPU_clock_speed(void) +{ + return (uint32_t)BSP_CPU_CLOCK_SPEED; +} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/startup/init548x.c b/c/src/lib/libbsp/m68k/genmcf548x/startup/init548x.c new file mode 100644 index 0000000000..22541781c2 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/startup/init548x.c @@ -0,0 +1,317 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: init548x.c | ++-----------------------------------------------------------------+ +| The file contains the c part of MCF548x init code | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +#include +#include + +#define SYSTEM_PERIOD 10 /* system bus period in ns */ + +/* SDRAM Timing Parameters */ +#define SDRAM_TWR 2 /* in clocks */ +#define SDRAM_CASL 2.5 /* in clocks */ +#define SDRAM_TRCD 20 /* in ns */ +#define SDRAM_TRP 20 /* in ns */ +#define SDRAM_TRFC 75 /* in ns */ +#define SDRAM_TREFI 7800 /* in ns */ + +extern uint8_t _DataRom[]; +extern uint8_t _DataRam[]; +extern uint8_t _DataEnd[]; +extern uint8_t _BssStart[]; +extern uint8_t _BssEnd[]; +extern uint8_t _BootFlashBase[]; +extern uint8_t _CodeFlashBase[]; +extern uint8_t _RamBase[]; +extern uint32_t InterruptVectorTable[]; +extern uint32_t _VectorRam[]; + +void gpio_init(void); +void fbcs_init(void); +void sdramc_init(void); +void mcf548x_init(void); + + +void mcf548x_init(void) + { + uint32_t n; + uint8_t *dp, *sp; + + /* set XLB arbiter timeouts */ +#ifdef M5484FIREENGINE + /* set XLB arbiter timeouts */ + MCF548X_XLB_ADRTO = 0x00000100; + MCF548X_XLB_DATTO = 0x00000100; + MCF548X_XLB_BUSTO = 0x00000100; +#endif + + gpio_init(); + fbcs_init(); + sdramc_init(); + + /* Copy the vector table to RAM */ + if (_VectorRam != InterruptVectorTable) + { + for( n = 0; n < 256; n++) + { + _VectorRam[n] = InterruptVectorTable[n]; + } + } + + m68k_set_vbr((uint32_t)_VectorRam); + + /* Move initialized data from ROM to RAM. */ + if (_DataRom != _DataRam) + { + n = _DataEnd - _DataRam; + sp = (uint8_t *)_DataRom; + dp = (uint8_t *)_DataRam; + while(n--) + *dp++ = *sp++; + } + + /* Zero uninitialized data */ + if (_BssStart != _BssEnd) + { + n = _BssEnd - _BssStart; + sp = (uint8_t *)_BssStart; + while (n--) + *sp++ = 0; + } + +} +/********************************************************************/ +void +fbcs_init (void) +{ +#ifdef M5484FIREENGINE + +volatile uint32_t cscr, clk_ratio, fb_period, ws; + +/* boot flash already valid ? */ +if(!(MCF548X_FBCS_CSMR0 & MCF548X_FBCS_CSMR_V)) + { + + /* + * Boot Flash + */ + MCF548X_FBCS_CSAR0 = MCF548X_FBCS_CSAR_BA((uint32_t)(_BootFlashBase)); + + cscr = (0 + | MCF548X_FBCS_CSCR_ASET(1) + | MCF548X_FBCS_CSCR_WRAH(0) + | MCF548X_FBCS_CSCR_RDAH(0) + | MCF548X_FBCS_CSCR_AA + | MCF548X_FBCS_CSCR_PS_16); + + /* + * Determine the necessary wait states based on the defined system + * period (XLB clock period) and the CLKIN to XLB ratio. + * The boot flash has a max access time of 110ns. + */ + clk_ratio = (MCF548X_PCI_PCIGSCR >> 24) & 0x7; + fb_period = SYSTEM_PERIOD * clk_ratio; + ws = 110 / fb_period; + + MCF548X_FBCS_CSCR0 = cscr | MCF548X_FBCS_CSCR_WS(ws); + MCF548X_FBCS_CSMR0 = (0 + | MCF548X_FBCS_CSMR_BAM_2M + | MCF548X_FBCS_CSMR_V); + + } + +/* code flash already valid ? */ +if(!(MCF548X_FBCS_CSMR1 & MCF548X_FBCS_CSMR_V)) + { + + /* + * Code Flash + */ + MCF548X_FBCS_CSAR1 = MCF548X_FBCS_CSAR_BA((uint32_t)(_CodeFlashBase)); + + /* + * Determine the necessary wait states based on the defined system + * period (XLB clock period) and the CLKIN to XLB ratio. + * The user/code flash has a max access time of 120ns. + */ + ws = 120 / fb_period; + MCF548X_FBCS_CSCR1 = cscr | MCF548X_FBCS_CSCR_WS(ws); + MCF548X_FBCS_CSMR1 = (0 + | MCF548X_FBCS_CSMR_BAM_16M + | MCF548X_FBCS_CSMR_V); + } + +#endif +} + +/********************************************************************/ +void +sdramc_init (void) +{ + + /* + * Check to see if the SDRAM has already been initialized + * by a run control tool + */ + if (!(MCF548X_SDRAMC_SDCR & MCF548X_SDRAMC_SDCR_REF)) + { + /* + * Basic configuration and initialization + */ + MCF548X_SDRAMC_SDRAMDS = (0 + | MCF548X_SDRAMC_SDRAMDS_SB_E(MCF548X_SDRAMC_SDRAMDS_DRIVE_8MA) + | MCF548X_SDRAMC_SDRAMDS_SB_C(MCF548X_SDRAMC_SDRAMDS_DRIVE_8MA) + | MCF548X_SDRAMC_SDRAMDS_SB_A(MCF548X_SDRAMC_SDRAMDS_DRIVE_8MA) + | MCF548X_SDRAMC_SDRAMDS_SB_S(MCF548X_SDRAMC_SDRAMDS_DRIVE_8MA) + | MCF548X_SDRAMC_SDRAMDS_SB_D(MCF548X_SDRAMC_SDRAMDS_DRIVE_8MA) + ); + MCF548X_SDRAMC_CS0CFG = (0 + | MCF548X_SDRAMC_CSnCFG_CSBA((uint32_t)(_RamBase)) + | MCF548X_SDRAMC_CSnCFG_CSSZ(MCF548X_SDRAMC_CSnCFG_CSSZ_64MBYTE) + ); + MCF548X_SDRAMC_SDCFG1 = (0 + | MCF548X_SDRAMC_SDCFG1_SRD2RW(7) + | MCF548X_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) + | MCF548X_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2)) + | MCF548X_SDRAMC_SDCFG1_ACT2RW((int)(((SDRAM_TRCD/SYSTEM_PERIOD) - 1) + 0.5)) + | MCF548X_SDRAMC_SDCFG1_PRE2ACT((int)(((SDRAM_TRP/SYSTEM_PERIOD) - 1) + 0.5)) + | MCF548X_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC/SYSTEM_PERIOD) - 1) + 0.5)) + | MCF548X_SDRAMC_SDCFG1_WTLAT(3) + ); + MCF548X_SDRAMC_SDCFG2 = (0 + | MCF548X_SDRAMC_SDCFG2_BRD2PRE(4) + | MCF548X_SDRAMC_SDCFG2_BWT2RW(6) + | MCF548X_SDRAMC_SDCFG2_BRD2WT(7) + | MCF548X_SDRAMC_SDCFG2_BL(7) + ); + + /* + * Precharge and enable write to SDMR + */ + MCF548X_SDRAMC_SDCR = (0 + | MCF548X_SDRAMC_SDCR_MODE_EN + | MCF548X_SDRAMC_SDCR_CKE + | MCF548X_SDRAMC_SDCR_DDR + | MCF548X_SDRAMC_SDCR_MUX(1) + | MCF548X_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5)) + | MCF548X_SDRAMC_SDCR_IPALL + ); + + /* + * Write extended mode register + */ + MCF548X_SDRAMC_SDMR = (0 + | MCF548X_SDRAMC_SDMR_BNKAD_LEMR + | MCF548X_SDRAMC_SDMR_AD(0x0) + | MCF548X_SDRAMC_SDMR_CMD + ); + + /* + * Write mode register and reset DLL + */ + MCF548X_SDRAMC_SDMR = (0 + | MCF548X_SDRAMC_SDMR_BNKAD_LMR + | MCF548X_SDRAMC_SDMR_AD(0x163) + | MCF548X_SDRAMC_SDMR_CMD + ); + + /* + * Execute a PALL command + */ + MCF548X_SDRAMC_SDCR |=MCF548X_SDRAMC_SDCR_IPALL; + + /* + * Perform two REF cycles + */ + MCF548X_SDRAMC_SDCR |= MCF548X_SDRAMC_SDCR_IREF; + MCF548X_SDRAMC_SDCR |= MCF548X_SDRAMC_SDCR_IREF; + + /* + * Write mode register and clear reset DLL + */ + MCF548X_SDRAMC_SDMR = (0 + | MCF548X_SDRAMC_SDMR_BNKAD_LMR + | MCF548X_SDRAMC_SDMR_AD(0x063) + | MCF548X_SDRAMC_SDMR_CMD + ); + + /* + * Enable auto refresh and lock SDMR + */ + MCF548X_SDRAMC_SDCR &= ~MCF548X_SDRAMC_SDCR_MODE_EN; + MCF548X_SDRAMC_SDCR |= (0 + | MCF548X_SDRAMC_SDCR_REF + | MCF548X_SDRAMC_SDCR_DQS_OE(0xF) + ); + } + +} + +/********************************************************************/ +void +gpio_init(void) +{ + +#ifdef M5484FIREENGINE + + /* + * Enable Ethernet signals so that, if a cable is plugged into + * the ports, the lines won't be floating and potentially cause + * erroneous transmissions + */ + MCF548X_GPIO_PAR_FECI2CIRQ = (0 + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E1MII + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E17 + ); + MCF548X_GPIO_PAR_FECI2CIRQ = (0 + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E0MDC + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E0MII + | MCF548X_GPIO_PAR_FECI2CIRQ_PAR_E07 + ); + +#endif +} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds b/c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds new file mode 100644 index 0000000000..93edba1b72 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds @@ -0,0 +1,232 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: linkcmd | ++-----------------------------------------------------------------+ +| The file contains the linker directives for the generic MCF548x | +| BSP to be used with an m5484FireEngine EVB to load and execute | +| code in the RAM. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +/* + * Location and size of on-chip devices + */ +_SdramBase = DEFINED(_SdramBase) ? _SdramBase : 0x00000000; +_SdramSize = DEFINED(_SdramSize) ? _SdramSize : (64 * 1024 * 1024); +_SysSramBase = DEFINED(_SysSramBase) ? _SysSramBase : __MBAR + 0x00010000; +_SysSramSize = DEFINED(_SysSramSize) ? _SysSramSize : (32 * 1024); +_McdapiBase = DEFINED(_McdapiBase) ? _McdapiBase : _SysSramBase; +_McdapiSize = DEFINED(_McdapiSize) ? _McdapiSize : (12 * 1024); +_CoreSramBase0 = DEFINED(_CoreSramBase0) ? _CoreSramBase0 : 0x20000000; +_CoreSramBase1 = DEFINED(_CoreSramBase1) ? _CoreSramBase1 : 0x20001000; +_CoreSramSize0 = DEFINED(_CoreSramSize0) ? _CoreSramSize0 : (4 * 1024); +_CoreSramSize1 = DEFINED(_CoreSramSize1) ? _CoreSramSize1 : (4 * 1024); +_BootFlashBase = DEFINED(_BootFlashBase) ? _BootFlashBase : 0xFF800000; +_BootFlashSize = DEFINED(_BootFlashSize) ? _BootFlashSize : (2 * 1024 * 1024); +_CodeFlashBase = DEFINED(_CodeFlashBase) ? _CodeFlashBase : 0xE0000000; +_CodeFlashSize = DEFINED(_CodeFlashSize) ? _CodeFlashSize : (16 * 1024 * 1024); + +_VectorRam = DEFINED(_VectorRam) ? _VectorRam : _SdramBase; +_DataRam = DEFINED(_DataRam) ? _DataRam : _data_dest_start; +_DataRom = DEFINED(_DataRom) ? _DataRom : _data_src_start; +_DataEnd = DEFINED(_DataEnd) ? _DataEnd : _data_dest_end; +_BssStart = DEFINED(_BssStart) ? _BssStart : _clear_start; +_BssEnd = DEFINED(_BssEnd) ? _BssEnd : _clear_end; +_SpInit = DEFINED(_SpInit) ? _SpInit : _EndInitStackSpace; +_InitPc = DEFINED(_InitPc) ? _InitPc : _SdramBase + 0x400; + +_InitStackSize = DEFINED(StackSize) ? StackSize : 0x800; /* 2 kB */ +_TopRamReserved = DEFINED(_TopRamReserved) ? _TopRamReserved : 0; + +_RamBase = DEFINED(_SdramBase) ? _SdramBase : _SdramBase; +_RamSize = DEFINED(_SdramSize) ? _SdramSize : _SdramSize; +_VBR = DEFINED(_VBR) ? _VBR : _RamBase; + +__MBAR = DEFINED(__MBAR) ? __MBAR : 0x10000000; + +ENTRY(start) +MEMORY +{ + sdram : ORIGIN = 0x400 , LENGTH = 64M - 0x400 + code_flash : ORIGIN = 0xE0000000, LENGTH = 16M + boot_flash : ORIGIN = 0xFF800000, LENGTH = 2M +} + +SECTIONS +{ + + _header_offset = 0; + + /* + * Text, data and bss segments .vectors + */ + .vectors : { + *(.vectors*) + } >sdram + .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 = .); + } >sdram + + .data : { + /*.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 = . ); + } >sdram + + _data_src_start = _etext; /*LOADADDR(.data);*/ + _data_src_end = _data_src_start + SIZEOF(.data); + + .bss : { + PROVIDE (_clear_start = .); + *(.bss*) + *(COMMON) + . = ALIGN (16); + PROVIDE (end = .); + PROVIDE (_clear_end = .); + . = ALIGN (4); + PROVIDE (_StartInitStackSpace = .); + /*. = _StartInitStackSpace + _InitStackSize;*/ + . += _InitStackSize; + PROVIDE (_EndInitStackSpace = .); + PROVIDE (_WorkspaceBase = .); + } >sdram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + +PROVIDE (end_of_all = .); +} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds.m5484FireEngine.flash b/c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds.m5484FireEngine.flash new file mode 100644 index 0000000000..5dcb520261 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/startup/linkcmds.m5484FireEngine.flash @@ -0,0 +1,232 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: linkcmd.m5484FireEngine.flash | ++-----------------------------------------------------------------+ +| The file contains the linker directives for the generic MCF548x | +| BSP to be used with an m5484FireEngine EVB to load and execute | +| code in the boot FLASH. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +/* + * Location and size of on-chip devices + */ +_SdramBase = DEFINED(_SdramBase) ? _SdramBase : 0x00000000; +_SdramSize = DEFINED(_SdramSize) ? _SdramSize : (64 * 1024 * 1024); +_SysSramBase = DEFINED(_SysSramBase) ? _SysSramBase : __MBAR + 0x00010000; +_SysSramSize = DEFINED(_SysSramSize) ? _SysSramSize : (32 * 1024); +_McdapiBase = DEFINED(_McdapiBase) ? _McdapiBase : _SysSramBase; +_McdapiSize = DEFINED(_McdapiSize) ? _McdapiSize : (12 * 1024); +_CoreSramBase0 = DEFINED(_CoreSramBase0) ? _CoreSramBase0 : 0x20000000; +_CoreSramBase1 = DEFINED(_CoreSramBase1) ? _CoreSramBase1 : 0x20001000; +_CoreSramSize0 = DEFINED(_CoreSramSize0) ? _CoreSramSize0 : (4 * 1024); +_CoreSramSize1 = DEFINED(_CoreSramSize1) ? _CoreSramSize1 : (4 * 1024); +_BootFlashBase = DEFINED(_BootFlashBase) ? _BootFlashBase : 0xFF800000; +_BootFlashSize = DEFINED(_BootFlashSize) ? _BootFlashSize : (2 * 1024 * 1024); +_CodeFlashBase = DEFINED(_CodeFlashBase) ? _CodeFlashBase : 0xE0000000; +_CodeFlashSize = DEFINED(_CodeFlashSize) ? _CodeFlashSize : (16 * 1024 * 1024); + +_VectorRam = DEFINED(_VectorRam) ? _VectorRam : _SdramBase; +_DataRam = DEFINED(_DataRam) ? _DataRam : _data_dest_start; +_DataRom = DEFINED(_DataRom) ? _DataRom : _data_src_start; +_DataEnd = DEFINED(_DataEnd) ? _DataEnd : _data_dest_end; +_BssStart = DEFINED(_BssStart) ? _BssStart : _clear_start; +_BssEnd = DEFINED(_BssEnd) ? _BssEnd : _clear_end; +_SpInit = DEFINED(_SpInit) ? _SpInit : _EndInitStackSpace; +_InitPc = DEFINED(_InitPc) ? _InitPc : _SdramBase + 0x400; + +_InitStackSize = DEFINED(StackSize) ? StackSize : 0x2000; /* 8 kB */ +_TopRamReserved = DEFINED(_TopRamReserved) ? _TopRamReserved : 0; + +_RamBase = DEFINED(_SdramBase) ? _SdramBase : _SdramBase; +_RamSize = DEFINED(_SdramSize) ? _SdramSize : _SdramSize; +_VBR = DEFINED(_VBR) ? _VBR : _RamBase; + +__MBAR = DEFINED(__MBAR) ? __MBAR : 0x10000000; + +ENTRY(start) +MEMORY +{ + sdram : ORIGIN = 0x400 , LENGTH = 64M - 0x400 + code_flash : ORIGIN = 0xE0000000, LENGTH = 16M + boot_flash : ORIGIN = 0xFF800000, LENGTH = 2M +} + +SECTIONS +{ + + _header_offset = 0; + + /* + * Text, data and bss segments .vectors + */ + .vectors : { + *(.vectors*) + } >boot_flash + .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 : AT(LOADADDR(.text) + SIZEOF(.text)) { + /*.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 = . ); + } >sdram + + _data_src_start = _etext; /*LOADADDR(.data);*/ + _data_src_end = _data_src_start + SIZEOF(.data); + + .bss : { + PROVIDE (_clear_start = .); + *(.bss*) + *(COMMON) + . = ALIGN (16); + PROVIDE (end = .); + PROVIDE (_clear_end = .); + . = ALIGN (4); + PROVIDE (_StartInitStackSpace = .); + /*. = _StartInitStackSpace + _InitStackSize;*/ + . += _InitStackSize; + PROVIDE (_EndInitStackSpace = .); + PROVIDE (_WorkspaceBase = .); + } >sdram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + +PROVIDE (end_of_all = .); +} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/timer/timer.c b/c/src/lib/libbsp/m68k/genmcf548x/timer/timer.c new file mode 100644 index 0000000000..676274e688 --- /dev/null +++ b/c/src/lib/libbsp/m68k/genmcf548x/timer/timer.c @@ -0,0 +1,94 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: timer.c | ++-----------------------------------------------------------------+ +| The file contains the diagnostic timer code of generic MCF548x | +| BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| 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. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + +/* + * Timer Init + * + * Use the second slice timer (SLT1) as the diagnostic timer. + */ + +#include +#include +#include + +rtems_boolean Timer_driver_Find_average_overhead; +static uint32_t microsecond_timer_value = 0; + +void Timer_initialize(void) +{ +MCF548X_SLT_SLTCNT1 = 0xFFFFFFFF; +MCF548X_SLT_SCR1 |= (MCF548X_SLT_SCR_TEN | MCF548X_SLT_SCR_RUN); +} + +/* + * Return timer value in microsecond units + * XLB clock 100 MHz / 1us is equal to 100 counts + */ +int +Read_timer(void) +{ + microsecond_timer_value = (0xFFFFFFFF - MCF548X_SLT_SCNT1)/100; + return microsecond_timer_value; +} + +/* + * 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) +{ +Timer_driver_Find_average_overhead = find_flag; +} + + + -- cgit v1.2.3