updated gen83xx BSP

updated haleakala BSP
added MPC55xx BSP
This commit is contained in:
Thomas Doerfler
2008-07-14 16:15:28 +00:00
parent 3c6fe2e7f9
commit 574fb67510
92 changed files with 12210 additions and 2515 deletions

View File

@@ -1,3 +1,8 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* aclocal/bsp-alias.m4, aclocal/check-bsps.m4: Added MPC5566EVB and
MPC8313ERDB. Added Doxygen style comment.
2008-07-14 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
* make/custom/haleakala.cfg:

View File

@@ -2,6 +2,15 @@ dnl
dnl $Id$
dnl
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Configuration macros.
#
dnl _RTEMS_BSP_ALIAS(BSP_ALIAS,RTEMS_BSP_FAMILY)
dnl Internal subroutine to RTEMS_BSP_ALIAS
AC_DEFUN([_RTEMS_BSP_ALIAS],
@@ -28,8 +37,10 @@ AC_DEFUN([_RTEMS_BSP_ALIAS],
brs5l*) $2=gen5200 ;; # MPC5200 based board
pm520*) $2=gen5200 ;; # MPC5200 based board
icecube) $2=gen5200 ;; # MPC5200 based board - LITE5200B
mpc55??evb) $2=mpc55xxevb ;; # MPC5566EVB based board
mpc8349eamds) $2=gen83xx ;; # MPC8349 based board
hsc_cm01) $2=gen83xx ;; # MPC8349 based board
mpc8313erdb) $2=gen83xx ;; # MPC83XX based board
rtl22xx_t) $2=rtl22xx ;; # rtl22xx bsp in thumb mode
simcpu32) $2=sim68000 ;; # BSVC CPU32 variant
simsh7032) $2=shsim ;; # SH7032 simulator

View File

@@ -1,5 +1,14 @@
dnl $Id$
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Configuration macros.
#
dnl Report all available bsps for a target within the source tree
dnl
dnl RTEMS_CHECK_BSPS(bsp_list)
@@ -27,7 +36,8 @@ AC_MSG_CHECKING([for available BSPs])
bsps="$bsps mbx860_005b"
;;
gen5200) bsps="pm520_cr825 pm520_ze30 brs5l";;
gen83xx) bsps="mpc8349eamds hsc_cm01";;
mpc55xxevb) bsps="mpc5566evb";;
gen83xx) bsps="mpc8349eamds hsc_cm01 mpc8313erdb";;
motorola_powerpc) bsps="mvme2307 mcp750 mtx603e mvme2100";;
pc386) bsps="pc386 pc386dx pc486 pc586 pc686 pck6";;
erc32) bsps="erc32 sis";;

View File

@@ -1,3 +1,9 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* libchip/i2c/spi-sd-card.c: Added missing header file.
* libchip/Makefile.am: Added SD Card driver.
2008-07-14 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
* libchip/display/font_hcms29xx.c, libchip/display/disp_fonts.h

View File

@@ -18,12 +18,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
AC_CONFIG_SUBDIRS([idp]);;
mcf5206elite )
AC_CONFIG_SUBDIRS([mcf5206elite]);;
mcf52235 )
AC_CONFIG_SUBDIRS([mcf52235]);;
mcf5235 )
AC_CONFIG_SUBDIRS([mcf5235]);;
mcf5329 )
AC_CONFIG_SUBDIRS([mcf5329]);;
mrm332 )
AC_CONFIG_SUBDIRS([mrm332]);;
mvme136 )

View File

@@ -1,3 +1,7 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* mpc55xxevb: New BSP.
2008-07-14 Thomas Doefler <Thomas.Doerfler@embedded-brains.de>
* haleakala: added new BSP

View File

@@ -14,6 +14,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
AC_CONFIG_SUBDIRS([mbx8xx]);;
motorola_powerpc )
AC_CONFIG_SUBDIRS([motorola_powerpc]);;
mpc55xxevb )
AC_CONFIG_SUBDIRS([mpc55xxevb]);;
mpc8260ads )
AC_CONFIG_SUBDIRS([mpc8260ads]);;
mvme3100 )

View File

@@ -1,3 +1,17 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* irq/irq_init.c, irq/irq.h, startup/linkcmds:
Removed.
* README.mpc8313erdb, include/irq-config.h, include/irq.h, irq/irq.c,
startup/linkcmds.base, startup/linkcmds.mpc8313erdb: New files.
* Makefile.am, configure.ac, console/config.c, console/console.c,
i2c/i2c_init.c, include/bsp.h, include/hwreg_vals.h, network/network.c,
spi/spi_init.c, start/start.S, startup/bspstart.c, startup/cpuinit.c,
startup/linkcmds.hsc_cm01, startup/linkcmds.mpc8349eamds: Support
MPC8313ERDB.
2008-05-15 Joel Sherrill <joel.sherrill@OARcorp.com>
* startup/bspstart.c: Add capability for bootcard.c BSP Initialization

View File

@@ -12,6 +12,8 @@ dist_project_lib_DATA = bsp_specs
include_HEADERS = include/bsp.h
include_HEADERS += include/tm27.h
libcpudir = ../../../libcpu/@RTEMS_CPU@
nodist_include_HEADERS = include/bspopts.h
DISTCLEANFILES = include/bspopts.h
@@ -33,26 +35,39 @@ rtems_crti.$(OBJEXT): ../../powerpc/shared/start/rtems_crti.S
$(CPPASCOMPILE) -o $@ -c $<
project_lib_DATA += rtems_crti.$(OBJEXT)
dist_project_lib_DATA += startup/linkcmds \
dist_project_lib_DATA += startup/linkcmds.base \
startup/linkcmds.mpc8313erdb \
startup/linkcmds.mpc8349eamds \
startup/linkcmds.hsc_cm01
mpc83xx_regs_SOURCES = startup/mpc83xx_regs.c
startup_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \
../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
startup_SOURCES = ../../shared/bspclean.c \
../../shared/bsplibc.c \
../../shared/bsppost.c \
../../shared/bootcard.c \
../../shared/bsppredriverhook.c \
../../shared/sbrk.c ../../shared/gnatinstallhandler.c startup/cpuinit.c
pclock_SOURCES = ../../powerpc/shared/clock/p_clock.c
../../shared/sbrk.c \
../../shared/gnatinstallhandler.c \
../shared/src/tictac.c \
startup/cpuinit.c \
startup/bspstart.c
include_bsp_HEADERS = ./irq/irq.h \
./include/hwreg_vals.h \
../../powerpc/shared/vectors/vectors.h
clock_SOURCES = ../shared/clock/clock.c
include_bsp_HEADERS = include/irq.h \
include/irq-config.h \
../../shared/include/irq-generic.h \
include/hwreg_vals.h \
../shared/include/u-boot.h \
../shared/include/tictac.h
irq_SOURCES = include/irq.h \
include/irq-config.h \
irq/irq.c \
../../shared/src/irq-generic.c \
../../shared/src/irq-legacy.c
vectors_SOURCES = ../../powerpc/shared/vectors/vectors.h \
../../powerpc/shared/vectors/vectors_init.c \
../../powerpc/shared/vectors/vectors.S
irq_SOURCES = ./irq/irq.h ./irq/irq_init.c ./irq/ipic.c \
../shared/irq/irq_asm.S
console_SOURCES = console/console.c console/ns16550cfg.c
bsp_i2c_SOURCES = i2c/i2c_init.c
bsp_spi_SOURCES = spi/spi_init.c
@@ -66,24 +81,24 @@ network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
noinst_LIBRARIES = libbsp.a
libbsp_a_SOURCES = $(startup_SOURCES) $(pclock_SOURCES) $(console_SOURCES) \
$(vectors_SOURCES) $(irq_SOURCES) $(mpc83xx_regs_SOURCES) \
libbsp_a_SOURCES = $(startup_SOURCES) $(clock_SOURCES) $(console_SOURCES) \
$(irq_SOURCES) $(mpc83xx_regs_SOURCES) \
$(bsp_i2c_SOURCES) $(bsp_spi_SOURCES)
libbsp_a_LIBADD = \
../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/raw_exception.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/mmu.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/timer.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/clock.rel \
../../../libcpu/@RTEMS_CPU@/mpc83xx/i2c.rel \
../../../libcpu/@RTEMS_CPU@/mpc83xx/spi.rel
libbsp_a_LIBADD = $(libcpudir)/shared/cpuIdent.rel \
$(libcpudir)/shared/cache.rel \
$(libcpudir)/@exceptions@/rtems-cpu.rel \
$(libcpudir)/@exceptions@/raw_exception.rel \
$(libcpudir)/@exceptions@/exc_bspsupport.rel \
$(libcpudir)/mpc6xx/mmu.rel \
$(libcpudir)/mpc6xx/timer.rel \
$(libcpudir)/mpc83xx/i2c.rel \
$(libcpudir)/mpc83xx/spi.rel \
$(libcpudir)/mpc83xx/gtm.rel
if HAS_NETWORKING
libbsp_a_LIBADD += network.rel
libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/mpc83xx/tsec.rel
libbsp_a_LIBADD += $(libcpudir)/mpc83xx/tsec.rel
endif
EXTRA_DIST += README.mpc8349eamds

View File

@@ -0,0 +1,13 @@
SPI:
In master mode SCS (SPI_D) cannot be used as GPIO[31]. Unfortunately this pin
is connected to the SD Card slot. See also [1] SPI 5.
TSEC:
The interrupt vector values are switched at the IPIC. See also [1] IPIC 1.
REFERENCES:
[1] MPC8313ECE Rev. 3, 3/2008: "MPC8313E PowerQUICC™ II Pro Integrated Host
Processor Device Errata"

View File

@@ -10,6 +10,7 @@ RTEMS_TOP(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.10])
RTEMS_BSP_CONFIGURE
RTEMS_AMPOLISH3
RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm])
RTEMS_CANONICALIZE_TOOLS

View File

@@ -97,7 +97,15 @@ console_tbl Console_Port_Tbl[] = {
&ns16550_flow_RTSCTS, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *)9600, /* baud rate */ /* pDeviceParams */
/* pDeviceParams */
/* baud rate */
#ifdef MPC8313ERDB
(void *)115200,
#else /* MPC8313ERDB */
(void *)9600,
#endif /* MPC8313ERDB */
(uint32_t)&(mpc83xx.duart[0]), /* ulCtrlPort1e */
0, /* ulCtrlPort2 */
(uint32_t)&(mpc83xx.duart[0]), /* ulDataPort */
@@ -117,7 +125,15 @@ console_tbl Console_Port_Tbl[] = {
&ns16550_flow_RTSCTS, /* pDeviceFlow */
16, /* ulMargin */
8, /* ulHysteresis */
(void *)9600, /* baud rate */ /* pDeviceParams */
/* pDeviceParams */
/* baud rate */
#ifdef MPC8313ERDB
(void *)115200,
#else /* MPC8313ERDB */
(void *)9600,
#endif /* MPC8313ERDB */
(uint32_t)&(mpc83xx.duart[1]), /* ulCtrlPort1-Filled in at runtime */
0, /* ulCtrlPort2 */
(uint32_t)&(mpc83xx.duart[1]), /* ulDataPort-Filled in at runtime*/

View File

@@ -44,6 +44,7 @@
#include "console.h"
#include <rtems/bspIo.h>
#include <rtems/termiostypes.h>
/*
* Load configuration table
@@ -98,6 +99,9 @@ rtems_device_driver console_open(
Callbacks.outputUsesInterrupts = c->deviceOutputUsesInterrupts;
status = rtems_termios_open ( major, minor, arg, &Callbacks);
Console_Port_Data[minor].termios_data = args->iop->data1;
if (status == 0) {
rtems_termios_set_initial_baud( Console_Port_Data [minor].termios_data, (int) Console_Port_Tbl [minor].pDeviceParams);
}
return status;
}
@@ -257,6 +261,11 @@ void debug_putc_onlcr(const char c)
Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
deviceWritePolled(Console_Port_Minor,c);
if (c == '\n') {
Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
deviceWritePolled(Console_Port_Minor,'\r');
}
rtems_interrupt_enable(Irql);
}
}

View File

@@ -25,27 +25,27 @@ static mpc83xx_i2c_desc_t mpc83xx_i2c_bus_tbl[2] = {
/* first channel */
{
{/* public fields */
ops: &mpc83xx_i2c_ops,
size: sizeof(mpc83xx_i2c_bus_tbl[0]),
.ops = &mpc83xx_i2c_ops,
.size = sizeof(mpc83xx_i2c_bus_tbl[0]),
},
{ /* our private fields */
reg_ptr: &mpc83xx.i2c[0],
initialized: FALSE,
irq_number : BSP_IPIC_IRQ_I2C1,
base_frq : 0 /* will be set during initiailization */
.reg_ptr = &mpc83xx.i2c[0],
.initialized = FALSE,
.irq_number = BSP_IPIC_IRQ_I2C1,
.base_frq = 0 /* will be set during initiailization */
}
},
/* second channel */
{
{ /* public fields */
ops: &mpc83xx_i2c_ops,
size: sizeof(mpc83xx_i2c_bus_tbl[1]),
.ops = &mpc83xx_i2c_ops,
.size = sizeof(mpc83xx_i2c_bus_tbl[1]),
},
{ /* our private fields */
reg_ptr: &mpc83xx.i2c[1],
initialized: FALSE,
irq_number : BSP_IPIC_IRQ_I2C2,
base_frq : 0 /* will be set during initiailization */
.reg_ptr = &mpc83xx.i2c[1],
.initialized = FALSE,
.irq_number = BSP_IPIC_IRQ_I2C2,
.base_frq = 0 /* will be set during initiailization */
}
}
};
@@ -114,16 +114,21 @@ rtems_status_code bsp_register_i2c
}
i2c2_busno = ret_code;
#ifdef RTEMS_BSP_I2C_EEPROM_DEVICE_NAME
/*
* register EEPROM to bus 1, Address 0x50
*/
ret_code = rtems_libi2c_register_drv(RTEMS_BSP_I2C_EEPROM_DEVICE_NAME,
i2c_2b_eeprom_driver_descriptor,
i2c1_busno,0x50);
if (ret_code < 0) {
return -ret_code;
}
#endif /* RTEMS_BSP_I2C_EEPROM_DEVICE_NAME */
/*
* FIXME: register RTC driver, when available
*/

View File

@@ -20,8 +20,57 @@
#ifndef __GEN83xx_BSP_h
#define __GEN83xx_BSP_h
/*
* MPC8313E Reference Design Board
*/
#ifdef MPC8313ERDB
#define HAS_UBOOT
/* For U-Boot */
#define CONFIG_MPC83XX
#define CONFIG_HAS_ETH1
#endif /* MPC8313ERDB */
#include <libcpu/powerpc-utility.h>
#include <bsp/hwreg_vals.h>
/*
* Some symbols defined in the linker command file.
*/
LINKER_SYMBOL( bsp_ram_start);
LINKER_SYMBOL( bsp_ram_end);
LINKER_SYMBOL( bsp_ram_size);
LINKER_SYMBOL( bsp_rom_start);
LINKER_SYMBOL( bsp_rom_end);
LINKER_SYMBOL( bsp_rom_size);
LINKER_SYMBOL( bsp_section_text_start);
LINKER_SYMBOL( bsp_section_text_end);
LINKER_SYMBOL( bsp_section_text_size);
LINKER_SYMBOL( bsp_section_data_start);
LINKER_SYMBOL( bsp_section_data_end);
LINKER_SYMBOL( bsp_section_data_size);
LINKER_SYMBOL( bsp_section_bss_start);
LINKER_SYMBOL( bsp_section_bss_end);
LINKER_SYMBOL( bsp_section_bss_size);
LINKER_SYMBOL( bsp_interrupt_stack_start);
LINKER_SYMBOL( bsp_interrupt_stack_end);
LINKER_SYMBOL( bsp_interrupt_stack_size);
LINKER_SYMBOL( bsp_interrupt_stack_pointer);
LINKER_SYMBOL( bsp_workspace_start);
LINKER_SYMBOL( IMMRBAR);
#ifndef ASM
#ifdef __cplusplus
@@ -35,6 +84,17 @@ extern "C" {
#include <rtems/clockdrv.h>
#include <bsp/irq.h>
#include <bsp/vectors.h>
#include <bsp/tictac.h>
#ifdef HAS_UBOOT
#include <bsp/u-boot.h>
extern bd_t mpc83xx_uboot_board_info;
extern const size_t mpc83xx_uboot_board_info_size;
#endif /* HAS_UBOOT */
/* miscellaneous stuff assumed to exist */
@@ -96,32 +156,25 @@ rtems_status_code bsp_register_spi(void);
#define SINGLE_CHAR_MODE
#define UARTS_USE_TERMIOS_INT 1
/*
* Convert decrement value to tenths of microsecnds (used by
* shared timer driver).
*
* + CPU has a csb_clock bus,
* + There are 4 bus cycles per click
* + We return value in 1/10 microsecond units.
* Modified following equation to integer equation to remove
* floating point math.
* (int) ((float)(_value) / ((XLB_CLOCK/1000000 * 0.1) / 4.0))
*/
extern unsigned int BSP_bus_frequency;
#define BSP_Convert_decrementer( _value ) \
(int) (((_value) * 4000) / (BSP_bus_frequency/10000))
/*
* Network driver configuration
*/
struct rtems_bsdnet_ifconfig;
extern int BSP_tsec_attach(struct rtems_bsdnet_ifconfig *config,int attaching);
#define RTEMS_BSP_NETWORK_DRIVER_NAME "tsec1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH BSP_tsec_attach
#ifdef MPC8313ERDB
#define RTEMS_BSP_NETWORK_DRIVER_NAME "tsec2"
#define RTEMS_BSP_NETWORK_DRIVER_NAME2 "tsec1"
#else /* MPC8313ERDB */
#define RTEMS_BSP_NETWORK_DRIVER_NAME "tsec1"
#define RTEMS_BSP_NETWORK_DRIVER_NAME2 "tsec2"
#endif /* MPC8313ERDB */
#if defined(MPC8349EAMDS)
/*
* i2c EEPROM device name
@@ -150,6 +203,19 @@ extern int BSP_tsec_attach(struct rtems_bsdnet_ifconfig *config,int attaching);
#define RTEMS_BSP_SPI_FRAM_DEVICE_PATH "/dev/spi.fram"
#endif /* defined(HSC_CM01) */
extern unsigned int BSP_bus_frequency;
extern uint32_t bsp_clicks_per_usec;
/*
* Convert decrementer value to tenths of microseconds (used by shared timer
* driver).
*/
#define BSP_Convert_decrementer( _value ) \
((int) (((_value) * 10) / bsp_clicks_per_usec))
void mpc83xx_zero_4( void *dest, size_t n);
#ifdef __cplusplus
}
#endif

View File

@@ -21,6 +21,7 @@
#define __GEN83xx_HWREG_VALS_h
#include <mpc83xx/mpc83xx.h>
/*
* distinguish board characteristics
*/
@@ -103,36 +104,26 @@
RCWHR_ENDIAN_BIG | \
RCWHR_LALE_NORM | \
RCWHR_LDP_PAR)
#elif defined( HAS_UBOOT)
/* TODO */
#else
#error "board type not defined"
#endif
#if defined(MPC8349EAMDS)
/**************************
* for Freescale MPC8349EAMDS
*/
/*
* address range definitions
*/
/* ROM definitions (8 MB, mirrored multiple times) */
#define ROM_START 0xFE000000
#define ROM_SIZE 0x02000000
#define ROM_END (ROM_START+ROM_SIZE-1)
#define BOOT_START ROM_START
#define BOOT_END ROM_END
/* SDRAM definitions (256 MB) */
#define RAM_START 0x00000000
#define RAM_SIZE 0x10000000
#define RAM_END (RAM_START+RAM_SIZE-1)
/* working internal memory map base address */
#define IMMRBAR 0xE0000000
/*
* working values for various registers, used in start/start.S
*/
/*
* Local Access Windows
* FIXME: decode bit settings
@@ -183,38 +174,21 @@
/**************************
* for JPK HSC_CM01
*/
/*
* address range definitions
*/
/* ROM definitions (8 MB, mirrored multiple times) */
#define ROM_START 0xFE000000
#define ROM_SIZE 0x02000000
#define ROM_END (ROM_START+ROM_SIZE-1)
#define BOOT_START ROM_START
#define BOOT_END ROM_END
/* SDRAM definitions (256 MB) */
#define RAM_START 0x00000000
#define RAM_SIZE 0x10000000
#define RAM_END (RAM_START+RAM_SIZE-1)
/* working internal memory map base address */
#define IMMRBAR 0xE0000000
/*
* working values for various registers, used in start/start.S
*/
/*
* Local Access Windows
* FIXME: decode bit settings
*/
#define LBLAWBAR0_VAL ROM_START
#define LBLAWBAR0_VAL bsp_rom_start
#define LBLAWAR0_VAL 0x80000018
#define LBLAWBAR1_VAL 0xF8000000
#define LBLAWAR1_VAL 0x80000015
#define DDRLAWBAR0_VAL RAM_START
#define DDRLAWBAR0_VAL bsp_ram_start
#define DDRLAWAR0_VAL 0x8000001B
/*
* Local Bus (Memory) Controller
@@ -250,10 +224,16 @@
#define DDR_SDRAM_DATA_INIT_VAL 0xC01DCAFE
#define DDR_SDRAM_INIT_ADDR_VAL 0
#define DDR_SDRAM_INTERVAL_VAL 0x05080000
#else
#error "board type not defined"
#endif
#elif defined( HAS_UBOOT)
/* TODO */
#else
#error "board type not defined"
#endif
/**************************
* derived values for all boards

View File

@@ -0,0 +1,78 @@
/**
* @file
*
* @ingroup bsp_interrupt
*
* @brief BSP interrupt support configuration.
*/
/*
* 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.
*/
#ifndef LIBBSP_POWERPC_GEN83XX_IRQ_CONFIG_H
#define LIBBSP_POWERPC_GEN83XX_IRQ_CONFIG_H
#include <stdint.h>
#include <bsp/irq.h>
/**
* @addtogroup bsp_interrupt
*
* @{
*/
/**
* @brief Minimum vector number.
*/
#define BSP_INTERRUPT_VECTOR_MIN BSP_LOWEST_OFFSET
/**
* @brief Maximum vector number.
*/
#define BSP_INTERRUPT_VECTOR_MAX BSP_MAX_OFFSET
/**
* @brief Enables the index table.
*
* If you enable the index table, you have to define a size for the handler
* table (@ref BSP_INTERRUPT_HANDLER_TABLE_SIZE) and must provide an integer
* type capable to index the complete handler table (@ref
* bsp_interrupt_handler_index_type).
*/
#undef BSP_INTERRUPT_USE_INDEX_TABLE
/**
* @brief Disables usage of the heap.
*
* If you define this, you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as
* well.
*/
#undef BSP_INTERRUPT_NO_HEAP_USAGE
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
/**
* @brief Size of the handler table.
*/
#define BSP_INTERRUPT_HANDLER_TABLE_SIZE 63
/**
* @brief Integer type capable to index the complete handler table.
*/
typedef uint8_t bsp_interrupt_handler_index_type;
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
/** @} */
#endif /* LIBBSP_POWERPC_GEN83XX_IRQ_CONFIG_H */

View File

@@ -19,8 +19,11 @@
#ifndef GEN83xx_IRQ_IRQ_H
#define GEN83xx_IRQ_IRQ_H
#include <stdbool.h>
#include <rtems.h>
#include <rtems/irq.h>
#include <rtems/irq-extension.h>
/*
* the following definitions specify the indices used
@@ -124,16 +127,17 @@ extern "C" {
/* reserved irqs 92-127 */
BSP_IPIC_IRQ_LAST = BSP_IPIC_IRQ_MAX_OFFSET,
BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0
} rtems_irq_symbolic_name;
extern rtems_irq_connect_data *BSP_rtems_irq_tbl;
void BSP_rtems_irq_mng_init(unsigned cpuId);
rtems_status_code mpc83xx_ipic_set_mask( rtems_vector_number vector, rtems_vector_number mask_vector, bool mask);
/* ipic.c */
rtems_status_code BSP_irq_handle_at_ipic(uint32_t excNum);
void BSP_irq_enable_at_ipic (rtems_irq_number irqnum);
void BSP_irq_disable_at_ipic (rtems_irq_number irqnum);
#define MPC83XX_IPIC_INTERRUPT_NORMAL 0
#define MPC83XX_IPIC_INTERRUPT_SYSTEM 1
#define MPC83XX_IPIC_INTERRUPT_CRITICAL 2
rtems_status_code mpc83xx_ipic_set_highest_priority_interrupt( rtems_vector_number vector, int type);
#ifdef __cplusplus
}

View File

@@ -1,408 +0,0 @@
/*===============================================================*\
| Project: RTEMS generic MPC83xx BSP |
+-----------------------------------------------------------------+
| Copyright (c) 2007 |
| 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 integrates the IPIC irq controller |
\*===============================================================*/
#include <mpc83xx/mpc83xx.h>
#include <rtems.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/powerpc/powerpc.h>
typedef struct {
volatile uint32_t *pend_reg;
volatile uint32_t *mask_reg;
const uint32_t bit_num;
} BSP_isrc_rsc_t;
const BSP_isrc_rsc_t BSP_ipic_isrc_rsc[] = {
/* vector 0 */
{&mpc83xx.ipic.sersr,&mpc83xx.ipic.sermr,31},
{NULL,NULL,0},
{NULL,NULL,0},
{NULL,NULL,0},
{NULL,NULL,0},
{NULL,NULL,0},
{NULL,NULL,0},
{NULL,NULL,0},
/* vector 8 */
{NULL,NULL,0}, /* reserved vector 8 */
/* vector 9: UART1 SIxxR_H, Bit 24 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],24},
/* vector 10: UART2 SIxxR_H, Bit 25 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],25},
/* vector 11: SEC SIxxR_H, Bit 26 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],26},
{NULL,NULL,0}, /* reserved vector 12 */
{NULL,NULL,0}, /* reserved vector 13 */
/* vector 14: I2C1 SIxxR_H, Bit 29 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],29},
/* vector 15: I2C2 SIxxR_H, Bit 30 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],30},
/* vector 16: SPI SIxxR_H, Bit 31 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0],31},
/* vector 17: IRQ1 SExxR , Bit 1 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 1},
/* vector 18: IRQ2 SExxR , Bit 2 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 2},
/* vector 19: IRQ3 SExxR , Bit 3 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 3},
/* vector 20: IRQ4 SExxR , Bit 4 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 4},
/* vector 21: IRQ5 SExxR , Bit 5 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 5},
/* vector 22: IRQ6 SExxR , Bit 6 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 6},
/* vector 23: IRQ7 SExxR , Bit 7 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 7},
{NULL,NULL,0}, /* reserved vector 24 */
{NULL,NULL,0}, /* reserved vector 25 */
{NULL,NULL,0}, /* reserved vector 26 */
{NULL,NULL,0}, /* reserved vector 27 */
{NULL,NULL,0}, /* reserved vector 28 */
{NULL,NULL,0}, /* reserved vector 29 */
{NULL,NULL,0}, /* reserved vector 30 */
{NULL,NULL,0}, /* reserved vector 31 */
/* vector 32: TSEC1 Tx SIxxR_H , Bit 0 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 0},
/* vector 33: TSEC1 Rx SIxxR_H , Bit 1 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 1},
/* vector 34: TSEC1 Err SIxxR_H , Bit 2 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 2},
/* vector 35: TSEC2 Tx SIxxR_H , Bit 3 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 3},
/* vector 36: TSEC2 Rx SIxxR_H , Bit 4 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 4},
/* vector 37: TSEC2 Err SIxxR_H , Bit 5 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 5},
/* vector 38: USB DR SIxxR_H , Bit 6 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 6},
/* vector 39: USB MPH SIxxR_H , Bit 7 */
{&mpc83xx.ipic.sipnr[0],&mpc83xx.ipic.simsr[0], 7},
{NULL,NULL,0}, /* reserved vector 40 */
{NULL,NULL,0}, /* reserved vector 41 */
{NULL,NULL,0}, /* reserved vector 42 */
{NULL,NULL,0}, /* reserved vector 43 */
{NULL,NULL,0}, /* reserved vector 44 */
{NULL,NULL,0}, /* reserved vector 45 */
{NULL,NULL,0}, /* reserved vector 46 */
{NULL,NULL,0}, /* reserved vector 47 */
/* vector 48: IRQ0 SExxR , Bit 0 */
{&mpc83xx.ipic.sepnr ,&mpc83xx.ipic.semsr , 0},
{NULL,NULL,0}, /* reserved vector 49 */
{NULL,NULL,0}, /* reserved vector 50 */
{NULL,NULL,0}, /* reserved vector 51 */
{NULL,NULL,0}, /* reserved vector 52 */
{NULL,NULL,0}, /* reserved vector 53 */
{NULL,NULL,0}, /* reserved vector 54 */
{NULL,NULL,0}, /* reserved vector 55 */
{NULL,NULL,0}, /* reserved vector 56 */
{NULL,NULL,0}, /* reserved vector 57 */
{NULL,NULL,0}, /* reserved vector 58 */
{NULL,NULL,0}, /* reserved vector 59 */
{NULL,NULL,0}, /* reserved vector 60 */
{NULL,NULL,0}, /* reserved vector 61 */
{NULL,NULL,0}, /* reserved vector 62 */
{NULL,NULL,0}, /* reserved vector 63 */
/* vector 64: RTC SEC SIxxR_L , Bit 0 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 0},
/* vector 65: PIT SIxxR_L , Bit 1 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 1},
/* vector 66: PCI1 SIxxR_L , Bit 2 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 2},
/* vector 67: PCI2 SIxxR_L , Bit 3 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 3},
/* vector 68: RTC ALR SIxxR_L , Bit 4 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 4},
/* vector 69: MU SIxxR_L , Bit 5 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 5},
/* vector 70: SBA SIxxR_L , Bit 6 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 6},
/* vector 71: DMA SIxxR_L , Bit 7 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 7},
/* vector 72: GTM4 SIxxR_L , Bit 8 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 8},
/* vector 73: GTM8 SIxxR_L , Bit 9 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1], 9},
/* vector 74: GPIO1 SIxxR_L , Bit 10 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],10},
/* vector 75: GPIO2 SIxxR_L , Bit 11 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],11},
/* vector 76: DDR SIxxR_L , Bit 12 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],12},
/* vector 77: LBC SIxxR_L , Bit 13 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],13},
/* vector 78: GTM2 SIxxR_L , Bit 14 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],14},
/* vector 79: GTM6 SIxxR_L , Bit 15 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],15},
/* vector 80: PMC SIxxR_L , Bit 16 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],16},
{NULL,NULL,0}, /* reserved vector 81 */
{NULL,NULL,0}, /* reserved vector 82 */
{NULL,NULL,0}, /* reserved vector 63 */
/* vector 84: GTM3 SIxxR_L , Bit 20 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],20},
/* vector 85: GTM7 SIxxR_L , Bit 21 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],21},
{NULL,NULL,0}, /* reserved vector 81 */
{NULL,NULL,0}, /* reserved vector 82 */
{NULL,NULL,0}, /* reserved vector 63 */
{NULL,NULL,0}, /* reserved vector 63 */
/* vector 90: GTM1 SIxxR_L , Bit 26 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],26},
/* vector 91: GTM5 SIxxR_L , Bit 27 */
{&mpc83xx.ipic.sipnr[1],&mpc83xx.ipic.simsr[1],27}
};
/*
* data structure to handle all mask registers in the IPIC
*/
typedef struct {
uint32_t simsr_mask[2];
uint32_t semsr_mask;
uint32_t sermr_mask;
} BSP_ipic_mask_t;
/*
* this array will be filled with mask values needed
* to temporarily disable all IRQ soures with lower or same
* priority of the current source (whose vector is the array index)
*/
BSP_ipic_mask_t BSP_ipic_prio2mask[BSP_ARRAY_CNT(BSP_ipic_isrc_rsc)];
/*
* functions to enable/disable a source at the ipic
*/
void BSP_irq_enable_at_ipic (rtems_irq_number irqnum)
{
uint32_t vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET;
const BSP_isrc_rsc_t *rsc_ptr;
if ((vecnum >= 0)
&& (vecnum < BSP_ARRAY_CNT(BSP_ipic_isrc_rsc))) {
rsc_ptr = &BSP_ipic_isrc_rsc[vecnum];
if (rsc_ptr->mask_reg != NULL) {
*(rsc_ptr->mask_reg) |= 1 << (31-rsc_ptr->bit_num);
}
}
}
void BSP_irq_disable_at_ipic (rtems_irq_number irqnum)
{
uint32_t vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET;
const BSP_isrc_rsc_t *rsc_ptr;
if ((vecnum >= 0)
&& (vecnum < BSP_ARRAY_CNT(BSP_ipic_isrc_rsc))) {
rsc_ptr = &BSP_ipic_isrc_rsc[vecnum];
if (rsc_ptr->mask_reg != NULL) {
*(rsc_ptr->mask_reg) &= ~(1 << (31-rsc_ptr->bit_num));
}
}
}
/*
* IRQ Handler: this is called from the primary exception dispatcher
*/
rtems_status_code BSP_irq_handle_at_ipic(uint32_t excNum)
{
rtems_status_code rc = RTEMS_SUCCESSFUL;
rtems_irq_connect_data *tbl_entry;
int32_t vecnum;
uint32_t msr_value;
uint32_t msr_save;
uint32_t msr_enable = 0;
BSP_ipic_mask_t mask_save;
const BSP_ipic_mask_t *mask_ptr;
/*
* get vector
*/
switch(excNum) {
case ASM_EXT_VECTOR:
vecnum = MPC83xx_VCR_TO_VEC(mpc83xx.ipic.sivcr);
msr_enable = PPC_MSR_EE;
break;
case ASM_60X_SYSMGMT_VECTOR:
vecnum = MPC83xx_VCR_TO_VEC(mpc83xx.ipic.smvcr);
msr_enable = PPC_MSR_EE;
break;
#if defined(ASM_BOOKE_CRIT_VECTOR)
case ASM_BOOKE_CRIT_VECTOR:
vecnum = MPC83xx_VCR_TO_VEC(mpc83xx.ipic.scvcr);
break;
#endif
default:
vecnum = -1;
}
/*
* check vector number
*/
if ((vecnum >= 0)
&& (vecnum < BSP_ARRAY_CNT(BSP_ipic_isrc_rsc))) {
/*
* save current mask registers
*/
mask_save.simsr_mask[0] = mpc83xx.ipic.simsr[0];
mask_save.simsr_mask[1] = mpc83xx.ipic.simsr[1];
mask_save.semsr_mask = mpc83xx.ipic.semsr ;
mask_save.sermr_mask = mpc83xx.ipic.sermr ;
/*
* mask all lower prio interrupts
*/
mask_ptr = &BSP_ipic_prio2mask[vecnum];
mpc83xx.ipic.simsr[0] &= mask_ptr->simsr_mask[0];
mpc83xx.ipic.simsr[1] &= mask_ptr->simsr_mask[1];
mpc83xx.ipic.semsr &= mask_ptr->semsr_mask ;
mpc83xx.ipic.sermr &= mask_ptr->sermr_mask ;
/*
* make sure, that the masking operations in
* ICTL and MSR are executed in order
*/
asm volatile("sync":::"memory");
/*
* reenable msr_ee
*/
_CPU_MSR_GET(msr_value);
msr_save = msr_value;
msr_value |= msr_enable;
_CPU_MSR_SET(msr_value);
/*
* call handler
*/
tbl_entry = &BSP_rtems_irq_tbl[vecnum+BSP_IPIC_IRQ_LOWEST_OFFSET];
if (tbl_entry->hdl != NULL) {
(tbl_entry->hdl) (tbl_entry->handle);
} else {
printk("IPIC: Spurious interrupt; excNum=0x%x, vector=0x%02x\n\r",
excNum,vecnum);
}
/*
* disable msr_enable
*/
_CPU_MSR_SET(msr_save);
/*
* make sure, that the masking operations in
* ICTL and MSR are executed in order
*/
asm volatile("sync":::"memory");
/*
* restore initial masks
*/
mpc83xx.ipic.simsr[0] = mask_save.simsr_mask[0];
mpc83xx.ipic.simsr[1] = mask_save.simsr_mask[1];
mpc83xx.ipic.semsr = mask_save.semsr_mask ;
mpc83xx.ipic.sermr = mask_save.sermr_mask ;
}
return rc;
}
/*
* fill the array BSP_ipic_prio2mask to allow masking of lower prio sources
* to implement nested interrupts
*/
rtems_status_code BSP_ipic_calc_prio2mask(void)
{
rtems_status_code rc = RTEMS_SUCCESSFUL;
/*
* FIXME: fill the array
*/
return rc;
}
/*
* activate the interrupt controller
*/
rtems_status_code BSP_ipic_intc_init(void)
{
uint32_t msr_value;
rtems_status_code rc = RTEMS_SUCCESSFUL;
/*
* mask off all interrupts
*/
mpc83xx.ipic.simsr[0] = 0;
mpc83xx.ipic.simsr[1] = 0;
mpc83xx.ipic.semsr = 0;
mpc83xx.ipic.sermr = 0;
/*
* set desired configuration as defined in bspopts.h
* normally, the default values should be fine
*/
#if defined(BSP_SICFR_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.sicfr = BSP_SICFR_VAL;
#endif
/*
* set desired priorities as defined in bspopts.h
* normally, the default values should be fine
*/
#if defined(BSP_SIPRR0_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr[0] = BSP_SIPRR0_VAL;
#endif
#if defined(BSP_SIPRR1_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr[1] = BSP_SIPRR1_VAL;
#endif
#if defined(BSP_SIPRR2_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr[2] = BSP_SIPRR2_VAL;
#endif
#if defined(BSP_SIPRR3_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr[3] = BSP_SIPRR3_VAL;
#endif
#if defined(BSP_SMPRR0_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.smprr[0] = BSP_SMPRR0_VAL;
#endif
#if defined(BSP_SMPRR1_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.smprr[1] = BSP_SMPRR1_VAL;
#endif
#if defined(BSP_SECNR_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.secnr = BSP_SECNR_VAL;
#endif
/*
* calculate priority masks
*/
rc = BSP_ipic_calc_prio2mask();
if (rc == RTEMS_SUCCESSFUL) {
/*
* enable (non-critical) exceptions
*/
_CPU_MSR_GET(msr_value);
msr_value |= PPC_MSR_EE;
_CPU_MSR_SET(msr_value);
/* install exit handler to close ipic when program atexit called */
/* atexit(ipic_intc_exit); */
}
return rc;
}

View File

