git: b8319d9f78f7 - stable/13 - atrtc: reads Century field from FADT table

From: Eric van Gyzen <vangyzen_at_FreeBSD.org>
Date: Thu, 03 Mar 2022 14:20:43 UTC
The branch stable/13 has been updated by vangyzen:

URL: https://cgit.FreeBSD.org/src/commit/?id=b8319d9f78f7456bb90b69d59403918e27b640d4

commit b8319d9f78f7456bb90b69d59403918e27b640d4
Author:     Austin Zhang <austin.zhang@dell.com>
AuthorDate: 2022-01-13 17:13:25 +0000
Commit:     Eric van Gyzen <vangyzen@FreeBSD.org>
CommitDate: 2022-03-03 14:20:07 +0000

    atrtc: reads Century field from FADT table
    
    The ACPI spec describes the FADT->Century field as:
    
        The RTC CMOS RAM index to the century of data value (hundred and
        thousand year decimals).  If this field contains a zero, then the
        RTC centenary feature is not supported.  If this field has a non-zero
        value, then this field contains an index into RTC RAM space that
        OSPM can use to program the centenary field.
    
    Use this field to decide whether to program the CENTURY register
    of the CMOS RTC device.
    
    Reviewed by:    akumar3@isilon.com, dab, vangyzen
    MFC after:      1 week
    Sponsored by:   Dell EMC Isilon
    Differential Revision:  https://reviews.freebsd.org/D33667
    
    MFC after:      1 week
    Sponsored by:   Dell EMC Isilon
    
    (cherry picked from commit e1ef6c0ef256f797d629b9490db3f0034b28ae43)
---
 sys/x86/isa/atrtc.c | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/sys/x86/isa/atrtc.c b/sys/x86/isa/atrtc.c
index cad8015435d0..aff838c53851 100644
--- a/sys/x86/isa/atrtc.c
+++ b/sys/x86/isa/atrtc.c
@@ -79,6 +79,7 @@ MTX_SYSINIT(atrtc_time_lock_init, &atrtc_time_lock, "atrtc_time", MTX_DEF);
 
 int	atrtcclock_disable = 0;
 
+static	int	rtc_century = 0;
 static	int	rtc_reg = -1;
 static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
 static	u_char	rtc_statusb = RTCSB_24HR;
@@ -420,6 +421,31 @@ atrtc_acpi_disabled(void)
 #endif
 }
 
+static int
+rtc_acpi_century_get(void)
+{
+#ifdef DEV_ACPI
+	ACPI_TABLE_FADT *fadt;
+	vm_paddr_t physaddr;
+	int century;
+
+	physaddr = acpi_find_table(ACPI_SIG_FADT);
+	if (physaddr == 0)
+		return (0);
+
+	fadt = acpi_map_table(physaddr, ACPI_SIG_FADT);
+	if (fadt == NULL)
+		return (0);
+
+	century = fadt->Century;
+	acpi_unmap_table(fadt);
+
+	return (century);
+#else
+	return (0);
+#endif
+}
+
 static int
 atrtc_probe(device_t dev)
 {
@@ -435,6 +461,7 @@ atrtc_probe(device_t dev)
 		device_set_desc(dev, "AT realtime clock");
 		return (BUS_PROBE_LOW_PRIORITY);
 	}
+	rtc_century = rtc_acpi_century_get();
 	return (result);
 }
 
@@ -548,9 +575,8 @@ atrtc_settime(device_t dev __unused, struct timespec *ts)
 	rtcout_locked(RTC_DAY,   bct.day);
 	rtcout_locked(RTC_MONTH, bct.mon);
 	rtcout_locked(RTC_YEAR,  bct.year & 0xff);
-#ifdef USE_RTC_CENTURY
-	rtcout_locked(RTC_CENTURY, bct.year >> 8);
-#endif
+	if (rtc_century)
+		rtcout_locked(rtc_century, bct.year >> 8);
 
 	/*
 	 * Re-enable RTC updates and interrupts.
@@ -592,9 +618,8 @@ atrtc_gettime(device_t dev, struct timespec *ts)
 	bct.day  = rtcin_locked(RTC_DAY);
 	bct.mon  = rtcin_locked(RTC_MONTH);
 	bct.year = rtcin_locked(RTC_YEAR);
-#ifdef USE_RTC_CENTURY
-	bct.year |= rtcin_locked(RTC_CENTURY) << 8;
-#endif
+	if (rtc_century)
+		bct.year |= rtcin_locked(rtc_century) << 8;
 	mtx_unlock_spin(&atrtc_lock);
 	mtx_unlock(&atrtc_time_lock);
 	/* dow is unused in timespec conversion and we have no nsec info. */