/* * inittodr: * * Initialize time from the time-of-day register. */ #define MINYEAR 2003 /* minimum plausible year */ void inittodr(time_t base) { time_t deltat; struct timeval rtctime; struct timespec ts; int badbase; if (base < (MINYEAR - 1970) * SECYR) { printf("WARNING: preposterous time in file system\n"); /* read the system clock anyway */ base = (MINYEAR - 1970) * SECYR; badbase = 1; } else badbase = 0; if (todr_handle == NULL || todr_gettime(todr_handle, &rtctime) != 0 || rtctime.tv_sec == 0) { /* * Believe the time in the file system for lack of * anything better, resetting the TODR. */ rtctime.tv_sec = base; rtctime.tv_usec = 0; if (todr_handle != NULL && !badbase) { printf("WARNING: preposterous clock chip time\n"); resettodr(); } ts.tv_sec = rtctime.tv_sec; ts.tv_nsec = rtctime.tv_usec * 1000; tc_setclock(&ts); goto bad; } else { ts.tv_sec = rtctime.tv_sec; ts.tv_nsec = rtctime.tv_usec * 1000; tc_setclock(&ts); } if (!badbase) { /* * See if we gained/lost two or more days; if * so, assume something is amiss. */ deltat = rtctime.tv_sec - base; if (deltat < 0) deltat = -deltat; if (deltat < 2 * SECDAY) return; /* all is well */ printf("WARNING: clock %s %ld days\n", rtctime.tv_sec < base ? "lost" : "gained", (long)deltat / SECDAY); } bad: printf("WARNING: CHECK AND RESET THE DATE!\n"); }
void mkclock_isa_get(struct device *self, time_t base, struct clocktime *ct) { struct mkclock_isa_softc *sc = (struct mkclock_isa_softc *)self; struct clock_ymdhms dt; struct timeval tv; todr_gettime(sc->sc_todr, &tv); /* Note: we ignore `tv_usec'. */ clock_secs_to_ymdhms(tv.tv_sec, &dt); ct->year = dt.dt_year - 1900; ct->mon = dt.dt_mon; ct->day = dt.dt_day; ct->hour = dt.dt_hour; ct->min = dt.dt_min; ct->sec = dt.dt_sec; ct->dow = dt.dt_wday; }
/* * Set up the system's time, given a `reasonable' time value. */ void inittodr(time_t base) { bool badbase = false; bool waszero = (base == 0); bool goodtime = false; bool badrtc = false; int s; struct timespec ts; struct timeval tv; rnd_add_data(NULL, &base, sizeof(base), 0); if (base < 5 * SECS_PER_COMMON_YEAR) { struct clock_ymdhms basedate; /* * If base is 0, assume filesystem time is just unknown * instead of preposterous. Don't bark. */ if (base != 0) printf("WARNING: preposterous time in file system\n"); /* not going to use it anyway, if the chip is readable */ basedate.dt_year = 2010; basedate.dt_mon = 1; basedate.dt_day = 1; basedate.dt_hour = 12; basedate.dt_min = 0; basedate.dt_sec = 0; base = clock_ymdhms_to_secs(&basedate); badbase = true; } /* * Some ports need to be supplied base in order to fabricate a time_t. */ if (todr_handle) todr_handle->base_time = base; if ((todr_handle == NULL) || (todr_gettime(todr_handle, &tv) != 0) || (tv.tv_sec < (25 * SECS_PER_COMMON_YEAR))) { if (todr_handle != NULL) printf("WARNING: preposterous TOD clock time\n"); else printf("WARNING: no TOD clock present\n"); badrtc = true; } else { time_t deltat = tv.tv_sec - base; if (deltat < 0) deltat = -deltat; if (!badbase && deltat >= 2 * SECS_PER_DAY) { if (tv.tv_sec < base) { /* * The clock should never go backwards * relative to filesystem time. If it * does by more than the threshold, * believe the filesystem. */ printf("WARNING: clock lost %" PRId64 " days\n", deltat / SECS_PER_DAY); badrtc = true; } else { aprint_verbose("WARNING: clock gained %" PRId64 " days\n", deltat / SECS_PER_DAY); goodtime = true; } } else { goodtime = true; } rnd_add_data(NULL, &tv, sizeof(tv), 0); } /* if the rtc time is bad, use the filesystem time */ if (badrtc) { if (badbase) { printf("WARNING: using default initial time\n"); } else { printf("WARNING: using filesystem time\n"); } tv.tv_sec = base; tv.tv_usec = 0; } timeset = true; ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; s = splclock(); tc_setclock(&ts); splx(s); if (waszero || goodtime) return; printf("WARNING: CHECK AND RESET THE DATE!\n"); }