From: "Theo de Raadt" Subject: Re: Y2K40 fixes for macppc To: Miod Vallat Cc: tech@openbsd.org Date: Fri, 09 Oct 2026 13:21:24 -0600 Looks great to me. Miod Vallat wrote: > Several macppc systems (the oldest ones with ADB, and the laptops) store > the time as the unsigned number of seconds since 1904. > > Instead of wrapping around in january 2038, they do so in february 2040. > > I might not be around to see this, but the following diff tries to cope > with this by acknowledging that this hardware was built in the late > 1990s, if not later, and that timestamps in the 1904-1970 range should > be handled as in the 2040-2106 range instead. > > With this diff, a PowerMac1,1 (courtesy of otto@ 21 years ago) allows > the system date to be set in 2041, and picks it correctly upon reboot. > > Index: dev/adb.c > =================================================================== > RCS file: /OpenBSD/src/sys/arch/macppc/dev/adb.c,v > diff -u -p -r1.52 adb.c > --- dev/adb.c 14 Apr 2024 03:26:25 -0000 1.52 > +++ dev/adb.c 9 Oct 2026 19:00:27 -0000 > @@ -1417,6 +1417,9 @@ set_adb_info(ADBSetInfoBlock * info, int > > } > > +/* Number of seconds between 19040101 and 19700101 */ > +#define DIFF19041970 2082844800 > + > /* caller should really use machine-independent version: getPramTime */ > /* this version does pseudo-adb access only */ > int > @@ -1430,7 +1433,7 @@ adb_read_date_time(time_t *time) > > switch (adbHardware) { > case ADB_HW_PMU: > - pm_read_date_time(time); > + pm_read_date_time(&t); > retcode = 0; > break; > > @@ -1450,7 +1453,6 @@ adb_read_date_time(time_t *time) > > delay(20); /* completion occurs too soon? */ > memcpy(&t, output + 1, sizeof(t)); > - *time = (time_t)t; > retcode = 0; > break; > > @@ -1460,9 +1462,16 @@ adb_read_date_time(time_t *time) > break; > } > if (retcode == 0) { > -#define DIFF19041970 2082844800 > + /* > + * The value we've obtained is a 32-bit value of the number > + * of seconds since 1904. It will wrap on 20400206. > + * Since this hardware did not exist until the late 1990s, > + * assume negative values are beyond 2040. > + */ > + *time = (time_t)t; > + if (t < DIFF19041970) > + *time += 1ULL << 32; > *time -= DIFF19041970; > - > } else { > *time = 0; > } > @@ -1483,7 +1492,7 @@ adb_set_date_time(time_t time) > switch (adbHardware) { > > case ADB_HW_CUDA: > - t = time; /* XXX eventually truncates */ > + t = time; /* truncates */ > > output[0] = 0x06; /* 6 byte message */ > output[1] = 0x01; /* to pram/rtc device */ > Index: dev/pm_direct.c > =================================================================== > RCS file: /OpenBSD/src/sys/arch/macppc/dev/pm_direct.c,v > diff -u -p -r1.35 pm_direct.c > --- dev/pm_direct.c 22 Nov 2023 18:14:35 -0000 1.35 > +++ dev/pm_direct.c 9 Oct 2026 19:00:27 -0000 > @@ -738,10 +738,9 @@ pm_adb_poweroff(void) > } > > void > -pm_read_date_time(time_t *time) > +pm_read_date_time(uint32_t *time) > { > PMData p; > - u_int32_t t; > > p.command = PMU_READ_RTC; > p.num_data = 0; > @@ -749,20 +748,18 @@ pm_read_date_time(time_t *time) > p.r_buf = p.data; > pmgrop(&p); > > - bcopy(p.data, &t, sizeof(t)); > - *time = (time_t)t; > + bcopy(p.data, time, sizeof(*time)); > } > > void > -pm_set_date_time(time_t time) > +pm_set_date_time(uint32_t time) > { > PMData p; > - u_int32_t t = time; /* XXX eventually truncates */ > > p.command = PMU_SET_RTC; > - p.num_data = sizeof(t); > + p.num_data = sizeof(time); > p.s_buf = p.r_buf = p.data; > - bcopy(&t, p.data, sizeof(t)); > + bcopy(&time, p.data, sizeof(time)); > pmgrop(&p); > } > > Index: dev/pm_direct.h > =================================================================== > RCS file: /OpenBSD/src/sys/arch/macppc/dev/pm_direct.h,v > diff -u -p -r1.17 pm_direct.h > --- dev/pm_direct.h 22 Oct 2024 21:50:02 -0000 1.17 > +++ dev/pm_direct.h 9 Oct 2026 19:00:27 -0000 > @@ -54,8 +54,8 @@ int pm_adb_op(u_char *, void *, void *, > void pm_adb_restart(void); > void pm_adb_poweroff(void); > void pm_intr(void); > -void pm_read_date_time(time_t *); > -void pm_set_date_time(time_t); > +void pm_read_date_time(uint32_t *); > +void pm_set_date_time(uint32_t); > > struct pmu_battery_info { > unsigned int flags; >