Bug 170705 - [rtc] [patch] AT realtime clock support routines fail on some RTC hardware.
Summary: [rtc] [patch] AT realtime clock support routines fail on some RTC hardware.
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: i386 (show other bugs)
Version: 10.0-CURRENT
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-i386 (Nobody)
Depends on:
Reported: 2012-08-17 15:50 UTC by Ian Lepore
Modified: 2017-12-31 22:27 UTC (History)
0 users

See Also:

atrtc.diff (4.50 KB, patch)
2012-08-17 15:50 UTC, Ian Lepore
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Lepore 2012-08-17 15:50:02 UTC
On some RTC hardware, the RTC interrupt handler (rtcintr() in x86/isa/clock.c)
can get stuck in its loop waiting for the RTCIR_PERIOD status bit to become
de-asserted in the hardware register.

To read RTC hardware registers you first set the index register at port 0x70
to select the register to read, then you read the value from port 0x71.  On
most hardware you can write to the index register once, then issue multiple
subsequent reads to port 0x71 to continuously read new values from the 
selected register.  At some point, the atrtc.c code was enhanced to avoid
the expensive outb(0x70,) if it would re-select the same index as last time.

It appears that on some hardware, the value in the selected register is 
latched at the time you select it with a write to 0x70, and then any number of
subsequent reads of 0x71 will keep returning the same latched value forever.
This is known to happen on systems based on the AMD Geode 500 and CS5536
companion chipset, used on a variety of single-board computers, including
the Soekris net5501 series.

The atrtc code also contains a delay (implemented by a dummy read of port 0x84)
after each access to ports rx70-71, which is expensive (about 1uS per read) and
is not required by modern hardware.  The attached patch eliminates this extra
IO unless it is specifically enabled with hint.atrtc.0.use_iodelay=1.

Finally, the attached patch adds a new routine, atrtc_nmi_enable(), which
can be used by drivers which need to enable nmi interrupts.  Without this 
routine, it's possible that a driver directly manipulating the nmi enable
bit will conflict with the atrtc driver reading and writing the same port
to change rtc index register.

There was some mailing-list discussion of this in January 2012, when I first
ran into the problem on an industrial single-board computer, and again in August
2012 when the attached patch was shown to fix a problem on a Soekris system.


Fix: Here is the patch for -current and 9.  I can provide a patch to 8-stable
as well; it's essentially the same patch with small context differences.

I've tested this using -current on several systems, recent and old
hardware, including manually bumping up the quality score for the rtc
event timer to force it to get used, and it seems to work without
trouble (and of course I've been testing the same patch at work in 8.2 for 
a while on a bunch of different hardware).
Comment 1 Ian Lepore 2012-09-04 22:12:47 UTC
Some testing by Michael Moll reveals that this patch causes a lockup
when running under VirtualBox.  Please don't commit the original patch
in this PR until I have time to investigate and resolve that.
Comment 2 Marek Salwerowicz 2012-10-04 23:19:45 UTC
Patch included in PR 170705 hangs booting  the 9.1 kernel on Virtual 
Machines under ESXi 4.1, 5.1 and VirtualBox 4.2

Marek Salwerowicz
Comment 3 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:56 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped