xref: /netbsd/sys/arch/newsmips/newsmips/clock.c (revision bf9ec67e)
1 /*	$NetBSD: clock.c,v 1.7 2000/07/29 11:11:53 tsubai Exp $	*/
2 
3 /*
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1992, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department, Ralph Campbell, and Kazumasa Utashiro of
11  * Software Research Associates, Inc.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *	This product includes software developed by the University of
24  *	California, Berkeley and its contributors.
25  * 4. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  * from: Utah $Hdr: clock.c 1.18 91/01/21$
42  *
43  *	@(#)clock.c	8.1 (Berkeley) 6/11/93
44  */
45 
46 #include <sys/param.h>
47 #include <sys/device.h>
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
50 
51 #include <dev/clock_subr.h>
52 
53 #include <newsmips/newsmips/clockvar.h>
54 
55 static struct clockfns *clockfns;
56 static struct device *clockdev;
57 static int clockinitted;
58 
59 void
60 clockattach(dev, fns)
61 	struct device *dev;
62 	struct clockfns *fns;
63 {
64 	if (clockfns != NULL)
65 		panic("clockattach: multiple clocks");
66 
67 	clockdev = dev;
68 	clockfns = fns;
69 }
70 
71 /*
72  * Machine-dependent clock routines.
73  *
74  * Startrtclock restarts the real-time clock, which provides
75  * hardclock interrupts to kern_clock.c.
76  *
77  * Inittodr initializes the time of day hardware which provides
78  * date functions.  Its primary function is to use some file
79  * system information in case the hardare clock lost state.
80  *
81  * Resettodr restores the time of day hardware after a time change.
82  */
83 
84 /*
85  * We assume newhz is either stathz or profhz, and that neither will
86  * change after being set up above.  Could recalculate intervals here
87  * but that would be a drag.
88  */
89 void
90 setstatclockrate(newhz)
91 	int newhz;
92 {
93 
94 	/* KU:XXX do something! */
95 }
96 
97 /*
98  * Set up the real-time and statistics clocks.  Leave stathz 0 only if
99  * no alternative timer is available.
100  */
101 void
102 cpu_initclocks()
103 {
104 	(*clockfns->cf_init)(clockdev);
105 }
106 
107 /*
108  * Initialze the time of day register, based on the time base which is, e.g.
109  * from a filesystem.  Base provides the time to within six months,
110  * and the time of year clock (if any) provides the rest.
111  */
112 void
113 inittodr(base)
114 	time_t base;
115 {
116 	int deltat, badbase = 0;
117 	struct clock_ymdhms dt;
118 
119 	if (base < 5*SECYR) {
120 		printf("WARNING: preposterous time in file system\n");
121 		/* read the system clock anyway */
122 		base = 6*SECYR + 186*SECDAY + SECDAY/2;
123 		badbase = 1;
124 	}
125 
126 	(*clockfns->cf_get)(clockdev, &dt);
127 	clockinitted = 1;
128 
129 	/* simple sanity checks */
130 	if (dt.dt_mon < 1 || dt.dt_mon > 12 ||
131 	    dt.dt_day < 1 || dt.dt_day > 31 ||
132 	    dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59) {
133 		printf("WARNING: preposterous clock chip time\n");
134 		/*
135 		 * Believe the time in the file system for lack of
136 		 * anything better, resetting the TODR.
137 		 */
138 		time.tv_sec = base;
139 		if (!badbase)
140 			resettodr();
141 		return;
142 	}
143 
144 	time.tv_sec = clock_ymdhms_to_secs(&dt);
145 
146 	if (!badbase) {
147 		/*
148 		 * See if we gained/lost two or more days;
149 		 * if so, assume something is amiss.
150 		 */
151 		deltat = time.tv_sec - base;
152 		if (deltat < 0)
153 			deltat = -deltat;
154 		if (deltat < 2 * SECDAY)
155 			return;
156 		printf("WARNING: clock %s %d days",
157 		    time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
158 	}
159 	printf(" -- CHECK AND RESET THE DATE!\n");
160 }
161 
162 /*
163  * Reset the TODR based on the time value; used when the TODR
164  * has a preposterous value and also when the time is reset
165  * by the stime system call.  Also called when the TODR goes past
166  * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
167  * to wrap the TODR around.
168  */
169 void
170 resettodr()
171 {
172 	struct clock_ymdhms dt;
173 
174 	if (! clockinitted)
175 		return;
176 
177 	clock_secs_to_ymdhms(time.tv_sec, &dt);
178 	(*clockfns->cf_set)(clockdev, &dt);
179 }
180