@@ -0,0 +1,576 @@
/*===============================================================*\
| Project: RTEMS generic MPC83xx BSP |
+-----------------------------------------------------------------+
| Copyright (c) 2007 |
| 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 integrates the IPIC irq controller |
\*===============================================================*/
#include <mpc83xx/mpc83xx.h>
#include <rtems.h>
#include <libcpu/powerpc-utility.h>
#include <libcpu/raw_exception.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/vectors.h>
#include <bsp/ppc_exc_bspsupp.h>
#include <bsp/irq-generic.h>
#define MPC83XX_IPIC_VECTOR_NUMBER 92
#define MPC83XX_IPIC_IS_VALID_VECTOR( vector) ((vector) >= 0 && (vector) < MPC83XX_IPIC_VECTOR_NUMBER)
#define MPC83XX_IPIC_INVALID_MASK_POSITION 255
typedef struct {
volatile uint32_t *pend_reg;
volatile uint32_t *mask_reg;
const uint32_t bit_num;
} BSP_isrc_rsc_t;
/*
* data structure to handle all mask registers in the IPIC
*
* Mask positions:
* simsr [0] : 0 .. 31
* simsr [1] : 32 .. 63
* semsr : 64 .. 95
* sermr : 96 .. 127
*/
typedef struct {
uint32_t simsr_mask [2];
uint32_t semsr_mask;
uint32_t sermr_mask;
} mpc83xx_ipic_mask_t;
static const BSP_isrc_rsc_t mpc83xx_ipic_isrc_rsc [MPC83XX_IPIC_VECTOR_NUMBER] = {
/* vector 0 */
{&mpc83xx.ipic.sersr, &mpc83xx.ipic.sermr, 31},
{NULL, NULL, 0},
{NULL, NULL, 0},
{NULL, NULL, 0},
{NULL, NULL, 0},
{NULL, NULL, 0},
{NULL, NULL, 0},
{NULL, NULL, 0},
/* vector 8 */
{NULL, NULL, 0}, /* reserved vector 8 */
/* vector 9: UART1 SIxxR_H, Bit 24 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 24},
/* vector 10: UART2 SIxxR_H, Bit 25 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 25},
/* vector 11: SEC SIxxR_H, Bit 26 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 26},
{NULL, NULL, 0}, /* reserved vector 12 */
{NULL, NULL, 0}, /* reserved vector 13 */
/* vector 14: I2C1 SIxxR_H, Bit 29 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 29},
/* vector 15: I2C2 SIxxR_H, Bit 30 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 30},
/* vector 16: SPI SIxxR_H, Bit 31 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 31},
/* vector 17: IRQ1 SExxR , Bit 1 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 1},
/* vector 18: IRQ2 SExxR , Bit 2 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 2},
/* vector 19: IRQ3 SExxR , Bit 3 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 3},
/* vector 20: IRQ4 SExxR , Bit 4 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 4},
/* vector 21: IRQ5 SExxR , Bit 5 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 5},
/* vector 22: IRQ6 SExxR , Bit 6 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 6},
/* vector 23: IRQ7 SExxR , Bit 7 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 7},
{NULL, NULL, 0}, /* reserved vector 24 */
{NULL, NULL, 0}, /* reserved vector 25 */
{NULL, NULL, 0}, /* reserved vector 26 */
{NULL, NULL, 0}, /* reserved vector 27 */
{NULL, NULL, 0}, /* reserved vector 28 */
{NULL, NULL, 0}, /* reserved vector 29 */
{NULL, NULL, 0}, /* reserved vector 30 */
{NULL, NULL, 0}, /* reserved vector 31 */
/* vector 32: TSEC1 Tx SIxxR_H , Bit 0 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 0},
/* vector 33: TSEC1 Rx SIxxR_H , Bit 1 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 1},
/* vector 34: TSEC1 Err SIxxR_H , Bit 2 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 2},
/* vector 35: TSEC2 Tx SIxxR_H , Bit 3 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 3},
/* vector 36: TSEC2 Rx SIxxR_H , Bit 4 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 4},
/* vector 37: TSEC2 Err SIxxR_H , Bit 5 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 5},
/* vector 38: USB DR SIxxR_H , Bit 6 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 6},
/* vector 39: USB MPH SIxxR_H , Bit 7 */
{&mpc83xx.ipic.sipnr [0], &mpc83xx.ipic.simsr [0], 7},
{NULL, NULL, 0}, /* reserved vector 40 */
{NULL, NULL, 0}, /* reserved vector 41 */
{NULL, NULL, 0}, /* reserved vector 42 */
{NULL, NULL, 0}, /* reserved vector 43 */
{NULL, NULL, 0}, /* reserved vector 44 */
{NULL, NULL, 0}, /* reserved vector 45 */
{NULL, NULL, 0}, /* reserved vector 46 */
{NULL, NULL, 0}, /* reserved vector 47 */
/* vector 48: IRQ0 SExxR , Bit 0 */
{&mpc83xx.ipic.sepnr, &mpc83xx.ipic.semsr, 0},
{NULL, NULL, 0}, /* reserved vector 49 */
{NULL, NULL, 0}, /* reserved vector 50 */
{NULL, NULL, 0}, /* reserved vector 51 */
{NULL, NULL, 0}, /* reserved vector 52 */
{NULL, NULL, 0}, /* reserved vector 53 */
{NULL, NULL, 0}, /* reserved vector 54 */
{NULL, NULL, 0}, /* reserved vector 55 */
{NULL, NULL, 0}, /* reserved vector 56 */
{NULL, NULL, 0}, /* reserved vector 57 */
{NULL, NULL, 0}, /* reserved vector 58 */
{NULL, NULL, 0}, /* reserved vector 59 */
{NULL, NULL, 0}, /* reserved vector 60 */
{NULL, NULL, 0}, /* reserved vector 61 */
{NULL, NULL, 0}, /* reserved vector 62 */
{NULL, NULL, 0}, /* reserved vector 63 */
/* vector 64: RTC SEC SIxxR_L , Bit 0 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 0},
/* vector 65: PIT SIxxR_L , Bit 1 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 1},
/* vector 66: PCI1 SIxxR_L , Bit 2 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 2},
/* vector 67: PCI2 SIxxR_L , Bit 3 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 3},
/* vector 68: RTC ALR SIxxR_L , Bit 4 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 4},
/* vector 69: MU SIxxR_L , Bit 5 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 5},
/* vector 70: SBA SIxxR_L , Bit 6 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 6},
/* vector 71: DMA SIxxR_L , Bit 7 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 7},
/* vector 72: GTM4 SIxxR_L , Bit 8 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 8},
/* vector 73: GTM8 SIxxR_L , Bit 9 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 9},
/* vector 74: GPIO1 SIxxR_L , Bit 10 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 10},
/* vector 75: GPIO2 SIxxR_L , Bit 11 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 11},
/* vector 76: DDR SIxxR_L , Bit 12 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 12},
/* vector 77: LBC SIxxR_L , Bit 13 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 13},
/* vector 78: GTM2 SIxxR_L , Bit 14 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 14},
/* vector 79: GTM6 SIxxR_L , Bit 15 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 15},
/* vector 80: PMC SIxxR_L , Bit 16 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 16},
{NULL, NULL, 0}, /* reserved vector 81 */
{NULL, NULL, 0}, /* reserved vector 82 */
{NULL, NULL, 0}, /* reserved vector 63 */
/* vector 84: GTM3 SIxxR_L , Bit 20 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 20},
/* vector 85: GTM7 SIxxR_L , Bit 21 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 21},
{NULL, NULL, 0}, /* reserved vector 81 */
{NULL, NULL, 0}, /* reserved vector 82 */
{NULL, NULL, 0}, /* reserved vector 63 */
{NULL, NULL, 0}, /* reserved vector 63 */
/* vector 90: GTM1 SIxxR_L , Bit 26 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 26},
/* vector 91: GTM5 SIxxR_L , Bit 27 */
{&mpc83xx.ipic.sipnr [1], &mpc83xx.ipic.simsr [1], 27}
};
static const uint8_t mpc83xx_ipic_mask_position_table [MPC83XX_IPIC_VECTOR_NUMBER] = {
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
7,
6,
5,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
2,
1,
0,
94,
93,
92,
91,
90,
89,
88,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
31,
30,
29,
28,
27,
26,
25,
24,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
95,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
63,
62,
61,
60,
59,
58,
57,
56,
55,
54,
53,
52,
51,
50,
49,
48,
47,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
43,
42,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
MPC83XX_IPIC_INVALID_MASK_POSITION,
37,
36
};
/*
* this array will be filled with mask values needed
* to temporarily disable all IRQ soures with lower or same
* priority of the current source (whose vector is the array index)
*/
static mpc83xx_ipic_mask_t mpc83xx_ipic_prio2mask [MPC83XX_IPIC_VECTOR_NUMBER];
rtems_status_code mpc83xx_ipic_set_mask( rtems_vector_number vector, rtems_vector_number mask_vector, bool mask)
{
uint8_t pos = 0;
mpc83xx_ipic_mask_t *mask_entry;
uint32_t *mask_reg;
rtems_interrupt_level level;
/* Parameter check */
if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector) || !MPC83XX_IPIC_IS_VALID_VECTOR( mask_vector)) {
return RTEMS_INVALID_NUMBER;
} else if (vector == mask_vector) {
return RTEMS_RESOURCE_IN_USE;
}
/* Position and mask entry */
pos = mpc83xx_ipic_mask_position_table [mask_vector];
mask_entry = &mpc83xx_ipic_prio2mask [vector];
/* Mask register and position */
if (pos < 32) {
mask_reg = &mask_entry->simsr_mask [0];
} else if (pos < 64) {
pos -= 32;
mask_reg = &mask_entry->simsr_mask [1];
} else if (pos < 96) {
pos -= 64;
mask_reg = &mask_entry->semsr_mask;
} else if (pos < 128) {
pos -= 96;
mask_reg = &mask_entry->sermr_mask;
} else {
return RTEMS_NOT_IMPLEMENTED;
}
/* Mask or unmask */
if (mask) {
rtems_interrupt_disable( level);
*mask_reg &= ~(1 << pos);
rtems_interrupt_enable( level);
} else {
rtems_interrupt_disable( level);
*mask_reg |= 1 << pos;
rtems_interrupt_enable( level);
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_ipic_set_highest_priority_interrupt( rtems_vector_number vector, int type)
{
rtems_interrupt_level level;
uint32_t reg = 0;
if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector)) {
return RTEMS_INVALID_NUMBER;
} else if (type < 0 || type > MPC83XX_IPIC_INTERRUPT_CRITICAL) {
return RTEMS_INVALID_NUMBER;
}
rtems_interrupt_disable( level);
reg = mpc83xx.ipic.sicfr;
mpc83xx.ipic.sicfr = (reg & ~0x7f000300) | (vector << 24) | (type << 8);
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
/*
* functions to enable/disable a source at the ipic
*/
rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqnum)
{
rtems_vector_number vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET;
const BSP_isrc_rsc_t *rsc_ptr;
if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
if (rsc_ptr->mask_reg != NULL) {
*(rsc_ptr->mask_reg) |= 1 << (31 - rsc_ptr->bit_num);
}
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum)
{
rtems_vector_number vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET;
const BSP_isrc_rsc_t *rsc_ptr;
if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum];
if (rsc_ptr->mask_reg != NULL) {
*(rsc_ptr->mask_reg) &= ~(1 << (31 - rsc_ptr->bit_num));
}
}
return RTEMS_SUCCESSFUL;
}
/*
* IRQ Handler: this is called from the primary exception dispatcher
*/
static int BSP_irq_handle_at_ipic( unsigned excNum)
{
int32_t vecnum;
mpc83xx_ipic_mask_t mask_save;
const mpc83xx_ipic_mask_t *mask_ptr;
uint32_t msr;
rtems_interrupt_level level;
/* Get vector number */
switch (excNum) {
case ASM_EXT_VECTOR:
vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.sivcr);
break;
case ASM_E300_SYSMGMT_VECTOR:
vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.smvcr);
break;
case ASM_E300_CRIT_VECTOR:
vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.scvcr);
break;
default:
return 1;
}
/*
* Check the vector number, mask lower priority interrupts, enable
* exceptions and dispatch the handler.
*/
if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) {
mask_ptr = &mpc83xx_ipic_prio2mask [vecnum];
rtems_interrupt_disable( level);
/* Save current mask registers */
mask_save.simsr_mask [0] = mpc83xx.ipic.simsr [0];
mask_save.simsr_mask [1] = mpc83xx.ipic.simsr [1];
mask_save.semsr_mask = mpc83xx.ipic.semsr;
mask_save.sermr_mask = mpc83xx.ipic.sermr;
/* Mask all lower priority interrupts */
mpc83xx.ipic.simsr [0] &= mask_ptr->simsr_mask [0];
mpc83xx.ipic.simsr [1] &= mask_ptr->simsr_mask [1];
mpc83xx.ipic.semsr &= mask_ptr->semsr_mask;
mpc83xx.ipic.sermr &= mask_ptr->sermr_mask;
rtems_interrupt_enable( level);
/* Enable all interrupts */
if (excNum != ASM_E300_CRIT_VECTOR) {
msr = ppc_external_exceptions_enable();
}
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( vecnum + BSP_IPIC_IRQ_LOWEST_OFFSET);
/* Restore machine state */
if (excNum != ASM_E300_CRIT_VECTOR) {
ppc_external_exceptions_disable( msr);
}
/* Restore initial masks */
rtems_interrupt_disable( level);
mpc83xx.ipic.simsr [0] = mask_save.simsr_mask [0];
mpc83xx.ipic.simsr [1] = mask_save.simsr_mask [1];
mpc83xx.ipic.semsr = mask_save.semsr_mask;
mpc83xx.ipic.sermr = mask_save.sermr_mask;
rtems_interrupt_enable( level);
} else {
bsp_interrupt_handler_default( vecnum);
}
return 0;
}
/*
* Fill the array mpc83xx_ipic_prio2mask to allow masking of lower prio sources
* to implement nested interrupts.
*/
rtems_status_code mpc83xx_ipic_calc_prio2mask( void)
{
rtems_status_code rc = RTEMS_SUCCESSFUL;
/*
* FIXME: fill the array
*/
return rc;
}
/*
* Activate the interrupt controller
*/
rtems_status_code mpc83xx_ipic_initialize( void)
{
/*
* mask off all interrupts
*/
mpc83xx.ipic.simsr [0] = 0;
mpc83xx.ipic.simsr [1] = 0;
mpc83xx.ipic.semsr = 0;
mpc83xx.ipic.sermr = 0;
/*
* set desired configuration as defined in bspopts.h
* normally, the default values should be fine
*/
#if defined( BSP_SICFR_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.sicfr = BSP_SICFR_VAL;
#endif
/*
* set desired priorities as defined in bspopts.h
* normally, the default values should be fine
*/
#if defined( BSP_SIPRR0_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr [0] = BSP_SIPRR0_VAL;
#endif
#if defined( BSP_SIPRR1_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr [1] = BSP_SIPRR1_VAL;
#endif
#if defined( BSP_SIPRR2_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr [2] = BSP_SIPRR2_VAL;
#endif
#if defined( BSP_SIPRR3_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.siprr [3] = BSP_SIPRR3_VAL;
#endif
#if defined( BSP_SMPRR0_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.smprr [0] = BSP_SMPRR0_VAL;
#endif
#if defined( BSP_SMPRR1_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.smprr [1] = BSP_SMPRR1_VAL;
#endif
#if defined( BSP_SECNR_VAL) /* defined in bspopts.h ? */
mpc83xx.ipic.secnr = BSP_SECNR_VAL;
#endif
/*
* calculate priority masks
*/
return mpc83xx_ipic_calc_prio2mask();
}
int mpc83xx_exception_handler( BSP_Exception_frame *frame, unsigned exception_number)
{
return BSP_irq_handle_at_ipic( exception_number);
}
rtems_status_code bsp_interrupt_facility_initialize()
{
/* Install exception handler */
if (ppc_exc_set_handler( ASM_EXT_VECTOR, mpc83xx_exception_handler)) {
return RTEMS_IO_ERROR;
}
if (ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, mpc83xx_exception_handler)) {
return RTEMS_IO_ERROR;
}
if (ppc_exc_set_handler( ASM_E300_CRIT_VECTOR, mpc83xx_exception_handler)) {
return RTEMS_IO_ERROR;
}
/* Initialize the interrupt controller */
return mpc83xx_ipic_initialize();
}
void bsp_interrupt_handler_default( rtems_vector_number vector)
{
printk( "Spurious interrupt: 0x%08x\n", vector);
}

View File

@@ -1,417 +0,0 @@
/*===============================================================*\
| Project: RTEMS generic MPC83xx BSP |
+-----------------------------------------------------------------+
| Copyright (c) 2007 |
| 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 irq controller init code |
+-----------------------------------------------------------------+
| derived from the virtex BSP |
\*===============================================================*/
#include <libcpu/spr.h>
#include <bsp/irq.h>
#include <bsp.h>
#include <libcpu/raw_exception.h>
#include <rtems/bspIo.h>
#include <rtems/powerpc/powerpc.h>
#include <rtems/score/apiext.h>
#include <bsp/vectors.h>
static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
rtems_irq_connect_data *BSP_rtems_irq_tbl;
rtems_irq_global_settings* BSP_rtems_irq_config;
/***********************************************************
* dummy functions for on/off/isOn calls
* these functions just do nothing fulfill the semantic
* requirements to enable/disable a certain interrupt or exception
*/
void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
{
/*
* nothing to do
*/
}
void BSP_irq_nop_hdl(void *hdl)
{
/*
* nothing to do
*/
}
int BSP_irq_true_func(const rtems_irq_connect_data *unused)
{
/*
* nothing to do
*/
return TRUE;
}
/***********************************************************
* interrupt handler and its enable/disable functions
***********************************************************/
/***********************************************************
* functions to enable/disable/query external/critical interrupts
*/
void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
{
uint32_t msr_value;
/*
* get current MSR value
*/
_CPU_MSR_GET(msr_value);
msr_value |= PPC_MSR_EE;
_CPU_MSR_SET(msr_value);
}
void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
{
/*
* nothing to do
*/
}
/***********************************************************
* High level IRQ handler called from shared_raw_irq_code_entry
*/
int C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
{
uint32_t msr_value,new_msr;
/*
* Handle interrupt
*/
switch(excNum) {
case ASM_DEC_VECTOR:
_CPU_MSR_GET(msr_value);
new_msr = msr_value | MSR_EE;
_CPU_MSR_SET(new_msr);
BSP_rtems_irq_tbl[BSP_DECREMENTER].hdl
(BSP_rtems_irq_tbl[BSP_DECREMENTER].handle);
_CPU_MSR_SET(msr_value);
break;
#if 0 /* Critical interrupts not yet supported */
case ASM_BOOKE_CRIT_VECTOR:
#endif
case ASM_60X_SYSMGMT_VECTOR:
case ASM_EXT_VECTOR:
BSP_irq_handle_at_ipic(excNum);
break;
}
return 0;
}
void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
{
/*
* Process pending signals that have not already been
* processed by _Thread_Displatch. This happens quite
* unfrequently : the ISR must have posted an action
* to the current running thread.
*/
if ( _Thread_Do_post_task_switch_extension ||
_Thread_Executing->do_post_task_switch_extension ) {
_Thread_Executing->do_post_task_switch_extension = FALSE;
_API_extensions_Run_postswitch();
}
}
/***********************************************************
* functions to set/get/remove interrupt handlers
***********************************************************/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_interrupt_level level;
/*
* check for valid irq name
* if invalid, print error and return 0
*/
if (!BSP_IS_VALID_IRQ(irq->name)) {
printk("Invalid interrupt vector %d\n",irq->name);
return 0;
}
/*
* disable interrupts
*/
rtems_interrupt_disable(level);
/*
* check, that default handler is installed now
*/
if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
rtems_interrupt_enable(level);
printk("IRQ vector %d already connected\n",irq->name);
return 0;
}
/*
* store new handler data
*/
rtemsIrqTbl[irq->name] = *irq;
/*
* enable irq at interrupt controller
*/
if (BSP_IS_IPIC_IRQ(irq->name)) {
BSP_irq_enable_at_ipic(irq->name);
}
/*
* call "on" function to enable interrupt at device
*/
irq->on(irq);
/*
* reenable interrupts
*/
rtems_interrupt_enable(level);
return 1;
}
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
{
rtems_interrupt_level level;
/*
* check for valid IRQ name
*/
if (!BSP_IS_VALID_IRQ(irq->name)) {
return 0;
}
rtems_interrupt_disable(level);
/*
* return current IRQ entry
*/
*irq = rtemsIrqTbl[irq->name];
rtems_interrupt_enable(level);
return 1;
}
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_interrupt_level level;
/*
* check for valid IRQ name
*/
if (!BSP_IS_VALID_IRQ(irq->name)) {
return 0;
}
rtems_interrupt_disable(level);
/*
* check, that specified handler is really connected now
*/
if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
rtems_interrupt_enable(level);
return 0;
}
/*
* disable interrupt at interrupt controller
*/
if (BSP_IS_IPIC_IRQ(irq->name)) {
BSP_irq_disable_at_ipic(irq->name);
}
/*
* disable interrupt at source
*/
irq->off(irq);
/*
* restore default interrupt handler
*/
rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
/*
* reenable interrupts
*/
rtems_interrupt_enable(level);
return 1;
}
/***********************************************************
* functions to set/get the basic interrupt management setup
***********************************************************/
/*
* (Re) get info on current RTEMS interrupt management.
*/
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
{
*ret_ptr = BSP_rtems_irq_config;
return 0;
}
/*
* set management stuff
*/
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
{
int i;
rtems_interrupt_level level;
rtems_interrupt_disable(level);
/*
* store given configuration
*/
BSP_rtems_irq_config = config;
BSP_rtems_irq_tbl = BSP_rtems_irq_config->irqHdlTbl;
/*
* enable any non-empty IRQ entries at OPBINTC
*/
for (i = BSP_IPIC_IRQ_LOWEST_OFFSET;
i <= BSP_IPIC_IRQ_MAX_OFFSET;
i++) {
if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
BSP_irq_enable_at_ipic(i);
BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
}
else {
BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
BSP_irq_disable_at_ipic(i);
}
}
/*
* store any irq-like processor exceptions
*/
for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
i++) {
if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
if (BSP_rtems_irq_tbl[i].on != NULL) {
BSP_rtems_irq_tbl[i].on
(&(BSP_rtems_irq_tbl[i]));
}
}
else {
if (BSP_rtems_irq_tbl[i].off != NULL) {
BSP_rtems_irq_tbl[i].off
(&(BSP_rtems_irq_tbl[i]));
}
}
}
rtems_interrupt_enable(level);
return 1;
}
/**********************************************
* list of exception vectors to tap for interrupt handlers
*/
static rtems_raw_except_connect_data BSP_vec_desc[] = {
#if defined(ASM_DEC_VECTOR)
{ASM_DEC_VECTOR,
{ASM_DEC_VECTOR,
decrementer_exception_vector_prolog_code,
(size_t)decrementer_exception_vector_prolog_code_size
},
exception_nop_enable,
exception_nop_enable,
exception_always_enabled
},
#endif
#if defined(ASM_60X_SYSMGMT_VECTOR)
{ASM_60X_SYSMGMT_VECTOR,
{ASM_60X_SYSMGMT_VECTOR,
sysmgmt_exception_vector_prolog_code,
(size_t)sysmgmt_exception_vector_prolog_code_size
},
exception_nop_enable,
exception_nop_enable,
exception_always_enabled
},
#endif
{ASM_EXT_VECTOR,
{ASM_EXT_VECTOR,
external_exception_vector_prolog_code,
(size_t)&external_exception_vector_prolog_code_size
},
exception_nop_enable,
exception_nop_enable,
exception_always_enabled
}
#if 0 /* Critical interrupts not yet supported */
,{ASM_BOOKE_CRIT_VECTOR,
{ASM_BOOKE_CRIT_VECTOR,
critical_exception_vector_prolog_code,
critical_exception_vector_prolog_code_size
}
BSP_irq_nop_func,
BSP_irq_nop_func,
BSP_irq_true_func
}
#endif
};
/*
* dummy for an empty IRQ handler entry
*/
static rtems_irq_connect_data emptyIrq = {
0, /* Irq Name */
BSP_irq_nop_hdl, /* handler function */
NULL, /* handle passed to handler */
BSP_irq_nop_func, /* on function */
BSP_irq_nop_func, /* off function */
BSP_irq_true_func /* isOn function */
};
static rtems_irq_global_settings initialConfig = {
BSP_IRQ_NUMBER, /* irqNb */
{ 0, /* Irq Name */
BSP_irq_nop_hdl, /* handler function */
NULL, /* handle passed to handler */
BSP_irq_nop_func, /* on function */
BSP_irq_nop_func, /* off function */
BSP_irq_true_func /* isOn function */
}, /* emptyIrq */
rtemsIrqTbl, /* irqHdlTbl */
0, /* irqBase */
NULL /* irqPrioTbl */
};
void BSP_rtems_irq_mng_init(unsigned cpuId)
{
int i;
/*
* connect all exception vectors needed
*/
for (i = 0;
i < (sizeof(BSP_vec_desc) /
sizeof(BSP_vec_desc[0]));
i++) {
if (!ppc_set_exception (&BSP_vec_desc[i])) {
BSP_panic("Unable to initialize RTEMS raw exception\n");
}
}
/*
* setup interrupt handlers table
*/
for (i = 0;
i < BSP_IRQ_NUMBER;
i++) {
rtemsIrqTbl[i] = emptyIrq;
rtemsIrqTbl[i].name = i;
}
/*
* initialize interrupt management
*/
if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
}
}

View File

@@ -29,12 +29,22 @@
#define TSEC_IFMODE_RGMII 0
#define TSEC_IFMODE_GMII 1
#if defined(MPC8349EAMDS)
#define TSEC_IFMODE TSEC_IFMODE_RGMII
#endif
#if defined( MPC8313ERDB)
#if defined(HSC_CM01)
#define TSEC_IFMODE TSEC_IFMODE_RGMII
#elif defined( MPC8349EAMDS)
#define TSEC_IFMODE TSEC_IFMODE_RGMII
#elif defined( HSC_CM01)
#define TSEC_IFMODE TSEC_IFMODE_RGMII
#else
#warning No TSEC configuration available
#endif
/*=========================================================================*\
@@ -56,7 +66,6 @@ int BSP_tsec_attach
| 1, if success |
\*=========================================================================*/
{
char hw_addr[6] = {0x00,0x04,0x9F,0x00,0x2f,0xcb};
int unitNumber;
char *unitName;
@@ -100,7 +109,44 @@ int BSP_tsec_attach
* FIXME: get the real address we need
*/
if (config->hardware_address == NULL) {
#ifdef HAS_UBOOT
switch (unitNumber) {
case 1:
config->hardware_address = mpc83xx_uboot_board_info.bi_enetaddr;
break;
#ifdef CONFIG_HAS_ETH1
case 2:
config->hardware_address = mpc83xx_uboot_board_info.bi_enet1addr;
break;
#endif /* CONFIG_HAS_ETH1 */
#ifdef CONFIG_HAS_ETH2
case 3:
config->hardware_address = mpc83xx_uboot_board_info.bi_enet2addr;
break;
#endif /* CONFIG_HAS_ETH2 */
#ifdef CONFIG_HAS_ETH3
case 4:
config->hardware_address = mpc83xx_uboot_board_info.bi_enet3addr;
break;
#endif /* CONFIG_HAS_ETH3 */
default:
return 0;
}
#else /* HAS_UBOOT */
char hw_addr [6] = { 0x00, 0x04, 0x9f, 0x00, 0x2f, 0xcb};
config->hardware_address = hw_addr;
#endif /* HAS_UBOOT */
}
/*
* set interrupt number for given interface

View File

@@ -40,6 +40,11 @@ $(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
../../../libcpu/@RTEMS_CPU@/$(dirstamp):
@$(MKDIR_P) ../../../libcpu/@RTEMS_CPU@
@: > ../../../libcpu/@RTEMS_CPU@/$(dirstamp)
PREINSTALL_DIRS += ../../../libcpu/@RTEMS_CPU@/$(dirstamp)
$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
@@ -65,9 +70,13 @@ $(PROJECT_LIB)/rtems_crti.$(OBJEXT): rtems_crti.$(OBJEXT) $(PROJECT_LIB)/$(dirst
$(INSTALL_DATA) $< $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
$(PROJECT_LIB)/linkcmds.base: startup/linkcmds.base $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.base
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
$(PROJECT_LIB)/linkcmds.mpc8313erdb: startup/linkcmds.mpc8313erdb $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.mpc8313erdb
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.mpc8313erdb
$(PROJECT_LIB)/linkcmds.mpc8349eamds: startup/linkcmds.mpc8349eamds $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.mpc8349eamds
@@ -77,15 +86,27 @@ $(PROJECT_LIB)/linkcmds.hsc_cm01: startup/linkcmds.hsc_cm01 $(PROJECT_LIB)/$(dir
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.hsc_cm01
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.hsc_cm01
$(PROJECT_INCLUDE)/bsp/irq.h: ./irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
$(PROJECT_INCLUDE)/bsp/hwreg_vals.h: ./include/hwreg_vals.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/irq-config.h: include/irq-config.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-config.h
$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
$(PROJECT_INCLUDE)/bsp/hwreg_vals.h: include/hwreg_vals.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/hwreg_vals.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/hwreg_vals.h
$(PROJECT_INCLUDE)/bsp/vectors.h: ../../powerpc/shared/vectors/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
$(PROJECT_INCLUDE)/bsp/u-boot.h: ../shared/include/u-boot.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/u-boot.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/u-boot.h
$(PROJECT_INCLUDE)/bsp/tictac.h: ../shared/include/tictac.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/tictac.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/tictac.h

View File

@@ -20,11 +20,23 @@
#include <mpc83xx/mpc83xx_spidrv.h>
#include <bsp/irq.h>
#include <bsp.h>
#if defined(MPC8349EAMDS)
#if defined( MPC8313ERDB)
#include <libchip/spi-sd-card.h>
#elif defined( MPC8349EAMDS)
#include <libchip/spi-flash-m25p40.h>
#endif
#if defined(HSC_CM01)
#elif defined( HSC_CM01)
#include <libchip/spi-fram-fm25l256.h>
#else
#warning No SPI configuration available
#endif
/*=========================================================================*\
@@ -51,7 +63,19 @@ static rtems_status_code bsp_spi_sel_addr
| o = ok or error code |
\*=========================================================================*/
{
#if defined(MPC8349EAMDS)
#if defined( MPC8313ERDB)
/* Check address */
if (addr > 0) {
return RTEMS_INVALID_NUMBER;
}
/* SCS (active low) */
mpc83xx.gpio [0].gpdat &= ~0x20000000;
#elif defined( MPC8349EAMDS)
/*
* check device address for valid range
*/
@@ -64,8 +88,9 @@ static rtems_status_code bsp_spi_sel_addr
* set it to be active/low
*/
mpc83xx.gpio[0].gpdat &= ~(1 << (31- 0));
#endif
#if defined(HSC_CM01)
#elif defined( HSC_CM01)
/*
* check device address for valid range
*/
@@ -88,7 +113,9 @@ static rtems_status_code bsp_spi_sel_addr
* GPIO1[27] is high-active strobe
*/
mpc83xx.gpio[0].gpdat |= (1 << (31- 27));
#endif
return RTEMS_SUCCESSFUL;
}
@@ -110,20 +137,30 @@ static rtems_status_code bsp_spi_send_start_dummy
| o = ok or error code |
\*=========================================================================*/
{
#if defined(MPC8349EAMDS)
#if defined( MPC8313ERDB)
/* SCS (inactive high) */
mpc83xx.gpio [0].gpdat |= 0x20000000;
#elif defined( MPC8349EAMDS)
/*
* GPIO1[0] is nSEL_SPI for M25P40
* set it to inactive/high
*/
mpc83xx.gpio[0].gpdat |= (1 << (31- 0));
#endif
#if defined(HSC_CM01)
#elif defined( HSC_CM01)
/*
* GPIO1[27] is high-active strobe
* set it to inactive/ low
*/
mpc83xx.gpio[0].gpdat &= ~(0x1 << (31-27));
#endif
return 0;
}
@@ -148,21 +185,31 @@ static rtems_status_code bsp_spi_send_stop
#if defined(DEBUG)
printk("bsp_spi_send_stop called... ");
#endif
#if defined(MPC8349EAMDS)
#if defined( MPC8313ERDB)
/* SCS (inactive high) */
mpc83xx.gpio [0].gpdat |= 0x20000000;
#elif defined( MPC8349EAMDS)
/*
* deselect given device
* GPIO1[0] is nSEL_SPI for M25P40
* set it to be inactive/high
*/
mpc83xx.gpio[0].gpdat |= (1 << (31- 0));
#endif
#if defined(HSC_CM01)
#elif defined( HSC_CM01)
/*
* deselect device
* GPIO1[27] is high-active strobe
*/
mpc83xx.gpio[0].gpdat &= ~(1 << (31- 27));
#endif
#if defined(DEBUG)
printk("... exit OK\r\n");
#endif
@@ -174,28 +221,58 @@ static rtems_status_code bsp_spi_send_stop
\*=========================================================================*/
rtems_libi2c_bus_ops_t bsp_spi_ops = {
init: mpc83xx_spi_init,
send_start: bsp_spi_send_start_dummy,
send_stop: bsp_spi_send_stop,
send_addr: bsp_spi_sel_addr,
read_bytes: mpc83xx_spi_read_bytes,
write_bytes: mpc83xx_spi_write_bytes,
ioctl: mpc83xx_spi_ioctl
.init = mpc83xx_spi_init,
.send_start = bsp_spi_send_start_dummy,
.send_stop = bsp_spi_send_stop,
.send_addr = bsp_spi_sel_addr,
.read_bytes = mpc83xx_spi_read_bytes,
.write_bytes = mpc83xx_spi_write_bytes,
.ioctl = mpc83xx_spi_ioctl
};
static mpc83xx_spi_desc_t bsp_spi_bus_desc = {
{/* public fields */
ops: &bsp_spi_ops,
size: sizeof(bsp_spi_bus_desc),
.ops = &bsp_spi_ops,
.size = sizeof(bsp_spi_bus_desc)
},
{ /* our private fields */
reg_ptr: &mpc83xx.spi,
initialized: FALSE,
irq_number: BSP_IPIC_IRQ_SPI,
base_frq : 0 /* filled in during init */
.reg_ptr =&mpc83xx.spi,
.initialized = FALSE,
.irq_number = BSP_IPIC_IRQ_SPI,
.base_frq = 0 /* filled in during init */
}
};
#ifdef MPC8313ERDB
#include <libchip/spi-sd-card.h>
sd_card_driver_entry sd_card_driver_table [1] = { {
.driver = {
.ops = &sd_card_driver_ops,
.size = sizeof( sd_card_driver_entry)
},
.table_index = 0,
.minor = 0,
.device_name = "sd-card-a",
.disk_device_name = "/dev/sd-card-a",
.transfer_mode = SD_CARD_TRANSFER_MODE_DEFAULT,
.command = SD_CARD_COMMAND_DEFAULT,
/* .response = whatever, */
.response_index = SD_CARD_COMMAND_SIZE,
.n_ac_max = SD_CARD_N_AC_MAX_DEFAULT,
.block_number = 0,
.block_size = 0,
.block_size_shift = 0,
.busy = 1,
.verbose = 1,
.schedule_if_busy = 0
}
};
#endif /* MPC8313ERDB */
/*=========================================================================*\
| initialization |
\*=========================================================================*/
@@ -229,7 +306,33 @@ rtems_status_code bsp_register_spi
/*
* init port pins used to address/select SPI devices
*/
#if defined(MPC8349EAMDS)
#if defined( MPC8313ERDB)
/*
* Configured as master (direct connection to SD card)
*
* GPIO[28] : SOUT
* GPIO[29] : SIN
* GPIO[30] : SCLK
* GPIO[02] : SCS (inactive high), GPIO[02] is normally connected to U43 at
* pin 15 of MC74LCX244DT.
*/
/* Function */
mpc83xx.syscon.sicrl = (mpc83xx.syscon.sicrl & ~0x03fc0000) | 0x30000000;
/* Direction */
mpc83xx.gpio [0].gpdir = (mpc83xx.gpio [0].gpdir & ~0x0000000f) | 0x2000000b;
/* Data */
mpc83xx.gpio [0].gpdat |= 0x20000000;
/* Open Drain */
/* mpc83xx.gpio [0].gpdr |= 0x0000000f; */
#elif defined( MPC8349EAMDS)
/*
* GPIO1[0] is nSEL_SPI for M25P40
* set it to be output, high
@@ -237,8 +340,9 @@ rtems_status_code bsp_register_spi
mpc83xx.gpio[0].gpdat |= (1 << (31- 0));
mpc83xx.gpio[0].gpdir |= (1 << (31- 0));
mpc83xx.gpio[0].gpdr &= ~(1 << (31- 0));
#endif
#if defined(HSC_CM01)
#elif defined( HSC_CM01)
/*
* GPIO1[24] is SPI_A0
* GPIO1[25] is SPI_A1
@@ -249,7 +353,9 @@ rtems_status_code bsp_register_spi
mpc83xx.gpio[0].gpdat &= ~(0xf << (31-27));
mpc83xx.gpio[0].gpdir |= (0xf << (31-27));
mpc83xx.gpio[0].gpdr &= ~(0xf << (31-27));
#endif
/*
* update base frequency in spi descriptor
*/
@@ -264,28 +370,40 @@ rtems_status_code bsp_register_spi
return -ret_code;
}
spi_busno = ret_code;
#if defined(MPC8349EAMDS)
#if defined( MPC8313ERDB)
/* Register SD Card driver */
ret_code = rtems_libi2c_register_drv(
sd_card_driver_table [0].device_name,
(rtems_libi2c_drv_t *) &sd_card_driver_table [0],
spi_busno,
0
);
#elif defined( MPC8349EAMDS)
/*
* register M25P40 Flash
*/
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
#if defined(HSC_CM01)
#elif defined(HSC_CM01)
/*
* register FM25L256 FRAM
*/
ret_code = rtems_libi2c_register_drv(RTEMS_BSP_SPI_FRAM_DEVICE_NAME,
spi_fram_fm25l256_rw_driver_descriptor,
spi_busno,0x02);
#endif
if (ret_code < 0) {
return -ret_code;
}
#endif
/*
* FIXME: further drivers, when available
*/

View File

