xref: /onnv-gate/usr/src/uts/i86pc/io/hardclk.c (revision 3446:5903aece022d)
1*3446Smrj /*
2*3446Smrj  * CDDL HEADER START
3*3446Smrj  *
4*3446Smrj  * The contents of this file are subject to the terms of the
5*3446Smrj  * Common Development and Distribution License (the "License").
6*3446Smrj  * You may not use this file except in compliance with the License.
7*3446Smrj  *
8*3446Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3446Smrj  * or http://www.opensolaris.org/os/licensing.
10*3446Smrj  * See the License for the specific language governing permissions
11*3446Smrj  * and limitations under the License.
12*3446Smrj  *
13*3446Smrj  * When distributing Covered Code, include this CDDL HEADER in each
14*3446Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3446Smrj  * If applicable, add the following below this CDDL HEADER, with the
16*3446Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
17*3446Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3446Smrj  *
19*3446Smrj  * CDDL HEADER END
20*3446Smrj  */
21*3446Smrj 
22*3446Smrj /*
23*3446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*3446Smrj  * Use is subject to license terms.
25*3446Smrj  */
26*3446Smrj 
27*3446Smrj /*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.	*/
28*3446Smrj /*	Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T	*/
29*3446Smrj /*	  All Rights Reserved  	*/
30*3446Smrj 
31*3446Smrj #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*3446Smrj 
33*3446Smrj #include <sys/param.h>
34*3446Smrj #include <sys/time.h>
35*3446Smrj #include <sys/systm.h>
36*3446Smrj #include <sys/archsystm.h>
37*3446Smrj #include <sys/lockstat.h>
38*3446Smrj 
39*3446Smrj #include <sys/clock.h>
40*3446Smrj #include <sys/debug.h>
41*3446Smrj #include <sys/smp_impldefs.h>
42*3446Smrj #include <sys/rtc.h>
43*3446Smrj 
44*3446Smrj /*
45*3446Smrj  * This file contains all generic part of clock and timer handling.
46*3446Smrj  * Specifics are now in separate files and may be overridden by TOD
47*3446Smrj  * modules.
48*3446Smrj  */
49*3446Smrj unsigned int microdata = 50;	/* loop count for 10 microsecond wait. */
50*3446Smrj 				/* MUST be initialized for those who */
51*3446Smrj 				/* insist on calling "tenmicrosec" before */
52*3446Smrj 				/* the clock has been initialized. */
53*3446Smrj 
54*3446Smrj char *tod_module_name;		/* Settable in /etc/system */
55*3446Smrj 
56*3446Smrj /*
57*3446Smrj  * Write the specified time into the clock chip.
58*3446Smrj  * Must be called with tod_lock held.
59*3446Smrj  */
60*3446Smrj void
61*3446Smrj tod_set(timestruc_t ts)
62*3446Smrj {
63*3446Smrj 	ASSERT(MUTEX_HELD(&tod_lock));
64*3446Smrj 
65*3446Smrj 	/*
66*3446Smrj 	 * Prevent false alarm in tod_validate() due to tod value change.
67*3446Smrj 	 */
68*3446Smrj 	tod_fault_reset();
69*3446Smrj 	TODOP_SET(tod_ops, ts);
70*3446Smrj }
71*3446Smrj 
72*3446Smrj /*
73*3446Smrj  * Read the current time from the clock chip and convert to UNIX form.
74*3446Smrj  * Assumes that the year in the clock chip is valid.
75*3446Smrj  * Must be called with tod_lock held.
76*3446Smrj  */
77*3446Smrj timestruc_t
78*3446Smrj tod_get(void)
79*3446Smrj {
80*3446Smrj 	timestruc_t ts;
81*3446Smrj 
82*3446Smrj 	ASSERT(MUTEX_HELD(&tod_lock));
83*3446Smrj 
84*3446Smrj 	ts = TODOP_GET(tod_ops);
85*3446Smrj 	ts.tv_sec = tod_validate(ts.tv_sec);
86*3446Smrj 	return (ts);
87*3446Smrj }
88*3446Smrj 
89*3446Smrj /*
90*3446Smrj  * The following wrappers have been added so that locking
91*3446Smrj  * can be exported to platform-independent clock routines
92*3446Smrj  * (ie adjtime(), clock_setttime()), via a functional interface.
93*3446Smrj  */
94*3446Smrj int
95*3446Smrj hr_clock_lock(void)
96*3446Smrj {
97*3446Smrj 	ushort_t s;
98*3446Smrj 
99*3446Smrj 	CLOCK_LOCK(&s);
100*3446Smrj 	return (s);
101*3446Smrj }
102*3446Smrj 
103*3446Smrj void
104*3446Smrj hr_clock_unlock(int s)
105*3446Smrj {
106*3446Smrj 	CLOCK_UNLOCK(s);
107*3446Smrj }
108*3446Smrj 
109*3446Smrj /*
110*3446Smrj  * Support routines for horrid GMT lag handling
111*3446Smrj  */
112*3446Smrj 
113*3446Smrj static time_t gmt_lag;		/* offset in seconds of gmt to local time */
114*3446Smrj 
115*3446Smrj void
116*3446Smrj sgmtl(time_t arg)
117*3446Smrj {
118*3446Smrj 	gmt_lag = arg;
119*3446Smrj }
120*3446Smrj 
121*3446Smrj time_t
122*3446Smrj ggmtl(void)
123*3446Smrj {
124*3446Smrj 	return (gmt_lag);
125*3446Smrj }
126*3446Smrj 
127*3446Smrj /* rtcsync() - set 'time', assuming RTC and GMT lag are correct */
128*3446Smrj 
129*3446Smrj void
130*3446Smrj rtcsync(void)
131*3446Smrj {
132*3446Smrj 	timestruc_t ts;
133*3446Smrj 
134*3446Smrj 	mutex_enter(&tod_lock);
135*3446Smrj 	ts = TODOP_GET(tod_ops);
136*3446Smrj 	set_hrestime(&ts);
137*3446Smrj 	mutex_exit(&tod_lock);
138*3446Smrj }
139