summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_tc.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1999-07-18 15:07:20 +0000
committerbde <bde@FreeBSD.org>1999-07-18 15:07:20 +0000
commit9ea61245a8fa724c231c6740852b5a8bc59549ac (patch)
treebc31fd524267dd705b46a40fbc5a62ff6dc3603d /sys/kern/kern_tc.c
parenta686f581bc15ec73b10b8f70547c9f1ee0d10e5e (diff)
downloadFreeBSD-src-9ea61245a8fa724c231c6740852b5a8bc59549ac.zip
FreeBSD-src-9ea61245a8fa724c231c6740852b5a8bc59549ac.tar.gz
Added a sysctl "kern.timecounter.hardware" for selecting the hardware
used for timecounting. The possible values are the names of the physically present harware timecounters ("i8254" and "TSC" on i386's). Fixed some nearby bitrot in comments in <sys/time.h>. Reviewed by: phk
Diffstat (limited to 'sys/kern/kern_tc.c')
-rw-r--r--sys/kern/kern_tc.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 23918b1..de15f18 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_clock.c,v 1.94 1999/04/25 08:59:59 phk Exp $
+ * $Id: kern_clock.c,v 1.95 1999/07/18 01:35:26 jdp Exp $
*/
#include "opt_ntp.h"
@@ -679,7 +679,14 @@ init_timecounter(struct timecounter *tc)
tc->tc_tweak = tc;
tco_setscales(tc);
tc->tc_offset_count = tc->tc_get_timecount(tc);
+ if (timecounter == &dummy_timecounter)
+ tc->tc_avail = tc;
+ else {
+ tc->tc_avail = timecounter->tc_tweak->tc_avail;
+ timecounter->tc_tweak->tc_avail = tc;
+ }
MALLOC(t1, struct timecounter *, sizeof *t1, M_TIMECOUNTER, M_WAITOK);
+ tc->tc_other = t1;
*t1 = *tc;
t2 = t1;
for (i = 1; i < NTIMECOUNTER; i++) {
@@ -720,9 +727,7 @@ set_timecounter(struct timespec *ts)
tco_forward(1);
}
-
-#if 0 /* Currently unused */
-void
+static void
switch_timecounter(struct timecounter *newtc)
{
int s;
@@ -731,19 +736,20 @@ switch_timecounter(struct timecounter *newtc)
s = splclock();
tc = timecounter;
- if (newtc == tc || newtc == tc->tc_other) {
+ if (newtc->tc_tweak == tc->tc_tweak) {
splx(s);
return;
}
+ newtc = newtc->tc_tweak->tc_other;
nanouptime(&ts);
newtc->tc_offset_sec = ts.tv_sec;
newtc->tc_offset_nano = (u_int64_t)ts.tv_nsec << 32;
newtc->tc_offset_micro = ts.tv_nsec / 1000;
newtc->tc_offset_count = newtc->tc_get_timecount(newtc);
+ tco_setscales(newtc);
timecounter = newtc;
splx(s);
}
-#endif
static struct timecounter *
sync_other_counter(void)
@@ -825,6 +831,35 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, method, CTLFLAG_RW, &tco_method, 0,
);
+static int
+sysctl_kern_timecounter_hardware SYSCTL_HANDLER_ARGS
+{
+ char newname[32];
+ struct timecounter *newtc, *tc;
+ int error;
+
+ tc = timecounter->tc_tweak;
+ strncpy(newname, tc->tc_name, sizeof(newname));
+ error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req);
+ if (error == 0 && req->newptr != NULL &&
+ strcmp(newname, tc->tc_name) != 0) {
+ for (newtc = tc->tc_avail; newtc != tc; newtc = tc->tc_avail) {
+ if (strcmp(newname, newtc->tc_name) == 0) {
+ /* Warm up new timecounter. */
+ (void)newtc->tc_get_timecount(newtc);
+
+ switch_timecounter(newtc);
+ return (0);
+ }
+ }
+ return (EINVAL);
+ }
+ return (error);
+}
+
+SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
+ 0, 0, sysctl_kern_timecounter_hardware, "A", "");
+
int
pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
OpenPOWER on IntegriCloud