@@ -18,70 +18,18 @@
\*===============================================================*/
/* $Id$ */
#include <rtems/asm.h>
#include <libcpu/powerpc-utility.h>
#include <rtems/powerpc/cache.h>
#include <rtems/powerpc/registers.h>
#include <mpc83xx/mpc83xx.h>
#include <bsp.h>
/* Macro definitions to load a register with a 32-bit address.
Both functions identically. Sometimes one mnemonic is more
appropriate than the other.
reg -> register to load
value -> value to be loaded
LA reg,value ("Load Address")
LWI reg,value ("Load Word Immediate") */
.macro LA reg, value
lis \reg , \value@h
ori \reg , \reg, \value@l
.endm
.macro LWI reg, value
lis \reg , (\value)@h
ori \reg , \reg, (\value)@l
.endm
#include <mpc83xx/mpc83xx.h>
.macro SET_IMM_REGW base, reg2, offset, value
LA \reg2, \value
stw \reg2,\offset(\base)
.endm
/* Macro definitions to test, set or clear a single
bit or bit pattern in a given 32bit GPR.
reg1 -> register content to be tested
reg2 -> 2nd register only needed for computation
mask -> any bit pattern */
.macro TSTBITS reg1, reg2, reg3, mask /* Match is indicated by EQ=0 (CR) */
LWI \reg3, \mask /* Unmatch is indicated by EQ=1 (CR) */
and \reg1, \reg1, \reg3
and \reg2, \reg2, \reg3
cmplw \reg1, \reg2
sync
.endm
.macro SETBITS reg1, reg2, mask
LWI \reg2, \mask
or \reg1, \reg1, \reg2
sync
.endm
.macro CLRBITS reg1, reg2, mask
LWI \reg2, \mask
andc \reg1, \reg1, \reg2
sync
.endm
#define REP8(l) l ; l; l; l; l; l; l; l;
.extern _bss_start
.extern _bss_size
.extern _data_start
.extern _data_size
.extern _text_start
.extern _text_size
/*.extern _s_got*/
.extern boot_card
.extern MBAR
@@ -108,6 +56,32 @@ reset_vec:
.section ".entry"
PUBLIC_VAR (start)
start:
#ifdef HAS_UBOOT
.extern mpc83xx_uboot_board_info
.extern mpc83xx_uboot_board_info_size
/* Reset time base */
li r0, 0
mtspr TBWU, r0
mtspr TBWL, r0
/* Copy board info */
LA r6, mpc83xx_uboot_board_info
LW r5, mpc83xx_uboot_board_info_size
mtctr r5
copy_uboot_board_info:
lwz r5, 0(r3)
addi r3, r3, 4
stw r5, 0(r6)
addi r6, r6, 4
bdnz copy_uboot_board_info
#endif /* HAS_UBOOT */
/*
* basic CPU setup:
* init MSR
@@ -116,6 +90,7 @@ start:
SETBITS r30, r29, MSR_ME|MSR_RI
CLRBITS r30, r29, MSR_IP|MSR_EE
mtmsr r30 /* Set RI/ME, Clr EE in MSR */
b start_rom_skip
PUBLIC_VAR (rom_entry)
@@ -165,7 +140,7 @@ rom_entry:
/*
* ROM startup: jump to code final ROM location
*/
LA r20, ROM_START /* ROM-RAM reloc in r20 */
LA r20, bsp_rom_start /* ROM-RAM reloc in r20 */
LA r29, start_code_in_rom /* get compile time addr of label */
add r29,r20,r29 /* compute exec address */
mtlr r29
@@ -380,12 +355,12 @@ start_rom_skip1:
* ROM or relocatable startup: copy startup code to SDRAM
*/
/* get start address of text section in RAM */
LA r29, _text_start
LA r29, bsp_section_text_start
/* get start address of text section in ROM (add reloc offset) */
add r30, r20, r29
/* get size of startup code */
LA r28, end_reloc_startup
LA r31, _text_start
LA r31, bsp_section_text_start
sub 28,r28,r31
/* copy startup code from ROM to RAM location */
bl copy_image
@@ -409,8 +384,8 @@ copy_rest_of_text:
/* get start address of text section in ROM (add reloc offset) */
add r30, r20, r29
/* get size of rest of code */
LA r28, _text_start
LA r31, _text_size
LA r28, bsp_section_text_start
LA r31, bsp_section_text_size
add r28,r28,r31
sub r28,r28,r29
bl copy_image /* copy text section from ROM to RAM location */
@@ -419,11 +394,11 @@ copy_rest_of_text:
* ROM or relocatable startup: copy data to SDRAM
*/
/* get start address of data section in RAM */
LA r29, _data_start
LA r29, bsp_section_data_start
/* get start address of data section in ROM (add reloc offset) */
add r30, r20, r29
/* get size of RAM image */
LA r28, _data_size
LA r28, bsp_section_data_size
/* copy initialized data section from ROM to RAM location */
bl copy_image
@@ -432,15 +407,32 @@ start_code_in_ram:
/*
* ROM/RAM startup: clear bss in SDRAM
*/
LWI r30, _bss_start /* get start address of bss section */
LWI r29, _bss_size /* get size of bss section */
bl clr_mem /* Clear the bss section */
LA r3, bsp_section_bss_start /* get start address of bss section */
LWI r4, bsp_section_bss_size /* get size of bss section */
bl mpc83xx_zero_4 /* Clear the bss section */
/*
* call boot_card
*/
/* set stack pointer (common for RAM/ROM startup) */
LA r1, _text_start
/* Set stack pointer (common for RAM/ROM startup) */
LA r1, bsp_section_text_start
addi r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */
/* Create NULL */
li r0, 0
/* Return address */
stw r0, 4(r1)
/* Back chain */
stw r0, 0(r1)
/* Read-only small data */
LA r2, _SDA2_BASE_
/* Read-write small data */
LA r13, _SDA_BASE_
/* clear arguments and do further init. in C (common for RAM/ROM startup) */
xor r3, r3, r3
xor r4, r4, r4 /* Clear argc and argv */
@@ -486,33 +478,58 @@ copy_image_byte:
copy_image_end:
blr
clr_mem:
mr r28, r29
srwi r29, r29, 2
mtctr r29 /* set ctr reg */
/**
* @fn int mpc83xx_zero_4( void *dest, size_t n)
*
* @brief Zero all @a n bytes starting at @a dest with 4 byte writes.
*
* The address @a dest has to be aligned on 4 byte boundaries. The size @a n
* must be evenly divisible by 4.
*/
GLOBAL_FUNCTION mpc83xx_zero_4
/* Create zero */
xor r0, r0, r0
slwi r29, r29, 2
sub r28, r28, r29 /* maybe some residual bytes */
xor r29, r29, r29
/* Set offset */
xor r5, r5, r5
/* Loop counter for the first bytes up to 16 bytes */
rlwinm. r9, r4, 30, 30, 31
beq mpc83xx_zero_4_more
mtctr r9
clr_mem_word:
stswi r29, r30, 0x04 /* store r29 (word) to r30 memory location */
addi r30, r30, 0x04 /* increment r30 */
mpc83xx_zero_4_head:
bdnz clr_mem_word /* dec counter and loop */
stwx r0, r3, r5
addi r5, r5, 8
bdnz mpc83xx_zero_4_head
mpc83xx_zero_4_more:
cmpwi r28, 0x00 /* clear mem. finished ? */
beq clr_mem_end;
mtctr r28 /* reload counter for residual bytes */
clr_mem_byte:
stswi r29, r30, 0x01 /* store r29 (byte) to r30 memory location */
addi r30, r30, 0x01 /* update r30 */
/* More than 16 bytes? */
srwi. r9, r4, 4
beqlr
mtctr r9
bdnz clr_mem_byte /* dec counter and loop */
/* Set offsets */
addi r6, r5, 4
addi r7, r5, 8
addi r8, r5, 12
mpc83xx_zero_4_tail:
stwx r0, r3, r5
addi r5, r5, 16
stwx r0, r3, r6
addi r6, r6, 16
stwx r0, r3, r7
addi r7, r7, 16
stwx r0, r3, r8
addi r8, r8, 16
bdnz mpc83xx_zero_4_tail
/* Return */
blr
clr_mem_end:
blr /* return */
end_reloc_startup:

View File

