[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: -current Clock Drift



Hi Brooks,

I put some print statements in sys/i386/isa/clock.c.  I understand how
I see both timecounter messages.

I think something is wrong with the method of selecting the rtclock.
The selection should be based on some real measurement, not a fixed
value.  I think the value set for the tsc_freq is wrong, on my
machine.

The frequency set for the TSC timecounter is 97342816, 133328970, and,
98302896 on three successive reboots.  The machine is rated as a
133MHz 2-CPU SMP machine.  I don't think the 133MHZ clock is bouncing
around +-35Mhz!

I attached a patch.  The first print statement replaced a blank line,
thus the ! and not a +.

The output produced by the patch on my machine is:

startrtclock: tsc_present=1
startrtclock: freq=1204958, timer_freq=1193182
startrtclock: delta=11776, freq=1204958, timer_freq=1193182
startrtclock: delta is smaller, set timer_freq=freq
startrtclock: freq=1204958, timer_freq=1204958, tsc_freq=133328694
startrtclock: tsc_freq=0
startrtclock: tsc_present=1, tsc_freq=98302896, tsc_is_broken=0

If you have the time, how about trying this on your machine?  If not,
I understand.

tomdean

==== /sys/i386/isa/clock.c.patch =======
*** /sys/i386/isa/clock.c	Fri Oct 27 23:55:08 2000
--- clock.c	Thu Nov 23 08:43:43 2000
***************
*** 718,724 ****
  		tsc_present = 1;
  	else
  		tsc_present = 0;
! 
  	writertc(RTC_STATUSA, rtc_statusa);
  	writertc(RTC_STATUSB, RTCSB_24HR);
  
--- 718,724 ----
  		tsc_present = 1;
  	else
  		tsc_present = 0;
! 	printf("startrtclock: tsc_present=%d\n", tsc_present);
  	writertc(RTC_STATUSA, rtc_statusa);
  	writertc(RTC_STATUSB, RTCSB_24HR);
  
***************
*** 732,737 ****
--- 732,738 ----
  			calibrate_clocks();
  	}
  #endif
+ 	printf("startrtclock: freq=%d, timer_freq=%d\n", freq, timer_freq);
  
  	/*
  	 * Use the calibrated i8254 frequency if it seems reasonable.
***************
*** 739,744 ****
--- 740,747 ----
  	 * frequency.
  	 */
  	delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
+ 	printf("startrtclock: delta=%d, freq=%d, timer_freq=%d\n",
+ 		   delta, freq, timer_freq);
  	if (delta < timer_freq / 100) {
  #ifndef CLK_USE_I8254_CALIBRATION
  		if (bootverbose)
***************
*** 746,751 ****
--- 749,755 ----
  "CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
  		freq = timer_freq;
  #endif
+ 		printf("startrtclock: delta is smaller, set timer_freq=freq\n");
  		timer_freq = freq;
  	} else {
  		if (bootverbose)
***************
*** 753,763 ****
--- 757,771 ----
  		    "%d Hz differs from default of %d Hz by more than 1%%\n",
  			       freq, timer_freq);
  		tsc_freq = 0;
+ 		printf("startrtclock: delta is larger, set tsc_freq=0\n");
  	}
  
  	set_timer_freq(timer_freq, hz);
  	i8254_timecounter.tc_frequency = timer_freq;
  	tc_init(&i8254_timecounter);
+ 	
+ 	printf("startrtclock: freq=%d, timer_freq=%d, tsc_freq=%d\n",
+ 		   freq, timer_freq, tsc_freq);
  
  #ifndef CLK_USE_TSC_CALIBRATION
  	if (tsc_freq != 0) {
***************
*** 767,772 ****
--- 775,781 ----
  		tsc_freq = 0;
  	}
  #endif
+ 	printf("startrtclock: tsc_freq=%d\n", tsc_freq);
  	if (tsc_present && tsc_freq == 0) {
  		/*
  		 * Calibration of the i586 clock relative to the mc146818A
***************
*** 811,816 ****
--- 820,828 ----
  #endif /* NAPM > 0 */
  
  	if (tsc_present && tsc_freq != 0 && !tsc_is_broken) {
+ 	  printf("startrtclock: tsc_present=%d, tsc_freq=%d, tsc_is_broken=%d\n",
+ 			 tsc_present, tsc_freq, tsc_is_broken);
+ 
  		tsc_timecounter.tc_frequency = tsc_freq;
  		tc_init(&tsc_timecounter);
  	}