freq_adj.in revision 280849
195212Sbde#! @PATH_PERL@ -w 264880Sphk 364880Sphkdie "perl5 needed\n" unless ($] > 5); 464880Sphk 564880Sphkuse Getopt::Std; 6100206Sdduse vars qw($opt_n); 7100206Sdd 864880Sphkgetopts('d:nt:'); 964880Sphk 1064880Sphk#chop($ncpu = `sysctl -n hw.ncpu`); 1164880Sphk#die "Found $ncpu CPUs; can only be run on systems with 1 CPU.\n" if ($ncpu > 1); 1264880Sphk 1364880Sphk$driftfile = "/etc/ntp.drift"; 1464880Sphk$driftfile = $opt_d if defined($opt_d); 1564880Sphk 1664880Sphkchop($timer = `sysctl -n kern.timecounter.hardware 2> /dev/null`); 1764880Sphk 1864880Sphk$timer =~ tr/\U/\L/; 1964880Sphk 2064880Sphkif ($timer eq '') { 2164880Sphk open(DM, "/var/run/dmesg.boot"); 2264880Sphk while(<DM>) { 2364880Sphk # Timecounter "i8254" frequency 1193182 Hz 2464880Sphk if (/^Timecounter "(\w+)"\s+/) { 2564880Sphk $timer = $1; 2664880Sphk last; 2764880Sphk } 2864880Sphk } 2964880Sphk close(DM); 3064880Sphk} 3164880Sphk 3264880Sphk$opt_t = $timer if !defined($opt_t); 3364880Sphk 3464880Sphkif ($timer ne '') { # $timer found... 3564880Sphk if ($opt_t ne '') { # - and $opt_t found 3664880Sphk if ($timer ne $opt_t) { # - - and they differ 3764880Sphk warn "You specified a $opt_t timer but I detected a $timer timer.\n"; 3864880Sphk usage(); 3965515Sphk exit 1; 4095212Sbde } else { # - - and they are the same 4164880Sphk ; 42100206Sdd } 4364880Sphk } else { # - but no $opt_t specified; this is OK 4465515Sphk ; 45100206Sdd } 46100206Sdd} else { # No $timer found... 47100206Sdd if ($opt_t ne '') { # - but $opt_t was specified 48100206Sdd $timer = $opt_t; # - - so use it. 49100206Sdd } else { # - and neither was $opt_t 50100206Sdd warn "I can't tell what timer you have. Please specify one.\n"; 51100206Sdd usage(); 52100206Sdd exit 1; 53100206Sdd } 54100206Sdd} 55100206Sdd 56100206Sddopen(DF, $driftfile) || die "Can't open driftfile ($driftfile): $!\n"; 57100206Sddwhile(<DF>) { 58100206Sdd chop; 59100206Sdd if (/^(-?\d+\.\d+)(\s\d)?$/) { 60100206Sdd $drift = $1; 61100206Sdd } else { 62100206Sdd die "Bogus value in driftfile $driftfile: <$_>\n"; 63100206Sdd } 64100206Sdd} 65100206Sddclose(DF); 66100206Sdd 67100206Sddprint "NTP drift is <$drift>\n"; 68100206Sdd 69100206Sdd# Convert from NTP's idea of PPM to a decimal equivalent 70100206Sdd$freq_adj = int ( $drift * ( 10 ** 6 / 2 ** 20) ); 71100206Sddprint "normalized freq_adj is <$freq_adj>\n"; 72100206Sdd 73100206Sdd$freq_adj = int ( ( $freq_adj - 1 ) / 2 ); 74100206Sddprint "Applying freq_adj of <".-$freq_adj.">\n"; 75100206Sdd 76100206Sdd$sysctl = "machdep.".$timer."_freq"; 77100206Sdd 78100206Sddchop($mach_freq = `sysctl -n $sysctl`); 79100206Sdd 80100206Sddprint "$sysctl is <$mach_freq>\n"; 81100206Sdd 82100206Sdd$n_mach_freq = $mach_freq - $freq_adj; 83100206Sdd 84100206Sddif (defined($opt_n)) { 85100206Sdd print "$sysctl $mach_freq -> $n_mach_freq\n"; 86100206Sdd} else { 87100206Sdd print "i8254: ".`sysctl -w $sysctl=$n_mach_freq`; 88100206Sdd} 89100206Sdd 90100206Sddsub usage { 91100804Sdd print STDERR <<EOUsage 92100206SddUsage: $0 [-d drift_file] [-n] [-t timer] 93100206Sddwhere "drift_file" defaults to /etc/ntp.drift 94100206Sddand "timer" is usually "tsc" or "i8254" 95100206Sddand "-n" says "don't really change anything, just say what would happen". 96100206SddEOUsage 97100206Sdd} 98100206Sdd