@@ -1,151 +1,126 @@
/*===============================================================*\
| Project: RTEMS generic MPC83xx BSP |
+-----------------------------------------------------------------+
| Copyright (c) 2007 |
| 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 BSP startup code |
\*===============================================================*/
/**
* @file
*
* @ingroup mpc83xx
*
* @brief Source for BSP startup code.
*/
/*
* 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.
*
* $Id$
*/
#include <bsp.h>
#include <string.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <rtems/powerpc/powerpc.h>
#include <rtems/score/thread.h>
#include <rtems/bspIo.h>
#include <libcpu/cpuIdent.h>
#include <libcpu/spr.h>
#include <bsp/irq.h>
#include <libcpu/powerpc-utility.h>
#include <string.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <bsp/ppc_exc_bspsupp.h>
SPR_RW(SPRG0)
SPR_RW(SPRG1)
extern unsigned long intrStackPtr;
static char *BSP_heap_start, *BSP_heap_end;
#ifdef HAS_UBOOT
/*
* constants for c_clock driver:
* system bus frequency (for timebase etc)
* and
* Time base divisior: scaling value:
* BSP_time_base_divisor = TB ticks per millisecond/BSP_bus_frequency
* We want this in the data section, because the startup code clears the BSS
* section after the initialization of the board info.
*/
bd_t mpc83xx_uboot_board_info = { .bi_baudrate = 123 };
/* Size in words */
const size_t mpc83xx_uboot_board_info_size = (sizeof( bd_t) + 3) / 4;
#endif /* HAS_UBOOT */
/* Configuration parameters for console driver, ... */
unsigned int BSP_bus_frequency;
unsigned int BSP_time_base_divisor = 4000; /* 4 bus clicks per TB click */
/*
* Driver configuration parameters
*/
/* Configuration parameters for clock driver, ... */
uint32_t bsp_clicks_per_usec;
static char *BSP_heap_start, *BSP_heap_end;
/*
* Use the shared implementations of the following routines.
* Look in rtems/c/src/lib/libbsp/shared/bsplibc.c.
*/
void bsp_libc_init( void *, uint32_t, int );
extern void initialize_exceptions(void);
extern void cpu_init(void);
extern void cpu_init( void);
void BSP_panic(char *s)
{
printk("%s PANIC %s\n",_RTEMS_version, s);
/*
* FIXME: hang/restart system
*/
__asm__ __volatile ("sc");
}
void _BSP_Fatal_error(unsigned int v)
{
printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
/*
* FIXME: hang/restart system
*/
__asm__ __volatile ("sc");
}
/*
* Function: bsp_pretasking_hook
* Created: 95/03/10
*
* Description:
* BSP pretasking hook. Called just before drivers are initialized.
* Used to setup libc and install any BSP extensions.
*
* NOTES:
* Must not use libc (to do io) from here, since drivers are
* not yet initialized.
*
*/
void
bsp_pretasking_hook(void)
void BSP_panic( char *s)
{
rtems_interrupt_level level;
/*
* initialize libc including the heap
*/
bsp_libc_init( BSP_heap_start,
BSP_heap_end - BSP_heap_start,
0);
rtems_interrupt_disable( level);
printk( "%s PANIC %s\n", _RTEMS_version, s);
while (1) {
/* Do nothing */
}
}
void _BSP_Fatal_error( unsigned n)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
printk( "%s PANIC ERROR %u\n", _RTEMS_version, n);
while (1) {
/* Do nothing */
}
}
void bsp_pretasking_hook( void)
{
/* Initialize libc including the heap */
bsp_libc_init( BSP_heap_start, BSP_heap_end - BSP_heap_start, 0);
}
void bsp_calc_mem_layout()
{
size_t workspace_size = rtems_configuration_get_work_space_size();
/* We clear the workspace here */
Configuration.do_zero_of_workspace = 0;
/*
* 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
TODO
mpc83xx_zero_4( bsp_workspace_start, workspace_size);
*/
extern unsigned char TopRamReserved;
extern unsigned char _WorkspaceBase[];
mpc83xx_zero_4( bsp_interrupt_stack_start, bsp_ram_end - bsp_interrupt_stack_start);
/*
* 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;
Configuration.work_space_start = bsp_workspace_start;
BSP_heap_start = ((char *)Configuration.work_space_start +
rtems_configuration_get_work_space_size());
#if defined(HAS_UBOOT)
BSP_heap_end = (uboot_bdinfo_ptr->bi_memstart
+ uboot_bdinfo_ptr->bi_memsize
- (uint32_t)&TopRamReserved);
#else
BSP_heap_end = (void *)(RAM_END - (uint32_t)&TopRamReserved);
#endif
BSP_heap_start = (char *) Configuration.work_space_start + workspace_size;
#ifdef HAS_UBOOT
BSP_heap_end = mpc83xx_uboot_board_info.bi_memstart + mpc83xx_uboot_board_info.bi_memsize;
#else /* HAS_UBOOT */
BSP_heap_end = bsp_ram_end;
#endif /* HAS_UBOOT */
}
void bsp_start(void)
void bsp_start( void)
{
ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision;
register unsigned char* intrStack;
uint32_t interrupt_stack_start = (uint32_t) bsp_interrupt_stack_start;
uint32_t interrupt_stack_size = (uint32_t) bsp_interrupt_stack_size;
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
@@ -153,91 +128,77 @@ void bsp_start(void)
*/
myCpu = get_ppc_cpu_type();
myCpuRevision = get_ppc_cpu_revision();
/*
* determine heap and workspace placement
*/
/* Determine heap and workspace placement */
bsp_calc_mem_layout();
cpu_init();
/*
* Initialize some SPRG registers related to irq handling
* This is evaluated during runtime, so it should be ok to set it
* before we initialize the drivers.
*/
intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE);
/* Initialize some device driver parameters */
_write_SPRG1((unsigned int)intrStack);
/* Signal them that this BSP has fixed PR288 - eventually, this should
* go away
*/
_write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
/*
* this is evaluated during runtime, so it should be ok to set it
* before we initialize the drivers
*/
#ifdef HAS_UBOOT
BSP_bus_frequency = mpc83xx_uboot_board_info.bi_busfreq;
#else /* HAS_UBOOT */
BSP_bus_frequency = BSP_CLKIN_FRQ * BSP_SYSPLL_MF / BSP_SYSPLL_CKID;
/*
* initialize the device driver parameters
*/
bsp_clicks_per_usec = (BSP_bus_frequency/1000000);
#endif /* HAS_UBOOT */
/*
* Install our own set of exception vectors
*/
initialize_exceptions();
bsp_clicks_per_usec = BSP_bus_frequency / 4000000;
/*
* Enable instruction and data caches. Do not force writethrough mode.
*/
#if INSTRUCTION_CACHE_ENABLE
rtems_cache_enable_instruction();
#endif
#if DATA_CACHE_ENABLE
rtems_cache_enable_data();
#endif
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
* RTEMS world (e.g. simulator or primitive memory manager), or (as
* typically done by stock BSPs) by subtracting the required amount
* of work space from the last physical address on the CPU board.
*/
/* Initialize exception handler */
ppc_exc_initialize(
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
interrupt_stack_start,
interrupt_stack_size
);
/*
* Initalize RTEMS IRQ system
*/
BSP_rtems_irq_mng_init(0);
/* Initalize interrupt support */
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
BSP_panic("Cannot intitialize interrupt support\n");
}
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Exit from bspstart\n");
#endif
}
}
/*
*
* _Thread_Idle_body
/**
* @brief Idle thread body.
*
* Replaces the one in c/src/exec/score/src/threadidlebody.c
* The MSR[POW] bit is set to put the CPU into the low power mode
* defined in HID0. HID0 is set during starup in start.S.
*
*/
Thread _Thread_Idle_body(uint32_t ignored )
{
for(;;)
{
asm volatile("mfmsr 3; oris 3,3,4; sync; mtmsr 3; isync; ori 3,3,0; ori 3,3,0");
}
return 0;
Thread _Thread_Idle_body( uint32_t ignored)
{
while (1) {
asm volatile (
"mfmsr 3;"
"oris 3, 3, 4;"
"sync;"
"mtmsr 3;"
"isync;"
"ori 3, 3, 0;"
"ori 3, 3, 0"
);
}
return NULL;
}

View File

@@ -155,7 +155,7 @@ void cpu_init(void)
* clear caches
*/
GET_HID0(reg);
reg |= (HID0_ICFI | HID0_DCI);
reg = (reg & ~(HID0_ILOCK | HID0_DLOCK)) | HID0_ICFI | HID0_DCI;
SET_HID0(reg);
reg &= ~(HID0_ICFI | HID0_DCI);
SET_HID0(reg);
@@ -170,10 +170,20 @@ void cpu_init(void)
SET_IBAT(5,ibat.batu,ibat.batl);
SET_IBAT(6,ibat.batu,ibat.batl);
SET_IBAT(7,ibat.batu,ibat.batl);
#ifdef HAS_UBOOT
calc_dbat_regvals(&ibat,mpc83xx_uboot_board_info.bi_memstart,mpc83xx_uboot_board_info.bi_memsize,0,0,0,0,BPP_RX);
#else /* HAS_UBOOT */
calc_dbat_regvals(&ibat,(uint32_t) bsp_ram_start,(uint32_t) bsp_ram_size,0,0,0,0,BPP_RX);
#endif /* HAS_UBOOT */
calc_dbat_regvals(&ibat,RAM_START,RAM_SIZE,0,0,0,0,BPP_RX);
SET_IBAT(0,ibat.batu,ibat.batl);
calc_dbat_regvals(&ibat,ROM_START,ROM_SIZE,0,0,0,0,BPP_RX);
#ifdef HAS_UBOOT
calc_dbat_regvals(&ibat,mpc83xx_uboot_board_info.bi_flashstart,mpc83xx_uboot_board_info.bi_flashsize,0,0,0,0,BPP_RX);
#else /* HAS_UBOOT */
calc_dbat_regvals(&ibat,(uint32_t) bsp_rom_start,(uint32_t) bsp_rom_size,0,0,0,0,BPP_RX);
#endif /* HAS_UBOOT */
SET_IBAT(1,ibat.batu,ibat.batl);
/*
@@ -186,13 +196,28 @@ void cpu_init(void)
SET_DBAT(6,dbat.batu,dbat.batl);
SET_DBAT(7,dbat.batu,dbat.batl);
calc_dbat_regvals(&dbat,RAM_START,RAM_SIZE,1,0,1,0,BPP_RW);
#ifdef HAS_UBOOT
calc_dbat_regvals(&dbat,mpc83xx_uboot_board_info.bi_memstart,mpc83xx_uboot_board_info.bi_memsize,0,0,0,0,BPP_RW);
#else /* HAS_UBOOT */
calc_dbat_regvals(&dbat,(uint32_t) bsp_ram_start,(uint32_t) bsp_ram_size,0,0,0,0,BPP_RW);
#endif /* HAS_UBOOT */
SET_DBAT(0,dbat.batu,dbat.batl);
calc_dbat_regvals(&dbat,ROM_START,ROM_SIZE,1,0,1,0,BPP_RX);
#ifdef HAS_UBOOT
calc_dbat_regvals(&dbat,mpc83xx_uboot_board_info.bi_flashstart,mpc83xx_uboot_board_info.bi_flashsize,0,0,0,0,BPP_RX);
#else /* HAS_UBOOT */
calc_dbat_regvals(&dbat,(uint32_t) bsp_rom_start,(uint32_t) bsp_rom_size,0,0,0,0,BPP_RX);
#endif /* HAS_UBOOT */
SET_DBAT(1,dbat.batu,dbat.batl);
calc_dbat_regvals(&dbat,IMMRBAR,1024*1024,1,1,1,1,BPP_RW);
#ifdef HAS_UBOOT
calc_dbat_regvals(&dbat,mpc83xx_uboot_board_info.bi_immrbar,1024*1024,0,1,0,1,BPP_RW);
#else /* HAS_UBOOT */
calc_dbat_regvals(&dbat,(uint32_t) IMMRBAR,1024*1024,0,1,0,1,BPP_RW);
#endif /* HAS_UBOOT */
SET_DBAT(2,dbat.batu,dbat.batl);
/*

View File

@@ -1,318 +0,0 @@
/*
* This file contains directives for the GNU linker which are specific
* to a gen8349eamds board.
*
* You MUST have a linker script named linkcmds autoconf tests which
* use the "-B... -specs bsp_specs -qrtems" arguments work.
*
* $Id$
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(start)
/*
* Declare some sizes.
* XXX: The assignment of ". += XyzSize;" fails in older gld's if the
* number used there is not constant. If this happens to you, edit
* the lines marked XXX below to use a constant value.
*/
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x6800000; /* 104M Heap */
StackSize = DEFINED(StackSize) ? StackSize : 0x80000; /* 512 kB */
WorkSpaceSize = DEFINED(WorkSpaceSize) ? WorkSpaceSize : 0x80000; /* 512k */
RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x80000; /* 512 ram disk */
/*
* optionally reserve additional space
*/
TopRamReserved = DEFINED(TopRamReserved) ? TopRamReserved : 0;
MEMORY
{
ram : org = 0x0, l = 256M
mpc83xx_regs : org = 0xE0000000, l = 256k
}
SECTIONS
{
mpc83xx_regs (NOLOAD) :
{
IMMRBAR = .;
mpc83xx_regs*(.text)
mpc83xx_regs*(.data)
mpc83xx_regs*(.bss)
mpc83xx_regs*(*COM*)
} > mpc83xx_regs
.resconf 0x000 :
{
*(.resconf)
} > ram
.vectors 0x100 :
{
*(.vectors)
}
> ram
/*
* The stack will live in this area - between the vectors and
* the text section.
*/
.text 0x10000:
{
_textbase = .;
text.start = .;
/* Entry point is the .entry section */
*(.entry)
*(.entry2)
/* Actual Code */
*(.text*)
*(.rodata*)
*(.rodata1)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* C++ constructors/destructors */
*(.gnu.linkonce.t*)
/* Initialization and finalization code.
*
* Various files can provide initialization and finalization functions.
* The bodies of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues from
* ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
* first; ecrtn.o must be linked last. Because these are wildcards, it
* doesn't matter if the user does not actually link against ecrti.o and
* ecrtn.o; the linker won't look for a file to match a wildcard. The
* wildcard also means that it doesn't matter which directory ecrti.o
* and ecrtn.o are in.
*/
PROVIDE (_init = .);
*ecrti.o(.init)
*(.init)
*ecrtn.o(.init)
PROVIDE (_fini = .);
*ecrti.o(.fini)
*(.fini)
*ecrtn.o(.init)
/*
* C++ constructors and destructors for static objects.
* PowerPC EABI does not use crtstuff yet, so we build "old-style"
* constructor and destructor lists that begin with the list lenght
* end terminate with a NULL entry.
*/
PROVIDE (__CTOR_LIST__ = .);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
LONG(0)
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
LONG(0)
PROVIDE (__DTOR_END__ = .);
/* Exception frame info */
*(.eh_frame)
/* Miscellaneous read-only data */
_rodata_start = . ;
*(.gnu.linkonce.r*)
*(.lit)
*(.shdata)
*(.rodata)
*(.rodata1)
*(.descriptors)
*(rom_ver)
_erodata = .;
PROVIDE (__EXCEPT_START__ = .);
*(.gcc_except_table*)
PROVIDE (__EXCEPT_END__ = .);
__GOT_START__ = .;
s.got = .;
*(.got.plt)
*(.got)
*(.got1)
PROVIDE (__GOT2_START__ = .);
PROVIDE (_GOT2_START_ = .);
*(.got2)
PROVIDE (__GOT2_END__ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (__FIXUP_START__ = .);
PROVIDE (_FIXUP_START_ = .);
*(.fixup)
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
/* Various possible names for the end of the .text section */
etext = ALIGN(0x10);
_etext = .;
_endtext = .;
text.end = .;
PROVIDE (etext = .);
PROVIDE (__etext = .);
} > ram
.jcr : { KEEP (*(.jcr)) } > ram
.rel.dyn : {
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
*(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
*(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
*(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
} >ram
.rela.dyn : {
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.got1)
*(.rela.got2)
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
} >ram
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >ram
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >ram
PROVIDE (__SBSS2_END__ = .);
.sbss2 : { *(.sbss2) } >ram
PROVIDE (__SBSS2_END__ = .);
/* R/W Data */
.data ( . ) :
{
. = ALIGN (4);
data.start = .;
*(.data)
*(.data1)
*(.data.* .gnu.linkonce.d.*)
PROVIDE (__SDATA_START__ = .);
*(.sdata*)
*(.gnu.linkonce.s.*)
data.end = .;
} > ram
__SBSS_START__ = .;
.bss :
{
bss.start = .;
*(.bss .bss* .gnu.linkonce.b*)
*(.sbss*) *(COMMON)
. = ALIGN(4);
bss.end = .;
} > ram
__SBSS_END__ = .;
PROVIDE(_bss_start = ADDR(.bss));
PROVIDE(_bss_size = SIZEOF(.bss));
PROVIDE(_data_start = ADDR(.data));
PROVIDE(_data_size = SIZEOF(.data));
PROVIDE(_text_start = ADDR(.text));
PROVIDE(_text_size = SIZEOF(.text));
PROVIDE(_end = data.end);
.gzipmalloc : {
. = ALIGN (16);
_startmalloc = .;
} >ram
clear_end = .;
/*
* Interrupt stack setup
*/
IntrStack_start = ALIGN(0x10);
. += 0x4000;
intrStack = .;
PROVIDE(intrStackPtr = intrStack);
_WorkspaceBase = .;
__WorkspaceBase = .;
/* Sections for compressed .text and .data */
/* after the .datarom section is an int specifying */
/* the length of the following compressed image */
/* Executes once then could get overwritten */
.textrom 0x100000 :
{
*(.textrom)
_endloader = .;
} > ram
.datarom :
{
_dr_start = .;
*(.datarom)
_dr_end = .;
} > ram
dr_len = _dr_end - _dr_start;
.line 0 : { *(.line) }
.debug 0 : { *(.debug) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_aregion 0 : { *(.debug_aregion) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
}

View File

@@ -0,0 +1,327 @@
/**
* @file
*
* Derived from internal linker script of GNU ld (GNU Binutils) 2.18 for elf32ppc emulation.
*/
OUTPUT_FORMAT ("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
OUTPUT_ARCH (powerpc)
ENTRY (start)
bsp_ram_start = ORIGIN (RAM);
bsp_ram_end = ORIGIN (RAM) + LENGTH (RAM);
bsp_ram_size = LENGTH (RAM);
bsp_rom_start = ORIGIN (ROM);
bsp_rom_end = ORIGIN (ROM) + LENGTH (ROM);
bsp_rom_size = LENGTH (ROM);
bsp_section_align = 32;
SECTIONS {
/*
* BSP: MPC83XX registers
*/
.mpc83xx_regs (NOLOAD) : {
IMMRBAR = .;
mpc83xx_regs*(.text)
mpc83xx_regs*(.data)
mpc83xx_regs*(.bss)
mpc83xx_regs*(COMMON)
} > MPC83XX_REGS
/*
* BSP: Reset configuration
*/
.resconf 0x0 : {
*(.resconf)
} > RAM
/*
* BSP: Exception vectors
*/
.vectors 0x100 : {
*(.vectors)
} > RAM
/*
* BSP: The initial stack will live in this area - between the vectors
* and the text section.
*/
.text 0x10000 : {
/*
* BSP: Start of text section
*/
bsp_section_text_start = .;
/*
* BSP: System startup entry
*/
KEEP (*(.entry))
/*
* BSP: Moved into .text from .init
*/
KEEP (*(.init))
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.glink)
/*
* BSP: Special FreeBSD sysctl sections
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/*
* BSP: Moved into .text from .*
*/
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
*(.interp)
*(.note.gnu.build-id)
*(.hash)
*(.gnu.hash)
*(.dynsym)
*(.dynstr)
*(.gnu.version)
*(.gnu.version_d)
*(.gnu.version_r)
*(.eh_frame_hdr)
/*
* BSP: Magic PPC stuff
*/
*(.PPC.*)
/*
* BSP: Required by cpukit/score/src/threadhandler.c
*/
PROVIDE (_fini = .);
/*
* BSP: Moved into .text from .fini
*/
KEEP (*(.fini))
. = ALIGN (bsp_section_align);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
} > RAM
.sdata2 : {
PROVIDE (_SDA2_BASE_ = 32768);
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
. = ALIGN (bsp_section_align);
} > RAM
.sbss2 : {
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
. = ALIGN (bsp_section_align);
/*
* BSP: End and size of text section
*/
bsp_section_text_end = .;
bsp_section_text_size = bsp_section_text_end - bsp_section_text_start;
} > RAM
.data : {
/*
* BSP: Start of data section
*/
bsp_section_data_start = .;
/*
* BSP: Moved into .data from .ctors
*/
/* gcc uses crtbegin.o to find the start of
the constructors, 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. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
/*
* BSP: Moved into .data from .dtors
*/
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/*
* BSP: Moved into .data from .*
*/
*(.tdata .tdata.* .gnu.linkonce.td.*)
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
*(.data1)
KEEP (*(.eh_frame))
*(.gcc_except_table .gcc_except_table.*)
KEEP (*(.jcr))
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
*(.fixup)
*(.got1)
*(.got2)
*(.dynamic)
*(.got)
*(.plt)
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
*(.data .data.* .gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
. = ALIGN (bsp_section_align);
} > RAM
.sdata : {
PROVIDE (_SDA_BASE_ = 32768);
*(.sdata .sdata.* .gnu.linkonce.s.*)
. = ALIGN (bsp_section_align);
_edata = .;
PROVIDE (edata = .);
/*
* BSP: End and size of data section
*/
bsp_section_data_end = .;
bsp_section_data_size = bsp_section_data_end - bsp_section_data_start;
} > RAM
.sbss : {
/*
* BSP: Start of bss section
*/
bsp_section_bss_start = .;
__bss_start = .;
PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
*(.scommon)
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
. = ALIGN (bsp_section_align);
} > RAM
.bss : {
*(COMMON)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN (bsp_section_align);
__end = .;
_end = .;
PROVIDE (end = .);
/*
* BSP: End and size of bss section
*/
bsp_section_bss_end = .;
bsp_section_bss_size = bsp_section_bss_end - bsp_section_bss_start;
} > RAM
/*
* BSP: Interrupt stack
*/
bsp_interrupt_stack_start = .;
bsp_interrupt_stack_end = bsp_interrupt_stack_start + 32k;
bsp_interrupt_stack_size = bsp_interrupt_stack_end - bsp_interrupt_stack_start;
bsp_interrupt_stack_pointer = bsp_interrupt_stack_end - 16;
. = bsp_interrupt_stack_end;
/*
* BSP: Workspace start
*/
bsp_workspace_start = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : {
*(.note.GNU-stack) *(.gnu_debuglink)
}
/*
* BSP: Catch all unknown sections
*/
.nirvana : {
*(*)
} > NIRVANA
}

View File

@@ -1,332 +1,14 @@
/*
* This file contains directives for the GNU linker which are specific
* to a hsc_cm01 board
/**
* @file
*
* $Id$
* HSC_CM01 Board.
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(start)
/*
* Declare some sizes.
* XXX: The assignment of ". += XyzSize;" fails in older gld's if the
* number used there is not constant. If this happens to you, edit
* the lines marked XXX below to use a constant value.
*/
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x6800000; /* 104M Heap */
StackSize = DEFINED(StackSize) ? StackSize : 0x80000; /* 512 kB */
WorkSpaceSize = DEFINED(WorkSpaceSize) ? WorkSpaceSize : 0x80000; /* 512k */
RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x80000; /* 512 ram disk */
/*
* optionally reserve additional space
*/
TopRamReserved = DEFINED(TopRamReserved) ? TopRamReserved : 0;
MEMORY
{
ram : org = 0x0, l = 256M
mpc83xx_regs : org = 0xE0000000, l = 256k
}
SECTIONS
{
.mpc83xx_regs (NOLOAD) :
{
IMMRBAR = .;
mpc83xx_regs*(.text)
mpc83xx_regs*(.data)
mpc83xx_regs*(.bss)
mpc83xx_regs*(*COM*)
} > mpc83xx_regs
.resconf 0x000 :
{
*(.resconf)
} > ram
.vectors 0x100 :
{
*(.vectors)
}
> ram
/*
* The stack will live in this area - between the vectors and
* the text section.
*/
.text 0x10000:
{
_textbase = .;
text.start = .;
/* Entry point is the .entry section */
*(.entry)
*(.entry2)
/* Actual Code */
*(.text*)
*(.rodata*)
*(.rodata1)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* C++ constructors/destructors */
*(.gnu.linkonce.t*)
/* Initialization and finalization code.
*
* Various files can provide initialization and finalization functions.
* The bodies of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues from
* ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
* first; ecrtn.o must be linked last. Because these are wildcards, it
* doesn't matter if the user does not actually link against ecrti.o and
* ecrtn.o; the linker won't look for a file to match a wildcard. The
* wildcard also means that it doesn't matter which directory ecrti.o
* and ecrtn.o are in.
*/
PROVIDE (_init = .);
*ecrti.o(.init)
*(.init)
*ecrtn.o(.init)
PROVIDE (_fini = .);
*ecrti.o(.fini)
*(.fini)
*ecrtn.o(.init)
/*
* C++ constructors and destructors for static objects.
* PowerPC EABI does not use crtstuff yet, so we build "old-style"
* constructor and destructor lists that begin with the list lenght
* end terminate with a NULL entry.
*/
PROVIDE (__CTOR_LIST__ = .);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
LONG(0)
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
LONG(0)
PROVIDE (__DTOR_END__ = .);
/* Exception frame info */
*(.eh_frame)
/* Miscellaneous read-only data */
_rodata_start = . ;
*(.gnu.linkonce.r*)
*(.lit)
*(.shdata)
*(.rodata)
*(.rodata1)
*(.descriptors)
*(rom_ver)
_erodata = .;
PROVIDE (__EXCEPT_START__ = .);
*(.gcc_except_table*)
PROVIDE (__EXCEPT_END__ = .);
__GOT_START__ = .;
s.got = .;
*(.got.plt)
*(.got)
*(.got1)
PROVIDE (__GOT2_START__ = .);
PROVIDE (_GOT2_START_ = .);
*(.got2)
PROVIDE (__GOT2_END__ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (__FIXUP_START__ = .);
PROVIDE (_FIXUP_START_ = .);
*(.fixup)
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
/* Various possible names for the end of the .text section */
etext = ALIGN(0x10);
_etext = .;
_endtext = .;
text.end = .;
PROVIDE (etext = .);
PROVIDE (__etext = .);
} > ram
.jcr : { KEEP (*(.jcr)) } > ram
.rel.dyn : {
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
*(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
*(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
*(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
} >ram
.rela.dyn : {
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.got1)
*(.rela.got2)
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
} >ram
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >ram
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >ram
PROVIDE (__SBSS2_END__ = .);
.sbss2 : { *(.sbss2) } >ram
PROVIDE (__SBSS2_END__ = .);
/* R/W Data */
.data ( . ) :
{
. = ALIGN (4);
data.start = .;
*(.data)
*(.data1)
*(.data.* .gnu.linkonce.d.*)
PROVIDE (__SDATA_START__ = .);
*(.sdata*)
*(.gnu.linkonce.s.*)
data.end = .;
} > ram
__SBSS_START__ = .;
.bss :
{
bss.start = .;
*(.bss .bss* .gnu.linkonce.b*)
*(.sbss*) *(COMMON)
. = ALIGN(4);
bss.end = .;
} > ram
__SBSS_END__ = .;
PROVIDE(_bss_start = ADDR(.bss));
PROVIDE(_bss_size = SIZEOF(.bss));
PROVIDE(_data_start = ADDR(.data));
PROVIDE(_data_size = SIZEOF(.data));
PROVIDE(_text_start = ADDR(.text));
PROVIDE(_text_size = SIZEOF(.text));
PROVIDE(_end = data.end);
.gzipmalloc : {
. = ALIGN (16);
_startmalloc = .;
} >ram
/*
* Interrupt stack setup
*/
IntrStack_start = ALIGN(0x10);
. += 0x4000;
intrStack = .;
PROVIDE(intrStackPtr = intrStack);
_WorkspaceBase = .;
__WorkspaceBase = .;
. += WorkSpaceSize;
_RamDiskBase = .;
__RamDiskBase = .;
. += RamDiskSize;
_RamDiskEnd = .;
__RamDiskEnd = .;
PROVIDE( _RamDiskSize = _RamDiskEnd - _RamDiskBase );
_HeapStart = .;
__HeapStart = .;
. += HeapSize;
_HeapEnd = .;
__HeapEnd = .;
clear_end = .;
/* Sections for compressed .text and .data */
/* after the .datarom section is an int specifying */
/* the length of the following compressed image */
/* Executes once then could get overwritten */
.textrom 0x100000 :
{
*(.textrom)
_endloader = .;
} > ram
.datarom :
{
_dr_start = .;
*(.datarom)
_dr_end = .;
} > ram
dr_len = _dr_end - _dr_start;
.line 0 : { *(.line) }
.debug 0 : { *(.debug) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_aregion 0 : { *(.debug_aregion) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
MEMORY {
RAM : ORIGIN = 0x0, LENGTH = 256M
ROM : ORIGIN = 0xfe000000, LENGTH = 8M
MPC83XX_REGS : ORIGIN = 0xe0000000, LENGTH = 256k
NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
INCLUDE linkcmds.base

View File

@@ -0,0 +1,14 @@
/**
* @file
*
* MPC8313E Reference Design Board.
*/
MEMORY {
RAM : ORIGIN = 0x0, LENGTH = 128M
ROM : ORIGIN = 0xfe000000, LENGTH = 8M
MPC83XX_REGS : ORIGIN = 0xe0000000, LENGTH = 256k
NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
INCLUDE linkcmds.base

View File

@@ -1,332 +1,14 @@
/*
* This file contains directives for the GNU linker which are specific
* to a gen8349eamds board
/**
* @file
*
* $Id$
* MPC8349EAMDS Board.
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(start)
/*
* Declare some sizes.
* XXX: The assignment of ". += XyzSize;" fails in older gld's if the
* number used there is not constant. If this happens to you, edit
* the lines marked XXX below to use a constant value.
*/
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x6800000; /* 104M Heap */
StackSize = DEFINED(StackSize) ? StackSize : 0x80000; /* 512 kB */
WorkSpaceSize = DEFINED(WorkSpaceSize) ? WorkSpaceSize : 0x80000; /* 512k */
RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x80000; /* 512 ram disk */
/*
* optionally reserve additional space
*/
TopRamReserved = DEFINED(TopRamReserved) ? TopRamReserved : 0;
MEMORY
{
ram : org = 0x0, l = 256M
mpc83xx_regs : org = 0xE0000000, l = 256k
}
SECTIONS
{
mpc83xx_regs (NOLOAD) :
{
IMMRBAR = .;
mpc83xx_regs*(.text)
mpc83xx_regs*(.data)
mpc83xx_regs*(.bss)
mpc83xx_regs*(*COM*)
} > mpc83xx_regs
.resconf 0x000 :
{
*(.resconf)
} > ram
.vectors 0x100 :
{
*(.vectors)
}
> ram
/*
* The stack will live in this area - between the vectors and
* the text section.
*/
.text 0x10000:
{
_textbase = .;
text.start = .;
/* Entry point is the .entry section */
*(.entry)
*(.entry2)
/* Actual Code */
*(.text*)
*(.rodata*)
*(.rodata1)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* C++ constructors/destructors */
*(.gnu.linkonce.t*)
/* Initialization and finalization code.
*
* Various files can provide initialization and finalization functions.
* The bodies of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues from
* ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
* first; ecrtn.o must be linked last. Because these are wildcards, it
* doesn't matter if the user does not actually link against ecrti.o and
* ecrtn.o; the linker won't look for a file to match a wildcard. The
* wildcard also means that it doesn't matter which directory ecrti.o
* and ecrtn.o are in.
*/
PROVIDE (_init = .);
*ecrti.o(.init)
*(.init)
*ecrtn.o(.init)
PROVIDE (_fini = .);
*ecrti.o(.fini)
*(.fini)
*ecrtn.o(.init)
/*
* C++ constructors and destructors for static objects.
* PowerPC EABI does not use crtstuff yet, so we build "old-style"
* constructor and destructor lists that begin with the list lenght
* end terminate with a NULL entry.
*/
PROVIDE (__CTOR_LIST__ = .);
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
LONG(0)
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
LONG(0)
PROVIDE (__DTOR_END__ = .);
/* Exception frame info */
*(.eh_frame)
/* Miscellaneous read-only data */
_rodata_start = . ;
*(.gnu.linkonce.r*)
*(.lit)
*(.shdata)
*(.rodata)
*(.rodata1)
*(.descriptors)
*(rom_ver)
_erodata = .;
PROVIDE (__EXCEPT_START__ = .);
*(.gcc_except_table*)
PROVIDE (__EXCEPT_END__ = .);
__GOT_START__ = .;
s.got = .;
*(.got.plt)
*(.got)
*(.got1)
PROVIDE (__GOT2_START__ = .);
PROVIDE (_GOT2_START_ = .);
*(.got2)
PROVIDE (__GOT2_END__ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (__FIXUP_START__ = .);
PROVIDE (_FIXUP_START_ = .);
*(.fixup)
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
/* Various possible names for the end of the .text section */
etext = ALIGN(0x10);
_etext = .;
_endtext = .;
text.end = .;
PROVIDE (etext = .);
PROVIDE (__etext = .);
} > ram
.jcr : { KEEP (*(.jcr)) } > ram
.rel.dyn : {
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
*(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
*(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
*(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
} >ram
.rela.dyn : {
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.got1)
*(.rela.got2)
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
} >ram
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >ram
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >ram
PROVIDE (__SBSS2_END__ = .);
.sbss2 : { *(.sbss2) } >ram
PROVIDE (__SBSS2_END__ = .);
/* R/W Data */
.data ( . ) :
{
. = ALIGN (4);
data.start = .;
*(.data)
*(.data1)
*(.data.* .gnu.linkonce.d.*)
PROVIDE (__SDATA_START__ = .);
*(.sdata*)
*(.gnu.linkonce.s.*)
data.end = .;
} > ram
__SBSS_START__ = .;
.bss :
{
bss.start = .;
*(.bss .bss* .gnu.linkonce.b*)
*(.sbss*) *(COMMON)
. = ALIGN(4);
bss.end = .;
} > ram
__SBSS_END__ = .;
PROVIDE(_bss_start = ADDR(.bss));
PROVIDE(_bss_size = SIZEOF(.bss));
PROVIDE(_data_start = ADDR(.data));
PROVIDE(_data_size = SIZEOF(.data));
PROVIDE(_text_start = ADDR(.text));
PROVIDE(_text_size = SIZEOF(.text));
PROVIDE(_end = data.end);
.gzipmalloc : {
. = ALIGN (16);
_startmalloc = .;
} >ram
/*
* Interrupt stack setup
*/
IntrStack_start = ALIGN(0x10);
. += 0x4000;
intrStack = .;
PROVIDE(intrStackPtr = intrStack);
_WorkspaceBase = .;
__WorkspaceBase = .;
. += WorkSpaceSize;
_RamDiskBase = .;
__RamDiskBase = .;
. += RamDiskSize;
_RamDiskEnd = .;
__RamDiskEnd = .;
PROVIDE( _RamDiskSize = _RamDiskEnd - _RamDiskBase );
_HeapStart = .;
__HeapStart = .;
. += HeapSize;
_HeapEnd = .;
__HeapEnd = .;
clear_end = .;
/* Sections for compressed .text and .data */
/* after the .datarom section is an int specifying */
/* the length of the following compressed image */
/* Executes once then could get overwritten */
.textrom 0x100000 :
{
*(.textrom)
_endloader = .;
} > ram
.datarom :
{
_dr_start = .;
*(.datarom)
_dr_end = .;
} > ram
dr_len = _dr_end - _dr_start;
.line 0 : { *(.line) }
.debug 0 : { *(.debug) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_aregion 0 : { *(.debug_aregion) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
MEMORY {
RAM : ORIGIN = 0x0, LENGTH = 256M
ROM : ORIGIN = 0xfe000000, LENGTH = 8M
MPC83XX_REGS : ORIGIN = 0xe0000000, LENGTH = 256k
NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
INCLUDE linkcmds.base

View File

@@ -1,3 +1,10 @@
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
* irq/irq.c: adapted DCR access syntax
* startup/linkcmds, startup/bspstartup.c, Makefile.am:
adapted to exception support code
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
* README, bsp_specs, INSTALL, bsp_specs.dl, configure.ac,

View File

@@ -63,13 +63,13 @@ irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
irq_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
## 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
@@ -77,9 +77,9 @@ libbsp_a_SOURCES =
libbsp_a_LIBADD = startup.rel dlentry.rel console.rel irq.rel
if HAS_NETWORKING
libbsp_a_LIBADD += network.rel
endif
## if HAS_NETWORKING
## libbsp_a_LIBADD += network.rel
## endif
libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/raw_exception.rel \

View File

@@ -69,9 +69,12 @@ static inline int IsUICIRQ(const rtems_irq_number irqLine)
static void WriteIState()
/* Write the gEnabledInts state masked by gIntInhibited to the hardware */
{
mtdcr(UIC0_ER, gEnabledInts[0] & ~gIntInhibited[0]);
mtdcr(UIC1_ER, gEnabledInts[1] & ~gIntInhibited[1]);
mtdcr(UIC2_ER, gEnabledInts[2] & ~gIntInhibited[2]);
PPC_SET_DEVICE_CONTROL_REGISTER(UIC0_ER,
gEnabledInts[0] & ~gIntInhibited[0]);
PPC_SET_DEVICE_CONTROL_REGISTER(UIC1_ER,
gEnabledInts[1] & ~gIntInhibited[1]);
PPC_SET_DEVICE_CONTROL_REGISTER(UIC2_ER,
gEnabledInts[2] & ~gIntInhibited[2]);
}
void
@@ -112,26 +115,44 @@ BSP_setup_the_pic(rtems_irq_global_settings* config)
for (i=0; i<kUICWords; i++)
gIntInhibited[i] = 0;
mtdcr (UIC2_ER, 0x00000000); /* disable all interrupts */
mtdcr (UIC2_CR, 0x00000000); /* Set Critical / Non Critical interrupts */
mtdcr (UIC2_PR, 0xf7ffffff); /* Set Interrupt Polarities */
mtdcr (UIC2_TR, 0x01e1fff8); /* Set Interrupt Trigger Levels */
mtdcr (UIC2_VR, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
mtdcr (UIC2_SR, 0xffffffff); /* clear all interrupts */
/* disable all interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_ER, 0x00000000);
/* Set Critical / Non Critical interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_CR, 0x00000000);
/* Set Interrupt Polarities */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_PR, 0xf7ffffff);
/* Set Interrupt Trigger Levels */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_TR, 0x01e1fff8);
/* Set Vect base=0,INT31 Highest priority */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_VR, 0x00000001);
/* clear all interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC2_SR, 0xffffffff);
mtdcr (UIC1_ER, 0x00000000); /* disable all interrupts */
mtdcr (UIC1_CR, 0x00000000); /* Set Critical / Non Critical interrupts */
mtdcr (UIC1_PR, 0xfffac785); /* Set Interrupt Polarities */
mtdcr (UIC1_TR, 0x001d0040); /* Set Interrupt Trigger Levels */
mtdcr (UIC1_VR, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
mtdcr (UIC1_SR, 0xffffffff); /* clear all interrupts */
/* disable all interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_ER, 0x00000000);
/* Set Critical / Non Critical interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_CR, 0x00000000);
/* Set Interrupt Polarities */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_PR, 0xfffac785);
/* Set Interrupt Trigger Levels */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_TR, 0x001d0040);
/* Set Vect base=0,INT31 Highest priority */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_VR, 0x00000001);
/* clear all interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC1_SR, 0xffffffff);
mtdcr (UIC0_ER, 0x0000000a); /* Disable all interrupts except cascade UIC0 and UIC1 */
mtdcr (UIC0_CR, 0x00000000); /* Set Critical / Non Critical interrupts */
mtdcr (UIC0_PR, 0xffbfefef); /* Set Interrupt Polarities */
mtdcr (UIC0_TR, 0x00007000); /* Set Interrupt Trigger Levels */
mtdcr (UIC0_VR, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
mtdcr (UIC0_SR, 0xffffffff); /* clear all interrupts */
/* Disable all interrupts except cascade UIC0 and UIC1 */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_ER, 0x0000000a);
/* Set Critical / Non Critical interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_CR, 0x00000000);
/* Set Interrupt Polarities */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_PR, 0xffbfefef);
/* Set Interrupt Trigger Levels */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_TR, 0x00007000);
/* Set Vect base=0,INT31 Highest priority */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_VR, 0x00000001);
/* clear all interrupts */
PPC_SET_DEVICE_CONTROL_REGISTER (UIC0_SR, 0xffffffff);
return 1;
}
@@ -153,9 +174,9 @@ C_dispatch_irq_handler( struct _BSP_Exception_frame* frame, unsigned int excNum
/* Fetch the masked flags that tell us what external ints are active.
Likely to be only one, but we need to handle more than one,
OR the flags into gIntInhibited */
active[0] = mfdcr(UIC0_MSR);
active[1] = mfdcr(UIC1_MSR);
active[2] = mfdcr(UIC2_MSR);
active[0] = PPC_DEVICE_CONTROL_REGISTER(UIC0_MSR);
active[1] = PPC_DEVICE_CONTROL_REGISTER(UIC1_MSR);
active[2] = PPC_DEVICE_CONTROL_REGISTER(UIC2_MSR);
gIntInhibited[0] |= active[0];
gIntInhibited[1] |= active[1];
gIntInhibited[2] |= active[2];
@@ -180,9 +201,15 @@ C_dispatch_irq_handler( struct _BSP_Exception_frame* frame, unsigned int excNum
/* Write a 1-bit to the appropriate status register to clear it */
bmask = 0x80000000 >> bit;
switch (index) {
case 0: mtdcr(UIC0_SR, bmask); break;
case 1: mtdcr(UIC1_SR, bmask); break;
case 2: mtdcr(UIC2_SR, bmask); break;
case 0:
PPC_SET_DEVICE_CONTROL_REGISTER(UIC0_SR, bmask);
break;
case 1:
PPC_SET_DEVICE_CONTROL_REGISTER(UIC1_SR, bmask);
break;
case 2:
PPC_SET_DEVICE_CONTROL_REGISTER(UIC2_SR, bmask);
break;
}
/* Clear in the active record and gIntInhibited */

View File

@@ -68,14 +68,11 @@
#include <bsp/irq.h>
#include <rtems/bspIo.h>
#include <libcpu/cpuIdent.h>
#include <libcpu/spr.h>
#include <rtems/powerpc/powerpc.h>
#include <bsp/ppc_exc_bspsupp.h>
#include <ppc4xx/ppc405gp.h>
#include <ppc4xx/ppc405ex.h>
SPR_RW(SPRG0)
SPR_RW(SPRG1)
#include <stdio.h>
/*
@@ -232,8 +229,8 @@ BSP_output_char_function_type BSP_output_char = DirectUARTWrite;
void bsp_start( void )
{
extern unsigned long *intrStackPtr;
register unsigned char* intrStack;
LINKER_SYMBOL(intrStack_start);
LINKER_SYMBOL(intrStack_size);
ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision;
@@ -261,17 +258,13 @@ void bsp_start( void )
bsp_timer_average_overhead = 2;
bsp_timer_least_valid = 3;
/*
* Initialize some SPRG registers related to irq handling
*/
intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE);
_write_SPRG1((unsigned int)intrStack);
/* signal them that we have fixed PR288 - eventually, this should go away */
/*
* Initialize default raw exception handlers.
*/
initialize_exceptions();
ppc_exc_initialize(
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
(uint32_t) intrStack_start,
(uint32_t) intrStack_size);
/*
* Install our own set of exception vectors

View File

@@ -229,6 +229,8 @@ SECTIONS
. += kIntrStackSize;
intrStack = .;
PROVIDE(intrStackPtr = intrStack);
PROVIDE(intrStack_start = IntrStack_start);
PROVIDE(intrStack_size = kIntrStackSize);
/* Main stack: align to a cache-line boundary */
stack.start = ALIGN(0x20);

View File

@@ -0,0 +1,7 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* bsp_specs, configure.ac, include/bsp.h, include/irq-config.h,
include/mpc55xxevb.h, Makefile.am, network/network.c, preinstall.am,
README, startup/bspclean.c, startup/bspstart.c, startup/linkcmds,
startup/linkcmds.memory, startup/sd-card-init.c, startup/start.S,
tests/tests.c: New files.

View File

@@ -0,0 +1,104 @@
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Makefile of LibBSP for the MPC55xx evaluation boards.
#
ACLOCAL_AMFLAGS = -I ../../../../aclocal
include $(top_srcdir)/../../../../automake/compile.am
include $(top_srcdir)/../../bsp.am
libcpudir = ../../../libcpu/@RTEMS_CPU@
DISTCLEANFILES = include/bspopts.h
# Compiler specs
dist_project_lib_DATA = bsp_specs
# Object files
EXTRA_DIST = startup/start.S
start.$(OBJEXT): startup/start.S
$(CPPASCOMPILE) -o $@ -c $<
project_lib_DATA = start.$(OBJEXT)
EXTRA_DIST += ../shared/start/rtems_crti.S
rtems_crti.$(OBJEXT): ../shared/start/rtems_crti.S
$(CPPASCOMPILE) -o $@ -c $<
project_lib_DATA += rtems_crti.$(OBJEXT)
# Link commands
dist_project_lib_DATA += startup/linkcmds startup/linkcmds.memory
# Includes
include_HEADERS = include/bsp.h
nodist_include_HEADERS = include/bspopts.h ../../shared/tod.h
include_bspdir = $(includedir)/bsp
include_bsp_HEADERS = include/mpc55xxevb.h \
include/irq-config.h \
../../shared/include/irq-generic.h \
../shared/include/tictac.h
# BSP library
noinst_LIBRARIES = libbsp.a
libbsp_a_SOURCES =
libbsp_a_LIBADD = $(libcpudir)/shared/cpuIdent.rel \
$(libcpudir)/shared/cache.rel \
$(libcpudir)/shared/stack.rel \
$(libcpudir)/@RTEMS_CPU_MODEL@/misc.rel \
$(libcpudir)/@RTEMS_CPU_MODEL@/irq.rel \
$(libcpudir)/@RTEMS_CPU_MODEL@/edma.rel \
$(libcpudir)/@RTEMS_CPU_MODEL@/dspi.rel \
$(libcpudir)/@RTEMS_CPU_MODEL@/esci.rel \
$(libcpudir)/@exceptions@/rtems-cpu.rel \
$(libcpudir)/@exceptions@/raw_exception.rel \
$(libcpudir)/@exceptions@/exc_bspsupport.rel
# Startup
noinst_PROGRAMS = startup.rel
startup_rel_SOURCES = ../../shared/bsplibc.c \
../../shared/bsppost.c \
../../shared/bootcard.c \
../shared/src/tictac.c \
startup/bspclean.c \
startup/bspstart.c
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
libbsp_a_LIBADD += startup.rel
# Clock
noinst_PROGRAMS += clock.rel
clock_rel_SOURCES = ../shared/clock/clock.c
clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
libbsp_a_LIBADD += clock.rel
# IRQ
noinst_PROGRAMS += irq-generic.rel
irq_generic_rel_SOURCES = ../../shared/src/irq-generic.c \
../../shared/src/irq-legacy.c
irq_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
libbsp_a_LIBADD += irq-generic.rel
# Tests
noinst_PROGRAMS += tests.rel
tests_rel_SOURCES = tests/tests.c \
startup/sd-card-init.c
tests_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
libbsp_a_LIBADD += tests.rel
# Network
if HAS_NETWORKING
noinst_PROGRAMS += network.rel
network_rel_SOURCES = network/network.c
network_rel_CPPFLAGS = $(AM_CPPFLAGS) -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ -D__BSD_VISIBLE
network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
libbsp_a_LIBADD += network.rel
endif
include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../../automake/local.am
BUILT_SOURCES = preinstall

View File

@@ -0,0 +1,64 @@
OVERVIEW
========
BSP NAME: mpc55xxevb
BOARD: Freescale MPC5566 evaluation board MPC5566EVB
BUS: N/A
CPU FAMILY: ppc
CPU: PowerPC e200z6
COPROCESSORS: N/A
MODE: 32 bit mode
DEBUG MONITOR: BAM
PERIPHERALS
===========
TIMERS: not yet supported
RESOLUTION: not yet supported
SERIAL PORTS: 2 internal eSCI
REAL-TIME CLOCK: N/A
DMA: eDMA
VIDEO: N/A
SCSI: N/A
NETWORKING: FEC (not yet supported)
SPI: DSPI
DRIVER INFORMATION
==================
CLOCK DRIVER: Book E decrementer
IOSUPP DRIVER: N/A
SHMSUPP: N/A
TIMER DRIVER: not yet supported
TTY DRIVER: BSP
STDIO
=====
PORT: ESCI A
ELECTRICAL: N/A
BAUD: 115200
BITS PER CHARACTER: 8
PARITY: N
STOP BITS: 1
NOTES
=====
BUS WIDTH: 32 bit Flash, 32 bit SDRAM
FLASH: 3 MByte
RAM: 128 kByte SDRAM
EXTERNAL RAM: 512 kByte SDRAM
DEBUGGING / CODE LOADING
========================
Tested using the Lauterbach TRACE32 ICD debugger.
ISSUES
======
The memory blocks allocated by LibBlock are in general not cache aligned so we
cannot use DMA transfers. This is suboptimal in combination with a SD Card and
SPI.

View File

@@ -0,0 +1,14 @@
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*startfile:
%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s \
%{!qrtems_debug: start.o%s} \
%{qrtems_debug: start_g.o%s}}}
*endfile:
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn.o%s}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -u start -e start}

View File

@@ -0,0 +1,53 @@
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Configure script of LibBSP for the MPC55xx evaluation boards.
#
AC_PREREQ(2.60)
AC_INIT([rtems-c-src-lib-libbsp-powerpc-mpc55xxevb],[_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_AMPOLISH3
RTEMS_PROG_CC_FOR_TARGET([-fasm])
RTEMS_CANONICALIZE_TOOLS
RTEMS_PROG_CCAS
RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
RTEMS_BSPOPTS_SET([UARTS_USE_TERMIOS],[*],[0])
RTEMS_BSPOPTS_HELP([UARTS_USE_TERMIOS],
[Define to 1 if you want termios support for every port.
Termios support is independent of the choice of UART I/O mode.])
RTEMS_BSPOPTS_SET([CONSOLE_MINOR],[*],[MPC55XX_ESCI_A_MINOR])
RTEMS_BSPOPTS_HELP([CONSOLE_MINOR],
[Must be defined to be one of MPC55XX_ESCI_A_MINOR or MPC55XX_ESCI_B_MINOR. Determines which
device will be registered as /dev/console.])
RTEMS_BSPOPTS_SET([UARTS_IO_MODE],[*],[0])
RTEMS_BSPOPTS_HELP([UARTS_IO_MODE],
[Define to 1 if you want interrupt-driven I/O for the SCI ports.])
RTEMS_BSPOPTS_SET([PRINTK_MINOR],[*],[MPC55XX_ESCI_B_MINOR])
RTEMS_BSPOPTS_HELP([PRINTK_MINOR],
[Must be defined to be one of MPC55XX_ESCI_A_MINOR or MPC55XX_ESCI_B_MINOR. Determines which
device is used for output by printk(). The printk port always uses polled
I/O. Don't open the printk port from RTEMS unless also using polled I/O
for the SCI ports.])
AC_CONFIG_FILES([Makefile
include/bspopts.h])
RTEMS_PPC_EXCEPTIONS
AC_OUTPUT

View File

@@ -0,0 +1,54 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Global BSP variables and functions
*/
/*
* 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.
*/
#ifndef LIBBSP_POWERPC_BSP_H
#define LIBBSP_POWERPC_BSP_H
#include <stdint.h>
#include <rtems.h>
#include <rtems/console.h>
#include <rtems/clockdrv.h>
#include <bspopts.h>
#include <bsp/tictac.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef ASM
/** @brief System clock frequency */
extern unsigned int bsp_clock_speed;
/** @brief Time base clicks per micro second */
extern uint32_t bsp_clicks_per_usec;
rtems_status_code mpc55xx_sd_card_init();
#endif /* ASM */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBBSP_POWERPC_BSP_H */

View File

@@ -0,0 +1,76 @@
/**
* @file
*
* @ingroup bsp_interrupt
*
* @brief BSP interrupt support configuration.
*/
/*
* 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.
*/
#ifndef LIBBSP_POWERPC_MPC55XXEVB_IRQ_CONFIG_H
#define LIBBSP_POWERPC_MPC55XXEVB_IRQ_CONFIG_H
#include <stdint.h>
/**
* @addtogroup bsp_interrupt
*
* @{
*/
/**
* @brief Minimum vector number.
*/
#define BSP_INTERRUPT_VECTOR_MIN 0
/**
* @brief Maximum vector number.
*/
#define BSP_INTERRUPT_VECTOR_MAX 328
/**
* @brief Enables the index table.
*
* If you enable the index table, you have to define a size for the handler
* table (@ref BSP_INTERRUPT_HANDLER_TABLE_SIZE) and must provide an integer
* type capable to index the complete handler table (@ref
* bsp_interrupt_handler_index_type).
*/
#define BSP_INTERRUPT_USE_INDEX_TABLE
/**
* @brief Disables usage of the heap.
*
* If you define this, you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as
* well.
*/
#define BSP_INTERRUPT_NO_HEAP_USAGE
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
/**
* @brief Size of the handler table.
*/
#define BSP_INTERRUPT_HANDLER_TABLE_SIZE 63
/**
* @brief Integer type capable to index the complete handler table.
*/
typedef uint8_t bsp_interrupt_handler_index_type;
#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
/** @} */
#endif /* LIBBSP_POWERPC_MPC55XXEVB_IRQ_CONFIG_H */

View File

@@ -0,0 +1,28 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Documentation for this file
*
* More details.
*
* @par Copyright
* Copyright (c) 2008<br>
* Embedded Brains GmbH<br>
* Obere Lagerstr. 30<br>
* D-82178 Puchheim<br>
* Germany<br>
* rtems@embedded-brains.de<br>
*
* @par License
* 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 LIBBSP_POWERPC_MPC55XXEVB_H
#define LIBBSP_POWERPC_MPC55XXEVB_H
/* TODO */
#endif /* LIBBSP_POWERPC_MPC55XXEVB_H */

View File

@@ -0,0 +1,21 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Documentation for this file
*
* More details.
*
* @par Copyright
* Copyright (c) 2008<br>
* Embedded Brains GmbH<br>
* Obere Lagerstr. 30<br>
* D-82178 Puchheim<br>
* Germany<br>
* rtems@embedded-brains.de<br>
*
* @par License
* 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.
*/

View File

@@ -0,0 +1,24 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief BSP cleanup code
*/
/*
* 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.
*/
void bsp_cleanup()
{
// TODO
}

View File

@@ -0,0 +1,263 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief BSP startup code.
*/
/*
* 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.
*/
#include <mpc55xx/mpc55xx.h>
#include <mpc55xx/regs.h>
#include <mpc55xx/edma.h>
#include <rtems.h>
#include <rtems/bspIo.h>
#include <rtems/libcsupport.h>
#include <libcpu/powerpc-utility.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/ppc_exc_bspsupp.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
#define DEBUG_DONE() DEBUG_PRINT( "Done\n")
#define MPC55XX_INTERRUPT_STACK_SIZE 0x1000
/* Symbols defined in linker command file */
LINKER_SYMBOL( bsp_ram_start);
LINKER_SYMBOL( bsp_ram_end);
LINKER_SYMBOL( bsp_external_ram_start);
LINKER_SYMBOL( bsp_external_ram_size);
LINKER_SYMBOL( bsp_section_bss_end);
unsigned int bsp_clock_speed = 0;
uint32_t bsp_clicks_per_usec = 0;
void BSP_panic( char *s)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
printk( "%s PANIC %s\n", _RTEMS_version, s);
while (1) {
/* Do nothing */
}
}
void _BSP_Fatal_error( unsigned n)
{
rtems_interrupt_level level;
rtems_interrupt_disable( level);
printk( "%s PANIC ERROR %u\n", _RTEMS_version, n);
while (1) {
/* Do nothing */
}
}
void bsp_pretasking_hook()
{
uint32_t heap_start = bsp_external_ram_start;
uint32_t heap_size = bsp_external_ram_size;
bsp_libc_init( heap_start, heap_size, 0);
#ifdef STACK_CHECKER_ON
Stack_check_Initialize();
#endif
#ifdef RTEMS_DEBUG
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
#endif
}
void bsp_predriver_hook()
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
DEBUG_PRINT( "Initialize eDMA ...\n");
sc = mpc55xx_edma_init();
if (sc != RTEMS_SUCCESSFUL) {
BSP_panic( "Cannot initialize eDMA");
} else {
DEBUG_DONE();
}
}
static void mpc55xx_ebi_init()
{
struct EBI_CS_tag cs = { BR : MPC55XX_ZERO_FLAGS, OR : MPC55XX_ZERO_FLAGS };
union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
int i = 0;
/* External SRAM (0 wait states, 512kB, 4 word burst) */
cs.BR.B.BA = 0;
cs.BR.B.PS = 1;
cs.BR.B.BL = 1;
cs.BR.B.WEBS = 0;
cs.BR.B.TBDIP = 0;
cs.BR.B.BI = 1; /* TODO: Enable burst */
cs.BR.B.V = 1;
cs.OR.B.AM = 0x1fff0;
cs.OR.B.SCY = 0;
cs.OR.B.BSCY = 0;
EBI.CS [0] = cs;
/* !CS [0] */
SIU.PCR [0].R = 0x443;
/* ADDR [8 : 31] */
for (i = 4; i < 4 + 24; ++i) {
SIU.PCR [i].R = 0x440;
}
/* DATA [0 : 15] */
for (i = 28; i < 28 + 16; ++i) {
SIU.PCR [i].R = 0x440;
}
/* RD_!WR */
SIU.PCR [62].R = 0x443;
/* !BDIP */
SIU.PCR [63].R = 0x443;
/* !WE [0 : 3] */
for (i = 64; i < 64 + 4; ++i) {
SIU.PCR [i].R = 0x443;
}
/* !OE */
SIU.PCR [68].R = 0x443;
/* !TS */
SIU.PCR [69].R = 0x443;
}
/**
* @brief Start BSP.
*/
void bsp_start(void)
{
ppc_cpu_id_t myCpu;
ppc_cpu_revision_t myCpuRevision;
uint32_t ram_start = bsp_ram_start;
uint32_t ram_end = bsp_ram_end;
uint32_t interrupt_stack_start = ram_end - 2 * MPC55XX_INTERRUPT_STACK_SIZE;
uint32_t interrupt_stack_size = MPC55XX_INTERRUPT_STACK_SIZE;
uint32_t work_space_start = bsp_section_bss_end;
uint32_t work_space_end = work_space_start + rtems_configuration_get_work_space_size();
/* ESCI pad configuration */
SIU.PCR [89].R = 0x400;
SIU.PCR [90].R = 0x400;
DEBUG_PRINT( "BSP start ...\n");
/* Memory layout */
Configuration.work_space_start = work_space_start;
DEBUG_PRINT( "System clock : %i\n", mpc55xx_get_system_clock());
DEBUG_PRINT( "Memory start : 0x%08x\n", ram_start);
DEBUG_PRINT( "Memory end : 0x%08x\n", ram_end);
DEBUG_PRINT( "Memory size : 0x%08x\n", ram_end - ram_start);
DEBUG_PRINT( "Work space start : 0x%08x\n", work_space_start);
DEBUG_PRINT( "Work space end : 0x%08x\n", work_space_end);
DEBUG_PRINT( "Work space size : 0x%08x\n", work_space_end - work_space_start);
DEBUG_PRINT( "Interrupt stack start : 0x%08x\n", interrupt_stack_start);
DEBUG_PRINT( "Interrupt stack end : 0x%08x\n", interrupt_stack_start + interrupt_stack_size);
DEBUG_PRINT( "Interrupt stack size : 0x%08x\n", interrupt_stack_size);
if (work_space_end > interrupt_stack_start) {
BSP_panic( "Not enough memory for the work space");
}
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type()
* function store the result in global variables so that it can be used
* latter...
*/
myCpu = get_ppc_cpu_type();
myCpuRevision = get_ppc_cpu_revision();
/* Time reference value */
bsp_clicks_per_usec = bsp_clock_speed / 1000000;
/* Initialize External Bus Interface */
mpc55xx_ebi_init();
/* Initialize exceptions */
DEBUG_PRINT( "Initialize exceptions ...\n");
ppc_exc_initialize( PPC_INTERRUPT_DISABLE_MASK_DEFAULT, interrupt_stack_start, interrupt_stack_size);
DEBUG_DONE();
/* Initialize interrupts */
DEBUG_PRINT( "Initialize interrupts ...\n");
if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
BSP_panic( "Cannot initialize interrupts");
} else {
DEBUG_DONE();
}
DEBUG_PRINT( "BSP start done\n");
return;
/* TODO */
/*
* Enable instruction and data caches. Do not force writethrough mode.
*/
#if INSTRUCTION_CACHE_ENABLE
rtems_cache_enable_instruction();
#endif
#if DATA_CACHE_ENABLE
rtems_cache_enable_data();
#endif
}
/**
* @brief Idle thread body.
*/
Thread _Thread_Idle_body( uint32_t ignored)
{
while (1) {
asm volatile(
"mfmsr 3;"
"oris 3,3,4;"
"sync;"
"mtmsr 3;"
"isync;"
"ori 3,3,0;"
"ori 3,3,0"
);
}
return 0;
}

View File

@@ -0,0 +1,278 @@
/**
* @file
*
* Derived from internal linker script of GNU ld (GNU Binutils) 2.18 for elf32ppc emulation.
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(start)
INCLUDE linkcmds.memory
SECTIONS
{
.text : {
/*
* BSP: Start of text section
*/
bsp_section_text_start = .;
/*
* BSP: System startup entry
*/
KEEP (*(.entry))
/*
* BSP: Moved into .text from .init
*/
KEEP (*(.init))
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.glink)
/*
* BSP: Special FreeBSD sysctl sections
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/*
* BSP: Moved into .text from .*
*/
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
*(.interp)
*(.note.gnu.build-id)
*(.hash)
*(.gnu.hash)
*(.dynsym)
*(.dynstr)
*(.gnu.version)
*(.gnu.version_d)
*(.gnu.version_r)
*(.eh_frame_hdr)
/*
* BSP: Magic PPC stuff
*/
*(.PPC.*)
/*
* BSP: Required by cpukit/score/src/threadhandler.c
*/
PROVIDE (_fini = .);
/*
* BSP: Moved into .text from .fini
*/
KEEP (*(.fini))
. = ALIGN (bsp_section_align);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
} > ROM =0
.sdata2 : {
PROVIDE (_SDA2_BASE_ = 32768);
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
. = ALIGN (bsp_section_align);
} > ROM =0
.sbss2 : {
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
. = ALIGN (bsp_section_align);
/*
* BSP: End of text section
*/
bsp_section_text_end = .;
} > ROM =0
.data : AT (bsp_section_text_end) {
/*
* BSP: Start of data section
*/
bsp_section_data_start = .;
/*
* BSP: Reserve space for exception handler
*/
. = . + 0x180;
/*
* BSP: Moved into .data from .ctors
*/
/* gcc uses crtbegin.o to find the start of
the constructors, 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. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
/*
* BSP: Moved into .data from .dtors
*/
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/*
* BSP: Moved into .data from .*
*/
*(.tdata .tdata.* .gnu.linkonce.td.*)
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
*(.data1)
KEEP (*(.eh_frame))
*(.gcc_except_table .gcc_except_table.*)
KEEP (*(.jcr))
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
*(.fixup)
*(.got1)
*(.got2)
*(.dynamic)
*(.got)
*(.plt)
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
*(.data .data.* .gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
. = ALIGN (bsp_section_align);
} > RAM
.sdata : {
PROVIDE (_SDA_BASE_ = 32768);
*(.sdata .sdata.* .gnu.linkonce.s.*)
. = ALIGN (bsp_section_align);
_edata = .;
PROVIDE (edata = .);
/*
* BSP: End of data section
*/
bsp_section_data_end = .;
} > RAM
.sbss : {
/*
* BSP: Start of bss section
*/
bsp_section_bss_start = .;
__bss_start = .;
PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
*(.scommon)
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
. = ALIGN (bsp_section_align);
} > RAM
.bss : {
*(COMMON)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN (bsp_section_align);
__end = .;
_end = .;
PROVIDE (end = .);
/*
* BSP: End of bss section
*/
bsp_section_bss_end = .;
} > RAM
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : {
*(.note.GNU-stack) *(.gnu_debuglink)
}
/*
* BSP: Catch all unknown sections
*/
.nirvana : {
*(*)
} > NIRVANA
}

View File

@@ -0,0 +1,21 @@
MEMORY
{
ROM (RX) : ORIGIN = 0x0, LENGTH = 3M
RAM (AIW) : ORIGIN = 0x40000000, LENGTH = 128K
EXT_RAM : ORIGIN = 0x20000000, LENGTH = 512K
NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
bsp_ram_start = ORIGIN (RAM);
bsp_ram_end = ORIGIN (RAM) + LENGTH (RAM);
bsp_ram_size = LENGTH (RAM);
bsp_rom_start = ORIGIN (ROM);
bsp_rom_end = ORIGIN (ROM) + LENGTH (ROM);
bsp_rom_size = LENGTH (ROM);
bsp_external_ram_start = ORIGIN (EXT_RAM);
bsp_external_ram_end = ORIGIN (EXT_RAM) + LENGTH (EXT_RAM);
bsp_external_ram_size = LENGTH (EXT_RAM);
bsp_section_align = 32;

View File

@@ -0,0 +1,149 @@
#include <stdio.h>
#include <mpc55xx/mpc55xx.h>
#include <mpc55xx/regs.h>
#include <mpc55xx/dspi.h>
#include <libchip/spi-sd-card.h>
#define DEBUG
#include <rtems/status-checks.h>
#include <bsp.h>
static rtems_status_code mpc55xx_dspi_init()
{
int rv = 0;
int i = 0;
char device_name [] = "/dev/spi0";
union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
rv = rtems_libi2c_initialize();
CHECK_RVSC( rv, "rtems_libi2c_initialize");
/* DSPI D inputs are taken from DSPI C */
SIU.DISR.R = 0x000000FC;
/* DSPI A signals */
pcr.B.PA = 1;
pcr.B.ODE = 0;
pcr.B.HYS = 0;
pcr.B.SRC = 3;
pcr.B.WPE = 1;
pcr.B.WPS = 1;
/* SCK */
pcr.B.OBE = 1;
pcr.B.IBE = 0;
SIU.PCR [93].R = pcr.R;
/* SIN */
pcr.B.OBE = 0;
pcr.B.IBE = 1;
SIU.PCR [94].R = pcr.R;
/* SOUT */
pcr.B.OBE = 1;
pcr.B.IBE = 0;
SIU.PCR [95].R = pcr.R;
/* PCSx */
pcr.B.OBE = 1;
pcr.B.IBE = 0;
SIU.PCR [96].R = pcr.R;
SIU.PCR [97].R = pcr.R;
SIU.PCR [98].R = pcr.R;
SIU.PCR [99].R = pcr.R;
SIU.PCR [100].R = pcr.R;
SIU.PCR [101].R = pcr.R;
mpc55xx_dspi_bus_table [3].master = 0;
for (i = 0; i < MPC55XX_DSPI_NUMBER; ++i) {
device_name [8] = '0' + i;
rv = rtems_libi2c_register_bus( device_name, (rtems_libi2c_bus_t *) &mpc55xx_dspi_bus_table [i]);
CHECK_RVSC( rv, device_name);
}
return RTEMS_SUCCESSFUL;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include <rtems/fsmount.h>
#include <rtems/dosfs.h>
#include <rtems/ide_part_table.h>
#include <rtems/console.h>
#define MPC55XX_DEVICE "sd-card-a"
#define MPC55XX_DEVICE_FILE "/dev/" MPC55XX_DEVICE
#define MPC55XX_PARTITION "/dev/sd-card-a1"
#define MPC55XX_MOUNT_POINT "/mnt"
static fstab_t mpc55xx_fs_table [] = { {
MPC55XX_PARTITION, MPC55XX_MOUNT_POINT,
&msdos_ops, RTEMS_FILESYSTEM_READ_WRITE,
FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
FSMOUNT_MNT_OK
}, {
MPC55XX_DEVICE_FILE, MPC55XX_MOUNT_POINT,
&msdos_ops, RTEMS_FILESYSTEM_READ_WRITE,
FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
0
}
};
#define SD_CARD_NUMBER 1
sd_card_driver_entry sd_card_driver_table [SD_CARD_NUMBER] = { {
.driver = {
.ops = &sd_card_driver_ops,
.size = sizeof( sd_card_driver_entry)
},
.table_index = 0,
.minor = 0,
.device_name = "sd-card-a",
.disk_device_name = "/dev/sd-card-a",
.transfer_mode = SD_CARD_TRANSFER_MODE_DEFAULT,
.command = SD_CARD_COMMAND_DEFAULT,
/* response : whatever, */
.response_index = SD_CARD_COMMAND_SIZE,
.n_ac_max = SD_CARD_N_AC_MAX_DEFAULT,
.block_number = 0,
.block_size = 0,
.block_size_shift = 0,
.busy = 1,
.verbose = 1,
.schedule_if_busy = 0,
}
};
rtems_status_code mpc55xx_sd_card_init()
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
sd_card_driver_entry *e = &sd_card_driver_table [0];
DEBUG_PRINT( "Task started\n");
sc = mpc55xx_dspi_init();
CHECK_SC( rv, "Intitalize DSPI bus");
rv = rtems_libi2c_register_drv( e->device_name, (rtems_libi2c_drv_t *) e, mpc55xx_dspi_bus_table [0].bus_number, 0);
CHECK_RVSC( rv, "Register SD Card driver");
sc = rtems_ide_part_table_initialize( MPC55XX_DEVICE_FILE);
CHECK_SC( sc, "Initialize IDE partition table");
rv = mkdir( MPC55XX_MOUNT_POINT, S_IRWXU);
CHECK_RVSC( rv, "Create mount point");
rv = rtems_fsmount( mpc55xx_fs_table, sizeof( mpc55xx_fs_table) / sizeof( mpc55xx_fs_table [0]), NULL);
CHECK_RVSC( rv, "Mount file systems");
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,272 @@
/**
* @file
*
* @ingroup mpc55xx_asm
*
* @brief Boot and system start code.
*/
/*
* 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.
*/
/**
* @defgroup mpc55xx_asm Assembler files
*
* @ingroup mpc55xx
*/
#include <libcpu/powerpc-utility.h>
#include <mpc55xx/reg-defs.h>
.section ".entry", "ax"
PUBLIC_VAR (start)
start:
/*
* BAM
*/
/* BAM: RCHW */
.int 0x5a0000
/* BAM: Address of start instruction */
.int 0x8
/*
* Enable time base
*/
li r0, 0
mtspr TBWU, r0
mtspr TBWL, r0
mfspr r2, HID0
ori r2, r2, 0x4000
mtspr HID0, r2
/*
* System clock
*/
bl SYM (mpc55xx_fmpll_reset_config)
/*
* Enable branch prediction
*/
LWI r2, BUCSR_BBFI | BUCSR_BPEN
mtspr BUCSR, r2
/*
* Basics
*/
/* Set stack start to end of ram */
LA r1, bsp_ram_end
addi r1, r1, -8
/* Enable SPE */
mfmsr r2
oris r2, r2, 0x200
mtmsr r2
/* Config internal flash */
bl SYM (mpc55xx_flash_config)
/* FIXME: Config cache */
bl config_cache
/*
* TODO, FIXME: Enable cache in the MMU for the SRAM
*/
.equ MAS0, 624
.equ MAS1, 625
.equ MAS2, 626
.equ MAS3, 627
LWI r3, 0x10030000
mtspr MAS0, r3
tlbre
LWI r4, ~0x00000008
mfspr r3, MAS2
and r3, r3, r4
mtspr MAS2, r3
tlbwe
/*
* TODO, FIXME: Set MMU for the external SRAM
*/
LWI r3, 0x10020000
mtspr MAS0, r3
tlbre
LWI r4, 0xfff
mfspr r3, MAS3
and r3, r3, r4
LWI r4, 0x20000000
or r3, r3, r4
mtspr MAS3, r3
tlbwe
/*
* Zero RAM
*/
/* Addresses */
LA r3, bsp_ram_start
LA r4, bsp_ram_end
/* Assert: Proper alignment of destination start */
andi. r6, r3, 0x37
bne twiddle
/* Assert: Proper alignment of destination end */
andi. r6, r4, 0x37
bne twiddle
/* Data size = destination end - destination start */
subf r4, r3, r4
/* Save time */
mftb r24
/* Zero */
bl SYM (mpc55xx_zero_32)
/* Save time and get time delta */
mftb r25
subf r24, r24, r25
/*
* Copy data
*/
/* Addresses */
LA r3, bsp_section_text_end
LA r4, bsp_section_data_start
LA r5, bsp_section_data_end
/* Assert: Proper alignment of source start */
andi. r6, r3, 0x7
bne twiddle
/* Assert: Proper alignment of destination start */
andi. r6, r4, 0x7
bne twiddle
/* Assert: Proper alignment of destination end */
andi. r6, r5, 0x7
bne twiddle
/* Data size = destination end - destination start */
subf r5, r4, r5
/* Copy */
bl SYM (mpc55xx_copy_8)
/* Save time and get time delta */
mftb r26
subf r25, r25, r26
/*
* Prepare high level initialization
*/
LA r3, bsp_ram_start
LA r4, ppc_exc_vector_base
stw r3, 0(r4)
/* Set global BSP clock speed variable */
bl SYM (mpc55xx_get_system_clock)
LA r4, bsp_clock_speed
stw r3, 0(r4)
/* Create NULL */
li r0, 0
/* Return address */
stw r0, 4(r1)
/* Back chain */
stw r0, 0(r1)
/* Read-only small data */
LA r2, _SDA2_BASE_
/* Read-write small data */
LA r13, _SDA_BASE_
/*
* Start RTEMS
*/
/* Clear argc and argv */
xor r3, r3, r3
xor r4, r4, r4
/* Start RTEMS */
bl SYM (boot_card)
/* Spin around */
b twiddle
.equ L1CSR0, 1010
.equ L1CSR0_CINV, 0x2
.equ L1CSR0_CABT, 0x4
/* FIXME: CORG??? .equ L1CSR0_SETTINGS, 0x00180011 */
.equ L1CSR0_SETTINGS, 0x00100001
/*
* Configure cache
*/
config_cache:
/* Start cache invalidation */
LWI r5, L1CSR0_CINV
mtspr L1CSR0, r5
/* Bit masks to test and clear invalidation abortion (CABT) */
LWI r6, L1CSR0_CABT
not r7, r6
/* Wait for cache invalidation to complete */
check_cache_invalidation:
mfspr r9, L1CSR0
/* Check if the invalidate was aborted */
and. r10, r9, r6
beq no_chache_invalidation_abort
/* Clear CABT bit */
and r10, r9, r7
mtspr L1CSR0, r10
/* Retry invalidation */
b config_cache
no_chache_invalidation_abort:
/* Check CINV bit */
and. r10, r5, r9
/* Wait? */
bne check_cache_invalidation
/* Enable cache */
LWI r6, L1CSR0_SETTINGS
mfspr r5, L1CSR0
or r5, r5, r6
msync
isync
mtspr L1CSR0, r5
/* Return */
blr
twiddle:
b twiddle

View File

@@ -0,0 +1,674 @@
#include <stdio.h>
#include <rtems/irq.h>
#include <mpc55xx/regs.h>
#include <mpc55xx/mpc55xx.h>
#include <mpc55xx/dspi.h>
#include <mpc55xx/edma.h>
#include <libchip/spi-sd-card.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/irq-extension.h>
#include <libcpu/powerpc-utility.h>
// #define DEBUG
#include <rtems/status-checks.h>
static rtems_driver_address_table test_mpc55xx_drv_ops = {
initialization_entry : NULL,
open_entry : NULL,
close_entry : NULL,
read_entry : NULL,
write_entry : NULL,
control_entry : NULL
};
static rtems_libi2c_drv_t test_mpc55xx_dspi_drv = {
ops : &test_mpc55xx_drv_ops,
size : sizeof( rtems_libi2c_drv_t)
};
#define MPC55XX_TEST_DSPI_ADDRESS 0
// #define MPC55XX_TEST_DSPI_BUFSIZE (16 * 32)
#define MPC55XX_TEST_DSPI_BUFSIZE 8
// #define MPC55XX_TEST_DSPI_BUFSIZE_CACHE_PROOF MPC55XX_TEST_DSPI_BUFSIZE
#define MPC55XX_TEST_DSPI_BUFSIZE_CACHE_PROOF 32
rtems_device_minor_number test_mpc55xx_dspi_bus [MPC55XX_DSPI_NUMBER];
static rtems_libi2c_tfr_mode_t test_mpc55xx_dspi_transfer_mode = { baudrate : 550000, bits_per_char : 8, lsb_first : FALSE, clock_inv : FALSE, clock_phs : FALSE };
static rtems_id test_mpc55xx_dspi_ping;
static rtems_id test_mpc55xx_dspi_pong;
static unsigned char test_mpc55xx_dspi_writer_outbuf [2] [MPC55XX_TEST_DSPI_BUFSIZE_CACHE_PROOF] __attribute__ ((aligned (32)));
static unsigned char test_mpc55xx_dspi_writer_inbuf [MPC55XX_TEST_DSPI_BUFSIZE_CACHE_PROOF] __attribute__ ((aligned (32)));
static unsigned char test_mpc55xx_dspi_reader_inbuf [MPC55XX_TEST_DSPI_BUFSIZE_CACHE_PROOF] __attribute__ ((aligned (32)));
static rtems_task test_mpc55xx_dspi_writer( rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
rtems_device_minor_number device;
rtems_libi2c_read_write_t read_and_write = { rd_buf : NULL, wr_buf : NULL, byte_cnt : 0 };
int i = 0;
DEBUG_PRINT( "Task started\n");
device = rtems_libi2c_register_drv( NULL, &test_mpc55xx_dspi_drv, test_mpc55xx_dspi_bus [2], 0);
CHECK_RV_TASK( device, "rtems_libi2c_register_drv");
sc = rtems_libi2c_send_start( device);
CHECK_SC_TASK( sc, "rtems_libi2c_send_start");
rv = rtems_libi2c_ioctl( device, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &test_mpc55xx_dspi_transfer_mode);
CHECK_RV_TASK( rv, "rtems_libi2c_ioctl");
sc = rtems_libi2c_send_addr( device, MPC55XX_TEST_DSPI_ADDRESS);
CHECK_SC_TASK( sc, "rtems_libi2c_send_addr");
for (i = 0; i < MPC55XX_TEST_DSPI_BUFSIZE; ++i) {
test_mpc55xx_dspi_writer_outbuf [0] [i] = 0xa5;
test_mpc55xx_dspi_writer_outbuf [1] [i] = 0xa5;
// test_mpc55xx_dspi_writer_outbuf [0] [i] = i + 1;
// test_mpc55xx_dspi_writer_outbuf [1] [i] = -(i + 1);
}
int toggle = 0;
read_and_write.byte_cnt = MPC55XX_TEST_DSPI_BUFSIZE;
read_and_write.rd_buf = test_mpc55xx_dspi_writer_inbuf;
read_and_write.wr_buf = test_mpc55xx_dspi_writer_outbuf [toggle];
while (1) {
tic();
// sc = rtems_semaphore_obtain( test_mpc55xx_dspi_pong, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
// CHECK_SC_TASK( sc, "rtems_semaphore_obtain");
DEBUG_PRINT( "Ping\n");
// sc = rtems_libi2c_send_start( device);
// CHECK_SC_TASK( sc, "rtems_libi2c_send_start");
// sc = rtems_libi2c_send_addr( device, MPC55XX_TEST_DSPI_ADDRESS);
// CHECK_SC_TASK( sc, "rtems_libi2c_send_addr");
rv = rtems_libi2c_ioctl( device, RTEMS_LIBI2C_IOCTL_READ_WRITE, &read_and_write);
CHECK_RV_TASK( rv, "rtems_libi2c_ioctl: RTEMS_LIBI2C_IOCTL_READ_WRITE");
// rv = rtems_libi2c_write_bytes( device, test_mpc55xx_dspi_writer_outbuf [0], MPC55XX_TEST_DSPI_BUFSIZE);
// CHECK_RV_TASK( rv, "rtems_libi2c_write_bytes");
// sc = rtems_libi2c_send_stop( device);
// CHECK_SC_TASK( sc, "rtems_libi2c_send_stop");
toggle = toggle ? 0 : 1;
read_and_write.wr_buf = test_mpc55xx_dspi_writer_outbuf [toggle];
// sc = rtems_semaphore_release( test_mpc55xx_dspi_ping);
// CHECK_SC_TASK( sc, "rtems_semaphore_release");
}
sc = rtems_libi2c_send_stop( device);
CHECK_SC_TASK( sc, "rtems_libi2c_send_stop");
sc = rtems_task_delete( RTEMS_SELF);
CHECK_SC_TASK( sc, "rtems_task_delete");
}
static rtems_task test_mpc55xx_dspi_reader( rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
rtems_device_minor_number device;
int i = 0;
DEBUG_PRINT( "Task started\n");
device = rtems_libi2c_register_drv( NULL, &test_mpc55xx_dspi_drv, test_mpc55xx_dspi_bus [3], 0);
CHECK_RV_TASK( device, "rtems_libi2c_register_drv");
sc = rtems_libi2c_send_start( device);
CHECK_SC_TASK( sc, "rtems_libi2c_send_start");
rv = rtems_libi2c_ioctl( device, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &test_mpc55xx_dspi_transfer_mode);
CHECK_RV_TASK( rv, "rtems_libi2c_ioctl");
sc = rtems_libi2c_send_addr( device, MPC55XX_TEST_DSPI_ADDRESS);
CHECK_SC_TASK( sc, "rtems_libi2c_send_addr");
for (i = 0; i < MPC55XX_TEST_DSPI_BUFSIZE; ++i) {
test_mpc55xx_dspi_reader_inbuf [i] = -1;
}
sc = rtems_semaphore_obtain( test_mpc55xx_dspi_ping, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
CHECK_SC_TASK( sc, "rtems_semaphore_obtain");
DEBUG_PRINT( "Pong\n");
sc = rtems_semaphore_release( test_mpc55xx_dspi_pong);
CHECK_SC_TASK( sc, "rtems_semaphore_release");
while (1) {
sc = rtems_semaphore_obtain( test_mpc55xx_dspi_ping, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
CHECK_SC_TASK( sc, "rtems_semaphore_obtain");
DEBUG_PRINT( "Pong\n");
rv = rtems_libi2c_read_bytes( device, test_mpc55xx_dspi_reader_inbuf, MPC55XX_TEST_DSPI_BUFSIZE);
CHECK_RV_TASK( rv, "rtems_libi2c_read_bytes");
sc = rtems_semaphore_release( test_mpc55xx_dspi_pong);
CHECK_SC_TASK( sc, "rtems_semaphore_release");
printk( "Time: %i, Value: 0x%02x%02x%02x%02x\n", tac(),
test_mpc55xx_dspi_reader_inbuf [0], test_mpc55xx_dspi_reader_inbuf [1],
test_mpc55xx_dspi_reader_inbuf [2], test_mpc55xx_dspi_reader_inbuf [3]);
}
sc = rtems_libi2c_send_stop( device);
CHECK_SC_TASK( sc, "rtems_libi2c_send_stop");
sc = rtems_task_delete( RTEMS_SELF);
CHECK_SC_TASK( sc, "rtems_task_delete");
}
rtems_task test_sd_card( rtems_task_argument arg);
static rtems_task test_mpc55xx_intc( rtems_task_argument arg);
rtems_status_code mpc55xx_dspi_register()
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
int i = 0;
char device_name [] = "/dev/spi0";
union SIU_PCR_tag pcr = MPC55XX_ZERO_FLAGS;
printk( "Boot time: %u\n", ppc_time_base());
test_mpc55xx_intc( 0);
rv = rtems_libi2c_initialize();
CHECK_RVSC( rv, "rtems_libi2c_initialize");
/* DSPI D inputs are taken from DSPI C */
SIU.DISR.R = 0x000000FC;
/* DSPI A signals */
pcr.B.PA = 1;
pcr.B.ODE = 0;
pcr.B.HYS = 0;
pcr.B.SRC = 3;
pcr.B.WPE = 1;
pcr.B.WPS = 1;
/* SCK */
pcr.B.OBE = 1;
pcr.B.IBE = 0;
SIU.PCR [93].R = pcr.R;
/* SIN */
pcr.B.OBE = 0;
pcr.B.IBE = 1;
SIU.PCR [94].R = pcr.R;
/* SOUT */
pcr.B.OBE = 1;
pcr.B.IBE = 0;
SIU.PCR [95].R = pcr.R;
/* PCSx */
pcr.B.OBE = 1;
pcr.B.IBE = 0;
SIU.PCR [96].R = pcr.R;
SIU.PCR [97].R = pcr.R;
SIU.PCR [98].R = pcr.R;
SIU.PCR [99].R = pcr.R;
SIU.PCR [100].R = pcr.R;
SIU.PCR [101].R = pcr.R;
mpc55xx_dspi_bus_table [3].master = 0;
for (i = 0; i < MPC55XX_DSPI_NUMBER; ++i) {
device_name [8] = '0' + i;
rv = rtems_libi2c_register_bus( device_name, (rtems_libi2c_bus_t *) &mpc55xx_dspi_bus_table [i]);
CHECK_RVSC( rv, device_name);
test_mpc55xx_dspi_bus [i] = rv;
}
sc = rtems_semaphore_create (
rtems_build_name ( 'P', 'I', 'N', 'G'),
1,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&test_mpc55xx_dspi_ping
);
CHECK_SC( sc, "rtems_semaphore_create");
sc = rtems_semaphore_create (
rtems_build_name ( 'P', 'O', 'N', 'G'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&test_mpc55xx_dspi_pong
);
CHECK_SC( sc, "rtems_semaphore_create");
// rtems_id writer_task_id;
// rtems_id reader_task_id;
//
// sc = rtems_task_create(
// rtems_build_name( 'T', 'W', 'R', 'T'),
// 2,
// RTEMS_MINIMUM_STACK_SIZE,
// RTEMS_DEFAULT_MODES,
// RTEMS_DEFAULT_ATTRIBUTES,
// &writer_task_id
// );
// CHECK_SC( sc, "rtems_task_create");
// sc = rtems_task_create(
// rtems_build_name( 'T', 'R', 'D', 'R'),
// 1,
// RTEMS_MINIMUM_STACK_SIZE,
// RTEMS_DEFAULT_MODES,
// RTEMS_DEFAULT_ATTRIBUTES,
// &reader_task_id
// );
// CHECK_SC( sc, "rtems_task_create");
//
// sc = rtems_task_start( writer_task_id, test_mpc55xx_dspi_writer, 0);
// CHECK_SC( sc, "rtems_task_start");
// sc = rtems_task_start( reader_task_id, test_mpc55xx_dspi_reader, 0);
// CHECK_SC( sc, "rtems_task_start");
rtems_id sd_card_task_id;
sc = rtems_task_create(
rtems_build_name( 'T', 'S', 'D', 'C'),
1,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&sd_card_task_id
);
CHECK_SC( sc, "rtems_task_create");
sc = rtems_task_start( sd_card_task_id, test_sd_card, 0);
CHECK_SC( sc, "rtems_task_start");
rtems_id intc_id;
sc = rtems_task_create(
rtems_build_name( 'I', 'N', 'T', 'C'),
2,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&intc_id
);
CHECK_SC( sc, "rtems_task_create");
sc = rtems_task_start( intc_id, test_mpc55xx_intc, 0);
CHECK_SC( sc, "rtems_task_start");
sc = rtems_task_delete( RTEMS_SELF);
CHECK_SC( sc, "rtems_task_delete");
return RTEMS_SUCCESSFUL;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include <rtems/fsmount.h>
#include <rtems/dosfs.h>
#include <rtems/ide_part_table.h>
#define TEST_SD_CARD_BUF_SIZE 512
#define TEST_SD_CARD_BIGBUF_SIZE (256 * 1024)
#define TEST_SD_CARD_DEVICE_FILE "/dev/sd-card-a"
#define TEST_SD_CARD_PARTITION "/dev/sd-card-a1"
#define TEST_SD_CARD_MOUNT_POINT "/mnt"
#define TEST_SD_CARD_DIRECTORY "/mnt/testdir"
static fstab_t test_sd_card_fs_table [] = { {
TEST_SD_CARD_PARTITION, TEST_SD_CARD_MOUNT_POINT,
&msdos_ops, RTEMS_FILESYSTEM_READ_WRITE,
FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
FSMOUNT_MNT_OK
}, {
TEST_SD_CARD_DEVICE_FILE, TEST_SD_CARD_MOUNT_POINT,
&msdos_ops, RTEMS_FILESYSTEM_READ_WRITE,
FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
0
}
};
static uint8_t test_sd_card_buf [TEST_SD_CARD_BUF_SIZE] __attribute__ ((aligned (32)));
static int test_sd_card_print_dir( const char* dirname, unsigned level)
{
int rv = 0;
DIR *dir = NULL;
struct dirent *ent;
struct stat s;
int i = 0;
/* Open */
dir = opendir( dirname);
rv = dir == NULL ? -1 : 0;
CHECK_RV( rv, "Open directory");
/* Change CWD */
rv = chdir( dirname);
CHECK_RV( rv, "Change directory");
/* Read */
ent = readdir( dir);
while (ent != NULL) {
if (stat( ent->d_name, &s) == 0 && strcmp( ".", ent->d_name) != 0 && strcmp( "..", ent->d_name)) {
for (i = 0; i < level; ++i) {
printk( "\t");
}
printk( "<%s>\n", ent->d_name);
if (S_ISDIR( s.st_mode)) {
rv = test_sd_card_print_dir( ent->d_name, level + 1);
CHECK_RV( rv, "Next directory");
}
}
ent = readdir( dir);
}
/* Change CWD */
rv = chdir( "..");
CHECK_RV( rv, "Change directory");
/* Close */
rv = closedir( dir);
CHECK_RV( rv, "Close directory");
return 0;
}
#define SD_CARD_NUMBER 1
static sd_card_driver_entry sd_card_driver_table_XXX [SD_CARD_NUMBER] = { {
driver : {
ops : &sd_card_driver_ops,
size : sizeof( sd_card_driver_entry)
},
table_index : 0,
minor : 0,
device_name : "sd-card-a",
disk_device_name : "/dev/sd-card-a",
transfer_mode : SD_CARD_TRANSFER_MODE_DEFAULT,
command : SD_CARD_COMMAND_DEFAULT,
/* response : whatever, */
response_index : SD_CARD_COMMAND_SIZE,
n_ac_max : SD_CARD_N_AC_MAX_DEFAULT,
block_number : 0,
block_size : 0,
block_size_shift : 0,
busy : 1,
verbose : 1,
schedule_if_busy : 0,
}
};
rtems_task test_sd_card( rtems_task_argument arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
rtems_device_minor_number minor;
sd_card_driver_entry *e = &sd_card_driver_table [0];
int fd = 0;
unsigned i = 0;
unsigned avg = 0;
unsigned t = 0;
char file_name [] = "00000000.TXT";
uint8_t *buf = NULL;
DEBUG_PRINT( "Task started\n");
minor = rtems_libi2c_register_drv( e->device_name, (rtems_libi2c_drv_t *) e, test_mpc55xx_dspi_bus [0], 0);
CHECK_RV_TASK( (int) minor, "rtems_libi2c_register_drv");
buf = malloc( TEST_SD_CARD_BIGBUF_SIZE);
for (i = 0; i < TEST_SD_CARD_BIGBUF_SIZE; ++i) {
if (i % 27 == 26) {
buf [i] = '\n';
} else {
buf [i] = 'A' + i % 27;
}
}
buf [i - 1] = '\n';
rv = test_sd_card_print_dir( "/dev", 0);
CHECK_RV_TASK( rv, "Print directory");
sc = rtems_ide_part_table_initialize( TEST_SD_CARD_DEVICE_FILE);
CHECK_SC_TASK( sc, "Initialize IDE partition table");
rv = test_sd_card_print_dir( "/dev", 0);
CHECK_RV_TASK( rv, "Print directory");
rv = mkdir( TEST_SD_CARD_MOUNT_POINT, S_IRWXU);
CHECK_RV_TASK( rv, "Create mount point");
rv = rtems_fsmount( test_sd_card_fs_table, sizeof( test_sd_card_fs_table) / sizeof( test_sd_card_fs_table [0]), NULL);
CHECK_RV_TASK( rv, "Mount file systems");
//rv = test_sd_card_print_dir( TEST_SD_CARD_MOUNT_POINT, 0);
//CHECK_RV_TASK( rv, "Print directory");
rv = mkdir( TEST_SD_CARD_DIRECTORY, S_IRWXU);
rv = chdir( TEST_SD_CARD_DIRECTORY);
CHECK_RV_TASK( rv, "Change directory");
i = 0;
while (1) {
snprintf( file_name, 13, "%08i.TXT", i);
tic();
fd = creat( file_name, S_IREAD | S_IWRITE);
CHECK_RV_TASK( fd, "Create file");
rv = write( fd, buf, TEST_SD_CARD_BIGBUF_SIZE);
CHECK_RV_TASK( rv, "Write file");
rv = close( fd);
CHECK_RV_TASK( rv, "Close file");
t = tac();
avg = ((uint64_t) avg * ((uint64_t) i) + (uint64_t) t) / ((uint64_t) i + 1);
printk( "%s: %u (%u)\n", file_name, tac(), avg);
++i;
}
rv = chdir( "..");
CHECK_RV_TASK( rv, "Change directory");
rv = test_sd_card_print_dir( TEST_SD_CARD_DIRECTORY, 0);
CHECK_RV_TASK( rv, "Print directory");
// /* Write */
// int b = 0;
// const char device_name [] = "/dev/spi0.sd-card-0";
// fd = open( device_name, O_RDWR);
//
// CHECK_RV_TASK( fd, "open");
// while (1) {
// for (i = 0; i < TEST_SD_CARD_BUF_SIZE; ++i) {
// test_sd_card_buf [i] = b;
// }
// ++b;
// rv = write( fd, test_sd_card_buf, TEST_SD_CARD_BUF_SIZE);
// if (rv < 0) {
// break;
// }
// }
// rv = close( fd);
// CHECK_RV_TASK( rv, "close");
//
// /* Read */
// fd = open( device_name, O_RDWR);
// CHECK_RV_TASK( fd, "open");
// while (1) {
// rv = read( fd, test_sd_card_buf, TEST_SD_CARD_BUF_SIZE);
// if (rv < 0) {
// break;
// }
// printk( "%02x", test_sd_card_buf [rv - 1]);
// if (i++ % 64 == 0) {
// printk( "\n");
// }
// }
// rv = close( fd);
// CHECK_RV_TASK( rv, "close");
sc = rtems_task_delete( RTEMS_SELF);
CHECK_SC_TASK( sc, "rtems_task_delete");
}
#define ITER 4
#define BUFSIZE (128 * ITER)
static char inbuf [BUFSIZE];
static char outbuf [BUFSIZE];
static rtems_status_code test_mpc55xx_edma()
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
int channel = 0;
uint32_t error_status = 0;
rtems_id transfer_update;
sc = rtems_semaphore_create (
rtems_build_name ( 'T', 'S', 'T', 'C'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&transfer_update
);
CHECK_SC( sc, "rtems_semaphore_create");
rv = mpc55xx_edma_obtain_channel( channel, &error_status, transfer_update);
CHECK_RV( rv, "mpc55xx_edma_obtain_channel");
int i = 0;
for (i = 0; i < BUFSIZE; ++i) {
inbuf [i] = i;
outbuf [i] = -1;
}
rtems_cache_flush_multiple_data_lines( inbuf, BUFSIZE);
rtems_cache_flush_multiple_data_lines( outbuf, BUFSIZE);
struct tcd_t tcd = MPC55XX_EDMA_TCD_DEFAULT;
tcd.SADDR = (uint32_t) &inbuf;
tcd.DADDR = (uint32_t) &outbuf;
tcd.NBYTES = BUFSIZE / ITER;
tcd.SLAST = -BUFSIZE;
tcd.CITER = ITER;
tcd.BITER = ITER;
tcd.INT_HALF = 1;
EDMA.TCD [channel] = tcd;
while (1) {
while (1) {
if (EDMA.TCD [channel].DONE == 1) {
EDMA.TCD [channel].DONE = 0;
printk( "%s: Done\n", __func__);
break;
} else if (EDMA.TCD [channel].ACTIVE == 0) {
EDMA.SSBR.R = channel;
printk( "%s: Start: %i (%i)\n", __func__, EDMA.TCD [channel].CITER, EDMA.TCD [channel].BITER);
}
sc = rtems_semaphore_obtain( transfer_update, RTEMS_WAIT, 10);
if (sc == RTEMS_TIMEOUT) {
continue;
}
CHECK_SC( sc, "rtems_semaphore_obtain");
}
printk( "%s: Error status: 0x%08x\n", __func__, error_status);
}
return sc;
}
static unsigned test_mpc55xx_intc_counter = 0;
static inline void test_mpc55xx_intc_worker( void *data)
{
int s = 0;
int i = *(int *) data;
printk( "(%i): Start: %u\n", i, tac());
s = mpc55xx_intc_clear_software_irq( i);
if (i < MPC55XX_IRQ_SOFTWARE_NUMBER) {
tic();
s = mpc55xx_intc_raise_software_irq( i + 1);
}
++test_mpc55xx_intc_counter;
printk( "(%i): Done\n", i);
}
static void test_mpc55xx_intc_handler( rtems_vector_number vector, void *data)
{
test_mpc55xx_intc_worker( data);
}
static void test_mpc55xx_intc_handler_2( void *data)
{
test_mpc55xx_intc_worker( data);
}
static void test_mpc55xx_intc_handler_3( void *data)
{
test_mpc55xx_intc_worker( data);
}
static int test_mpc55xx_intc_handler_data [MPC55XX_IRQ_SOFTWARE_NUMBER];
static rtems_task test_mpc55xx_intc( rtems_task_argument arg)
{
volatile int i = 0;
int p = 0;
unsigned s = 0;
rtems_irq_connect_data e;
rtems_status_code sc = RTEMS_SUCCESSFUL;
for (i = MPC55XX_IRQ_SOFTWARE_MIN, p = MPC55XX_INTC_MIN_PRIORITY; i <= MPC55XX_IRQ_SOFTWARE_MAX; ++i, ++p) {
test_mpc55xx_intc_handler_data [i] = i;
e.name = i;
e.handle = &test_mpc55xx_intc_handler_data [i];
sc = rtems_interrupt_handler_install( i, "test_mpc55xx_intc_handler", RTEMS_INTERRUPT_SHARED, test_mpc55xx_intc_handler, e.handle);
if (sc != RTEMS_SUCCESSFUL) {
BSP_panic( "Handler install failed");
}
e.hdl = test_mpc55xx_intc_handler_2;
if (BSP_install_rtems_shared_irq_handler( &e) != RTEMS_SUCCESSFUL) {
BSP_panic( "Handler install 2 failed");
}
e.hdl = test_mpc55xx_intc_handler_3;
if (BSP_install_rtems_shared_irq_handler( &e) != RTEMS_SUCCESSFUL) {
BSP_panic( "Handler install 3 failed");
}
}
while (1) {
i = (int) (7.0 * (rand_r( &s) / (RAND_MAX + 1.0)));
tic();
mpc55xx_intc_raise_software_irq( i);
}
}

View File

@@ -1,3 +1,7 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* bootcard.c: Removed duplicated code.
2008-07-10 Sebastian Huber <sebastian.huber@embedded-brains.de>
* bootcard.c: Special case for PowerPC: The interrupt disable

View File

@@ -232,22 +232,6 @@ int boot_card(
*/
bsp_predriver_hook();
/*
* Let RTEMS perform initialization it requires before drivers
* are allowed to be initialized.
*/
rtems_initialize_before_drivers();
/*
* Execute BSP specific pre-driver hook. Drivers haven't gotten
* to initialize yet so this is a good chance to initialize
* buses, spurious interrupt handlers, etc..
*
* NOTE: Many BSPs do not require this handler and use the
* shared stub.
*/
bsp_predriver_hook();
/*
* Initialize all device drivers.
*/

View File

@@ -1,3 +1,29 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* configure.ac: Support for MPC55XX. Changed comment format to
Doxygen.
* mpc55xx/dspi/dspi.c, mpc55xx/edma/edma.c, mpc55xx/esci/esci.c,
mpc55xx/fec/fec.c, mpc55xx/include/dspi.h, mpc55xx/include/edma.h,
mpc55xx/include/esci.h, mpc55xx/include/irq.h,
mpc55xx/include/mpc55xx.h, mpc55xx/include/reg-defs.h,
mpc55xx/include/regs.h, mpc55xx/irq/irq.c, mpc55xx/misc/copy.S,
mpc55xx/misc/flash.S, mpc55xx/misc/fmpll.S: New BSP.
* mpc83xx/i2c/mpc83xx_i2cdrv.c,
mpc83xx/network/tsec.c, mpc83xx/spi/mpc83xx_spidrv.c,
mpc83xx/spi/mpc83xx_spidrv.h: Support for MPC8313ERDB.
* shared/include/powerpc-utility.h: Exchanged ASM and non ASM code
sections.
* rtems/powerpc/powerpc.h, shared/src/cache.c, shared/src/cache_.h:
New defines PPC_NO_CACHE_ALIGNMENT and PPC_NO_CACHE_ALIGNMENT_POWER for
CPUs with no cache. Provide default implementations for all cache
functions.
* mpc83xx/include/gtm.h, mpc83xx/gtm/gtm.c: New files.
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
* Makefile.am, new-exceptions/raw_exception.c,

View File

@@ -1,6 +1,15 @@
#
# $Id$
#
##
## $Id$
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Makefile of LibCPU for PowerPC.
#
ACLOCAL_AMFLAGS = -I ../../../aclocal
@@ -55,7 +64,7 @@ EXTRA_DIST += new-exceptions/bspsupport/README
EXTRA_DIST += new-exceptions/bspsupport/nest_irq_test.c
EXTRA_DIST += new-exceptions/bspsupport/ppc_exc_test.c
## shared/include
# shared/include
if shared
include_libcpu_HEADERS += shared/include/io.h shared/include/mmu.h shared/include/page.h \
shared/include/byteorder.h shared/include/pgtable.h
@@ -67,7 +76,7 @@ shared_cpuIdent_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
include_libcpu_HEADERS += shared/include/cpuIdent.h
## shared/cache
# shared/cache
noinst_PROGRAMS += shared/cache.rel
shared_cache_rel_SOURCES = shared/src/cache.c shared/src/cache_.h \
../shared/src/cache_aligned_malloc.c ../shared/src/cache_manager.c \
@@ -77,7 +86,7 @@ shared_cache_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
include_libcpu_HEADERS += ../shared/include/cache.h
## shared/stack
# shared/stack
noinst_PROGRAMS += shared/stack.rel
shared_stack_rel_SOURCES = shared/src/stack.c shared/include/spr.h shared/src/stackTrace.h
shared_stack_rel_CPPFLAGS = $(AM_CPPFLAGS)
@@ -89,13 +98,13 @@ endif
EXTRA_DIST += ppc403/README ppc403/vectors/README
if ppc403
## ppc403/clock
# ppc403/clock
noinst_PROGRAMS += ppc403/clock.rel
ppc403_clock_rel_SOURCES = ppc403/clock/clock.c
ppc403_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
ppc403_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## ppc403/console
# ppc403/console
noinst_PROGRAMS += ppc403/console.rel
if ppc405
ppc403_console_rel_SOURCES = ppc403/console/console405.c
@@ -110,13 +119,13 @@ shared_cpuIdent_rel_SOURCES = shared/include/cpuIdent.c
shared_cpuIdent_rel_CPPFLAGS = $(AM_CPPFLAGS)
shared_cpuIdent_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## ppc403/timer
# ppc403/timer
noinst_PROGRAMS += ppc403/timer.rel
ppc403_timer_rel_SOURCES = ppc403/timer/timer.c
ppc403_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
ppc403_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## ppc403/tty_drv
# ppc403/tty_drv
if ppc405
include_HEADERS += ppc403/tty_drv/tty_drv.h
@@ -145,13 +154,13 @@ include_mpc5xxdir = $(includedir)/mpc5xx
include_HEADERS = mpc5xx/include/mpc5xx.h
## mpc5xx/clock
# mpc5xx/clock
noinst_PROGRAMS += mpc5xx/clock.rel
mpc5xx_clock_rel_SOURCES = mpc5xx/clock/clock.c
mpc5xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc5xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc5xx/console-generic
# mpc5xx/console-generic
include_mpc5xx_HEADERS = mpc5xx/include/console.h
noinst_PROGRAMS += mpc5xx/console-generic.rel
@@ -159,7 +168,7 @@ mpc5xx_console_generic_rel_SOURCES = mpc5xx/console-generic/console-generic.c
mpc5xx_console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc5xx_console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc5xx/exceptions
# mpc5xx/exceptions
include_libcpu_HEADERS += mpc5xx/exceptions/raw_exception.h
noinst_PROGRAMS += mpc5xx/exceptions.rel
@@ -167,7 +176,7 @@ mpc5xx_exceptions_rel_SOURCES = mpc5xx/exceptions/raw_exception.c
mpc5xx_exceptions_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc5xx_exceptions_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc5xx/irq
# mpc5xx/irq
include_libcpu_HEADERS += mpc5xx/irq/irq.h
noinst_PROGRAMS += mpc5xx/irq.rel
@@ -175,13 +184,13 @@ mpc5xx_irq_rel_SOURCES = mpc5xx/irq/irq.c mpc5xx/irq/irq_init.c mpc5xx/irq/irq_a
mpc5xx_irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc5xx_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc5xx/timer
# mpc5xx/timer
noinst_PROGRAMS += mpc5xx/timer.rel
mpc5xx_timer_rel_SOURCES = mpc5xx/timer/timer.c
mpc5xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc5xx_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc5xx/vectors
# mpc5xx/vectors
include_libcpu_HEADERS += mpc5xx/vectors/vectors.h
noinst_PROGRAMS += mpc5xx/vectors.rel
@@ -191,7 +200,7 @@ mpc5xx_vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
if mpc505
## mpc505/ictrl
# mpc505/ictrl
include_HEADERS = mpc505/ictrl/ictrl.h
noinst_PROGRAMS += mpc505/ictrl.rel
@@ -199,13 +208,13 @@ mpc505_ictrl_rel_SOURCES = mpc505/ictrl/ictrl.c
mpc505_ictrl_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc505_ictrl_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc505/timer
# mpc505/timer
noinst_PROGRAMS += mpc505/timer.rel
mpc505_timer_rel_SOURCES = mpc505/timer/timer.c
mpc505_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc505_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc505/vector
# mpc505/vector
noinst_PROGRAMS += mpc505/vectors.rel
mpc505_vectors_rel_SOURCES = mpc505/vectors/vectors.S
mpc505_vectors_rel_CPPFLAGS = $(AM_CPPFLAGS)
@@ -214,7 +223,7 @@ endif
if mpc6xx
## mpc6xx/mmu
# mpc6xx/mmu
include_libcpu_HEADERS += mpc6xx/mmu/bat.h mpc6xx/mmu/pte121.h
noinst_PROGRAMS += mpc6xx/mmu.rel
@@ -224,7 +233,7 @@ mpc6xx_mmu_rel_SOURCES = mpc6xx/mmu/bat.c mpc6xx/mmu/bat.h \
mpc6xx_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc6xx_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc6xx/clock
# mpc6xx/clock
include_libcpu_HEADERS += mpc6xx/clock/c_clock.h
noinst_PROGRAMS += mpc6xx/clock.rel
@@ -232,7 +241,7 @@ mpc6xx_clock_rel_SOURCES = mpc6xx/clock/c_clock.c mpc6xx/clock/c_clock.h
mpc6xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc6xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc6xx/timer
# mpc6xx/timer
noinst_PROGRAMS += mpc6xx/timer.rel
mpc6xx_timer_rel_SOURCES = mpc6xx/timer/timer.c
mpc6xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
@@ -240,7 +249,7 @@ mpc6xx_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
if e500
## mpc6xx/clock
# mpc6xx/clock
include_libcpu_HEADERS += mpc6xx/clock/c_clock.h
noinst_PROGRAMS += e500/clock.rel
@@ -248,13 +257,13 @@ e500_clock_rel_SOURCES = mpc6xx/clock/c_clock.c mpc6xx/clock/c_clock.h
e500_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
e500_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc6xx/timer
# mpc6xx/timer
noinst_PROGRAMS += e500/timer.rel
e500_timer_rel_SOURCES = mpc6xx/timer/timer.c
e500_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
e500_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## e500/mmu
# e500/mmu
include_libcpu_HEADERS += e500/mmu/e500_mmu.h
noinst_PROGRAMS += e500/mmu.rel
e500_mmu_rel_SOURCES = e500/mmu/mmu.c e500/mmu/e500_mmu.h
@@ -268,13 +277,13 @@ include_mpc8xxdir = $(includedir)/mpc8xx
include_HEADERS = mpc8xx/include/mpc8xx.h
## mpc8xx/clock
# mpc8xx/clock
noinst_PROGRAMS += mpc8xx/clock.rel
mpc8xx_clock_rel_SOURCES = mpc8xx/clock/clock.c
mpc8xx_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8xx_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8xx/console-generic
# mpc8xx/console-generic
include_mpc8xx_HEADERS = mpc8xx/include/console.h
noinst_PROGRAMS += mpc8xx/console-generic.rel
@@ -282,7 +291,7 @@ mpc8xx_console_generic_rel_SOURCES = mpc8xx/console-generic/console-generic.c
mpc8xx_console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8xx_console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8xx/cpm
# mpc8xx/cpm
include_mpc8xx_HEADERS += mpc8xx/include/cpm.h
noinst_PROGRAMS += mpc8xx/cpm.rel
@@ -290,7 +299,7 @@ mpc8xx_cpm_rel_SOURCES = mpc8xx/cpm/cp.c mpc8xx/cpm/dpram.c
mpc8xx_cpm_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8xx_cpm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8xx/mmu
# mpc8xx/mmu
include_mpc8xx_HEADERS += mpc8xx/include/mmu.h
noinst_PROGRAMS += mpc8xx/mmu.rel
@@ -298,7 +307,7 @@ mpc8xx_mmu_rel_SOURCES = mpc8xx/mmu/mmu.c
mpc8xx_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8xx_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8xx/timer
# mpc8xx/timer
noinst_PROGRAMS += mpc8xx/timer.rel
mpc8xx_timer_rel_SOURCES = mpc8xx/timer/timer.c
mpc8xx_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
@@ -311,7 +320,7 @@ include_mpc8260dir = $(includedir)/mpc8260
include_HEADERS = mpc8260/include/mpc8260.h
## mpc8260/console-generic
# mpc8260/console-generic
include_mpc8260_HEADERS = mpc8260/include/console.h
noinst_PROGRAMS += mpc8260/console-generic.rel
@@ -320,13 +329,13 @@ mpc8260_console_generic_rel_SOURCES = mpc8260/console-generic/console-generic.c
mpc8260_console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8260_console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8260/clock
# mpc8260/clock
noinst_PROGRAMS += mpc8260/clock.rel
mpc8260_clock_rel_SOURCES = mpc8260/clock/clock.c
mpc8260_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8260_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8260/cpm
# mpc8260/cpm
include_mpc8260_HEADERS += mpc8260/include/cpm.h
noinst_PROGRAMS += mpc8260/cpm.rel
@@ -335,7 +344,7 @@ mpc8260_cpm_rel_SOURCES = mpc8260/cpm/cp.c mpc8260/cpm/dpram.c mpc8260/cpm/brg.c
mpc8260_cpm_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8260_cpm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8260/mmu
# mpc8260/mmu
include_mpc8260_HEADERS += mpc8260/include/mmu.h
noinst_PROGRAMS += mpc8260/mmu.rel
@@ -344,44 +353,121 @@ mpc8260_mmu_rel_SOURCES = mpc8260/mmu/mmu.c \
mpc8260_mmu_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8260_mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc8260/timer
# mpc8260/timer
noinst_PROGRAMS += mpc8260/timer.rel
mpc8260_timer_rel_SOURCES = mpc8260/timer/timer.c
mpc8260_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc8260_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
##############################################################################
# START: MPC83XX #
##############################################################################
if mpc83xx
include_mpc83xxdir = $(includedir)/mpc83xx
include_mpc83xx_HEADERS = mpc83xx/include/mpc83xx.h
include_mpc83xx_HEADERS += mpc83xx/network/tsec.h
# Includes
include_bspdir = $(includedir)/bsp
## mpc83xx/network
include_bsp_HEADERS = new-exceptions/bspsupport/vectors.h \
new-exceptions/bspsupport/ppc_exc_bspsupp.h
include_mpc83xxdir = $(includedir)/mpc83xx
include_mpc83xx_HEADERS = mpc83xx/include/mpc83xx.h
# Network
include_mpc83xx_HEADERS += mpc83xx/network/tsec.h
if HAS_NETWORKING
noinst_PROGRAMS += mpc83xx/tsec.rel
mpc83xx_tsec_rel_SOURCES = mpc83xx/network/tsec.c
mpc83xx_tsec_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc83xx_tsec_rel_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ -D__BSD_VISIBLE
mpc83xx_tsec_rel_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ -D__BSD_VISIBLE
mpc83xx_tsec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
## mpc83xx/i2c
# i2c
include_mpc83xx_HEADERS += mpc83xx/i2c/mpc83xx_i2cdrv.h
noinst_PROGRAMS += mpc83xx/i2c.rel
mpc83xx_i2c_rel_SOURCES = mpc83xx/i2c/mpc83xx_i2cdrv.c \
mpc83xx/i2c/mpc83xx_i2cdrv.h
mpc83xx_i2c_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc83xx_i2c_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
## mpc83xx/spi
# SPI
include_mpc83xx_HEADERS += mpc83xx/spi/mpc83xx_spidrv.h
noinst_PROGRAMS += mpc83xx/spi.rel
mpc83xx_spi_rel_SOURCES = mpc83xx/spi/mpc83xx_spidrv.c \
mpc83xx/spi/mpc83xx_spidrv.h
mpc83xx_spi_rel_CPPFLAGS = $(AM_CPPFLAGS)
mpc83xx_spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# GTM
include_mpc83xx_HEADERS += mpc83xx/include/gtm.h
noinst_PROGRAMS += mpc83xx/gtm.rel
mpc83xx_gtm_rel_SOURCES = mpc83xx/gtm/gtm.c \
mpc83xx/include/gtm.h
mpc83xx_gtm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
##############################################################################
# END: MPC83XX #
##############################################################################
##############################################################################
# START: MPC55XX #
##############################################################################
if mpc55xx
# Includes
include_bspdir = $(includedir)/bsp
include_bsp_HEADERS = new-exceptions/bspsupport/vectors.h \
new-exceptions/bspsupport/ppc_exc_bspsupp.h \
mpc55xx/include/irq.h
include_mpc55xxdir = $(includedir)/mpc55xx
include_mpc55xx_HEADERS = mpc55xx/include/regs.h \
mpc55xx/include/reg-defs.h \
mpc55xx/include/dspi.h \
mpc55xx/include/edma.h \
mpc55xx/include/mpc55xx.h \
mpc55xx/include/esci.h
# IRQ
noinst_PROGRAMS += mpc55xx/irq.rel
mpc55xx_irq_rel_SOURCES = mpc55xx/irq/irq.c
mpc55xx_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# FEC
noinst_PROGRAMS += mpc55xx/fec.rel
mpc55xx_fec_rel_SOURCES = mpc55xx/fec/fec.c
mpc55xx_fec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# EMDA
noinst_PROGRAMS += mpc55xx/edma.rel
mpc55xx_edma_rel_SOURCES = mpc55xx/edma/edma.c
mpc55xx_edma_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# ESCI
noinst_PROGRAMS += mpc55xx/esci.rel
mpc55xx_esci_rel_SOURCES = mpc55xx/esci/esci.c
mpc55xx_esci_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# DSPI
noinst_PROGRAMS += mpc55xx/dspi.rel
mpc55xx_dspi_rel_SOURCES = mpc55xx/dspi/dspi.c
mpc55xx_dspi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# Misc
noinst_PROGRAMS += mpc55xx/misc.rel
mpc55xx_misc_rel_SOURCES = mpc55xx/misc/copy.S \
mpc55xx/misc/fmpll.S \
mpc55xx/misc/flash.S
mpc55xx_misc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
##############################################################################
# END: MPC55XX #
##############################################################################
include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../automake/local.am

View File

@@ -1,6 +1,15 @@
## Process this file with autoconf to produce a configure script.
# Process this file with autoconf to produce a configure script.
#
# $Id$
##
## $Id$
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Configure script of LibCPU for PowerPC.
#
AC_PREREQ(2.60)
AC_INIT([rtems-c-src-lib-libcpu-powerpc],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
@@ -27,6 +36,7 @@ AM_CONDITIONAL(shared, \
|| test "$RTEMS_CPU_MODEL" = "mpc7455" \
|| test "$RTEMS_CPU_MODEL" = "mpc7457" \
|| test "$RTEMS_CPU_MODEL" = "mpc555" \
|| test "$RTEMS_CPU_MODEL" = "mpc55xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc5xx" \
|| test "$RTEMS_CPU_MODEL" = "ppc603e" \
|| test "$RTEMS_CPU_MODEL" = "ppc403" \
@@ -42,8 +52,9 @@ AM_CONDITIONAL(shared, \
|| test "$RTEMS_CPU_MODEL" = "mpc83xx" \
|| test "$RTEMS_CPU_MODEL" = "e500")
## test on CPU type
# test on CPU type
AM_CONDITIONAL(mpc505, test "$RTEMS_CPU_MODEL" = "mpc505")
AM_CONDITIONAL(mpc55xx, test "$RTEMS_CPU_MODEL" = "mpc55xx")
AM_CONDITIONAL(mpc5xx, test "$RTEMS_CPU_MODEL" = "mpc5xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc555" )
AM_CONDITIONAL(mpc6xx, test "$RTEMS_CPU_MODEL" = "mpc6xx" \

View File

@@ -0,0 +1,746 @@
/**
* @file
*
* @ingroup mpc55xx_dspi
*
* @brief Source file for the LibI2C bus driver for the Deserial Serial Peripheral Interface (DSPI).
*/
/*
* 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.
*/
#include <mpc55xx/regs.h>
#include <mpc55xx/dspi.h>
#include <mpc55xx/edma.h>
#include <mpc55xx/mpc55xx.h>
#include <libcpu/powerpc-utility.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
#define MPC55XX_DSPI_FIFO_SIZE 4
#define MPC55XX_DSPI_CTAR_NUMBER 8
#define MPC55XX_DSPI_CTAR_DEFAULT 0
#define MPC55XX_DSPI_EDMA_MAGIC_SIZE 128
#define MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE 63
typedef struct {
uint32_t scaler : 26;
uint32_t pbr : 2;
uint32_t br : 4;
} mpc55xx_dspi_baudrate_scaler_entry;
static const mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_baudrate_scaler_table [MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE] = {
{ 4, 0, 0 },
{ 6, 1, 0 },
{ 8, 0, 1 },
{ 10, 2, 0 },
{ 12, 1, 1 },
{ 14, 3, 0 },
{ 16, 0, 3 },
{ 18, 1, 2 },
{ 20, 2, 1 },
{ 24, 1, 3 },
{ 28, 3, 1 },
{ 30, 2, 2 },
{ 32, 0, 4 },
{ 40, 2, 3 },
{ 42, 3, 2 },
{ 48, 1, 4 },
{ 56, 3, 3 },
{ 64, 0, 5 },
{ 80, 2, 4 },
{ 96, 1, 5 },
{ 112, 3, 4 },
{ 128, 0, 6 },
{ 160, 2, 5 },
{ 192, 1, 6 },
{ 224, 3, 5 },
{ 256, 0, 7 },
{ 320, 2, 6 },
{ 384, 1, 7 },
{ 448, 3, 6 },
{ 512, 0, 8 },
{ 640, 2, 7 },
{ 768, 1, 8 },
{ 896, 3, 7 },
{ 1024, 0, 9 },
{ 1280, 2, 8 },
{ 1536, 1, 9 },
{ 1792, 3, 8 },
{ 2048, 0, 10 },
{ 2560, 2, 9 },
{ 3072, 1, 10 },
{ 3584, 3, 9 },
{ 4096, 0, 11 },
{ 5120, 2, 10 },
{ 6144, 1, 11 },
{ 7168, 3, 10 },
{ 8192, 0, 12 },
{ 10240, 2, 11 },
{ 12288, 1, 12 },
{ 14336, 3, 11 },
{ 16384, 0, 13 },
{ 20480, 2, 12 },
{ 24576, 1, 13 },
{ 28672, 3, 12 },
{ 32768, 0, 14 },
{ 40960, 2, 13 },
{ 49152, 1, 14 },
{ 57344, 3, 13 },
{ 65536, 0, 15 },
{ 81920, 2, 14 },
{ 98304, 1, 15 },
{ 114688, 3, 14 },
{ 163840, 2, 15 },
{ 229376, 3, 15 },
};
static mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_search_baudrate_scaler( uint32_t scaler, int min, int mid, int max)
{
if (scaler <= mpc55xx_dspi_baudrate_scaler_table [mid].scaler) {
max = mid;
} else {
min = mid;
}
mid = (min + max) / 2;
if (mid == min) {
return mpc55xx_dspi_baudrate_scaler_table [max];
} else {
return mpc55xx_dspi_search_baudrate_scaler( scaler, min, mid, max);
}
}
static uint32_t mpc55xx_dspi_push_data [8 * MPC55XX_DSPI_NUMBER] __attribute__ ((aligned (32)));
static inline void mpc55xx_dspi_store_push_data( mpc55xx_dspi_bus_entry *e)
{
mpc55xx_dspi_push_data [e->table_index * 8] = e->push_data.R;
rtems_cache_flush_multiple_data_lines( &mpc55xx_dspi_push_data [e->table_index * 8], 4);
}
static inline uint32_t mpc55xx_dspi_push_data_address( mpc55xx_dspi_bus_entry *e)
{
return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8];
}
static inline uint32_t mpc55xx_dspi_nirvana_address( mpc55xx_dspi_bus_entry *e)
{
return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8 + 1];
}
static rtems_status_code mpc55xx_dspi_init( rtems_libi2c_bus_t *bus)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
union DSPI_MCR_tag mcr = MPC55XX_ZERO_FLAGS;
union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
union DSPI_RSER_tag rser = MPC55XX_ZERO_FLAGS;
struct tcd_t tcd_push = MPC55XX_EDMA_TCD_DEFAULT;
int i = 0;
/* eDMA receive */
sc = rtems_semaphore_create (
rtems_build_name ( 'S', 'P', 'I', 'R'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&e->edma_channel_receive_update
);
CHECK_SC( sc, "Create receive update semaphore");
sc = mpc55xx_edma_obtain_channel( e->edma_channel_receive, &e->edma_channel_receive_error, e->edma_channel_receive_update);
CHECK_SC( sc, "Obtain receive eDMA channel");
/* eDMA transmit */
sc = rtems_semaphore_create (
rtems_build_name ( 'S', 'P', 'I', 'T'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&e->edma_channel_transmit_update
);
CHECK_SC( sc, "Create transmit update semaphore");
sc = mpc55xx_edma_obtain_channel( e->edma_channel_transmit, &e->edma_channel_transmit_error, e->edma_channel_transmit_update);
CHECK_SC( sc, "Obtain transmit eDMA channel");
sc = mpc55xx_edma_obtain_channel( e->edma_channel_push, NULL, RTEMS_ID_NONE);
CHECK_SC( sc, "Obtain push eDMA channel");
tcd_push.SADDR = mpc55xx_dspi_push_data_address( e);
tcd_push.SSIZE = 2;
tcd_push.SOFF = 0;
tcd_push.DADDR = (uint32_t) &e->regs->PUSHR.R;
tcd_push.DSIZE = 2;
tcd_push.DOFF = 0;
tcd_push.NBYTES = 4;
tcd_push.CITER = 1;
tcd_push.BITER = 1;
EDMA.TCD [e->edma_channel_push] = tcd_push;
/* Module Control Register */
mcr.B.MSTR = e->master ? 1 : 0;
mcr.B.CONT_SCKE = 0;
mcr.B.DCONF = 0;
mcr.B.FRZ = 0;
mcr.B.MTFE = 0;
mcr.B.PCSSE = 0;
mcr.B.ROOE = 0;
mcr.B.PCSIS0 = 1;
mcr.B.PCSIS1 = 1;
mcr.B.PCSIS2 = 1;
mcr.B.PCSIS3 = 1;
mcr.B.PCSIS5 = 1;
mcr.B.MDIS = 0;
mcr.B.DIS_TXF = 0;
mcr.B.DIS_RXF = 0;
mcr.B.CLR_TXF = 0;
mcr.B.CLR_RXF = 0;
mcr.B.SMPL_PT = 0;
mcr.B.HALT = 0;
e->regs->MCR.R = mcr.R;
/* Clock and Transfer Attributes Register */
ctar.B.DBR = 0;
ctar.B.FMSZ = 0x7;
ctar.B.CPOL = 0;
ctar.B.CPHA = 0;
ctar.B.LSBFE = 0;
ctar.B.PCSSCK = 0;
ctar.B.PASC = 0;
ctar.B.PDT = 0;
ctar.B.PBR = 0;
ctar.B.CSSCK = 0;
ctar.B.ASC = 0;
ctar.B.DT = 0;
ctar.B.BR = 0;
for (i = 0; i < MPC55XX_DSPI_CTAR_NUMBER; ++i) {
e->regs->CTAR [i].R = ctar.R;
}
/* DMA/Interrupt Request Select and Enable Register */
rser.B.TFFFRE = 1;
rser.B.TFFFDIRS = 1;
rser.B.RFDFRE = 1;
rser.B.RFDFDIRS = 1;
e->regs->RSER.R = rser.R;
return RTEMS_SUCCESSFUL;
}
static rtems_status_code mpc55xx_dspi_send_start( rtems_libi2c_bus_t *bus)
{
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
/* Reset chip selects */
e->push_data.B.PCS0 = 0;
e->push_data.B.PCS1 = 0;
e->push_data.B.PCS2 = 0;
e->push_data.B.PCS3 = 0;
e->push_data.B.PCS4 = 0;
e->push_data.B.PCS5 = 0;
mpc55xx_dspi_store_push_data( e);
return RTEMS_SUCCESSFUL;
}
static rtems_status_code mpc55xx_dspi_send_stop( rtems_libi2c_bus_t *bus)
{
return RTEMS_SUCCESSFUL;
}
static rtems_status_code mpc55xx_dspi_send_addr( rtems_libi2c_bus_t *bus, uint32_t addr, int rw)
{
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
union DSPI_SR_tag sr = MPC55XX_ZERO_FLAGS;
/* Flush transmit and receive FIFO */
e->regs->MCR.B.CLR_TXF = 1;
e->regs->MCR.B.CLR_RXF = 1;
/* Clear status flags */
sr.B.EOQF = 1;
sr.B.TFFF = 1;
sr.B.RFDF = 1;
e->regs->SR.R = sr.R;
/* Frame command */
e->push_data.R = 0;
e->push_data.B.CONT = 0;
e->push_data.B.CTAS = MPC55XX_DSPI_CTAR_DEFAULT;
e->push_data.B.EOQ = 0;
e->push_data.B.CTCNT = 0;
switch (addr) {
case 0:
e->push_data.B.PCS0 = 1;
break;
case 1:
e->push_data.B.PCS1 = 1;
break;
case 2:
e->push_data.B.PCS2 = 1;
break;
case 3:
e->push_data.B.PCS3 = 1;
break;
case 4:
e->push_data.B.PCS4 = 1;
break;
case 5:
e->push_data.B.PCS5 = 1;
break;
default:
return -RTEMS_INVALID_ADDRESS;
}
mpc55xx_dspi_store_push_data( e);
return RTEMS_SUCCESSFUL;
}
static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_libi2c_tfr_mode_t *mode)
{
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
// FIXME, TODO
extern uint32_t bsp_clock_speed;
uint32_t scaler = bsp_clock_speed / mode->baudrate;
mpc55xx_dspi_baudrate_scaler_entry bse = mpc55xx_dspi_search_baudrate_scaler( scaler, 0, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE / 2, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE);
if (mode->bits_per_char != 8) {
return -RTEMS_INVALID_NUMBER;
}
e->idle_char = mode->idle_char;
ctar.R = e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R;
ctar.B.PBR = bse.pbr;
ctar.B.BR = bse.br;
// ctar.B.PCSSCK = bse.pbr;
// ctar.B.CSSCK = bse.br;
// ctar.B.PASC = bse.pbr;
// ctar.B.ASC = bse.br;
ctar.B.PCSSCK = 0;
ctar.B.CSSCK = 0;
ctar.B.PASC = 0;
ctar.B.ASC = 0;
ctar.B.LSBFE = mode->lsb_first ? 1 : 0;
ctar.B.CPOL = mode->clock_inv ? 1 : 0;
ctar.B.CPHA = mode->clock_phs ? 1 : 0;
e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R = ctar.R;
return 0;
}
/**
* @brief Writes @a n characters from @a out to bus @a bus and synchronously stores the received data in @a in.
*
* eDMA channel usage for transmission:
* @dot
* digraph push {
* push [label="Push Register"];
* push_data [label="Push Data"];
* idle_push_data [label="Idle Push Data"];
* out [shape=box,label="Output Buffer"];
* edge [color=red,fontcolor=red];
* push -> idle_push_data [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_transmit"];
* push -> out [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_transmit"];
* out -> push_data [label="Channel Link",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_push"];
* edge [color=blue,fontcolor=blue];
* out -> push_data [label="Data"];
* push_data -> push [label="Data"];
* idle_push_data -> push [label="Data"];
* }
* @enddot
*
* eDMA channel usage for receiving:
* @dot
* digraph pop {
* pop [label="Pop Register"];
* nirvana [label="Nirvana"];
* in [shape=box,label="Input Buffer"];
* edge [color=red,fontcolor=red];
* pop -> nirvana [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_receive"];
* pop -> in [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_channel_receive"];
* edge [color=blue,fontcolor=blue];
* pop -> nirvana [label="Data"];
* pop -> in [label="Data"];
* }
* @enddot
*/
static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in, const unsigned char *out, int n)
{
mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
/* Non cache aligned characters */
int n_nc = n;
/* Cache aligned characters */
int n_c = 0;
/* Register addresses */
volatile void *push = &e->regs->PUSHR.R;
volatile void *pop = &e->regs->POPR.R;
volatile union DSPI_SR_tag *status = &e->regs->SR;
/* Push and pop data */
union DSPI_PUSHR_tag push_data = e->push_data;
union DSPI_POPR_tag pop_data;
/* Status register */
union DSPI_SR_tag sr;
/* Read and write indices */
int r = 0;
int w = 0;
if (n == 0) {
return 0;
} else if (in == NULL && out == NULL) {
return -RTEMS_INVALID_ADDRESS;
}
if (n > MPC55XX_DSPI_EDMA_MAGIC_SIZE) {
n_nc = mpc55xx_non_cache_aligned_size( in);
n_c = mpc55xx_cache_aligned_size( in, n);
if (n_c > EDMA_TCD_BITER_LINKED_SIZE) {
SYSLOG_WARNING( "Buffer size out of range, cannot use eDMA\n");
n_nc = n;
n_c = 0;
} else if (n_nc + n_c != n) {
SYSLOG_WARNING( "Input buffer not proper cache aligned, cannot use eDMA\n");
n_nc = n;
n_c = 0;
}
}
#ifdef DEBUG
if (e->regs->SR.B.TXCTR != e->regs->SR.B.RXCTR) {
SYSLOG_WARNING( "FIFO counter not equal\n");
}
#endif /* DEBUG */
/* Direct IO */
if (out == NULL) {
push_data.B.TXDATA = e->idle_char;
while (r < n_nc || w < n_nc) {
/* Wait for available FIFO */
do {
sr.R = status->R;
} while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
/* Write */
if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
++w;
ppc_write_word( push_data.R, push);
}
/* Read */
if (r < n_nc && sr.B.RXCTR != 0) {
pop_data.R = ppc_read_word( pop);
in [r] = pop_data.B.RXDATA;
// printk( "[%03u]: 0x%02x -> 0x%02x\n", r, out [r], in [r]);
++r;
}
}
} else if (in == NULL) {
while (r < n_nc || w < n_nc) {
/* Wait for available FIFO */
do {
sr.R = status->R;
} while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
/* Write */
if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
push_data.B.TXDATA = out [w];
++w;
ppc_write_word( push_data.R, push);
}
/* Read */
if (r < n_nc && sr.B.RXCTR != 0) {
pop_data.R = ppc_read_word( pop);
// printk( "[%03u]: 0x%02x -> 0x%02x\n", r, out [r], in [r]);
++r;
}
}
} else {
while (r < n_nc || w < n_nc) {
/* Wait for available FIFO */
do {
sr.R = status->R;
} while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
/* Write */
if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
push_data.B.TXDATA = out [w];
++w;
ppc_write_word( push_data.R, push);
}
/* Read */
if (r < n_nc && sr.B.RXCTR != 0) {
pop_data.R = ppc_read_word( pop);
in [r] = pop_data.B.RXDATA;
// printk( "[%03u]: 0x%02x -> 0x%02x\n", r, out [r], in [r]);
++r;
}
}
}
/* eDMA transfers */
if (n_c > 0) {
rtems_status_code sc = RTEMS_SUCCESSFUL;
unsigned char *in_c = in + n_nc;
const unsigned char *out_c = out + n_nc;
struct tcd_t tcd_transmit = MPC55XX_EDMA_TCD_DEFAULT;
struct tcd_t tcd_receive = MPC55XX_EDMA_TCD_DEFAULT;
/* Cache operations */
rtems_cache_flush_multiple_data_lines( out_c, n_c);
rtems_cache_invalidate_multiple_data_lines( in_c, n_c);
/* Set transmit TCD */
if (out == NULL) {
e->push_data.B.TXDATA = e->idle_char;
mpc55xx_dspi_store_push_data( e);
tcd_transmit.SADDR = mpc55xx_dspi_push_data_address( e);
tcd_transmit.SSIZE = 2;
tcd_transmit.SOFF = 0;
tcd_transmit.DADDR = (uint32_t) push;
tcd_transmit.DSIZE = 2;
tcd_transmit.DOFF = 0;
tcd_transmit.NBYTES = 4;
tcd_transmit.CITER = n_c;
tcd_transmit.BITER = n_c;
} else {
EDMA.CDSBR.R = e->edma_channel_transmit;
tcd_transmit.SADDR = (uint32_t) out_c;
tcd_transmit.SSIZE = 0;
tcd_transmit.SOFF = 1;
tcd_transmit.DADDR = mpc55xx_dspi_push_data_address( e) + 3;
tcd_transmit.DSIZE = 0;
tcd_transmit.DOFF = 0;
tcd_transmit.NBYTES = 1;
tcd_transmit.CITERE_LINK = 1;
tcd_transmit.BITERE_LINK = 1;
tcd_transmit.MAJORLINKCH = e->edma_channel_push;
tcd_transmit.CITER = EDMA_TCD_LINK_AND_BITER( e->edma_channel_push, n_c);
tcd_transmit.BITER = EDMA_TCD_LINK_AND_BITER( e->edma_channel_push, n_c);
tcd_transmit.MAJORE_LINK = 1;
}
tcd_transmit.D_REQ = 1;
tcd_transmit.INT_MAJ = 1;
EDMA.TCD [e->edma_channel_transmit] = tcd_transmit;
/* Set receive TCD */
if (in == NULL) {
tcd_receive.DOFF = 0;
tcd_receive.DADDR = mpc55xx_dspi_nirvana_address( e);
} else {
tcd_receive.DOFF = 1;
tcd_receive.DADDR = (uint32_t) in_c;
}
tcd_receive.SADDR = (uint32_t) pop + 3;
tcd_receive.SSIZE = 0;
tcd_receive.SOFF = 0;
tcd_receive.DSIZE = 0;
tcd_receive.NBYTES = 1;
tcd_receive.D_REQ = 1;
tcd_receive.INT_MAJ = 1;
tcd_receive.CITER = n_c;
tcd_receive.BITER = n_c;
EDMA.TCD [e->edma_channel_receive] = tcd_receive;
/* Clear request flags */
sr.R = 0;
sr.B.TFFF = 1;
sr.B.RFDF = 1;
status->R = sr.R;
/* Enable hardware requests */
sc = mpc55xx_edma_enable_hardware_requests( e->edma_channel_receive, true);
CHECK_SCRV( sc, "Enable receive hardware requests");
sc = mpc55xx_edma_enable_hardware_requests( e->edma_channel_transmit, true);
CHECK_SCRV( sc, "Enable transmit hardware requests");
/* Wait for transmit update */
sc = rtems_semaphore_obtain( e->edma_channel_transmit_update, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
CHECK_SCRV( sc, "Transmit update");
if (e->edma_channel_transmit_error != 0) {
SYSLOG_ERROR( "Transmit error status: 0x%08x\n", e->edma_channel_transmit_error);
e->edma_channel_transmit_error = 0;
return -RTEMS_IO_ERROR;
}
/* Wait for receive update */
sc = rtems_semaphore_obtain( e->edma_channel_receive_update, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
CHECK_SCRV( sc, "Receive update");
if (e->edma_channel_receive_error != 0) {
SYSLOG_ERROR( "Receive error status: 0x%08x\n", e->edma_channel_receive_error);
e->edma_channel_receive_error = 0;
return -RTEMS_IO_ERROR;
}
}
return n;
}
/**
* @brief Reads @a n characters from bus @a bus and stores it in @a in.
*
* Writes idle characters to receive data.
*
* @see mpc55xx_dspi_read_write().
*/
static int mpc55xx_dspi_read( rtems_libi2c_bus_t *bus, unsigned char *in, int n)
{
return mpc55xx_dspi_read_write( bus, in, NULL, n);
}
/**
* @brief Writes @a n characters from @a out to bus @a bus.
*
* Discards the synchronously received data.
*
* @see mpc55xx_dspi_read_write().
*/
static int mpc55xx_dspi_write( rtems_libi2c_bus_t *bus, unsigned char *out, int n)
{
return mpc55xx_dspi_read_write( bus, NULL, out, n);
}
static int mpc55xx_dspi_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg)
{
int rv = -1;
switch (cmd) {
case RTEMS_LIBI2C_IOCTL_SET_TFRMODE:
rv = mpc55xx_dspi_set_transfer_mode( bus, (const rtems_libi2c_tfr_mode_t *) arg);
break;
case RTEMS_LIBI2C_IOCTL_READ_WRITE:
rv = mpc55xx_dspi_read_write(
bus,
((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:
rv = -RTEMS_NOT_DEFINED;
break;
}
return rv;
}
static const rtems_libi2c_bus_ops_t mpc55xx_dspi_ops = {
.init = mpc55xx_dspi_init,
.send_start = mpc55xx_dspi_send_start,
.send_stop = mpc55xx_dspi_send_stop,
.send_addr = mpc55xx_dspi_send_addr,
.read_bytes = mpc55xx_dspi_read,
.write_bytes = mpc55xx_dspi_write,
.ioctl = mpc55xx_dspi_ioctl
};
mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { {
/* DSPI A */
.bus = {
.ops = &mpc55xx_dspi_ops,
.size = sizeof( mpc55xx_dspi_bus_entry)
},
.table_index = 0,
.bus_number = 0,
.regs = &DSPI_A,
.master = 1,
.push_data = MPC55XX_ZERO_FLAGS,
.edma_channel_transmit = 32,
.edma_channel_push = 43,
.edma_channel_receive = 33,
.edma_channel_transmit_update = 0,
.edma_channel_receive_update = 0,
.edma_channel_transmit_error = 0,
.edma_channel_receive_error = 0,
.idle_char = 0xffffffff,
}, {
/* DSPI B */
.bus = {
.ops = &mpc55xx_dspi_ops,
.size = sizeof( mpc55xx_dspi_bus_entry)
},
.table_index = 1,
.bus_number = 0,
.regs = &DSPI_B,
.master = 1,
.push_data = MPC55XX_ZERO_FLAGS,
.edma_channel_transmit = 12,
.edma_channel_push = 10,
.edma_channel_receive = 13,
.edma_channel_transmit_update = 0,
.edma_channel_receive_update = 0,
.edma_channel_transmit_error = 0,
.edma_channel_receive_error = 0,
.idle_char = 0xffffffff,
}, {
/* DSPI C */
.bus = {
.ops = &mpc55xx_dspi_ops,
.size = sizeof( mpc55xx_dspi_bus_entry)
},
.table_index = 2,
.bus_number = 0,
.regs = &DSPI_C,
.master = 1,
.push_data = MPC55XX_ZERO_FLAGS,
.edma_channel_transmit = 14,
.edma_channel_push = 11,
.edma_channel_receive = 15,
.edma_channel_transmit_update = 0,
.edma_channel_receive_update = 0,
.edma_channel_transmit_error = 0,
.edma_channel_receive_error = 0,
.idle_char = 0xffffffff,
}, {
/* DSPI D */
.bus = {
.ops = &mpc55xx_dspi_ops,
.size = sizeof( mpc55xx_dspi_bus_entry)
},
.table_index = 3,
.bus_number = 0,
.regs = &DSPI_D,
.master = 1,
.push_data = MPC55XX_ZERO_FLAGS,
.edma_channel_transmit = 16,
.edma_channel_push = 18,
.edma_channel_receive = 17,
.edma_channel_transmit_update = 0,
.edma_channel_receive_update = 0,
.edma_channel_transmit_error = 0,
.edma_channel_receive_error = 0,
.idle_char = 0xffffffff,
},
};

View File

@@ -0,0 +1,279 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Enhanced Direct Memory Access (eDMA).
*/
/*
* 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.
*/
#include <mpc55xx/regs.h>
#include <mpc55xx/edma.h>
#include <mpc55xx/mpc55xx.h>
#include <bsp/irq.h>
#include <string.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
#define MPC55XX_EDMA_CHANNEL_NUMBER 64
#define MPC55XX_EDMA_INVALID_CHANNEL -1
#define MPC55XX_EDMA_IS_CHANNEL_INVALID( i) ((i) < 0 || (i) >= MPC55XX_EDMA_CHANNEL_NUMBER)
#define MPC55XX_EDMA_IRQ_PRIORITY MPC55XX_INTC_MIN_PRIORITY
typedef struct {
uint8_t channel;
rtems_id transfer_update;
uint32_t *error_status;
} mpc55xx_edma_channel_entry;
static mpc55xx_edma_channel_entry mpc55xx_edma_channel_table [MPC55XX_EDMA_CHANNEL_NUMBER];
static uint32_t mpc55xx_edma_channel_occupation_low = 0;
static uint32_t mpc55xx_edma_channel_occupation_high = 0;
static rtems_id mpc55xx_edma_channel_occupation_mutex = RTEMS_ID_NONE;
static uint8_t mpc55xx_edma_irq_error_low_channel = 0;
static uint8_t mpc55xx_edma_irq_error_high_channel = 32;
static void mpc55xx_edma_irq_handler( rtems_vector_number vector, void *data)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
mpc55xx_edma_channel_entry *e = (mpc55xx_edma_channel_entry *) data;
#ifdef DEBUG
uint32_t citer = EDMA.TCD [e->channel].CITERE_LINK ? EDMA.TCD [e->channel].CITER & EDMA_TCD_BITER_LINKED_MASK : EDMA.TCD [e->channel].CITER;
DEBUG_PRINT( "Channel %i (CITER = %i)\n", e->channel, citer);
#endif /* DEBUG */
EDMA.CIRQR.R = e->channel;
sc = rtems_semaphore_release( e->transfer_update);
SYSLOG_WARNING_SC( sc, "Transfer update semaphore release");
}
static void mpc55xx_edma_irq_update_error_table( uint8_t *link_table, uint8_t *error_table, uint8_t channel)
{
int i = 0;
error_table [channel] = 1;
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
if (channel == link_table [i] && error_table [i] == 0) {
mpc55xx_edma_irq_update_error_table( link_table, error_table, i);
}
}
}
static void mpc55xx_edma_irq_error_handler( rtems_vector_number vector, void *data)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
uint8_t channel_start = *((uint8_t *) data);
uint8_t channel_end = channel_start + 32;
uint8_t i = 0;
uint32_t mask = 0x1;
uint32_t error_register = 0;
uint8_t channel_link_table [MPC55XX_EDMA_CHANNEL_NUMBER];
uint8_t channel_error_table [MPC55XX_EDMA_CHANNEL_NUMBER];
/* Error register */
if (channel_start < 32) {
error_register = EDMA.ERL.R;
} else if (channel_start < 64) {
error_register = EDMA.ERH.R;
}
DEBUG_PRINT( "Error register %s: 0x%08x\n", channel_start < 32 ? "low" : "high", error_register);
/* Fill channel link table */
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
if (EDMA.TCD [i].BITERE_LINK && EDMA.TCD [i].CITER != EDMA.TCD [i].BITER) {
channel_link_table [i] = EDMA_TCD_BITER_LINK( i);
} else if (EDMA.TCD [i].MAJORE_LINK && EDMA.TCD [i].CITER == EDMA.TCD [i].BITER) {
channel_link_table [i] = EDMA.TCD [i].MAJORLINKCH;
} else {
channel_link_table [i] = MPC55XX_EDMA_INVALID_CHANNEL;
}
channel_error_table [i] = 0;
}
/* Search for channels with errors */
for (i = channel_start; i < channel_end; ++i) {
if ((error_register & mask) != 0) {
mpc55xx_edma_irq_update_error_table( channel_link_table, channel_error_table, i);
}
mask <<= 1;
}
/* Process the channels related to errors */
error_register = EDMA.ESR.R;
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
if (channel_error_table [i]) {
mpc55xx_edma_channel_entry *e = &mpc55xx_edma_channel_table [i];
if (e->error_status != NULL) {
*e->error_status = error_register;
}
sc = mpc55xx_edma_enable_hardware_requests( i, false);
SYSLOG_ERROR_SC( sc, "Disable hardware requests, channel = %i", i);
sc = rtems_semaphore_release( e->transfer_update);
SYSLOG_WARNING_SC( sc, "Transfer update semaphore release, channel = %i", i);
}
}
/* Clear the error interrupt requests */
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
if (channel_error_table [i]) {
EDMA.CER.R = i;
}
}
}
rtems_status_code mpc55xx_edma_enable_hardware_requests( int channel, bool enable)
{
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
return RTEMS_INVALID_NUMBER;
}
if (enable) {
EDMA.SERQR.R = channel;
} else {
EDMA.CERQR.R = channel;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc55xx_edma_enable_error_interrupts( int channel, bool enable)
{
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
return RTEMS_INVALID_NUMBER;
}
if (enable) {
EDMA.SEEIR.R = channel;
} else {
EDMA.CEEIR.R = channel;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc55xx_edma_init()
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int i = 0;
/* Channel occupation mutex */
sc = rtems_semaphore_create (
rtems_build_name ( 'D', 'M', 'A', 'O'),
1,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&mpc55xx_edma_channel_occupation_mutex
);
CHECK_SC( sc, "Create channel occupation mutex");
/* Arbitration mode: round robin */
EDMA.CR.B.ERCA = 1;
EDMA.CR.B.ERGA = 1;
/* Clear TCDs */
memset( &EDMA.TCD [0], 0, sizeof( EDMA.TCD));
/* Channel table */
for (i = 0; i < MPC55XX_EDMA_CHANNEL_NUMBER; ++i) {
mpc55xx_edma_channel_table [i].channel = i;
mpc55xx_edma_channel_table [i].transfer_update = RTEMS_ID_NONE;
mpc55xx_edma_channel_table [i].error_status = NULL;
}
/* Error interrupt handler */
sc = mpc55xx_interrupt_handler_install(
MPC55XX_IRQ_EDMA_ERROR_LOW,
MPC55XX_EDMA_IRQ_PRIORITY,
"eDMA Error (Low)",
RTEMS_INTERRUPT_UNIQUE,
mpc55xx_edma_irq_error_handler,
&mpc55xx_edma_irq_error_low_channel
);
CHECK_SC( sc, "Install low error interrupt handler");
sc = mpc55xx_interrupt_handler_install(
MPC55XX_IRQ_EDMA_ERROR_HIGH,
MPC55XX_EDMA_IRQ_PRIORITY,
"eDMA Error (High)",
RTEMS_INTERRUPT_UNIQUE,
mpc55xx_edma_irq_error_handler,
&mpc55xx_edma_irq_error_high_channel
);
CHECK_SC( sc, "Install high error interrupt handler");
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc55xx_edma_obtain_channel( int channel, uint32_t *error_status, rtems_id transfer_update)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int channel_occupied = 1;
if (MPC55XX_EDMA_IS_CHANNEL_INVALID( channel)) {
return RTEMS_INVALID_NUMBER;
}
/* Check occupation */
sc = rtems_semaphore_obtain( mpc55xx_edma_channel_occupation_mutex, RTEMS_WAIT, 0);
CHECK_SC( sc, "Obtain channel occupation mutex");
if (channel < 32) {
channel_occupied = mpc55xx_edma_channel_occupation_low & (0x1 << channel);
if (!channel_occupied) {
mpc55xx_edma_channel_occupation_low |= 0x1 << channel;
}
} else if (channel < 64) {
channel_occupied = mpc55xx_edma_channel_occupation_high & (0x1 << (channel - 32));
if (!channel_occupied) {
mpc55xx_edma_channel_occupation_high |= 0x1 << (channel - 32);
}
}
if (channel_occupied) {
sc = rtems_semaphore_release( mpc55xx_edma_channel_occupation_mutex);
SYSLOG_WARNING_SC( sc, "Release occupation mutex");
return RTEMS_RESOURCE_IN_USE;
} else {
sc = rtems_semaphore_release( mpc55xx_edma_channel_occupation_mutex);
CHECK_SC( sc, "Release channel occupation mutex");
}
/* Channel data */
mpc55xx_edma_channel_table [channel].transfer_update = transfer_update;
mpc55xx_edma_channel_table [channel].error_status = error_status;
/* Interrupt handler */
sc = mpc55xx_interrupt_handler_install(
MPC55XX_IRQ_EDMA_GET_REQUEST( channel),
MPC55XX_EDMA_IRQ_PRIORITY,
"eDMA Channel",
RTEMS_INTERRUPT_SHARED,
mpc55xx_edma_irq_handler,
&mpc55xx_edma_channel_table [channel]
);
CHECK_SC( sc, "Install channel interrupt handler");
/* Enable error interrupts */
sc = mpc55xx_edma_enable_error_interrupts( channel, true);
CHECK_SC( sc, "Enable error interrupts");
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc55xx_edma_release_channel( int channel)
{
// TODO
return RTEMS_NOT_IMPLEMENTED;
}

View File

@@ -0,0 +1,659 @@
/**
* @file
*
* @ingroup mpc55xx_esci
*
* @brief Source file for the Enhanced Serial Communication Interface (eSCI).
*/
/*
* 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.
*/
/* Include order is important */
#include <mpc55xx/regs.h>
#include <mpc55xx/esci.h>
#include <bsp/irq.h>
#include <unistd.h>
#include <termios.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/console.h>
#include <rtems/bspIo.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
/* Evil define conflicts */
#define TERMIOS_CR1 CR1
#undef CR1
#define TERMIOS_CR2 CR2
#undef CR2
#define MPC55XX_ESCI_IRQ_PRIORITY MPC55XX_INTC_MIN_PRIORITY
#define MPC55XX_ESCI_IS_MINOR_INVALD(minor) ((minor) < 0 || (minor) >= MPC55XX_ESCI_NUMBER)
#define MPC55XX_ESCI_USE_INTERRUPTS(e) (!(e)->console && (e)->use_interrupts)
/**
* @brief eSCI driver table.
*/
mpc55xx_esci_driver_entry mpc55xx_esci_driver_table [MPC55XX_ESCI_NUMBER] = { {
.regs = &ESCI_A,
.device_name = "/dev/tty1",
.use_termios = 1,
.use_interrupts = 0,
.console = 1,
.tty = NULL,
.irq_number = 146
}, {
.regs = &ESCI_B,
.device_name = "/dev/tty2",
.use_termios = 1,
.use_interrupts = 0,
.console = 0,
.tty = NULL,
.irq_number = 149
}
};
/**
* @brief Default termios configuration.
*/
static const struct termios mpc55xx_esci_termios_default = {
0,
0,
CS8 | CREAD | CLOCAL | B115200,
0,
0,
{ 0 }
};
/**
* @name Low-Level
* @{
*/
/**
* @brief Reads one character from the receive register.
*
* @note Waits for the receive data register full flag.
*/
static inline uint8_t mpc55xx_esci_read_char( mpc55xx_esci_driver_entry *e)
{
volatile union ESCI_SR_tag *status = &e->regs->SR;
volatile union ESCI_DR_tag *data = &e->regs->DR;
union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
while (status->B.RDRF == 0) {
/* Wait */
}
/* Clear flag */
sr.B.RDRF = 1;
status->R = sr.R;
/* Read */
return data->B.D;
}
/**
* @brief Writes the character @a c to the transmit register.
*
* @note Waits for the transmit data register empty flag.
*/
static inline void mpc55xx_esci_write_char( mpc55xx_esci_driver_entry *e, uint8_t c)
{
volatile union ESCI_SR_tag *status = &e->regs->SR;
volatile union ESCI_DR_tag *data = &e->regs->DR;
union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
while (status->B.TDRE == 0) {
/* Wait */
}
/* Clear flag */
sr.B.TDRE = 1;
status->R = sr.R;
/* Write */
data->B.D = c;
}
/** @} */
/**
* @name Termios Support
* @{
*/
/**
* @brief Opens port @a minor.
*
* @return Status code.
*/
static int mpc55xx_esci_termios_first_open( int major, int minor, void *arg)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
struct rtems_termios_tty *tty = ((rtems_libio_open_close_args_t *) arg)->iop->data1;
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
/* Connect TTY */
e->tty = tty;
/* Enable interrupts */
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
cr1.R = e->regs->CR1.R;
cr1.B.RIE = 1;
cr1.B.TIE = 1;
e->regs->CR1.R = cr1.R;
}
return RTEMS_SUCCESSFUL;
}
/**
* @brief Closes port @a minor.
*
* @return Status code.
*/
static int mpc55xx_esci_termios_last_close( int major, int minor, void* arg)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
/* Disable interrupts */
cr1.R = e->regs->CR1.R;
cr1.B.RIE = 0;
cr1.B.TIE = 0;
e->regs->CR1.R = cr1.R;
/* Disconnect TTY */
e->tty = NULL;
return RTEMS_SUCCESSFUL;
}
/**
* @brief Reads one character from port @a minor.
*
* @return Returns the character or -1 on error.
*/
static int mpc55xx_esci_termios_poll_read( int minor)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return -1;
}
return (int) mpc55xx_esci_read_char( e);
}
/**
* @brief Writes @a n characters from @a out to port @a minor.
*
* @return Returns 0 on success or -1 otherwise.
*/
static int mpc55xx_esci_termios_poll_write( int minor, const char *out, int n)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
int i = 0;
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return -1;
}
/* Write */
for (i = 0; i < n; ++i) {
mpc55xx_esci_write_char( e, out [i]);
if (out [i] == '\n') {
mpc55xx_esci_write_char( e, '\r');
}
}
return 0;
}
/**
* @brief Writes one character from @a out to port @a minor.
*
* @return Returns always 0.
*
* @note The buffer @a out has to provide at least one character.
* This function assumes that the transmit data register is empty.
*/
static int mpc55xx_esci_termios_write( int minor, const char *out, int n)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Write */
e->regs->DR.B.D = out [0];
return 0;
}
/**
* @brief Sets attributes of port @a minor according to termios attributes @a t.
*
* @return Status code.
*/
static int mpc55xx_esci_termios_set_attributes( int minor, const struct termios *t)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
volatile struct ESCI_tag *regs = e->regs;
union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS;
union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS;
unsigned br = 0;
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
/* Enable module */
cr2.B.MDIS = 0;
/* Interrupts */
if (MPC55XX_ESCI_USE_INTERRUPTS( e) && e->tty != NULL) {
cr1.B.RIE = 1;
cr1.B.TIE = 1;
} else {
cr1.B.RIE = 0;
cr1.B.TIE = 0;
}
cr1.B.TCIE = 0;
cr1.B.ILIE = 0;
cr2.B.IEBERR = 0;
cr2.B.ORIE = 0;
cr2.B.NFIE = 0;
cr2.B.FEIE = 0;
cr2.B.PFIE = 0;
/* Disable receiver wake-up standby */
cr1.B.RWU = 0;
/* Disable DMA channels */
cr2.B.RXDMA = 0;
cr2.B.TXDMA = 0;
/* Idle line type */
cr1.B.ILT = 0;
/* Disable loops */
cr1.B.LOOPS = 0;
/* Enable or disable receiver */
cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0;
/* Enable transmitter */
cr1.B.TE = 1;
/* Baud rate */
switch (t->c_cflag & CBAUD) {
case B50: br = 50; break;
case B75: br = 75; break;
case B110: br = 110; break;
case B134: br = 134; break;
case B150: br = 150; break;
case B200: br = 200; break;
case B300: br = 300; break;
case B600: br = 600; break;
case B1200: br = 1200; break;
case B1800: br = 1800; break;
case B2400: br = 2400; break;
case B4800: br = 4800; break;
case B9600: br = 9600; break;
case B19200: br = 19200; break;
case B38400: br = 38400; break;
case B57600: br = 57600; break;
case B115200: br = 115200; break;
case B230400: br = 230400; break;
case B460800: br = 460800; break;
default: br = 0; break;
}
if (br > 0) {
// FIXME, TODO
extern uint32_t bsp_clock_speed;
br = bsp_clock_speed / (16 * br);
br = (br > 8191) ? 8191 : br;
} else {
br = 0;
}
cr1.B.SBR = br;
/* Number of data bits */
if ((t->c_cflag & CSIZE) != CS8) {
return RTEMS_IO_ERROR;
}
cr1.B.M = 0;
/* Parity */
cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0;
cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0;
/* Stop bits */
if ( t->c_cflag & CSTOPB ) {
/* Two stop bits */
return RTEMS_IO_ERROR;
}
/* Set control registers */
regs->CR1.R = cr1.R;
regs->CR2.R = cr2.R;
/* Disable LIN */
regs->LCR.R = 0;
return RTEMS_SUCCESSFUL;
}
/**
* @brief Interrupt handler.
*/
static void mpc55xx_esci_termios_interrupt_handler( rtems_vector_number vector, void *arg)
{
mpc55xx_esci_driver_entry *e = (mpc55xx_esci_driver_entry *) arg;
volatile union ESCI_SR_tag *status = &e->regs->SR;
volatile union ESCI_DR_tag *data = &e->regs->DR;
union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS;
union ESCI_SR_tag active = MPC55XX_ZERO_FLAGS;
/* Status */
sr.R = status->R;
/* Receive data register full? */
if (sr.B.RDRF != 0) {
active.B.RDRF = 1;
}
/* Transmit data register empty? */
if (sr.B.TDRE != 0) {
active.B.TDRE = 1;
}
/* Clear flags */
status->R = active.R;
/* Enqueue */
if (active.B.RDRF != 0) {
char c = data->B.D;
rtems_termios_enqueue_raw_characters( e->tty, &c, 1);
}
/* Dequeue */
if (active.B.TDRE != 0) {
rtems_termios_dequeue_characters( e->tty, 1);
}
}
/** @} */
/**
* @brief Termios callbacks with interrupt support.
*/
static const rtems_termios_callbacks mpc55xx_esci_termios_callbacks = {
.firstOpen = mpc55xx_esci_termios_first_open,
.lastClose = mpc55xx_esci_termios_last_close,
.pollRead = NULL,
.write = mpc55xx_esci_termios_write,
.setAttributes = mpc55xx_esci_termios_set_attributes,
.stopRemoteTx = NULL,
.startRemoteTx = NULL,
.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
};
/**
* @brief Termios callbacks with polling functions (no interrupts).
*/
static const rtems_termios_callbacks mpc55xx_esci_termios_callbacks_polled = {
.firstOpen = mpc55xx_esci_termios_first_open,
.lastClose = mpc55xx_esci_termios_last_close,
.pollRead = mpc55xx_esci_termios_poll_read,
.write = mpc55xx_esci_termios_poll_write,
.setAttributes = mpc55xx_esci_termios_set_attributes,
.stopRemoteTx = NULL,
.startRemoteTx = NULL,
.outputUsesInterrupts = TERMIOS_POLLED
};
/**
* @name Console Driver
* @{
*/
rtems_device_driver console_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int console_done = 0;
int termios_do_init = 1;
int i = 0;
mpc55xx_esci_driver_entry *e = NULL;
for (i = 0; i < MPC55XX_ESCI_NUMBER; ++i) {
e = &mpc55xx_esci_driver_table [i];
sc = rtems_io_register_name ( e->device_name, major, i);
CHECK_SC( sc, "Register IO device");
if (e->console) {
if (console_done) {
SYSLOG_WARNING( "Multiple console ports defined\n");
} else {
console_done = 1;
if (e->use_interrupts) {
SYSLOG_WARNING( "Cannot use interrupts for console port\n");
}
sc = rtems_io_register_name( CONSOLE_DEVICE_NAME, major, i);
CHECK_SC( sc, "Register IO device");
}
}
if (e->use_termios && termios_do_init) {
if (termios_do_init) {
termios_do_init = 0;
rtems_termios_initialize();
}
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
sc = mpc55xx_interrupt_handler_install(
e->irq_number,
MPC55XX_ESCI_IRQ_PRIORITY,
"eSCI",
RTEMS_INTERRUPT_UNIQUE,
mpc55xx_esci_termios_interrupt_handler,
e
);
CHECK_SC( sc, "Install IRQ handler");
}
}
mpc55xx_esci_termios_set_attributes( minor, &mpc55xx_esci_termios_default);
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_open( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
int rv = 0;
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
if (e->use_termios) {
if (MPC55XX_ESCI_USE_INTERRUPTS( e)) {
sc = rtems_termios_open( major, minor, arg, &mpc55xx_esci_termios_callbacks);
} else {
sc = rtems_termios_open( major, minor, arg, &mpc55xx_esci_termios_callbacks_polled);
}
if (sc != RTEMS_SUCCESSFUL) {
return sc;
}
rv = rtems_termios_set_initial_baud( e->tty, 115200);
if (rv < 0) {
return RTEMS_IO_ERROR;
}
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_close( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
if (e->use_termios) {
return rtems_termios_close( arg);
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_read( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
if (e->use_termios) {
return rtems_termios_read( arg);
} else {
rtems_libio_rw_args_t *rw = (rtems_libio_rw_args_t *) arg;
uint32_t i = 0;
while (i < rw->count) {
rw->buffer [i] = mpc55xx_esci_read_char( e);
++i;
}
rw->bytes_moved = i;
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_write( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
if (e->use_termios) {
return rtems_termios_write( arg);
} else {
rtems_libio_rw_args_t *rw = (rtems_libio_rw_args_t *) arg;
uint32_t i = 0;
while (i < rw->count) {
mpc55xx_esci_write_char( e, rw->buffer [i]);
if (rw->buffer [i] == '\n') {
mpc55xx_esci_write_char( e, '\r');
}
++i;
}
rw->bytes_moved = i;
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_control( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [minor];
/* Check minor number */
if (MPC55XX_ESCI_IS_MINOR_INVALD( minor)) {
return RTEMS_INVALID_NUMBER;
}
if (e->use_termios) {
return rtems_termios_ioctl( arg);
}
return RTEMS_NOT_DEFINED;
}
/** @} */
/**
* @brief Port number for the BSP character output function.
*
* The correct value will be set by mpc55xx_esci_output_char_init().
*/
static unsigned mpc55xx_esci_output_char_minor = 0;
/**
* @name BSP Character Output
* @{
*/
static void mpc55xx_esci_output_char( char c)
{
mpc55xx_esci_driver_entry *e = &mpc55xx_esci_driver_table [mpc55xx_esci_output_char_minor];
mpc55xx_esci_write_char( e, c);
if (c == '\n') {
mpc55xx_esci_write_char( e, '\r');
}
}
static void mpc55xx_esci_output_char_nop( char c)
{
/* Do nothing */
}
static void mpc55xx_esci_output_char_init( char c)
{
int console_found = 0;
unsigned i = 0;
for (i = 0; i < MPC55XX_ESCI_NUMBER; ++i) {
if (mpc55xx_esci_driver_table [i].console) {
console_found = 1;
mpc55xx_esci_output_char_minor = i;
break;
}
}
if (console_found) {
BSP_output_char = mpc55xx_esci_output_char;
mpc55xx_esci_termios_set_attributes( mpc55xx_esci_output_char_minor, &mpc55xx_esci_termios_default);
mpc55xx_esci_output_char( c);
} else {
BSP_output_char = mpc55xx_esci_output_char_nop;
}
}
/** @} */
BSP_output_char_function_type BSP_output_char = mpc55xx_esci_output_char_init;

View File

@@ -0,0 +1,19 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Device driver for the Fast Ethernet Controller
*
* @par Copyright
* Copyright (c) 2008<br>
* Embedded Brains GmbH<br>
* Obere Lagerstr. 30<br>
* D-82178 Puchheim<br>
* Germany<br>
* rtems@embedded-brains.de<br>
*
* @par License
* 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.
*/

View File

@@ -0,0 +1,135 @@
/**
* @file
*
* @ingroup mpc55xx_dspi
*
* @brief Header file for the LibI2C bus driver for the Deserial Serial Peripheral Interface (DSPI).
*/
/*
* 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.
*/
/**
* @defgroup mpc55xx_dspi Deserial Serial Peripheral Interface (DSPI)
*
* @ingroup mpc55xx
*/
#ifndef LIBCPU_POWERPC_MPC55XX_DSPI_H
#define LIBCPU_POWERPC_MPC55XX_DSPI_H
#include <rtems/libi2c.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct DSPI_tag;
/**
* @brief LibI2C bus driver entry.
*/
typedef struct {
/**
* @brief Standard bus driver fields.
*/
rtems_libi2c_bus_t bus;
/**
* @brief Index in the bus table: @ref mpc55xx_dspi_bus_table.
*/
unsigned table_index;
/**
* @brief Bus number (available after rtems_libi2c_register_bus()).
*
* @note You must set it in the initialization code after the bus registration.
*/
unsigned bus_number;
/**
* @brief Hardware registers.
*/
volatile struct DSPI_tag *regs;
/**
* @brief Selects SPI master or slave mode.
*/
int master;
/**
* @brief Data for the Push Register.
*/
union DSPI_PUSHR_tag push_data;
/**
* @brief eDMA channel for transmission.
*
* The channel is fixed to particular DSPI.
*/
int edma_channel_transmit;
/**
* @brief eDMA channel to generate the push data.
*
* You can choose any available channel.
*/
int edma_channel_push;
/**
* @brief eDMA channel for receiving.
*
* The channel is fixed to particular DSPI.
*/
int edma_channel_receive;
/**
* @brief Semaphore ID for a transmit update.
*/
rtems_id edma_channel_transmit_update;
/**
* @brief Semaphore ID for a receive update.
*/
rtems_id edma_channel_receive_update;
/**
* @brief Transmit error status.
*/
uint32_t edma_channel_transmit_error;
/**
* @brief Receive error status.
*/
uint32_t edma_channel_receive_error;
/**
* @brief Idle character transmitted in read only mode.
*/
uint32_t idle_char;
} mpc55xx_dspi_bus_entry;
/**
* @brief Number of DSPIs.
*/
#define MPC55XX_DSPI_NUMBER 4
/**
* @brief Table with bus driver entries.
*/
extern mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [ /* MPC55XX_DSPI_NUMBER */ ];
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBCPU_POWERPC_MPC55XX_DSPI_H */

View File

@@ -0,0 +1,102 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Enhanced Direct Memory Access (eDMA).
*/
/*
* 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.
*/
#ifndef LIBCPU_POWERPC_MPC55XX_EDMA_H
#define LIBCPU_POWERPC_MPC55XX_EDMA_H
#include <stdbool.h>
#include <rtems.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MPC55XX_EDMA_TCD_DEFAULT { \
.SADDR = 0, \
.SMOD = 0, \
.SSIZE = 0x2, \
.SOFF = 4, \
.DADDR = 0, \
.DMOD = 0, \
.DSIZE = 0x2, \
.DOFF = 4, \
.NBYTES = 0, \
.SLAST = 0, \
.CITER = 1, \
.BITER = 1, \
.MAJORLINKCH = 0, \
.CITERE_LINK = 0, \
.BITERE_LINK = 0, \
.MAJORE_LINK = 0, \
.E_SG = 0, \
.DLAST_SGA = 0, \
.D_REQ = 0, \
.BWC = 0, \
.INT_HALF = 0, \
.INT_MAJ = 0, \
.DONE = 0, \
.ACTIVE = 0, \
.START = 0, \
}
#define MPC55XX_EDMA_TCD_ALT_DEFAULT { \
.SADDR = 0, \
.SMOD = 0, \
.SSIZE = 2, \
.DMOD = 0, \
.DSIZE = 2, \
.SOFF = 4, \
.NBYTES = 0, \
.SLAST = 0, \
.DADDR = 0, \
.CITERE_LINK = 0, \
.CITERLINKCH = 0, \
.CITER = 0, \
.DOFF = 4, \
.DLAST_SGA = 0, \
.BITERE_LINK = 0, \
.BITERLINKCH = 0, \
.BITER = 0, \
.BWC = 0, \
.MAJORLINKCH = 0, \
.DONE = 0, \
.ACTIVE = 0, \
.MAJORE_LINK = 0, \
.E_SG = 0, \
.D_REQ = 0, \
.INT_HALF = 0, \
.INT_MAJ = 0, \
.START = 0, \
}
rtems_status_code mpc55xx_edma_init();
rtems_status_code mpc55xx_edma_obtain_channel( int channel, uint32_t *error_status, rtems_id transfer_update);
rtems_status_code mpc55xx_edma_enable_hardware_requests( int channel, bool enable);
rtems_status_code mpc55xx_edma_enable_error_interrupts( int channel, bool enable);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBCPU_POWERPC_MPC55XX_EDMA_H */

View File

@@ -0,0 +1,48 @@
/**
* @file
*
* @ingroup mpc55xx_esci
*
* @brief Header file for the Enhanced Serial Communication Interface (eSCI).
*/
/*
* 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.
*/
/**
* @defgroup mpc55xx_esci Enhanced Serial Communication Interface (eSCI).
*
* @ingroup mpc55xx
*/
#ifndef LIBCPU_POWERPC_MPC55XX_ESCI_H
#define LIBCPU_POWERPC_MPC55XX_ESCI_H
#include <rtems/termiostypes.h>
#define MPC55XX_ESCI_NUMBER 2
struct ESCI_tag;
typedef struct {
volatile struct ESCI_tag *regs;
const char *device_name;
int use_termios;
int use_interrupts;
int console;
struct rtems_termios_tty *tty;
unsigned irq_number;
} mpc55xx_esci_driver_entry;
extern mpc55xx_esci_driver_entry mpc55xx_esci_driver_table [ /* MPC55XX_ESCI_NUMBER */ ];
#endif /* LIBCPU_POWERPC_MPC55XX_ESCI_H */

View File

@@ -0,0 +1,92 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief IRQ
*/
/*
* 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.
*/
#ifndef LIBBSP_POWERPC_IRQ_H
#define LIBBSP_POWERPC_IRQ_H
#include <rtems/irq-extension.h>
#include <rtems/irq.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* Interrupt numbers
*/
/* Basics */
#define MPC55XX_IRQ_MIN 0
#define MPC55XX_IRQ_MAX 328
#define MPC55XX_IRQ_BASE MPC55XX_IRQ_MIN
#define MPC55XX_IRQ_NUMBER (MPC55XX_IRQ_MAX + 1)
/* Software interrupts */
#define MPC55XX_IRQ_SOFTWARE_MIN 0
#define MPC55XX_IRQ_SOFTWARE_MAX 7
#define MPC55XX_IRQ_SOFTWARE_NUMBER (MPC55XX_IRQ_SOFTWARE_MAX + 1)
/* eDMA interrupts */
#define MPC55XX_IRQ_EDMA_ERROR_LOW 10
#define MPC55XX_IRQ_EDMA_ERROR_HIGH 210
#define MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN 11
#define MPC55XX_IRQ_EDMA_REQUEST_LOW_MAX 42
#define MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN 211
#define MPC55XX_IRQ_EDMA_REQUEST_HIGH_MAX 242
#define MPC55XX_IRQ_EDMA_GET_CHANNEL( i) (((i) > MPC55XX_IRQ_EDMA_REQUEST_LOW_MAX) ? ((i) - MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN + 32) : ((i) - MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN))
#define MPC55XX_IRQ_EDMA_GET_REQUEST( c) (((c) > 31) ? ((c) + MPC55XX_IRQ_EDMA_REQUEST_HIGH_MIN - 32) : ((c) + MPC55XX_IRQ_EDMA_REQUEST_LOW_MIN))
/* Checks */
#define MPC55XX_IRQ_IS_VALID(i) ((i) >= MPC55XX_IRQ_MIN && (i) <= MPC55XX_IRQ_MAX)
#define MPC55XX_IRQ_IS_SOFTWARE(i) ((i) >= MPC55XX_IRQ_SOFTWARE_MIN && (i) <= MPC55XX_IRQ_SOFTWARE_MAX)
/*
* Interrupt controller
*/
#define MPC55XX_INTC_INVALID_PRIORITY -1
#define MPC55XX_INTC_DISABLED_PRIORITY 0
#define MPC55XX_INTC_MIN_PRIORITY 1
#define MPC55XX_INTC_MAX_PRIORITY 15
#define MPC55XX_INTC_DEFAULT_PRIORITY MPC55XX_INTC_MIN_PRIORITY
#define MPC55XX_INTC_IS_VALID_PRIORITY(p) ((p) >= MPC55XX_INTC_DISABLED_PRIORITY && (p) <= MPC55XX_INTC_MAX_PRIORITY)
rtems_status_code mpc55xx_interrupt_handler_install(
rtems_vector_number vector,
int priority,
const char *info,
rtems_option options,
rtems_interrupt_handler handler,
void *arg
);
rtems_status_code mpc55xx_intc_get_priority( int i, int *p);
rtems_status_code mpc55xx_intc_set_priority( int i, int p);
rtems_status_code mpc55xx_intc_raise_software_irq( int i);
rtems_status_code mpc55xx_intc_clear_software_irq( int i);
#ifdef __cplusplus
};
#endif /* __cplusplus */
#endif /* LIBBSP_POWERPC_IRQ_H */

View File

@@ -0,0 +1,111 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Documentation for this file
*/
/*
* 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.
*/
/**
* @defgroup mpc55xx BSP for MPC55xx boards
*/
/**
* @defgroup mpc55xx_config Configuration files
*
* @ingroup mpc55xx
*
* Makefiles, configure scripts etc.
*/
/**
* @page mpc55xx_ext_doc External Documentation
*
* @section mpc55xx_ext_doc_mpc5567rm_1 MPC5567 Microcontroller Reference Manual (Rev. 1, January 2007, Volume 1 of 2)
* @section mpc55xx_ext_doc_mpc5567rm_2 MPC5567 Microcontroller Reference Manual (Rev. 1, January 2007, Volume 2 of 2)
*/
#ifndef LIBCPU_POWERPC_MPC55XX_H
#define LIBCPU_POWERPC_MPC55XX_H
#include <stddef.h>
#include <stdint.h>
/* Defined in copy.S */
int mpc55xx_copy_8( const void *src, void *dest, size_t n);
/* Defined in copy.S */
int mpc55xx_zero_8( void *dest, size_t n);
/* Defined in copy.S */
int mpc55xx_zero_32( void *dest, size_t n);
/* Defined in fmpll.S */
void mpc55xx_fmpll_reset_config();
/* Defined in fmpll.S */
void mpc55xx_fmpll_wait_for_lock();
/* Defined in fmpll.S */
int mpc55xx_get_system_clock();
/* Defined in fmpll.S */
void mpc55xx_system_reset();
/* Defined in flash.S */
void mpc55xx_flash_config();
#define MPC55XX_CACHE_ALIGNED_MASK ((uintptr_t) 0x1f)
#define MPC55XX_CACHE_LINE_SIZE 32
/**
* @brief Returns true if the buffer starting at @a s of size @a n is cache aligned.
*/
static inline int mpc55xx_is_cache_aligned( const void *s, size_t n)
{
return !(((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) || (n & MPC55XX_CACHE_ALIGNED_MASK));
}
static inline void* mpc55xx_cache_aligned_start( const void *s)
{
return ((uintptr_t) s & MPC55XX_CACHE_ALIGNED_MASK) ? (((uintptr_t) s & ~MPC55XX_CACHE_ALIGNED_MASK) + MPC55XX_CACHE_LINE_SIZE) : s;
}
static inline size_t mpc55xx_non_cache_aligned_size( const void *s)
{
return (uintptr_t) mpc55xx_cache_aligned_start( s) - (uintptr_t) s;
}
static inline size_t mpc55xx_cache_aligned_size( const void *s, size_t n)
{
return (n - mpc55xx_non_cache_aligned_size( s)) & ~MPC55XX_CACHE_ALIGNED_MASK;
}
/**
* @brief Returns the number of leading zeros.
*/
static inline uint32_t mpc55xx_count_leading_zeros( uint32_t value)
{
uint32_t count;
asm (
"cntlzw %0, %1;"
: "=r" (count)
: "r" (value)
);
return count;
}
#endif /* LIBCPU_POWERPC_MPC55XX_H */

View File

@@ -0,0 +1,193 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Register definitions.
*/
/*
* 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.
*/
#ifndef LIBCPU_POWERPC_MPC55XX_REG_DEFS_H
#define LIBCPU_POWERPC_MPC55XX_REG_DEFS_H
/*
* Register addresses
*/
#define FMPLL_SYNCR 0xC3F80000
#define FMPLL_SYNSR 0xC3F80004
#define FLASH_BIUCR 0xC3F8801C
#define SIU_ECCR 0xC3F90984
#define SIU_SRCR 0xC3F90010
/*
* Special purpose registers
*/
#define BUCSR 1013
/*
* Branch Unit Control and Status Register (BUCSR)
*/
#define BUCSR_BBFI 0x00000200
#define BUCSR_BPEN 0x00000001
/*
* Definitions for FMPLL_SYNCR (FMPLL Synthesizer Control Register)
*/
/* Fields used for PREDIV (Pre-Divider bits [1:3]) */
#define FMPLL_SYNCR_PREDIV_0 0x00000000
/* Fields used for MFD (Muliplication Factor Divider bits [4:8]) */
#define FMPLL_SYNCR_MFD_0 0x00000000
#define FMPLL_SYNCR_MFD_2 0x01000000
#define FMPLL_SYNCR_MFD_4 0x02000000
#define FMPLL_SYNCR_MFD_6 0x03000000
#define FMPLL_SYNCR_MFD_8 0x04000000
#define FMPLL_SYNCR_MFD_10 0x05000000
#define FMPLL_SYNCR_MFD_12 0x06000000
/* Fields used for RFD (Reduced Frequency Divider bits [10:12]) */
#define FMPLL_SYNCR_RFD_0 0x00000000
#define FMPLL_SYNCR_RFD_1 0x00080000
#define FMPLL_SYNCR_RFD_2 0x00100000
#define FMPLL_SYNCR_RFD_3 0x00180000
#define FMPLL_SYNCR_RFD_4 0x00200000
#define FMPLL_SYNCR_RFD_5 0x00280000
#define FMPLL_SYNCR_RFD_6 0x00300000
#define FMPLL_SYNCR_RFD_7 0x00380000
/* Fields for LOCEN (Loss-of-clock enable bit [13]) */
#define FMPLL_SYNCR_LOCEN 0x00040000
/* Fields for LOLRE (Loss-of-lock reset enable bit [14]) */
#define FMPLL_SYNCR_LOLRE 0x00020000
/* Fields for LOCRE (Loss-of-clock reset enable bit [15]) */
#define FMPLL_SYNCR_LOCRE 0x00010000
/* Fields for DISCLK (Disable CLKOUT bit [16]) */
#define FMPLL_SYNCR_DISCLK 0x00008000
/* Fields for LOLIRQ (Loss-of-lock interrupt request bit [17]) */
#define FMPLL_SYNCR_LOLIRQ 0x00004000
/* Fields for LOCIRQ (Loss-of-clock interrupt request bit [18]) */
#define FMPLL_SYNCR_LOCIRQ 0x00002000
/* Fields for RATE (Modulation rate bit [19]) */
#define FMPLL_SYNCR_RATE_FREF 0x00001000
/* Fields for DEPTH (Modulation depth percentage bits [20:21]) */
#define FMPLL_SYNCR_DEPTH_0 0x00000000
#define FMPLL_SYNCR_DEPTH_1 0x00000400
#define FMPLL_SYNCR_DEPTH_2 0x00000800
/* Fields for EXP (Expected difference bits [22:31]) */
#define FMPLL_SYNCR_EXP_0 0x00000000
/*
* Definitions for the FMPLL_SYNSR (Synthesizer Status Register)
*/
/* Fields for LOLF (Loss-of-lock flag bit [22]) */
#define FMPLL_SYNSR_LOLF 0x00000200
/* Fields for LOCK (Lock status bit [28]) */
#define FMPLL_SYNSR_LOCK 0x00000008
/* Fields for LOCF (Loss-of-clock flag bit [29]) */
#define FMPLL_SYNSR_LOCF 0x00000004
/*
* Definitions for the SIU_SRCR (System Reset Control Register)
*/
/* Fields for SSR (software system reset bit [0]) */
#define SIU_SRCR_SSR 0x80000000
/* Fields for SER (external system reset bit [1]) */
#define SIU_SRCR_SER 0x40000000
/* Fields for CRE (checkstop reset enable bit [16]) */
#define SIU_SRCR_CRE 0x00008000
/*
* Definitions for FLASH_BIUCR (Flash BIU Control Register)
*/
/* Fields for Flash Bus Interface Control */
/* Fields for Prefetch Control (MnPFE Master n Prefetch Enable) */
/* Fields for M3PFE (Master 3 (EBI) prefetch enable bit [12]) */
#define FLASH_BUICR_EBI_PREFTCH 0x00080000
/* Fields for M2PFE (Master 2 (eDMA) prefetch enable bit [13]) */
#define FLASH_BUICR_EDMA_PREFTCH 0x00040000
/* Fields for M1PFE (Master 1 (Nexus) prefetch enable bit [14]) */
#define FLASH_BUICR_NEX_PREFTCH 0x00020000
/* Fields for M0PFE (Master 0 (e200z core) prefetch enable bit [15]) */
#define FLASH_BUICR_CPU_PREFTCH 0x00010000
/* Fields for APC (access pipelining control bits [16:18]) */
#define FLASH_BUICR_APC_1 0x00002000
#define FLASH_BUICR_APC_2 0x00004000
#define FLASH_BUICR_APC_3 0x00006000
#define FLASH_BUICR_APC_4 0x00008000
#define FLASH_BUICR_APC_5 0x0000A000
#define FLASH_BUICR_APC_6 0x0000C000
#define FLASH_BUICR_APC_NO 0x0000E000
/* Fields for WWSC (write wait state control bits [19:20]) */
#define FLASH_BUICR_WWSC_1 0x00000800
#define FLASH_BUICR_WWSC_2 0x00001000
#define FLASH_BUICR_WWSC_3 0x00001800
/* Fields for RWSC (read wait state control bits [21:23]) */
#define FLASH_BUICR_RWSC_0 0x00000000
#define FLASH_BUICR_RWSC_1 0x00000100
#define FLASH_BUICR_RWSC_2 0x00000200
#define FLASH_BUICR_RWSC_3 0x00000300
#define FLASH_BUICR_RWSC_4 0x00000400
#define FLASH_BUICR_RWSC_5 0x00000500
#define FLASH_BUICR_RWSC_6 0x00000600
#define FLASH_BUICR_RWSC_7 0x00000700
/* Fields for DPFEN (data prefetch enable bits [24:25]) */
#define FLASH_BUICR_DPFEN_0 0x00000000
#define FLASH_BUICR_DPFEN_1 0x00000040
#define FLASH_BUICR_DPFEN_3 0x000000C0
/* Fields for IPFEN (instruction prefetch enable bits [26:27]) */
#define FLASH_BUICR_IPFEN_0 0x00000000
#define FLASH_BUICR_IPFEN_1 0x00000010
#define FLASH_BUICR_IPFEN_3 0x00000030
/* Fields for PFLIM (additional line prefetch (limit) bits [28:30]) */
#define FLASH_BUICR_PFLIM_0 0x00000000
#define FLASH_BUICR_PFLIM_1 0x00000002
#define FLASH_BUICR_PFLIM_2 0x00000004
#define FLASH_BUICR_PFLIM_3 0x00000006
#define FLASH_BUICR_PFLIM_4 0x00000008
#define FLASH_BUICR_PFLIM_5 0x0000000A
#define FLASH_BUICR_PFLIM_6 0x0000000C
/* Fields for BFEN (enable line read buffer hits bit [31]) */
#define FLASH_BUICR_BFEN 0x00000001
#endif /* LIBCPU_POWERPC_MPC55XX_REG_DEFS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Source file for MPC55XX interrupt support.
*/
/*
* 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.
*/
#include <mpc55xx/regs.h>
#include <libcpu/raw_exception.h>
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/ppc_exc_bspsupp.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
/**
* @brief Returns the priority @a p of IRQ @a i from the INTC.
*/
rtems_status_code mpc55xx_intc_get_priority( int i, int *p)
{
if (MPC55XX_IRQ_IS_VALID( i)) {
*p = INTC.PSR [i].B.PRI;
return RTEMS_SUCCESSFUL;
} else {
*p = MPC55XX_INTC_INVALID_PRIORITY;
return RTEMS_INVALID_NUMBER;
}
}
/**
* @brief Sets the priority of IRQ @a i to @a p at the INTC.
*/
rtems_status_code mpc55xx_intc_set_priority( int i, int p)
{
if (MPC55XX_IRQ_IS_VALID( i) && MPC55XX_INTC_IS_VALID_PRIORITY( p)) {
INTC.PSR [i].B.PRI = p;
if (INTC.PSR [i].B.PRI == p) {
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_IO_ERROR;
}
} else {
return RTEMS_INVALID_NUMBER;
}
}
/**
* @brief Raises the software IRQ with number @a i.
*/
rtems_status_code mpc55xx_intc_raise_software_irq( int i)
{
if (MPC55XX_IRQ_IS_SOFTWARE( i)) {
INTC.SSCIR [i].B.SET = 1;
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_INVALID_NUMBER;
}
}
/**
* @brief Clears the software IRQ with number @a i.
*/
rtems_status_code mpc55xx_intc_clear_software_irq( int i)
{
if (MPC55XX_IRQ_IS_SOFTWARE( i)) {
INTC.SSCIR [i].B.CLR = 1;
return RTEMS_SUCCESSFUL;
} else {
return RTEMS_INVALID_NUMBER;
}
}
/**
* @brief Installs interrupt handler and sets priority.
*/
rtems_status_code mpc55xx_interrupt_handler_install(
rtems_vector_number vector,
int priority,
const char *info,
rtems_option options,
rtems_interrupt_handler handler,
void *arg
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) {
sc = rtems_interrupt_handler_install( vector, info, options, handler, arg);
CHECK_SC( sc, "Install interrupt handler");
return mpc55xx_intc_set_priority( vector, priority);
} else {
return RTEMS_INVALID_NUMBER;
}
}
/**
* @brief External exception handler.
*/
static int mpc55xx_external_exception_handler( BSP_Exception_frame *frame, unsigned exception_number)
{
/* Acknowlege interrupt request */
rtems_vector_number vector_number = INTC.IACKR.B.INTVEC;
/* Save current interrupt level */
uint32_t level = _ISR_Get_level();
/* Enable all interrupts */
_ISR_Set_level( 0);
/* Dispatch interrupt handlers */
bsp_interrupt_handler_dispatch( vector_number);
/* Restore interrupt level */
_ISR_Set_level( level);
/* End of interrupt */
INTC.EOIR.R = 1;
return 0;
}
rtems_status_code bsp_interrupt_facility_initialize()
{
/* Install exception handler */
if (ppc_exc_set_handler( ASM_EXT_VECTOR, mpc55xx_external_exception_handler)) {
return RTEMS_IO_ERROR;
}
/* Initialize interrupt controller */
/* Software vector mode */
INTC.MCR.B.VTES = 0;
INTC.MCR.B.HVEN = 0;
/* Set current priority to 0 */
INTC.CPR.B.PRI = 0;
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector)
{
if (MPC55XX_IRQ_IS_VALID( vector)) {
return mpc55xx_intc_set_priority( vector, MPC55XX_INTC_DEFAULT_PRIORITY);
} else {
return RTEMS_SUCCESSFUL;
}
}
rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector)
{
if (MPC55XX_IRQ_IS_VALID( vector)) {
return mpc55xx_intc_set_priority( vector, MPC55XX_INTC_DISABLED_PRIORITY);
} else {
return RTEMS_SUCCESSFUL;
}
}
void bsp_interrupt_handler_default( rtems_vector_number vector)
{
/* Do nothing */
}

View File

@@ -0,0 +1,150 @@
/**
* @file
*
* @ingroup mpc55xx_asm
*
* @brief Memory copy and zero functions.
*/
/*
* 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.
*/
#include <libcpu/powerpc-utility.h>
.section ".text"
/**
* @fn int mpc55xx_copy_8( const void *src, void *dest, size_t n)
*
* @brief Copy @a n bytes from @a src to @a dest with 8 byte reads and writes.
*
* The memory areas should not overlap. The addresses @a src and @a dest have
* to be aligned on 8 byte boundaries. The size @a n must be evenly divisible by 8.
* The SPE operations @b evxor, @b evlddx and @b evstddx will be used.
*/
GLOBAL_FUNCTION mpc55xx_copy_8
/* Loop counter = data size / 8 */
srwi. r5, r5, 3
beqlr
mtctr r5
/* Set offset */
evxor r5, r5, r5
copy_data:
evlddx r6, r3, r5
evstddx r6, r4, r5
addi r5, r5, 8
bdnz copy_data
/* Return */
blr
/**
* @fn int mpc55xx_zero_8( void *dest, size_t n)
*
* @brief Zero all @a n bytes starting at @a dest with 8 byte writes.
*
* The address @a dest has to be aligned on 8 byte boundaries. The size @a n
* must be evenly divisible by 8. The SPE operations @b evxor and @b evstddx will be used.
*/
GLOBAL_FUNCTION mpc55xx_zero_8
/* Create zero */
evxor r0, r0, r0
/* Set offset */
evxor r5, r5, r5
/* Loop counter for the first bytes up to 32 bytes */
rlwinm. r9, r4, 29, 30, 31
beq zero_more
mtctr r9
zero_data:
evstddx r0, r3, r5
addi r5, r5, 8
bdnz zero_data
zero_more:
/* More than 32 bytes? */
srwi. r9, r4, 5
beqlr
mtctr r9
/* Set offsets */
addi r6, r5, 8
addi r7, r5, 16
addi r8, r5, 24
zero_big_data:
evstddx r0, r3, r5
addi r5, r5, 32
evstddx r0, r3, r6
addi r6, r6, 32
evstddx r0, r3, r7
addi r7, r7, 32
evstddx r0, r3, r8
addi r8, r8, 32
bdnz zero_big_data
/* Return */
blr
/**
* @fn int mpc55xx_zero_32( void *dest, size_t n)
*
* @brief Zero all @a n bytes starting at @a dest with 32 byte writes.
*
* The address @a dest has to be aligned on 32 byte boundaries. The size @a n
* must be evenly divisible by 32. The function operates with the cache block zero
* operation @b dcbz.
*
* @note The cache has to be enabled for the desired memory area.
*/
GLOBAL_FUNCTION mpc55xx_zero_32
/* Set offset */
xor r5, r5, r5
/* Loop counter for the first bytes up to 128 bytes */
rlwinm. r9, r4, 27, 28, 31
beq zero_more_lines
mtctr r9
zero_line:
dcbz r3, r5
addi r5, r5, 32
bdnz zero_line
zero_more_lines:
/* More than 128 bytes? */
srwi. r9, r4, 7
beqlr
mtctr r9
/* Set offsets */
addi r6, r5, 32
addi r7, r5, 64
addi r8, r5, 96
zero_big_line:
dcbz r3, r5
addi r5, r5, 128
dcbz r3, r6
addi r6, r6, 128
dcbz r3, r7
addi r7, r7, 128
dcbz r3, r8
addi r8, r8, 128
bdnz zero_big_line
/* Return */
blr

View File

@@ -0,0 +1,101 @@
/**
* @file
*
* @ingroup mpc55xx_asm
*
* @brief Flash configuration.
*/
/*
* 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.
*/
#include <libcpu/powerpc-utility.h>
#include <mpc55xx/reg-defs.h>
.section ".text"
/* Optimized flash configurations (Table 13-15 [MPC5567 Microcontroller Reference Manual]) */
.equ FLASH_SETTINGS_RESET, 0xff00
.equ FLASH_SETTINGS_82, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_1 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
.equ FLASH_SETTINGS_102, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_1 | FLASH_BUICR_RWSC_2 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
.equ FLASH_SETTINGS_132, FLASH_BUICR_CPU_PREFTCH | FLASH_BUICR_APC_2 | FLASH_BUICR_RWSC_3 | FLASH_BUICR_WWSC_1 | FLASH_BUICR_DPFEN_3 | FLASH_BUICR_IPFEN_3 | FLASH_BUICR_PFLIM_6 | FLASH_BUICR_BFEN
/**
* @fn void mpc55xx_flash_config()
* @brief Optimized flash configuration.
* @warning Code will be copied and executed on the stack. The stack pointer
* will not be updated, since this function has to work before memory
* initialization.
*/
GLOBAL_FUNCTION mpc55xx_flash_config
mflr r31
/* Flash settings dependent on system clock */
bl mpc55xx_get_system_clock
LWI r4, 82000000
cmpw r3, r4
ble clock_82
LWI r4, 102000000
cmpw r3, r4
ble clock_102
LWI r4, 132000000
cmpw r3, r4
ble clock_132
LWI r30, FLASH_SETTINGS_RESET
b settings_done
clock_82:
LWI r30, FLASH_SETTINGS_82
b settings_done
clock_102:
LWI r30, FLASH_SETTINGS_102
b settings_done
clock_132:
LWI r30, FLASH_SETTINGS_132
b settings_done
settings_done:
/* Copy store code on the stack */
LA r3, store_start
LA r5, store_end
subf r5, r3, r5
subf r4, r5, r1
/* Assert: Proper alignment of destination start */
andi. r6, r4, 0x7
bne twiddle
/* Copy */
bl mpc55xx_copy_8
LA r6, FLASH_BIUCR
/* Execute store code */
mtctr r4
bctrl
mtlr r31
blr
/*
* Store flash settings
*/
.align 3
.set store_start, .
stw r30, 0(r6)
isync
blr
.align 3
.set store_end, .
twiddle:
b twiddle

View File

@@ -0,0 +1,133 @@
/**
* @file
*
* @ingroup mpc55xx_asm
*
* @brief FMPLL setup.
*/
/*
* 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.
*/
#include <libcpu/powerpc-utility.h>
#include <mpc55xx/reg-defs.h>
.section ".text"
/* Timeout for delay in clocks */
.equ FMPLL_TIMEOUT, 6000
/* Reference clock */
.equ FMPLL_REF_CLOCK, 8000000
/* Settings for FMPLL from 12 MHz up to 128 MHz with 8 MHz reference frequency */
.equ FMPLL_128_8_SYNCR_SETTING_0, (FMPLL_SYNCR_PREDIV_0 | FMPLL_SYNCR_MFD_12 | FMPLL_SYNCR_RFD_2 | FMPLL_SYNCR_LOCEN)
.equ FMPLL_128_8_SYNCR_SETTING_1, (FMPLL_SYNCR_PREDIV_0 | FMPLL_SYNCR_MFD_12 | FMPLL_SYNCR_RFD_0 | FMPLL_SYNCR_LOCEN)
.macro DO_SETTING setting
LWI r5, FMPLL_128_8_SYNCR_SETTING_\setting
stw r5, 0(r4)
msync
bl mpc55xx_fmpll_wait_for_lock
.endm
/**
* @fn void mpc55xx_fmpll_reset_config()
* @brief Configure FMPLL after reset.
*
* Sets the system clock from 12 MHz in two steps up to 128 MHz.
*/
GLOBAL_FUNCTION mpc55xx_fmpll_reset_config
/* Save link register */
mflr r3
LA r4, FMPLL_SYNCR
DO_SETTING 0
DO_SETTING 1
/* Enable loss-of-clock and loss-of-lock IRQs */
lwz r5, 0(r4)
LWI r6, FMPLL_SYNCR_LOCIRQ | FMPLL_SYNCR_LOLIRQ
or r5, r5, r6
/* Disable loss-of-clock and loss-of-lock resets */
LWI r6, ~FMPLL_SYNCR_LOCRE & ~FMPLL_SYNCR_LOLRE
and r5, r5, r6
stw r5, 0(r4)
/* Restore link register and return */
mtlr r3
blr
/**
* @fn void mpc55xx_fmpll_wait_for_lock()
* @brief Wait for FMPLL lock.
* @warning If the lock cannot be obtained within some clock cycles a software
* system reset will be initiated.
*/
GLOBAL_FUNCTION mpc55xx_fmpll_wait_for_lock
LWI r6, FMPLL_TIMEOUT
mtctr r6
LWI r7, FMPLL_SYNSR_LOCK
LA r6, FMPLL_SYNSR
fmpll_not_locked:
bdnz fmpll_continue
b mpc55xx_system_reset
fmpll_continue:
lwz r8, 0(r6)
and. r8, r8, r7
beq fmpll_not_locked
blr
/**
* @fn int mpc55xx_get_system_clock()
* @brief Returns the system clock.
*/
GLOBAL_FUNCTION mpc55xx_get_system_clock
LA r4, FMPLL_SYNCR
lwz r3, 0(r4)
/* PREDIV */
rlwinm r5, r3, 4, 29, 31
/* MFD */
rlwinm r6, r3, 9, 27, 31
/* RFD */
rlwinm r7, r3, 13, 29, 31
/* Calculate system clock (Table 11-10 [MPC5567 Microcontroller Reference Manual]) */
LWI r8, FMPLL_REF_CLOCK
addi r5, r5, 1
addi r6, r6, 4
mullw r6, r6, r8
sraw r6, r6, r7
divw r3, r6, r5
blr
/**
* @fn void mpc55xx_system_reset()
* @brief Software system reset.
*/
GLOBAL_FUNCTION mpc55xx_system_reset
LA r8, SIU_SRCR
LWI r9, SIU_SRCR_SSR
stw r9, 0(r8)
twiddle:
b twiddle

View File

@@ -0,0 +1,274 @@
/**
* @file
*
* @brief Source file for timer functions.
*/
/*
* 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.
*/
#include <rtems/bspIo.h>
#include <mpc83xx/mpc83xx.h>
#include <mpc83xx/gtm.h>
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems/status-checks.h>
#define MPC83XX_GTM_CHECK_INDEX( timer) \
if (( timer) < 0 || ( timer) >= MPC83XX_GTM_NUMBER) { \
return RTEMS_INVALID_NUMBER; \
}
#define MPC83XX_GTM_VARIABLES( timer) \
int module = (timer) / 4; \
int module_timer = (timer) % 4; \
int high = module_timer / 2; \
int low = module_timer % 2; \
rtems_interrupt_level level;
#define MPC83XX_GTM_CLOCK_MASK MPC83XX_GTM_CLOCK_EXTERN
static const uint8_t mpc83xx_gmt_interrupt_vector_table [MPC83XX_GTM_NUMBER] = { 90, 78, 84, 72, 91, 79, 85, 73 };
static const uint8_t mpc83xx_gmt_interrupt_priority_table [MPC83XX_GTM_NUMBER] = { 113, 77, 95, 59, 116, 80, 98, 62 };
rtems_status_code mpc83xx_gtm_initialize( int timer, int clock)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
MPC83XX_GTM_VARIABLES( timer);
uint8_t mask = 0xf << (low * 4);
uint8_t flags = 0x3 << (low * 4);
uint16_t reg = 0;
MPC83XX_GTM_CHECK_INDEX( timer);
rtems_interrupt_disable( level);
reg = mpc83xx.gtm [module].gtcfr [high].reg;
mpc83xx.gtm [module].gtcfr [high].reg = (reg & ~mask) | flags;
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] = 0;
rtems_interrupt_enable( level);
sc = mpc83xx_gtm_set_clock( timer, clock);
CHECK_SC( sc, "Set clock");
sc = mpc83xx_gtm_set_value( timer, 0);
CHECK_SC( sc, "Set value");
sc = mpc83xx_gtm_set_reference( timer, 0);
CHECK_SC( sc, "Set reference");
sc = mpc83xx_gtm_set_prescale( timer, 0);
CHECK_SC( sc, "Set prescale");
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
rtems_interrupt_disable( level);
if (enable) {
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] |= 0x0008;
} else {
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] &= ~0x0008;
}
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock)
{
MPC83XX_GTM_VARIABLES( timer);
uint16_t reg = 0;
MPC83XX_GTM_CHECK_INDEX( timer);
if (clock & ~MPC83XX_GTM_CLOCK_MASK) {
return RTEMS_INVALID_CLOCK;
}
rtems_interrupt_disable( level);
reg = mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low];
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] = (reg & ~MPC83XX_GTM_CLOCK_MASK) | clock;
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
*clock = mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] & MPC83XX_GTM_CLOCK_MASK;
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_start( int timer)
{
MPC83XX_GTM_VARIABLES( timer);
uint8_t flags = 0x2 << (low * 4);
MPC83XX_GTM_CHECK_INDEX( timer);
rtems_interrupt_disable( level);
mpc83xx.gtm [module].gtcfr [high].reg &= ~flags;
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_stop( int timer)
{
MPC83XX_GTM_VARIABLES( timer);
uint8_t flags = 0x2 << (low * 4);
MPC83XX_GTM_CHECK_INDEX( timer);
rtems_interrupt_disable( level);
mpc83xx.gtm [module].gtcfr [high].reg |= flags;
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
mpc83xx.gtm [module].gt_tim_regs [high].gtcnr [low] = value;
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
*value = mpc83xx.gtm [module].gt_tim_regs [high].gtcnr [low];
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
mpc83xx.gtm [module].gt_tim_regs [high].gtrfr [low] = reference;
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
reference = mpc83xx.gtm [module].gt_tim_regs [high].gtrfr [low];
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
mpc83xx.gtm [module].gtpsr [module_timer] = prescale;
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
prescale = mpc83xx.gtm [module].gtpsr [module_timer];
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector)
{
MPC83XX_GTM_CHECK_INDEX( timer);
*vector = mpc83xx_gmt_interrupt_vector_table [timer];
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_interrupt_enable( int timer)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
rtems_interrupt_disable( level);
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] |= 0x0010;
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_interrupt_disable( int timer)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
rtems_interrupt_disable( level);
mpc83xx.gtm [module].gt_tim_regs [high].gtmdr [low] &= ~0x0010;
rtems_interrupt_enable( level);
return RTEMS_SUCCESSFUL;
}
rtems_status_code mpc83xx_gtm_interrupt_clear( int timer)
{
MPC83XX_GTM_VARIABLES( timer);
MPC83XX_GTM_CHECK_INDEX( timer);
mpc83xx.gtm [module].gtevr [module_timer] = 0x0002;
return RTEMS_SUCCESSFUL;
}

