source: rtems/bsps/powerpc/qoriq/clock/clock-config.c @ 7ee59313

5
Last change on this file since 7ee59313 was 7ee59313, checked in by Sebastian Huber <sebastian.huber@…>, on 06/01/18 at 05:11:12

Remove Clock_driver_support_shutdown_hardware()

The aim of this clock driver hook was to stop clock tick interrupts at
some late point in the exit() procedure.

The use of atexit() pulls in malloc() which pulls in errno. It is
incompatible with the intention of the
CONFIGURE_DISABLE_NEWLIB_REENTRANCY configuration option.

The exit() function must be called from thread context, so accompanied
clock tick interrupts should cause no harm. On the contrary, someone
may assume a normal operating system operation, e.g. working timeouts.

Remove the Clock_driver_support_shutdown_hardware() clock driver hook.

Close #3436.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief QorIQ clock configuration.
7 */
8
9/*
10 * Copyright (c) 2011, 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <rtems/timecounter.h>
24
25#include <libcpu/powerpc-utility.h>
26
27#include <bsp.h>
28#include <bsp/qoriq.h>
29#include <bsp/irq.h>
30
31/* This is defined in dev/clock/clockimpl.h */
32static rtems_isr Clock_isr(void *arg);
33
34static struct timecounter qoriq_clock_tc;
35
36#ifdef QORIQ_IS_HYPERVISOR_GUEST
37
38#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
39
40void qoriq_decrementer_dispatch(void)
41{
42  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_TSR, BOOKE_TSR_DIS);
43  Clock_isr(NULL);
44}
45
46static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
47{
48  return ppc_alternate_time_base();
49}
50
51static void qoriq_clock_initialize(void)
52{
53  uint64_t frequency = bsp_time_base_frequency;
54  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
55  uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
56
57  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1);
58  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(
59    BOOKE_TCR,
60    BOOKE_TCR_DIE | BOOKE_TCR_ARE
61  );
62  ppc_set_decrementer_register(interval - 1);
63
64  qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
65  qoriq_clock_tc.tc_counter_mask = 0xffffffff;
66  qoriq_clock_tc.tc_frequency = qoriq_clock_frequency;
67  qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
68  rtems_timecounter_install(&qoriq_clock_tc);
69}
70
71#else /* !QORIQ_IS_HYPERVISOR_GUEST */
72
73static volatile qoriq_pic_global_timer *const qoriq_clock =
74  #if QORIQ_CLOCK_TIMER < 4
75    &qoriq.pic.gta [QORIQ_CLOCK_TIMER];
76  #else
77    &qoriq.pic.gtb [QORIQ_CLOCK_TIMER - 4];
78  #endif
79
80static volatile qoriq_pic_global_timer *const qoriq_timecounter =
81  #if QORIQ_CLOCK_TIMECOUNTER < 4
82    &qoriq.pic.gta [QORIQ_CLOCK_TIMECOUNTER];
83  #else
84    &qoriq.pic.gtb [QORIQ_CLOCK_TIMECOUNTER - 4];
85  #endif
86
87#define CLOCK_INTERRUPT (QORIQ_IRQ_GT_BASE + QORIQ_CLOCK_TIMER)
88
89static void qoriq_clock_handler_install(void)
90{
91  rtems_status_code sc = RTEMS_SUCCESSFUL;
92
93#if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)
94  {
95    Processor_mask affinity;
96
97    _Processor_mask_From_index(&affinity, ppc_processor_id());
98    bsp_interrupt_set_affinity(CLOCK_INTERRUPT, &affinity);
99  }
100#endif
101
102  sc = qoriq_pic_set_priority(
103    CLOCK_INTERRUPT,
104    QORIQ_PIC_PRIORITY_LOWEST,
105    NULL
106  );
107  if (sc != RTEMS_SUCCESSFUL) {
108    rtems_fatal_error_occurred(0xdeadbeef);
109  }
110
111  sc = rtems_interrupt_handler_install(
112    CLOCK_INTERRUPT,
113    "Clock",
114    RTEMS_INTERRUPT_UNIQUE,
115    Clock_isr,
116    NULL
117  );
118  if (sc != RTEMS_SUCCESSFUL) {
119    rtems_fatal_error_occurred(0xdeadbeef);
120  }
121}
122
123static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
124{
125  uint32_t ccr = qoriq_timecounter->ccr;
126
127  return GTCCR_COUNT_GET(-ccr);
128}
129
130static void qoriq_clock_initialize(void)
131{
132  uint32_t timer_frequency = BSP_bus_frequency / 8;
133  uint32_t interval = (uint32_t) (((uint64_t) timer_frequency
134    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000);
135
136  qoriq_clock->bcr = GTBCR_COUNT(interval);
137
138  qoriq_timecounter->bcr = GTBCR_COUNT(0xffffffff);
139
140  qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
141  qoriq_clock_tc.tc_counter_mask = GTCCR_COUNT_GET(0xffffffff);
142  qoriq_clock_tc.tc_frequency = timer_frequency;
143  qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
144  rtems_timecounter_install(&qoriq_clock_tc);
145}
146
147#define Clock_driver_support_install_isr(clock_isr) \
148  qoriq_clock_handler_install()
149
150#define Clock_driver_support_set_interrupt_affinity(online_processors) \
151  bsp_interrupt_set_affinity(CLOCK_INTERRUPT, online_processors)
152
153#endif /* QORIQ_IS_HYPERVISOR_GUEST */
154
155#define Clock_driver_support_initialize_hardware() \
156  qoriq_clock_initialize()
157
158/* Include shared source clock driver code */
159#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.