summaryrefslogtreecommitdiffstats
path: root/c/src
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2008-07-18 15:56:48 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2008-07-18 15:56:48 +0000
commitd3c321367c659f195f1bf03efc2ce5487e1848de (patch)
treea99c57117499eff7a5532fdd966c10dbd18dbeb5 /c/src
parenttypos. (diff)
downloadrtems-d3c321367c659f195f1bf03efc2ce5487e1848de.tar.bz2
Changed special purpose register inline functions to macros.
fixed some minors in mpc83xx support added file for mpc55xx watchdog support
Diffstat (limited to 'c/src')
-rw-r--r--c/src/lib/libbsp/powerpc/ChangeLog4
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/ChangeLog5
-rw-r--r--c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c68
-rw-r--r--c/src/lib/libbsp/powerpc/shared/clock/clock.c26
-rw-r--r--c/src/lib/libcpu/powerpc/ChangeLog15
-rw-r--r--c/src/lib/libcpu/powerpc/Makefile.am4
-rw-r--r--c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h59
-rw-r--r--c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c4
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c2
-rw-r--r--c/src/lib/libcpu/powerpc/preinstall.am4
-rw-r--r--c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h344
11 files changed, 299 insertions, 236 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog
index 52bc5d630b..c01ce630ea 100644
--- a/c/src/lib/libbsp/powerpc/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/ChangeLog
@@ -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>
* mpc55xxevb: New BSP.
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog b/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog
index 1f94955ddf..d8ce2a9c47 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/gen83xx/ChangeLog
@@ -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>
* network/network.c:
diff --git a/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c
index bf6aae74ae..cc8ade43bd 100644
--- a/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c
@@ -91,29 +91,6 @@ void bsp_pretasking_hook( void)
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)
{
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_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
* store the result in global variables so that it can be used latter...
@@ -129,12 +108,37 @@ void bsp_start( void)
myCpu = get_ppc_cpu_type();
myCpuRevision = get_ppc_cpu_revision();
- /* Determine heap and workspace placement */
- bsp_calc_mem_layout();
-
+ /* Basic CPU initialization */
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
* before we initialize the drivers.
*/
@@ -149,18 +153,6 @@ void bsp_start( void)
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 */
ppc_exc_initialize(
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
diff --git a/c/src/lib/libbsp/powerpc/shared/clock/clock.c b/c/src/lib/libbsp/powerpc/shared/clock/clock.c
index 85f7db60b7..a30078550e 100644
--- a/c/src/lib/libbsp/powerpc/shared/clock/clock.c
+++ b/c/src/lib/libbsp/powerpc/shared/clock/clock.c
@@ -124,7 +124,7 @@ int ppc_clock_exception_handler_booke( BSP_Exception_frame *frame, unsigned numb
uint32_t msr;
/* Acknowledge decrementer request */
- ppc_set_timer_status_register( BOOKE_TSR_DIS);
+ PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
/* Increment clock ticks */
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_interrupt_level level;
-
/* Current 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()) {
/* 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 */
ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
/* Enable decrementer and auto-reload */
- rtems_interrupt_disable( level);
- ppc_set_timer_control_register( ppc_timer_control_register() | BOOKE_TCR_DIE | BOOKE_TCR_ARE);
- rtems_interrupt_enable( level);
+ PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
} else if (cpu_type == PPC_e300c2 || cpu_type == PPC_e300c3) {
/* TODO: Not tested for e300c2 */
/* Enable auto-reload */
- rtems_interrupt_disable( level);
- ppc_set_hardware_implementation_dependent_register_0( ppc_hardware_implementation_dependent_register_0() | 0x00000040);
- rtems_interrupt_enable( level);
+ PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( HID0, 0x00000040);
/* Install exception handler */
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 */
++ppc_clock_decrementer_value;
- rtems_interrupt_disable( level);
-
/* Initialize next time base */
ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
/* Install exception handler */
ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
-
- rtems_interrupt_enable( level);
}
/* Set the decrementer value */
@@ -257,14 +247,16 @@ rtems_device_driver Clock_control( rtems_device_major_number major, rtems_device
if (io == NULL) {
return RTEMS_SUCCESSFUL;
- } else if (ppc_clock_tick == NULL) {
- Clock_initialize( major, minor, 0);
}
if (io->command == rtems_build_name( 'I', 'S', 'R', ' ')) {
ppc_clock_tick();
} else if (io->command == rtems_build_name( 'N', 'E', 'W', ' ')) {
- ppc_clock_tick = io->buffer;
+ if (io->buffer != NULL) {
+ ppc_clock_tick = io->buffer;
+ } else {
+ ppc_clock_tick = ppc_clock_no_tick;
+ }
}
return RTEMS_SUCCESSFUL;
diff --git a/c/src/lib/libcpu/powerpc/ChangeLog b/c/src/lib/libcpu/powerpc/ChangeLog
index 5033d9087f..f9dc8605d2 100644
--- a/c/src/lib/libcpu/powerpc/ChangeLog
+++ b/c/src/lib/libcpu/powerpc/ChangeLog
@@ -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,
diff --git a/c/src/lib/libcpu/powerpc/Makefile.am b/c/src/lib/libcpu/powerpc/Makefile.am
index d0e719aff4..45c1d2b9a0 100644
--- a/c/src/lib/libcpu/powerpc/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/Makefile.am
@@ -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
diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h b/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h
new file mode 100644
index 0000000000..2c00621076
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h
@@ -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 */
diff --git a/c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c b/c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c
index ddb175d30a..3974c56941 100644
--- a/c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c
+++ b/c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c
@@ -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;
}
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
index 06ed62423d..795661fa7c 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
@@ -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,
diff --git a/c/src/lib/libcpu/powerpc/preinstall.am b/c/src/lib/libcpu/powerpc/preinstall.am
index b9973945b9..e6b86878b5 100644
--- a/c/src/lib/libcpu/powerpc/preinstall.am
+++ b/c/src/lib/libcpu/powerpc/preinstall.am
@@ -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
diff --git a/c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h b/c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h
index f138884086..bfbf919e2c 100644
--- a/c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h
+++ b/c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h
@@ -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_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_0()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0);
-}
-
-static inline void ppc_set_special_purpose_register_0( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0, val);
-}
-
-static inline uint32_t ppc_special_purpose_register_1()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1);
-}
-
-static inline void ppc_set_special_purpose_register_1( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG1, val);
-}
-
-static inline uint32_t ppc_special_purpose_register_2()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2);
-}
-
-static inline void ppc_set_special_purpose_register_2( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG2, val);
-}
-
-static inline uint32_t ppc_special_purpose_register_3()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG3);
-}
-
-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);
-}
+#define PPC_STRINGOF( x) #x
-static inline uint32_t ppc_timer_control_register()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TCR);
-}
+/**
+ * @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;\
+ } )
-static inline void ppc_set_timer_control_register( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TCR, 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_timer_status_register()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TSR);
-}
+/**
+ * @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_timer_status_register( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_TSR, 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_decrementer_auto_reload_register()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_DECAR);
-}
+/**
+ * @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_decrementer_auto_reload_register( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( BOOKE_DECAR, 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_hardware_implementation_dependent_register_0()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( HID0);
-}
+/**
+ * @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_hardware_implementation_dependent_register_0( uint32_t val)
-{
- PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( HID0, 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_hardware_implementation_dependent_register_1()
-{
- PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( HID1);
-}
+/**
+ * @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_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
/*