efi_loader: complete implementation of GetTime()
Subsystems (4)
v2 cover efi_loader: complete implementation of GetTime()
The year 2038 problem in rtc_to_tm() is reusing code from Linux.
The EFI runtime service GetTime() is used to read the time form the real time clock.
The RTC drivers are made usable even if U-Boot is built without CONFIG_CMD_DATE.
The implementation of the GetTime() runtime service is corrected.
v2:
do not support non-driver-model drivers
Heinrich Schuchardt (6):
drivers: rtc: resolve year 2038 problem in rtc_to_tm
rtc: remove CONFIG_CMD_DATE dependency
efi_loader: remove unused efi_get_time_init()
efi_loader: complete implementation of GetTime()
efi_selftest: support printing leading zeroes
efi_selftest: unit test for GetTime()
cmd/bootefi.c | 3 - drivers/rtc/Makefile | 1 + drivers/rtc/at91sam9_rtt.c | 4 -- drivers/rtc/date.c | 43 --------------- drivers/rtc/davinci.c | 2 - drivers/rtc/ds1302.c | 4 -- drivers/rtc/ds1306.c | 4 -- drivers/rtc/ds1307.c | 4 -- drivers/rtc/ds1337.c | 4 -- drivers/rtc/ds1374.c | 3 - drivers/rtc/ds164x.c | 4 -- drivers/rtc/ds174x.c | 4 -- drivers/rtc/ds3231.c | 4 -- drivers/rtc/i2c_rtc_emul.c | 4 +- drivers/rtc/imxdi.c | 4 -- drivers/rtc/m41t11.c | 3 - drivers/rtc/m41t60.c | 3 - drivers/rtc/m41t62.c | 4 -- drivers/rtc/m48t35ax.c | 4 -- drivers/rtc/max6900.c | 4 -- drivers/rtc/mc146818.c | 3 - drivers/rtc/mcfrtc.c | 4 -- drivers/rtc/mk48t59.c | 4 -- drivers/rtc/pcf8563.c | 4 -- drivers/rtc/rs5c372.c | 3 - drivers/rtc/rtc-lib.c | 73 +++++++++++++++++++++++++ drivers/rtc/rx8025.c | 4 -- drivers/rtc/s3c24x0_rtc.c | 4 -- drivers/rtc/x1205.c | 4 -- include/efi_loader.h | 1 - include/rtc.h | 16 +++++- lib/efi_loader/efi_runtime.c | 58 ++++++++++++++------ lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_console.c | 33 +++++++---- lib/efi_selftest/efi_selftest_rtc.c | 67 +++++++++++++++++++++++ 35 files changed, 221 insertions(+), 168 deletions(-) create mode 100644 drivers/rtc/rtc-lib.c create mode 100644 lib/efi_selftest/efi_selftest_rtc.c
Signature · 1 line
2.18.0
PATCH v2 1/6 drivers: rtc: resolve year 2038 problem in rtc_to_tm
Our implementation of rtc_to_tm() cannot handle dates of more than 0x7fffffff seconds after 1970-01-01.
Adopt the Linux kernel implementation.
---
v2
adopt the Linux kernel implementation
--- drivers/rtc/Makefile | 1 + drivers/rtc/date.c | 43 ---------------------- drivers/rtc/i2c_rtc_emul.c | 4 ++- drivers/rtc/rtc-lib.c | 73 ++++++++++++++++++++++++++++++++++++++ include/rtc.h | 16 +++++++-- 5 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 drivers/rtc/rtc-lib.c
drivers/rtc/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_DM_RTC) += rtc-uclass.o obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o obj-y += date.o +obj-y += rtc-lib.o obj-$(CONFIG_RTC_DAVINCI) += davinci.o obj-$(CONFIG_RTC_DS1302) += ds1302.o obj-$(CONFIG_RTC_DS1306) += ds1306.o
drivers/rtc/date.c +0 -43
55 lines not on this page · raw message
drivers/rtc/i2c_rtc_emul.c +3 -1
@@ -96,7 +96,9 @@ static int sandbox_i2c_rtc_get(struct udevice *dev, struct rtc_time *time) now = plat->base_time; } -return rtc_to_tm (now + plat->offset, time); +rtc_to_tm (now + plat->offset, time); + +return 0 ; }static int sandbox_i2c_rtc_set (struct udevice *dev,const struct rtc_time *time)
drivers/rtc/rtc-lib.c new file +73 -0
73 lines not on this page · raw message
include/rtc.h +13 -3
@@ -208,7 +208,18 @@ void rtc_write32(int reg, u32 value);* rtc_init() - Set up the real time clock ready for use */ void rtc_init (void ); -#endif +#endif /* CONFIG_DM_RTC */ + +/** +* is_leap_year - Check if year is a leap year +* +* @year Year +* @return 1 if leap year +*/ +static inline bool is_leap_year (unsigned int year) +{ +return (!(year %4 ) && (year %100 )) || !(year %400 ); +}/** * rtc_calc_weekday() - Work out the weekday from a time
@@ -231,9 +242,8 @@ int rtc_calc_weekday(struct rtc_time *time);* * @time_t: Number of seconds since 1970-01-01 00:00:00 * @time: Place to put the broken-out time -* @return 0 if OK, -EINVAL if the weekday could not be determined */ -int rtc_to_tm (int time_t,struct rtc_time *time); +void rtc_to_tm (u64 time_t,struct rtc_time *time);/** * rtc_mktime() - Convert a broken-out time into a time_t value
Signature · 1 line
2.18.0
PATCH v2 1/6 drivers: rtc: resolve year 2038 problem in rtc_to_tm
Quoted 6 lines · Heinrich Schuchardt
Our implementation of
rtc_to_tm()cannot handle dates of more than0x7fffffffseconds after 1970-01-01.Adopt the Linux kernel implementation.
Signed-off-by Heinrich Schuchardt <[email protected]>
This patch is slightly out of scope for efi-next and the other patches are independent of it FWIW, so I'll leave it to others to review.
I'll CC Arnd though, as I'm quite sure he has a good grip on anything 2038 :)
Alex
Quoted 215 lines
---
v2
adopt the Linux kernel implementation--- drivers/rtc/Makefile | 1 + drivers/rtc/date.c | 43 ---------------------- drivers/rtc/i2c_rtc_emul.c | 4 ++- drivers/rtc/rtc-lib.c | 73 ++++++++++++++++++++++++++++++++++++++ include/rtc.h | 16 +++++++-- 5 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 drivers/rtc/rtc-lib.cdrivers/rtc/Makefile +1
-0@@ -8,6 +8,7 @@ obj-$(CONFIG_DM_RTC) += rtc-uclass.o obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o obj-y += date.o +obj-y += rtc-lib.o obj-$(CONFIG_RTC_DAVINCI) += davinci.o obj-$(CONFIG_RTC_DS1302) += ds1302.o obj-$(CONFIG_RTC_DS1306) += ds1306.odrivers/rtc/date.c +0
-43@@ -19,10 +19,6 @@#define days_in_year (a) (leapyear(a) ? 366 : 365)#define days_in_month (a) (month_days[(a) - 1]) -static int month_days[12 ] = { -31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 -}; -static int month_offset[] = {0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 };@@ -65,45 +61,6 @@ int rtc_calc_weekday(struct rtc_time *tm)return 0 ; } -int rtc_to_tm (int tim,struct rtc_time *tm) -{ - registerint i; - registerlong hms, day; - - day = tim /SECDAY ; - hms = tim %SECDAY ; - -/* Hours, minutes, seconds are easy */ - tm->tm_hour = hms /3600 ; - tm->tm_min = (hms %3600 ) /60 ; - tm->tm_sec = (hms %3600 ) %60 ; - -/* Number of years in days */ -for (i =STARTOFTIME ; day >=days_in_year (i); i++) - day -=days_in_year (i); - tm->tm_year = i; - -/* Number of months in days left */ -if (leapyear (tm->tm_year)) -days_in_month (FEBRUARY ) =29 ; -for (i =1 ; day >=days_in_month (i); i++) - day -=days_in_month (i); -days_in_month (FEBRUARY ) =28 ; - tm->tm_mon = i; - -/* Days are what is left over (+1) from all that */ - tm->tm_mday = day +1 ; - -/* Zero unused fields */ - tm->tm_yday =0 ; - tm->tm_isdst =0 ; - -/* -* Determine the day of week -*/ -return rtc_calc_weekday (tm); -} -/* * Converts Gregorian date to seconds since 1970-01-01 00:00:00. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 drivers/rtc/i2c_rtc_emul.c +3
-1@@ -96,7 +96,9 @@ static int sandbox_i2c_rtc_get(struct udevice *dev, struct rtc_time *time) now = plat->base_time; } -return rtc_to_tm (now + plat->offset, time); +rtc_to_tm (now + plat->offset, time); + +return 0 ; }static int sandbox_i2c_rtc_set (struct udevice *dev,const struct rtc_time *time)drivers/rtc/rtc-lib.c new file +73
-0@@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* rtc and date/time utility functions +* +* Copyright (C) 2005-06 Tower Technologies +* Author: Alessandro Zummo <[email protected]> +* +* U-Boot rtc_time differs from Linux rtc_time: +* - The year field takes the actual value, not year - 1900. +* - January is month 1. +*/ + +#include <common.h> +#include <rtc.h> +#include <linux/math64.h> + +static const unsigned char rtc_days_in_month[] = { +31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 +}; + +#define LEAPS_THRU_END_OF (y) ((y) / 4 - (y) / 100 + (y) / 400) + +/* +* The number of days in the month. +*/ +static int rtc_month_days (unsigned int month,unsigned int year) +{ +return rtc_days_in_month[month] + (is_leap_year (year) && month ==1 ); +} + +/* +* rtc_to_tm - Converts u64 to rtc_time. +* Convert seconds since 01-01-1970 00:00:00 to Gregorian date. +*/ +void rtc_to_tm (u64 time,struct rtc_time *tm) +{ +unsigned int month, year, secs, days; + + days =div_u64_rem (time,86400 , &secs); + +/* day of the week, 1970-01-01 was a Thursday */ + tm->tm_wday = (days +4 ) %7 ; + + year =1970 + days /365 ; + days -= (year -1970 ) *365 + +LEAPS_THRU_END_OF (year -1 ) + -LEAPS_THRU_END_OF (1970 -1 ); +while (days <0 ) { + year -=1 ; + days +=365 +is_leap_year (year); + } + tm->tm_year = year;/* Not year - 1900 */ + tm->tm_yday = days +1 ; + +for (month =0 ; month <11 ; month++) { +int newdays; + + newdays = days -rtc_month_days (month, year); +if (newdays <0 ) +break ; + days = newdays; + } + tm->tm_mon = month +1 ;/* January = 1 */ + tm->tm_mday = days +1 ; + + tm->tm_hour = secs /3600 ; + secs -= tm->tm_hour *3600 ; + tm->tm_min = secs /60 ; + tm->tm_sec = secs - tm->tm_min *60 ; + +/* Zero unused fields */ + tm->tm_isdst =0 ; +}include/rtc.h +13
-3@@ -208,7 +208,18 @@ void rtc_write32(int reg, u32 value);* rtc_init() - Set up the real time clock ready for use */ void rtc_init (void ); -#endif +#endif /* CONFIG_DM_RTC */ + +/** +* is_leap_year - Check if year is a leap year +* +* @year Year +* @return 1 if leap year +*/ +static inline bool is_leap_year (unsigned int year) +{ +return (!(year %4 ) && (year %100 )) || !(year %400 ); +}/** * rtc_calc_weekday() - Work out the weekday from a time @@ -231,9 +242,8 @@ int rtc_calc_weekday(struct rtc_time *time);* * @time_t: Number of seconds since 1970-01-01 00:00:00 * @time: Place to put the broken-out time -* @return 0 if OK, -EINVAL if the weekday could not be determined */ -int rtc_to_tm (int time_t,struct rtc_time *time); +void rtc_to_tm (u64 time_t,struct rtc_time *time);/** * rtc_mktime() - Convert a broken-out time into a time_t value
PATCH v2 1/6 drivers: rtc: resolve year 2038 problem in rtc_to_tm
Quoted 8 lines · Alexander Graf
Quoted 5 lines · Heinrich Schuchardt
Our implementation of
rtc_to_tm()cannot handle dates of more than0x7fffffffseconds after 1970-01-01.Adopt the Linux kernel implementation.
Quoted 7 lines
Quoted 1 line
Signed-off-by Heinrich Schuchardt <[email protected]>This patch is slightly out of scope for efi-next and the other patches are independent of it FWIW, so I'll leave it to others to review.
I'll CC Arnd though, as I'm quite sure he has a good grip on anything 2038 :)
Ok, I'll point out some common issues with RTC devices:
Quoted 8 lines
Quoted 8 lines
drivers/rtc/i2c_rtc_emul.c +0
-0@@ -96,7 +96,9 @@ static int sandbox_i2c_rtc_get(struct udevice *dev, struct rtc_time *time) now = plat->base_time; }
Quoted 5 lines
drivers/rtc/i2c_rtc_emul.c static int sandbox_i2c_rtc_get(struct udevice *dev, struct rtc_time *time) · line 102
Quoted 5 lines
drivers/rtc/i2c_rtc_emul.c +3
-1-return rtc_to_tm (now + plat->offset, time); +rtc_to_tm (now + plat->offset, time); + +return 0 ; }
Looking at the sources here:
https://github.com/u-boot/u-boot/blob/master/drivers/rtc/i2c_rtc_emul.c
I found that 'now' is sometimes an 'int' and sometimes a 'long', but both of them
are typically signed 32-bit numbers that still overflow. To actually make this patch have any effect, u-boot would consistently need to use 64-bit signed numbers in all the common code as well as in drivers for devices that support times after 2038.
In particular the rtc_mktime() should use the same types as rtc_to_tm(), since it does the reverse operation.
Quoted 13 lines
Quoted 13 lines
include/rtc.h +4
-1@@ -208,7 +208,18 @@ void rtc_write32(int reg, u32 value);* rtc_init() - Set up the real time clock ready for use */ void rtc_init (void ); -#endif +#endif /* CONFIG_DM_RTC */ + +/** +* is_leap_year - Check if year is a leap year
Quoted 8 lines
include/rtc.h void rtc_write32(int reg, u32 value); · line 222
Quoted 8 lines
include/rtc.h +8
-0+* +* @year Year +* @return 1 if leap year +*/ +static inline bool is_leap_year (unsigned int year) +{ +return (!(year %4 ) && (year %100 )) || !(year %400 ); +}
Note that many hardware RTC implementations get the the leap year computation wrong: Since 2000 was a leap year but 2100 is not, a typical shortcut was to assume that every fourth year is a leap year. In RTC devices that have a two-digit BCD number for storing the year, this means we can use the 00-99 range either to encode years 2000 through 2099, or (using the typical wrapping) assuming that all numbers larger 69 are 1970 through 1999, while numbers from 00 to 69 are 2000 through 2099.
The i2c test driver has an unsigned 8-bit number for the year, starting at 1900, so it could support years up to 2155, which is also a common value in hardware RTCs, but I would assume that many of those also have a problem on March 1, 2100, working on the assumption that there is a Feb 29 that year, which requires adding another day to the calculation after that day.
Arnd
PATCH v2 1/6 drivers: rtc: resolve year 2038 problem in rtc_to_tm
In reply to Heinrich SchuchardtQuoted 6 lines · Heinrich Schuchardt
Our implementation of
rtc_to_tm()cannot handle dates of more than0x7fffffffseconds after 1970-01-01.Adopt the Linux kernel implementation.
Signed-off-by Heinrich Schuchardt <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180720/697d91f2/attachment.sig>
PATCH v2 2/6 rtc: remove CONFIG_CMD_DATE dependency
In reply to Heinrich SchuchardtThe EFI subsystem accesses the real time clock and is enabled by default. So we should drop any CONFIG_CMD_DATE dependency from the real time clock drivers.
---
v2
new patch
--- drivers/rtc/at91sam9_rtt.c | 4 ---- drivers/rtc/davinci.c | 2 -- drivers/rtc/ds1302.c | 4 ---- drivers/rtc/ds1306.c | 4 ---- drivers/rtc/ds1307.c | 4 ---- drivers/rtc/ds1337.c | 4 ---- drivers/rtc/ds1374.c | 3 --- drivers/rtc/ds164x.c | 4 ---- drivers/rtc/ds174x.c | 4 ---- drivers/rtc/ds3231.c | 4 ---- drivers/rtc/imxdi.c | 4 ---- drivers/rtc/m41t11.c | 3 --- drivers/rtc/m41t60.c | 3 --- drivers/rtc/m41t62.c | 4 ---- drivers/rtc/m48t35ax.c | 4 ---- drivers/rtc/max6900.c | 4 ---- drivers/rtc/mc146818.c | 3 --- drivers/rtc/mcfrtc.c | 4 ---- drivers/rtc/mk48t59.c | 4 ---- drivers/rtc/pcf8563.c | 4 ---- drivers/rtc/rs5c372.c | 3 --- drivers/rtc/rx8025.c | 4 ---- drivers/rtc/s3c24x0_rtc.c | 4 ---- drivers/rtc/x1205.c | 4 ---- 24 files changed, 89 deletions(-)
drivers/rtc/at91sam9_rtt.c +0 -4
@@ -27,8 +27,6 @@#include <asm/arch/at91_rtt.h> #include <asm/arch/at91_gpbr.h> -#if defined(CONFIG_CMD_DATE ) -int rtc_get (struct rtc_time *tmp) {at91_rtt_t *rtt = (at91_rtt_t *)ATMEL_BASE_RTT ;
@@ -78,5 +76,3 @@ void rtc_reset (void)while (readl (&rtt->vr) !=0 ) ; } - -#endif
drivers/rtc/davinci.c +0 -2
@@ -9,7 +9,6 @@#include <asm/io.h> #include <asm/davinci_rtc.h> -#if defined(CONFIG_CMD_DATE )int rtc_get (struct rtc_time *tmp) {struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE ;
@@ -79,4 +78,3 @@ void rtc_reset(void)/* run RTC counter */ writel (0x01 , &rtc->ctrl); } -#endif
drivers/rtc/ds1302.c +0 -4
@@ -9,8 +9,6 @@#include <command.h> #include <rtc.h> -#if defined(CONFIG_CMD_DATE ) -/* GPP Pins */ #define DATA 0x200#define SCLK 0x400
@@ -328,5 +326,3 @@ int rtc_set(struct rtc_time *tmp)return 0 ; } - -#endif
drivers/rtc/ds1306.c +0 -4
@@ -19,8 +19,6 @@#include <rtc.h> #include <spi.h> -#if defined(CONFIG_CMD_DATE ) -#define RTC_SECONDS 0x00#define RTC_MINUTES 0x01#define RTC_HOURS 0x02
@@ -437,5 +435,3 @@ static void rtc_write (unsigned char reg, unsigned char val) }#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */ - -#endif
drivers/rtc/ds1307.c +0 -4
@@ -51,8 +51,6 @@ enum ds_type {#ifndef CONFIG_DM_RTC -#if defined(CONFIG_CMD_DATE ) -/*---------------------------------------------------------------------*/ #undef DEBUG_RTC
@@ -204,8 +202,6 @@ static void rtc_write (uchar reg, uchar val) i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val); } -#endif /* CONFIG_CMD_DATE*/ -#endif /* !CONFIG_DM_RTC */ #ifdef CONFIG_DM_RTC
drivers/rtc/ds1337.c +0 -4
@@ -15,8 +15,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -/* * RTC register addresses */
@@ -190,5 +188,3 @@ static void rtc_write (uchar reg, uchar val) {i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR , reg, val); } - -#endif
drivers/rtc/ds1374.c +0 -3
@@ -18,8 +18,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -/*---------------------------------------------------------------------*/ #undef DEBUG_RTC#define DEBUG_RTC
@@ -214,4 +212,3 @@ static void rtc_write_raw (uchar reg, uchar val) {i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR , reg, val); } -#endif
drivers/rtc/ds164x.c +0 -4
@@ -20,8 +20,6 @@#include <rtc.h> -#if defined(CONFIG_CMD_DATE ) -static uchar rtc_read (unsigned int addr );static void rtc_write (unsigned int addr,uchar val);
@@ -171,5 +169,3 @@ static void rtc_write( unsigned int addr, uchar val )#endif *(volatile unsigned char *)(addr) = val; } - -#endif
drivers/rtc/ds174x.c +0 -4
@@ -16,8 +16,6 @@#include <command.h> #include <rtc.h> -#if defined(CONFIG_CMD_DATE ) -static uchar rtc_read (unsigned int addr );static void rtc_write (unsigned int addr,uchar val);
@@ -172,5 +170,3 @@ static void rtc_write( unsigned int addr, uchar val )#endif out8 ( addr, val ); } - -#endif
drivers/rtc/ds3231.c +0 -4
@@ -16,8 +16,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -/* * RTC register addresses */
@@ -166,5 +164,3 @@ static void rtc_write (uchar reg, uchar val) {i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR , reg, val); } - -#endif
drivers/rtc/imxdi.c +0 -4
@@ -17,8 +17,6 @@#include <linux/compat.h> #include <rtc.h> -#if defined(CONFIG_CMD_DATE ) -#include <asm/io.h> #include <asm/arch/imx-regs.h>
@@ -222,5 +220,3 @@ void rtc_reset(void) {di_init (); } - -#endif
drivers/rtc/m41t11.c +0 -3
@@ -29,8 +29,6 @@#endif */ -#if defined(CONFIG_SYS_I2C_RTC_ADDR ) && defined(CONFIG_CMD_DATE ) -/* ------------------------------------------------------------------------- */ /* these are simple defines for the chip local to here so they aren't too
@@ -167,4 +165,3 @@ void rtc_reset (void) val = val &0x3F ;/*turn off freq test keep calibration*/ i2c_write (CONFIG_SYS_I2C_RTC_ADDR ,RTC_CONTROL_ADDR ,1 , &val,1 ); } -#endif
drivers/rtc/m41t60.c +0 -3
@@ -20,8 +20,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_SYS_I2C_RTC_ADDR ) && defined(CONFIG_CMD_DATE ) -/* * Convert between century and "century bits" (CB1 and CB0). These routines * assume years are in the range 1900 - 2299.
@@ -237,4 +235,3 @@ void rtc_reset(void) }rtc_dump ("end reset" ); } -#endif /* CONFIG_RTC_M41T60 && CONFIG_SYS_I2C_RTC_ADDR && CONFIG_CMD_DATE */
drivers/rtc/m41t62.c +0 -4
@@ -18,8 +18,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -#define M41T62_REG_SSEC 0#define M41T62_REG_SEC 1#define M41T62_REG_MIN 2
@@ -130,5 +128,3 @@ void rtc_reset(void) val &= ~M41T80_ALHOUR_HT ;i2c_write (CONFIG_SYS_I2C_RTC_ADDR ,M41T62_REG_ALARM_HOUR ,1 , &val,1 ); } - -#endif
drivers/rtc/m48t35ax.c +0 -4
@@ -16,8 +16,6 @@#include <rtc.h> #include <config.h> -#if defined(CONFIG_CMD_DATE ) -static uchar rtc_read (uchar reg);static void rtc_write (uchar reg,uchar val);
@@ -135,5 +133,3 @@ static void rtc_write (uchar reg, uchar val) *(unsigned char *) ((CONFIG_SYS_NVRAM_BASE_ADDR +CONFIG_SYS_NVRAM_SIZE -8 ) + reg) = val; } - -#endif
drivers/rtc/max6900.c +0 -4
@@ -15,8 +15,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -#ifndef CONFIG_SYS_I2C_RTC_ADDR #define CONFIG_SYS_I2C_RTC_ADDR 0x50#endif
@@ -104,5 +102,3 @@ int rtc_set (struct rtc_time *tmp)void rtc_reset (void ) { } - -#endif
drivers/rtc/mc146818.c +0 -3
@@ -19,8 +19,6 @@#define out8 (p, v) outb(v, p)#endif -#if defined(CONFIG_CMD_DATE ) -/* Set this to 1 to clear the CMOS RAM */ #define CLEAR_CMOS 0
@@ -191,7 +189,6 @@ static void mc146818_init(void)/* Clear any pending interrupts */ mc146818_read8 (RTC_CONFIG_C ); } -#endif /* CONFIG_CMD_DATE */ #ifdef CONFIG_DM_RTC
drivers/rtc/mcfrtc.c +0 -4
@@ -6,8 +6,6 @@#include <common.h> -#if defined(CONFIG_CMD_DATE ) -#include <command.h> #include <rtc.h> #include <asm/immap.h>
@@ -104,5 +102,3 @@ void rtc_reset(void) rtc->cr |=RTC_CR_SWR ; } - -#endif /* CONFIG_MCFRTC && CONFIG_CMD_DATE */
drivers/rtc/mk48t59.c +0 -4
@@ -70,8 +70,6 @@ void nvram_write(short dest, const void *src, size_t count)rtc_write (d++, *s++); } -#if defined(CONFIG_CMD_DATE ) -/* ------------------------------------------------------------------------- */ int rtc_get (struct rtc_time *tmp)
@@ -175,5 +173,3 @@ void rtc_set_watchdog(short multi, short res) wd_value =RTC_WDS | ((multi &0x1F ) <<2 ) | (res &0x3 );rtc_write (RTC_WATCHDOG , wd_value); } - -#endif
drivers/rtc/pcf8563.c +0 -4
@@ -15,8 +15,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -static uchar rtc_read (uchar reg);static void rtc_write (uchar reg,uchar val);
@@ -117,5 +115,3 @@ static void rtc_write (uchar reg, uchar val) {i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR , reg, val); } - -#endif
drivers/rtc/rs5c372.c +0 -3
@@ -24,7 +24,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE )/* * Reads are always done starting with register 15, which requires some * jumping-through-hoops to access the data correctly.
@@ -255,5 +254,3 @@ rtc_reset (void)if (!setup_done)rs5c372_enable (); } - -#endif
drivers/rtc/rx8025.c +0 -4
@@ -13,8 +13,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -/*---------------------------------------------------------------------*/ #undef DEBUG_RTC
@@ -190,5 +188,3 @@ static void rtc_write (uchar reg, uchar val)printf ("Error writing to RTC\n" ); } - -#endif /* CONFIG_RTC_RX8025 && CONFIG_CMD_DATE */
drivers/rtc/s3c24x0_rtc.c +0 -4
@@ -11,8 +11,6 @@#include <common.h> #include <command.h> -#if (defined(CONFIG_CMD_DATE )) -#include <asm/arch/s3c24x0_cpu.h> #include <rtc.h>
@@ -149,5 +147,3 @@ void rtc_reset(void)writeb ((readb (&rtc->rtccon) & ~0x06 ) |0x08 , &rtc->rtccon);writeb (readb (&rtc->rtccon) & ~(0x08 |0x01 ), &rtc->rtccon); } - -#endif
drivers/rtc/x1205.c +0 -4
@@ -22,8 +22,6 @@#include <rtc.h> #include <i2c.h> -#if defined(CONFIG_CMD_DATE ) -#define CCR_SEC 0#define CCR_MIN 1#define CCR_HOUR 2
@@ -160,5 +158,3 @@ void rtc_reset(void)* Nothing to do */ } - -#endif
Signature · 1 line
2.18.0
PATCH v2 3/6 efi_loader: remove unused efi_get_time_init()
In reply to Heinrich SchuchardtRemove unused function efi_get_time_init().
Initialization of the RTC has to be done in board bring up not in the EFI subsystem.
There is no RTC device in the UEFI spec. The RTC is only accessed through the runtime services.
---
v2
update commit message
--- cmd/bootefi.c | 3 --- include/efi_loader.h | 1 - lib/efi_loader/efi_runtime.c | 5 ----- 3 files changed, 9 deletions(-)
cmd/bootefi.c +0 -3
@@ -90,9 +90,6 @@ efi_status_t efi_init_obj_list(void) ret =efi_reset_system_init ();if (ret !=EFI_SUCCESS ) goto out; - ret =efi_get_time_init (); -if (ret !=EFI_SUCCESS ) - goto out; out: efi_obj_list_initialized = ret;
include/efi_loader.h +0 -1
@@ -437,7 +437,6 @@ efi_status_t efi_reset_system_init(void); efi_status_t __efi_runtime EFIAPI efi_get_time(struct efi_time *time,struct efi_time_cap *capabilities); -efi_status_t efi_get_time_init (void );#ifdef CONFIG_CMD_BOOTEFI_SELFTEST /*
lib/efi_loader/efi_runtime.c +0 -5
@@ -186,11 +186,6 @@ efi_status_t __weak __efi_runtime EFIAPI efi_get_time(return EFI_DEVICE_ERROR ; } -efi_status_t __weak efi_get_time_init (void ) -{ -return EFI_SUCCESS ; -} -struct efi_runtime_detach_list_struct {void *ptr;void *patchto;
Signature · 1 line
2.18.0
PATCH v2 4/6 efi_loader: complete implementation of GetTime()
In reply to Heinrich SchuchardtImplement the missing parts of the GetTime() runtime service.
Fill seconds.
Fill daylight saving time flag correctly.
Provide dummy values for capabilities.
---
v2
do not add support for non driver model drivers
--- lib/efi_loader/efi_runtime.c | 53 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-)
lib/efi_loader/efi_runtime.c +41 -12
@@ -129,24 +129,41 @@ static void EFIAPI efi_reset_system_boottime(while (1 ) { } } +/** +* efi_get_time_boottime - get current time +* +* This function implements the GetTime runtime service. +* See the Unified Extensible Firmware Interface (UEFI) specification +* for details. +* +* @time: pointer to structure to receive current time +* @capabilities: pointer to structure to receive RTC properties +* Return Value: status code +*/ static efi_status_t EFIAPI efi_get_time_boottime(struct efi_time *time,struct efi_time_cap *capabilities) { -#if defined(CONFIG_CMD_DATE ) && defined(CONFIG_DM_RTC ) -struct rtc_time tm; +#ifdef CONFIG_DM_RTC +efi_status_t ret =EFI_SUCCESS ;int r; +struct rtc_time tm;struct udevice *dev;EFI_ENTRY ("%p %p" , time, capabilities); - r =uclass_get_device (UCLASS_RTC ,0 , &dev); -if (r) -return EFI_EXIT (EFI_DEVICE_ERROR ); +if (!time) { + ret =EFI_INVALID_PARAMETER ; + goto out; + } - r =dm_rtc_get (dev, &tm); -if (r) -return EFI_EXIT (EFI_DEVICE_ERROR ); + r =uclass_get_device (UCLASS_RTC ,0 , &dev); +if (!r) + r =dm_rtc_get (dev, &tm); +if (r) { + ret =EFI_DEVICE_ERROR ; + goto out; + }memset (time,0 ,sizeof (*time)); time->year = tm.tm_year;
@@ -154,11 +171,23 @@ static efi_status_t EFIAPI efi_get_time_boottime( time->day = tm.tm_mday; time->hour = tm.tm_hour; time->minute = tm.tm_min; - time->daylight = tm.tm_isdst; - -return EFI_EXIT (EFI_SUCCESS ); + time->second = tm.tm_sec; + time->daylight =EFI_TIME_ADJUST_DAYLIGHT ; +if (tm.tm_isdst >0 ) + time->daylight |=EFI_TIME_IN_DAYLIGHT ; + time->timezone =EFI_UNSPECIFIED_TIMEZONE ; + +if (capabilities) { +/* Set reasonable dummy values */ + capabilities->resolution =1 ;/* 1 Hz */ + capabilities->accuracy =100000000 ;/* 100 ppm */ + capabilities->sets_to_zero = false; + } +out: +return EFI_EXIT (ret);#else -return EFI_DEVICE_ERROR ; +EFI_ENTRY ("%p %p" , time, capabilities); +return EFI_EXIT (EFI_DEVICE_ERROR );#endif }
Signature · 1 line
2.18.0
PATCH v2 5/6 efi_selftest: support printing leading zeroes
In reply to Heinrich SchuchardtAllow specifying the precision when printing integers, e.g.
efi_st_printf("%.4u-%.2u-%.2u\n", year, month, day);
---
v2
no change
--- lib/efi_selftest/efi_selftest_console.c | 33 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-)
lib/efi_selftest/efi_selftest_console.c +22 -11
@@ -70,11 +70,12 @@ static void pointer(void *pointer, u16 **buf)/* * Print an unsigned 32bit value as decimal number to an u16 string * -* @value: value to be printed -* @buf: pointer to buffer address -* on return position of terminating zero word +* @value: value to be printed +* @prec: minimum number of digits to display +* @buf: pointer to buffer address +* on return position of terminating zero word */ -static void uint2dec (u32 value,u16 **buf) +static void uint2dec (u32 value,int prec,u16 **buf) {u16 *pos = *buf;int i;
@@ -93,7 +94,7 @@ static void uint2dec(u32 value, u16 **buf)for (i =0 ; i <10 ; ++i) {/* Write current digit */ c = f >>60 ; -if (c || pos != *buf) +if (c || pos != *buf ||10 - i <= prec) *pos++ = c +'0' ;/* Eliminate current digit */ f &=0xfffffffffffffff ;
@@ -109,11 +110,12 @@ static void uint2dec(u32 value, u16 **buf)/* * Print a signed 32bit value as decimal number to an u16 string * -* @value: value to be printed -* @buf: pointer to buffer address +* @value: value to be printed +* @prec: minimum number of digits to display +* @buf: pointer to buffer address * on return position of terminating zero word */ -static void int2dec (s32 value,u16 **buf) +static void int2dec (s32 value,int prec,u16 **buf) {u32 u;u16 *pos = *buf;
@@ -124,7 +126,7 @@ static void int2dec(s32 value, u16 **buf) }else { u = value; } -uint2dec (u, &pos); +uint2dec (u, prec, &pos); *buf = pos; }
@@ -143,6 +145,7 @@ void efi_st_printc(int color, const char *fmt, ...)u16 *pos = buf;const char *s;u16 *u; +int prec;va_start (args, fmt);
@@ -172,12 +175,20 @@ void efi_st_printc(int color, const char *fmt, ...)break ;case '%' : ++c; +/* Parse precision */ +if (*c =='.' ) { + ++c; + prec = *c -'0' ; + ++c; + }else { + prec =0 ; + }switch (*c) {case '\0' : --c;break ;case 'd' : -int2dec (va_arg (args, s32), &pos); +int2dec (va_arg (args, s32), prec, &pos);break ;case 'p' : ++c;
@@ -209,7 +220,7 @@ void efi_st_printc(int color, const char *fmt, ...) *pos++ = *s;break ;case 'u' : -uint2dec (va_arg (args, u32), &pos); +uint2dec (va_arg (args, u32), prec, &pos);break ;default :break ;
Signature · 1 line
2.18.0
PATCH v2 6/6 efi_selftest: unit test for GetTime()
In reply to Heinrich SchuchardtProvide a unit test for the GetTime() runtime service.
---
v2
no change
--- lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_rtc.c | 67 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_rtc.c
lib/efi_selftest/Makefile +1 -0
@@ -25,6 +25,7 @@ efi_selftest_exitbootservices.o \ efi_selftest_fdt.o \ efi_selftest_gop.o \ efi_selftest_manageprotocols.o \ +efi_selftest_rtc.o \ efi_selftest_snp.o \ efi_selftest_textinput.o \ efi_selftest_textoutput.o \
lib/efi_selftest/efi_selftest_rtc.c new file +67 -0
67 lines not on this page · raw message
Signature · 1 line
2.18.0