Example #1
0
void
inittodr(time_t base)
{
	struct clock_ymdhms dt;
	struct timespec ts;
	time_t rtc;

	if (!sh_clock.rtc_initialized)
		sh_clock.rtc_initialized = 1;

	sh_clock.rtc.get(sh_clock.rtc._cookie, base, &dt);
	rtc = clock_ymdhms_to_secs(&dt);

#ifdef DEBUG
	printf("inittodr: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year,
	    dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
	    dt.dt_wday);
#endif

	if (!(sh_clock.flags & SH_CLOCK_NOINITTODR) &&
	    (rtc < base ||
		dt.dt_year < MINYEAR || dt.dt_year > 2037 ||
		dt.dt_mon < 1 || dt.dt_mon > 12 ||
		dt.dt_wday > 6 ||
		dt.dt_day < 1 || dt.dt_day > 31 ||
		dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59)) {
		/*
		 * Believe the time in the file system for lack of
		 * anything better, resetting the RTC.
		 */
		ts.tv_sec = base;
		ts.tv_nsec = 0;
		tc_setclock(&ts);
		printf("WARNING: preposterous clock chip time\n");
		resettodr();
		printf(" -- CHECK AND RESET THE DATE!\n");
		return;
	}

	ts.tv_sec = rtc;
	ts.tv_nsec = 0;
	tc_setclock(&ts);

	return;
}
Example #2
0
File: aurtc.c Project: MarginC/kame
/*
 * Reset the TODR based on the time value.
 */
void
aurtc_set(struct device *dev, struct clocktime *ct)
{
	struct clock_ymdhms ymdhms;
	time_t secs;

	ymdhms.dt_sec = ct->sec;
	ymdhms.dt_min = ct->min;
	ymdhms.dt_hour = ct->hour;
	ymdhms.dt_wday = ct->dow;
	ymdhms.dt_day = ct->day;
	ymdhms.dt_mon = ct->mon;
	ymdhms.dt_year = ct->year + PB1000_YEAR_OFFSET;

	secs = clock_ymdhms_to_secs(&ymdhms);

	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(PC_BASE + PC_COUNTER_READ_0) = secs;
}
Example #3
0
void
mkclock_isa_set(struct device *self, struct clocktime *ct)
{
	struct mkclock_isa_softc *sc = (struct mkclock_isa_softc *)self;
	struct clock_ymdhms dt;
	struct timeval tv;

	dt.dt_year = ct->year + 1900;
	if (dt.dt_year < 1970)
		dt.dt_year += 100;
	dt.dt_mon  = ct->mon;
	dt.dt_day  = ct->day;
	dt.dt_wday = ct->dow;
	dt.dt_hour = ct->hour;
	dt.dt_min  = ct->min;
	dt.dt_sec  = ct->sec;
	
	tv.tv_sec = clock_ymdhms_to_secs(&dt);
	tv.tv_usec = 0;

	todr_settime(sc->sc_todr, &tv);
}
Example #4
0
/*
 * Return current RTC time. Note that due to waiting for the update cycle to
 * complete, this call may take some time.
 */
static uint64_t rtc_gettimeofday(void) {
    struct bmk_clock_ymdhms dt;

    interrupts_disable();

    /*
     * If RTC_UIP is down, we have at least 244us to obtain a
     * consistent reading before an update can occur.
     */
    while (rtc_read(RTC_STATUS_A) & RTC_UIP)
        continue;

    dt.dt_sec = bcdtobin(rtc_read(RTC_SEC));
    dt.dt_min = bcdtobin(rtc_read(RTC_MIN));
    dt.dt_hour = bcdtobin(rtc_read(RTC_HOUR));
    dt.dt_day = bcdtobin(rtc_read(RTC_DAY));
    dt.dt_mon = bcdtobin(rtc_read(RTC_MONTH));
    dt.dt_year = bcdtobin(rtc_read(RTC_YEAR)) + 2000;

    interrupts_enable();

    return clock_ymdhms_to_secs(&dt) * NSEC_PER_SEC;
}
Example #5
0
/*
 * Convert a NMEA 0183 formatted date string to seconds since the epoch.
 * The string must be of the form DDMMYY.
 * Return 0 on success, -1 if illegal characters are encountered.
 */
int
nmea_date_to_nano(char *s, int64_t *nano)
{
	struct clock_ymdhms ymd;
	time_t secs;
	char *p;
	int n;

	/* make sure the input contains only numbers and is six digits long */
	for (n = 0, p = s; n < 6 && *p && *p >= '0' && *p <= '9'; n++, p++)
		;
	if (n != 6 || (*p != '\0'))
		return (-1);

	ymd.dt_year = 2000 + (s[4] - '0') * 10 + (s[5] - '0');
	ymd.dt_mon = (s[2] - '0') * 10 + (s[3] - '0');
	ymd.dt_day = (s[0] - '0') * 10 + (s[1] - '0');
	ymd.dt_hour = ymd.dt_min = ymd.dt_sec = 0;

	secs = clock_ymdhms_to_secs(&ymd);
	*nano = secs * 1000000000LL;
	return (0);
}
Example #6
0
static void
todr_debug(const char *prefix, int rv, struct clock_ymdhms *dt,
    struct timeval *tvp)
{
	struct timeval tv_val;
	struct clock_ymdhms dt_val;

	if (dt == NULL) {
		clock_secs_to_ymdhms(tvp->tv_sec, &dt_val);
		dt = &dt_val;
	}
	if (tvp == NULL) {
		tvp = &tv_val;
		tvp->tv_sec = clock_ymdhms_to_secs(dt);
		tvp->tv_usec = 0;
	}
	printf("%s: rv = %d\n", prefix, rv);
	printf("%s: rtc_offset = %d\n", prefix, rtc_offset);
	printf("%s: %4u/%02u/%02u %02u:%02u:%02u, (wday %d) (epoch %u.%06u)\n",
	    prefix,
	    (unsigned)dt->dt_year, dt->dt_mon, dt->dt_day,
	    dt->dt_hour, dt->dt_min, dt->dt_sec,
	    dt->dt_wday, (unsigned)tvp->tv_sec, (unsigned)tvp->tv_usec);
}
Example #7
0
/*
 * 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");
}