diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2008-07-18 15:56:48 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2008-07-18 15:56:48 +0000 |
commit | d3c321367c659f195f1bf03efc2ce5487e1848de (patch) | |
tree | a99c57117499eff7a5532fdd966c10dbd18dbeb5 /c | |
parent | typos. (diff) | |
download | rtems-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')
-rw-r--r-- | c/src/lib/libbsp/powerpc/ChangeLog | 4 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/ChangeLog | 5 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c | 68 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/clock/clock.c | 26 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ChangeLog | 15 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/Makefile.am | 4 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc55xx/include/watchdog.h | 59 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc83xx/gtm/gtm.c | 4 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c | 2 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/preinstall.am | 4 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/shared/include/powerpc-utility.h | 344 |
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 /* |