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