Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
xen.787
53dba447-x86-ACPI-allow-CMOS-RTC-use-even-when-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 53dba447-x86-ACPI-allow-CMOS-RTC-use-even-when-ACPI-says-there-is-none.patch of Package xen.787
References: bnc#883112 # Commit e9425f05b90811458a08355a55a0b0d608c440cf # Date 2014-08-01 16:29:27 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86/ACPI: allow CMOS RTC use even when ACPI says there is none HP is setting the ACPI_FADT_NO_CMOS_RTC flag on newer systems, regardless of whether they're being booted from UEFI. Add a command line option to allow probing for a working RTC in that case. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Index: xen-4.4.2-testing/docs/misc/xen-command-line.markdown =================================================================== --- xen-4.4.2-testing.orig/docs/misc/xen-command-line.markdown +++ xen-4.4.2-testing/docs/misc/xen-command-line.markdown @@ -210,6 +210,14 @@ If set, override Xen's calculation of th If set, override Xen's default choice for the platform timer. +### cmos-rtc-probe +> `= <boolean>` + +> Default: `false` + +Flag to indicate whether to probe for a CMOS Real Time Clock irrespective of +ACPI indicating none to be there. + ### com1,com2 > `= <baud>[/<clock_hz>][,[DPS][,[<io-base>|pci|amt][,[<irq>][,[<port-bdf>][,[<bridge-bdf>]]]]]]` Index: xen-4.4.2-testing/xen/arch/x86/time.c =================================================================== --- xen-4.4.2-testing.orig/xen/arch/x86/time.c +++ xen-4.4.2-testing/xen/arch/x86/time.c @@ -651,37 +651,40 @@ mktime (unsigned int year, unsigned int )*60 + sec; /* finally seconds */ } -static unsigned long __get_cmos_time(void) -{ +struct rtc_time { unsigned int year, mon, day, hour, min, sec; +}; - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); +static void __get_cmos_time(struct rtc_time *rtc) +{ + rtc->sec = CMOS_READ(RTC_SECONDS); + rtc->min = CMOS_READ(RTC_MINUTES); + rtc->hour = CMOS_READ(RTC_HOURS); + rtc->day = CMOS_READ(RTC_DAY_OF_MONTH); + rtc->mon = CMOS_READ(RTC_MONTH); + rtc->year = CMOS_READ(RTC_YEAR); if ( !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD ) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); + BCD_TO_BIN(rtc->sec); + BCD_TO_BIN(rtc->min); + BCD_TO_BIN(rtc->hour); + BCD_TO_BIN(rtc->day); + BCD_TO_BIN(rtc->mon); + BCD_TO_BIN(rtc->year); } - if ( (year += 1900) < 1970 ) - year += 100; - - return mktime(year, mon, day, hour, min, sec); + if ( (rtc->year += 1900) < 1970 ) + rtc->year += 100; } static unsigned long get_cmos_time(void) { unsigned long res, flags; - int i; + struct rtc_time rtc; + unsigned int seconds = 60; + static bool_t __read_mostly cmos_rtc_probe; + boolean_param("cmos-rtc-probe", cmos_rtc_probe); if ( efi_enabled ) { @@ -690,23 +693,58 @@ static unsigned long get_cmos_time(void) return res; } - if ( unlikely(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) ) - panic("System without CMOS RTC must be booted from EFI"); + if ( likely(!(acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC)) ) + cmos_rtc_probe = 0; + else if ( system_state < SYS_STATE_active && !cmos_rtc_probe ) + panic("System with no CMOS RTC advertised must be booted from EFI" + " (or with command line option \"cmos-rtc-probe\")"); + + for ( ; ; ) + { + s_time_t start, t1, t2; - spin_lock_irqsave(&rtc_lock, flags); + spin_lock_irqsave(&rtc_lock, flags); - /* read RTC exactly on falling edge of update flag */ - for ( i = 0 ; i < 1000000 ; i++ ) /* may take up to 1 second... */ - if ( (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) ) + /* read RTC exactly on falling edge of update flag */ + start = NOW(); + do { /* may take up to 1 second... */ + t1 = NOW() - start; + } while ( !(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) && + t1 <= SECONDS(1) ); + + start = NOW(); + do { /* must try at least 2.228 ms */ + t2 = NOW() - start; + } while ( (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) && + t2 < MILLISECS(3) ); + + __get_cmos_time(&rtc); + + spin_unlock_irqrestore(&rtc_lock, flags); + + if ( likely(!cmos_rtc_probe) || + t1 > SECONDS(1) || t2 >= MILLISECS(3) || + rtc.sec >= 60 || rtc.min >= 60 || rtc.hour >= 24 || + !rtc.day || rtc.day > 31 || + !rtc.mon || rtc.mon > 12 ) break; - for ( i = 0 ; i < 1000000 ; i++ ) /* must try at least 2.228 ms */ - if ( !(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) ) + + if ( seconds < 60 ) + { + if ( rtc.sec != seconds ) + cmos_rtc_probe = 0; break; + } + + process_pending_softirqs(); + + seconds = rtc.sec; + } - res = __get_cmos_time(); + if ( unlikely(cmos_rtc_probe) ) + panic("No CMOS RTC found - system must be booted from EFI"); - spin_unlock_irqrestore(&rtc_lock, flags); - return res; + return mktime(rtc.year, rtc.mon, rtc.day, rtc.hour, rtc.min, rtc.sec); } /***************************************************************************
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor