diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/include/rtems/score/timecounter.h | 9 | ||||
-rw-r--r-- | cpukit/include/sys/timex.h | 4 | ||||
-rw-r--r-- | cpukit/posix/src/adjtime.c | 93 | ||||
-rw-r--r-- | cpukit/score/src/kern_ntptime.c | 138 | ||||
-rw-r--r-- | cpukit/score/src/kern_tc.c | 6 |
5 files changed, 152 insertions, 98 deletions
diff --git a/cpukit/include/rtems/score/timecounter.h b/cpukit/include/rtems/score/timecounter.h index 39f0dc353e..954da65676 100644 --- a/cpukit/include/rtems/score/timecounter.h +++ b/cpukit/include/rtems/score/timecounter.h @@ -270,6 +270,15 @@ void _Timecounter_Set_NTP_update_second( Timecounter_NTP_update_second handler ); +/** + * @brief Updates the time adjustment and seconds according to the NTP state. + * + * @param[in, out] adjustment is the NTP time adjustment. + * + * @param[in, out] newsec is the number of seconds since Unix epoch. + */ +void _Timecounter_NTP_update_second(int64_t *adjustment, time_t *newsec); + /** @} */ #ifdef __cplusplus diff --git a/cpukit/include/sys/timex.h b/cpukit/include/sys/timex.h index d2d2012ff5..8e763bb30f 100644 --- a/cpukit/include/sys/timex.h +++ b/cpukit/include/sys/timex.h @@ -37,7 +37,7 @@ #define NTP_API 4 /* NTP API version */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__rtems__) #include <sys/_timespec.h> #endif /* __FreeBSD__ */ @@ -153,7 +153,7 @@ struct timex { long stbcnt; /* stability limit exceeded (ro) */ }; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__rtems__) #ifdef _KERNEL void ntp_update_second(int64_t *adjustment, time_t *newsec); diff --git a/cpukit/posix/src/adjtime.c b/cpukit/posix/src/adjtime.c deleted file mode 100644 index ec8cb19a2e..0000000000 --- a/cpukit/posix/src/adjtime.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file - * - * @brief Adjust the Time to Synchronize the System Clock - * @ingroup POSIXAPI - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _BSD_SOURCE -#include <time.h> -#include <sys/time.h> -#include <errno.h> - -#include <rtems/score/timespec.h> -#include <rtems/score/threaddispatch.h> -#include <rtems/score/todimpl.h> -#include <rtems/config.h> -#include <rtems/seterr.h> - -/** - * This method was initially added as part of porting NTP to RTEMS. - * It is a BSD compatability function and now is available on - * GNU/Linux. - * - * At one point there was a static variable named adjustment - * used by this implementation. I don't see any reason for it - * to be here based upon the GNU/Linux documentation. - */ -int adjtime( - const struct timeval *delta, - struct timeval *olddelta -) -{ - struct timespec delta_as_timespec; - Status_Control status; - - /* - * Simple validations - */ - if ( !delta ) - rtems_set_errno_and_return_minus_one( EINVAL ); - - if ( delta->tv_usec >= TOD_MICROSECONDS_PER_SECOND ) - rtems_set_errno_and_return_minus_one( EINVAL ); - - /* - * An adjustment of zero is pretty easy. - */ - if ( delta->tv_sec == 0 && delta->tv_usec == 0 ) - return 0; - - /* - * Currently, RTEMS does the adjustment in one movement so there - * is no way an adjustment was currently underway. - * - * Given interest, requirements, and sponsorship, a future - * enhancement would be to adjust the time in smaller increments - * at each clock tick. Until then, there is no outstanding - * adjustment. - */ - if ( olddelta ) { - olddelta->tv_sec = 0; - olddelta->tv_usec = 0; - } - - /* - * convert delta timeval to timespec - */ - delta_as_timespec.tv_sec = delta->tv_sec; - delta_as_timespec.tv_nsec = delta->tv_usec * 1000; - - /* - * Now apply the adjustment - */ - status = _TOD_Adjust( &delta_as_timespec ); - if ( status != STATUS_SUCCESSFUL ) { - rtems_set_errno_and_return_minus_one( STATUS_GET_POSIX( status ) ); - } - - return 0; -} diff --git a/cpukit/score/src/kern_ntptime.c b/cpukit/score/src/kern_ntptime.c index 96f14a408b..cb39133408 100644 --- a/cpukit/score/src/kern_ntptime.c +++ b/cpukit/score/src/kern_ntptime.c @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSScoreTimecounter + * + * @brief This source file contains the implementation of ntp_gettime(), + * ntp_adjtime(), adjtime(), and _Timecounter_NTP_update_second(). + */ + /*- *********************************************************************** * * @@ -36,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include "opt_ntp.h" #include <sys/param.h> +#ifndef __rtems__ #include <sys/systm.h> #include <sys/sysproto.h> #include <sys/eventhandler.h> @@ -44,12 +54,24 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/lock.h> #include <sys/mutex.h> +#endif /* __rtems__ */ #include <sys/time.h> #include <sys/timex.h> #include <sys/timetc.h> #include <sys/timepps.h> +#ifndef __rtems__ #include <sys/syscallsubr.h> #include <sys/sysctl.h> +#else /* __rtems__ */ +#include <rtems/sysinit.h> +#include <rtems/score/timecounter.h> +#include <errno.h> +#include <string.h> +#define nanotime(_tsp) _Timecounter_Nanotime(_tsp) +#define ntp_update_second _Timecounter_NTP_update_second +#define time_uptime _Timecounter_Time_uptime +struct thread; +#endif /* __rtems__ */ #ifdef PPS_SYNC FEATURE(pps_sync, "Support usage of external PPS signal by kernel PLL"); @@ -148,12 +170,18 @@ typedef int64_t l_fp; #define SHIFT_FLL 2 /* FLL loop gain (shift) */ static int time_state = TIME_OK; /* clock state */ +#ifdef __rtems__ +static +#endif /* __rtems__ */ int time_status = STA_UNSYNC; /* clock status bits */ static long time_tai; /* TAI offset (s) */ static long time_monitor; /* last time offset scaled (ns) */ static long time_constant; /* poll interval (shift) (s) */ static long time_precision = 1; /* clock precision (ns) */ static long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */ +#ifdef __rtems__ +static +#endif /* __rtems__ */ long time_esterror = MAXPHASE / 1000; /* estimated error (us) */ static long time_reftime; /* uptime at last adjustment (s) */ static l_fp time_offset; /* time offset (ns) */ @@ -162,12 +190,24 @@ static l_fp time_adj; /* tick adjust (ns/s) */ static int64_t time_adjtime; /* correction from adjtime(2) (usec) */ +#ifndef __rtems__ static struct mtx ntp_lock; MTX_SYSINIT(ntp, &ntp_lock, "ntp", MTX_SPIN); #define NTP_LOCK() mtx_lock_spin(&ntp_lock) #define NTP_UNLOCK() mtx_unlock_spin(&ntp_lock) #define NTP_ASSERT_LOCKED() mtx_assert(&ntp_lock, MA_OWNED) +#else /* __rtems__ */ +#define NTP_LOCK() \ + do { \ + ISR_lock_Context lock_context; \ + _Timecounter_Acquire(&lock_context); +#define NTP_UNLOCK() \ + _Timecounter_Release(&lock_context); \ + } while (0) +#define NTP_ASSERT_LOCKED() \ + _Assert(_ISR_lock_Is_owner(&_Timecounter_Lock)) +#endif /* __rtems__ */ #ifdef PPS_SYNC /* @@ -273,6 +313,7 @@ ntp_gettime1(struct ntptimeval *ntvp) * See the timex.h header file for synopsis and API description. Note that * the TAI offset is returned in the ntvtimeval.tai structure member. */ +#ifndef __rtems__ #ifndef _SYS_SYSPROTO_H_ struct ntp_gettime_args { struct ntptimeval *ntvp; @@ -293,7 +334,27 @@ sys_ntp_gettime(struct thread *td, struct ntp_gettime_args *uap) td->td_retval[0] = ntv.time_state; return (copyout(&ntv, uap->ntvp, sizeof(ntv))); } +#else /* __rtems__ */ +int +ntp_gettime(struct ntptimeval *ntv) +{ + + if (ntv == NULL) { + errno = EFAULT; + return (-1); + } + + ntv = memset(ntv, 0, sizeof(*ntv)); + NTP_LOCK(); + ntp_gettime1(ntv); + NTP_UNLOCK(); + + return (ntv->time_state); +} +#endif /* __rtems__ */ + +#ifndef __rtems__ static int ntp_sysctl(SYSCTL_HANDLER_ARGS) { @@ -313,6 +374,7 @@ SYSCTL_NODE(_kern, OID_AUTO, ntp_pll, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, SYSCTL_PROC(_kern_ntp_pll, OID_AUTO, gettime, CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, sizeof(struct ntptimeval) , ntp_sysctl, "S,ntptimeval", ""); +#endif /* __rtems__ */ #ifdef PPS_SYNC SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW, @@ -337,12 +399,19 @@ SYSCTL_S64(_kern_ntp_pll, OID_AUTO, time_freq, CTLFLAG_RD | CTLFLAG_MPSAFE, * the timex.constant structure member has a dual purpose to set the time * constant and to set the TAI offset. */ +#ifdef __rtems__ +static +#endif /* __rtems__ */ int kern_ntp_adjtime(struct thread *td, struct timex *ntv, int *retvalp) { long freq; /* frequency ns/s) */ int modes; /* mode bits from structure */ +#ifndef __rtems__ int error, retval; +#else /* __rtems__ */ + int retval; +#endif /* __rtems__ */ /* * Update selected clock variables - only the superuser can @@ -354,11 +423,13 @@ kern_ntp_adjtime(struct thread *td, struct timex *ntv, int *retvalp) * status words are reset to the initial values at boot. */ modes = ntv->modes; +#ifndef __rtems__ error = 0; if (modes) error = priv_check(td, PRIV_NTP_ADJTIME); if (error != 0) return (error); +#endif /* __rtems__ */ NTP_LOCK(); if (modes & MOD_MAXERROR) time_maxerror = ntv->maxerror; @@ -460,6 +531,16 @@ kern_ntp_adjtime(struct thread *td, struct timex *ntv, int *retvalp) ntv->jitcnt = pps_jitcnt; ntv->stbcnt = pps_stbcnt; #endif /* PPS_SYNC */ +#ifdef __rtems__ + ntv->ppsfreq = 0; + ntv->jitter = 0; + ntv->shift = 0; + ntv->stabil = 0; + ntv->jitcnt = 0; + ntv->calcnt = 0; + ntv->errcnt = 0; + ntv->stbcnt = 0; +#endif /* __rtems__ */ retval = ntp_is_time_error(time_status) ? TIME_ERROR : time_state; NTP_UNLOCK(); @@ -473,6 +554,7 @@ struct ntp_adjtime_args { }; #endif +#ifndef __rtems__ int sys_ntp_adjtime(struct thread *td, struct ntp_adjtime_args *uap) { @@ -490,6 +572,23 @@ sys_ntp_adjtime(struct thread *td, struct ntp_adjtime_args *uap) } return (error); } +#else /* __rtems__ */ +int +ntp_adjtime(struct timex *ntv) +{ + int error; + int retval; + + if (ntv == NULL) { + errno = EFAULT; + return (-1); + } + + error = kern_ntp_adjtime(NULL, ntv, &retval); + _Assert_Unused_variable_equals(error, 0); + return (retval); +} +#endif /* __rtems__ */ /* * second_overflow() - called after ntp_tick_adjust() @@ -505,7 +604,11 @@ ntp_update_second(int64_t *adjustment, time_t *newsec) int tickrate; l_fp ftemp; /* 32/64-bit temporary */ +#ifndef __rtems__ NTP_LOCK(); +#else /* __rtems__ */ + NTP_ASSERT_LOCKED(); +#endif /* __rtems__ */ /* * On rollover of the second both the nanosecond and microsecond @@ -628,9 +731,22 @@ ntp_update_second(int64_t *adjustment, time_t *newsec) time_status &= ~STA_PPSSIGNAL; #endif /* PPS_SYNC */ +#ifndef __rtems__ NTP_UNLOCK(); +#endif /* __rtems__ */ +} +#ifdef __rtems__ +static void +_NTP_Initialize(void) +{ + + _Timecounter_Set_NTP_update_second(ntp_update_second); } +RTEMS_SYSINIT_ITEM(_NTP_Initialize, RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_FOURTH); +#endif /* __rtems__ */ + /* * hardupdate() - local clock update * @@ -930,6 +1046,7 @@ out: } #endif /* PPS_SYNC */ +#ifndef __rtems__ #ifndef _SYS_SYSPROTO_H_ struct adjtime_args { struct timeval *delta; @@ -958,15 +1075,23 @@ sys_adjtime(struct thread *td, struct adjtime_args *uap) int kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta) +#else /* __rtems__ */ +static int +kern_adjtime(const struct timeval *delta, struct timeval *olddelta) +#endif /* __rtems__ */ { struct timeval atv; int64_t ltr, ltw; +#ifndef __rtems__ int error; +#endif /* __rtems__ */ if (delta != NULL) { +#ifndef __rtems__ error = priv_check(td, PRIV_ADJTIME); if (error != 0) return (error); +#endif /* __rtems__ */ ltw = (int64_t)delta->tv_sec * 1000000 + delta->tv_usec; } NTP_LOCK(); @@ -985,7 +1110,19 @@ kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta) } return (0); } +#ifdef __rtems__ +int +adjtime(const struct timeval *delta, struct timeval *olddelta) +{ + int error; + + error = kern_adjtime(delta, olddelta); + _Assert_Unused_variable_equals(error, 0); + return (0); +} +#endif /* __rtems__ */ +#ifndef __rtems__ static struct callout resettodr_callout; static int resettodr_period = 1800; @@ -1051,3 +1188,4 @@ start_periodic_resettodr(void *arg __unused) SYSINIT(periodic_resettodr, SI_SUB_LAST, SI_ORDER_MIDDLE, start_periodic_resettodr, NULL); +#endif /* __rtems__ */ diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index b757a2e28c..e57da2c0ca 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -135,13 +135,13 @@ atomic_load_ptr(void *ptr) return ((void *)_Atomic_Load_uintptr(ptr, ATOMIC_ORDER_RELAXED)); } -static Timecounter_NTP_update_second _Timecounter_NTP_update_second; +static Timecounter_NTP_update_second _Timecounter_NTP_update_second_handler; void _Timecounter_Set_NTP_update_second(Timecounter_NTP_update_second handler) { - _Timecounter_NTP_update_second = handler; + _Timecounter_NTP_update_second_handler = handler; } #define ntp_update_second(a, b) (*ntp_update_second_handler)(a, b) @@ -1721,7 +1721,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, bt = th->th_offset; bintime_add(&bt, &th->th_boottime); #ifdef __rtems__ - ntp_update_second_handler = _Timecounter_NTP_update_second; + ntp_update_second_handler = _Timecounter_NTP_update_second_handler; if (ntp_update_second_handler != NULL) { #endif /* __rtems__ */ i = bt.sec - tho->th_microtime.tv_sec; |