Changed special purpose register inline functions to macros.

fixed some minors in mpc83xx support
added file for mpc55xx watchdog support
This commit is contained in:
Thomas Doerfler
2008-07-18 15:56:48 +00:00
parent eb98e4c627
commit d3c321367c
13 changed files with 307 additions and 236 deletions

View File

@@ -1,3 +1,18 @@
2008-07-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/include/powerpc-utility.h: Changed special purpose register
inline functions to macros. Added macros to set and clear bits for
SPRs and DCRs.
* new-exceptions/raw_exception.c: The watchdog exception for e200 is
now asynchronous.
* mpc83xx/gtm/gtm.c: Bugfix for some value assignments.
* mpc55xx/include/watchdog.h: New file.
* Makefile.am: Install mpc55xx/include/watchdog.h for MPC55XX.
2008-07-18 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
* mpc83xx/network/tsec.c: Initialize PHY registers late enough,

View File

@@ -429,8 +429,8 @@ include_mpc55xx_HEADERS = mpc55xx/include/regs.h \
mpc55xx/include/dspi.h \
mpc55xx/include/edma.h \
mpc55xx/include/mpc55xx.h \
mpc55xx/include/esci.h
mpc55xx/include/esci.h \
mpc55xx/include/watchdog.h
# IRQ
noinst_PROGRAMS += mpc55xx/irq.rel

View File

@@ -0,0 +1,59 @@
/**
* @file
*
* @ingroup mpc55xx
*
* @brief Header file for the watchdog timer.
*/
/*
* 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_WATCHDOG_H
#define LIBCPU_POWERPC_MPC55XX_WATCHDOG_H
#include <stdbool.h>
#include <rtems.h>
#include <libcpu/powerpc-utility.h>
static inline void mpc55xx_watchdog_clear()
{
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_WIS);
}
static inline void mpc55xx_watchdog_enable_interrupt( bool enable)
{
if (enable) {
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_WIE);
} else {
PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_WIE);
}
}
static inline rtems_status_code mpc55xx_watchdog_set_time_base_bit( uint32_t bit)
{
if (bit > 63) {
return RTEMS_INVALID_NUMBER;
}
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED(
BOOKE_TCR,
BOOKE_TCR_WP( bit) | BOOKE_TCR_WPEXT( bit >> 2),
BOOKE_TCR_WP_MASK | BOOKE_TCR_WPEXT_MASK
);
return RTEMS_SUCCESSFUL;
}
#endif /* LIBCPU_POWERPC_MPC55XX_WATCHDOG_H */

View File

@@ -200,7 +200,7 @@ rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
MPC83XX_GTM_CHECK_INDEX( timer);
reference = mpc83xx.gtm [module].gt_tim_regs [high].gtrfr [low];
*reference = mpc83xx.gtm [module].gt_tim_regs [high].gtrfr [low];
return RTEMS_SUCCESSFUL;
}
@@ -222,7 +222,7 @@ rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
MPC83XX_GTM_CHECK_INDEX( timer);
prescale = mpc83xx.gtm [module].gtpsr [module_timer];
*prescale = mpc83xx.gtm [module].gtpsr [module_timer];
return RTEMS_SUCCESSFUL;
}

View File

