Module Name:    src
Committed By:   isaki
Date:           Tue Mar  5 11:19:30 UTC 2024

Modified Files:
        src/sys/arch/virt68k/dev: gfrtc_mainbus.c
        src/sys/dev/goldfish: gfrtc.c

Log Message:
Fix two problems that the time runs late on virt68k.
- The time between the time the alarm occurred and the time read by
  TIME_* register in the next interrupt handler was not accumulated.
- With the one-shot timer method, once the host time prolongs, the
  guest time will never be able to catch up with the host time again.
New one does:
- The driver maintains its (guest's) time (as sc_alarm_time) and always
  set the next alarm sc_interval_ns after the previous alarm.
- gfrtc_set_alarm() takes an absolute time instead of a relative time
  as the argument.
PR kern/57980.  Confirmed on QEMU.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/virt68k/dev/gfrtc_mainbus.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/goldfish/gfrtc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/virt68k/dev/gfrtc_mainbus.c
diff -u src/sys/arch/virt68k/dev/gfrtc_mainbus.c:1.2 src/sys/arch/virt68k/dev/gfrtc_mainbus.c:1.3
--- src/sys/arch/virt68k/dev/gfrtc_mainbus.c:1.2	Fri Jan 12 06:23:20 2024
+++ src/sys/arch/virt68k/dev/gfrtc_mainbus.c	Tue Mar  5 11:19:30 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: gfrtc_mainbus.c,v 1.2 2024/01/12 06:23:20 mlelstv Exp $	*/
+/*	$NetBSD: gfrtc_mainbus.c,v 1.3 2024/03/05 11:19:30 isaki Exp $	*/
 
 /*-
  * Copyright (c) 2023, 2024 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gfrtc_mainbus.c,v 1.2 2024/01/12 06:23:20 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gfrtc_mainbus.c,v 1.3 2024/03/05 11:19:30 isaki Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -58,6 +58,7 @@ struct gfrtc_mainbus_softc {
 	struct gfrtc_softc	sc_gfrtc;
 	struct clock_attach_args sc_clock_args;
 	uint64_t		sc_interval_ns;
+	uint64_t		sc_alarm_time;
 	void			(*sc_handler)(struct clockframe *);
 	struct evcnt *		sc_evcnt;
 	void *			sc_ih;
@@ -68,8 +69,9 @@ do {									\
 	/* Clear the interrupt condition. */				\
 	gfrtc_clear_interrupt(&sc->sc_gfrtc);				\
 									\
-	/* Get the next alarm set ASAP. */				\
-	gfrtc_set_alarm(&sc->sc_gfrtc, sc->sc_interval_ns);		\
+	/* Get the next alarm set. */					\
+	sc->sc_alarm_time += sc->sc_interval_ns;			\
+	gfrtc_set_alarm(&sc->sc_gfrtc, sc->sc_alarm_time);		\
 									\
 	/* Increment the counter and call the handler. */		\
 	sc->sc_evcnt->ev_count++;					\
@@ -103,7 +105,8 @@ gfrtc_mainbus_initclock(void *arg, unsig
 	gfrtc_enable_interrupt(&sc->sc_gfrtc);
 
 	/* Start the first alarm! */
-	gfrtc_set_alarm(&sc->sc_gfrtc, sc->sc_interval_ns);
+	sc->sc_alarm_time = gfrtc_get_time(&sc->sc_gfrtc) + sc->sc_interval_ns;
+	gfrtc_set_alarm(&sc->sc_gfrtc, sc->sc_alarm_time);
 }
 
 static int

Index: src/sys/dev/goldfish/gfrtc.c
diff -u src/sys/dev/goldfish/gfrtc.c:1.4 src/sys/dev/goldfish/gfrtc.c:1.5
--- src/sys/dev/goldfish/gfrtc.c:1.4	Thu Jan  4 12:02:11 2024
+++ src/sys/dev/goldfish/gfrtc.c	Tue Mar  5 11:19:30 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: gfrtc.c,v 1.4 2024/01/04 12:02:11 simonb Exp $	*/
+/*	$NetBSD: gfrtc.c,v 1.5 2024/03/05 11:19:30 isaki Exp $	*/
 
 /*-
  * Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gfrtc.c,v 1.4 2024/01/04 12:02:11 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gfrtc.c,v 1.5 2024/03/05 11:19:30 isaki Exp $");
 
 #include <sys/param.h>
 
@@ -141,10 +141,8 @@ gfrtc_get_time(struct gfrtc_softc * cons
 
 
 void
-gfrtc_set_alarm(struct gfrtc_softc * const sc, const uint64_t nsec)
+gfrtc_set_alarm(struct gfrtc_softc * const sc, const uint64_t next)
 {
-	uint64_t next = gfrtc_get_time(sc) + nsec;
-
 	GOLDFISH_RTC_WRITE(sc, GOLDFISH_RTC_ALARM_HIGH, (uint32_t)(next >> 32));
 	GOLDFISH_RTC_WRITE(sc, GOLDFISH_RTC_ALARM_LOW, (uint32_t)next);
 }

Reply via email to