edk2/PcAtChipsetPkg
James Lu 04679c85b4 PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe: Avoid torn RTC time reads
GetTime()/GetWakeupTime() wait for the RTC Update-In-Progress (UIP) bit to
clear, then read the time/date registers (offsets 0-9) back to back.  A clear
UIP bit only guarantees a documented minimum before the next update cycle
begins, not that the whole read fits inside it.  Where a single RTC access is
slow the read overruns that window and picks up undefined data from registers
the update cycle has disconnected from the bus; the corrupted field fails the
range check and GetTime() returns EFI_DEVICE_ERROR, which intermittently fails
OS boot and resume.

Read the registers through RtcReadTimeDateOrFail(), which samples the Seconds
register before the read and requires both UIP still clear and Seconds
unchanged afterwards.  The update cycle is specified to increment the stored
time, so Seconds changes if and only if an update occurred, which detects a
collision anywhere inside the read.  RtcReadRegistersSafe() drives that with at
most one retry and copies out only on success.  The full reasoning, including
why one retry is enough, is documented at those two functions.

The four read paths (GetTime, Init, GetWakeupTime, SetWakeupTime disable-alarm)
use the helper; write paths already inhibit updates via the Register B SET bit
and are unchanged.  The helper enters its own update-free window, so the
up-front RtcWaitToUpdate() in PcRtcGetTime() and in the PcRtcInit() read path is
now redundant and is removed.

Signed-off-by: James Lu <james.lu@intel.com>
2026-08-25 20:10:25 +00:00
..
Bus/Pci/IdeControllerDxe PcAtChipsetPkg: Replace include guards with #pragma once 2026-02-23 21:01:28 +00:00
HpetTimerDxe PcAtChipsetPkg/HpetTimerDxe: Fix nested interrupt time accuracy 2024-01-29 19:17:00 +00:00
Include PcAtChipsetPkg: Replace include guards with #pragma once 2026-02-23 21:01:28 +00:00
Library PcAtChipsetPkg/SerialIoLib: Allow configurable UART IO Port Base Address 2026-07-31 02:55:23 +00:00
PcatRealTimeClockRuntimeDxe PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe: Avoid torn RTC time reads 2026-08-25 20:10:25 +00:00
PcAtChipsetPkg.ci.yaml PcAtChipsetPkg: Add VarPolicy to PcAtRealTimeClock variables 2026-07-31 07:14:46 +00:00
PcAtChipsetPkg.dec PcAtChipsetPkg/SerialIoLib: Allow configurable UART IO Port Base Address 2026-07-31 02:55:23 +00:00
PcAtChipsetPkg.dsc PcAtChipsetPkg: Add VarPolicy to PcAtRealTimeClock variables 2026-07-31 07:14:46 +00:00
PcAtChipsetPkg.uni PcAtChipsetPkg: Add PCD for RTC default year 2023-03-27 06:19:04 +00:00
PcAtChipsetPkgExtra.uni PcAtChipsetPkg: Replace BSD License with BSD+Patent License 2019-04-09 10:58:20 -07:00