add support for lpc32xx

This commit is contained in:
Thomas Doerfler
2010-01-12 15:03:22 +00:00
parent 29a3d72cd9
commit 39c8fdb416
40 changed files with 3091 additions and 576 deletions

View File

@@ -1,3 +1,10 @@
2010-01-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
* include/lpc-ethernet-config.h: New file.
* network/network.c: Removed file.
* Makefile.am, configure.ac, preinstall.am, include/bsp.h,
include/lpc24xx.h: Changes throughout.
2009-12-15 Sebastian Huber <sebastian.huber@embedded-brains.de>
* clock/clock-config.c: Removed file.

View File

@@ -12,6 +12,7 @@ ACLOCAL_AMFLAGS = -I ../../../../aclocal
include $(top_srcdir)/../../../../automake/compile.am
include_bspdir = $(includedir)/bsp
include_libcpudir = $(includedir)/libcpu
dist_project_lib_DATA = bsp_specs
@@ -44,9 +45,12 @@ include_bsp_HEADERS += include/dma.h
include_bsp_HEADERS += include/i2c.h
include_bsp_HEADERS += include/io.h
include_bsp_HEADERS += include/lpc-clock-config.h
include_bsp_HEADERS += include/lpc-ethernet-config.h
include_HEADERS += ../../shared/include/tm27.h
include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/cache.h
###############################################################################
# Data #
###############################################################################
@@ -72,6 +76,8 @@ EXTRA_DIST += startup/linkcmds.lpc2362
noinst_LIBRARIES += libbsp.a
libbsp_a_SOURCES =
libbsp_a_CPPFLAGS =
libbsp_a_LIBADD =
# Shared
libbsp_a_SOURCES += ../../shared/bootcard.c \
@@ -124,12 +130,18 @@ libbsp_a_SOURCES += ssp/ssp.c
# I2C
libbsp_a_SOURCES += i2c/i2c.c
# Cache
libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c \
../../../libcpu/arm/shared/cache/cache_.h
libbsp_a_CPPFLAGS += -I$(srcdir)/../../../libcpu/arm/shared/include
# Start hooks (FIXME: This is brittle.)
libbsp_a_SOURCES += startup/bspstarthooks.c
bspstarthooks.o: startup/bspstarthooks.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS:-mthumb=) \
-MT bspstarthooks.o -MD -MP -MF $(DEPDIR)/bspstarthooks.Tpo -c -o bspstarthooks.o \
libbsp_a-bspstarthooks.o: startup/bspstarthooks.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbsp_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS:-mthumb=) \
-MT libbsp_a-bspstarthooks.o -MD -MP -MF $(DEPDIR)/libbsp_a-bspstarthooks.Tpo -c -o libbsp_a-bspstarthooks.o \
`test -f 'startup/bspstarthooks.c' || echo '$(srcdir)/'`startup/bspstarthooks.c
$(am__mv) $(DEPDIR)/libbsp_a-bspstarthooks.Tpo $(DEPDIR)/libbsp_a-bspstarthooks.Po
###############################################################################
# Network #
@@ -139,11 +151,11 @@ if HAS_NETWORKING
noinst_PROGRAMS = network.rel
network_rel_SOURCES = network/network.c
network_rel_SOURCES = ../shared/lpc/network/lpc-ethernet.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
libbsp_a_LIBADD += network.rel
endif

View File

@@ -33,7 +33,7 @@ RTEMS_BSPOPTS_HELP([LPC24XX_CCLK],[CPU clock in Hz])
RTEMS_BSPOPTS_SET([LPC24XX_UART_BAUD],[*],[115200U])
RTEMS_BSPOPTS_HELP([LPC24XX_UART_BAUD],[baud for UARTs])
RTEMS_BSPOPTS_SET([LPC24XX_ETHERNET_RMII],[lpc24xx_ncs_*],[1])
RTEMS_BSPOPTS_SET([LPC24XX_ETHERNET_RMII],[*],[])
RTEMS_BSPOPTS_HELP([LPC24XX_ETHERNET_RMII],[enable RMII for Ethernet])
RTEMS_BSPOPTS_SET([LPC24XX_EMC_MICRON],[lpc24xx_ncs_rom_*],[1])

View File

