On Sun, Jul 8, 2018 at 11:32 PM, Alexander Graf <ag...@suse.de> wrote: > > > On 07.07.18 23:39, Heinrich Schuchardt wrote: >> Our implementation of rtc_to_tm() cannot handle dates of more than >> 0x7fffffff seconds after 1970-01-01. >> >> Adopt the Linux kernel implementation. >> >> Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de> > > 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: >> diff --git a/drivers/rtc/i2c_rtc_emul.c b/drivers/rtc/i2c_rtc_emul.c >> index bad61c377f..d4b33e59d6 100644 >> --- a/drivers/rtc/i2c_rtc_emul.c >> +++ b/drivers/rtc/i2c_rtc_emul.c >> @@ -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; >> } 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. >> diff --git a/include/rtc.h b/include/rtc.h >> index 746624d799..0d964d56d5 100644 >> --- a/include/rtc.h >> +++ b/include/rtc.h >> @@ -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); >> +} 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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot