Files
rtems/bsps/sparc64/shared/clock/ckinit.c
Sebastian Huber 7ee5931393 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.
2018-06-27 08:58:16 +02:00

118 lines
3.0 KiB
C

/* ckinit.c
*
* This file provides a template for the clock device driver initialization.
*
* Modified for sun4v - niagara
*/
/*
* Copyright (c) 2010 Gedare Bloom.
*
* 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 <stdlib.h>
#include <rtems.h>
#include <bsp.h>
#include <bspopts.h>
#include <boot/ofw.h>
#include <rtems/bspIo.h>
/* This is default frequency for simics simulator of niagara. Use the
* get_Frequency function to determine the CPU clock frequency at runtime.
*/
#define CPU_FREQ (5000000)
uint64_t sparc64_cycles_per_tick;
/* TICK_CMPR and STICK_CMPR trigger soft interrupt 14 */
#define CLOCK_VECTOR SPARC_SYNCHRONOUS_TRAP(0x4E)
static unsigned int get_Frequency(void)
{
phandle root = ofw_find_device("/");
unsigned int freq;
if (ofw_get_property(root, "clock-frequency", &freq, sizeof(freq)) <= 0) {
printk("Unable to determine frequency, default: 0x%x\n",CPU_FREQ);
return CPU_FREQ;
}
return freq;
}
#define Clock_driver_support_at_tick() \
Clock_driver_support_at_tick_helper()
static void Clock_driver_support_at_tick_helper(void)
{
uint64_t tick_reg;
int bit_mask;
uint64_t pil_reg;
bit_mask = SPARC_SOFTINT_TM_MASK | SPARC_SOFTINT_SM_MASK | (1<<14);
sparc64_clear_interrupt_bits(bit_mask);
sparc64_get_pil(pil_reg);
if(pil_reg == 0xe) { /* 0xe is the tick compare interrupt (softint(14)) */
pil_reg--;
sparc64_set_pil(pil_reg); /* enable the next timer interrupt */
}
/* Note: sun4v uses stick_cmpr for clock driver for M5 simulator, which
* does not currently have tick_cmpr implemented */
/* TODO: this could be more efficiently implemented as a single assembly
* inline */
#if defined (SUN4U)
sparc64_read_tick(tick_reg);
#elif defined (SUN4V)
sparc64_read_stick(tick_reg);
#endif
tick_reg &= ~(1UL<<63); /* mask out NPT bit, prevents int_dis from being set */
tick_reg += sparc64_cycles_per_tick;
#if defined (SUN4U)
sparc64_write_tick_cmpr(tick_reg);
#elif defined (SUN4V)
sparc64_write_stick_cmpr(tick_reg);
#endif
}
#define Clock_driver_support_install_isr(_new) \
set_vector( _new, CLOCK_VECTOR, 1 )
static void Clock_driver_support_initialize_hardware(void)
{
uint64_t tick_reg;
int bit_mask;
bit_mask = SPARC_SOFTINT_TM_MASK | SPARC_SOFTINT_SM_MASK | (1<<14);
sparc64_clear_interrupt_bits(bit_mask);
sparc64_cycles_per_tick =
rtems_configuration_get_microseconds_per_tick()*(get_Frequency()/1000000);
#if defined (SUN4U)
sparc64_read_tick(tick_reg);
#elif defined (SUN4V)
sparc64_read_stick(tick_reg);
#endif
tick_reg &= ~(1UL<<63); /* mask out NPT bit, prevents int_dis from being set */
tick_reg += sparc64_cycles_per_tick;
#if defined (SUN4U)
sparc64_write_tick_cmpr(tick_reg);
#elif defined (SUN4V)
sparc64_write_stick_cmpr(tick_reg);
#endif
}
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
#include "../../../shared/dev/clock/clockimpl.h"