freq_adj.in revision 275970
11573Srgrimes#! @PATH_PERL@ -w
21573Srgrimes
31573Srgrimesdie "perl5 needed\n" unless ($] > 5);
41573Srgrimes
51573Srgrimesuse Getopt::Std;
61573Srgrimesuse vars qw($opt_n);
71573Srgrimes
81573Srgrimesgetopts('d:nt:');
91573Srgrimes
101573Srgrimes#chop($ncpu = `sysctl -n hw.ncpu`);
111573Srgrimes#die "Found $ncpu CPUs; can only be run on systems with 1 CPU.\n" if ($ncpu > 1);
121573Srgrimes
131573Srgrimes$driftfile = "/etc/ntp.drift";
141573Srgrimes$driftfile = $opt_d if defined($opt_d);
151573Srgrimes
161573Srgrimeschop($timer = `sysctl -n kern.timecounter.hardware 2> /dev/null`);
171573Srgrimes
181573Srgrimes$timer =~ tr/\U/\L/;
191573Srgrimes
201573Srgrimesif ($timer eq '') {
211573Srgrimes  open(DM, "/var/run/dmesg.boot");
221573Srgrimes  while(<DM>) {
231573Srgrimes    # Timecounter "i8254"  frequency 1193182 Hz
241573Srgrimes    if (/^Timecounter "(\w+)"\s+/) {
251573Srgrimes      $timer = $1;
261573Srgrimes      last;
271573Srgrimes    }
281573Srgrimes  }
2950476Speter  close(DM);
301573Srgrimes}
31207757Sjilles
321573Srgrimes$opt_t = $timer if !defined($opt_t);
331573Srgrimes
341573Srgrimesif ($timer ne '') {		# $timer found...
351573Srgrimes  if ($opt_t ne  '') {		# - and $opt_t found
361573Srgrimes    if ($timer ne $opt_t) {	# - - and they differ
3759460Sphantom      warn "You specified a $opt_t timer but I detected a $timer timer.\n";
3859460Sphantom      usage();
391573Srgrimes      exit 1;
4084306Sru    } else {			# - - and they are the same
411573Srgrimes      ;
42107387Sru    }
43107387Sru  } else {			# - but no $opt_t specified; this is OK
44107387Sru    ;
45107387Sru  }
46107387Sru} else {			# No $timer found...
471573Srgrimes  if ($opt_t ne '') {		# - but $opt_t was specified
481573Srgrimes    $timer = $opt_t;		# - - so use it.
491573Srgrimes  } else {			# - and neither was $opt_t
50108028Sru    warn "I can't tell what timer you have.  Please specify one.\n";
511573Srgrimes    usage();
521573Srgrimes    exit 1;
531573Srgrimes  }
541573Srgrimes}
551573Srgrimes
561573Srgrimesopen(DF, $driftfile) || die "Can't open driftfile ($driftfile): $!\n";
571573Srgrimeswhile(<DF>) {
58108087Sru    chop;
59108087Sru    if (/^(-?\d+\.\d+)(\s\d)?$/) {
60108087Sru	$drift = $1;
611573Srgrimes    } else {
621573Srgrimes	die "Bogus value in driftfile $driftfile: <$_>\n";
631573Srgrimes    }
641573Srgrimes}
651573Srgrimesclose(DF);
661573Srgrimes
67119893Sruprint "NTP drift is <$drift>\n";
681573Srgrimes
691573Srgrimes# Convert from NTP's idea of PPM to a decimal equivalent
701573Srgrimes$freq_adj = int ( $drift * ( 10 ** 6 / 2 ** 20) );
711573Srgrimesprint "normalized freq_adj  is <$freq_adj>\n";
721573Srgrimes
731573Srgrimes$freq_adj = int ( ( $freq_adj - 1 ) / 2 );
741573Srgrimesprint "Applying freq_adj of <".-$freq_adj.">\n";
751573Srgrimes
761573Srgrimes$sysctl = "machdep.".$timer."_freq";
771573Srgrimes
781573Srgrimeschop($mach_freq = `sysctl -n $sysctl`);
791573Srgrimes
801573Srgrimesprint "$sysctl is <$mach_freq>\n";
811573Srgrimes
821573Srgrimes$n_mach_freq = $mach_freq - $freq_adj;
831573Srgrimes
841573Srgrimesif (defined($opt_n)) {
851573Srgrimes  print "$sysctl $mach_freq -> $n_mach_freq\n";
861573Srgrimes} else {
871573Srgrimes  print "i8254: ".`sysctl -w $sysctl=$n_mach_freq`;
881573Srgrimes}
89108040Sru
901573Srgrimessub usage {
911573Srgrimes  print STDERR <<EOUsage
921573SrgrimesUsage: $0 [-d drift_file] [-n] [-t timer]
931573Srgrimeswhere "drift_file" defaults to /etc/ntp.drift
941573Srgrimesand "timer" is usually "tsc" or "i8254"
951573Srgrimesand "-n" says "don't really change anything, just say what would happen".
961573SrgrimesEOUsage
971573Srgrimes}
981573Srgrimes