1. Fix a comment. Locking _is_ needed (but not done).

2. Update a comment.  We now restore much more than RTC updates and
   interrupts.
3. Order change.  Stop interrupts by writing to RTC_STATUSB,
   restore rate bits for the interrupts by writing to RTC_STATUSA,
   then enable interrupts again.
   This seems to be done perfectly backwards in startrtclock().
   Otherwise, the idea for this change was obtained from
   startrtclock().
4. Don't stop the clock (RTCB_HALT).  We only program some control bits
   and don't want to stop the clock.
5. (Not really related.)  Add caveats to the comment about timer_restore().
   The update is non-atomic since locking is not done.

On locking:
6. rtcin() and writertc() are locked() adequately by splhigh() in RELENG_4,
   but this locking is null in -current.
7. Doing things in the correct order in (3) combined with (6) is probably
   enough locking for rtcrestore() in RELENG_4.  In -current, the
   writertc()'s race with rtcintr() unless the BIOS disables RTC interrupts.

Submitted by:	bde (including commit message)
MFC after:	1 week
This commit is contained in:
Mitsuru IWASAKI 2002-10-17 13:55:39 +00:00
parent ccc4bab104
commit 0ebefa8c4e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=105328
5 changed files with 40 additions and 60 deletions

View File

@ -692,14 +692,6 @@ set_timer_freq(u_int freq, int intr_freq)
mtx_unlock_spin(&clock_lock);
}
/*
* 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.
*/
static void
i8254_restore(void)
{
@ -715,15 +707,19 @@ static void
rtc_restore(void)
{
/* Reenable RTC updates and interrupts. */
/* XXX locking is needed for RTC access? */
/* Restore all of the RTC's "status" (actually, control) registers. */
/* XXX locking is needed for RTC access. */
writertc(RTC_STATUSB, RTCSB_24HR);
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
writertc(RTC_STATUSB, rtc_statusb);
}
/*
* Restore all the timers atomically.
* Restore all the timers non-atomically (XXX: should be atomically).
*
* This function is called from pmtimer_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.
*/
void
timer_restore(void)

View File

@ -692,14 +692,6 @@ set_timer_freq(u_int freq, int intr_freq)
mtx_unlock_spin(&clock_lock);
}
/*
* 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.
*/
static void
i8254_restore(void)
{
@ -715,15 +707,19 @@ static void
rtc_restore(void)
{
/* Reenable RTC updates and interrupts. */
/* XXX locking is needed for RTC access? */
/* Restore all of the RTC's "status" (actually, control) registers. */
/* XXX locking is needed for RTC access. */
writertc(RTC_STATUSB, RTCSB_24HR);
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
writertc(RTC_STATUSB, rtc_statusb);
}
/*
* Restore all the timers atomically.
* Restore all the timers non-atomically (XXX: should be atomically).
*
* This function is called from pmtimer_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.
*/
void
timer_restore(void)

View File

@ -692,14 +692,6 @@ set_timer_freq(u_int freq, int intr_freq)
mtx_unlock_spin(&clock_lock);
}
/*
* 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.
*/
static void
i8254_restore(void)
{
@ -715,15 +707,19 @@ static void
rtc_restore(void)
{
/* Reenable RTC updates and interrupts. */
/* XXX locking is needed for RTC access? */
/* Restore all of the RTC's "status" (actually, control) registers. */
/* XXX locking is needed for RTC access. */
writertc(RTC_STATUSB, RTCSB_24HR);
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
writertc(RTC_STATUSB, rtc_statusb);
}
/*
* Restore all the timers atomically.
* Restore all the timers non-atomically (XXX: should be atomically).
*
* This function is called from pmtimer_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.
*/
void
timer_restore(void)

View File

@ -692,14 +692,6 @@ set_timer_freq(u_int freq, int intr_freq)
mtx_unlock_spin(&clock_lock);
}
/*
* 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.
*/
static void
i8254_restore(void)
{
@ -715,15 +707,19 @@ static void
rtc_restore(void)
{
/* Reenable RTC updates and interrupts. */
/* XXX locking is needed for RTC access? */
/* Restore all of the RTC's "status" (actually, control) registers. */
/* XXX locking is needed for RTC access. */
writertc(RTC_STATUSB, RTCSB_24HR);
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
writertc(RTC_STATUSB, rtc_statusb);
}
/*
* Restore all the timers atomically.
* Restore all the timers non-atomically (XXX: should be atomically).
*
* This function is called from pmtimer_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.
*/
void
timer_restore(void)

View File

@ -692,14 +692,6 @@ set_timer_freq(u_int freq, int intr_freq)
mtx_unlock_spin(&clock_lock);
}
/*
* 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.
*/
static void
i8254_restore(void)
{
@ -715,15 +707,19 @@ static void
rtc_restore(void)
{
/* Reenable RTC updates and interrupts. */
/* XXX locking is needed for RTC access? */
/* Restore all of the RTC's "status" (actually, control) registers. */
/* XXX locking is needed for RTC access. */
writertc(RTC_STATUSB, RTCSB_24HR);
writertc(RTC_STATUSA, rtc_statusa);
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
writertc(RTC_STATUSB, rtc_statusb);
}
/*
* Restore all the timers atomically.
* Restore all the timers non-atomically (XXX: should be atomically).
*
* This function is called from pmtimer_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.
*/
void
timer_restore(void)