03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
88294e09b5c27cbb12b6735e2fb247a86b76666dRichard Bean * Common Development and Distribution License (the "License").
88294e09b5c27cbb12b6735e2fb247a86b76666dRichard Bean * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * tod driver module for Serengeti
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This module implements a soft tod since
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Serengeti has no tod part.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/modctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/systm.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cpuvar.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/promif.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc_iosram.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/todsg.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cmn_err.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/time.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysmacros.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/clock.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if defined(DEBUG) || defined(lint)
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int todsg_debug = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DCMNERR if (todsg_debug) cmn_err
03831d35f7499c87d51205817c93e9a8d42c4baestevel#else
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DCMNERR
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define OFFSET(base, field) ((char *)&base.field - (char *)&base)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SC_DOWN_COUNT_THRESHOLD 2
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SC_TOD_MIN_REV 2
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic timestruc_t todsg_get(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void todsg_set(timestruc_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint32_t todsg_set_watchdog_timer(uint_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint32_t todsg_clear_watchdog_timer(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void todsg_set_power_alarm(timestruc_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void todsg_clear_power_alarm(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint64_t todsg_get_cpufrequency(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int update_heartbeat(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int verify_sc_tod_version(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int update_tod_skew(time_t skew);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint32_t i_am_alive = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint32_t sc_tod_version = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic time_t skew_adjust = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int is_sc_down = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int adjust_sc_down = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Module linkage information for the kernel.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modlmisc modlmisc = {
88294e09b5c27cbb12b6735e2fb247a86b76666dRichard Bean &mod_miscops, "Serengeti tod module"
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modlinkage modlinkage = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MODREV_1, (void *)&modlmisc, NULL
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg:_init(): begins");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(tod_module_name, "todsg") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t ssc_time = (time_t)0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char obp_string[80];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * To obtain the initial start of day time, we use an
03831d35f7499c87d51205817c93e9a8d42c4baestevel * OBP callback; this is because the iosram is not yet
03831d35f7499c87d51205817c93e9a8d42c4baestevel * accessible from the OS at this early stage of startup.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Set the string to pass to OBP
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(obp_string,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "h# %p \" unix-get-tod\" $find if execute else 3drop then",
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (void *)&ssc_time);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel prom_interpret(obp_string, 0, 0, 0, 0, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ssc_time == (time_t)0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Initial date is invalid. "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "This can be caused by older firmware.");
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "Please flashupdate the System "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "Controller firmware to the latest version.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "Attempting to set the date and time "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "based on the last shutdown.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "Please inspect the date and time and "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "correct if necessary.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel hrestime.tv_sec = ssc_time;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg: _init(): time from OBP 0x%lX",
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson ssc_time);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Verify whether the received date/clock has overflowed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * an integer(32bit), so that we capture any corrupted
03831d35f7499c87d51205817c93e9a8d42c4baestevel * date from SC, thereby preventing boot failure.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (TIMESPEC_OVERFLOW(&hrestime)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Date overflow detected.");
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "Attempting to set the date and time "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "based on the last shutdown.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "Please inspect the date and time and "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "correct if necessary.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * By setting hrestime.tv_sec to zero
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we force the vfs_mountroot() to set
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the date from the last shutdown.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel hrestime.tv_sec = (time_t)0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Save the skew so that we can update
03831d35f7499c87d51205817c93e9a8d42c4baestevel * IOSRAM when it becomes accessible.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel skew_adjust = -ssc_time;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg:_init(): set tod_ops");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_get = todsg_get;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_set = todsg_set;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_set_watchdog_timer = todsg_set_watchdog_timer;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_clear_watchdog_timer = todsg_clear_watchdog_timer;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_set_power_alarm = todsg_set_power_alarm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_clear_power_alarm = todsg_clear_power_alarm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_ops.tod_get_cpufrequency = todsg_get_cpufrequency;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_install(&modlinkage));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(tod_module_name, "todsg") == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBUSY);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_remove(&modlinkage));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_info(struct modinfo *modinfop)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_info(&modlinkage, modinfop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelupdate_heartbeat(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int complained = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Update the heartbeat */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (i_am_alive == UINT32_MAX)
03831d35f7499c87d51205817c93e9a8d42c4baestevel i_am_alive = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel i_am_alive++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_write(SBBC_TOD_KEY, OFFSET(tod_buf, tod_i_am_alive),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&i_am_alive, sizeof (uint32_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "update_heartbeat(): write heartbeat failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (complained);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelverify_sc_tod_version(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t magic;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!todsg_use_sc)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * read tod_version only when the first time and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * when there has been a previous sc down time
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!sc_tod_version || is_sc_down >= SC_DOWN_COUNT_THRESHOLD) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_read(SBBC_TOD_KEY, OFFSET(tod_buf, tod_magic),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&magic, sizeof (uint32_t)) ||
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson magic != TODSG_MAGIC) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "get_sc_tod_version(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "TOD SRAM magic error");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_read(SBBC_TOD_KEY, OFFSET(tod_buf, tod_version),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&sc_tod_version, sizeof (uint32_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "get_sc_tod_version(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "read tod version failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel sc_tod_version = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sc_tod_version >= SC_TOD_MIN_REV) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel todsg_use_sc = 0;
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson cmn_err(CE_WARN, "todsg_get(): incorrect firmware version, "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "(%d): expected version >= %d.", sc_tod_version,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson SC_TOD_MIN_REV);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelupdate_tod_skew(time_t skew)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t domain_skew;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int complained = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "update_tod_skew(): skew 0x%lX", skew);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_read(SBBC_TOD_KEY, OFFSET(tod_buf, tod_domain_skew),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&domain_skew, sizeof (time_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson cmn_err(CE_WARN,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "update_tod_skew(): read tod domain skew failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel domain_skew += skew;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* we shall update the skew_adjust too now */
03831d35f7499c87d51205817c93e9a8d42c4baestevel domain_skew += skew_adjust;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && iosram_write(SBBC_TOD_KEY,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson OFFSET(tod_buf, tod_domain_skew), (char *)&domain_skew,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson sizeof (time_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson cmn_err(CE_WARN,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "update_tod_skew(): write domain skew failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained)
03831d35f7499c87d51205817c93e9a8d42c4baestevel skew_adjust = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (complained);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Return time value read from IOSRAM.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Must be called with tod_lock held.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic timestruc_t
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_get(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t seconds;
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t domain_skew;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int complained = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static time_t pre_seconds = (time_t)0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(MUTEX_HELD(&tod_lock));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!verify_sc_tod_version()) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* if we can't use SC */
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto return_hrestime;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (watchdog_activated != 0 || watchdog_enable != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained = update_heartbeat();
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && (iosram_read(SBBC_TOD_KEY,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson OFFSET(tod_buf, tod_get_value), (char *)&seconds,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson sizeof (time_t)))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_get(): read 64-bit tod value failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && skew_adjust) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This is our first chance to update IOSRAM
03831d35f7499c87d51205817c93e9a8d42c4baestevel * with local copy of the skew, so update it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained = update_tod_skew(0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && iosram_read(SBBC_TOD_KEY,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson OFFSET(tod_buf, tod_domain_skew), (char *)&domain_skew,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson sizeof (time_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_get(): read tod domain skew failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (complained) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_get(): turned off using tod");
03831d35f7499c87d51205817c93e9a8d42c4baestevel todsg_use_sc = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto return_hrestime;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the SC gets rebooted, and we are using NTP, then we need
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to sync the IOSRAM to hrestime when the SC comes back. We
03831d35f7499c87d51205817c93e9a8d42c4baestevel * can determine that either NTP slew (or date -a) was called if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the global timedelta was non-zero at any point while the SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel * was away. If timedelta remains zero throughout, then the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * default action will be to sync hrestime to IOSRAM
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (seconds != pre_seconds) { /* SC still alive */
03831d35f7499c87d51205817c93e9a8d42c4baestevel pre_seconds = seconds;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (is_sc_down >= SC_DOWN_COUNT_THRESHOLD && adjust_sc_down) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel skew_adjust = hrestime.tv_sec - (seconds + domain_skew);
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained = update_tod_skew(0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && (iosram_read(SBBC_TOD_KEY,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson OFFSET(tod_buf, tod_domain_skew),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&domain_skew, sizeof (time_t)))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_get(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "read tod domain skew failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel is_sc_down = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel adjust_sc_down = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If complained then domain_skew is invalid.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Hand back hrestime instead.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained) {
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson /*
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson * The read was successful so ensure the failure
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson * flag is clear.
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson */
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson tod_status_clear(TOD_GET_FAILED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel timestruc_t ts = {0, 0};
03831d35f7499c87d51205817c93e9a8d42c4baestevel ts.tv_sec = seconds + domain_skew;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ts);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto return_hrestime;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* SC/TOD is down */
03831d35f7499c87d51205817c93e9a8d42c4baestevel is_sc_down++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (timedelta != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel adjust_sc_down = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelreturn_hrestime:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson * We need to inform the tod_validate() code to stop checking until
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson * the SC comes back up again. Note we will return hrestime below
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson * which may be different to the previous TOD value we returned.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson tod_status_set(TOD_GET_FAILED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (hrestime);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_set(timestruc_t ts)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int complained = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t domain_skew;
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t seconds;
03831d35f7499c87d51205817c93e9a8d42c4baestevel time_t hwtod;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(MUTEX_HELD(&tod_lock));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!verify_sc_tod_version()) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* if we can't use SC */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the SC is down just note the fact that we should
03831d35f7499c87d51205817c93e9a8d42c4baestevel * have adjusted the hardware skew which caters for calls
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to stime(). (eg NTP step, as opposed to NTP skew)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (is_sc_down) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel adjust_sc_down = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reason to update i_am_alive here:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * To work around a generic Solaris bug that can
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cause tod_get() to be starved by too frequent
03831d35f7499c87d51205817c93e9a8d42c4baestevel * calls to the stime() system call.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (watchdog_activated != 0 || watchdog_enable != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained = update_heartbeat();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We are passed hrestime from clock.c so we need to read the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * IOSRAM for the hardware's idea of the time to see if we need
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to update the skew.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && (iosram_read(SBBC_TOD_KEY,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson OFFSET(tod_buf, tod_get_value), (char *)&seconds,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson sizeof (time_t)))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_set(): read 64-bit tod value failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && iosram_read(SBBC_TOD_KEY,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson OFFSET(tod_buf, tod_domain_skew), (char *)&domain_skew,
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson sizeof (time_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_set(): read tod domain skew failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Only update the skew if the time passed differs from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * what the hardware thinks & no errors talking to SC
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!complained && (ts.tv_sec != (seconds + domain_skew))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel hwtod = seconds + domain_skew;
03831d35f7499c87d51205817c93e9a8d42c4baestevel complained = update_tod_skew(ts.tv_sec - hwtod);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_set(): set time %lX (%lX)%s",
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson ts.tv_sec, hwtod, complained ? " failed" : "");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (complained) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "todsg_set(): turned off using tod");
03831d35f7499c87d51205817c93e9a8d42c4baestevel todsg_use_sc = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint32_t
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_set_watchdog_timer(uint32_t timeoutval)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(MUTEX_HELD(&tod_lock));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!verify_sc_tod_version()) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_set_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "verify_sc_tod_version failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_set_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "set watchdog timer value = %d", timeoutval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_write(SBBC_TOD_KEY, OFFSET(tod_buf, tod_timeout_period),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&timeoutval, sizeof (uint32_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_set_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "write new timeout value failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel watchdog_activated = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (timeoutval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint32_t
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_clear_watchdog_timer(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel tod_iosram_t tod_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t r_timeout_period;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t w_timeout_period;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(MUTEX_HELD(&tod_lock));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((watchdog_activated == 0) || !verify_sc_tod_version()) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_set_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "either watchdog not activated or "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "verify_sc_tod_version failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_read(SBBC_TOD_KEY, OFFSET(tod_buf, tod_timeout_period),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&r_timeout_period, sizeof (uint32_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_clear_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "read timeout value failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_clear_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "clear watchdog timer (old value=%d)", r_timeout_period);
03831d35f7499c87d51205817c93e9a8d42c4baestevel w_timeout_period = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (iosram_write(SBBC_TOD_KEY, OFFSET(tod_buf, tod_timeout_period),
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson (char *)&w_timeout_period, sizeof (uint32_t))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_clear_watchdog_timer(): "
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson "write zero timeout value failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel watchdog_activated = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (r_timeout_period);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Null function.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_set_power_alarm(timestruc_t ts)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(MUTEX_HELD(&tod_lock));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Null function
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_clear_power_alarm()
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(MUTEX_HELD(&tod_lock));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get clock freq from the cpunode
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baesteveluint64_t
03831d35f7499c87d51205817c93e9a8d42c4baesteveltodsg_get_cpufrequency(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel DCMNERR(CE_NOTE, "todsg_get_cpufrequency(): frequency=%ldMHz",
8fc99e42676a23421c75e76660640f9765d693b1Trevor Thompson cpunodes[CPU->cpu_id].clock_freq/1000000);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (cpunodes[CPU->cpu_id].clock_freq);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}