@@ -266,7 +266,7 @@ static const cat_ini_t e200_vector_categories [LAST_VALID_EXC + 1] = {
[ASM_SYS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_BOOKE_DEC_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ASM_BOOKE_FIT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ASM_BOOKE_WDOG_VECTOR] = PPC_EXC_BOOKE_CRITICAL,
[ASM_BOOKE_WDOG_VECTOR] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
[ASM_BOOKE_ITLBMISS_VECTOR] = PPC_EXC_CLASSIC,
[ASM_BOOKE_DTLBMISS_VECTOR] = PPC_EXC_CLASSIC,

View File

@@ -294,4 +294,8 @@ 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
$(PROJECT_INCLUDE)/mpc55xx/watchdog.h: mpc55xx/include/watchdog.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/watchdog.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/watchdog.h
endif

View File

@@ -239,184 +239,176 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
PPC_Set_decrementer( dec);
}
#define PPC_STRINGOF(x) #x
/* Do not use the following macros. Use the inline functions instead. */
#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr) \
uint32_t val; \
asm volatile ( \
"mfspr %0, " #spr \
: "=r" (val) \
); \
return val;
#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( spr) \
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr)
#define PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER( spr, val) \
asm volatile ( \
"mtspr " #spr ", %0" \
: \
: "r" (val) \
);
#define PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( spr, val) \
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER( spr, val)
/*
* PPC4xx have Device Control Registers...
/**
* @brief Preprocessor magic for stringification of @a x.
*/
#define PPC_DEVICE_CONTROL_REGISTER(dcr) \
({uint32_t val;asm volatile ("mfdcr %0," PPC_STRINGOF(dcr) \
: "=r" (val)); val;})
#define PPC_STRINGOF( x) #x
#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr,val) \
do { \
asm volatile ("mtdcr " PPC_STRINGOF(dcr)",%0" \
:: "r" (val)); \
} while (0)
/**
* @brief Returns the value of the Special Purpose Register with number @a spr.
*
* @note This macro uses a GNU C extension.
*/
#define PPC_SPECIAL_PURPOSE_REGISTER( spr) \
( { \
uint32_t val; \
asm volatile ( \
"mfspr %0, " PPC_STRINGOF( spr) \
: "=r" (val) \
); \
val;\
} )
/**
* @brief Sets the Special Purpose Register with number @a spr to the value in
* @a val.
*/
#define PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val) \
do { \
asm volatile ( \
"mtspr " PPC_STRINGOF( spr) ", %0" \
: \
: "r" (val) \
); \
} while (0)
static inline uint32_t ppc_special_purpose_register_0()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0);
}
/**
* @brief Sets in the Special Purpose Register with number @a spr all bits
* which are set in @a bits.
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( spr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
rtems_interrupt_disable( level); \
val = PPC_SPECIAL_PURPOSE_REGISTER( spr); \
val |= bits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val); \
rtems_interrupt_enable( level); \
} while (0)
static inline void ppc_set_special_purpose_register_0( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0, val);
}
/**
* @brief Sets in the Special Purpose Register with number @a spr all bits
* which are set in @a bits. The previous register value will be masked with
* @a mask.
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED( spr, bits, mask) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
rtems_interrupt_disable( level); \
val = PPC_SPECIAL_PURPOSE_REGISTER( spr); \
val &= ~mask; \
val |= bits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val); \
rtems_interrupt_enable( level); \
} while (0)
static inline uint32_t ppc_special_purpose_register_1()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1);
}
/**
* @brief Clears in the Special Purpose Register with number @a spr all bits
* which are set in @a bits.
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS( spr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
rtems_interrupt_disable( level); \
val = PPC_SPECIAL_PURPOSE_REGISTER( spr); \
val &= ~bits; \
PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val); \
rtems_interrupt_enable( level); \
} while (0)
static inline void ppc_set_special_purpose_register_1( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1, val);
}
/**
* @brief Returns the value of the Device Control Register with number @a dcr.
*
* The PowerPC 4XX family has Device Control Registers.
*
* @note This macro uses a GNU C extension.
*/
#define PPC_DEVICE_CONTROL_REGISTER( dcr) \
( { \
uint32_t val; \
asm volatile ( \
"mfdcr %0, " PPC_STRINGOF( dcr) \
: "=r" (val) \
); \
val;\
} )
static inline uint32_t ppc_special_purpose_register_2()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2);
}
/**
* @brief Sets the Device Control Register with number @a dcr to the value in
* @a val.
*
* The PowerPC 4XX family has Device Control Registers.
*/
#define PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val) \
do { \
asm volatile ( \
"mtdcr " PPC_STRINGOF( dcr) ", %0" \
: \
: "r" (val) \
); \
} while (0)
static inline void ppc_set_special_purpose_register_2( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2, val);
}
/**
* @brief Sets in the Device Control Register with number @a dcr all bits
* which are set in @a bits.
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS( dcr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
rtems_interrupt_disable( level); \
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
val |= bits; \
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
rtems_interrupt_enable( level); \
} while (0)
static inline uint32_t ppc_special_purpose_register_3()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3);
}
/**
* @brief Sets in the Device Control Register with number @a dcr all bits
* which are set in @a bits. The previous register value will be masked with
* @a mask.
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED( dcr, bits, mask) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
rtems_interrupt_disable( level); \
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
val &= ~mask; \
val |= bits; \
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
rtems_interrupt_enable( level); \
} while (0)
static inline void ppc_set_special_purpose_register_3( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3, val);
}
static inline uint32_t ppc_special_purpose_register_4()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG4);
}
static inline void ppc_set_special_purpose_register_4( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG4, val);
}
static inline uint32_t ppc_special_purpose_register_5()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG5);
}
static inline void ppc_set_special_purpose_register_5( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG5, val);
}
static inline uint32_t ppc_special_purpose_register_6()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG6);
}
static inline void ppc_set_special_purpose_register_6( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG6, val);
}
static inline uint32_t ppc_special_purpose_register_7()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG7);
}
static inline void ppc_set_special_purpose_register_7( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG7, val);
}
static inline uint32_t ppc_user_special_purpose_register_0()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( USPRG0);
}
static inline void ppc_set_user_special_purpose_register_0( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( USPRG0, val);
}
static inline uint32_t ppc_timer_control_register()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TCR);
}
static inline void ppc_set_timer_control_register( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TCR, val);
}
static inline uint32_t ppc_timer_status_register()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TSR);
}
static inline void ppc_set_timer_status_register( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TSR, val);
}
static inline uint32_t ppc_decrementer_auto_reload_register()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_DECAR);
}
static inline void ppc_set_decrementer_auto_reload_register( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_DECAR, val);
}
static inline uint32_t ppc_hardware_implementation_dependent_register_0()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( HID0);
}
static inline void ppc_set_hardware_implementation_dependent_register_0( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( HID0, val);
}
static inline uint32_t ppc_hardware_implementation_dependent_register_1()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( HID1);
}
static inline void ppc_set_hardware_implementation_dependent_register_1( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( HID1, val);
}
/**
* @brief Clears in the Device Control Register with number @a dcr all bits
* which are set in @a bits.
*
* Interrupts are disabled throughout this operation.
*/
#define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS( dcr, bits) \
do { \
rtems_interrupt_level level; \
uint32_t val; \
rtems_interrupt_disable( level); \
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
val &= ~bits; \
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
rtems_interrupt_enable( level); \
} while (0)
static inline uint32_t ppc_time_base()
{
@@ -429,17 +421,17 @@ static inline uint32_t ppc_time_base()
static inline void ppc_set_time_base( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( TBWL, val);
PPC_SET_SPECIAL_PURPOSE_REGISTER( TBWL, val);
}
static inline uint32_t ppc_time_base_upper()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( TBRU);
return PPC_SPECIAL_PURPOSE_REGISTER( TBRU);
}
static inline void ppc_set_time_base_upper( uint32_t val)
{
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( TBWU, val);
PPC_SET_SPECIAL_PURPOSE_REGISTER( TBWU, val);
}
static inline uint64_t ppc_time_base_64()
@@ -457,18 +449,18 @@ static inline void ppc_set_time_base_64( uint64_t val)
#include <rtems/asm.h>
.macro LA reg, addr
lis \reg, (\addr)@h
ori \reg, \reg, (\addr)@l
lis \reg, (\addr)@h
ori \reg, \reg, (\addr)@l
.endm
.macro LWI reg, value
lis \reg, (\value)@h
ori \reg, \reg, (\value)@l
ori \reg, \reg, (\value)@l
.endm
.macro LW reg, addr
lis \reg, \addr@ha
lwz \reg, \addr@l(\reg)
lis \reg, \addr@ha
lwz \reg, \addr@l(\reg)
.endm
/*
@@ -502,7 +494,7 @@ static inline void ppc_set_time_base_64( uint64_t val)
* Obtain interrupt mask
*/
.macro GET_INTERRUPT_MASK mask
mfspr \mask, sprg0
mfspr \mask, sprg0
.endm
/*