Example #1
0
/*
 * Program DS1307 with the specified time.
 * Must be called with tod_lock held. The TOD
 * chip supports date from 1969-2068 only. We must
 * reject requests to set date below 2000.
 */
static void
todds1307_set(timestruc_t ts)
{
    struct rtc_t	rtc;
    todinfo_t	tod = utc_to_tod(ts.tv_sec);
    int		year;


    ASSERT(MUTEX_HELD(&tod_lock));

    /*
     * Year is base 1900, valid year range 1969-2068
     */
    if ((tod.tod_year < 69) || (tod.tod_year > 168))
        return;

    year = tod.tod_year;
    if (year >= 100)
        year -= 100;

    rtc.rtc_year	= int2bcd(year);
    rtc.rtc_mon	= int2bcd(tod.tod_month);
    rtc.rtc_dom	= int2bcd(tod.tod_day);
    rtc.rtc_dow	= int2bcd(tod.tod_dow);
    rtc.rtc_hrs	= int2bcd(tod.tod_hour);
    rtc.rtc_min	= int2bcd(tod.tod_min);
    rtc.rtc_sec	= int2bcd(tod.tod_sec);

    todds1307_write_rtc(&rtc);
}
Example #2
0
/*
 * program the rtc registers for alarm to go off at the specified time
 */
static void
todbq4802_set_power_alarm(timestruc_t ts)
{
	todinfo_t	tod;
	uint8_t		regc;
	struct rtc_t	rtc;

	ASSERT(MUTEX_HELD(&tod_lock));
	tod = utc_to_tod(ts.tv_sec);

	/*
	 * disable alarms and clear AF flag by reading reg Flags (D)
	 */
	regc = BQ4802_DATA_REG(RTC_ENABLES);
	BQ4802_DATA_REG(RTC_ENABLES) = regc & ~(RTC_AIE | RTC_ABE);
	(void) BQ4802_DATA_REG(RTC_FLAGS);

	rtc.rtc_asec = (uint8_t)tod.tod_sec;
	rtc.rtc_amin = (uint8_t)tod.tod_min;
	rtc.rtc_ahrs = (uint8_t)tod.tod_hour;
	rtc.rtc_adom = (uint8_t)tod.tod_day;
	DPRINTF("todbq4802_set_alarm: dom=%d hrs=%d min=%d sec=%d\n",
	    rtc.rtc_adom, rtc.rtc_ahrs, rtc.rtc_amin, rtc.rtc_asec);

	/*
	 * Write alarm values and enable alarm
	 */
	write_rtc_alarm(&rtc);

	BQ4802_DATA_REG(RTC_ENABLES) = regc | RTC_AIE | RTC_ABE;
}
/*
 * program the rtc registers for alarm to go off at the specified time
 */
static void
todm5819_set_power_alarm(timestruc_t ts)
{
	todinfo_t	tod;
	uint8_t		regb;
	struct rtc_t	rtc;

	ASSERT(MUTEX_HELD(&tod_lock));
	tod = utc_to_tod(ts.tv_sec);

	/*
	 * disable alarms
	 */
	regb = RTC_GET8(RTC_B);
	RTC_PUT8(RTC_B, (regb & ~RTC_AIE));


	rtc.rtc_asec = (uint8_t)tod.tod_sec;
	rtc.rtc_amin = (uint8_t)tod.tod_min;
	rtc.rtc_ahrs = (uint8_t)tod.tod_hour;
	rtc.rtc_adom = (uint8_t)tod.tod_day;

	write_rtc_alarm(&rtc);
	/*
	 * Enable alarm.
	 */
	RTC_PUT8(RTC_B, (regb | RTC_AIE));
}
/*
 * program the rtc registers for alarm to go off at the specified time
 */
