Commit fe4470bb authored by Alessandro Rubini's avatar Alessandro Rubini

support changing UTC/TAI offset

This patch adds support for modifying the utc/tai offset. The
"set" time operation, when called with a NULL pointer to the time
structure, will do the operation in its own arch-specific way.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent c842f754
...@@ -155,7 +155,7 @@ extern struct pp_network_operations unix_net_ops; ...@@ -155,7 +155,7 @@ extern struct pp_network_operations unix_net_ops;
* Time operations, like network operations above, are encapsulated. * Time operations, like network operations above, are encapsulated.
* They may live in their own time-<name> subdirectory. * They may live in their own time-<name> subdirectory.
* *
* Maybe this structure will need updating, to pass ppi as well * If "set" receives a NULL time value, it should update the TAI offset.
*/ */
struct pp_time_operations { struct pp_time_operations {
int (*get)(struct pp_instance *ppi, TimeInternal *t); int (*get)(struct pp_instance *ppi, TimeInternal *t);
......
...@@ -61,10 +61,12 @@ static void s1(struct pp_instance *ppi, MsgHeader *hdr, MsgAnnounce *ann) ...@@ -61,10 +61,12 @@ static void s1(struct pp_instance *ppi, MsgHeader *hdr, MsgAnnounce *ann)
/* Timeproperties DS */ /* Timeproperties DS */
prop->timeSource = ann->timeSource; prop->timeSource = ann->timeSource;
if (prop->currentUtcOffset != ann->currentUtcOffset) if (prop->currentUtcOffset != ann->currentUtcOffset) {
pp_diag(ppi, bmc, 1, "New UTC offset: %i\n", pp_diag(ppi, bmc, 1, "New UTC offset: %i\n",
ann->currentUtcOffset); ann->currentUtcOffset);
prop->currentUtcOffset = ann->currentUtcOffset; prop->currentUtcOffset = ann->currentUtcOffset;
ppi->t_ops->set(ppi, NULL);
}
/* FIXME: can't we just copy the bit keeping values? */ /* FIXME: can't we just copy the bit keeping values? */
prop->currentUtcOffsetValid = ((hdr->flagField[1] & FFB_UTCV) != 0); prop->currentUtcOffsetValid = ((hdr->flagField[1] & FFB_UTCV) != 0);
......
...@@ -29,6 +29,19 @@ static int bare_time_set(struct pp_instance *ppi, TimeInternal *t) ...@@ -29,6 +29,19 @@ static int bare_time_set(struct pp_instance *ppi, TimeInternal *t)
{ {
struct bare_timeval tv; struct bare_timeval tv;
if (!t) { /* Change the network notion of the utc/tai offset */
struct bare_timex t;
t.modes = MOD_TAI;
t.constant = DSPRO(ppi)->currentUtcOffset;
if (sys_adjtimex(&t) < 0)
pp_diag(ppi, time, 1, "Can't change TAI offset");
else
pp_diag(ppi, time, 1, "New TAI offset: %i\n",
DSPRO(ppi)->currentUtcOffset);
return 0;
}
/* UTC = TAI - 34 */ /* UTC = TAI - 34 */
tv.tv_sec = t->seconds - DSPRO(ppi)->currentUtcOffset; tv.tv_sec = t->seconds - DSPRO(ppi)->currentUtcOffset;
tv.tv_usec = t->nanoseconds / 1000; tv.tv_usec = t->nanoseconds / 1000;
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
#include <sys/timex.h> #include <sys/timex.h>
#include <ppsi/ppsi.h> #include <ppsi/ppsi.h>
#ifndef MOD_TAI
#define MOD_TAI 0x80
#endif
static void clock_fatal_error(char *context) static void clock_fatal_error(char *context)
{ {
pp_error("failure in \"%s\": %s\n.Exiting.\n", context, pp_error("failure in \"%s\": %s\n.Exiting.\n", context,
...@@ -34,10 +38,22 @@ static int unix_time_get(struct pp_instance *ppi, TimeInternal *t) ...@@ -34,10 +38,22 @@ static int unix_time_get(struct pp_instance *ppi, TimeInternal *t)
return 0; return 0;
} }
static int32_t unix_time_set(struct pp_instance *ppi, TimeInternal *t) static int unix_time_set(struct pp_instance *ppi, TimeInternal *t)
{ {
struct timespec tp; struct timespec tp;
if (!t) { /* Change the network notion of the utc/tai offset */
struct timex t;
t.modes = MOD_TAI;
t.constant = DSPRO(ppi)->currentUtcOffset;
if (adjtimex(&t) < 0)
clock_fatal_error("change TAI offset");
pp_diag(ppi, time, 1, "New TAI offset: %i\n",
DSPRO(ppi)->currentUtcOffset);
return 0;
}
/* UTC = TAI - 34 */ /* UTC = TAI - 34 */
tp.tv_sec = t->seconds - DSPRO(ppi)->currentUtcOffset; tp.tv_sec = t->seconds - DSPRO(ppi)->currentUtcOffset;
tp.tv_nsec = t->nanoseconds; tp.tv_nsec = t->nanoseconds;
......
...@@ -29,6 +29,9 @@ static int wrpc_time_set(struct pp_instance *ppi, TimeInternal *t) ...@@ -29,6 +29,9 @@ static int wrpc_time_set(struct pp_instance *ppi, TimeInternal *t)
uint64_t sec; uint64_t sec;
unsigned long nsec; unsigned long nsec;
if (!t) /* tai offset changed. We don't have it in wrpc-sw */
return 0;
sec = t->seconds; sec = t->seconds;
nsec = t->nanoseconds; nsec = t->nanoseconds;
......
...@@ -195,15 +195,17 @@ static int wrs_time_get(struct pp_instance *ppi, TimeInternal *t) ...@@ -195,15 +195,17 @@ static int wrs_time_get(struct pp_instance *ppi, TimeInternal *t)
return rval; return rval;
} }
static int32_t wrs_time_set(struct pp_instance *ppi, TimeInternal *t) static int wrs_time_set(struct pp_instance *ppi, TimeInternal *t)
{ {
TimeInternal diff; TimeInternal diff;
/* /*
* This is almost unused in ppsi, only proto-standard/servo.c * This is almost unused in ppsi, only proto-standard/servo.c
* calls it, at initialization time, when the offset is bigger * calls it, at initialization time, when the offset is bigger
* than one second. Run this transient by just adjusting the * than one second. Or ...
* WR seconds. Later on it will fix the nanos by ->adjust
*/ */
if (!t) /* ... when the utc/tai offset changes, if t is NULL */
return unix_time_ops.set(ppi, t);
pp_diag(ppi, time, 1, "%s: (weird) %9li.%09li\n", __func__, pp_diag(ppi, time, 1, "%s: (weird) %9li.%09li\n", __func__,
(long)t->seconds, (long)t->nanoseconds); (long)t->seconds, (long)t->nanoseconds);
/* We have no way to get the WR time, currently. So use our T3 */ /* We have no way to get the WR time, currently. So use our T3 */
......
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