diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-19 06:35:52 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 09:57:01 +0200 |
commit | 7632906fc290b652416ab59eb5fb49356c064ed6 (patch) | |
tree | ac036b1f95637e044e10138ceea8d2b56d80ec97 /bsps/powerpc/shared | |
parent | bsps: Move bspsmpgetcurrentprocessor.c to bsps (diff) | |
download | rtems-7632906fc290b652416ab59eb5fb49356c064ed6.tar.bz2 |
bsps: Move clock drivers to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/powerpc/shared')
-rw-r--r-- | bsps/powerpc/shared/clock/clock-ppc-dec.c (renamed from bsps/powerpc/shared/dev/clock-ppc-dec.c) | 0 | ||||
-rw-r--r-- | bsps/powerpc/shared/clock/clock-ppc403.c (renamed from bsps/powerpc/shared/dev/clock-ppc403.c) | 0 | ||||
-rw-r--r-- | bsps/powerpc/shared/clock/clock.c | 247 | ||||
-rw-r--r-- | bsps/powerpc/shared/clock/p_clock.c | 43 |
4 files changed, 290 insertions, 0 deletions
diff --git a/bsps/powerpc/shared/dev/clock-ppc-dec.c b/bsps/powerpc/shared/clock/clock-ppc-dec.c index c9bb16c451..c9bb16c451 100644 --- a/bsps/powerpc/shared/dev/clock-ppc-dec.c +++ b/bsps/powerpc/shared/clock/clock-ppc-dec.c diff --git a/bsps/powerpc/shared/dev/clock-ppc403.c b/bsps/powerpc/shared/clock/clock-ppc403.c index 64e6f29d39..64e6f29d39 100644 --- a/bsps/powerpc/shared/dev/clock-ppc403.c +++ b/bsps/powerpc/shared/clock/clock-ppc403.c diff --git a/bsps/powerpc/shared/clock/clock.c b/bsps/powerpc/shared/clock/clock.c new file mode 100644 index 0000000000..431488a901 --- /dev/null +++ b/bsps/powerpc/shared/clock/clock.c @@ -0,0 +1,247 @@ +/** + * @file + * + * @ingroup powerpc_shared + * + * @brief Source file for a clock driver. + */ + +/* + * Copyright (c) 2008-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 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.org/license/LICENSE. + */ + +#include <rtems.h> +#include <rtems/clockdrv.h> +#include <rtems/timecounter.h> + +#include <libcpu/powerpc-utility.h> +#include <bsp/vectors.h> + +#define RTEMS_STATUS_CHECKS_USE_PRINTK + +#include <rtems/status-checks.h> + +/* + * This variable must be defined in the BSP and valid before clock driver + * initialization. + */ +extern uint32_t bsp_time_base_frequency; + +#define PPC405_PIT 0x3db + +#define PPC_CLOCK_DECREMENTER_MAX UINT32_MAX + +volatile uint32_t Clock_driver_ticks = 0; + +static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX; + +static uint32_t ppc_clock_next_time_base; + +static struct timecounter ppc_tc; + +static uint32_t ppc_get_timecount(struct timecounter *tc) +{ + return ppc_time_base(); +} + +static void ppc_clock_no_tick(void) +{ + /* Do nothing */ +} + +static void (*ppc_clock_tick)(void) = ppc_clock_no_tick; + +static int ppc_clock_exception_handler( + BSP_Exception_frame *frame, + unsigned number +) +{ + uint32_t delta = ppc_clock_decrementer_value; + uint32_t next = ppc_clock_next_time_base; + uint32_t dec = 0; + uint32_t now = 0; + uint32_t msr = 0; + + do { + /* Increment clock ticks */ + Clock_driver_ticks += 1; + + /* Enable external exceptions */ + msr = ppc_external_exceptions_enable(); + + /* Call clock ticker */ + ppc_clock_tick(); + + /* Restore machine state */ + ppc_external_exceptions_disable( msr); + + /* Next time base */ + next += delta; + + /* Current time */ + now = ppc_time_base(); + + /* New decrementer value */ + dec = next - now; + } while (dec > delta); + + /* Set decrementer */ + ppc_set_decrementer_register( dec); + + /* Expected next time base */ + ppc_clock_next_time_base = next; + + return 0; +} + +static int ppc_clock_exception_handler_first( + BSP_Exception_frame *frame, + unsigned number +) +{ + /* We have to clear the first pending decrementer exception this way */ + + if (ppc_decrementer_register() >= 0x80000000) { + ppc_clock_exception_handler( frame, number); + } + + ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler); + + return 0; +} + +static int ppc_clock_exception_handler_booke( + BSP_Exception_frame *frame, + unsigned number +) +{ + uint32_t msr; + + /* Acknowledge decrementer request */ + PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS); + + /* Increment clock ticks */ + Clock_driver_ticks += 1; + + /* Enable external exceptions */ + msr = ppc_external_exceptions_enable(); + + /* Call clock ticker */ + ppc_clock_tick(); + + /* Restore machine state */ + ppc_external_exceptions_disable( msr); + + return 0; +} + +static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsigned number) +{ + uint32_t msr; + + /* Acknowledge PIT request */ + PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS); + + /* Increment clock ticks */ + Clock_driver_ticks += 1; + + /* Enable external exceptions */ + msr = ppc_external_exceptions_enable(); + + /* Call clock ticker */ + ppc_clock_tick(); + + /* Restore machine state */ + ppc_external_exceptions_disable(msr); + + return 0; +} + +void Clock_exit(void) +{ + /* Set the decrementer to the maximum value */ + ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX); + + /* Use default clock handler */ + ppc_clock_tick = ppc_clock_no_tick; +} + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + uint64_t frequency = bsp_time_base_frequency; + uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); + uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000); + + /* + * Set default ticker. + */ + ppc_clock_tick = rtems_timecounter_tick; + + if (ppc_cpu_is_bookE() != PPC_BOOKE_405) { + /* Decrementer value */ + ppc_clock_decrementer_value = interval - 1; + + /* Check decrementer value */ + if (ppc_clock_decrementer_value == 0) { + ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX; + RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n"); + } + if (ppc_cpu_is_bookE()) { + /* Set decrementer auto-reload 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 */ + PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE); + } else { + /* Here the decrementer value is actually the interval */ + ++ppc_clock_decrementer_value; + + /* 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_first); + } + + /* Set the decrementer value */ + ppc_set_decrementer_register( ppc_clock_decrementer_value); + } else { + /* PIT interval value */ + ppc_clock_decrementer_value = interval; + + /* Install exception handler */ + ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405); + + /* Enable PIT and auto-reload */ + PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE); + + /* Set PIT auto-reload and initial value */ + PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval); + } + + /* Install timecounter */ + ppc_tc.tc_get_timecount = ppc_get_timecount; + ppc_tc.tc_counter_mask = 0xffffffff; + ppc_tc.tc_frequency = frequency; + ppc_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&ppc_tc); + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/powerpc/shared/clock/p_clock.c b/bsps/powerpc/shared/clock/p_clock.c new file mode 100644 index 0000000000..1ff7ca06a6 --- /dev/null +++ b/bsps/powerpc/shared/clock/p_clock.c @@ -0,0 +1,43 @@ +/* + * Clock Tick interrupt conexion code. + */ + +/* + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Modified to support the MPC750. + * Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <libcpu/c_clock.h> +#include <libcpu/cpuIdent.h> + +static rtems_irq_connect_data clockIrqData; +static rtems_irq_connect_data clockIrqData = { + BSP_DECREMENTER, + clockIsr, + NULL, + (rtems_irq_enable)clockOn, + (rtems_irq_disable)clockOff, + (rtems_irq_is_enabled) clockIsOn +}; + +int BSP_disconnect_clock_handler(void) +{ + return BSP_remove_rtems_irq_handler(&clockIrqData); +} + +int BSP_connect_clock_handler(void) +{ + if ( ppc_cpu_is_bookE() ) + clockIrqData.hdl = clockIsrBookE; + + return BSP_install_rtems_irq_handler(&clockIrqData); +} |