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:
parent
ccc4bab104
commit
0ebefa8c4e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=105328
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user