@@ -50,7 +50,7 @@ struct rtems_bsdnet_ifconfig;
/**
* @brief Network driver attach and detach function.
*/
int lpc24xx_eth_attach_detach(
int lpc_eth_attach_detach(
struct rtems_bsdnet_ifconfig *config,
int attaching
);
@@ -58,7 +58,7 @@ int lpc24xx_eth_attach_detach(
/**
* @brief Standard network driver attach and detach function.
*/
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH lpc24xx_eth_attach_detach
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH lpc_eth_attach_detach
/**
* @brief Standard network driver name.

View File

@@ -0,0 +1,82 @@
/**
* @file
*
* @ingroup lpc24xx
*
* @brief Ethernet driver configuration.
*/
/*
* Copyright (c) 2009
* 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_ARM_LPC24XX_LPC_ETHERNET_CONFIG_H
#define LIBBSP_ARM_LPC24XX_LPC_ETHERNET_CONFIG_H
#include <bsp.h>
#include <bsp/io.h>
#include <bsp/lpc24xx.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define LPC_ETH_CONFIG_INTERRUPT LPC24XX_IRQ_ETHERNET
#define LPC_ETH_CONFIG_REG_BASE MAC_BASE_ADDR
#define LPC_ETH_CONFIG_RX_UNIT_COUNT_DEFAULT 16
#define LPC_ETH_CONFIG_RX_UNIT_COUNT_MAX 54
#define LPC_ETH_CONFIG_TX_UNIT_COUNT_DEFAULT 10
#define LPC_ETH_CONFIG_TX_UNIT_COUNT_MAX 10
#define LPC_ETH_CONFIG_UNIT_MULTIPLE 1U
#ifdef LPC24XX_ETHERNET_RMII
#define LPC_ETH_CONFIG_RMII
static void lpc_eth_config_module_enable(void)
{
lpc24xx_module_enable(LPC24XX_MODULE_ETHERNET, LPC24XX_MODULE_PCLK_DEFAULT);
lpc24xx_io_config(LPC24XX_MODULE_ETHERNET, 0);
}
#else
static void lpc_eth_config_module_enable(void)
{
lpc24xx_module_enable(LPC24XX_MODULE_ETHERNET, LPC24XX_MODULE_PCLK_DEFAULT);
lpc24xx_io_config(LPC24XX_MODULE_ETHERNET, 1);
}
#endif
#define LPC24XX_ETH_RAM_BEGIN 0x7fe00000U
#define LPC24XX_ETH_RAM_SIZE (16U * 1024U)
static char *lpc_eth_config_alloc_table_area(size_t size)
{
if (size < LPC24XX_ETH_RAM_SIZE) {
return (char *) LPC24XX_ETH_RAM_BEGIN;
} else {
return NULL;
}
}
static void lpc_eth_config_free_table_area(char *table_area)
{
/* Do nothing */
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBBSP_ARM_LPC24XX_LPC_ETHERNET_CONFIG_H */

View File

@@ -207,29 +207,29 @@
#define FIO4CLR (*(volatile uint32_t *) (FIO_BASE_ADDR + 0x9C))
/* FIOs can be accessed through WORD, HALF-WORD or BYTE. */
#define FIO0DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x01))
#define FIO1DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x21))
#define FIO2DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x41))
#define FIO3DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x61))
#define FIO4DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x81))
#define FIO0DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x00))
#define FIO1DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x20))
#define FIO2DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x40))
#define FIO3DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x60))
#define FIO4DIR0 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x80))
#define FIO0DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x02))
#define FIO1DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x22))
#define FIO2DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x42))
#define FIO3DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x62))
#define FIO4DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x82))
#define FIO0DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x01))
#define FIO1DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x21))
#define FIO2DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x41))
#define FIO3DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x61))
#define FIO4DIR1 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x81))
#define FIO0DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x03))
#define FIO1DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x23))
#define FIO2DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x43))
#define FIO3DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x63))
#define FIO4DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x83))
#define FIO0DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x02))
#define FIO1DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x22))
#define FIO2DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x42))
#define FIO3DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x62))
#define FIO4DIR2 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x82))
#define FIO0DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x04))
#define FIO1DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x24))
#define FIO2DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x44))
#define FIO3DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x64))
#define FIO4DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x84))
#define FIO0DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x03))
#define FIO1DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x23))
#define FIO2DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x43))
#define FIO3DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x63))
#define FIO4DIR3 (*(volatile uint8_t *) (FIO_BASE_ADDR + 0x83))
#define FIO0DIRL (*(volatile uint16_t *) (FIO_BASE_ADDR + 0x00))
#define FIO1DIRL (*(volatile uint16_t *) (FIO_BASE_ADDR + 0x20))
@@ -1837,190 +1837,6 @@ typedef struct {
#define GPDMA_CH_CFG_HALT 0x00040000U
/* Ethernet (MAC) */
typedef struct {
uint32_t start;
uint32_t control;
} lpc24xx_eth_transfer_descriptor;
typedef struct {
uint32_t status;
uint32_t hash_crc;
} lpc24xx_eth_receive_info;
#define ETH_TRANSFER_DESCRIPTOR_SIZE 8
#define ETH_RECEIVE_INFO_SIZE 8
#define ETH_TRANSMIT_STATUS_SIZE 4
/* ETH_RX_CTRL */
#define ETH_RX_CTRL_SIZE_MASK 0x000007ffU
#define GET_ETH_RX_CTRL_SIZE(reg) \
GET_FIELD(reg, ETH_RX_CTRL_SIZE_MASK, 0)
#define SET_ETH_RX_CTRL_SIZE(reg, val) \
SET_FIELD(reg, val, ETH_RX_CTRL_SIZE_MASK, 0)
#define ETH_RX_CTRL_INTERRUPT 0x80000000U
/* ETH_RX_STAT */
#define ETH_RX_STAT_RXSIZE_MASK 0x000007ffU
#define GET_ETH_RX_STAT_RXSIZE(reg) \
GET_FIELD(reg, ETH_RX_STAT_RXSIZE_MASK, 0)
#define SET_ETH_RX_STAT_RXSIZE(reg, val) \
SET_FIELD(reg, val, ETH_RX_STAT_RXSIZE_MASK, 0)
#define ETH_RX_STAT_BYTES 0x00000100U
#define ETH_RX_STAT_CONTROL_FRAME 0x00040000U
#define ETH_RX_STAT_VLAN 0x00080000U
#define ETH_RX_STAT_FAIL_FILTER 0x00100000U
#define ETH_RX_STAT_MULTICAST 0x00200000U
#define ETH_RX_STAT_BROADCAST 0x00400000U
#define ETH_RX_STAT_CRC_ERROR 0x00800000U
#define ETH_RX_STAT_SYMBOL_ERROR 0x01000000U
#define ETH_RX_STAT_LENGTH_ERROR 0x02000000U
#define ETH_RX_STAT_RANGE_ERROR 0x04000000U
#define ETH_RX_STAT_ALIGNMENT_ERROR 0x08000000U
#define ETH_RX_STAT_OVERRUN 0x10000000U
#define ETH_RX_STAT_NO_DESCRIPTOR 0x20000000U
#define ETH_RX_STAT_LAST_FLAG 0x40000000U
#define ETH_RX_STAT_ERROR 0x80000000U
/* ETH_TX_CTRL */
#define ETH_TX_CTRL_SIZE_MASK 0x000007ffU
#define GET_ETH_TX_CTRL_SIZE(reg) \
GET_FIELD(reg, ETH_TX_CTRL_SIZE_MASK, 0)
#define SET_ETH_TX_CTRL_SIZE(reg, val) \
SET_FIELD(reg, val, ETH_TX_CTRL_SIZE_MASK, 0)
#define ETH_TX_CTRL_OVERRIDE 0x04000000U
#define ETH_TX_CTRL_HUGE 0x08000000U
#define ETH_TX_CTRL_PAD 0x10000000U
#define ETH_TX_CTRL_CRC 0x20000000U
#define ETH_TX_CTRL_LAST 0x40000000U
#define ETH_TX_CTRL_INTERRUPT 0x80000000U
/* ETH_TX_STAT */
#define ETH_TX_STAT_COLLISION_COUNT_MASK 0x01e00000U
#define GET_ETH_TX_STAT_COLLISION_COUNT(reg) \
GET_FIELD(reg, ETH_TX_STAT_COLLISION_COUNT_MASK, 21)
#define SET_ETH_TX_STAT_COLLISION_COUNT(reg, val) \
SET_FIELD(reg, val, ETH_TX_STAT_COLLISION_COUNT_MASK, 21)
#define ETH_TX_STAT_DEFER 0x02000000U
#define ETH_TX_STAT_EXCESSIVE_DEFER 0x04000000U
#define ETH_TX_STAT_EXCESSIVE_COLLISION 0x08000000U
#define ETH_TX_STAT_LATE_COLLISION 0x10000000U
#define ETH_TX_STAT_UNDERRUN 0x20000000U
#define ETH_TX_STAT_NO_DESCRIPTOR 0x40000000U
#define ETH_TX_STAT_ERROR 0x80000000U
/* ETH_INT */
#define ETH_INT_RX_OVERRUN 0x00000001U
#define ETH_INT_RX_ERROR 0x00000002U
#define ETH_INT_RX_FINISHED 0x00000004U
#define ETH_INT_RX_DONE 0x00000008U
#define ETH_INT_TX_UNDERRUN 0x00000010U
#define ETH_INT_TX_ERROR 0x00000020U
#define ETH_INT_TX_FINISHED 0x00000040U
#define ETH_INT_TX_DONE 0x00000080U
#define ETH_INT_SOFT 0x00001000U
#define ETH_INT_WAKEUP 0x00002000U
/* ETH_RX_FIL_CTRL */
#define ETH_RX_FIL_CTRL_ACCEPT_UNICAST 0x00000001U
#define ETH_RX_FIL_CTRL_ACCEPT_BROADCAST 0x00000002U
#define ETH_RX_FIL_CTRL_ACCEPT_MULTICAST 0x00000004U
#define ETH_RX_FIL_CTRL_ACCEPT_UNICAST_HASH 0x00000008U
#define ETH_RX_FIL_CTRL_ACCEPT_MULTICAST_HASH 0x00000010U
#define ETH_RX_FIL_CTRL_ACCEPT_PERFECT 0x00000020U
#define ETH_RX_FIL_CTRL_MAGIC_PACKET_WOL 0x00001000U
#define ETH_RX_FIL_CTRL_RX_FILTER_WOL 0x00002000U
/* ETH_CMD */
#define ETH_CMD_RX_ENABLE 0x00000001U
#define ETH_CMD_TX_ENABLE 0x00000002U
#define ETH_CMD_REG_RESET 0x00000008U
#define ETH_CMD_TX_RESET 0x00000010U
#define ETH_CMD_RX_RESET 0x00000020U
#define ETH_CMD_PASS_RUNT_FRAME 0x00000040U
#define ETH_CMD_PASS_RX_FILTER 0X00000080U
#define ETH_CMD_TX_FLOW_CONTROL 0x00000100U
#define ETH_CMD_RMII 0x00000200U
#define ETH_CMD_FULL_DUPLEX 0x00000400U
/* ETH_STAT */
#define ETH_STAT_RX_ACTIVE 0x00000001U
#define ETH_STAT_TX_ACTIVE 0x00000002U
/* AHBCFG */
#define AHBCFG_SCHEDULER_UNIFORM 0x00000001U

View File

@@ -33,6 +33,11 @@ $(PROJECT_INCLUDE)/bsp/$(dirstamp):
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/libcpu/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/libcpu
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
@@ -121,10 +126,18 @@ $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h: include/lpc-clock-config.h $(PROJECT_
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h
$(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h: include/lpc-ethernet-config.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h
$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
$(PROJECT_INCLUDE)/libcpu/cache.h: ../../../libcpu/arm/shared/include/cache.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cache.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cache.h
$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)

View File

@@ -1,3 +1,11 @@
2010-01-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
* include/lpc-ethernet-config.h, include/mmu.h: New files.
* Makefile.am, configure.ac, preinstall.am, include/bsp.h,
include/bspopts.h.in, include/irq.h, include/lpc32xx.h, irq/irq.c,
rtc/rtc-config.c, startup/bspstarthooks.c,
startup/linkcmds.lpc32xx_phycore: Changes throughout.
2009-12-17 Joel Sherrill <joel.sherrill@oarcorp.com>
* include/bspopts.h.in: Regenerated.

View File

@@ -12,6 +12,7 @@ ACLOCAL_AMFLAGS = -I ../../../../aclocal
include $(top_srcdir)/../../../../automake/compile.am
include_bspdir = $(includedir)/bsp
include_libcpudir = $(includedir)/libcpu
dist_project_lib_DATA = bsp_specs
@@ -20,6 +21,7 @@ dist_project_lib_DATA = bsp_specs
###############################################################################
include_HEADERS = include/bsp.h
include_HEADERS += ../../shared/include/tm27.h
nodist_include_HEADERS = ../../shared/include/coverhd.h \
include/bspopts.h
@@ -37,10 +39,13 @@ include_bsp_HEADERS += ../shared/include/start.h
include_bsp_HEADERS += ../shared/lpc/include/lpc-timer.h
include_bsp_HEADERS += include/irq-config.h
include_bsp_HEADERS += include/irq.h
include_bsp_HEADERS += include/mmu.h
include_bsp_HEADERS += include/lpc32xx.h
include_bsp_HEADERS += include/lpc-clock-config.h
include_bsp_HEADERS += include/lpc-ethernet-config.h
include_HEADERS += ../../shared/include/tm27.h
include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/cache.h \
../../../libcpu/arm/shared/include/arm-cp15.h
###############################################################################
# Data #
@@ -64,6 +69,8 @@ EXTRA_DIST = startup/linkcmds.lpc32xx_phycore
noinst_LIBRARIES += libbsp.a
libbsp_a_SOURCES =
libbsp_a_CPPFLAGS =
libbsp_a_LIBADD =
# Shared
libbsp_a_SOURCES += ../../shared/bootcard.c \
@@ -109,12 +116,18 @@ libbsp_a_SOURCES += misc/timer.c
# I2C
# Cache
libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c \
../../../libcpu/arm/shared/cache/cache_.h
libbsp_a_CPPFLAGS += -I$(srcdir)/../../../libcpu/arm/shared/include
# Start hooks (FIXME: This is brittle.)
libbsp_a_SOURCES += startup/bspstarthooks.c
bspstarthooks.o: startup/bspstarthooks.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS:-mthumb=) \
-MT bspstarthooks.o -MD -MP -MF $(DEPDIR)/bspstarthooks.Tpo -c -o bspstarthooks.o \
libbsp_a-bspstarthooks.o: startup/bspstarthooks.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbsp_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS:-mthumb=) \
-MT libbsp_a-bspstarthooks.o -MD -MP -MF $(DEPDIR)/libbsp_a-bspstarthooks.Tpo -c -o libbsp_a-bspstarthooks.o \
`test -f 'startup/bspstarthooks.c' || echo '$(srcdir)/'`startup/bspstarthooks.c
$(am__mv) $(DEPDIR)/libbsp_a-bspstarthooks.Tpo $(DEPDIR)/libbsp_a-bspstarthooks.Po
###############################################################################
# Network #
@@ -122,13 +135,13 @@ bspstarthooks.o: startup/bspstarthooks.c
if HAS_NETWORKING
# noinst_PROGRAMS = network.rel
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)
network_rel_SOURCES = ../shared/lpc/network/lpc-ethernet.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
libbsp_a_LIBADD += network.rel
endif

View File

@@ -33,6 +33,9 @@ RTEMS_BSPOPTS_HELP([LPC32XX_ARM_CLK],[ARM clock in Hz])
RTEMS_BSPOPTS_SET([LPC32XX_HCLK],[*],[104000000U])
RTEMS_BSPOPTS_HELP([LPC32XX_HCLK],[AHB bus clock in Hz])
RTEMS_BSPOPTS_SET([LPC32XX_ETHERNET_RMII],[*],[1])
RTEMS_BSPOPTS_HELP([LPC32XX_ETHERNET_RMII],[enable RMII for Ethernet])
RTEMS_BSPOPTS_SET([LPC32XX_PERIPH_CLK],[*],[13000000U])
RTEMS_BSPOPTS_HELP([LPC32XX_PERIPH_CLK],[peripheral clock in Hz])

View File

@@ -51,7 +51,7 @@ struct rtems_bsdnet_ifconfig;
/**
* @brief Network driver attach and detach function.
*/
int lpc32xx_eth_attach_detach(
int lpc_eth_attach_detach(
struct rtems_bsdnet_ifconfig *config,
int attaching
);
@@ -59,7 +59,7 @@ int lpc32xx_eth_attach_detach(
/**
* @brief Standard network driver attach and detach function.
*/
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH lpc32xx_eth_attach_detach
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH lpc_eth_attach_detach
/**
* @brief Standard network driver name.

View File

@@ -33,6 +33,9 @@
/* clock mode configuration for UARTs */
#undef LPC32XX_CONFIG_UART_CLKMODE
/* enable RMII for Ethernet */
#undef LPC32XX_ETHERNET_RMII
/* AHB bus clock in Hz */
#undef LPC32XX_HCLK

View File

@@ -158,6 +158,8 @@ void lpc32xx_irq_set_activation_type(rtems_vector_number vector, lpc32xx_irq_act
lpc32xx_irq_activation_type lpc32xx_irq_get_activation_type(rtems_vector_number vector);
void lpc32xx_set_exception_handler(Arm_symbolic_exception_name exception, void (*handler)(void));
/** @} */
#endif /* ASM */

View File

@@ -0,0 +1,81 @@
/**
* @file
*
* @ingroup lpc32xx
*
* @brief Ethernet driver configuration.
*/
/*
* Copyright (c) 2009
* 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_ARM_LPC32XX_LPC_ETHERNET_CONFIG_H
#define LIBBSP_ARM_LPC32XX_LPC_ETHERNET_CONFIG_H
#include <stdlib.h>
#include <limits.h>
#include <rtems.h>
#include <rtems/malloc.h>
#include <bsp.h>
#include <bsp/lpc32xx.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define LPC_ETH_CONFIG_INTERRUPT LPC32XX_IRQ_ETHERNET
#define LPC_ETH_CONFIG_REG_BASE LPC32XX_BASE_ETHERNET
#define LPC_ETH_CONFIG_RX_UNIT_COUNT_DEFAULT 16
#define LPC_ETH_CONFIG_RX_UNIT_COUNT_MAX INT_MAX
#define LPC_ETH_CONFIG_TX_UNIT_COUNT_DEFAULT 32
#define LPC_ETH_CONFIG_TX_UNIT_COUNT_MAX INT_MAX
#define LPC_ETH_CONFIG_UNIT_MULTIPLE 8U
#ifdef LPC32XX_ETHERNET_RMII
#define LPC_ETH_CONFIG_RMII
static void lpc_eth_config_module_enable(void)
{
LPC32XX_MAC_CLK_CTRL = 0x1f;
}
#else
static void lpc_eth_config_module_enable(void)
{
LPC32XX_MAC_CLK_CTRL = 0x0f;
}
#endif
#define LPC_ETH_CONFIG_USE_TRANSMIT_DMA
static char *lpc_eth_config_alloc_table_area(size_t size)
{
return rtems_heap_allocate_aligned_with_boundary(size, 32, 0);
}
static void lpc_eth_config_free_table_area(char *table_area)
{
/* FIXME: Type */
free(table_area, (int) 0xdeadbeef);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBBSP_ARM_LPC32XX_LPC_ETHERNET_CONFIG_H */

View File

@@ -90,5 +90,6 @@
#define LPC32XX_UART_CLKMODE (*(volatile uint32_t *) 0x40054004)
#define LPC32XX_UART_LOOP (*(volatile uint32_t *) 0x40054008)
#define LPC32XX_SW_INT (*(volatile uint32_t *) 0x400040a8)
#define LPC32XX_MAC_CLK_CTRL (*(volatile uint32_t *) 0x40004090)
#endif /* LIBBSP_ARM_LPC32XX_LPC32XX_H */

View File

@@ -23,6 +23,8 @@
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/lpc32xx.h>
#include <bsp/linker-symbols.h>
#include <bsp/mmu.h>
/*
* Mask out SIC 1 and 2 IRQ request. There is no need to mask out the FIQ,
@@ -125,15 +127,15 @@ static inline void lpc32xx_irq_clear_bit_in_field(unsigned index, lpc32xx_irq_fi
static inline unsigned lpc32xx_irq_get_index(uint32_t val)
{
uint32_t reg;
ARM_SWITCH_REGISTERS;
asm volatile (
THUMB_TO_ARM
"clz %1, %1\n"
"rsb %1, %1, #31\n"
ARM_TO_THUMB
: "=&r" (reg), "=r" (val)
: "1" (val)
ARM_SWITCH_TO_ARM
"clz %[val], %[val]\n"
"rsb %[val], %[val], #31\n"
ARM_SWITCH_BACK
: [val] "=r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
: "[val]" (val)
);
return val;
@@ -304,6 +306,21 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
return RTEMS_SUCCESSFUL;
}
void lpc32xx_set_exception_handler(
Arm_symbolic_exception_name exception,
void (*handler)(void)
)
{
if ((unsigned) exception < MAX_EXCEPTIONS) {
uint32_t *table = (uint32_t *) bsp_section_vector_begin + MAX_EXCEPTIONS;
table [exception] = (uint32_t) handler;
rtems_cache_flush_multiple_data_lines(NULL, 64);
rtems_cache_invalidate_multiple_data_lines(NULL, 64);
}
}
rtems_status_code bsp_interrupt_facility_initialize(void)
{
size_t i = 0;
@@ -341,7 +358,7 @@ rtems_status_code bsp_interrupt_facility_initialize(void)
lpc32xx_sic_1->atr = 0x26000;
lpc32xx_sic_2->atr = 0x0;
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, arm_exc_interrupt, NULL);
lpc32xx_set_exception_handler(ARM_EXCEPTION_IRQ, arm_exc_interrupt);
return RTEMS_SUCCESSFUL;
}
@@ -350,23 +367,3 @@ void bsp_interrupt_handler_default(rtems_vector_number vector)
{
printk("spurious interrupt: %u\n", vector);
}
static void lpc32xx_irq_dump_controller(volatile lpc32xx_irq_controller *controller)
{
printk(
"er %08x\nrsr %08x\nsr %08x\napr %08x\natr %08x\nitr %08x\n",
controller->er,
controller->rsr,
controller->sr,
controller->apr,
controller->atr,
controller->itr
);
}
void lpc32xx_irq_dump(void)
{
lpc32xx_irq_dump_controller(lpc32xx_mic);
lpc32xx_irq_dump_controller(lpc32xx_sic_1);
lpc32xx_irq_dump_controller(lpc32xx_sic_2);
}

View File

@@ -33,6 +33,11 @@ $(PROJECT_INCLUDE)/bsp/$(dirstamp):
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_INCLUDE)/libcpu/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/libcpu
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
@@ -41,6 +46,10 @@ $(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
@@ -93,6 +102,10 @@ $(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/mmu.h: include/mmu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/mmu.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/mmu.h
$(PROJECT_INCLUDE)/bsp/lpc32xx.h: include/lpc32xx.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc32xx.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc32xx.h
@@ -101,9 +114,17 @@ $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h: include/lpc-clock-config.h $(PROJECT_
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h
$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
$(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h: include/lpc-ethernet-config.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-ethernet-config.h
$(PROJECT_INCLUDE)/libcpu/cache.h: ../../../libcpu/arm/shared/include/cache.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cache.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cache.h
$(PROJECT_INCLUDE)/libcpu/arm-cp15.h: ../../../libcpu/arm/shared/include/arm-cp15.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)

View File

@@ -21,44 +21,108 @@
#include <libchip/rtc.h>
#include <bsp.h>
#include <bsp/lpc32xx.h>
#define LPC32XX_RTC_COUNT 1
#define LPC32XX_RTC_COUNT 1U
#define LPC32XX_RTC_COUNTER_DELTA 0xfffffffeU
#define LPC32XX_RTC_KEY 0xb5c13f27U
#define LPC32XX_RTC_CTRL_FORCE_ONSW (1U << 7)
#define LPC32XX_RTC_CTRL_STOP (1U << 6)
#define LPC32XX_RTC_CTRL_RESET (1U << 4)
#define LPC32XX_RTC_CTRL_MATCH_1_ONSW (1U << 3)
#define LPC32XX_RTC_CTRL_MATCH_0_ONSW (1U << 2)
#define LPC32XX_RTC_CTRL_MATCH_1_INTR (1U << 1)
#define LPC32XX_RTC_CTRL_MATCH_0_INTR (1U << 0)
typedef struct {
uint32_t ucount;
uint32_t dcount;
uint32_t match0;
uint32_t match1;
uint32_t ctrl;
uint32_t intstat;
uint32_t key;
uint32_t sram [32];
} lpc32xx_rtc_registers;
static volatile lpc32xx_rtc_registers *const lpc32xx_rtc =
(volatile lpc32xx_rtc_registers *) LPC32XX_BASE_RTC;
static void lpc32xx_rtc_set(uint32_t val)
{
unsigned i = LPC32XX_ARM_CLK / LPC32XX_OSCILLATOR_RTC;
lpc32xx_rtc->ctrl |= LPC32XX_RTC_CTRL_STOP;
lpc32xx_rtc->ucount = val;
lpc32xx_rtc->dcount = LPC32XX_RTC_COUNTER_DELTA - val;
lpc32xx_rtc->ctrl &= ~LPC32XX_RTC_CTRL_STOP;
/* It needs some time before we can read the values back */
while (i != 0) {
asm volatile ("nop");
--i;
}
}
static void lpc32xx_rtc_reset(void)
{
lpc32xx_rtc->ctrl = LPC32XX_RTC_CTRL_RESET;
lpc32xx_rtc->ctrl = 0;
lpc32xx_rtc->key = LPC32XX_RTC_KEY;
lpc32xx_rtc_set(0);
}
static void lpc32xx_rtc_initialize(int minor)
{
/* TODO */
uint32_t up_first = 0;
uint32_t up_second = 0;
uint32_t down_first = 0;
uint32_t down_second = 0;
if (lpc32xx_rtc->key != LPC32XX_RTC_KEY) {
lpc32xx_rtc_reset();
}
do {
up_first = lpc32xx_rtc->ucount;
down_first = lpc32xx_rtc->dcount;
up_second = lpc32xx_rtc->ucount;
down_second = lpc32xx_rtc->dcount;
} while (up_first != up_second || down_first != down_second);
if (up_first + down_first != LPC32XX_RTC_COUNTER_DELTA) {
lpc32xx_rtc_reset();
}
}
static int lpc32xx_rtc_get_time(int minor, rtems_time_of_day *tod)
{
/* TODO */
struct timeval now = {
.tv_sec = lpc32xx_rtc->ucount,
.tv_usec = 0
};
struct tm time;
#if 0
tod->ticks = 0;
tod->second = RTC_SEC;
tod->minute = RTC_MIN;
tod->hour = RTC_HOUR;
tod->day = RTC_DOM;
tod->month = RTC_MONTH;
tod->year = RTC_YEAR;
#endif
gmtime_r(&now.tv_sec, &time);
return 0;
tod->year = time.tm_year + 1900;
tod->month = time.tm_mon + 1;
tod->day = time.tm_mday;
tod->hour = time.tm_hour;
tod->minute = time.tm_min;
tod->second = time.tm_sec;
tod->ticks = 0;
return RTEMS_SUCCESSFUL;
}
static int lpc32xx_rtc_set_time(int minor, const rtems_time_of_day *tod)
{
/* TODO */
#if 0
RTC_SEC = tod->second;
RTC_MIN = tod->minute;
RTC_HOUR = tod->hour;
RTC_DOM = tod->day;
RTC_MONTH = tod->month;
RTC_YEAR = tod->year;
#endif
lpc32xx_rtc_set(_TOD_To_seconds(tod));
return 0;
}

View File

@@ -24,9 +24,11 @@
#include <bspopts.h>
#include <bsp/start.h>
#include <bsp/lpc32xx.h>
#include <bsp/mmu.h>
#include <bsp/linker-symbols.h>
#define BSP_START_SECTION __attribute__((section(".bsp_start")))
#define BSP_START_DATA_SECTION __attribute__((section(".bsp_start_data")))
static void BSP_START_SECTION lpc32xx_clear_bss(void)
{
@@ -40,9 +42,125 @@ static void BSP_START_SECTION lpc32xx_clear_bss(void)
}
}
typedef struct {
uint32_t begin;
uint32_t end;
uint32_t flags;
} lpc32xx_mmu_config;
static const BSP_START_DATA_SECTION lpc32xx_mmu_config
lpc32xx_mmu_config_table [] = {
{
.begin = (uint32_t) bsp_section_start_begin,
.end = (uint32_t) bsp_section_start_end,
.flags = LPC32XX_MMU_READ_WRITE_CACHED
}, {
.begin = (uint32_t) bsp_section_vector_begin,
.end = (uint32_t) bsp_section_vector_end,
.flags = LPC32XX_MMU_READ_WRITE_CACHED
}, {
.begin = (uint32_t) bsp_section_text_begin,
.end = (uint32_t) bsp_section_text_end,
.flags = LPC32XX_MMU_READ_WRITE_CACHED
}, {
.begin = (uint32_t) bsp_section_rodata_begin,
.end = (uint32_t) bsp_section_rodata_end,
.flags = LPC32XX_MMU_READ_ONLY_CACHED
}, {
.begin = (uint32_t) bsp_section_data_begin,
.end = (uint32_t) bsp_section_data_end,
.flags = LPC32XX_MMU_READ_WRITE
}, {
.begin = (uint32_t) bsp_section_fast_begin,
.end = (uint32_t) bsp_section_fast_end,
.flags = LPC32XX_MMU_READ_ONLY_CACHED
}, {
.begin = (uint32_t) bsp_section_bss_begin,
.end = (uint32_t) bsp_section_bss_end,
.flags = LPC32XX_MMU_READ_WRITE
}, {
.begin = (uint32_t) bsp_section_work_begin,
.end = (uint32_t) bsp_section_work_end,
.flags = LPC32XX_MMU_READ_WRITE_CACHED
}, {
.begin = (uint32_t) bsp_section_stack_begin,
.end = (uint32_t) bsp_section_stack_end,
.flags = LPC32XX_MMU_READ_WRITE_CACHED
}, {
.begin = 0x0U,
.end = 0x100000U,
.flags = LPC32XX_MMU_READ_ONLY_CACHED
}, {
.begin = 0x20000000U,
.end = 0x200c0000U,
.flags = LPC32XX_MMU_READ_WRITE
}, {
.begin = 0x30000000U,
.end = 0x32000000U,
.flags = LPC32XX_MMU_READ_WRITE
}, {
.begin = 0x40000000U,
.end = 0x40100000U,
.flags = LPC32XX_MMU_READ_WRITE
}
};
static void BSP_START_SECTION lpc32xx_mmu_set_entries(
uint32_t *ttb,
const lpc32xx_mmu_config *config
)
{
uint32_t i = ARM_MMU_SECT_GET_INDEX(config->begin);
uint32_t iend = ARM_MMU_SECT_GET_INDEX(ARM_MMU_SECT_MVA_ALIGN_UP(config->end));
if (config->begin != config->end) {
while (i < iend) {
ttb [i] = (i << ARM_MMU_SECT_BASE_SHIFT) | config->flags;
++i;
}
}
}
static void BSP_START_SECTION lpc32xx_mmu_and_cache_setup(void)
{
uint32_t const dac =
ARM_CP15_DAC_DOMAIN(LPC32XX_MMU_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT);
uint32_t ctrl = 0;
uint32_t *const ttb = (uint32_t *) bsp_section_work_end;
size_t const config_entry_count =
sizeof(lpc32xx_mmu_config_table) / sizeof(lpc32xx_mmu_config_table [0]);
size_t i = 0;
/* Disable MMU and cache, basic settings */
ctrl = arm_cp15_get_control();
ctrl &= ~(ARM_CP15_CTRL_I | ARM_CP15_CTRL_R | ARM_CP15_CTRL_C
| ARM_CP15_CTRL_V | ARM_CP15_CTRL_M);
ctrl |= ARM_CP15_CTRL_S | ARM_CP15_CTRL_A;
arm_cp15_set_control(ctrl);
arm_cp15_cache_invalidate();
arm_cp15_tlb_invalidate();
arm_cp15_set_domain_access_control(dac);
arm_cp15_set_translation_table_base(ttb);
/* Initialize translation table with invalid entries */
for (i = 0; i < ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT; ++i) {
ttb [i] = 0;
}
for (i = 0; i < config_entry_count; ++i) {
lpc32xx_mmu_set_entries(ttb, &lpc32xx_mmu_config_table [i]);
}
/* Enable MMU and cache */
ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M;
arm_cp15_set_control(ctrl);
}
void BSP_START_SECTION bsp_start_hook_0(void)
{
/* TODO */
lpc32xx_mmu_and_cache_setup();
}
void BSP_START_SECTION bsp_start_hook_1(void)
@@ -50,6 +168,7 @@ void BSP_START_SECTION bsp_start_hook_1(void)
/* TODO */
/* Copy .text section */
arm_cp15_instruction_cache_invalidate();
bsp_start_memcpy_arm(
(int *) bsp_section_text_begin,
(const int *) bsp_section_text_load_begin,
@@ -57,6 +176,7 @@ void BSP_START_SECTION bsp_start_hook_1(void)
);
/* Copy .rodata section */
arm_cp15_instruction_cache_invalidate();
bsp_start_memcpy_arm(
(int *) bsp_section_rodata_begin,
(const int *) bsp_section_rodata_load_begin,
@@ -64,6 +184,7 @@ void BSP_START_SECTION bsp_start_hook_1(void)
);
/* Copy .data section */
arm_cp15_instruction_cache_invalidate();
bsp_start_memcpy_arm(
(int *) bsp_section_data_begin,
(const int *) bsp_section_data_load_begin,
@@ -71,6 +192,7 @@ void BSP_START_SECTION bsp_start_hook_1(void)
);
/* Copy .fast section */
arm_cp15_instruction_cache_invalidate();
bsp_start_memcpy_arm(
(int *) bsp_section_fast_begin,
(const int *) bsp_section_fast_load_begin,

View File

@@ -36,7 +36,7 @@
MEMORY {
RAM_INT (AIW) : ORIGIN = 0x08000000, LENGTH = 256k
RAM_EXT (AIW) : ORIGIN = 0x80000000, LENGTH = 64M /* SDRAM on DYCS0 */
RAM_EXT (AIW) : ORIGIN = 0x80000000, LENGTH = 64M - 16k /* SDRAM on DYCS0 */
ROM_EXT (RX) : ORIGIN = 0xe0000000, LENGTH = 2M /* NOR flash on CS0 */
NIRVANA : ORIGIN = 0, LENGTH = 0
}
@@ -56,5 +56,8 @@ REGION_ALIAS ("REGION_WORK", RAM_EXT);
REGION_ALIAS ("REGION_STACK", RAM_INT);
bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1M;
INCLUDE linkcmds.base

View File

@@ -63,7 +63,7 @@ char *_print_full_context_mode2txt[0x20]={
void _print_full_context(uint32_t spsr)
{
char *mode;
uint32_t prev_sp,prev_lr,cpsr,tmp;
uint32_t prev_sp,prev_lr,cpsr,arm_switch_reg;
int i;
printk("active thread thread 0x%08x\n", _Thread_Executing->Object.id);
@@ -71,14 +71,16 @@ void _print_full_context(uint32_t spsr)
mode=_print_full_context_mode2txt[spsr&0x1f];
if(!mode) mode="unknown";
asm volatile (" MRS %[cpsr], cpsr \n"
" ORR %[tmp], %[spsr], #0xc0 \n"
" MSR cpsr_c, %[tmp] \n"
asm volatile (ARM_SWITCH_TO_ARM
" MRS %[cpsr], cpsr \n"
" ORR %[arm_switch_reg], %[spsr], #0xc0 \n"
" MSR cpsr_c, %[arm_switch_reg] \n"
" MOV %[prev_sp], sp \n"
" MOV %[prev_lr], lr \n"
" MSR cpsr_c, %[cpsr] \n"
: [prev_sp] "=&r" (prev_sp), [prev_lr] "=&r" (prev_lr),
[cpsr] "=&r" (cpsr), [tmp] "=&r" (tmp)
ARM_SWITCH_BACK
: [arm_switch_reg] "=&r" (arm_switch_reg), [prev_sp] "=&r" (prev_sp), [prev_lr] "=&r" (prev_lr),
[cpsr] "=&r" (cpsr)
: [spsr] "r" (spsr)
: "cc");

View File

@@ -56,7 +56,7 @@ char *_print_full_context_mode2txt[0x10]={
void _print_full_context(uint32_t spsr)
{
char *mode;
uint32_t prev_sp,prev_lr,cpsr,tmp;
uint32_t prev_sp,prev_lr,cpsr,arm_switch_reg;
int i, j;
printk("active thread thread 0x%08x\n", _Thread_Executing->Object.id);
@@ -65,16 +65,16 @@ void _print_full_context(uint32_t spsr)
if(!mode) mode="unknown";
asm volatile (
THUMB_TO_ARM
ARM_SWITCH_TO_ARM
"mrs %[cpsr], cpsr\n"
"orr %[tmp], %[spsr], #0xc0\n"
"msr cpsr_c, %[tmp]\n"
"orr %[arm_switch_reg], %[spsr], #0xc0\n"
"msr cpsr_c, %[arm_switch_reg]\n"
"mov %[prev_sp], sp\n"
"mov %[prev_lr], lr\n"
"msr cpsr_c, %[cpsr]\n"
ARM_TO_THUMB
ARM_SWITCH_BACK
: [prev_sp] "=&r" (prev_sp), [prev_lr] "=&r" (prev_lr),
[cpsr] "=&r" (cpsr), [tmp] "=&r" (tmp)
[cpsr] "=&r" (cpsr), [arm_switch_reg] "=&r" (arm_switch_reg)
: [spsr] "r" (spsr)
: "cc"
);

View File

@@ -54,9 +54,9 @@ LINKER_SYMBOL(bsp_stack_abt_begin)
LINKER_SYMBOL(bsp_stack_abt_end)
LINKER_SYMBOL(bsp_stack_abt_size)
LINKER_SYMBOL(bsp_stack_undef_begin)
LINKER_SYMBOL(bsp_stack_undef_end)
LINKER_SYMBOL(bsp_stack_undef_size)
LINKER_SYMBOL(bsp_stack_und_begin)
LINKER_SYMBOL(bsp_stack_und_end)
LINKER_SYMBOL(bsp_stack_und_size)
LINKER_SYMBOL(bsp_stack_svc_begin)
LINKER_SYMBOL(bsp_stack_svc_end)

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
*/
#include <rtems/asm.h>
#include <rtems/score/cpu.h>
#include <bspopts.h>
#include <bsp/linker-symbols.h>
@@ -33,19 +34,6 @@
.globl start
.globl bsp_start_memcpy
/* Program Status Register definitions */
.equ PSR_MODE_USR, 0x10
.equ PSR_MODE_FIQ, 0x11
.equ PSR_MODE_IRQ, 0x12
.equ PSR_MODE_SVC, 0x13
.equ PSR_MODE_ABT, 0x17
.equ PSR_MODE_UNDEF, 0x1b
.equ PSR_MODE_SYS, 0x1f
.equ PSR_I, 0x80
.equ PSR_F, 0x40
.equ PSR_T, 0x20
.section ".bsp_start", "ax"
.arm
@@ -117,33 +105,33 @@ start:
/*
* Set SVC mode, disable interrupts and enable ARM instructions.
*/
mov r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
mov r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
/* Initialize stack pointer registers for the various modes */
/* Enter IRQ mode and set up the IRQ stack pointer */
mov r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)
mov r0, #(ARM_PSR_M_IRQ | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_irq_end
/* Enter FIQ mode and set up the FIQ stack pointer */
mov r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)
mov r0, #(ARM_PSR_M_FIQ | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_fiq_end
/* Enter ABT mode and set up the ABT stack pointer */
mov r0, #(PSR_MODE_ABT | PSR_I | PSR_F)
mov r0, #(ARM_PSR_M_ABT | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_abt_end
/* Enter UNDEF mode and set up the UNDEF stack pointer */
mov r0, #(PSR_MODE_UNDEF | PSR_I | PSR_F)
/* Enter UND mode and set up the UND stack pointer */
mov r0, #(ARM_PSR_M_UND | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_undef_end
ldr sp, =bsp_stack_und_end
/* Enter SVC mode and set up the SVC stack pointer */
mov r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
mov r0, #(ARM_PSR_M_SVC | ARM_PSR_I | ARM_PSR_F)
msr cpsr, r0
ldr sp, =bsp_stack_svc_end
@@ -178,32 +166,16 @@ bsp_start_hook_0_done:
/* Branch to start hook 1 */
bl bsp_start_hook_1
SWITCH_FROM_ARM_TO_THUMB r0
/* Branch to boot card */
mov r0, #0
#ifdef __thumb__
ldr r3, =boot_card
mov lr, pc
bx r3
.thumb
bx pc
nop
.arm
#else
bl boot_card
#endif
/* Branch to reset function */
#ifdef __thumb__
ldr r3, =bsp_reset
mov lr, pc
bx r3
.thumb
bx pc
nop
.arm
#else
bl bsp_reset
#endif
SWITCH_FROM_THUMB_TO_ARM
/* Spin forever */

View File

@@ -25,16 +25,23 @@ OUTPUT_ARCH (arm)
ENTRY (start)
/*
* BSP: Global symbols
* BSP: Global symbols that may be defined externally
*/
bsp_section_align = 32;
bsp_stack_align = DEFINED (bsp_stack_align) ? bsp_stack_align : 4;
bsp_stack_align = 4;
bsp_section_align = DEFINED (bsp_section_align) ? bsp_section_align : 32;
/*
* BSP: Symbols that may be defined externally
*/
bsp_section_start_end_align = DEFINED (bsp_section_start_end_align) ? bsp_section_start_end_align : bsp_section_align;
bsp_section_vector_end_align = DEFINED (bsp_section_vector_end_align) ? bsp_section_vector_end_align : bsp_section_align;
bsp_section_text_end_align = DEFINED (bsp_section_text_end_align) ? bsp_section_text_end_align : bsp_section_align;
bsp_section_rodata_end_align = DEFINED (bsp_section_rodata_end_align) ? bsp_section_rodata_end_align : bsp_section_align;
bsp_section_data_end_align = DEFINED (bsp_section_data_end_align) ? bsp_section_data_end_align : bsp_section_align;
bsp_section_fast_end_align = DEFINED (bsp_section_fast_end_align) ? bsp_section_fast_end_align : bsp_section_align;
bsp_section_bss_end_align = DEFINED (bsp_section_bss_end_align) ? bsp_section_bss_end_align : bsp_section_align;
bsp_section_vbarrier_align = DEFINED (bsp_section_vbarrier_align) ? bsp_section_vbarrier_align : 1;
bsp_section_robarrier_align = DEFINED (bsp_section_robarrier_align) ? bsp_section_robarrier_align : 1;
bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 128;
bsp_stack_abt_size = ALIGN (bsp_stack_abt_size, bsp_stack_align);
@@ -48,8 +55,8 @@ bsp_stack_irq_size = ALIGN (bsp_stack_irq_size, bsp_stack_align);
bsp_stack_svc_size = DEFINED (bsp_stack_svc_size) ? bsp_stack_svc_size : 512;
bsp_stack_svc_size = ALIGN (bsp_stack_svc_size, bsp_stack_align);
bsp_stack_undef_size = DEFINED (bsp_stack_undef_size) ? bsp_stack_undef_size : 128;
bsp_stack_undef_size = ALIGN (bsp_stack_undef_size, bsp_stack_align);
bsp_stack_und_size = DEFINED (bsp_stack_und_size) ? bsp_stack_und_size : 128;
bsp_stack_und_size = ALIGN (bsp_stack_und_size, bsp_stack_align);
SECTIONS {
.start : {
@@ -62,8 +69,9 @@ SECTIONS {
* BSP: System startup entry
*/
KEEP (*(.bsp_start))
KEEP (*(.bsp_start_data))
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_start_end_align);
/*
* BSP: End of start section
@@ -107,16 +115,16 @@ SECTIONS {
. = . + bsp_stack_svc_size;
bsp_stack_svc_end = .;
bsp_stack_undef_begin = .;
. = . + bsp_stack_undef_size;
bsp_stack_undef_end = .;
bsp_stack_und_begin = .;
. = . + bsp_stack_und_size;
bsp_stack_und_end = .;
/*
* BSP: Special vector data
*/
*(.bsp_vector)
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_vector_end_align);
/*
* BSP: End of vector section
@@ -126,6 +134,10 @@ SECTIONS {
bsp_section_vector_size = bsp_section_vector_end - bsp_section_vector_begin;
.vbarrier : {
. = ALIGN (bsp_section_vbarrier_align);
} > REGION_VECTOR
.text : {
/*
* BSP: Begin of text section
@@ -175,7 +187,7 @@ SECTIONS {
*/
KEEP (*(.fini))
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_text_end_align);
/*
* BSP: End of text section
@@ -203,7 +215,7 @@ SECTIONS {
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_rodata_end_align);
/*
* BSP: End of rodata section
@@ -215,6 +227,10 @@ SECTIONS {
bsp_section_rodata_load_begin = LOADADDR (.rodata);
.robarrier : {
. = ALIGN (bsp_section_robarrier_align);
} > REGION_RODATA
.data : {
/*
* BSP: Begin of data section
@@ -264,7 +280,7 @@ SECTIONS {
KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_data_end_align);
/*
* BSP: End of data section
@@ -281,7 +297,7 @@ SECTIONS {
*(.bsp_fast)
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_fast_end_align);
bsp_section_fast_end = .;
} > REGION_FAST AT > REGION_FAST_LOAD
@@ -300,7 +316,7 @@ SECTIONS {
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN (bsp_section_align);
. = ALIGN (bsp_section_bss_end_align);
/*
* BSP: End of bss section

View File

@@ -1,3 +1,10 @@
2010-01-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/include/arm-cp15.h, shared/include/cache.h,
shared/include/cache_.h: New files.
* Makefile.am, preinstall.am: Update for new files.
* shared/arm920/mmu.c: Include and use <libcpu/arm-cp15.h>.
2009-11-30 Fernando Nicodemos <fgnicodemos@terra.com.br>
* at91rm9200/include/at91rm9200.h: Update to match development version.

View File

@@ -15,6 +15,7 @@ if shared
include_libcpudir = $(includedir)/libcpu
include_libcpu_HEADERS = shared/include/mmu.h
include_libcpu_HEADERS += shared/include/arm-cp15.h
## shared/arm920
noinst_PROGRAMS += shared/arm920.rel

View File

@@ -27,6 +27,10 @@ PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(PROJECT_INCLUDE)/libcpu/mmu.h: shared/include/mmu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu.h
$(PROJECT_INCLUDE)/libcpu/arm-cp15.h: shared/include/arm-cp15.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
endif
if pxa255
$(PROJECT_INCLUDE)/pxa255.h: pxa255/include/pxa255.h $(PROJECT_INCLUDE)/$(dirstamp)

View File

@@ -7,26 +7,12 @@
* $Id$
*/
#include <libcpu/mmu.h>
#include <libcpu/arm-cp15.h>
typedef uint32_t mmu_lvl1_t;
extern uint32_t _ttbl_base;
static inline uint32_t mmu_get_id(void);
static inline uint32_t mmu_get_ctrl(void);
static inline void mmu_set_ctrl(uint32_t val);
static inline uint32_t mmu_get_trans_tbl(void);
static inline void mmu_set_trans_tbl(uint32_t val);
static inline uint32_t mmu_get_domain_ctrl(void);
static inline void mmu_set_domain_ctrl(uint32_t val);
static inline uint32_t mmu_get_fault_stat(void);
static inline void mmu_set_fault_stat(uint32_t val);
static inline uint32_t mmu_get_fault_addr(void);
static inline void mmu_set_fault_addr(uint32_t val);
static inline void mmu_set_cache_inval(void);
static inline void mmu_set_tlb_inval(void);
static inline uint32_t mmu_get_proc_id(void);
static inline void mmu_set_proc_id(uint32_t val);
static void mmu_set_map_inval(mmu_lvl1_t *base);
#define MMU_CTRL_MMU_EN (1 << 0)
@@ -54,25 +40,23 @@ static void mmu_set_map_inval(mmu_lvl1_t *base);
#define MMU_SECT_AP_ALL (0x3 << 10)
#define NOP ( { asm volatile ("nop\n" ); } )
void mmu_init(mmu_sect_map_t *map)
{
mmu_lvl1_t *lvl1_base;
int i;
/* flush the cache and TLB */
mmu_set_cache_inval();
mmu_set_tlb_inval();
arm_cp15_cache_invalidate();
arm_cp15_tlb_invalidate();
/* set manage mode access for all domains */
mmu_set_domain_ctrl(0xffffffff);
arm_cp15_set_domain_access_control(0xffffffff);
lvl1_base = (mmu_lvl1_t *)&_ttbl_base;
/* set up the trans table */
mmu_set_map_inval(lvl1_base);
mmu_set_trans_tbl((uint32_t) lvl1_base);
arm_cp15_set_translation_table_base(lvl1_base);
/* create a 1:1 mapping of the entire address space */
i = 0;
@@ -120,118 +104,20 @@ void mmu_init(mmu_sect_map_t *map)
}
/* flush the cache and TLB */
mmu_set_cache_inval();
mmu_set_tlb_inval();
NOP;
NOP;
arm_cp15_cache_invalidate();
arm_cp15_tlb_invalidate();
/* I & D caches turned on */
mmu_set_ctrl(MMU_CTRL_DEFAULT |
MMU_CTRL_D_CACHE_EN |
MMU_CTRL_I_CACHE_EN |
MMU_CTRL_ALIGN_FAULT_EN |
MMU_CTRL_LITTLE_ENDIAN |
MMU_CTRL_MMU_EN);
NOP;
NOP;
arm_cp15_set_control(MMU_CTRL_DEFAULT |
MMU_CTRL_D_CACHE_EN |
MMU_CTRL_I_CACHE_EN |
MMU_CTRL_ALIGN_FAULT_EN |
MMU_CTRL_LITTLE_ENDIAN |
MMU_CTRL_MMU_EN);
return;
}
static inline uint32_t mmu_get_id(void)
{
uint32_t val;
asm volatile ("msr 15, 0, %0, cr0, cr0\n" : "=r" (val));
return val;
}
static inline uint32_t mmu_get_ctrl(void)
{
uint32_t val;
asm volatile ("mrc 15, 0, %0, cr1, cr0\n" : "=r" (val));
return val;
}
static inline void mmu_set_ctrl(uint32_t val)
{
asm volatile ("mcr 15, 0, %0, cr1, cr0, 0\n" : :"r" (val));
}
static inline uint32_t mmu_get_trans_tbl(void)
{
uint32_t val;
asm volatile ("msr 15, 0, %0, cr2, cr0\n" : "=r" (val));
return val;
}
static inline void mmu_set_trans_tbl(uint32_t val)
{
asm volatile ("mcr 15, 0, %0, cr2, cr0, 0\n" : :"r" (val));
}
static inline uint32_t mmu_get_domain_ctrl(void)
{
uint32_t val;
asm volatile ("msr 15, 0, %0, cr3, cr0\n" : "=r" (val));
return val;
}
static inline void mmu_set_domain_ctrl(uint32_t val)
{
asm volatile ("mcr 15, 0, %0, cr3, cr0, 0\n" : :"r" (val));
}
static inline uint32_t mmu_get_fault_stat(void)
{
uint32_t val;
asm volatile ("msr 15, 0, %0, cr5, cr0\n" : "=r" (val));
return val;
}
static inline void mmu_set_fault_stat(uint32_t val)
{
asm volatile ("mcr 15, 0, %0, cr5, cr0, 0\n" : :"r" (val));
}
static inline uint32_t mmu_get_fault_addr(void)
{
uint32_t val;
asm volatile ("msr 15, 0, %0, cr6, cr0\n" : "=r" (val));
return val;
}
static inline void mmu_set_fault_addr(uint32_t val)
{
asm volatile ("mcr 15, 0, %0, cr6, cr0, 0\n" : :"r" (val));
}
static inline void mmu_set_cache_inval(void)
{
uint32_t val = 0;
asm volatile ("mcr 15, 0, %0, cr7, cr7, 0\n" : :"r" (val));
}
static inline void mmu_set_tlb_inval(void)
{
uint32_t val = 0;
asm volatile ("mcr 15, 0, %0, cr8, cr7, 0\n" : :"r" (val));
}
static inline uint32_t mmu_get_proc_id(void)
{
uint32_t val;
asm volatile ("msr 15, 0, %0, cr13, cr0\n" : "=r" (val));
return val;
}
static inline void mmu_set_proc_id(uint32_t val)
{
asm volatile ("mcr 15, 0, %0, cr13, cr0, 0\n" : :"r" (val));
}
/* set all the level 1 entrys to be invalid descriptors */
static void mmu_set_map_inval(mmu_lvl1_t *base)
{
@@ -241,12 +127,10 @@ static void mmu_set_map_inval(mmu_lvl1_t *base)
}
}
void mmu_set_cpu_async_mode(void)
{
uint32_t reg;
reg = mmu_get_ctrl();
reg = arm_cp15_get_control();
reg |= 0xc0000000;
mmu_set_ctrl(reg);
arm_cp15_set_control(reg);
}

View File

@@ -0,0 +1,644 @@
/**
* @file
*
* @ingroup arm
*
* @brief ARM co-processor 15 (CP15) API.
*/
/*
* Copyright (c) 2009
* 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_SHARED_ARM_CP15_H
#define LIBCPU_SHARED_ARM_CP15_H
#include <rtems.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define ARM_MMU_SECT_BASE_SHIFT 20
#define ARM_MMU_SECT_BASE_MASK 0xfffU
#define ARM_MMU_SECT_DOMAIN_SHIFT 5
#define ARM_MMU_SECT_DOMAIN_MASK 0xfU
#define ARM_MMU_SECT_AP_1 (1U << 11)
#define ARM_MMU_SECT_AP_0 (1U << 10)
#define ARM_MMU_SECT_AP_SHIFT 10
#define ARM_MMU_SECT_AP_MASK 0x3U
#define ARM_MMU_SECT_C (1U << 3)
#define ARM_MMU_SECT_B (1U << 2)
#define ARM_MMU_SECT_DEFAULT 0x12U
#define ARM_MMU_SECT_GET_INDEX(mva) \
(((uint32_t) (mva)) >> ARM_MMU_SECT_BASE_SHIFT)
#define ARM_MMU_SECT_MVA_ALIGN_UP(mva) \
((1U << ARM_MMU_SECT_BASE_SHIFT) \
+ ((((uint32_t) (mva) - 1U)) & ~((1U << ARM_MMU_SECT_BASE_SHIFT) - 1U)))
#define ARM_MMU_TRANSLATION_TABLE_ENTRY_SIZE 4U
#define ARM_MMU_TRANSLATION_TABLE_ENTRY_COUNT 4096U
static inline uint32_t arm_cp15_get_id_code(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c0, c0, 0\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
static inline uint32_t arm_cp15_get_cache_type(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c0, c0, 1\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
static inline uint32_t arm_cp15_get_tcm_status(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c0, c0, 2\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
#define ARM_CP15_CTRL_L4 (1U << 15)
#define ARM_CP15_CTRL_RR (1U << 14)
#define ARM_CP15_CTRL_V (1U << 13)
#define ARM_CP15_CTRL_I (1U << 12)
#define ARM_CP15_CTRL_R (1U << 9)
#define ARM_CP15_CTRL_S (1U << 8)
#define ARM_CP15_CTRL_B (1U << 7)
#define ARM_CP15_CTRL_C (1U << 2)
#define ARM_CP15_CTRL_A (1U << 1)
#define ARM_CP15_CTRL_M (1U << 0)
static inline uint32_t arm_cp15_get_control(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c1, c0, 0\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
static inline void arm_cp15_set_control(uint32_t val)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[val], c1, c0, 0\n"
"nop\n"
"nop\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [val] "r" (val)
: "memory"
);
}
static inline uint32_t *arm_cp15_get_translation_table_base(void)
{
ARM_SWITCH_REGISTERS;
uint32_t *base;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[base], c2, c0, 0\n"
ARM_SWITCH_BACK
: [base] "=&r" (base) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return base;
}
static inline void arm_cp15_set_translation_table_base(uint32_t *base)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[base], c2, c0, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [base] "r" (base)
);
}
#define ARM_CP15_DAC_NO_ACCESS 0x0U
#define ARM_CP15_DAC_CLIENT 0x1U
#define ARM_CP15_DAC_MANAGER 0x3U
#define ARM_CP15_DAC_DOMAIN(index, val) ((val) << (2 * index))
static inline uint32_t arm_cp15_get_domain_access_control(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c3, c0, 0\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
static inline void arm_cp15_set_domain_access_control(uint32_t val)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[val], c3, c0, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [val] "r" (val)
);
}
static inline uint32_t arm_cp15_get_data_fault_status(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c5, c0, 0\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
static inline void arm_cp15_set_data_fault_status(uint32_t val)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[val], c5, c0, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [val] "r" (val)
);
}
static inline uint32_t arm_cp15_get_instruction_fault_status(void)
{
ARM_SWITCH_REGISTERS;
uint32_t val;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[val], c5, c0, 1\n"
ARM_SWITCH_BACK
: [val] "=&r" (val) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return val;
}
static inline void arm_cp15_set_instruction_fault_status(uint32_t val)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[val], c5, c0, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [val] "r" (val)
);
}
static inline void *arm_cp15_get_fault_address(void)
{
ARM_SWITCH_REGISTERS;
void *mva;
asm volatile (
ARM_SWITCH_TO_ARM
"mrc p15, 0, %[mva], c6, c0, 0\n"
ARM_SWITCH_BACK
: [mva] "=&r" (mva) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return mva;
}
static inline void arm_cp15_set_fault_address(const void *mva)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c6, c0, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
);
}
#define ARM_CP15_CACHE_PREPARE_MVA(mva) \
((const void *) (((uint32_t) (mva)) & ~0x1fU))
static inline void arm_cp15_cache_invalidate(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c7, c7, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
: "memory"
);
}
static inline void arm_cp15_instruction_cache_invalidate(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c7, c5, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
: "memory"
);
}
static inline void arm_cp15_instruction_cache_invalidate_line(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c7, c5, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
: "memory"
);
}
static inline void arm_cp15_instruction_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[set_and_way], c7, c5, 2\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [set_and_way] "r" (set_and_way)
: "memory"
);
}
static inline void arm_cp15_instruction_cache_prefetch_line(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c7, c13, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
);
}
static inline void arm_cp15_data_cache_invalidate(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c7, c6, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
: "memory"
);
}
static inline void arm_cp15_data_cache_invalidate_line(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c7, c6, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
: "memory"
);
}
static inline void arm_cp15_data_cache_invalidate_line_by_set_and_way(uint32_t set_and_way)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[set_and_way], c7, c6, 2\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [set_and_way] "r" (set_and_way)
: "memory"
);
}
static inline void arm_cp15_data_cache_clean_line(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c7, c10, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
: "memory"
);
}
static inline void arm_cp15_data_cache_clean_line_by_set_and_way(uint32_t set_and_way)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[set_and_way], c7, c10, 2\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [set_and_way] "r" (set_and_way)
: "memory"
);
}
static inline void arm_cp15_data_cache_test_and_clean(void)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"1:\n"
"mrc p15, 0, r15, c7, c10, 3\n"
"bne 1b\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
:
: "memory"
);
}
static inline void arm_cp15_data_cache_clean_and_invalidate_line(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_CACHE_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c7, c14, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
: "memory"
);
}
static inline void arm_cp15_data_cache_clean_and_invalidate_line_by_set_and_way(uint32_t set_and_way)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[set_and_way], c7, c14, 2\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [set_and_way] "r" (set_and_way)
: "memory"
);
}
static inline void arm_cp15_data_cache_test_and_clean_and_invalidate(void)
{
ARM_SWITCH_REGISTERS;
asm volatile (
ARM_SWITCH_TO_ARM
"1:\n"
"mrc p15, 0, r15, c7, c14, 3\n"
"bne 1b\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
:
: "memory"
);
}
static inline void arm_cp15_drain_write_buffer(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c7, c10, 4\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
: "memory"
);
}
static inline void arm_cp15_wait_for_interrupt(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c7, c0, 4\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
: "memory"
);
}
#define ARM_CP15_TLB_PREPARE_MVA(mva) \
((const void *) (((uint32_t) (mva)) & ~0x3fU))
static inline void arm_cp15_tlb_invalidate(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c8, c7, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
);
}
static inline void arm_cp15_tlb_invalidate_entry(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_TLB_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c8, c7, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
);
}
static inline void arm_cp15_tlb_instruction_invalidate(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c8, c5, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
);
}
static inline void arm_cp15_tlb_instruction_invalidate_entry(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_TLB_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c8, c5, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
);
}
static inline void arm_cp15_tlb_data_invalidate(void)
{
ARM_SWITCH_REGISTERS;
uint32_t sbz = 0;
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[sbz], c8, c6, 0\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [sbz] "r" (sbz)
);
}
static inline void arm_cp15_tlb_data_invalidate_entry(const void *mva)
{
ARM_SWITCH_REGISTERS;
mva = ARM_CP15_TLB_PREPARE_MVA(mva);
asm volatile (
ARM_SWITCH_TO_ARM
"mcr p15, 0, %[mva], c8, c6, 1\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [mva] "r" (mva)
);
}
static inline void arm_cp15_tlb_lockdown_entry(const void *mva)
{
uint32_t arm_switch_reg;
asm volatile (
ARM_SWITCH_TO_ARM
"add %[arm_switch_reg], pc, #16\n"
"mcr p15, 0, %[arm_switch_reg], c7, c13, 1\n"
"mcr p15, 0, %[mva], c8, c7, 1\n"
"mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
"orr %[arm_switch_reg], #0x1\n"
"mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
"ldr %[mva], [%[mva]]\n"
"mrc p15, 0, %[arm_switch_reg], c10, c0, 0\n"
"bic %[arm_switch_reg], #0x1\n"
"mcr p15, 0, %[arm_switch_reg], c10, c0, 0\n"
ARM_SWITCH_BACK
: [mva] "=r" (mva), [arm_switch_reg] "=&r" (arm_switch_reg)
: "[mva]" (mva)
);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBCPU_SHARED_ARM_CP15_H */

View File

@@ -0,0 +1,132 @@
/**
* @file
*
* @ingroup arm
*
* @brief ARM cache defines and implementation.
*/
/*
* Copyright (c) 2009
* 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_ARM_CACHE_H
#define LIBCPU_ARM_CACHE_H
#ifdef __ARM_ARCH_5TEJ__
#include <libcpu/arm-cp15.h>
#define CPU_DATA_CACHE_ALIGNMENT 32
#define CPU_INSTRUCTION_CACHE_ALIGNMENT 32
static inline void _CPU_cache_flush_1_data_line(const void *d_addr)
{
arm_cp15_data_cache_clean_line(d_addr);
}
static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr)
{
arm_cp15_data_cache_invalidate_line(d_addr);
}
static inline void _CPU_cache_freeze_data(void)
{
/* TODO */
}
static inline void _CPU_cache_unfreeze_data(void)
{
/* TODO */
}
static inline void _CPU_cache_invalidate_1_instruction_line(const void *d_addr)
{
arm_cp15_instruction_cache_invalidate_line(d_addr);
}
static inline void _CPU_cache_freeze_instruction(void)
{
/* TODO */
}
static inline void _CPU_cache_unfreeze_instruction(void)
{
/* TODO */
}
static inline void _CPU_cache_flush_entire_data(void)
{
arm_cp15_data_cache_test_and_clean();
}
static inline void _CPU_cache_invalidate_entire_data(void)
{
arm_cp15_data_cache_invalidate();
}
static inline void _CPU_cache_enable_data(void)
{
rtems_interrupt_level level;
uint32_t ctrl;
rtems_interrupt_disable(level);
ctrl = arm_cp15_get_control();
ctrl |= ARM_CP15_CTRL_C;
arm_cp15_set_control(ctrl);
rtems_interrupt_enable(level);
}
static inline void _CPU_cache_disable_data(void)
{
rtems_interrupt_level level;
uint32_t ctrl;
rtems_interrupt_disable(level);
ctrl = arm_cp15_get_control();
ctrl &= ~ARM_CP15_CTRL_C;
arm_cp15_set_control(ctrl);
rtems_interrupt_enable(level);
arm_cp15_data_cache_test_and_clean_and_invalidate();
}
static inline void _CPU_cache_invalidate_entire_instruction(void)
{
arm_cp15_instruction_cache_invalidate();
}
static inline void _CPU_cache_enable_instruction(void)
{
rtems_interrupt_level level;
uint32_t ctrl;
rtems_interrupt_disable(level);
ctrl = arm_cp15_get_control();
ctrl |= ARM_CP15_CTRL_I;
arm_cp15_set_control(ctrl);
rtems_interrupt_enable(level);
}
static inline void _CPU_cache_disable_instruction(void)
{
rtems_interrupt_level level;
uint32_t ctrl;
rtems_interrupt_disable(level);
ctrl = arm_cp15_get_control();
ctrl &= ~ARM_CP15_CTRL_I;
arm_cp15_set_control(ctrl);
rtems_interrupt_enable(level);
}
#endif
#endif /* LIBCPU_ARM_CACHE_H */

View File

@@ -0,0 +1,27 @@
/**
* @file
*
* @ingroup arm
*
* @brief Empty file.
*/
/*
* Copyright (c) 2009
* 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_ARM_CACHE__H
#define LIBCPU_ARM_CACHE__H
/* Empty */
#endif /* LIBCPU_ARM_CACHE__H */

View File

@@ -1,3 +1,12 @@
2010-01-12 Sebastian Huber <sebastian.huber@embedded-brains.de>
* arm_exc_abort.S: New file.
* Makefile.am: Update for new file.
* arm_exc_interrupt.S, cpu.c, rtems/asm.h, rtems/score/cpu.h: Changed
macros which switch from and to THUMB mode. Added a default prefetch
and data abort handler which reports the complete processor context.
Added PSR defines.
2009-12-15 Sebastian Huber <sebastian.huber@embedded-brains.de>
* rtems/score/arm.h: Recognize ARMv5TEJ.

View File

@@ -13,6 +13,7 @@ noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
libscorecpu_a_SOURCES = cpu.c \
cpu_asm.S \
arm_exc_abort.S \
arm_exc_interrupt.S \
arm_exc_handler_low.S \
arm_exc_handler_high.c

View File

@@ -0,0 +1,123 @@
/**
* @file
*
* @ingroup arm
*
* @brief ARM data and prefetch abort exception prologue and epilogue.
*/
/*
* Copyright (c) 2009
* 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/asm.h>
#include <rtems/score/cpu.h>
.extern rtems_fatal_error_occurred
.globl arm_exc_data_abort_set_handler
.globl arm_exc_data_abort
.globl arm_exc_prefetch_abort_set_handler
.globl arm_exc_prefetch_abort
.section ".bss"
data_abort_handler:
.long 0
prefetch_abort_handler:
.long 0
.section ".text"
#ifdef __thumb__
.thumb_func
#endif
arm_exc_data_abort_set_handler:
ldr r1, =data_abort_handler
str r0, [r1]
bx lr
#ifdef __thumb__
.thumb_func
#endif
arm_exc_prefetch_abort_set_handler:
ldr r1, =prefetch_abort_handler
str r0, [r1]
bx lr
.arm
arm_exc_prefetch_abort:
/* Save context and load handler */
sub sp, #16
stmdb sp!, {r0-r12}
ldr r6, =prefetch_abort_handler
b save_more_context
arm_exc_data_abort:
/* Save context and load handler */
sub sp, #16
stmdb sp!, {r0-r12}
ldr r6, =data_abort_handler
save_more_context:
/* Save more context */
mov r2, lr
mrs r3, spsr
mrs r4, cpsr
orr r5, r3, #ARM_PSR_I
bic r5, #ARM_PSR_T
msr cpsr, r5
mov r0, sp
mov r1, lr
msr cpsr, r4
add r5, sp, #68
stmdb r5!, {r0-r3}
/* Call high level handler */
ldr r2, [r6]
cmp r2, #0
ldreq r2, =rtems_fatal_error_occurred
movne r0, sp
moveq r0, #0xaa
#ifndef __thumb__
mov lr, pc
bx r2
#else /* __thumb__ */
SWITCH_FROM_ARM_TO_THUMB r1
bl call_handler
SWITCH_FROM_THUMB_TO_ARM
#endif /* __thumb__ */
/* Restore context */
ldmia r5!, {r0-r3}
mov lr, r2
msr spsr, r3
ldmia sp!, {r0-r12}
add sp, #16
/* Return from interrupt */
subs pc, lr, #8
#ifdef __thumb__
.thumb
call_handler:
bx r2
#endif /* __thumb__ */

View File

@@ -1,6 +1,8 @@
/**
* @file
*
* @ingroup arm
*
* @brief ARM interrupt exception prologue and epilogue.
*/
@@ -23,6 +25,8 @@
* The exchange area is only accessed if INT is disabled.
*/
#include <rtems/asm.h>
#define EXCHANGE_LR r4
#define EXCHANGE_SPSR r5
#define EXCHANGE_CPSR r6
@@ -41,22 +45,6 @@
.extern bsp_interrupt_dispatch
.macro SWITCH_FROM_THUMB_TO_ARM
#ifdef __thumb__
.align 2
bx pc
.arm
#endif /* __thumb__ */
.endm
.macro SWITCH_FROM_ARM_TO_THUMB REG
#ifdef __thumb__
add \REG, pc, #1
bx \REG
.thumb
#endif /* __thumb__ */
.endm
.arm
.globl arm_exc_interrupt
arm_exc_interrupt:

View File

@@ -56,31 +56,31 @@ void _CPU_Context_Initialize(
void _CPU_ISR_Set_level( uint32_t level )
{
uint32_t reg;
uint32_t arm_switch_reg;
asm volatile (
THUMB_TO_ARM
"mrs %0, cpsr\n"
"bic %0, %0, #" _CPU_ISR_LEVEL_STRINGOF( CPU_MODES_INTERRUPT_MASK ) "\n"
"orr %0, %0, %1\n"
ARM_SWITCH_TO_ARM
"mrs %[arm_switch_reg], cpsr\n"
"bic %[arm_switch_reg], #" _CPU_ISR_LEVEL_STRINGOF( CPU_MODES_INTERRUPT_MASK ) "\n"
"orr %[arm_switch_reg], %[level]\n"
"msr cpsr, %0\n"
ARM_TO_THUMB
: "=r" (reg)
: "r" (level)
ARM_SWITCH_BACK
: [arm_switch_reg] "=&r" (arm_switch_reg)
: [level] "r" (level)
);
}
uint32_t _CPU_ISR_Get_level( void )
{
uint32_t reg;
ARM_SWITCH_REGISTERS;
uint32_t level;
asm volatile (
THUMB_TO_ARM
"mrs %0, cpsr\n"
"and %1, %0, #" _CPU_ISR_LEVEL_STRINGOF( CPU_MODES_INTERRUPT_MASK ) "\n"
ARM_TO_THUMB
: "=r" (reg), "=r" (level)
ARM_SWITCH_TO_ARM
"mrs %[level], cpsr\n"
"and %[level], #" _CPU_ISR_LEVEL_STRINGOF( CPU_MODES_INTERRUPT_MASK ) "\n"
ARM_SWITCH_BACK
: [level] "=&r" (level) ARM_SWITCH_ADDITIONAL_OUTPUT
);
return level;

View File

@@ -141,4 +141,20 @@
.globl name ; name: ; .globl name ## _arm ; name ## _arm:
#endif
.macro SWITCH_FROM_THUMB_TO_ARM
#ifdef __thumb__
.align 2
bx pc
.arm
#endif /* __thumb__ */
.endm
.macro SWITCH_FROM_ARM_TO_THUMB REG
#ifdef __thumb__
add \REG, pc, #1
bx \REG
.thumb
#endif /* __thumb__ */
.endm
#endif /* _RTEMS_ASM_H */

View File

@@ -8,6 +8,8 @@
* This include file contains information pertaining to the ARM
* processor.
*
* Copyright (c) 2009 embedded brains GmbH.
*
* Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com>
*
* Copyright (c) 2006 OAR Corporation
@@ -44,13 +46,42 @@
#endif
#ifdef __thumb__
#define ARM_TO_THUMB "add %0, pc, #1\nbx %0\n.thumb\n"
#define THUMB_TO_ARM ".align 2\nbx pc\n.arm\n"
#define ARM_SWITCH_REGISTERS uint32_t arm_switch_reg
#define ARM_SWITCH_TO_ARM ".align 2\nbx pc\n.arm\n"
#define ARM_SWITCH_BACK "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n"
#define ARM_SWITCH_OUTPUT [arm_switch_reg] "=&r" (arm_switch_reg)
#define ARM_SWITCH_ADDITIONAL_OUTPUT , ARM_SWITCH_OUTPUT
#else
#define ARM_TO_THUMB
#define THUMB_TO_ARM
#define ARM_SWITCH_REGISTERS
#define ARM_SWITCH_TO_ARM
#define ARM_SWITCH_BACK
#define ARM_SWITCH_OUTPUT
#define ARM_SWITCH_ADDITIONAL_OUTPUT
#endif
#define ARM_PSR_N (1 << 31)
#define ARM_PSR_Z (1 << 30)
#define ARM_PSR_C (1 << 29)
#define ARM_PSR_V (1 << 28)
#define ARM_PSR_Q (1 << 27)
#define ARM_PSR_J (1 << 24)
#define ARM_PSR_GE_SHIFT 16
#define ARM_PSR_GE_MASK (0xf << ARM_PSR_GE_SHIFT)
#define ARM_PSR_E (1 << 9)
#define ARM_PSR_A (1 << 8)
#define ARM_PSR_I (1 << 7)
#define ARM_PSR_F (1 << 6)
#define ARM_PSR_T (1 << 5)
#define ARM_PSR_M_SHIFT 0
#define ARM_PSR_M_MASK (0x1f << ARM_PSR_M_SHIFT)
#define ARM_PSR_M_USR 0x10
#define ARM_PSR_M_FIQ 0x11
#define ARM_PSR_M_IRQ 0x12
#define ARM_PSR_M_SVC 0x13
#define ARM_PSR_M_ABT 0x17
#define ARM_PSR_M_UND 0x1b
#define ARM_PSR_M_SYS 0x1f
/* If someone uses THUMB we assume she wants minimal code size */
#ifdef __thumb__
#define CPU_INLINE_ENABLE_DISPATCH FALSE
@@ -205,16 +236,16 @@ SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
static inline uint32_t arm_interrupt_disable( void )
{
uint32_t reg;
uint32_t arm_switch_reg;
uint32_t level;
asm volatile (
THUMB_TO_ARM
"mrs %1, cpsr\n"
"orr %0, %1, #0x80\n"
"msr cpsr, %0\n"
ARM_TO_THUMB
: "=r" (reg), "=r" (level)
ARM_SWITCH_TO_ARM
"mrs %[level], cpsr\n"
"orr %[arm_switch_reg], %[level], #0x80\n"
"msr cpsr, %[arm_switch_reg]\n"
ARM_SWITCH_BACK
: [arm_switch_reg] "=&r" (arm_switch_reg), [level] "=&r" (level)
);
return level;
@@ -222,54 +253,46 @@ static inline uint32_t arm_interrupt_disable( void )
static inline void arm_interrupt_enable( uint32_t level )
{
#ifdef __thumb__
uint32_t reg;
ARM_SWITCH_REGISTERS;
asm volatile (
THUMB_TO_ARM
"msr cpsr, %1\n"
ARM_TO_THUMB
: "=r" (reg)
: "r" (level)
);
#else
asm volatile (
"msr cpsr, %0"
:
: "r" (level)
);
#endif
asm volatile (
ARM_SWITCH_TO_ARM
"msr cpsr, %[level]\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [level] "r" (level)
);
}
static inline void arm_interrupt_flash( uint32_t level )
{
uint32_t reg;
uint32_t arm_switch_reg;
asm volatile (
THUMB_TO_ARM
"mrs %0, cpsr\n"
"msr cpsr, %1\n"
"msr cpsr, %0\n"
ARM_TO_THUMB
: "=r" (reg)
: "r" (level)
ARM_SWITCH_TO_ARM
"mrs %[arm_switch_reg], cpsr\n"
"msr cpsr, %[level]\n"
"msr cpsr, %[arm_switch_reg]\n"
ARM_SWITCH_BACK
: [arm_switch_reg] "=&r" (arm_switch_reg)
: [level] "r" (level)
);
}
static inline uint32_t arm_status_irq_enable( void )
{
uint32_t reg;
uint32_t arm_switch_reg;
uint32_t psr;
RTEMS_COMPILER_MEMORY_BARRIER();
asm volatile (
THUMB_TO_ARM
"mrs %1, cpsr\n"
"bic %0, %1, #0x80\n"
"msr cpsr, %0\n"
ARM_TO_THUMB
: "=r" (reg), "=r" (psr)
ARM_SWITCH_TO_ARM
"mrs %[psr], cpsr\n"
"bic %[arm_switch_reg], %[psr], #0x80\n"
"msr cpsr, %[arm_switch_reg]\n"
ARM_SWITCH_BACK
: [arm_switch_reg] "=&r" (arm_switch_reg), [psr] "=&r" (psr)
);
return psr;
@@ -277,23 +300,15 @@ static inline uint32_t arm_status_irq_enable( void )
static inline void arm_status_restore( uint32_t psr )
{
#ifdef __thumb__
uint32_t reg;
ARM_SWITCH_REGISTERS;
asm volatile (
THUMB_TO_ARM
"msr cpsr, %1\n"
ARM_TO_THUMB
: "=r" (reg)
: "r" (psr)
);
#else
asm volatile (
"msr cpsr, %0"
:
: "r" (psr)
);
#endif
asm volatile (
ARM_SWITCH_TO_ARM
"msr cpsr, %[psr]\n"
ARM_SWITCH_BACK
: ARM_SWITCH_OUTPUT
: [psr] "r" (psr)
);
RTEMS_COMPILER_MEMORY_BARRIER();
}
@@ -402,16 +417,42 @@ static inline uint16_t CPU_swap_u16( uint16_t value )
extern uint32_t arm_cpu_mode;
void arm_exc_abort_data( void );
typedef struct {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t sp;
uint32_t lr;
uint32_t pc;
uint32_t cpsr;
} arm_cpu_context;
void arm_exc_abort_prefetch( void );
typedef void arm_exc_abort_handler( arm_cpu_context *context );
void arm_exc_data_abort_set_handler( arm_exc_abort_handler handler );
void arm_exc_data_abort( void );
void arm_exc_prefetch_abort_set_handler( arm_exc_abort_handler handler );
void arm_exc_prefetch_abort( void );
void bsp_interrupt_dispatch( void );
void arm_exc_interrupt( void );
void arm_exc_undefined( void );
void bsp_interrupt_dispatch( void );
#ifdef __cplusplus
}
#endif