static void
todds_set_power_alarm(timestruc_t ts)
{
	todinfo_t	tod;
	uint8_t		apcr2;
	struct rtc_t	rtc;

	ASSERT(MUTEX_HELD(&tod_lock));
	tod = utc_to_tod(ts.tv_sec);
	mutex_enter(&ds1287_reg_mutex);

	/* Clear Time Match Detect */
	select_bank(2);
	DS1287_ADDR_REG = APC_APSR;
	apcr2 = DS1287_DATA_REG;

	/* Disable Time Match Enable */
	DS1287_ADDR_REG = APC_APCR2;
	apcr2 = DS1287_DATA_REG;
	DS1287_DATA_REG = (apcr2 & (~APC_TME));

	mutex_exit(&ds1287_reg_mutex);

	rtc.rtc_asec = (uint8_t)tod.tod_sec;
	rtc.rtc_amin = (uint8_t)tod.tod_min;
	rtc.rtc_ahrs = (uint8_t)tod.tod_hour;
	rtc.rtc_adom = (uint8_t)tod.tod_day;
	rtc.rtc_amon = (uint8_t)tod.tod_month;

	rtc.apc_wdwr = (uint8_t)tod.tod_dow;
	rtc.apc_wdmr = (uint8_t)tod.tod_day;
	rtc.apc_wmr = (uint8_t)tod.tod_month;
	rtc.apc_wyr = tod.tod_year % 100;
	rtc.apc_wcr = (tod.tod_year / 100) + 19;

	write_rtc_alarm(&rtc);

	mutex_enter(&ds1287_reg_mutex);
	/* Enable Time Match enable */
	select_bank(2);
	DS1287_ADDR_REG = APC_APCR2;
	DS1287_DATA_REG = (apcr2 | APC_TME);

	mutex_exit(&ds1287_reg_mutex);
}
Example #5
0
/*
 * Write the specified time into the clock chip.
 * Must be called with tod_lock held.
 */
static void
todbq4802_set(timestruc_t ts)
{
	struct rtc_t	rtc;
	todinfo_t tod = utc_to_tod(ts.tv_sec);
	int year;

	ASSERT(MUTEX_HELD(&tod_lock));

	/* tod_year is base 1900 so this code needs to adjust */
	year = 1900 + tod.tod_year;
	rtc.rtc_year	= year % 100;
	rtc.rtc_century = year / 100;
	rtc.rtc_mon	= (uint8_t)tod.tod_month;
	rtc.rtc_dom	= (uint8_t)tod.tod_day;
	rtc.rtc_dow	= (uint8_t)tod.tod_dow;
	rtc.rtc_hrs	= (uint8_t)tod.tod_hour;
	rtc.rtc_min	= (uint8_t)tod.tod_min;
	rtc.rtc_sec	= (uint8_t)tod.tod_sec;
	DPRINTF("todbq4802_set: year=%d dom=%d hrs=%d min=%d sec=%d\n",
	    rtc.rtc_year, rtc.rtc_dom, rtc.rtc_hrs, rtc.rtc_min, rtc.rtc_sec);

	write_rtc_time(&rtc);
}
Example #6
0
static timestruc_t
todxen_get(tod_ops_t *top)
{
	todinfo_t tod;
	timestruc_t ts, wcts;
	shared_info_t *si = HYPERVISOR_shared_info;
	uint32_t xen_wc_version;
	hrtime_t now;

	ASSERT(MUTEX_HELD(&tod_lock));

	/*
	 * Pick up the wallclock base time
	 */
	do {
		xen_wc_version = si->wc_version;

		membar_consumer();

		wcts.tv_sec = si->wc_sec;
		wcts.tv_nsec = si->wc_nsec;

		membar_consumer();

	} while ((si->wc_version & 1) | (xen_wc_version ^ si->wc_version));

	/*
	 * Compute the TOD as the wallclock (boot) time plus time-since-boot
	 * (/not/ hrtime!) and normalize.
	 */
	now = xpv_getsystime() +
	    (hrtime_t)wcts.tv_nsec + (hrtime_t)wcts.tv_sec * NANOSEC;
	ts.tv_sec = (time_t)(now / NANOSEC);
	ts.tv_nsec = (long)(now % NANOSEC);

	/*
	 * Apply GMT lag correction from /etc/rtc_config to get UTC time
	 */
	ts.tv_sec += ggmtl();

	/*
	 * Validate the TOD in case of total insanity
	 */
	tod = utc_to_tod(ts.tv_sec);
	if (tod.tod_year < 69) {
		static int range_warn = 1;	/* warn only once */

		if (range_warn) {
			/*
			 * If we're dom0, go invoke the underlying driver; the
			 * routine should complain if it discovers something
			 * wrong.
			 */
			if (DOMAIN_IS_INITDOMAIN(xen_info))
				(void) TODOP_GET(top->tod_next);

			/*
			 * Check the virtual hardware.
			 */
			if (tod.tod_year > 38)
				cmn_err(CE_WARN,
				    "hypervisor wall clock is out "
				    "of range -- time needs to be reset");
			range_warn = 0;
		}
		tod.tod_year += 100;
		ts.tv_sec = tod_to_utc(tod);
	}

	return (ts);
}