View File

@@ -619,11 +619,11 @@ static int mpc83xx_i2c_write_bytes
}
rtems_libi2c_bus_ops_t mpc83xx_i2c_ops = {
init: mpc83xx_i2c_init,
send_start: mpc83xx_i2c_send_start,
send_stop: mpc83xx_i2c_send_stop,
send_addr: mpc83xx_i2c_send_addr,
read_bytes: mpc83xx_i2c_read_bytes,
write_bytes: mpc83xx_i2c_write_bytes,
.init = mpc83xx_i2c_init,
.send_start = mpc83xx_i2c_send_start,
.send_stop = mpc83xx_i2c_send_stop,
.send_addr = mpc83xx_i2c_send_addr,
.read_bytes = mpc83xx_i2c_read_bytes,
.write_bytes = mpc83xx_i2c_write_bytes,
};

View File

@@ -0,0 +1,66 @@
/**
* @file
*
* @brief Header file for timer functions.
*/
/*
* 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.
*/
#ifndef LIBBSP_POWERPC_MPC83XX_TIMER_H
#define LIBBSP_POWERPC_MPC83XX_TIMER_H
#include <stdint.h>
#include <stdbool.h>
#include <rtems.h>
#define MPC83XX_GTM_NUMBER 8
#define MPC83XX_GTM_CLOCK_CASCADED 0x0000
#define MPC83XX_GTM_CLOCK_SYSTEM 0x0002
#define MPC83XX_GTM_CLOCK_SYSTEM_SLOW 0x0004
#define MPC83XX_GTM_CLOCK_EXTERN 0x0006
rtems_status_code mpc83xx_gtm_initialize( int timer, int clock);
rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable);
rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock);
rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock);
rtems_status_code mpc83xx_gtm_start( int timer);
rtems_status_code mpc83xx_gtm_stop( int timer);
rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value);
rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value);
rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference);
rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference);
rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale);
rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale);
rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector);
rtems_status_code mpc83xx_gtm_interrupt_enable( int timer);
rtems_status_code mpc83xx_gtm_interrupt_disable( int timer);
rtems_status_code mpc83xx_gtm_interrupt_clear( int timer);
#endif /* LIBBSP_POWERPC_MPC83XX_TIMER_H */

