5

I am looking for a way to query the current RTC from the motherboard while running under windows. I am looking for a simple unaltered time as it is stored in the hardware clock (no drift compensation, no NTP time synchronization, not an old timestamp which is continued using a performance counter, ...).

I looked at the windows calls GetSystemTime, GetSystemTimeAdjustment, QueryInterruptTime, QueryPerformanceCounter, GetTickCount/GetTickCount64, GetLocalTime. I read about the Windows Time Service (and that I can shut it off), looked if there is a way to get to the BIOS using the old DOS ways (port 70/71, INT 21h, INT 1Ah), looked at the WMI classes, ... but I'm running out of ideas.

I understand that windows queries the hardware clock from time to time and adjusts the system time accordingly, when the deviations exceed 60sec. This is without NTP. The docs I found do not say what happens after that reading of the hardware clock. There must be another timer in use to do the micro-timing between hardware reads.

Since I want to draw conclusions about the drift of clock sources, this would defeat all reasoning when asking windows for the "local time" and comparing its progress against any high resolution timer (multimedia timer, time stamp counter, ...).

Does anybody know a way how to obtain the time currently stored in the hardware clock (RTC) as raw as possible while running under windows?

ash
  • 51
  • 3
  • 2
    RTC is used only while the OS is not running. It should realistically be called a low power calendar, not a real-time clock. The actual functionality of timekeeping is done by a programmable interrupt timer (PIT) which on modern systems is integrated into the APIC. The APIC timer or PIT is "the" clock hardware, so you probably want to ask about reading that value, uncompensated. – Ben Voigt Apr 12 '19 at 18:08
  • (I have to split my answer since it is too long. Sorry for that.) First of all, thanks for pointing me to the PIT/APIC! I had a look at a current server chipset from intel: https://www.mouser.com/ds/2/612/100-series-chipset-datasheet-vol-1-1130164.pdf This chipset requires two crystals one with 24 MHz and one with 32.768 KHz. Given such a board as an example, these are the two crystals I would like to get drift information on. Chapter 28, page 219 says that the RTC is driven using the 32.768 KHz crystal. The requirements for this are listed in section 28.7.6. – ash Apr 13 '19 at 08:33
  • Section 6.2 (page 41) talks about the HPET. It is driven by a 24 MHz crystal from the PCH. Section 6.2.2 says, that once the 24 MHz clock is disabled, this will be off-loaded to be based on the 32.768 KHz source. Fine, I only care about the running state, The 8259 PIT (or its internal equivalent, section 22.7.1 on page 157) can feed its interruprt to the APIC (section 22.8). Also "PIN 0" is connected to the "Internal Timer/Counter 0 output or Multimedia Timer #0". – ash Apr 13 '19 at 08:35
  • The internal timers are (at least I expect this) fed by the integrated 8264 circuitry (section 12 on page 99). It is said states that the 8254 is clocked by a frequency derived from the 24 MHz clock. So, in summary, when the system is running, then all timer sources (except for the RTC itself) are derived from the 24 MHz external clock source. In that case it would be pointless to try to calculate drift values. The only differences I'd see would stem from frequency division / multiplication circuitry, operating system effects, or numerical issues when converting counters to different bases. – ash Apr 13 '19 at 08:36
  • The only thing that remains independent from the 24 MHz source and keeps to be fed from the 32.768 KHz source is the RTC really. – ash Apr 13 '19 at 08:37
  • 1
    oops I realize my above comment mixed together the two acronyms. PIT stands for programmable *interval* timer. APIC for advanced programmable *interrupt* controller. Anyway, the thing to do with drift measurements is normally to let the hardware run for a bit and then compare to a remote atomic clock (a GPS peripheral is probably better than NTP because the GPS isn't affected by Internet latency -- although a receiver for atomic clock radio broadcasts would also work). Using the 32.786 kHz crystal to measure drift on the 24 MHz isn't useful because (to be continued...) – Ben Voigt Apr 13 '19 at 16:11
  • You find out about the clock skew between the two crystals, but you don't know which one is the more accurate, or how much of the skew is attributable to each of the two drift figures. Independent source is nice, but you really want independent and super-accurate, hence my recommendation of GPS. – Ben Voigt Apr 13 '19 at 16:14
  • Unfortunately, I don't think that reading the RTC during Windows execution is going to help you measure its drift (even with a GPS clock source to compare against) because my research indicates that Windows periodically rewrites the RTC's value based on the PIT/APIC or more accurate sources. The value read from the RTC is only considered trustworthy during boot, and used to initialize the calendar data in the PIT/APIC. – Ben Voigt Apr 13 '19 at 16:19
  • You can read the OS's estimate of drift using `GetSystemTimeAdjustment` or `GetSystemTimeAdjustmentPrecise` – Ben Voigt Apr 13 '19 at 16:23
  • Thanks Ben for being very persistent to point out alternatives! Unfortunately I really need what I was asking for in the headline: the RTC to draw conclusions and make experiments with the hardware timers. I found that the RTC is mapped in the ACPI. On my desktop PC it is under ROOT/_SB/PCI0/LPCB/RTC in the tree. And it lists the old addresses from DOS days (0x70, 0x71) for port I/O. So, I'm currently making myself familiar with Windows WDF to create a small driver runs in kernel mode and is permitted to do port I/O. Maybe I can get access this way... – ash Apr 13 '19 at 17:41
  • Another update. I found a tool called RWEveryting that is able to read port 0x70/0x71. If I set the update frequency for the display to some milliseconds... there I can see the clock tick. After some struggle with windows driver examples I came across "WinIO" and InpOut32/InpOutx64 which are DLLs that claim to read arbitrary ports. So it is possible this way. – ash Apr 14 '19 at 21:36
  • Yes, as long as the register accesses have no side effects. If they do, then you have a race condition with whatever accesses the OS code does. – Ben Voigt Apr 14 '19 at 21:38

0 Answers0