public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* 500 ms offset in i386 Real Time Clock setting
@ 2001-01-06 19:35 BJerrick
  2001-01-06 20:19 ` Kurt Roeckx
  2001-01-07 12:38 ` Paul Gortmaker
  0 siblings, 2 replies; 6+ messages in thread
From: BJerrick @ 2001-01-06 19:35 UTC (permalink / raw)
  To: aeb, linux-kernel, p_gortmaker

    Neither hwclock nor the /dev/rtc driver takes the following comment from
set_rtc_mmss() in arch/i386/kernel/time.c into account.  As a result, using
hwclock --systohc or --adjust always leaves the Hardware Clock 500 ms ahead of
the System Clock:

     * In order to set the CMOS clock precisely, set_rtc_mmss has to be
     * called 500 ms after the second nowtime has started, because when
     * nowtime is written into the registers of the CMOS clock, it will
     * jump to the next second precisely 500 ms later. Check the Motorola
     * MC146818A or Dallas DS12887 data sheet for details.

(It looks like the only thing that does account for it is the 11-minute
STA_UNSYNC updater in do_timer_interrupt(), in arch/i386/kernel/time.c .)

Shouldn't there be some kernel interface that hides this machine-dependency
from user-level code; i.e., that sets time more precisely?

Bruce Jerrick
Portland, Oregon, USA
email:   bjerrick@easystreet.com

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: 500 ms offset in i386 Real Time Clock setting
  2001-01-06 19:35 500 ms offset in i386 Real Time Clock setting BJerrick
@ 2001-01-06 20:19 ` Kurt Roeckx
  2001-01-07 12:38 ` Paul Gortmaker
  1 sibling, 0 replies; 6+ messages in thread
From: Kurt Roeckx @ 2001-01-06 20:19 UTC (permalink / raw)
  To: BJerrick; +Cc: aeb, linux-kernel, p_gortmaker

On Sat, Jan 06, 2001 at 11:35:52AM -0800, BJerrick@easystreet.com wrote:
>     Neither hwclock nor the /dev/rtc driver takes the following comment from
> set_rtc_mmss() in arch/i386/kernel/time.c into account.  As a result, using
> hwclock --systohc or --adjust always leaves the Hardware Clock 500 ms ahead of
> the System Clock:

I mailed a patch to Andries Brouwer yesterday for exactly the
same problem if hwclock writes writes to the cmos directly, and
said to check if other places have the same problem.

I added an usleep() of 500 ms in cmos.c


Kurt

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: 500 ms offset in i386 Real Time Clock setting
@ 2001-01-06 21:56 Andries.Brouwer
  0 siblings, 0 replies; 6+ messages in thread
From: Andries.Brouwer @ 2001-01-06 21:56 UTC (permalink / raw)
  To: Andries.Brouwer, BJerrick, linux-kernel, p_gortmaker

> Neither hwclock nor the /dev/rtc driver takes the following comment from
> set_rtc_mmss() in arch/i386/kernel/time.c into account.
> As a result, using hwclock --systohc or --adjust always leaves the
> Hardware Clock 500 ms ahead of the System Clock

By pure coincidence Q@ping.be sent me patches just one day ago.
I still have to look at the details, but it seems very likely
that this will be corrected in the next util-linux release.

Andries
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: 500 ms offset in i386 Real Time Clock setting
  2001-01-06 19:35 500 ms offset in i386 Real Time Clock setting BJerrick
  2001-01-06 20:19 ` Kurt Roeckx
@ 2001-01-07 12:38 ` Paul Gortmaker
  1 sibling, 0 replies; 6+ messages in thread
From: Paul Gortmaker @ 2001-01-07 12:38 UTC (permalink / raw)
  To: BJerrick; +Cc: aeb, linux-kernel

BJerrick@easystreet.com wrote:
> 
>     Neither hwclock nor the /dev/rtc driver takes the following comment from
> set_rtc_mmss() in arch/i386/kernel/time.c into account.  As a result, using
> hwclock --systohc or --adjust always leaves the Hardware Clock 500 ms ahead of
> the System Clock:

[...]

> Shouldn't there be some kernel interface that hides this machine-dependency
> from user-level code; i.e., that sets time more precisely?

I don't have a problem with the rtc driver delaying 500ms before setting the
time since that is in fact a feature of the hardware, and it probably should
have done this from the beginning.  However I would have a problem with the 
rtc driver using system time (kernel xtime) to synchronize the start of that
delay - the user may want to synchronize the rtc with some external source.

Simple patch (2.4.0) to add the delay follows, along with a $0.02 test prog 
I used to make sure things behave as desired.  (I guess hwclock will still
require its own delay for when /dev/rtc isn't present and it goes direct.)

Paul.

--- drivers/char/rtc.c~	Sat Jan  6 05:40:24 2001
+++ drivers/char/rtc.c	Sun Jan  7 07:17:39 2001
@@ -40,6 +40,7 @@
  *	1.10b	Andrew Morton: SMP lock fix
  *	1.10c	Cesar Barros: SMP locking fixes and cleanup
  *	1.10d	Paul Gortmaker: delete paranoia check in rtc_exit
+ *	1.10e	Paul Gortmaker: wait 0.5s before writing time to rtc.
  */
 
 #define RTC_VERSION		"1.10d"
@@ -414,6 +415,13 @@
 			BIN_TO_BCD(mon);
 			BIN_TO_BCD(yrs);
 		}
