Make doubly sure that timer2 is not used for speaker operation.
[dragonfly.git] / sys / i386 / isa / clock.c
index 450ae7f..ed71450 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)clock.c       7.2 (Berkeley) 5/12/91
  * $FreeBSD: src/sys/i386/isa/clock.c,v 1.149.2.6 2002/11/02 04:41:50 iwasaki Exp $
- * $DragonFly: src/sys/i386/isa/Attic/clock.c,v 1.12 2004/02/12 06:57:46 dillon Exp $
+ * $DragonFly: src/sys/i386/isa/Attic/clock.c,v 1.16 2004/08/02 23:20:30 dillon Exp $
  */
 
 /*
@@ -57,6 +57,7 @@
 #include <sys/systm.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
+#include <sys/bus.h>
 #ifndef SMP
 #include <sys/lock.h>
 #endif
@@ -559,17 +560,13 @@ calibrate_clocks(void)
        if (tsc_present) 
                tsc_freq = rdtsc() - old_tsc;
 
-       if (bootverbose) {
-               if (tsc_present)
-                       printf("TSC clock: %u Hz, ", tsc_freq);
-               printf("i8254 clock: %u Hz\n", tot_count);
-       }
+       if (tsc_present)
+               printf("TSC clock: %u Hz, ", tsc_freq);
+       printf("i8254 clock: %u Hz\n", tot_count);
        return (tot_count);
 
 fail:
-       if (bootverbose)
-               printf("failed, using default i8254 clock of %u Hz\n",
-                      cputimer_freq);
+       printf("failed, using default i8254 clock of %u Hz\n", cputimer_freq);
        return (cputimer_freq);
 }
 
@@ -599,17 +596,21 @@ rtc_restore(void)
 }
 
 /*
- * Restore all the timers non-atomically (XXX: should be atomically).
+ * Restore all the timers.
  *
- * This function is called from apm_default_resume() to restore all the timers.
- * This should not be necessary, but there are broken laptops that do not
- * restore all the timers on resume.
+ * This function is called from apm_default_resume() / pmtimer to restore
+ * all the timers.  We also have to restore our timebases, especially on
+ * MP systems, because cputimer_count() counter's delta may have grown
+ * too large for nanouptime() and friends to handle.
  */
 void
 timer_restore(void)
 {
+       crit_enter();
        i8254_restore();                /* restore timer_freq and hz */
        rtc_restore();                  /* reenable RTC interrupts */
+       restoreclocks();
+       crit_exit();
 }
 
 /*
@@ -809,13 +810,16 @@ wrong_time:
 void
 resettodr()
 {
-       unsigned long   tm;
-       int             y, m;
+       struct timeval tv;
+       unsigned long tm;
+       int m;
+       int y;
 
        if (disable_rtc_set)
                return;
 
-       tm = time_second;
+       microtime(&tv);
+       tm = tv.tv_sec;
 
        crit_enter();
        /* Disable RTC updates and interrupts. */
@@ -1076,3 +1080,30 @@ _TSTMP(u_int32_t x)
 }
 #endif /* KERN_TIMESTAMP */
 
+/*
+ *
+ */
+
+static int
+hw_i8254_timestamp(SYSCTL_HANDLER_ARGS)
+{
+    sysclock_t count;
+    __uint64_t tscval;
+    char buf[32];
+
+    crit_enter();
+    count = cputimer_count();
+    if (tsc_present)
+       tscval = rdtsc();
+    else
+       tscval = 0;
+    crit_exit();
+    snprintf(buf, sizeof(buf), "%08x %016llx", count, (long long)tscval);
+    return(SYSCTL_OUT(req, buf, strlen(buf) + 1));
+}
+
+SYSCTL_NODE(_hw, OID_AUTO, i8254, CTLFLAG_RW, 0, "I8254");
+SYSCTL_UINT(_hw_i8254, OID_AUTO, freq, CTLFLAG_RD, &cputimer_freq, 0, "");
+SYSCTL_PROC(_hw_i8254, OID_AUTO, timestamp, CTLTYPE_STRING|CTLFLAG_RD,
+               0, 0, hw_i8254_timestamp, "A", "");
+