summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitsuru IWASAKI <iwasaki@FreeBSD.org>1999-10-30 14:56:01 +0000
committerMitsuru IWASAKI <iwasaki@FreeBSD.org>1999-10-30 14:56:01 +0000
commit29803c20034d8b84776cbbfe18f1e1ae2904a2c4 (patch)
tree44779f7a28dcd79760060b54d492be07d1a097e2
parent840c0de7aa7558cbf2419f23fb6710af40115833 (diff)
Notes
-rw-r--r--sys/amd64/amd64/tsc.c22
-rw-r--r--sys/amd64/include/clock.h1
-rw-r--r--sys/amd64/isa/clock.c22
-rw-r--r--sys/i386/apm/apm.c1
-rw-r--r--sys/i386/bios/apm.c1
-rw-r--r--sys/i386/i386/tsc.c22
-rw-r--r--sys/i386/include/clock.h1
-rw-r--r--sys/i386/isa/clock.c22
-rw-r--r--sys/isa/atrtc.c22
9 files changed, 114 insertions, 0 deletions
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
index c65974141b01..4d393b041365 100644
--- a/sys/amd64/amd64/tsc.c
+++ b/sys/amd64/amd64/tsc.c
@@ -691,6 +691,28 @@ set_timer_freq(u_int freq, int intr_freq)
}
/*
+ * i8254_restore is called from apm_default_resume() to reload
+ * the countdown register.
+ * this should not be necessary but there are broken laptops that
+ * do not restore the countdown register on resume.
+ * when it happnes, it messes up the hardclock interval and system clock,
+ * which leads to the infamous "calcru: negative time" problem.
+ */
+void
+i8254_restore(void)
+{
+ u_long ef;
+
+ ef = read_eflags();
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(TIMER_CNTR0, timer0_max_count & 0xff);
+ outb(TIMER_CNTR0, timer0_max_count >> 8);
+ CLOCK_UNLOCK();
+ write_eflags(ef);
+}
+
+/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.
*/
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h
index f5c654a6a64f..8d0e2d3ef20e 100644
--- a/sys/amd64/include/clock.h
+++ b/sys/amd64/include/clock.h
@@ -44,6 +44,7 @@ int acquire_timer1 __P((int mode));
int release_timer1 __P((void));
#endif
int sysbeep __P((int pitch, int period));
+void i8254_restore __P((void));
#endif /* KERNEL */
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index c65974141b01..4d393b041365 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -691,6 +691,28 @@ set_timer_freq(u_int freq, int intr_freq)
}
/*
+ * i8254_restore is called from apm_default_resume() to reload
+ * the countdown register.
+ * this should not be necessary but there are broken laptops that
+ * do not restore the countdown register on resume.
+ * when it happnes, it messes up the hardclock interval and system clock,
+ * which leads to the infamous "calcru: negative time" problem.
+ */
+void
+i8254_restore(void)
+{
+ u_long ef;
+
+ ef = read_eflags();
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(TIMER_CNTR0, timer0_max_count & 0xff);
+ outb(TIMER_CNTR0, timer0_max_count >> 8);
+ CLOCK_UNLOCK();
+ write_eflags(ef);
+}
+
+/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.
*/
diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c
index 96860f6a9d67..9630f02e5281 100644
--- a/sys/i386/apm/apm.c
+++ b/sys/i386/apm/apm.c
@@ -404,6 +404,7 @@ apm_default_resume(void *arg)
/* modified for adjkerntz */
pl = splsoftclock();
+ i8254_restore(); /* restore timer_freq and hz */
inittodr(0); /* adjust time to RTC */
microtime(&resume_time);
getmicrotime(&tmp_time);
diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c
index 96860f6a9d67..9630f02e5281 100644
--- a/sys/i386/bios/apm.c
+++ b/sys/i386/bios/apm.c
@@ -404,6 +404,7 @@ apm_default_resume(void *arg)
/* modified for adjkerntz */
pl = splsoftclock();
+ i8254_restore(); /* restore timer_freq and hz */
inittodr(0); /* adjust time to RTC */
microtime(&resume_time);
getmicrotime(&tmp_time);
diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c
index c65974141b01..4d393b041365 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/i386/i386/tsc.c
@@ -691,6 +691,28 @@ set_timer_freq(u_int freq, int intr_freq)
}
/*
+ * i8254_restore is called from apm_default_resume() to reload
+ * the countdown register.
+ * this should not be necessary but there are broken laptops that
+ * do not restore the countdown register on resume.
+ * when it happnes, it messes up the hardclock interval and system clock,
+ * which leads to the infamous "calcru: negative time" problem.
+ */
+void
+i8254_restore(void)
+{
+ u_long ef;
+
+ ef = read_eflags();
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(TIMER_CNTR0, timer0_max_count & 0xff);
+ outb(TIMER_CNTR0, timer0_max_count >> 8);
+ CLOCK_UNLOCK();
+ write_eflags(ef);
+}
+
+/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.
*/
diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h
index f5c654a6a64f..8d0e2d3ef20e 100644
--- a/sys/i386/include/clock.h
+++ b/sys/i386/include/clock.h
@@ -44,6 +44,7 @@ int acquire_timer1 __P((int mode));
int release_timer1 __P((void));
#endif
int sysbeep __P((int pitch, int period));
+void i8254_restore __P((void));
#endif /* KERNEL */
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index c65974141b01..4d393b041365 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -691,6 +691,28 @@ set_timer_freq(u_int freq, int intr_freq)
}
/*
+ * i8254_restore is called from apm_default_resume() to reload
+ * the countdown register.
+ * this should not be necessary but there are broken laptops that
+ * do not restore the countdown register on resume.
+ * when it happnes, it messes up the hardclock interval and system clock,
+ * which leads to the infamous "calcru: negative time" problem.
+ */
+void
+i8254_restore(void)
+{
+ u_long ef;
+
+ ef = read_eflags();
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(TIMER_CNTR0, timer0_max_count & 0xff);
+ outb(TIMER_CNTR0, timer0_max_count >> 8);
+ CLOCK_UNLOCK();
+ write_eflags(ef);
+}
+
+/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.
*/
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index c65974141b01..4d393b041365 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -691,6 +691,28 @@ set_timer_freq(u_int freq, int intr_freq)
}
/*
+ * i8254_restore is called from apm_default_resume() to reload
+ * the countdown register.
+ * this should not be necessary but there are broken laptops that
+ * do not restore the countdown register on resume.
+ * when it happnes, it messes up the hardclock interval and system clock,
+ * which leads to the infamous "calcru: negative time" problem.
+ */
+void
+i8254_restore(void)
+{
+ u_long ef;
+
+ ef = read_eflags();
+ disable_intr();
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
+ outb(TIMER_CNTR0, timer0_max_count & 0xff);
+ outb(TIMER_CNTR0, timer0_max_count >> 8);
+ CLOCK_UNLOCK();
+ write_eflags(ef);
+}
+
+/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.
*/