forked from Imagelibrary/rtems
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:
@@ -1,3 +1,7 @@
|
|||||||
|
2008-07-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* shared/clock/clock.c: Update due to powerpc-utilty.h changes.
|
||||||
|
|
||||||
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
2008-07-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
* mpc55xxevb: New BSP.
|
* mpc55xxevb: New BSP.
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
2008-07-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* startup/bspstart.c: Enable cache after CPU initialization. Clear
|
||||||
|
only workspace memory area.
|
||||||
|
|
||||||
2008-07-18 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
|
2008-07-18 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
|
||||||
|
|
||||||
* network/network.c:
|
* network/network.c:
|
||||||
|
|||||||
@@ -91,29 +91,6 @@ void bsp_pretasking_hook( void)
|
|||||||
bsp_libc_init( BSP_heap_start, BSP_heap_end - BSP_heap_start, 0);
|
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;
|
|
||||||
/*
|
|
||||||
TODO
|
|
||||||
mpc83xx_zero_4( bsp_workspace_start, workspace_size);
|
|
||||||
*/
|
|
||||||
mpc83xx_zero_4( bsp_interrupt_stack_start, bsp_ram_end - bsp_interrupt_stack_start);
|
|
||||||
|
|
||||||
Configuration.work_space_start = bsp_workspace_start;
|
|
||||||
|
|
||||||
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_id_t myCpu;
|
||||||
@@ -122,6 +99,8 @@ void bsp_start( void)
|
|||||||
uint32_t interrupt_stack_start = (uint32_t) bsp_interrupt_stack_start;
|
uint32_t interrupt_stack_start = (uint32_t) bsp_interrupt_stack_start;
|
||||||
uint32_t interrupt_stack_size = (uint32_t) bsp_interrupt_stack_size;
|
uint32_t interrupt_stack_size = (uint32_t) bsp_interrupt_stack_size;
|
||||||
|
|
||||||
|
size_t workspace_size = rtems_configuration_get_work_space_size();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
* 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...
|
* store the result in global variables so that it can be used latter...
|
||||||
@@ -129,11 +108,36 @@ void bsp_start( void)
|
|||||||
myCpu = get_ppc_cpu_type();
|
myCpu = get_ppc_cpu_type();
|
||||||
myCpuRevision = get_ppc_cpu_revision();
|
myCpuRevision = get_ppc_cpu_revision();
|
||||||
|
|
||||||
/* Determine heap and workspace placement */
|
/* Basic CPU initialization */
|
||||||
bsp_calc_mem_layout();
|
|
||||||
|
|
||||||
cpu_init();
|
cpu_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
/* Clear the workspace */
|
||||||
|
Configuration.do_zero_of_workspace = 0;
|
||||||
|
mpc83xx_zero_4( bsp_workspace_start, workspace_size);
|
||||||
|
|
||||||
|
/* Workspace start */
|
||||||
|
Configuration.work_space_start = bsp_workspace_start;
|
||||||
|
|
||||||
|
/* Heap area */
|
||||||
|
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 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is evaluated during runtime, so it should be ok to set it
|
* This is evaluated during runtime, so it should be ok to set it
|
||||||
* before we initialize the drivers.
|
* before we initialize the drivers.
|
||||||
@@ -149,18 +153,6 @@ void bsp_start( void)
|
|||||||
|
|
||||||
bsp_clicks_per_usec = BSP_bus_frequency / 4000000;
|
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
|
|
||||||
|
|
||||||
/* Initialize exception handler */
|
/* Initialize exception handler */
|
||||||
ppc_exc_initialize(
|
ppc_exc_initialize(
|
||||||
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
|
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ int ppc_clock_exception_handler_booke( BSP_Exception_frame *frame, unsigned numb
|
|||||||
uint32_t msr;
|
uint32_t msr;
|
||||||
|
|
||||||
/* Acknowledge decrementer request */
|
/* Acknowledge decrementer request */
|
||||||
ppc_set_timer_status_register( BOOKE_TSR_DIS);
|
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
|
||||||
|
|
||||||
/* Increment clock ticks */
|
/* Increment clock ticks */
|
||||||
Clock_driver_ticks += 1;
|
Clock_driver_ticks += 1;
|
||||||
@@ -176,8 +176,6 @@ void Clock_exit()
|
|||||||
|
|
||||||
rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
|
||||||
{
|
{
|
||||||
rtems_interrupt_level level;
|
|
||||||
|
|
||||||
/* Current CPU type */
|
/* Current CPU type */
|
||||||
ppc_cpu_id_t cpu_type = get_ppc_cpu_type();
|
ppc_cpu_id_t cpu_type = get_ppc_cpu_type();
|
||||||
|
|
||||||
@@ -211,22 +209,18 @@ rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_dev
|
|||||||
|
|
||||||
if (ppc_cpu_is_bookE()) {
|
if (ppc_cpu_is_bookE()) {
|
||||||
/* Set decrementer auto-reload value */
|
/* Set decrementer auto-reload value */
|
||||||
ppc_set_decrementer_auto_reload_register( ppc_clock_decrementer_value);
|
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
|
||||||
|
|
||||||
/* Install exception handler */
|
/* Install exception handler */
|
||||||
ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
|
ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
|
||||||
|
|
||||||
/* Enable decrementer and auto-reload */
|
/* Enable decrementer and auto-reload */
|
||||||
rtems_interrupt_disable( level);
|
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
||||||
ppc_set_timer_control_register( ppc_timer_control_register() | BOOKE_TCR_DIE | BOOKE_TCR_ARE);
|
|
||||||
rtems_interrupt_enable( level);
|
|
||||||
} else if (cpu_type == PPC_e300c2 || cpu_type == PPC_e300c3) {
|
} else if (cpu_type == PPC_e300c2 || cpu_type == PPC_e300c3) {
|
||||||
/* TODO: Not tested for e300c2 */
|
/* TODO: Not tested for e300c2 */
|
||||||
|
|
||||||
/* Enable auto-reload */
|
/* Enable auto-reload */
|
||||||
rtems_interrupt_disable( level);
|
PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( HID0, 0x00000040);
|
||||||
ppc_set_hardware_implementation_dependent_register_0( ppc_hardware_implementation_dependent_register_0() | 0x00000040);
|
|
||||||
rtems_interrupt_enable( level);
|
|
||||||
|
|
||||||
/* Install exception handler */
|
/* Install exception handler */
|
||||||
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_e300);
|
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_e300);
|
||||||
@@ -234,15 +228,11 @@ rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_dev
|
|||||||
/* Here the decrementer value is actually the interval */
|
/* Here the decrementer value is actually the interval */
|
||||||
++ppc_clock_decrementer_value;
|
++ppc_clock_decrementer_value;
|
||||||
|
|
||||||
rtems_interrupt_disable( level);
|
|
||||||
|
|
||||||
/* Initialize next time base */
|
/* Initialize next time base */
|
||||||
ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
|
ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
|
||||||
|
|
||||||
/* Install exception handler */
|
/* Install exception handler */
|
||||||
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
|
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
|
||||||
|
|
||||||
rtems_interrupt_enable( level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the decrementer value */
|
/* Set the decrementer value */
|
||||||
@@ -257,14 +247,16 @@ rtems_device_driver Clock_control( rtems_device_major_number major, rtems_device
|
|||||||
|
|
||||||
if (io == NULL) {
|
if (io == NULL) {
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
} else if (ppc_clock_tick == NULL) {
|
|
||||||
Clock_initialize( major, minor, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io->command == rtems_build_name( 'I', 'S', 'R', ' ')) {
|
if (io->command == rtems_build_name( 'I', 'S', 'R', ' ')) {
|
||||||
ppc_clock_tick();
|
ppc_clock_tick();
|
||||||
} else if (io->command == rtems_build_name( 'N', 'E', 'W', ' ')) {
|
} else if (io->command == rtems_build_name( 'N', 'E', 'W', ' ')) {
|
||||||
|
if (io->buffer != NULL) {
|
||||||
ppc_clock_tick = io->buffer;
|
ppc_clock_tick = io->buffer;
|
||||||
|
} else {
|
||||||
|
ppc_clock_tick = ppc_clock_no_tick;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
|
|||||||
@@ -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>
|
2008-07-18 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
|
||||||
|
|
||||||
* mpc83xx/network/tsec.c: Initialize PHY registers late enough,
|
* mpc83xx/network/tsec.c: Initialize PHY registers late enough,
|
||||||
|
|||||||
@@ -429,8 +429,8 @@ include_mpc55xx_HEADERS = mpc55xx/include/regs.h \
|
|||||||
mpc55xx/include/dspi.h \
|
mpc55xx/include/dspi.h \
|
||||||
mpc55xx/include/edma.h \
|
mpc55xx/include/edma.h \
|
||||||
mpc55xx/include/mpc55xx.h \
|
mpc55xx/include/mpc55xx.h \
|
||||||
mpc55xx/include/esci.h
|
mpc55xx/include/esci.h \
|
||||||
|
mpc55xx/include/watchdog.h
|
||||||
|
|
||||||
# IRQ
|
# IRQ
|
||||||
noinst_PROGRAMS += mpc55xx/irq.rel
|
noinst_PROGRAMS += mpc55xx/irq.rel
|
||||||
|
|||||||
59
c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h
Normal file
59
c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h
Normal 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 */
|
||||||
@@ -200,7 +200,7 @@ rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
|
|||||||
|
|
||||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
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;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
|
|||||||
|
|
||||||
MPC83XX_GTM_CHECK_INDEX( timer);
|
MPC83XX_GTM_CHECK_INDEX( timer);
|
||||||
|
|
||||||
prescale = mpc83xx.gtm [module].gtpsr [module_timer];
|
*prescale = mpc83xx.gtm [module].gtpsr [module_timer];
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ static const cat_ini_t e200_vector_categories [LAST_VALID_EXC + 1] = {
|
|||||||
[ASM_SYS_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_SYS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_BOOKE_DEC_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
|
[ASM_BOOKE_DEC_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
|
||||||
[ASM_BOOKE_FIT_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_ITLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
[ASM_BOOKE_DTLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
[ASM_BOOKE_DTLBMISS_VECTOR] = PPC_EXC_CLASSIC,
|
||||||
|
|
||||||
|
|||||||
@@ -294,4 +294,8 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc55xx/mpc55xx.h
|
|||||||
$(PROJECT_INCLUDE)/mpc55xx/esci.h: mpc55xx/include/esci.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
$(PROJECT_INCLUDE)/mpc55xx/esci.h: mpc55xx/include/esci.h $(PROJECT_INCLUDE)/mpc55xx/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/esci.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc55xx/esci.h
|
||||||
PREINSTALL_FILES += $(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
|
endif
|
||||||
|
|||||||
@@ -239,184 +239,176 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
|
|||||||
PPC_Set_decrementer( dec);
|
PPC_Set_decrementer( dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PPC_STRINGOF(x) #x
|
/**
|
||||||
|
* @brief Preprocessor magic for stringification of @a x.
|
||||||
|
*/
|
||||||
|
#define PPC_STRINGOF( x) #x
|
||||||
|
|
||||||
/* Do not use the following macros. Use the inline functions instead. */
|
/**
|
||||||
|
* @brief Returns the value of the Special Purpose Register with number @a spr.
|
||||||
#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr) \
|
*
|
||||||
|
* @note This macro uses a GNU C extension.
|
||||||
|
*/
|
||||||
|
#define PPC_SPECIAL_PURPOSE_REGISTER( spr) \
|
||||||
|
( { \
|
||||||
uint32_t val; \
|
uint32_t val; \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"mfspr %0, " #spr \
|
"mfspr %0, " PPC_STRINGOF( spr) \
|
||||||
: "=r" (val) \
|
: "=r" (val) \
|
||||||
); \
|
); \
|
||||||
return val;
|
val;\
|
||||||
|
} )
|
||||||
|
|
||||||
#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( spr) \
|
/**
|
||||||
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr)
|
* @brief Sets the Special Purpose Register with number @a spr to the value in
|
||||||
|
* @a val.
|
||||||
#define PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER( spr, val) \
|
*/
|
||||||
|
#define PPC_SET_SPECIAL_PURPOSE_REGISTER( spr, val) \
|
||||||
|
do { \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"mtspr " #spr ", %0" \
|
"mtspr " PPC_STRINGOF( spr) ", %0" \
|
||||||
: \
|
: \
|
||||||
: "r" (val) \
|
: "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...
|
|
||||||
*/
|
|
||||||
#define PPC_DEVICE_CONTROL_REGISTER(dcr) \
|
|
||||||
({uint32_t val;asm volatile ("mfdcr %0," PPC_STRINGOF(dcr) \
|
|
||||||
: "=r" (val)); val;})
|
|
||||||
|
|
||||||
#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr,val) \
|
|
||||||
do { \
|
|
||||||
asm volatile ("mtdcr " PPC_STRINGOF(dcr)",%0" \
|
|
||||||
:: "r" (val)); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 uint32_t ppc_special_purpose_register_0()
|
/**
|
||||||
{
|
* @brief Sets in the Special Purpose Register with number @a spr all bits
|
||||||
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0);
|
* 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 void ppc_set_special_purpose_register_0( uint32_t val)
|
/**
|
||||||
{
|
* @brief Clears in the Special Purpose Register with number @a spr all bits
|
||||||
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0, val);
|
* 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 uint32_t ppc_special_purpose_register_1()
|
/**
|
||||||
{
|
* @brief Returns the value of the Device Control Register with number @a dcr.
|
||||||
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1);
|
*
|
||||||
}
|
* 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 void ppc_set_special_purpose_register_1( uint32_t val)
|
/**
|
||||||
{
|
* @brief Sets the Device Control Register with number @a dcr to the value in
|
||||||
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1, val);
|
* @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 uint32_t ppc_special_purpose_register_2()
|
/**
|
||||||
{
|
* @brief Sets in the Device Control Register with number @a dcr all bits
|
||||||
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2);
|
* 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 void ppc_set_special_purpose_register_2( uint32_t val)
|
/**
|
||||||
{
|
* @brief Sets in the Device Control Register with number @a dcr all bits
|
||||||
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2, val);
|
* 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 uint32_t ppc_special_purpose_register_3()
|
/**
|
||||||
{
|
* @brief Clears in the Device Control Register with number @a dcr all bits
|
||||||
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3);
|
* which are set in @a bits.
|
||||||
}
|
*
|
||||||
|
* Interrupts are disabled throughout this operation.
|
||||||
static inline void ppc_set_special_purpose_register_3( uint32_t val)
|
*/
|
||||||
{
|
#define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS( dcr, bits) \
|
||||||
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3, val);
|
do { \
|
||||||
}
|
rtems_interrupt_level level; \
|
||||||
|
uint32_t val; \
|
||||||
static inline uint32_t ppc_special_purpose_register_4()
|
rtems_interrupt_disable( level); \
|
||||||
{
|
val = PPC_DEVICE_CONTROL_REGISTER( dcr); \
|
||||||
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG4);
|
val &= ~bits; \
|
||||||
}
|
PPC_SET_DEVICE_CONTROL_REGISTER( dcr, val); \
|
||||||
|
rtems_interrupt_enable( level); \
|
||||||
static inline void ppc_set_special_purpose_register_4( uint32_t val)
|
} while (0)
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t ppc_time_base()
|
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)
|
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()
|
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)
|
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()
|
static inline uint64_t ppc_time_base_64()
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
2008-07-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* rtems/powerpc/registers.h: Added masks for BOOKE_TCR fields.
|
||||||
|
|
||||||
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
|
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
|
||||||
* rtems/powerpc/registers.h:
|
* rtems/powerpc/registers.h:
|
||||||
|
|
||||||
|
|||||||
@@ -302,14 +302,18 @@ lidate */
|
|||||||
#define PPC405_TCR 0x3DA
|
#define PPC405_TCR 0x3DA
|
||||||
#define BOOKE_TCR 340
|
#define BOOKE_TCR 340
|
||||||
#define BOOKE_TCR_WP(x) (((x)&3)<<30)
|
#define BOOKE_TCR_WP(x) (((x)&3)<<30)
|
||||||
|
#define BOOKE_TCR_WP_MASK (3<<30)
|
||||||
#define BOOKE_TCR_WRC(x) (((x)&3)<<28)
|
#define BOOKE_TCR_WRC(x) (((x)&3)<<28)
|
||||||
|
#define BOOKE_TCR_WRC_MASK (3<<28)
|
||||||
#define BOOKE_TCR_WIE (1<<27)
|
#define BOOKE_TCR_WIE (1<<27)
|
||||||
#define BOOKE_TCR_DIE (1<<26)
|
#define BOOKE_TCR_DIE (1<<26)
|
||||||
#define BOOKE_TCR_FP(x) (((x)&3)<<24)
|
#define BOOKE_TCR_FP(x) (((x)&3)<<24)
|
||||||
#define BOOKE_TCR_FIE (1<<23)
|
#define BOOKE_TCR_FIE (1<<23)
|
||||||
#define BOOKE_TCR_ARE (1<<22)
|
#define BOOKE_TCR_ARE (1<<22)
|
||||||
#define BOOKE_TCR_WPEXT(x) (((x)&0xf)<<17)
|
#define BOOKE_TCR_WPEXT(x) (((x)&0xf)<<17)
|
||||||
|
#define BOOKE_TCR_WPEXT_MASK (0xf<<17)
|
||||||
#define BOOKE_TCR_FPEXT(x) (((x)&0xf)<<13)
|
#define BOOKE_TCR_FPEXT(x) (((x)&0xf)<<13)
|
||||||
|
#define BOOKE_TCR_FPEXT_MASK (0xf<<13)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default value for the interrupt disable mask.
|
* @brief Default value for the interrupt disable mask.
|
||||||
|
|||||||
Reference in New Issue
Block a user