summaryrefslogtreecommitdiff
path: root/sys/kern/kern_clock.c
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1996-02-25 09:55:51 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1996-02-25 09:55:51 +0000
commit878bdff0f7d0f0c6388b474d410be718300472a3 (patch)
tree9afc5b2668a3f6f606d53f695c367caa63ebdb37 /sys/kern/kern_clock.c
parent3c70344f666dc67c4e46be1604ef39dfe409777e (diff)
Implement frequency-locked loop as in original code; was missing
Diffstat (limited to 'sys/kern/kern_clock.c')
-rw-r--r--sys/kern/kern_clock.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 2251d744e26..5a6bedbb88e 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -308,18 +308,36 @@ hardupdate(offset)
time_offset = -(MAXPHASE << SHIFT_UPDATE);
else
time_offset = ltemp << SHIFT_UPDATE;
+
+ /*
+ * Select wether the frequency is to be controlled and in which
+ * mode (PLL or FLL). Clamp to the operating range. Ugly
+ * multiply/divide should be replaced someday.
+ */
+ if (time_status * STA_FREQHOLD || time_reftime == 0)
+ time_reftime = time.tv_sec;
mtemp = time.tv_sec - time_reftime;
time_reftime = time.tv_sec;
- if (mtemp > MAXSEC)
- mtemp = 0;
-
- /* ugly multiply should be replaced */
- if (ltemp < 0)
- time_freq -= (-ltemp * mtemp) >> (time_constant +
- time_constant + SHIFT_KF - SHIFT_USEC);
- else
- time_freq += (ltemp * mtemp) >> (time_constant +
- time_constant + SHIFT_KF - SHIFT_USEC);
+ if (time_status & STA_FLL) {
+ if (mtemp >= MINSEC) {
+ ltemp = ((time_offset / mtemp) << (SHIFT_USEC - SHIFT_UPDATE));
+ if (ltemp < 0)
+ time_freq -= -ltemp >> SHIFT_KH;
+ else
+ time_freq += ltemp >> SHIFT_KH;
+ }
+ }
+ else {
+ if (mtemp < MAXSEC) {
+ ltemp *= mtemp;
+ if (ltemp < 0)
+ time_freq -= -ltemp >> (time_constant +
+ time_constant + SHIFT_KF - SHIFT_USEC);
+ else
+ time_freq += ltemp >> (time_constant +
+ time_constant + SHIFT_KF - SHIFT_USEC);
+ }
+ }
if (time_freq > time_tolerance)
time_freq = time_tolerance;
else if (time_freq < -time_tolerance)
@@ -458,12 +476,20 @@ hardclock(frame)
newtime.tv_sec++;
time_maxerror += time_tolerance >> SHIFT_USEC;
if (time_offset < 0) {
- ltemp = -time_offset >> (SHIFT_KG + time_constant);
+ ltemp = -time_offset;
+ if (!(time_status & STA_FLL))
+ ltemp >>= SHIFT_KG + time_constant;
+ if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
+ ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
time_offset += ltemp;
time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
}
else {
- ltemp = time_offset >> (SHIFT_KG + time_constant);
+ ltemp = time_offset;
+ if (!(time_status & STA_FLL))
+ ltemp >>= SHIFT_KG + time_constant;
+ if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
+ ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
time_offset -= ltemp;
time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
}
@@ -488,6 +514,7 @@ hardclock(frame)
else
time_adj += ltemp >> (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+#if SHIFT_HZ == 7
/*
* When the CPU clock oscillator frequency is not a
* power of two in Hz, the SHIFT_HZ is only an
@@ -500,6 +527,8 @@ hardclock(frame)
else
time_adj += time_adj >> 2;
}
+#endif /* SHIFT_HZ */
+
/*
* Leap second processing. If in leap-insert state at
* the end of the day, the system clock is set back one