+
+		/* The second for which the clock is set is only 0.5s long */
+		spin_unlock_irq(&rtc_lock);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/2);
+		set_current_state(TASK_RUNNING);
+		spin_lock_irq(&rtc_lock);
 
 		save_control = CMOS_READ(RTC_CONTROL);
 		CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);

   ----------------------8<-------------------8<-----------------------
/* 
 * set RTC when system time ticks over, and then read system time on
 * ten RTC interrupts.  An offset of 500,000 usec (0.5sec) will appear
 * for rtc drivers that don't schedule_timeout(HZ/2) before setting rtc
 * time, since the second for which the rtc is set is only 1/2 sec long.
 * With schedule_timeout(), it will be between (n-1)990,000 and (n)10,000
 * (Assumes RTC=UTC; change gmtime() to localtime() if not the case)
 */

#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
 
void main(void)

{

int i, fd, retval;
unsigned long data;
struct tm *tm;

struct timezone tz = {0,};
struct timeval start, now;

fd = open ("/dev/rtc", O_RDONLY);

if (fd ==  -1) {
	perror("/dev/rtc");
	exit(errno);
}
 
printf("ZZZzzz. Waiting for next second...\n");
gettimeofday(&start, &tz);
do {
	gettimeofday(&now, &tz);
} while (now.tv_sec == start.tv_sec);

tm = gmtime(&start.tv_sec);

retval = ioctl(fd, RTC_SET_TIME, tm);	/* need root */
if (retval == -1) {
	perror("ioctl");
	exit(errno);
}

ioctl(fd, RTC_UIE_ON);
printf("10 gettimeofday values (sec, usec) exactly when RTC updates:\n");

gettimeofday(&start, &tz);
for (i=0;i<10;i++){
	read(fd, &data, sizeof(unsigned long));    /* this blocks */
	gettimeofday(&now, &tz);
	printf("\t%ld\t%ld\n", now.tv_sec-start.tv_sec, now.tv_usec);
}

}
 





_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: 500 ms offset in i386 Real Time Clock setting
@ 2001-01-07 17:59 Andries.Brouwer
  2001-01-08  9:59 ` Paul Gortmaker
  0 siblings, 1 reply; 6+ messages in thread
From: Andries.Brouwer @ 2001-01-07 17:59 UTC (permalink / raw)
  To: BJerrick, p_gortmaker; +Cc: Andries.Brouwer, linux-kernel

> I don't have a problem with the rtc driver delaying 500ms

I still haven't looked at things, but two points:
(i) is the behaviour constant on all architectures?
(ii) instead of waiting, isn't it much easier to redefine
what it means to access rtc?
(If you read a certain value then on average you are halfway
that second; if you write a certain value you are precisely
halfway that second. Maybe no delays are needed or desired.)

Andries

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: 500 ms offset in i386 Real Time Clock setting
  2001-01-07 17:59 Andries.Brouwer
@ 2001-01-08  9:59 ` Paul Gortmaker
  0 siblings, 0 replies; 6+ messages in thread
From: Paul Gortmaker @ 2001-01-08  9:59 UTC (permalink / raw)
  To: Andries.Brouwer; +Cc: BJerrick, linux-kernel

Andries.Brouwer@cwi.nl wrote:
> 
> I still haven't looked at things, but two points:
> (i) is the behaviour constant on all architectures?

As it is a property of the mc146818, it should be constant across all 
arch that use drivers/char/rtc.c

Sparc uses drivers/sbus/char/rtc.c which is for Mostek 4802.  No comment
mentions a 500ms delay there - or in the file arch/sparc/kernel/time.c 
*However* the test for the 500ms is still in the latter (in set_rtc_mmss).

> (ii) instead of waiting, isn't it much easier to redefine
> what it means to access rtc?

Yes, and possibly what I had in mind some 5 years ago (as I'm sure I would
have looked at set_rtc_mmss at the time...)

> (If you read a certain value then on average you are halfway
> that second; if you write a certain value you are precisely
> halfway that second. Maybe no delays are needed or desired.)

Calling it a "feature" is clearly easier - no code patched, no flag day
for new behaviour, and no need for user space utils to have to do a 
uname() to see if a 500ms delay is implemented.  The more I think about
it, the better I like this option.

Paul.

--- drivers/char/rtc.c~	Sat Jan  6 05:40:24 2001
+++ drivers/char/rtc.c	Mon Jan  8 04:57:59 2001
@@ -20,6 +20,14 @@
  *	interrupts since the last read in the remaining high bytes. The 
  *	/dev/rtc interface can also be used with the select(2) call.
  *
+ *	The driver also supports ioctls for reading and setting the
+ *	date/time stored in the RTC in a SMP safe fashion (used by
+ *	the [hw]clock program).  Note that for the mc146818 RTC, the
+ *	second for which the RTC is set is half over, by definition.
+ *	Thus your application may require a 0.5 second delay before
+ *	calling this driver to set the RTC time if exact synchronization
+ *	is desired.
+ *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
  *	as published by the Free Software Foundation; either version




_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-01-08 10:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-01-06 19:35 500 ms offset in i386 Real Time Clock setting BJerrick
2001-01-06 20:19 ` Kurt Roeckx
2001-01-07 12:38 ` Paul Gortmaker
  -- strict thread matches above, loose matches on Subject: below --
2001-01-06 21:56 Andries.Brouwer
2001-01-07 17:59 Andries.Brouwer
2001-01-08  9:59 ` Paul Gortmaker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox