BSD 4_4 release
[unix-history] / usr / src / sys / news3400 / news3400 / clock.c
CommitLineData
af5295ff
KM
1/*
2 * Copyright (c) 1988 University of Utah.
ad787160
C
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
af5295ff
KM
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department, Ralph Campbell, and Kazumasa Utashiro of
9 * Software Research Associates, Inc.
10 *
ad787160
C
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
af5295ff
KM
38 *
39 * from: Utah $Hdr: clock.c 1.18 91/01/21$
40 *
ad787160 41 * @(#)clock.c 8.1 (Berkeley) 6/11/93
af5295ff
KM
42 */
43
f5e2c85d 44#include <machine/adrsmap.h>
af5295ff 45
f5e2c85d
KU
46#include <sys/param.h>
47#include <sys/kernel.h>
af5295ff 48
f5e2c85d 49#include <news3400/news3400/clockreg.h>
af5295ff
KM
50
51/*
52 * Machine-dependent clock routines.
53 *
54 * Startrtclock restarts the real-time clock, which provides
55 * hardclock interrupts to kern_clock.c.
56 *
57 * Inittodr initializes the time of day hardware which provides
58 * date functions. Its primary function is to use some file
59 * system information in case the hardare clock lost state.
60 *
61 * Resettodr restores the time of day hardware after a time change.
62 */
63
6d429c8e
KB
64/*
65 * We assume newhz is either stathz or profhz, and that neither will
66 * change after being set up above. Could recalculate intervals here
67 * but that would be a drag.
68 */
69void
70setstatclockrate(newhz)
71 int newhz;
72{
73
74 /* KU:XXX do something! */
75}
76
679d1338
KU
77/*
78 * Set up the real-time and statistics clocks. Leave stathz 0 only if
79 * no alternative timer is available.
679d1338
KU
80 */
81cpu_initclocks()
82{
83
92daa486
KU
84 /*
85 * Start the real-time clock.
86 */
87 *(char *)ITIMER = IOCLOCK / 6144 / 100 - 1;
88
89 /*
90 * Enable the real-time clock.
91 */
92 *(char *)INTEN0 |= (char)INTEN0_TIMINT;
679d1338
KU
93}
94
af5295ff
KM
95/*
96 * This code is defunct after 2099.
97 * Will Unix still be here then??
98 */
99static short dayyr[12] = {
100 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
101};
102
f8bea1d3 103#define bcd_to_int(BCD) (i = BCD, (((i) >> 4) & 0xf) * 10 + ((i) & 0xf))
af5295ff
KM
104#define int_to_bcd(INT) (i = INT, ((((i) / 10) % 10) << 4) + (i) % 10)
105
106/*
107 * Initialze the time of day register, based on the time base which is, e.g.
108 * from a filesystem. Base provides the time to within six months,
109 * and the time of year clock (if any) provides the rest.
110 */
111inittodr(base)
112 time_t base;
113{
114 register volatile u_char *rtc_port = (u_char *)RTC_PORT;
115 register volatile u_char *rtc_data = (u_char *)DATA_PORT;
116 register int days, yr;
117 int sec, min, hour, week, day, mon, year;
118 long deltat, badbase = 0;
f8bea1d3 119 register u_int i;
af5295ff
KM
120
121 if (base < 5*SECYR) {
122 printf("WARNING: preposterous time in file system\n");
123 /* read the system clock anyway */
124 base = 6*SECYR + 186*SECDAY + SECDAY/2;
125 badbase = 1;
126 }
127
128 *rtc_port = READ_CLOCK;
129 sec = bcd_to_int(*rtc_data++);
130 min = bcd_to_int(*rtc_data++);
131 hour = bcd_to_int(*rtc_data++);
132 week = bcd_to_int(*rtc_data++);
133 day = bcd_to_int(*rtc_data++);
134 mon = bcd_to_int(*rtc_data++);
135 year = bcd_to_int(*rtc_data++);
136 *rtc_port = 0;
137
138 /* simple sanity checks */
139 if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31 ||
140 hour > 23 || min > 59 || sec > 59) {
f8bea1d3 141 printf("WARNING: preposterous clock chip time\n");
af5295ff
KM
142 /*
143 * Believe the time in the file system for lack of
144 * anything better, resetting the TODR.
145 */
146 time.tv_sec = base;
147 if (!badbase)
148 resettodr();
149 return (0);
150 }
151 days = 0;
152 for (yr = 70; yr < year; yr++)
153 days += LEAPYEAR(yr) ? 366 : 365;
154 days += dayyr[mon - 1] + day - 1;
155 if (LEAPYEAR(yr) && mon > 2)
156 days++;
157 /* now have days since Jan 1, 1970; the rest is easy... */
158 time.tv_sec = days * SECDAY + hour * 3600 + min * 60 + sec;
159
160 if (!badbase) {
161 /*
162 * See if we gained/lost two or more days;
163 * if so, assume something is amiss.
164 */
165 deltat = time.tv_sec - base;
166 if (deltat < 0)
167 deltat = -deltat;
168 if (deltat < 2 * SECDAY)
169 return;
170 printf("WARNING: clock %s %d days",
171 time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
172 }
173 printf(" -- CHECK AND RESET THE DATE!\n");
174}
175
176/*
177 * Reset the TODR based on the time value; used when the TODR
178 * has a preposterous value and also when the time is reset
179 * by the stime system call. Also called when the TODR goes past
180 * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
181 * to wrap the TODR around.
182 */
183resettodr()
184{
185 register volatile u_char *rtc_port = (u_char *)RTC_PORT;
186 register volatile u_char *rtc_data = (u_char *)DATA_PORT;
187 int sec, min, hour, week, day, mon, year;
188 register int t, t2, t3;
189 register int i;
190
191 /* compute the year */
192 t2 = time.tv_sec / SECDAY;
193 t = 69;
194 while (t2 >= 0) { /* whittle off years */
195 t3 = t2;
196 t++;
197 t2 -= LEAPYEAR(t) ? 366 : 365;
198 }
199
200 year = t;
201
202 /* t3 = month + day; separate */
203 t = LEAPYEAR(t);
204 for (t2 = 1; t2 < 12; t2++)
205 if (t3 < dayyr[t2] + (t && t2 > 1))
206 break;
207
208 /* t2 is month */
209 mon = t2;
210 t3 = t3 - dayyr[t2 - 1] + 1;
211 if (t && t2 > 2)
212 t3--;
213 day = t3;
214
215 week = 0;
216
217 /* the rest is easy */
218 t = time.tv_sec % SECDAY;
219 hour = t / 3600;
220 t %= 3600;
221 min = t / 60;
222 sec = t % 60;
223
224 *rtc_port = SET_CLOCK;
225 *rtc_data++ = int_to_bcd(sec);
226 *rtc_data++ = int_to_bcd(min);
227 *rtc_data++ = int_to_bcd(hour);
228 *rtc_data++ = int_to_bcd(week);
229 *rtc_data++ = int_to_bcd(day);
230 *rtc_data++ = int_to_bcd(mon);
231 *rtc_data = int_to_bcd(year);
232 *rtc_port = 0;
233}