]> xenbits.xensource.com Git - people/royger/freebsd.git/commitdiff
atrtc: reads Century field from FADT table
authorAustin Zhang <austin.zhang@dell.com>
Thu, 13 Jan 2022 17:13:25 +0000 (11:13 -0600)
committerEric van Gyzen <vangyzen@FreeBSD.org>
Thu, 3 Mar 2022 14:20:07 +0000 (08:20 -0600)
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

index cad8015435d0b84b057bcaf13afcb1e65f994135..aff838c53851655e3b0b70289771ea5b8c1c4560 100644 (file)
@@ -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. */