Commit d9499c1e authored by Philippe Gerum's avatar Philippe Gerum Committed by Jan Kiszka

cobalt/clock: pipeline: move TSC-related code to the I-pipe section

Cobalt over Dovetail represents time values as counts of nanoseconds,
dismissing the legacy (hardware) TSC representation entirely. For this
reason, we can move any code which implements TSC/nanosecs conversion
to the I-pipe specific section.

This includes the handler applying CPU frequency updates
(xnclock_update_freq()) which has no purpose over Dovetail, since
these events are transparently dealt with for the proxy device by the
generic clockevent framework.

No functional change is introduced.
Signed-off-by: Philippe Gerum's avatarPhilippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent b10574bc
......@@ -348,9 +348,7 @@ static inline void xnclock_init_proc(void) { }
static inline void xnclock_cleanup_proc(void) { }
#endif
void xnclock_update_freq(unsigned long long freq);
int xnclock_init(unsigned long long freq);
int xnclock_init(void);
void xnclock_cleanup(void);
......
......@@ -33,4 +33,8 @@ static inline const char *pipeline_clock_name(void)
int pipeline_get_host_time(struct timespec *tp);
void pipeline_update_clock_freq(unsigned long long freq);
void pipeline_init_clock(void);
#endif /* !_COBALT_KERNEL_IPIPE_CLOCK_H */
......@@ -34,22 +34,10 @@
*/
unsigned long nktimerlat;
static unsigned long long clockfreq;
#ifdef XNARCH_HAVE_LLMULSHFT
static unsigned int tsc_scale, tsc_shift;
#ifdef XNARCH_HAVE_NODIV_LLIMD
static struct xnarch_u32frac tsc_frac;
static struct xnarch_u32frac bln_frac;
long long xnclock_core_ns_to_ticks(long long ns)
{
return xnarch_nodiv_llimd(ns, tsc_frac.frac, tsc_frac.integ);
}
unsigned long long xnclock_divrem_billion(unsigned long long value,
unsigned long *rem)
{
......@@ -66,57 +54,17 @@ unsigned long long xnclock_divrem_billion(unsigned long long value,
return q;
}
#else /* !XNARCH_HAVE_NODIV_LLIMD */
long long xnclock_core_ns_to_ticks(long long ns)
{
return xnarch_llimd(ns, 1 << tsc_shift, tsc_scale);
}
#endif /* !XNARCH_HAVE_NODIV_LLIMD */
xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks)
{
return xnarch_llmulshft(ticks, tsc_scale, tsc_shift);
}
xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks)
{
unsigned int shift = tsc_shift - 1;
return (xnarch_llmulshft(ticks, tsc_scale, shift) + 1) / 2;
}
#else /* !XNARCH_HAVE_LLMULSHFT */
xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks)
{
return xnarch_llimd(ticks, 1000000000, clockfreq);
}
#else
xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks)
{
return (xnarch_llimd(ticks, 1000000000, clockfreq/2) + 1) / 2;
}
xnsticks_t xnclock_core_ns_to_ticks(xnsticks_t ns)
{
return xnarch_llimd(ns, clockfreq, 1000000000);
}
#endif /* !XNARCH_HAVE_LLMULSHFT */
#ifndef XNARCH_HAVE_NODIV_LLIMD
unsigned long long xnclock_divrem_billion(unsigned long long value,
unsigned long *rem)
{
return xnarch_ulldiv(value, 1000000000, rem);
}
#endif /* !XNARCH_HAVE_NODIV_LLIMD */
EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns);
EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns_rounded);
EXPORT_SYMBOL_GPL(xnclock_core_ns_to_ticks);
EXPORT_SYMBOL_GPL(xnclock_divrem_billion);
DEFINE_PRIVATE_XNLOCK(ratelimit_lock);
......@@ -823,23 +771,6 @@ void xnclock_tick(struct xnclock *clock)
}
EXPORT_SYMBOL_GPL(xnclock_tick);
void xnclock_update_freq(unsigned long long freq)
{
spl_t s;
xnlock_get_irqsave(&nklock, s);
clockfreq = freq;
#ifdef XNARCH_HAVE_LLMULSHFT
xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
#ifdef XNARCH_HAVE_NODIV_LLIMD
xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
xnarch_init_u32frac(&bln_frac, 1, 1000000000);
#endif
#endif
cobalt_pipeline.clock_freq = freq;
xnlock_put_irqrestore(&nklock, s);
}
static int set_core_clock_gravity(struct xnclock *clock,
const struct xnclock_gravity *p)
{
......@@ -880,9 +811,12 @@ void xnclock_cleanup(void)
xnclock_deregister(&nkclock);
}
int __init xnclock_init(unsigned long long freq)
int __init xnclock_init()
{
xnclock_update_freq(freq);
#ifdef XNARCH_HAVE_NODIV_LLIMD
xnarch_init_u32frac(&bln_frac, 1, 1000000000);
#endif
pipeline_init_clock();
nktimerlat = xnarch_timer_calibrate();
xnclock_reset_gravity(&nkclock);
xnclock_register(&nkclock, &xnsched_realtime_cpus);
......
......@@ -6,6 +6,66 @@
#include <cobalt/kernel/clock.h>
#include <cobalt/kernel/vdso.h>
#include <cobalt/kernel/arith.h>
#include <pipeline/machine.h>
static unsigned long long clockfreq;
#ifdef XNARCH_HAVE_LLMULSHFT
static unsigned int tsc_scale, tsc_shift;
#ifdef XNARCH_HAVE_NODIV_LLIMD
static struct xnarch_u32frac tsc_frac;
long long xnclock_core_ns_to_ticks(long long ns)
{
return xnarch_nodiv_llimd(ns, tsc_frac.frac, tsc_frac.integ);
}
#else /* !XNARCH_HAVE_NODIV_LLIMD */
long long xnclock_core_ns_to_ticks(long long ns)
{
return xnarch_llimd(ns, 1 << tsc_shift, tsc_scale);
}
#endif /* !XNARCH_HAVE_NODIV_LLIMD */
xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks)
{
return xnarch_llmulshft(ticks, tsc_scale, tsc_shift);
}
xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks)
{
unsigned int shift = tsc_shift - 1;
return (xnarch_llmulshft(ticks, tsc_scale, shift) + 1) / 2;
}
#else /* !XNARCH_HAVE_LLMULSHFT */
xnsticks_t xnclock_core_ticks_to_ns(xnsticks_t ticks)
{
return xnarch_llimd(ticks, 1000000000, clockfreq);
}
xnsticks_t xnclock_core_ticks_to_ns_rounded(xnsticks_t ticks)
{
return (xnarch_llimd(ticks, 1000000000, clockfreq/2) + 1) / 2;
}
xnsticks_t xnclock_core_ns_to_ticks(xnsticks_t ns)
{
return xnarch_llimd(ns, clockfreq, 1000000000);
}
#endif /* !XNARCH_HAVE_LLMULSHFT */
EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns);
EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns_rounded);
EXPORT_SYMBOL_GPL(xnclock_core_ns_to_ticks);
int pipeline_get_host_time(struct timespec *tp)
{
......@@ -60,3 +120,24 @@ int pipeline_get_host_time(struct timespec *tp)
return -EINVAL;
#endif
}
void pipeline_update_clock_freq(unsigned long long freq)
{
spl_t s;
xnlock_get_irqsave(&nklock, s);
clockfreq = freq;
#ifdef XNARCH_HAVE_LLMULSHFT
xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
#ifdef XNARCH_HAVE_NODIV_LLIMD
xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
#endif
#endif
cobalt_pipeline.clock_freq = freq;
xnlock_put_irqrestore(&nklock, s);
}
void pipeline_init_clock(void)
{
pipeline_update_clock_freq(cobalt_pipeline.clock_freq);
}
......@@ -61,7 +61,7 @@ int __init pipeline_init(void)
(ipipe_irq_handler_t)__xnsched_run_handler,
NULL, NULL);
ret = xnclock_init(cobalt_pipeline.clock_freq);
ret = xnclock_init();
if (ret)
goto fail_clock;
......
......@@ -16,6 +16,7 @@
#include <pipeline/kevents.h>
#include <cobalt/kernel/sched.h>
#include <cobalt/kernel/thread.h>
#include <cobalt/kernel/clock.h>
#include <cobalt/kernel/vdso.h>
#include <rtdm/driver.h>
#include <trace/events/cobalt-core.h>
......@@ -675,7 +676,7 @@ static inline int handle_clockfreq_event(unsigned int *p)
{
unsigned int newfreq = *p;
xnclock_update_freq(newfreq);
pipeline_update_clock_freq(newfreq);
return KEVENT_PROPAGATE;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment