As Mathieu pointed out, my conversion to time64_t was incorrect and resulted in negative times to be read from the RTC. The problem is that during the conversion from a byte array to a time64_t, the 'unsigned char' variable holding the top byte gets turned into a negative signed 32-bit integer before being assigned to the 64-bit variable for any times after 1972.
This changes the logic to cast to an unsigned 32-bit number first for the Macintosh time and then convert that to the Unix time, which then gives us a time in the documented 1904..2040 year range. I decided not to use the longer 1970..2106 range that other drivers use, for consistency with the literal interpretation of the register, but that could be easily changed if we decide we want to support any Mac after 2040.
Just to be on the safe side, I'm also adding a WARN_ON that will trigger if either the year 2040 has come and is observed by this driver, or we run into an RTC that got set back to a pre-1970 date for some reason (the two are indistinguishable).
For the RTC write functions, Andreas found another problem: both pmu_request() and cuda_request() are varargs functions, so changing the type of the arguments passed into them from 32 bit to 64 bit breaks the API for the set_rtc_time functions. This changes it back to 32 bits.
The same code exists in arch/m68k/ and is patched in an identical way now in a separate patch.
Fixes: 5bfd643583b2 ("powerpc: use time64_t in read_persistent_clock") Reported-by: Mathieu Malaterre malat@debian.org Reported-by: Andreas Schwab schwab@linux-m68k.org Signed-off-by: Arnd Bergmann arnd@arndb.de --- arch/powerpc/platforms/powermac/time.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 7c968e46736f..12e6e4d30602 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -42,7 +42,11 @@ #define DBG(x...) #endif
-/* Apparently the RTC stores seconds since 1 Jan 1904 */ +/* + * Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU + * times wrap in 2040. If we need to handle later times, the read_time functions + * need to be changed to interpret wrapped times as post-2040. + */ #define RTC_OFFSET 2082844800
/* @@ -97,8 +101,11 @@ static time64_t cuda_get_time(void) if (req.reply_len != 7) printk(KERN_ERR "cuda_get_time: got %d byte reply\n", req.reply_len); - now = (req.reply[3] << 24) + (req.reply[4] << 16) - + (req.reply[5] << 8) + req.reply[6]; + now = (u32)((req.reply[3] << 24) + (req.reply[4] << 16) + + (req.reply[5] << 8) + req.reply[6]); + /* it's either after year 2040, or the RTC has gone backwards */ + WARN_ON(now < RTC_OFFSET); + return now - RTC_OFFSET; }
@@ -106,10 +113,10 @@ static time64_t cuda_get_time(void)
static int cuda_set_rtc_time(struct rtc_time *tm) { - time64_t nowtime; + u32 nowtime; struct adb_request req;
- nowtime = rtc_tm_to_time64(tm) + RTC_OFFSET; + nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET); if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) @@ -140,8 +147,12 @@ static time64_t pmu_get_time(void) if (req.reply_len != 4) printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n", req.reply_len); - now = (req.reply[0] << 24) + (req.reply[1] << 16) - + (req.reply[2] << 8) + req.reply[3]; + now = (u32)((req.reply[0] << 24) + (req.reply[1] << 16) + + (req.reply[2] << 8) + req.reply[3]); + + /* it's either after year 2040, or the RTC has gone backwards */ + WARN_ON(now < RTC_OFFSET); + return now - RTC_OFFSET; }
@@ -149,10 +160,10 @@ static time64_t pmu_get_time(void)
static int pmu_set_rtc_time(struct rtc_time *tm) { - time64_t nowtime; + u32 nowtime; struct adb_request req;
- nowtime = rtc_tm_to_time64(tm) + RTC_OFFSET; + nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET); if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) return -ENXIO;
The real-time clock on m68k (and powerpc) mac systems uses an unsigned 32-bit value starting in 1904, which overflows in 2040, about two years later than everyone else, but this gets wrapped around in the Linux code in 2038 already because of the deprecated usage of time_t and/or long in the conversion.
Getting rid of the deprecated interfaces makes it work until 2040 as documented, and it could be easily extended by reinterpreting the resulting time64_t as a positive number. For the moment, I'm adding a WARN_ON() that triggers if we encounter a time before 1970 or after 2040 (the two are indistinguishable).
This brings it in line with the corresponding code that we have on powerpc macintosh.
Signed-off-by: Arnd Bergmann arnd@arndb.de --- v2: Fix varargs passing bug pointed out by Andreas Schwab Fix a typo that caused a build regression --- arch/m68k/mac/misc.c | 62 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-)
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index c68054361615..0a2572a6bfe5 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -26,33 +26,39 @@
#include <asm/machdep.h>
-/* Offset between Unix time (1970-based) and Mac time (1904-based) */ +/* Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU + * times wrap in 2040. If we need to handle later times, the read_time functions + * need to be changed to interpret wrapped times as post-2040. */
#define RTC_OFFSET 2082844800
static void (*rom_reset)(void);
#ifdef CONFIG_ADB_CUDA -static long cuda_read_time(void) +static time64_t cuda_read_time(void) { struct adb_request req; - long time; + time64_t time;
if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) return 0; while (!req.complete) cuda_poll();
- time = (req.reply[3] << 24) | (req.reply[4] << 16) | - (req.reply[5] << 8) | req.reply[6]; + time = (u32)((req.reply[3] << 24) | (req.reply[4] << 16) | + (req.reply[5] << 8) | req.reply[6]); + + /* it's either after year 2040, or the RTC has gone backwards */ + WARN_ON(time < RTC_OFFSET); + return time - RTC_OFFSET; }
-static void cuda_write_time(long data) +static void cuda_write_time(time64_t time) { struct adb_request req; + u32 data = lower_32_bits(time + RTC_OFFSET);
- data += RTC_OFFSET; if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, (data >> 24) & 0xFF, (data >> 16) & 0xFF, (data >> 8) & 0xFF, data & 0xFF) < 0) @@ -86,26 +92,30 @@ static void cuda_write_pram(int offset, __u8 data) #endif /* CONFIG_ADB_CUDA */
#ifdef CONFIG_ADB_PMU68K -static long pmu_read_time(void) +static time64_t pmu_read_time(void) { struct adb_request req; - long time; + time64_t time;
if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) return 0; while (!req.complete) pmu_poll();
- time = (req.reply[1] << 24) | (req.reply[2] << 16) | - (req.reply[3] << 8) | req.reply[4]; + time = (u32)((req.reply[1] << 24) | (req.reply[2] << 16) | + (req.reply[3] << 8) | req.reply[4]); + + /* it's either after year 2040, or the RTC has gone backwards */ + WARN_ON(time < RTC_OFFSET); + return time - RTC_OFFSET; }
-static void pmu_write_time(long data) +static void pmu_write_time(time64_t time) { struct adb_request req; + u32 data = lower_32_bits(time + RTC_OFFSET);
- data += RTC_OFFSET; if (pmu_request(&req, NULL, 5, PMU_SET_RTC, (data >> 24) & 0xFF, (data >> 16) & 0xFF, (data >> 8) & 0xFF, data & 0xFF) < 0) @@ -269,8 +279,12 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]);
- if (result.idata == last_result.idata) + if (result.idata == last_result.idata) { + if (result.idata < RTC_OFFSET) + result.idata += 0x100000000ull; + return result.idata - RTC_OFFSET; + }
if (++count > 10) break; @@ -291,11 +305,11 @@ static long via_read_time(void) * is basically any machine with Mac II-style ADB. */
-static void via_write_time(long time) +static void via_write_time(time64_t time) { union { __u8 cdata[4]; - long idata; + __u32 idata; } data; __u8 temp;
@@ -585,12 +599,15 @@ void mac_reset(void) * This function translates seconds since 1970 into a proper date. * * Algorithm cribbed from glibc2.1, __offtime(). + * + * This is roughly same as rtc_time64_to_tm(), which we should probably + * use here, but it's only available when CONFIG_RTC_LIB is enabled. */ #define SECS_PER_MINUTE (60) #define SECS_PER_HOUR (SECS_PER_MINUTE * 60) #define SECS_PER_DAY (SECS_PER_HOUR * 24)
-static void unmktime(unsigned long time, long offset, +static void unmktime(time64_t time, long offset, int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp) { @@ -602,11 +619,10 @@ static void unmktime(unsigned long time, long offset, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; - long int days, rem, y, wday, yday; + int days, rem, y, wday, yday; const unsigned short int *ip;
- days = time / SECS_PER_DAY; - rem = time % SECS_PER_DAY; + days = div_u64_rem(time, SECS_PER_DAY, &rem); rem += offset; while (rem < 0) { rem += SECS_PER_DAY; @@ -657,7 +673,7 @@ static void unmktime(unsigned long time, long offset,
int mac_hwclk(int op, struct rtc_time *t) { - unsigned long now; + time64_t now;
if (!op) { /* read */ switch (macintosh_config->adb_type) { @@ -693,8 +709,8 @@ int mac_hwclk(int op, struct rtc_time *t) __func__, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
- now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec); + now = mktime64(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec);
switch (macintosh_config->adb_type) { case MAC_ADB_IOP:
On Tue, 19 Jun 2018, Arnd Bergmann wrote:
The real-time clock on m68k (and powerpc) mac systems uses an unsigned 32-bit value starting in 1904, which overflows in 2040, about two years later than everyone else, but this gets wrapped around in the Linux code in 2038 already because of the deprecated usage of time_t and/or long in the conversion.
Getting rid of the deprecated interfaces makes it work until 2040 as documented, and it could be easily extended by reinterpreting the resulting time64_t as a positive number. For the moment, I'm adding a WARN_ON() that triggers if we encounter a time before 1970 or after 2040 (the two are indistinguishable).
I really don't like the WARN_ON(), but I'd prefer to address that in a separate patch rather than impede the progress of this patch (or of this series, since 3/3 seems to be unrelated).
BTW, have you considered using the same wrap-around test (i.e. YY < 70) that we use for the year register in the other RTC chips?
This brings it in line with the corresponding code that we have on powerpc macintosh.
Your recent patches to the Mac RTC routines (which are duplicated under arch/m68k and arch/powerpc) conflict with my recent patch that deduplicates the same code. So I will rebase and resubmit after someone merges these fixes.
Apparently the PowerMac routines work now, which is sufficient testing for me; the PowerMac routines will get tested on m68k Macs when that code gets deduplicated again.
BTW, Joshua tells me that he is not doing code review. We should probably drop the "M68K ON APPLE MACINTOSH" entry from the MAINTAINERS file, like the Amiga and Atari ports...
On Fri, Jun 22, 2018 at 7:26 AM, Finn Thain fthain@telegraphics.com.au wrote:
On Tue, 19 Jun 2018, Arnd Bergmann wrote:
The real-time clock on m68k (and powerpc) mac systems uses an unsigned 32-bit value starting in 1904, which overflows in 2040, about two years later than everyone else, but this gets wrapped around in the Linux code in 2038 already because of the deprecated usage of time_t and/or long in the conversion.
Getting rid of the deprecated interfaces makes it work until 2040 as documented, and it could be easily extended by reinterpreting the resulting time64_t as a positive number. For the moment, I'm adding a WARN_ON() that triggers if we encounter a time before 1970 or after 2040 (the two are indistinguishable).
I really don't like the WARN_ON(), but I'd prefer to address that in a separate patch rather than impede the progress of this patch (or of this series, since 3/3 seems to be unrelated).
BTW, have you considered using the same wrap-around test (i.e. YY < 70) that we use for the year register in the other RTC chips?
That wrap-around test would have the same effect as the my original version (aside from the two bugs I now fixed), doing rougly
- return time - RTC_OFFSET; + return (u32)(time - RTC_OFFSET);
or some other variation of that will give us an RTC that supports all dates between 1970 and 2106. I don't think anyone so far had a strong preference here, so I went with what Mathieu suggested and kept the original Mac behavior, but added the WARN_ON().
This brings it in line with the corresponding code that we have on powerpc macintosh.
Your recent patches to the Mac RTC routines (which are duplicated under arch/m68k and arch/powerpc) conflict with my recent patch that deduplicates the same code. So I will rebase and resubmit after someone merges these fixes.
Apparently the PowerMac routines work now, which is sufficient testing for me; the PowerMac routines will get tested on m68k Macs when that code gets deduplicated again.
Sorry about introducing that conflict, and thanks for bearing with me on the rebase. One thing to watch out for (if you haven't noticed already) is that the powerpc version now depends on rtc_time64_to_tm/rtc_tm_to_time64 which are only available if CONFIG_RTC_LIB is enabled but simplifies the code a bit. I did not want to introduce that as a global dependency on m68k which is rather limited on code size already, but it probably doesn't hurt to require RTC_LIB on m68k-mac.
Arnd
Hi Arnd, Finn,
On Fri, Jun 22, 2018 at 10:55 AM Arnd Bergmann arnd@arndb.de wrote:
On Fri, Jun 22, 2018 at 7:26 AM, Finn Thain fthain@telegraphics.com.au wrote:
On Tue, 19 Jun 2018, Arnd Bergmann wrote:
The real-time clock on m68k (and powerpc) mac systems uses an unsigned 32-bit value starting in 1904, which overflows in 2040, about two years later than everyone else, but this gets wrapped around in the Linux code in 2038 already because of the deprecated usage of time_t and/or long in the conversion.
Getting rid of the deprecated interfaces makes it work until 2040 as documented, and it could be easily extended by reinterpreting the resulting time64_t as a positive number. For the moment, I'm adding a WARN_ON() that triggers if we encounter a time before 1970 or after 2040 (the two are indistinguishable).
I really don't like the WARN_ON(), but I'd prefer to address that in a separate patch rather than impede the progress of this patch (or of this series, since 3/3 seems to be unrelated).
BTW, have you considered using the same wrap-around test (i.e. YY < 70) that we use for the year register in the other RTC chips?
That wrap-around test would have the same effect as the my original version (aside from the two bugs I now fixed), doing rougly
return time - RTC_OFFSET;
return (u32)(time - RTC_OFFSET);
or some other variation of that will give us an RTC that supports all dates between 1970 and 2106. I don't think anyone so far had a strong preference here, so I went with what Mathieu suggested and kept the original Mac behavior, but added the WARN_ON().
So, is this safe to apply? Especially in light of the warnings seen by Meelis with the PPC version.
Thanks!
Gr{oetje,eeting}s,
Geert
-- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Sun, 8 Jul 2018, Geert Uytterhoeven wrote:
On Fri, Jun 22, 2018 at 10:55 AM Arnd Bergmann arnd@arndb.de wrote:
I don't think anyone so far had a strong preference here, so I went with what Mathieu suggested and kept the original Mac behavior, but added the WARN_ON().
So, is this safe to apply? Especially in light of the warnings seen by Meelis with the PPC version.
You mean, "can we apply this and avoid warning splats?"
Meelis's result says, "no".
I forget what date the RTC gets set to when the PMU/Cuda is reset but I suspect that timezone arithmetic in either MacOS or Linux could cause it to end up in 1969.
So I'd prefer to see the WARN_ON() removed.
--
On Tue, Jun 19, 2018 at 4:04 PM Arnd Bergmann arnd@arndb.de wrote:
The real-time clock on m68k (and powerpc) mac systems uses an unsigned 32-bit value starting in 1904, which overflows in 2040, about two years later than everyone else, but this gets wrapped around in the Linux code in 2038 already because of the deprecated usage of time_t and/or long in the conversion.
Getting rid of the deprecated interfaces makes it work until 2040 as documented, and it could be easily extended by reinterpreting the resulting time64_t as a positive number. For the moment, I'm adding a WARN_ON() that triggers if we encounter a time before 1970 or after 2040 (the two are indistinguishable).
This brings it in line with the corresponding code that we have on powerpc macintosh.
Signed-off-by: Arnd Bergmann arnd@arndb.de
Thanks for your patch!
Applied and queued for v4.19, with the WARN_ON() dropped.
Gr{oetje,eeting}s,
Geert
-- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Wed, 18 Jul 2018, Geert Uytterhoeven wrote:
Thanks for your patch!
Applied and queued for v4.19, with the WARN_ON() dropped.
The patch you've committed to your for-v4.19 branch has this hunk:
@@ -269,8 +275,12 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]);
- if (result.idata == last_result.idata) + if (result.idata == last_result.idata) { + if (result.idata < RTC_OFFSET) + result.idata += 0x100000000ull; + return result.idata - RTC_OFFSET; + }
if (++count > 10) break;
That looks bogus to me, since result.idata is a long.
Also, the following hunk seems a bit pointless (?)
@@ -291,11 +301,11 @@ static long via_read_time(void) * is basically any machine with Mac II-style ADB. */
-static void via_write_time(long time) +static void via_write_time(time64_t time) { union { __u8 cdata[4]; - long idata; + __u32 idata; } data; __u8 temp;
But if data.idata needs to be changed to __u32 here, why not change the same struct member in via_read_time() also?
--
On Wed, Jul 18, 2018 at 2:02 PM, Finn Thain fthain@telegraphics.com.au wrote:
On Wed, 18 Jul 2018, Geert Uytterhoeven wrote:
Thanks for your patch!
Applied and queued for v4.19, with the WARN_ON() dropped.
The patch you've committed to your for-v4.19 branch has this hunk:
@@ -269,8 +275,12 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]);
if (result.idata == last_result.idata)
if (result.idata == last_result.idata) {
if (result.idata < RTC_OFFSET)
result.idata += 0x100000000ull;
return result.idata - RTC_OFFSET;
} if (++count > 10) break;
That looks bogus to me, since result.idata is a long.
Also, the following hunk seems a bit pointless (?)
@@ -291,11 +301,11 @@ static long via_read_time(void)
- is basically any machine with Mac II-style ADB.
*/
-static void via_write_time(long time) +static void via_write_time(time64_t time) { union { __u8 cdata[4];
long idata;
__u32 idata; } data; __u8 temp;
But if data.idata needs to be changed to __u32 here, why not change the same struct member in via_read_time() also?
Hmm, apparently I forgot to update via_read_time(), that one is indeed bogus and now inconsistent with the other functions.
The change in via_write_time() seems at least consistent wtih what we do elsewhere, and using __u32 makes this code more portable. (yes, I realize that 64-bit powermac doesn't use the VIA RTC, but it feels better to write code portably anyway).
I'd suggest we do it like below to make it consistent with the rest again, using the 1904..2040 range of dates and no warning for invalid dates.
If you agree, I'll send that as a proper patch.
Arnd
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index bf8df47a6d09..8335509969f1 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -255,12 +255,13 @@ static void via_write_pram(int offset, __u8 data) * is basically any machine with Mac II-style ADB. */
-static long via_read_time(void) +static time64_t via_read_time(void) { union { __u8 cdata[4]; - long idata; + __u32 idata; } result, last_result; + time64_t ret; int count = 1;
via_pram_command(0x81, &last_result.cdata[3]); @@ -279,12 +280,8 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]);
- if (result.idata == last_result.idata) { - if (result.idata < RTC_OFFSET) - result.idata += 0x100000000ull; - - return result.idata - RTC_OFFSET; - } + if (result.idata == last_result.idata) + return (time64_t(result.idata) - RTC_OFFSET);
if (++count > 10) break;
On Wed, 18 Jul 2018, Arnd Bergmann wrote:
Hmm, apparently I forgot to update via_read_time(), that one is indeed bogus and now inconsistent with the other functions.
The change in via_write_time() seems at least consistent wtih what we do elsewhere, and using __u32 makes this code more portable. (yes, I realize that 64-bit powermac doesn't use the VIA RTC, but it feels better to write code portably anyway).
As for portability, I think you just contradicted yourself. But I take your point about consistency. So I won't object to adopting __u32.
I'd suggest we do it like below to make it consistent with the rest again, using the 1904..2040 range of dates and no warning for invalid dates.
If you agree, I'll send that as a proper patch.
Geert may instead wish to fixup or revert the patch he has committed already...
Arnd
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index bf8df47a6d09..8335509969f1 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -255,12 +255,13 @@ static void via_write_pram(int offset, __u8 data)
- is basically any machine with Mac II-style ADB.
*/
-static long via_read_time(void) +static time64_t via_read_time(void) { union { __u8 cdata[4];
long idata;
__u32 idata; } result, last_result;
time64_t ret;
ret isn't used.
int count = 1; via_pram_command(0x81, &last_result.cdata[3]);
@@ -279,12 +280,8 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]);
if (result.idata == last_result.idata) {
if (result.idata < RTC_OFFSET)
result.idata += 0x100000000ull;
return result.idata - RTC_OFFSET;
}
if (result.idata == last_result.idata)
return (time64_t(result.idata) - RTC_OFFSET);
Did you mean to write,
return (time64_t)result.idata - RTC_OFFSET;
?
--
On Wed, Jul 18, 2018 at 3:49 PM, Finn Thain fthain@telegraphics.com.au wrote:
On Wed, 18 Jul 2018, Arnd Bergmann wrote:
-static long via_read_time(void) +static time64_t via_read_time(void) { union { __u8 cdata[4];
long idata;
__u32 idata; } result, last_result;
time64_t ret;
ret isn't used.
int count = 1; via_pram_command(0x81, &last_result.cdata[3]);
@@ -279,12 +280,8 @@ static long via_read_time(void) via_pram_command(0x89, &result.cdata[1]); via_pram_command(0x8D, &result.cdata[0]);
if (result.idata == last_result.idata) {
if (result.idata < RTC_OFFSET)
result.idata += 0x100000000ull;
return result.idata - RTC_OFFSET;
}
if (result.idata == last_result.idata)
return (time64_t(result.idata) - RTC_OFFSET);
Did you mean to write,
return (time64_t)result.idata - RTC_OFFSET;
?
Right, I should have at least tried to build it again.
Arnd
On Wed, 18 Jul 2018, I wrote:
On Wed, 18 Jul 2018, Arnd Bergmann wrote:
I'd suggest we do it like below to make it consistent with the rest again, using the 1904..2040 range of dates and no warning for invalid dates.
If you agree, I'll send that as a proper patch.
Geert may instead wish to fixup or revert the patch he has committed already...
Geert, how do you want to handle this?
Do you want a fixup patch or a v3 patch with the WARN_ON and the other two issues addressed?
I'm willing to send either one if Arnd is okay with that. I'd really like to resolve this before the merge window opens, since my PMU patch series is affected.
--
Hi Finn,
On Sun, Jul 22, 2018 at 1:56 PM Finn Thain fthain@telegraphics.com.au wrote:
On Wed, 18 Jul 2018, I wrote:
On Wed, 18 Jul 2018, Arnd Bergmann wrote:
I'd suggest we do it like below to make it consistent with the rest again, using the 1904..2040 range of dates and no warning for invalid dates.
If you agree, I'll send that as a proper patch.
Geert may instead wish to fixup or revert the patch he has committed already...
Geert, how do you want to handle this?
Do you want a fixup patch or a v3 patch with the WARN_ON and the other two issues addressed?
Please send a fixup patch, for the m68k/master branch, which is non-rebasing. I'll fold it into the original commit on the m68k/for-next branch.
I'm willing to send either one if Arnd is okay with that. I'd really like to resolve this before the merge window opens, since my PMU patch series is affected.
+1. If it's not resolved (a few days) before the merge window opens, I may have to revert the patch instead.
Thanks!
Gr{oetje,eeting}s,
Geert
Commit 397ac99c6cef ("m68k: remove dead timer code") removed set_rtc_mmss() because it was unused in 2012. However, this was itself the only user of the mach_set_clock_mmss() callback and the many implementations of that callback, which are equally unused.
This removes all of those as well.
Acked-by: Greg Ungerer gerg@linux-m68k.org Signed-off-by: Arnd Bergmann arnd@arndb.de --- v2: no changes --- arch/m68k/apollo/config.c | 8 ------ arch/m68k/atari/config.c | 5 ---- arch/m68k/atari/time.c | 63 ----------------------------------------- arch/m68k/bvme6000/config.c | 45 ----------------------------- arch/m68k/include/asm/machdep.h | 1 - arch/m68k/kernel/setup_mm.c | 1 - arch/m68k/kernel/setup_no.c | 1 - arch/m68k/mac/config.c | 2 -- arch/m68k/mac/misc.c | 16 ----------- arch/m68k/mvme147/config.c | 7 ----- arch/m68k/mvme16x/config.c | 8 ------ arch/m68k/q40/config.c | 30 -------------------- 12 files changed, 187 deletions(-)
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c index b2a6bc63f8cd..aef8d42e078d 100644 --- a/arch/m68k/apollo/config.c +++ b/arch/m68k/apollo/config.c @@ -31,7 +31,6 @@ extern void dn_sched_init(irq_handler_t handler); extern void dn_init_IRQ(void); extern u32 dn_gettimeoffset(void); extern int dn_dummy_hwclk(int, struct rtc_time *); -extern int dn_dummy_set_clock_mmss(unsigned long); extern void dn_dummy_reset(void); #ifdef CONFIG_HEARTBEAT static void dn_heartbeat(int on); @@ -156,7 +155,6 @@ void __init config_apollo(void) arch_gettimeoffset = dn_gettimeoffset; mach_max_dma_address = 0xffffffff; mach_hwclk = dn_dummy_hwclk; /* */ - mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */ mach_reset = dn_dummy_reset; /* */ #ifdef CONFIG_HEARTBEAT mach_heartbeat = dn_heartbeat; @@ -240,12 +238,6 @@ int dn_dummy_hwclk(int op, struct rtc_time *t) {
}
-int dn_dummy_set_clock_mmss(unsigned long nowtime) -{ - pr_info("set_clock_mmss\n"); - return 0; -} - void dn_dummy_reset(void) {
dn_serial_print("The end !\n"); diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c index 565c6f06ab0b..bd96702a1ad0 100644 --- a/arch/m68k/atari/config.c +++ b/arch/m68k/atari/config.c @@ -81,9 +81,6 @@ extern void atari_sched_init(irq_handler_t); extern u32 atari_gettimeoffset(void); extern int atari_mste_hwclk (int, struct rtc_time *); extern int atari_tt_hwclk (int, struct rtc_time *); -extern int atari_mste_set_clock_mmss (unsigned long); -extern int atari_tt_set_clock_mmss (unsigned long); -
/* ++roman: This is a more elaborate test for an SCC chip, since the plain * Medusa board generates DTACK at the SCC's standard addresses, but a SCC @@ -362,13 +359,11 @@ void __init config_atari(void) ATARIHW_SET(TT_CLK); pr_cont(" TT_CLK"); mach_hwclk = atari_tt_hwclk; - mach_set_clock_mmss = atari_tt_set_clock_mmss; } if (hwreg_present(&mste_rtc.sec_ones)) { ATARIHW_SET(MSTE_CLK); pr_cont(" MSTE_CLK"); mach_hwclk = atari_mste_hwclk; - mach_set_clock_mmss = atari_mste_set_clock_mmss; } if (!MACH_IS_MEDUSA && hwreg_present(&dma_wd.fdc_speed) && hwreg_write(&dma_wd.fdc_speed, 0)) { diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c index c549b48174ec..9cca64286464 100644 --- a/arch/m68k/atari/time.c +++ b/arch/m68k/atari/time.c @@ -285,69 +285,6 @@ int atari_tt_hwclk( int op, struct rtc_time *t ) return( 0 ); }
- -int atari_mste_set_clock_mmss (unsigned long nowtime) -{ - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - struct MSTE_RTC val; - unsigned char rtc_minutes; - - mste_read(&val); - rtc_minutes= val.min_ones + val.min_tens * 10; - if ((rtc_minutes < real_minutes - ? real_minutes - rtc_minutes - : rtc_minutes - real_minutes) < 30) - { - val.sec_ones = real_seconds % 10; - val.sec_tens = real_seconds / 10; - val.min_ones = real_minutes % 10; - val.min_tens = real_minutes / 10; - mste_write(&val); - } - else - return -1; - return 0; -} - -int atari_tt_set_clock_mmss (unsigned long nowtime) -{ - int retval = 0; - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - unsigned char save_control, save_freq_select, rtc_minutes; - - save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */ - RTC_WRITE (RTC_CONTROL, save_control | RTC_SET); - - save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */ - RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2); - - rtc_minutes = RTC_READ (RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY)) - rtc_minutes = bcd2bin(rtc_minutes); - - /* Since we're only adjusting minutes and seconds, don't interfere - with hour overflow. This avoids messing with unknown time zones - but requires your RTC not to be off by more than 30 minutes. */ - if ((rtc_minutes < real_minutes - ? real_minutes - rtc_minutes - : rtc_minutes - real_minutes) < 30) - { - if (!(save_control & RTC_DM_BINARY)) - { - real_seconds = bin2bcd(real_seconds); - real_minutes = bin2bcd(real_minutes); - } - RTC_WRITE (RTC_SECONDS, real_seconds); - RTC_WRITE (RTC_MINUTES, real_minutes); - } - else - retval = -1; - - RTC_WRITE (RTC_FREQ_SELECT, save_freq_select); - RTC_WRITE (RTC_CONTROL, save_control); - return retval; -} - /* * Local variables: * c-indent-level: 4 diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index 2cfff4765040..143ee9fa3893 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c @@ -41,7 +41,6 @@ static void bvme6000_get_model(char *model); extern void bvme6000_sched_init(irq_handler_t handler); extern u32 bvme6000_gettimeoffset(void); extern int bvme6000_hwclk (int, struct rtc_time *); -extern int bvme6000_set_clock_mmss (unsigned long); extern void bvme6000_reset (void); void bvme6000_set_vectors (void);
@@ -113,7 +112,6 @@ void __init config_bvme6000(void) mach_init_IRQ = bvme6000_init_IRQ; arch_gettimeoffset = bvme6000_gettimeoffset; mach_hwclk = bvme6000_hwclk; - mach_set_clock_mmss = bvme6000_set_clock_mmss; mach_reset = bvme6000_reset; mach_get_model = bvme6000_get_model;
@@ -305,46 +303,3 @@ int bvme6000_hwclk(int op, struct rtc_time *t)
return 0; } - -/* - * Set the minutes and seconds from seconds value 'nowtime'. Fail if - * clock is out by > 30 minutes. Logic lifted from atari code. - * Algorithm is to wait for the 10ms register to change, and then to - * wait a short while, and then set it. - */ - -int bvme6000_set_clock_mmss (unsigned long nowtime) -{ - int retval = 0; - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - unsigned char rtc_minutes, rtc_tenms; - volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE; - unsigned char msr = rtc->msr & 0xc0; - unsigned long flags; - volatile int i; - - rtc->msr = 0; /* Ensure clock accessible */ - rtc_minutes = bcd2bin (rtc->bcd_min); - - if ((rtc_minutes < real_minutes - ? real_minutes - rtc_minutes - : rtc_minutes - real_minutes) < 30) - { - local_irq_save(flags); - rtc_tenms = rtc->bcd_tenms; - while (rtc_tenms == rtc->bcd_tenms) - ; - for (i = 0; i < 1000; i++) - ; - rtc->bcd_min = bin2bcd(real_minutes); - rtc->bcd_sec = bin2bcd(real_seconds); - local_irq_restore(flags); - } - else - retval = -1; - - rtc->msr = msr; - - return retval; -} - diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h index 1605da48ebf2..49bd3266b4b1 100644 --- a/arch/m68k/include/asm/machdep.h +++ b/arch/m68k/include/asm/machdep.h @@ -22,7 +22,6 @@ extern int (*mach_hwclk)(int, struct rtc_time*); extern unsigned int (*mach_get_ss)(void); extern int (*mach_get_rtc_pll)(struct rtc_pll_info *); extern int (*mach_set_rtc_pll)(struct rtc_pll_info *); -extern int (*mach_set_clock_mmss)(unsigned long); extern void (*mach_reset)( void ); extern void (*mach_halt)( void ); extern void (*mach_power_off)( void ); diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index f35e3ebd6331..07244732eb41 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -88,7 +88,6 @@ void (*mach_get_hardware_list) (struct seq_file *m); /* machine dependent timer functions */ int (*mach_hwclk) (int, struct rtc_time*); EXPORT_SYMBOL(mach_hwclk); -int (*mach_set_clock_mmss) (unsigned long); unsigned int (*mach_get_ss)(void); int (*mach_get_rtc_pll)(struct rtc_pll_info *); int (*mach_set_rtc_pll)(struct rtc_pll_info *); diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c index a98af1018201..3c53e4c366ac 100644 --- a/arch/m68k/kernel/setup_no.c +++ b/arch/m68k/kernel/setup_no.c @@ -51,7 +51,6 @@ char __initdata command_line[COMMAND_LINE_SIZE];
/* machine dependent timer functions */ void (*mach_sched_init)(irq_handler_t handler) __initdata = NULL; -int (*mach_set_clock_mmss)(unsigned long); int (*mach_hwclk) (int, struct rtc_time*);
/* machine dependent reboot functions */ diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index e522307db47c..da1aeb966474 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -57,7 +57,6 @@ static unsigned long mac_orig_videoaddr; /* Mac specific timer functions */ extern u32 mac_gettimeoffset(void); extern int mac_hwclk(int, struct rtc_time *); -extern int mac_set_clock_mmss(unsigned long); extern void iop_preinit(void); extern void iop_init(void); extern void via_init(void); @@ -158,7 +157,6 @@ void __init config_mac(void) mach_get_model = mac_get_model; arch_gettimeoffset = mac_gettimeoffset; mach_hwclk = mac_hwclk; - mach_set_clock_mmss = mac_set_clock_mmss; mach_reset = mac_reset; mach_halt = mac_poweroff; mach_power_off = mac_poweroff; diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index 0a2572a6bfe5..bf8df47a6d09 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -735,19 +735,3 @@ int mac_hwclk(int op, struct rtc_time *t) } return 0; } - -/* - * Set minutes/seconds in the hardware clock - */ - -int mac_set_clock_mmss (unsigned long nowtime) -{ - struct rtc_time now; - - mac_hwclk(0, &now); - now.tm_sec = nowtime % 60; - now.tm_min = (nowtime / 60) % 60; - mac_hwclk(1, &now); - - return 0; -} diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index f8a710fd84cd..adea549d240e 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c @@ -40,7 +40,6 @@ static void mvme147_get_model(char *model); extern void mvme147_sched_init(irq_handler_t handler); extern u32 mvme147_gettimeoffset(void); extern int mvme147_hwclk (int, struct rtc_time *); -extern int mvme147_set_clock_mmss (unsigned long); extern void mvme147_reset (void);
@@ -92,7 +91,6 @@ void __init config_mvme147(void) mach_init_IRQ = mvme147_init_IRQ; arch_gettimeoffset = mvme147_gettimeoffset; mach_hwclk = mvme147_hwclk; - mach_set_clock_mmss = mvme147_set_clock_mmss; mach_reset = mvme147_reset; mach_get_model = mvme147_get_model;
@@ -164,8 +162,3 @@ int mvme147_hwclk(int op, struct rtc_time *t) } return 0; } - -int mvme147_set_clock_mmss (unsigned long nowtime) -{ - return 0; -} diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 4ffd9ef98de4..6ee36a5b528d 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c @@ -46,7 +46,6 @@ static void mvme16x_get_model(char *model); extern void mvme16x_sched_init(irq_handler_t handler); extern u32 mvme16x_gettimeoffset(void); extern int mvme16x_hwclk (int, struct rtc_time *); -extern int mvme16x_set_clock_mmss (unsigned long); extern void mvme16x_reset (void);
int bcd2int (unsigned char b); @@ -280,7 +279,6 @@ void __init config_mvme16x(void) mach_init_IRQ = mvme16x_init_IRQ; arch_gettimeoffset = mvme16x_gettimeoffset; mach_hwclk = mvme16x_hwclk; - mach_set_clock_mmss = mvme16x_set_clock_mmss; mach_reset = mvme16x_reset; mach_get_model = mvme16x_get_model; mach_get_hardware_list = mvme16x_get_hardware_list; @@ -411,9 +409,3 @@ int mvme16x_hwclk(int op, struct rtc_time *t) } return 0; } - -int mvme16x_set_clock_mmss (unsigned long nowtime) -{ - return 0; -} - diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 71c0867ecf20..96810d91da2b 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -43,7 +43,6 @@ extern void q40_sched_init(irq_handler_t handler); static u32 q40_gettimeoffset(void); static int q40_hwclk(int, struct rtc_time *); static unsigned int q40_get_ss(void); -static int q40_set_clock_mmss(unsigned long); static int q40_get_rtc_pll(struct rtc_pll_info *pll); static int q40_set_rtc_pll(struct rtc_pll_info *pll);
@@ -175,7 +174,6 @@ void __init config_q40(void) mach_get_ss = q40_get_ss; mach_get_rtc_pll = q40_get_rtc_pll; mach_set_rtc_pll = q40_set_rtc_pll; - mach_set_clock_mmss = q40_set_clock_mmss;
mach_reset = q40_reset; mach_get_model = q40_get_model; @@ -267,34 +265,6 @@ static unsigned int q40_get_ss(void) return bcd2bin(Q40_RTC_SECS); }
-/* - * Set the minutes and seconds from seconds value 'nowtime'. Fail if - * clock is out by > 30 minutes. Logic lifted from atari code. - */ - -static int q40_set_clock_mmss(unsigned long nowtime) -{ - int retval = 0; - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - - int rtc_minutes; - - rtc_minutes = bcd2bin(Q40_RTC_MINS); - - if ((rtc_minutes < real_minutes ? - real_minutes - rtc_minutes : - rtc_minutes - real_minutes) < 30) { - Q40_RTC_CTRL |= Q40_RTC_WRITE; - Q40_RTC_MINS = bin2bcd(real_minutes); - Q40_RTC_SECS = bin2bcd(real_seconds); - Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } else - retval = -1; - - return retval; -} - - /* get and set PLL calibration of RTC clock */ #define Q40_RTC_PLL_MASK ((1<<5)-1) #define Q40_RTC_PLL_SIGN (1<<5)
On Tue, Jun 19, 2018 at 4:04 PM Arnd Bergmann arnd@arndb.de wrote:
Commit 397ac99c6cef ("m68k: remove dead timer code") removed set_rtc_mmss() because it was unused in 2012. However, this was itself the only user of the mach_set_clock_mmss() callback and the many implementations of that callback, which are equally unused.
This removes all of those as well.
Acked-by: Greg Ungerer gerg@linux-m68k.org Signed-off-by: Arnd Bergmann arnd@arndb.de
Thanks, applied and queued for v4.19.
Gr{oetje,eeting}s,
Geert
-- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Tue, Jun 19, 2018 at 4:04 PM Arnd Bergmann arnd@arndb.de wrote:
As Mathieu pointed out, my conversion to time64_t was incorrect and resulted in negative times to be read from the RTC. The problem is that during the conversion from a byte array to a time64_t, the 'unsigned char' variable holding the top byte gets turned into a negative signed 32-bit integer before being assigned to the 64-bit variable for any times after 1972.
This changes the logic to cast to an unsigned 32-bit number first for the Macintosh time and then convert that to the Unix time, which then gives us a time in the documented 1904..2040 year range. I decided not to use the longer 1970..2106 range that other drivers use, for consistency with the literal interpretation of the register, but that could be easily changed if we decide we want to support any Mac after 2040.
Just to be on the safe side, I'm also adding a WARN_ON that will trigger if either the year 2040 has come and is observed by this driver, or we run into an RTC that got set back to a pre-1970 date for some reason (the two are indistinguishable).
For the RTC write functions, Andreas found another problem: both pmu_request() and cuda_request() are varargs functions, so changing the type of the arguments passed into them from 32 bit to 64 bit breaks the API for the set_rtc_time functions. This changes it back to 32 bits.
The same code exists in arch/m68k/ and is patched in an identical way now in a separate patch.
Fixes: 5bfd643583b2 ("powerpc: use time64_t in read_persistent_clock") Reported-by: Mathieu Malaterre malat@debian.org Reported-by: Andreas Schwab schwab@linux-m68k.org Signed-off-by: Arnd Bergmann arnd@arndb.de
Doing a reboot on Debian sets the hardware clock from system clock and upon reboot everything is back in shape:
[ 5.645082] rtc-generic rtc-generic: setting system clock to 2018-06-20 07:12:04 UTC (1529478724)
Tested-by: Mathieu Malaterre malat@debian.org
Thanks!
arch/powerpc/platforms/powermac/time.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 7c968e46736f..12e6e4d30602 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -42,7 +42,11 @@ #define DBG(x...) #endif
-/* Apparently the RTC stores seconds since 1 Jan 1904 */ +/*
- Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU
- times wrap in 2040. If we need to handle later times, the read_time functions
- need to be changed to interpret wrapped times as post-2040.
- */
#define RTC_OFFSET 2082844800
/* @@ -97,8 +101,11 @@ static time64_t cuda_get_time(void) if (req.reply_len != 7) printk(KERN_ERR "cuda_get_time: got %d byte reply\n", req.reply_len);
now = (req.reply[3] << 24) + (req.reply[4] << 16)
+ (req.reply[5] << 8) + req.reply[6];
now = (u32)((req.reply[3] << 24) + (req.reply[4] << 16) +
(req.reply[5] << 8) + req.reply[6]);
/* it's either after year 2040, or the RTC has gone backwards */
WARN_ON(now < RTC_OFFSET);
return now - RTC_OFFSET;
}
@@ -106,10 +113,10 @@ static time64_t cuda_get_time(void)
static int cuda_set_rtc_time(struct rtc_time *tm) {
time64_t nowtime;
u32 nowtime; struct adb_request req;
nowtime = rtc_tm_to_time64(tm) + RTC_OFFSET;
nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET); if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
@@ -140,8 +147,12 @@ static time64_t pmu_get_time(void) if (req.reply_len != 4) printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n", req.reply_len);
now = (req.reply[0] << 24) + (req.reply[1] << 16)
+ (req.reply[2] << 8) + req.reply[3];
now = (u32)((req.reply[0] << 24) + (req.reply[1] << 16) +
(req.reply[2] << 8) + req.reply[3]);
/* it's either after year 2040, or the RTC has gone backwards */
WARN_ON(now < RTC_OFFSET);
return now - RTC_OFFSET;
}
@@ -149,10 +160,10 @@ static time64_t pmu_get_time(void)
static int pmu_set_rtc_time(struct rtc_time *tm) {
time64_t nowtime;
u32 nowtime; struct adb_request req;
nowtime = rtc_tm_to_time64(tm) + RTC_OFFSET;
nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET); if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) return -ENXIO;
-- 2.9.0
A patch for the subject is now upstream. That made me finally take some time to test it on my PowerMac G4. Tha date is OK but I get two warnings with backtrace on bootup. Full dmesg below.
[ 0.000000] Total memory = 1024MB; using 2048kB for hash table (at (ptrval)) [ 0.000000] RAM mapped without BATs [ 0.000000] Linux version 4.18.0-rc2-00223-g1904148a361a (mroos@pohl) (gcc version 7.3.0 (Debian 7.3.0-24)) #88 Sun Jul 1 01:39:01 EEST 2018 [ 0.000000] Found UniNorth memory controller & host bridge @ 0xf8000000 revision: 0x11 [ 0.000000] Mapped at 0xff7c0000 [ 0.000000] Found a Keylargo mac-io controller, rev: 3, mapped at 0x(ptrval) [ 0.000000] Processor NAP mode on idle enabled. [ 0.000000] PowerMac motherboard: PowerMac G4 Silver [ 0.000000] Using PowerMac machine description [ 0.000000] bootconsole [udbg0] enabled [ 0.000000] ----------------------------------------------------- [ 0.000000] Hash_size = 0x200000 [ 0.000000] phys_mem_size = 0x40000000 [ 0.000000] dcache_bsize = 0x20 [ 0.000000] icache_bsize = 0x20 [ 0.000000] cpu_features = 0x000000000401a00a [ 0.000000] possible = 0x000000002f7ff04b [ 0.000000] always = 0x0000000000000000 [ 0.000000] cpu_user_features = 0x9c000001 0x00000000 [ 0.000000] mmu_features = 0x00000001 [ 0.000000] Hash = 0x(ptrval) [ 0.000000] Hash_mask = 0x7fff [ 0.000000] ----------------------------------------------------- [ 0.000000] Found UniNorth PCI host bridge at 0x00000000f0000000. Firmware bus number: 0->0 [ 0.000000] PCI host bridge /pci@f0000000 ranges: [ 0.000000] MEM 0x00000000f1000000..0x00000000f1ffffff -> 0x00000000f1000000 [ 0.000000] IO 0x00000000f0000000..0x00000000f07fffff -> 0x0000000000000000 [ 0.000000] MEM 0x0000000090000000..0x000000009fffffff -> 0x0000000090000000 [ 0.000000] Found UniNorth PCI host bridge at 0x00000000f2000000. Firmware bus number: 0->0 [ 0.000000] PCI host bridge /pci@f2000000 (primary) ranges: [ 0.000000] MEM 0x00000000f3000000..0x00000000f3ffffff -> 0x00000000f3000000 [ 0.000000] IO 0x00000000f2000000..0x00000000f27fffff -> 0x0000000000000000 [ 0.000000] MEM 0x0000000080000000..0x000000008fffffff -> 0x0000000080000000 [ 0.000000] Found UniNorth PCI host bridge at 0x00000000f4000000. Firmware bus number: 0->0 [ 0.000000] PCI host bridge /pci@f4000000 ranges: [ 0.000000] MEM 0x00000000f5000000..0x00000000f5ffffff -> 0x00000000f5000000 [ 0.000000] IO 0x00000000f4000000..0x00000000f47fffff -> 0x0000000000000000 [ 0.000000] via-pmu: Server Mode is disabled [ 0.000000] PMU driver v2 initialized for Core99, firmware: 0c [ 0.000000] nvram: Checking bank 0... [ 0.000000] nvram: gen0=134, gen1=135 [ 0.000000] nvram: Active bank is: 1 [ 0.000000] nvram: OF partition at 0x210 [ 0.000000] nvram: XP partition at 0x1220 [ 0.000000] nvram: NR partition at 0x1320 [ 0.000000] Top of RAM: 0x40000000, Total RAM: 0x40000000 [ 0.000000] Memory hole size: 0MB [ 0.000000] Zone ranges: [ 0.000000] DMA [mem 0x0000000000000000-0x000000002fffffff] [ 0.000000] Normal empty [ 0.000000] HighMem [mem 0x0000000030000000-0x000000003fffffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000000000000-0x000000003fffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff] [ 0.000000] On node 0 totalpages: 262144 [ 0.000000] DMA zone: 1536 pages used for memmap [ 0.000000] DMA zone: 0 pages reserved [ 0.000000] DMA zone: 196608 pages, LIFO batch:31 [ 0.000000] HighMem zone: 65536 pages, LIFO batch:15 [ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [ 0.000000] pcpu-alloc: [0] 0 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 260608 [ 0.000000] Kernel command line: root=/dev/sda3 ro [ 0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [ 0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [ 0.000000] Memory: 1029696K/1048576K available (5136K kernel code, 228K rwdata, 996K rodata, 208K init, 255K bss, 18880K reserved, 0K cma-reserved, 262144K highmem) [ 0.000000] Kernel virtual memory layout: [ 0.000000] * 0xfffcf000..0xfffff000 : fixmap [ 0.000000] * 0xff800000..0xffc00000 : highmem PTEs [ 0.000000] * 0xfded8000..0xff800000 : early ioremap [ 0.000000] * 0xf1000000..0xfded8000 : vmalloc & ioremap [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] NR_IRQS: 512, nr_irqs: 512, preallocated irqs: 16 [ 0.000000] mpic: Resetting [ 0.000000] mpic: Setting up MPIC " MPIC 1 " version 1.2 at 80040000, max 1 CPUs [ 0.000000] mpic: ISU size: 64, shift: 6, mask: 3f [ 0.000000] mpic: Initializing for 64 sources [ 0.000000] GMT Delta read from XPRAM: 120 minutes, DST: on [ 0.000000] WARNING: CPU: 0 PID: 0 at arch/powerpc/platforms/powermac/time.c:154 pmu_get_time+0x7c/0xc8 [ 0.000000] Modules linked in: [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.18.0-rc2-00223-g1904148a361a #88 [ 0.000000] NIP: c0021354 LR: c0021308 CTR: 00000000 [ 0.000000] REGS: c0659df0 TRAP: 0700 Not tainted (4.18.0-rc2-00223-g1904148a361a) [ 0.000000] MSR: 00021032 <ME,IR,DR,RI> CR: 48000222 XER: 20000000 [ 0.000000] GPR00: c0021308 c0659ea0 c0635320 00000000 00d70298 00000004 00000001 00000098 GPR08: 00d70000 00000001 00000200 c06a0000 28000228 00000000 006cf290 006cf738 GPR16: ffbc1700 00000000 00000000 0076b855 006d6594 0013da24 009f0028 40140000 GPR24: 00000000 006ac000 efff44c0 c06293ec c065e020 c06293dc c066c4e4 c0659f78 [ 0.000000] NIP [c0021354] pmu_get_time+0x7c/0xc8 [ 0.000000] LR [c0021308] pmu_get_time+0x30/0xc8 [ 0.000000] Call Trace: [ 0.000000] [c0659ea0] [c0021308] pmu_get_time+0x30/0xc8 (unreliable) [ 0.000000] [c0659f10] [c000c428] read_persistent_clock64+0xc8/0x13c [ 0.000000] [c0659f50] [c060e288] timekeeping_init+0x1c/0x24c [ 0.000000] [c0659fc0] [c06020d8] start_kernel+0x2a0/0x38c [ 0.000000] [c0659ff0] [00003444] 0x3444 [ 0.000000] Instruction dump: [ 0.000000] 8941002e 5484c00e 5508801e 88e1002f 7c844214 554a402e 7c845214 7c843a14 [ 0.000000] 7d244810 7d294910 7d2948f8 552907fe <0f090000> 3d2083da 80010074 38210070 [ 0.000000] random: get_random_bytes called from print_oops_end_marker+0x58/0x7c with crng_init=0 [ 0.000000] ---[ end trace 2e01ad9337fe08fa ]--- [ 0.000000] time_init: decrementer frequency = 33.290001 MHz [ 0.000000] time_init: processor frequency = 533.333332 MHz [ 0.000021] clocksource: timebase: mask: 0xffffffffffffffff max_cycles: 0x7ad7d595e, max_idle_ns: 440795202265 ns [ 0.000697] clocksource: timebase mult[1e09ff2c] shift[24] registered [ 0.001075] clockevent: decrementer mult[885b18a] shift[32] cpu[0] [ 0.001234] Console: colour dummy device 80x25 [ 0.001558] console [tty0] enabled [ 0.001855] bootconsole [udbg0] disabled [ 0.002335] pid_max: default: 32768 minimum: 301 [ 0.002463] Security Framework initialized [ 0.002586] AppArmor: AppArmor initialized [ 0.002676] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.002701] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.004649] devtmpfs: initialized [ 0.005064] Duplicate name in PowerPC,G4@0, renamed to "l2-cache#1" [ 0.007902] random: get_random_u32 called from bucket_table_alloc+0x90/0x1dc with crng_init=0 [ 0.008118] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns [ 0.008143] futex hash table entries: 256 (order: -1, 3072 bytes) [ 0.008462] NET: Registered protocol family 16 [ 0.008890] audit: initializing netlink subsys (disabled) [ 0.010008] KeyWest i2c @0xf8001003 irq 42 /uni-n@f8000000/i2c@f8001000 [ 0.010033] channel 0 bus <multibus> [ 0.010042] channel 1 bus <multibus> [ 0.010154] KeyWest i2c @0x80018000 irq 26 /pci@f2000000/mac-io@17/i2c@18000 [ 0.010183] channel 0 bus <multibus> [ 0.010228] PMU i2c /pci@f2000000/mac-io@17/via-pmu@16000 [ 0.010240] channel 1 bus <multibus> [ 0.010249] channel 2 bus <multibus> [ 0.010670] PCI: Probing PCI hardware [ 0.010826] PCI host bridge to bus 0000:00 [ 0.010860] pci_bus 0000:00: root bus resource [io 0x802000-0x1001fff] (bus address [0x0000-0x7fffff]) [ 0.010886] pci_bus 0000:00: root bus resource [mem 0xf1000000-0xf1ffffff] [ 0.010906] pci_bus 0000:00: root bus resource [mem 0x90000000-0x9fffffff] [ 0.010928] pci_bus 0000:00: root bus resource [bus 00-ff] [ 0.010950] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to ff [ 0.011456] pci 0000:00:0b.0: [106b:002d] type 00 class 0x060000 [ 0.011929] pci 0000:00:10.0: [1002:5046] type 00 class 0x030000 [ 0.011960] pci 0000:00:10.0: reg 0x10: [mem 0x94000000-0x97ffffff pref] [ 0.011973] pci 0000:00:10.0: reg 0x14: [io 0x802400-0x8024ff] [ 0.011986] pci 0000:00:10.0: reg 0x18: [mem 0x90000000-0x90003fff] [ 0.012014] pci 0000:00:10.0: reg 0x30: [mem 0x90020000-0x9003ffff pref] [ 0.012058] pci 0000:00:10.0: supports D1 [ 0.012948] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00 [ 0.013076] PCI host bridge to bus 0001:10 [ 0.013105] pci_bus 0001:10: root bus resource [io 0x0000-0x7fffff] [ 0.013125] pci_bus 0001:10: root bus resource [mem 0xf3000000-0xf3ffffff] [ 0.013144] pci_bus 0001:10: root bus resource [mem 0x80000000-0x8fffffff] [ 0.013193] pci_bus 0001:10: root bus resource [bus 10-ff] [ 0.013214] pci_bus 0001:10: busn_res: [bus 10-ff] end is updated to ff [ 0.013706] pci 0001:10:0b.0: [106b:002e] type 00 class 0x060000 [ 0.014424] pci 0001:10:17.0: [106b:0022] type 00 class 0xff0000 [ 0.014449] pci 0001:10:17.0: reg 0x10: [mem 0x80000000-0x8007ffff] [ 0.014685] pci 0001:10:18.0: [106b:0019] type 00 class 0x0c0310 [ 0.014710] pci 0001:10:18.0: reg 0x10: [mem 0x80081000-0x80081fff] [ 0.014944] pci 0001:10:19.0: [106b:0019] type 00 class 0x0c0310 [ 0.014970] pci 0001:10:19.0: reg 0x10: [mem 0x80080000-0x80080fff] [ 0.015553] pci_bus 0001:10: busn_res: [bus 10-ff] end is updated to 10 [ 0.015671] PCI host bridge to bus 0002:20 [ 0.015702] pci_bus 0002:20: root bus resource [io 0xff7fe000-0xffffdfff] (bus address [0x0000-0x7fffff]) [ 0.015728] pci_bus 0002:20: root bus resource [mem 0xf5000000-0xf5ffffff] [ 0.015749] pci_bus 0002:20: root bus resource [bus 20-ff] [ 0.015768] pci_bus 0002:20: busn_res: [bus 20-ff] end is updated to ff [ 0.016256] pci 0002:20:0b.0: [106b:002f] type 00 class 0x060000 [ 0.016581] pci 0002:20:0e.0: [11c1:5811] type 00 class 0x0c0010 [ 0.016606] pci 0002:20:0e.0: reg 0x10: [mem 0xf5000000-0xf5000fff] [ 0.016658] pci 0002:20:0e.0: supports D1 D2 [ 0.016665] pci 0002:20:0e.0: PME# supported from D0 D1 D2 D3hot [ 0.016875] pci 0002:20:0f.0: [106b:0021] type 00 class 0x020000 [ 0.016899] pci 0002:20:0f.0: reg 0x10: [mem 0xf5200000-0xf53fffff] [ 0.016934] pci 0002:20:0f.0: reg 0x30: [mem 0xf5100000-0xf51fffff pref] [ 0.017919] pci_bus 0002:20: busn_res: [bus 20-ff] end is updated to 20 [ 0.017991] PCI 0000:00 Cannot reserve Legacy IO [io 0x802000-0x802fff] [ 0.018011] pci_bus 0000:00: resource 4 [io 0x802000-0x1001fff] [ 0.018018] pci_bus 0000:00: resource 5 [mem 0xf1000000-0xf1ffffff] [ 0.018025] pci_bus 0000:00: resource 6 [mem 0x90000000-0x9fffffff] [ 0.018035] pci_bus 0001:10: resource 4 [io 0x0000-0x7fffff] [ 0.018042] pci_bus 0001:10: resource 5 [mem 0xf3000000-0xf3ffffff] [ 0.018049] pci_bus 0001:10: resource 6 [mem 0x80000000-0x8fffffff] [ 0.018058] pci_bus 0002:20: resource 4 [io 0xff7fe000-0xffffdfff] [ 0.018065] pci_bus 0002:20: resource 5 [mem 0xf5000000-0xf5ffffff] [ 0.025369] audit: type=2000 audit(0.008:1): state=initialized audit_enabled=0 res=1 [ 0.034974] pci 0000:00:10.0: vgaarb: VGA device added: decodes=io+mem,owns=mem,locks=none [ 0.035036] pci 0000:00:10.0: vgaarb: bridge control possible [ 0.035055] pci 0000:00:10.0: vgaarb: setting as boot device (VGA legacy resources not available) [ 0.035077] vgaarb: loaded [ 0.035363] SCSI subsystem initialized [ 0.035944] libata version 3.00 loaded. [ 0.036069] usbcore: registered new interface driver usbfs [ 0.036135] usbcore: registered new interface driver hub [ 0.036205] usbcore: registered new device driver usb [ 0.038128] clocksource: Switched to clocksource timebase [ 0.038599] AppArmor: AppArmor Filesystem Enabled [ 0.054259] NET: Registered protocol family 2 [ 0.054390] random: get_random_u32 called from neigh_hash_alloc+0x84/0xe0 with crng_init=0 [ 0.054948] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes) [ 0.054995] TCP established hash table entries: 8192 (order: 3, 32768 bytes) [ 0.055096] TCP bind hash table entries: 8192 (order: 3, 32768 bytes) [ 0.055183] TCP: Hash tables configured (established 8192 bind 8192) [ 0.055338] UDP hash table entries: 512 (order: 1, 8192 bytes) [ 0.055387] UDP-Lite hash table entries: 512 (order: 1, 8192 bytes) [ 0.055564] NET: Registered protocol family 1 [ 0.055606] NET: Registered protocol family 44 [ 0.055700] pci 0001:10:18.0: enabling device (0000 -> 0002) [ 0.114214] pci 0001:10:18.0: quirk_usb_early_handoff+0x0/0x8cc took 57137 usecs [ 0.114270] pci 0001:10:19.0: enabling device (0000 -> 0002) [ 0.174156] pci 0001:10:19.0: quirk_usb_early_handoff+0x0/0x8cc took 58481 usecs [ 0.174197] PCI: CLS mismatch (32 != 1020), using 32 bytes [ 0.174448] Thermal assist unit [ 0.174453] using timers, [ 0.174473] shrink_timer: 500 jiffies [ 0.175062] Initialise system trusted keyrings [ 0.175711] workingset: timestamp_bits=30 max_order=18 bucket_order=0 [ 0.194025] Key type asymmetric registered [ 0.194079] Asymmetric key parser 'x509' registered [ 0.194248] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252) [ 0.194278] io scheduler noop registered [ 0.194291] io scheduler deadline registered [ 0.194481] io scheduler cfq registered (default) [ 0.195115] aty128fb 0000:00:10.0: enabling device (0086 -> 0087) [ 0.195588] aty128fb 0000:00:10.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0x1111 [ 0.195623] aty128fb: ROM failed to map [ 0.195636] aty128fb: BIOS not located, guessing timings. [ 0.195659] aty128fb: Rage128 PF PRO AGP [chip rev 0x1] [ 0.195663] 16M 128-bit SDR SGRAM (1:1) [ 0.212238] Console: switching to colour frame buffer device 128x48 [ 0.227164] fb0: ATY Rage128 frame buffer device on Rage128 PF PRO AGP [ 0.227746] pmac_zilog: 0.6 (Benjamin Herrenschmidt benh@kernel.crashing.org) [ 0.228033] Generic non-volatile memory driver v1.1 [ 0.233973] loop: module loaded [ 0.234259] MacIO PCI driver attached to Keylargo chipset [ 0.236238] 0.00013020:ch-a: ttyS0 at MMIO 0x80013020 (irq = 22, base_baud = 230400) is a Z85c30 ESCC - Serial port [ 0.238389] 0.00013000:ch-b: ttyS1 at MMIO 0x80013000 (irq = 50, base_baud = 230400) is a Z85c30 ESCC - Serial port [ 1.282145] pata-macio 0.0001f000:ata-4: Activating pata-macio chipset KeyLargo ATA-4, Apple bus ID 2 [ 1.283355] scsi host0: pata_macio [ 1.283766] ata1: PATA max UDMA/66 irq 19 [ 1.445026] ata1.00: ATA-6: Maxtor 92049U3, BAC51JJ0, max UDMA/66 [ 1.445230] ata1.00: 40010544 sectors, multi 0: LBA [ 1.450748] scsi 0:0:0:0: Direct-Access ATA Maxtor 92049U3 1JJ0 PQ: 0 ANSI: 5 [ 1.452076] sd 0:0:0:0: [sda] 40010544 512-byte logical blocks: (20.5 GB/19.1 GiB) [ 1.452392] sd 0:0:0:0: [sda] Write Protect is off [ 1.452557] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00 [ 1.452660] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 1.472546] sda: [mac] sda1 sda2 sda3 sda4 [ 1.474038] sd 0:0:0:0: [sda] Attached SCSI disk [ 2.338145] pata-macio 0.00020000:ata-3: Activating pata-macio chipset KeyLargo ATA-3, Apple bus ID 0 [ 2.344877] scsi host1: pata_macio [ 2.350832] ata2: PATA max MWDMA2 irq 20 [ 2.554418] ata2.00: ATAPI: MATSHITA CD-RW CW-7586, 1A17, max MWDMA2 [ 2.560218] ata2.01: ATAPI: IOMEGA ZIP 250 ATAPI, 41.S, max UDMA/33, CDB intr [ 2.618851] scsi 1:0:0:0: CD-ROM MATSHITA CD-RW CW-7586 1A17 PQ: 0 ANSI: 5 [ 2.630676] scsi 1:0:1:0: Direct-Access IOMEGA ZIP 250 41.S PQ: 0 ANSI: 5 [ 2.671193] sd 1:0:1:0: [sdb] Attached SCSI removable disk [ 3.394143] pata-macio 0.00021000:ata-3: Activating pata-macio chipset KeyLargo ATA-3, Apple bus ID 1 [ 3.401263] scsi host2: pata_macio [ 3.407591] ata3: PATA max MWDMA2 irq 21 [ 3.413826] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 3.420094] ohci-pci: OHCI PCI platform driver [ 3.426292] ohci-pci 0001:10:18.0: OHCI PCI host controller [ 3.432457] ohci-pci 0001:10:18.0: new USB bus registered, assigned bus number 1 [ 3.438790] ohci-pci 0001:10:18.0: irq 27, io mem 0x80081000 [ 3.522135] usb usb1: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 4.18 [ 3.528544] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 3.534935] usb usb1: Product: OHCI PCI host controller [ 3.541239] usb usb1: Manufacturer: Linux 4.18.0-rc2-00223-g1904148a361a ohci_hcd [ 3.547669] usb usb1: SerialNumber: 0001:10:18.0 [ 3.554601] hub 1-0:1.0: USB hub found [ 3.561194] hub 1-0:1.0: 2 ports detected [ 3.568015] ohci-pci 0001:10:19.0: OHCI PCI host controller [ 3.574418] ohci-pci 0001:10:19.0: new USB bus registered, assigned bus number 2 [ 3.580866] ohci-pci 0001:10:19.0: irq 28, io mem 0x80080000 [ 3.666142] usb usb2: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 4.18 [ 3.672533] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 3.678911] usb usb2: Product: OHCI PCI host controller [ 3.685256] usb usb2: Manufacturer: Linux 4.18.0-rc2-00223-g1904148a361a ohci_hcd [ 3.691597] usb usb2: SerialNumber: 0001:10:19.0 [ 3.698572] hub 2-0:1.0: USB hub found [ 3.704984] hub 2-0:1.0: 2 ports detected [ 3.711898] mousedev: PS/2 mouse device common for all mice [ 3.718339] WARNING: CPU: 0 PID: 1 at arch/powerpc/platforms/powermac/time.c:154 pmu_get_time+0x7c/0xc8 [ 3.724661] Modules linked in: [ 3.730901] CPU: 0 PID: 1 Comm: swapper Tainted: G W 4.18.0-rc2-00223-g1904148a361a #88 [ 3.737332] NIP: c0021354 LR: c0021308 CTR: 00000000 [ 3.743649] REGS: ef047b50 TRAP: 0700 Tainted: G W (4.18.0-rc2-00223-g1904148a361a) [ 3.750136] MSR: 00029032 <EE,ME,IR,DR,RI> CR: 44000822 XER: 20000000 [ 3.756639] GPR00: c0021308 ef047c00 ef048000 00000000 00d7029c 00000004 00000001 0000009c GPR08: 00d70000 00000001 00000200 c06a0000 24000828 00000000 c0004c9c 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 c0670000 c0601a38 GPR24: 00000007 00000000 ef0ccf40 00000000 ef047cec ef273800 ef047cec ef047cec [ 3.788482] NIP [c0021354] pmu_get_time+0x7c/0xc8 [ 3.794736] LR [c0021308] pmu_get_time+0x30/0xc8 [ 3.800944] Call Trace: [ 3.807004] [ef047c00] [c0021308] pmu_get_time+0x30/0xc8 (unreliable) [ 3.813217] [ef047c70] [c00213e8] pmac_get_rtc_time+0x28/0x40 [ 3.819357] [ef047c80] [c000bc04] rtc_generic_get_time+0x20/0x34 [ 3.825395] [ef047c90] [c03aca34] __rtc_read_time+0x5c/0xe0 [ 3.831290] [ef047ca0] [c03acafc] rtc_read_time+0x44/0x7c [ 3.837184] [ef047cc0] [c03ad81c] __rtc_read_alarm+0x28/0x440 [ 3.843035] [ef047d30] [c03ac048] rtc_device_register+0x84/0x1b8 [ 3.848869] [ef047d80] [c03ac1e4] devm_rtc_device_register+0x68/0xe8 [ 3.854718] [ef047da0] [c061e1c8] generic_rtc_probe+0x2c/0x54 [ 3.860538] [ef047db0] [c03209b4] platform_drv_probe+0x4c/0xb8 [ 3.866355] [ef047dd0] [c031ed78] driver_probe_device+0x25c/0x35c [ 3.872071] [ef047e00] [c031ef8c] __driver_attach+0x114/0x118 [ 3.877738] [ef047e20] [c031c960] bus_for_each_dev+0x80/0xc0 [ 3.883334] [ef047e50] [c031df18] bus_add_driver+0x144/0x258 [ 3.888857] [ef047e70] [c031f81c] driver_register+0x88/0x15c [ 3.894317] [ef047e80] [c03210e0] __platform_driver_probe+0x84/0x13c [ 3.899820] [ef047ea0] [c0004aa4] do_one_initcall+0x4c/0x1a8 [ 3.905364] [ef047f00] [c06022f0] kernel_init_freeable+0x12c/0x1f4 [ 3.910893] [ef047f30] [c0004cb4] kernel_init+0x18/0x130 [ 3.916367] [ef047f40] [c00121c4] ret_from_kernel_thread+0x14/0x1c [ 3.921842] Instruction dump: [ 3.927168] 8941002e 5484c00e 5508801e 88e1002f 7c844214 554a402e 7c845214 7c843a14 [ 3.932672] 7d244810 7d294910 7d2948f8 552907fe <0f090000> 3d2083da 80010074 38210070 [ 3.938214] ---[ end trace 2e01ad9337fe08fb ]--- [ 3.944429] rtc-generic rtc-generic: rtc core: registered rtc-generic as rtc0 [ 3.950813] NET: Registered protocol family 10 [ 3.956508] _warn_unseeded_randomness: 3 callbacks suppressed [ 3.956530] random: get_random_u32 called from neigh_hash_alloc+0x84/0xe0 with crng_init=0 [ 3.969365] random: get_random_u32 called from bucket_table_alloc+0x90/0x1dc with crng_init=0 [ 3.975248] Segment Routing with IPv6 [ 3.980920] NET: Registered protocol family 17 [ 3.986625] drmem: No dynamic reconfiguration memory found [ 3.992809] Loading compiled-in X.509 certificates [ 3.998321] AppArmor: AppArmor sha1 policy hashing enabled [ 4.003695] random: get_random_bytes called from prandom_seed_full_state+0x20/0x8c with crng_init=0 [ 4.009807] input: PMU as /devices/virtual/input/input0 [ 4.015320] console [netcon0] enabled [ 4.020771] netconsole: network logging started [ 4.026490] WARNING: CPU: 0 PID: 1 at arch/powerpc/platforms/powermac/time.c:154 pmu_get_time+0x7c/0xc8 [ 4.032261] Modules linked in: [ 4.037878] CPU: 0 PID: 1 Comm: swapper Tainted: G W 4.18.0-rc2-00223-g1904148a361a #88 [ 4.043750] NIP: c0021354 LR: c0021308 CTR: 00000000 [ 4.049585] REGS: ef047cd0 TRAP: 0700 Tainted: G W (4.18.0-rc2-00223-g1904148a361a) [ 4.055572] MSR: 00029032 <EE,ME,IR,DR,RI> CR: 44000222 XER: 20000000 [ 4.061620] GPR00: c0021308 ef047d80 ef048000 00000000 00d7029c 00000004 00000001 0000009c GPR08: 00d70000 00000001 00000200 c06a0000 24000228 00000000 c0004c9c 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 c0670000 c0601a38 GPR24: 00000008 c0630f18 c062a40c c05fc10c ef047e50 ef273800 ef047e50 ef047e50 [ 4.092393] NIP [c0021354] pmu_get_time+0x7c/0xc8 [ 4.098596] LR [c0021308] pmu_get_time+0x30/0xc8 [ 4.104779] Call Trace: [ 4.110909] [ef047d80] [c0021308] pmu_get_time+0x30/0xc8 (unreliable) [ 4.117209] [ef047df0] [c00213e8] pmac_get_rtc_time+0x28/0x40 [ 4.123470] [ef047e00] [c000bc04] rtc_generic_get_time+0x20/0x34 [ 4.129770] [ef047e10] [c03aca34] __rtc_read_time+0x5c/0xe0 [ 4.136060] [ef047e20] [c03acafc] rtc_read_time+0x44/0x7c [ 4.142356] [ef047e40] [c061e000] rtc_hctosys+0x64/0x11c [ 4.148616] [ef047ea0] [c0004aa4] do_one_initcall+0x4c/0x1a8 [ 4.154866] [ef047f00] [c06022f0] kernel_init_freeable+0x12c/0x1f4 [ 4.161123] [ef047f30] [c0004cb4] kernel_init+0x18/0x130 [ 4.167359] [ef047f40] [c00121c4] ret_from_kernel_thread+0x14/0x1c [ 4.173610] Instruction dump: [ 4.179766] 8941002e 5484c00e 5508801e 88e1002f 7c844214 554a402e 7c845214 7c843a14 [ 4.186076] 7d244810 7d294910 7d2948f8 552907fe <0f090000> 3d2083da 80010074 38210070 [ 4.192388] ---[ end trace 2e01ad9337fe08fd ]--- [ 4.198643] rtc-generic rtc-generic: hctosys: unable to read the hardware clock [ 4.209046] EXT4-fs (sda3): mounting ext3 file system using the ext4 subsystem [ 4.236629] EXT4-fs (sda3): mounted filesystem with ordered data mode. Opts: (null) [ 4.243073] VFS: Mounted root (ext3 filesystem) readonly on device 8:3. [ 4.260646] devtmpfs: mounted [ 4.267211] Freeing unused kernel memory: 208K [ 4.398178] usb 2-1: new full-speed USB device number 2 using ohci-pci [ 4.629315] usb 2-1: New USB device found, idVendor=05ac, idProduct=1001, bcdDevice= 2.10 [ 4.635736] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 4.642038] usb 2-1: Product: Hub in Apple USB Keyboard [ 4.648301] usb 2-1: Manufacturer: Alps Electric [ 4.656332] hub 2-1:1.0: USB hub found [ 4.663208] hub 2-1:1.0: 3 ports detected [ 4.974155] usb 2-1.1: new low-speed USB device number 3 using ohci-pci [ 5.104225] usb 2-1.1: New USB device found, idVendor=05ac, idProduct=0201, bcdDevice= 1.02 [ 5.110383] usb 2-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 5.116265] usb 2-1.1: Product: Apple USB Keyboard [ 5.122014] usb 2-1.1: Manufacturer: Alps Electric [ 5.210159] usb 2-1.2: new low-speed USB device number 4 using ohci-pci [ 5.242205] random: fast init done [ 5.338230] usb 2-1.2: New USB device found, idVendor=05ac, idProduct=0301, bcdDevice= 5.02 [ 5.344013] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 5.349638] usb 2-1.2: Product: M4848 [ 5.355197] usb 2-1.2: Manufacturer: Logitech [ 7.600059] systemd[1]: System time before build time, advancing clock. [ 7.952523] systemd[1]: Failed to insert module 'autofs4': No such file or directory [ 8.148253] systemd[1]: systemd 239 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid) [ 8.178244] systemd[1]: Detected architecture ppc. [ 8.297863] systemd[1]: Set hostname to <pohl>. [ 8.319596] _warn_unseeded_randomness: 7 callbacks suppressed [ 8.319629] random: get_random_u32 called from bucket_table_alloc+0x90/0x1dc with crng_init=1 [ 8.456375] random: get_random_u32 called from arch_pick_mmap_layout+0xe8/0x160 with crng_init=1 [ 8.463131] random: get_random_u32 called from load_elf_binary+0x768/0x1214 with crng_init=1 [ 9.348994] _warn_unseeded_randomness: 67 callbacks suppressed [ 9.349025] random: get_random_u32 called from arch_align_stack+0x44/0x64 with crng_init=1 [ 9.362283] random: get_random_u32 called from arch_randomize_brk+0x20/0x78 with crng_init=1 [ 9.893854] random: get_random_u32 called from arch_pick_mmap_layout+0xe8/0x160 with crng_init=1 [ 9.962756] random: crng init done [ 9.969134] random: 5 get_random_xx warning(s) missed due to ratelimiting [ 13.408566] systemd[1]: Listening on Syslog Socket. [ 13.422964] systemd[1]: Listening on Journal Socket. [ 13.436231] systemd[1]: Starting of Arbitrary Executable File Formats File System Automount Point not supported. [ 13.525715] systemd[1]: Listening on udev Kernel Socket. [ 13.540122] systemd[1]: Reached target Remote File Systems. [ 13.554279] systemd[1]: Started Forward Password Requests to Wall Directory Watch. [ 13.569207] systemd[1]: Listening on udev Control Socket. [ 13.587771] systemd[1]: Starting udev Coldplug all Devices... [ 13.606824] systemd[1]: Listening on Journal Audit Socket. [ 13.626991] systemd[1]: Mounting Kernel Debug File System... [ 15.424946] PowerMac i2c bus pmu 2 registered [ 15.431134] PowerMac i2c bus pmu 1 registered [ 15.436983] PowerMac i2c bus mac-io 0 registered [ 15.442651] PowerMac i2c bus uni-n 1 registered [ 15.448242] PowerMac i2c bus uni-n 0 registered [ 15.879672] input: PowerMac Beep as /devices/pci0001:10/0001:10:17.0/input/input1 [ 16.008274] EXT4-fs (sda3): re-mounted. Opts: acl [ 16.381033] systemd-journald[543]: Received request to flush runtime journal from PID 1 [ 19.281274] genirq: Flags mismatch irq 31. 00000001 (i2sbus: i2s-a (tx)) vs. 00000001 (PMac Output) [ 19.422231] firewire_ohci 0002:20:0e.0: added OHCI v1.0 device as card 0, 8 IR + 8 IT contexts, quirks 0x0 [ 19.487853] Linux agpgart interface v0.103 [ 19.550217] sungem.c:v1.0 David S. Miller davem@redhat.com [ 19.556595] gem 0002:20:0f.0 eth0: Sun GEM (PCI) 10/100/1000BaseT Ethernet 00:03:93:48:0e:fe [ 19.566755] sd 0:0:0:0: Attached scsi generic sg0 type 0 [ 19.610255] scsi 1:0:0:0: Attached scsi generic sg1 type 5 [ 19.617423] agpgart-uninorth 0000:00:0b.0: Apple UniNorth 1.5 chipset [ 19.642340] agpgart-uninorth 0000:00:0b.0: configuring for size idx: 64 [ 19.665663] sd 1:0:1:0: Attached scsi generic sg2 type 0 [ 19.698818] sr 1:0:0:0: [sr0] scsi3-mmc drive: 32x/32x writer cd/rw xa/form2 cdda tray [ 19.704575] cdrom: Uniform CD-ROM driver Revision: 3.20 [ 19.717067] agpgart-uninorth 0000:00:0b.0: AGP aperture is 256M @ 0x0 [ 19.762489] sr 1:0:0:0: Attached scsi CD-ROM sr0 [ 19.938493] firewire_core 0002:20:0e.0: created device fw0: GUID 000393fffe480efe, S400 [ 20.294101] hidraw: raw HID events driver (C) Jiri Kosina [ 20.464381] usbcore: registered new interface driver usbhid [ 20.470456] usbhid: USB HID core driver [ 21.029892] input: Alps Electric Apple USB Keyboard as /devices/pci0001:10/0001:10:19.0/usb2/2-1/2-1.1/2-1.1:1.0/0003:05AC:0201.0001/input/input2 [ 21.103209] hid-generic 0003:05AC:0201.0001: input,hidraw0: USB HID v1.00 Keyboard [Alps Electric Apple USB Keyboard] on usb-0001:10:19.0-1.1/input0 [ 21.121248] input: Logitech M4848 as /devices/pci0001:10/0001:10:19.0/usb2/2-1/2-1.2/2-1.2:1.0/0003:05AC:0301.0002/input/input3 [ 21.145442] hid-generic 0003:05AC:0301.0002: input,hidraw1: USB HID v1.00 Mouse [Logitech M4848] on usb-0001:10:19.0-1.2/input0 [ 23.026805] Adding 848984k swap on /dev/sda4. Priority:-2 extents:1 across:848984k [ 33.034566] sungem_phy: PHY ID: 206053, addr: 0 [ 33.555712] gem 0002:20:0f.0 eth0: Found BCM5401 PHY [ 33.561204] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready [ 36.002364] gem 0002:20:0f.0 eth0: Link is up at 100 Mbps, full-duplex [ 36.007833] gem 0002:20:0f.0 eth0: Pause is enabled (rxfifo: 10240 off: 7168 on: 5632) [ 36.013215] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready [ 43.522088] aty128fb 0000:00:10.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0x1111
On Sun, Jul 1, 2018 at 5:47 PM, Meelis Roos mroos@linux.ee wrote:
A patch for the subject is now upstream. That made me finally take some time to test it on my PowerMac G4. Tha date is OK but I get two warnings with backtrace on bootup. Full dmesg below.
Thanks for testing this, and sorry for the slow reply.
[ 4.026490] WARNING: CPU: 0 PID: 1 at arch/powerpc/platforms/powermac/time.c:154 pmu_get_time+0x7c/0xc8 [ 4.032261] Modules linked in: [ 4.037878] CPU: 0 PID: 1 Comm: swapper Tainted: G W 4.18.0-rc2-00223-g1904148a361a #88 [ 4.043750] NIP: c0021354 LR: c0021308 CTR: 00000000 [ 4.049585] REGS: ef047cd0 TRAP: 0700 Tainted: G W (4.18.0-rc2-00223-g1904148a361a) [ 4.055572] MSR: 00029032 <EE,ME,IR,DR,RI> CR: 44000222 XER: 20000000 [ 4.061620] GPR00: c0021308 ef047d80 ef048000 00000000 00d7029c 00000004 00000001 0000009c GPR08: 00d70000 00000001 00000200 c06a0000 24000228 00000000 c0004c9c 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 c0670000 c0601a38 GPR24: 00000008 c0630f18 c062a40c c05fc10c ef047e50 ef273800 ef047e50 ef047e50 [ 4.092393] NIP [c0021354] pmu_get_time+0x7c/0xc8 [ 4.098596] LR [c0021308] pmu_get_time+0x30/0xc8
I don't see how the WARN_ON() triggered unless the PMU time is actually before 1970.
[ 4.104779] Call Trace: [ 4.110909] [ef047d80] [c0021308] pmu_get_time+0x30/0xc8 (unreliable) [ 4.117209] [ef047df0] [c00213e8] pmac_get_rtc_time+0x28/0x40 [ 4.123470] [ef047e00] [c000bc04] rtc_generic_get_time+0x20/0x34 [ 4.129770] [ef047e10] [c03aca34] __rtc_read_time+0x5c/0xe0 [ 4.136060] [ef047e20] [c03acafc] rtc_read_time+0x44/0x7c [ 4.142356] [ef047e40] [c061e000] rtc_hctosys+0x64/0x11c [ 4.148616] [ef047ea0] [c0004aa4] do_one_initcall+0x4c/0x1a8 [ 4.154866] [ef047f00] [c06022f0] kernel_init_freeable+0x12c/0x1f4 [ 4.161123] [ef047f30] [c0004cb4] kernel_init+0x18/0x130 [ 4.167359] [ef047f40] [c00121c4] ret_from_kernel_thread+0x14/0x1c [ 4.173610] Instruction dump: [ 4.179766] 8941002e 5484c00e 5508801e 88e1002f 7c844214 554a402e 7c845214 7c843a14 [ 4.186076] 7d244810 7d294910 7d2948f8 552907fe <0f090000> 3d2083da 80010074 38210070 [ 4.192388] ---[ end trace 2e01ad9337fe08fd ]--- [ 4.198643] rtc-generic rtc-generic: hctosys: unable to read the hardware clock
The last message here happens exactly in that case as well: tm_year is before 1970:
int rtc_valid_tm(struct rtc_time *tm) { if (tm->tm_year < 70 || ((unsigned)tm->tm_mon) >= 12 || tm->tm_mday < 1 || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) || ((unsigned)tm->tm_hour) >= 24 || ((unsigned)tm->tm_min) >= 60 || ((unsigned)tm->tm_sec) >= 60) return -EINVAL;
return 0; }
The most likely explanation I have here is that the RTC was indeed set to an incorrect date, either because of a depleted battery (not unlikely for a ~15 year old box) or because it was previously stored incorrectly. You say that the time is correct, but that could also be the case if the machine is connected to the network and synchronized using NTP. It should not have gotten the time from the RTC after that error.
If you have the time to do another test, can you boot the machine with its network disconnected, see if the warning persists (it may have been repaired after the correct time got written into the RTC during shutdown), what the output of 'sudo hwclock' is, and whether anything changes after you set the correct time using 'hwclock --systohc' and reboot?
Arnd
On Mon, 9 Jul 2018, Arnd Bergmann wrote:
The most likely explanation I have here is that the RTC was indeed set to an incorrect date, either because of a depleted battery (not unlikely for a ~15 year old box) or because it was previously stored incorrectly.
The PowerMac stores the GMT offset in NVRAM, and this gets used to initialize timezone_offset.
If timezone_offset was negative and now.tv_sec was zero, I think this could store a 1969 date in the RTC:
int update_persistent_clock64(struct timespec64 now) { struct rtc_time tm;
if (!ppc_md.set_rtc_time) return -ENODEV;
rtc_time64_to_tm(now.tv_sec + 1 + timezone_offset, &tm);
return ppc_md.set_rtc_time(&tm); }
But maybe now.tv_sec can be shown to be greater than timezone_offset.
Then, what would happen when the timezone in /etc/localtime disagrees with the timezone_offset stored in NVRAM (PRAM)?
Besides that, if the battery went flat, what use is a backtrace? Why not scrap the WARN_ON()?
--
Arnd Bergmann arnd@arndb.de writes:
As Mathieu pointed out, my conversion to time64_t was incorrect and resulted in negative times to be read from the RTC. The problem is that during the conversion from a byte array to a time64_t, the 'unsigned char' variable holding the top byte gets turned into a negative signed 32-bit integer before being assigned to the 64-bit variable for any times after 1972.
This changes the logic to cast to an unsigned 32-bit number first for the Macintosh time and then convert that to the Unix time, which then gives us a time in the documented 1904..2040 year range. I decided not to use the longer 1970..2106 range that other drivers use, for consistency with the literal interpretation of the register, but that could be easily changed if we decide we want to support any Mac after 2040.
Just to be on the safe side, I'm also adding a WARN_ON that will trigger if either the year 2040 has come and is observed by this driver, or we run into an RTC that got set back to a pre-1970 date for some reason (the two are indistinguishable).
For the RTC write functions, Andreas found another problem: both pmu_request() and cuda_request() are varargs functions, so changing the type of the arguments passed into them from 32 bit to 64 bit breaks the API for the set_rtc_time functions. This changes it back to 32 bits.
The same code exists in arch/m68k/ and is patched in an identical way now in a separate patch.
Fixes: 5bfd643583b2 ("powerpc: use time64_t in read_persistent_clock") Reported-by: Mathieu Malaterre malat@debian.org Reported-by: Andreas Schwab schwab@linux-m68k.org Signed-off-by: Arnd Bergmann arnd@arndb.de
arch/powerpc/platforms/powermac/time.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
So I think I can take this patch in isolation via the powerpc tree as a fix for 4.18.
I'll leave the other two alone.
cheers
On Wed, Jun 27, 2018 at 6:32 AM, Michael Ellerman mpe@ellerman.id.au wrote:
So I think I can take this patch in isolation via the powerpc tree as a fix for 4.18.
I'll leave the other two alone.
Yes, that is what I had intended with this series but should have made clearer. The two m68k patches are 4.19 material.
Arnd
Arnd Bergmann arnd@arndb.de writes:
On Wed, Jun 27, 2018 at 6:32 AM, Michael Ellerman mpe@ellerman.id.au wrote:
So I think I can take this patch in isolation via the powerpc tree as a fix for 4.18.
I'll leave the other two alone.
Yes, that is what I had intended with this series but should have made clearer. The two m68k patches are 4.19 material.
OK thanks.
cheers
On Tue, 2018-06-19 at 14:02:27 UTC, Arnd Bergmann wrote:
As Mathieu pointed out, my conversion to time64_t was incorrect and resulted in negative times to be read from the RTC. The problem is that during the conversion from a byte array to a time64_t, the 'unsigned char' variable holding the top byte gets turned into a negative signed 32-bit integer before being assigned to the 64-bit variable for any times after 1972.
This changes the logic to cast to an unsigned 32-bit number first for the Macintosh time and then convert that to the Unix time, which then gives us a time in the documented 1904..2040 year range. I decided not to use the longer 1970..2106 range that other drivers use, for consistency with the literal interpretation of the register, but that could be easily changed if we decide we want to support any Mac after 2040.
Just to be on the safe side, I'm also adding a WARN_ON that will trigger if either the year 2040 has come and is observed by this driver, or we run into an RTC that got set back to a pre-1970 date for some reason (the two are indistinguishable).
For the RTC write functions, Andreas found another problem: both pmu_request() and cuda_request() are varargs functions, so changing the type of the arguments passed into them from 32 bit to 64 bit breaks the API for the set_rtc_time functions. This changes it back to 32 bits.
The same code exists in arch/m68k/ and is patched in an identical way now in a separate patch.
Fixes: 5bfd643583b2 ("powerpc: use time64_t in read_persistent_clock") Reported-by: Mathieu Malaterre malat@debian.org Reported-by: Andreas Schwab schwab@linux-m68k.org Signed-off-by: Arnd Bergmann arnd@arndb.de Tested-by: Mathieu Malaterre malat@debian.org
Applied to powerpc fixes, thanks.
https://git.kernel.org/powerpc/c/22db552b50fa11d8c1d171de908a1f
cheers