View File

@@ -27,6 +27,7 @@
#include <bsp/irq.h>
#include <mpc83xx/mpc83xx.h>
#include <mpc83xx/tsec.h>
#include <libcpu/spr.h>
#include <rtems/error.h>
#include <rtems/bspIo.h>
#include <rtems/rtems_bsdnet.h>
@@ -43,6 +44,13 @@
#include <netinet/if_ether.h>
#include <stdio.h>
/* System Version Register */
#define SVR 286
SPR_RO( SVR)
/* Processor Version Register */
SPR_RO( PVR)
#define CLREVENT_IN_IRQ
#define TSEC_WATCHDOG_TIMEOUT 5 /* check media every 5 seconds */
@@ -58,6 +66,7 @@ struct mpc83xx_tsec_struct {
* HW links: (filled from rtems_bsdnet_ifconfig
*/
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC register block */
m83xxTSEC_Registers_t *mdio_ptr; /* pointer to TSEC register block which is responsible for MDIO communication */
int irq_num_tx; /* tx irq number */
int irq_num_rx; /* rx irq number */
int irq_num_err; /* error irq number */
@@ -192,7 +201,7 @@ static void mpc83xx_tsec_hwinit
{
m83xxTSEC_Registers_t *reg_ptr = sc->reg_ptr; /* pointer to TSEC registers*/
uint8_t *mac_addr;
int i;
size_t i;
/*
* init ECNTL register
@@ -272,9 +281,9 @@ static void mpc83xx_tsec_hwinit
/*
* init MACCFG2 register
*/
reg_ptr->maccfg2 = ((reg_ptr->maccfg2 & M83xx_TSEC_MACCFG2_IFMODE_MSK)
| M83xx_TSEC_MACCFG2_PRELEN(7)
| M83xx_TSEC_MACCFG2_FULLDUPLEX);
reg_ptr->maccfg2 = (reg_ptr->maccfg2 & M83xx_TSEC_MACCFG2_IFMODE_MSK)
| M83xx_TSEC_MACCFG2_PRELEN( 7)
| M83xx_TSEC_MACCFG2_FULLDUPLEX;
/*
* init station address register
@@ -324,10 +333,19 @@ static void mpc83xx_tsec_mdio_init
| <none> |
\*=========================================================================*/
{
/* Set TSEC registers for MDIO communication */
/*
* FIXME: Not clear if this works for all boards.
* Tested only on MPC8313ERDB.
*/
sc->mdio_ptr = &mpc83xx.tsec [0];
/*
* set clock divider
*/
sc->reg_ptr->miimcfg = 3;
sc->mdio_ptr->miimcfg = 3;
}
/*=========================================================================*\
@@ -352,9 +370,9 @@ int mpc83xx_tsec_mdio_read
\*=========================================================================*/
{
struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC registers */
reg_ptr = sc->reg_ptr;
/* pointer to TSEC registers */
m83xxTSEC_Registers_t *reg_ptr = sc->mdio_ptr;
/*
* make sure we work with a valid phy
@@ -420,9 +438,9 @@ int mpc83xx_tsec_mdio_write
\*=========================================================================*/
{
struct mpc83xx_tsec_struct *sc = uarg;/* control structure */
m83xxTSEC_Registers_t *reg_ptr; /* pointer to TSEC registers */
reg_ptr = sc->reg_ptr;
/* pointer to TSEC registers */
m83xxTSEC_Registers_t *reg_ptr = sc->mdio_ptr;
/*
* make sure we work with a valid phy
@@ -1685,9 +1703,9 @@ int rtems_mpc83xx_tsec_mode_adapt
| 0, if success |
\*=========================================================================*/
{
int result;
int media;
int result = 0;
struct mpc83xx_tsec_struct *sc = ifp->if_softc;
int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default);
#ifdef DEBUG
printf("c");
@@ -1819,6 +1837,8 @@ static int mpc83xx_tsec_driver_attach
struct ifnet *ifp;
int unitNumber;
char *unitName;
uint32_t svr = _read_SVR();
uint32_t pvr = _read_PVR();
/*
* Parse driver name
@@ -1865,10 +1885,30 @@ static int mpc83xx_tsec_driver_attach
/* get pointer to TSEC register block */
sc->reg_ptr = &mpc83xx.tsec[unitNumber-1];
if (svr == 0x80b00010 && pvr == 0x80850010) {
/*
* This is a special case for MPC8313ERDB with silicon revision 1. Look in
* "MPC8313ECE Rev. 3, 3/2008" errata for "IPIC 1".
*/
if (unitNumber == 1) {
sc->irq_num_tx = 37;
sc->irq_num_rx = 36;
sc->irq_num_err = 35;
} else if (unitNumber == 2) {
sc->irq_num_tx = 34;
sc->irq_num_rx = 33;
sc->irq_num_err = 32;
} else {
return 0;
}
} else {
/* get base interrupt number (for Tx irq, Rx=base+1,Err=base+2) */
sc->irq_num_tx = config->irno + 0; /* tx irq number from BSP */
sc->irq_num_rx = config->irno + 1; /* rx irq number from BSP */
sc->irq_num_err = config->irno + 2; /* err irq number from BSP */
}
if (config->irno == 0) {
rtems_panic("TSEC: interupt base number irno not defined");
}
@@ -1878,11 +1918,22 @@ static int mpc83xx_tsec_driver_attach
sc->mdio_info.mdio_r = mpc83xx_tsec_mdio_read;
sc->mdio_info.mdio_w = mpc83xx_tsec_mdio_write;
sc->mdio_info.has_gmii = 1; /* we support gigabit IF */
/*
* XXX: Although most hardware builders will assign the PHY addresses
* like this, this should be more configurable
*/
#ifdef MPC8313ERDB
if (unitNumber == 2) {
sc->phy_default = 4;
} else {
/* TODO */
return 0;
}
#else /* MPC8313ERDB */
sc->phy_default = unitNumber-1;
#endif /* MPC8313ERDB */
/*
* Set up network interface values
*/

View File

@@ -434,9 +434,9 @@ int mpc83xx_spi_read_write_bytes
#endif
if (tbuf == NULL) {
/*
* perform dummy write to read byte
* perform idle char write to read byte
*/
softc_ptr->reg_ptr->spitd = 0;
softc_ptr->reg_ptr->spitd = softc_ptr->idle_char << bit_shift;
}
else {
switch(bytes_per_char) {
@@ -583,6 +583,10 @@ rtems_status_code mpc83xx_spi_set_tfr_mode
mpc83xx_spi_softc_t *softc_ptr = &(((mpc83xx_spi_desc_t *)(bh))->softc);
uint32_t spimode_baud,spimode;
rtems_status_code rc = RTEMS_SUCCESSFUL;
/* Set idle character */
softc_ptr->idle_char = tfr_mode->idle_char;
/*
* FIXME: set proper mode
*/

View File

@@ -35,6 +35,7 @@ typedef struct mpc83xx_spi_softc {
uint32_t base_frq; /* input frq for baud rate divider */
rtems_id irq_sema_id;
uint32_t curr_addr; /* current spi address */
uint32_t idle_char;
uint8_t bytes_per_char;
uint8_t bit_shift;
} mpc83xx_spi_softc_t ;

View File

@@ -210,6 +210,19 @@ $(PROJECT_INCLUDE)/mpc8260/mmu.h: mpc8260/include/mmu.h $(PROJECT_INCLUDE)/mpc82
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc8260/mmu.h
endif
if mpc83xx
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/vectors.h: new-exceptions/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
$(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h: new-exceptions/bspsupport/ppc_exc_bspsupp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
$(PROJECT_INCLUDE)/mpc83xx/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/mpc83xx
@: > $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
@@ -230,4 +243,55 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_i2cdrv.h
$(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h: mpc83xx/spi/mpc83xx_spidrv.h $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/mpc83xx_spidrv.h
$(PROJECT_INCLUDE)/mpc83xx/gtm.h: mpc83xx/include/gtm.h $(PROJECT_INCLUDE)/mpc83xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc83xx/gtm.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc83xx/gtm.h
endif
if mpc55xx
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/vectors.h: new-exceptions/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
$(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h: new-exceptions/bspsupport/ppc_exc_bspsupp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
$(PROJECT_INCLUDE)/bsp/irq.h: mpc55xx/include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
$(PROJECT_INCLUDE)/mpc55xx/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/mpc55xx
@: > $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(PROJECT_INCLUDE)/mpc55xx/regs.h: mpc55xx/include/regs.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/regs.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/regs.h
$(PROJECT_INCLUDE)/mpc55xx/reg-defs.h: mpc55xx/include/reg-defs.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/reg-defs.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/reg-defs.h
$(PROJECT_INCLUDE)/mpc55xx/dspi.h: mpc55xx/include/dspi.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/dspi.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/dspi.h
$(PROJECT_INCLUDE)/mpc55xx/edma.h: mpc55xx/include/edma.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/edma.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/edma.h
$(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h: mpc55xx/include/mpc55xx.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h
$(PROJECT_INCLUDE)/mpc55xx/esci.h: mpc55xx/include/esci.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/esci.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/esci.h
endif

View File

@@ -91,6 +91,17 @@ extern "C" {
#define PPC_LOW_POWER_MODE_NONE 0
#define PPC_LOW_POWER_MODE_STANDARD 1
/**
* @brief For boards with no cache set PPC_CACHE_ALIGNMENT to this value.
*/
#define PPC_NO_CACHE_ALIGNMENT 4
/**
* @brief Used to define PPC_CACHE_ALIGN_POWER for boards with no cache (and
* PPC_NO_CACHE_ALIGNMENT defined).
*/
#define PPC_NO_CACHE_ALIGNMENT_POWER 2
/*
* Figure out all CPU Model Feature Flags based upon compiler
* predefines.
@@ -129,7 +140,7 @@ extern "C" {
#elif defined(mpc555)
/* Copied from mpc505 */
#define PPC_CACHE_ALIGNMENT 16
#define PPC_CACHE_ALIGNMENT PPC_NO_CACHE_ALIGNMENT
/* Added by querbach@realtime.bc.ca */
#define PPC_LOW_POWER_MODE PPC_LOW_POWER_MODE_STANDARD
@@ -145,7 +156,9 @@ extern "C" {
* to get the setting correct.
*/
#define PPC_CACHE_ALIGNMENT 16
#define CPU_MODEL_NAME "PowerPC 505/509"
#define PPC_CACHE_ALIGNMENT PPC_NO_CACHE_ALIGNMENT
#define PPC_I_CACHE 4096
#define PPC_D_CACHE 0
@@ -280,6 +293,8 @@ extern "C" {
#define PPC_CACHE_ALIGN_POWER 4
#elif (PPC_CACHE_ALIGNMENT == 32)
#define PPC_CACHE_ALIGN_POWER 5
#elif (PPC_CACHE_ALIGNMENT == PPC_NO_CACHE_ALIGNMENT)
#define PPC_CACHE_ALIGN_POWER PPC_NO_CACHE_ALIGNMENT_POWER
#else
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
#endif

View File

@@ -31,73 +31,7 @@
#include <rtems/powerpc/registers.h>
#ifdef ASM
#include <rtems/asm.h>
.macro LA reg, addr
lis \reg, (\addr)@h
ori \reg, \reg, (\addr)@l
.endm
.macro LWI reg, value
lis \reg, (\value)@h
ori \reg, \reg, (\value)@l
.endm
.macro LW reg, addr
lis \reg, \addr@ha
lwz \reg, \addr@l(\reg)
.endm
/*
* Tests the bits in reg1 against the bits set in mask. A match is indicated
* by EQ = 0 in CR0. A mismatch is indicated by EQ = 1 in CR0. The register
* reg2 is used to load the mask.
*/
.macro TSTBITS reg1, reg2, mask
LWI \reg2, \mask
and \reg1, \reg1, \reg2
cmplw \reg1, \reg2
.endm
.macro SETBITS reg1, reg2, mask
LWI \reg2, \mask
or \reg1, \reg1, \reg2
.endm
.macro CLRBITS reg1, reg2, mask
LWI \reg2, \mask
andc \reg1, \reg1, \reg2
.endm
.macro GLOBAL_FUNCTION name
.global \name
.type \name, @function
\name:
.endm
/*
* Disables all asynchronous exeptions (interrupts) which may cause a context
* switch.
*/
.macro INTERRUPT_DISABLE level, mask
mfmsr \level
mfspr \mask, sprg0
andc \mask, \level, \mask
mtmsr \mask
.endm
/*
* Restore previous machine state.
*/
.macro INTERRUPT_ENABLE level
mtmsr \level
.endm
#define LINKER_SYMBOL( sym) .extern sym
#else /* ASM */
#ifndef ASM
#include <stdint.h>
@@ -518,6 +452,72 @@ static inline void ppc_set_time_base_64( uint64_t val)
PPC_Set_timebase_register( val);
}
#else /* ASM */
#include <rtems/asm.h>
.macro LA reg, addr
lis \reg, (\addr)@h
ori \reg, \reg, (\addr)@l
.endm
.macro LWI reg, value
lis \reg, (\value)@h
ori \reg, \reg, (\value)@l
.endm
.macro LW reg, addr
lis \reg, \addr@ha
lwz \reg, \addr@l(\reg)
.endm
/*
* Tests the bits in reg1 against the bits set in mask. A match is indicated
* by EQ = 0 in CR0. A mismatch is indicated by EQ = 1 in CR0. The register
* reg2 is used to load the mask.
*/
.macro TSTBITS reg1, reg2, mask
LWI \reg2, \mask
and \reg1, \reg1, \reg2
cmplw \reg1, \reg2
.endm
.macro SETBITS reg1, reg2, mask
LWI \reg2, \mask
or \reg1, \reg1, \reg2
.endm
.macro CLRBITS reg1, reg2, mask
LWI \reg2, \mask
andc \reg1, \reg1, \reg2
.endm
.macro GLOBAL_FUNCTION name
.global \name
.type \name, @function
\name:
.endm
/*
* Disables all asynchronous exeptions (interrupts) which may cause a context
* switch.
*/
.macro INTERRUPT_DISABLE level, mask
mfmsr \level
mfspr \mask, sprg0
andc \mask, \level, \mask
mtmsr \mask
.endm
/*
* Restore previous machine state.
*/
.macro INTERRUPT_ENABLE level
mtmsr \level
.endm
#define LINKER_SYMBOL( sym) .extern sym
#endif /* ASM */
#endif /* LIBCPU_POWERPC_UTILITY_H */

View File

@@ -1,3 +1,11 @@
/**
* @file
*
* #ingroup powerpc_shared
*
* @brief Source file for the Cache Manager PowerPC support.
*/
/*
* Cache Management Support Routines for the MC68040
* Modified for MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
@@ -194,6 +202,67 @@ void _CPU_cache_disable_instruction ( void )
mtspr( 560, r1 );
isync;
}
#else
#warning Most cache functions are not implemented
void _CPU_cache_flush_entire_data()
{
/* Void */
}
void _CPU_cache_invalidate_entire_data()
{
/* Void */
}
void _CPU_cache_freeze_data()
{
/* Void */
}
void _CPU_cache_unfreeze_data()
{
/* Void */
}
void _CPU_cache_enable_data()
{
/* Void */
}
void _CPU_cache_disable_data()
{
/* Void */
}
void _CPU_cache_invalidate_entire_instruction()
{
/* Void */
}
void _CPU_cache_freeze_instruction()
{
/* Void */
}
void _CPU_cache_unfreeze_instruction()
{
/* Void */
}
void _CPU_cache_enable_instruction()
{
/* Void */
}
void _CPU_cache_disable_instruction()
{
/* Void */
}
#endif
void _CPU_cache_invalidate_1_data_line(

View File

@@ -1,38 +1,25 @@
/*
* PowerPC Cache Manager Support
/**
* @file
*
* #ingroup powerpc_shared
*
* @brief Header file for the Cache Manager PowerPC support.
*/
#ifndef __POWERPC_CACHE_h
#define __POWERPC_CACHE_h
/*
* get definitions from the score/powerpc header
* about individual cache alignments
*/
#ifndef LIBCPU_POWERPC_CACHE_H
#define LIBCPU_POWERPC_CACHE_H
#include <rtems/score/powerpc.h>
/*
* CACHE MANAGER: The following functions are CPU-specific.
* They provide the basic implementation for the rtems_* cache
* management routines. If a given function has no meaning for the CPU,
* it does nothing by default.
*
* FIXME: Some functions simply have not been implemented.
*/
#if defined(ppc603) || defined(ppc603e) || defined(mpc8260)
/* And possibly others */
#if defined(PPC_CACHE_ALIGNMENT)
#define CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define CPU_INSTRUCTION_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#endif
/* Provide the CPU defines only if we have a cache */
#if PPC_CACHE_ALIGNMENT != PPC_NO_CACHE_ALIGNMENT
#define CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define CPU_INSTRUCTION_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#endif
#ifdef _OLD_EXCEPTIONS
#include <libcpu/cache.h>
# warning OLD EXCEPTIONS
# include <libcpu/cache.h>
#endif
#endif
/* end of include file */
#endif /* LIBCPU_POWERPC_CACHE_H */

View File

@@ -82,17 +82,29 @@ EXTRA_DIST += rtc/README.ds1643 rtc/README.icm7170 rtc/README.m48t08 \
# i2c
if LIBCHIP
include_libchip_HEADERS += i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h \
include_libchip_HEADERS += i2c/i2c-ds1621.h \
i2c/i2c-2b-eeprom.h \
i2c/spi-memdrv.h \
i2c/spi-flash-m25p40.h i2c/spi-fram-fm25l256.h
i2c/spi-flash-m25p40.h \
i2c/spi-fram-fm25l256.h \
i2c/spi-sd-card.h
noinst_LIBRARIES += libi2cio.a
libi2cio_a_CPPFLAGS = $(AM_CPPFLAGS)
libi2cio_a_SOURCES = i2c/i2c-ds1621.c i2c/i2c-2b-eeprom.c \
i2c/i2c-ds1621.h i2c/i2c-2b-eeprom.h \
i2c/spi-memdrv.c i2c/spi-memdrv.h \
i2c/spi-flash-m25p40.c i2c/spi-flash-m25p40.h \
i2c/spi-fram-fm25l256.c i2c/spi-fram-fm25l256.h
libi2cio_a_SOURCES = i2c/i2c-ds1621.h \
i2c/i2c-2b-eeprom.h \
i2c/spi-memdrv.h \
i2c/spi-flash-m25p40.h \
i2c/spi-fram-fm25l256.h \
i2c/i2c-ds1621.c \
i2c/i2c-2b-eeprom.c \
i2c/spi-memdrv.c \
i2c/spi-flash-m25p40.c \
i2c/spi-fram-fm25l256.c \
i2c/spi-sd-card.c
endif
# serial

View File

@@ -16,17 +16,16 @@
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
*/
#include <stdio.h>
#include <errno.h>
#include <rtems.h>
#include <rtems/libi2c.h>
#include <rtems/libio.h>
#include <rtems/diskdevs.h>
#include <errno.h>
#include <libchip/spi-sd-card.h>
// #define DEBUG
#include <rtems/status-checks.h>
/**

View File

@@ -141,6 +141,10 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/spi-flash-m25p40.h
$(PROJECT_INCLUDE)/libchip/spi-fram-fm25l256.h: i2c/spi-fram-fm25l256.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/spi-fram-fm25l256.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/spi-fram-fm25l256.h
$(PROJECT_INCLUDE)/libchip/spi-sd-card.h: i2c/spi-sd-card.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/spi-sd-card.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/spi-sd-card.h
endif
if LIBCHIP
$(PROJECT_INCLUDE)/libchip/mc68681.h: serial/mc68681.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)

View File

@@ -1,3 +1,11 @@
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* custom/mpc5566evb.cfg, custom/mpc55xx.cfg, custom/mpc8313erdb.cfg:
New files.
* custom/mpc83xx.cfg: More CPU_CFLAGS: -meabi -msdata -fno-common.
More CFLAGS_OPTIMIZE_V: -funit-at-a-time -W -Wno-unused.
2008-07-09 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
* custom/pgh360.cfg:

View File

@@ -19,10 +19,11 @@ RTEMS_BSP_FAMILY=gen83xx
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
#
CPU_CFLAGS = -mcpu=603e -mstrict-align -fno-strict-aliasing\
CPU_CFLAGS = -mcpu=603e -mstrict-align -fno-strict-aliasing \
-meabi -msdata -fno-common \
-D$(RTEMS_BOARD_MODEL) -D$(RTEMS_83XX_DERIVATE)
# optimize flag: typically -O2
CFLAGS_OPTIMIZE_V = -O2 -g -fno-keep-inline-functions
CFLAGS_OPTIMIZE_V = -O2 -g -fno-keep-inline-functions -funit-at-a-time -W -Wno-unused
AM_LDFLAGS+= -qnolinkcmds -T $(RTEMS_LINKCMDS)

View File

@@ -0,0 +1,12 @@
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Configuration file for MPC5566 evaluation board.
#
RTEMS_BOARD_MODEL = MPC5566EVB
include $(RTEMS_ROOT)/make/custom/mpc55xx.cfg

27
make/custom/mpc55xx.cfg Normal file
View File

@@ -0,0 +1,27 @@
##
#
# @file
#
# @ingroup mpc55xx_config
#
# @brief Shared configuration file for the MPC55xx board family.
#
include $(RTEMS_ROOT)/make/custom/default.cfg
RTEMS_CPU = powerpc
RTEMS_CPU_MODEL = mpc55xx
RTEMS_BSP_FAMILY = mpc55xxevb
# FIXME
CPU_CFLAGS = -mcpu=8540 -meabi -msdata -fno-common -funit-at-a-time -D__ppc_generic -mstrict-align -D$(RTEMS_BOARD_MODEL)
CFLAGS_OPTIMIZE_V = -O2 -g -fno-keep-inline-functions
define make-exe
$(LINK.c) $(AM_CFLAGS) $(AM_LDFLAGS)-o $(basename $@).exe $(LINK_OBJS) $(LINK_LIBS)
$(NM) -g -n $(basename $@).exe > $(basename $@).num
$(SIZE) $(basename $@).exe
endef

View File

@@ -0,0 +1,14 @@
##
#
# @file
#
# @ingroup mpc83xx_config
#
# @brief Configuration file for the MPC8313E Reference Design Board.
#
RTEMS_BOARD_MODEL=MPC8313ERDB
RTEMS_83XX_DERIVATE=MPC8349
RTEMS_LINKCMDS=linkcmds.mpc8313erdb
include $(RTEMS_ROOT)/make/custom/gen83xx.cfg