fix auto-quoting screwup
[unix-history] / usr / src / sys / news3400 / news3400 / clock.c
CommitLineData
af5295ff
KM
1/*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1992 The Regents of the University of California.
4 * All rights reserved.
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 *
11 * %sccs.include.redist.c%
12 *
13 * from: Utah $Hdr: clock.c 1.18 91/01/21$
14 *
679d1338 15 * @(#)clock.c 7.4 (Berkeley) %G%
af5295ff
KM
16 */
17
18#include "../include/fix_machine_type.h"
19#include "../include/adrsmap.h"
20
21#include "param.h"
22#include "kernel.h"
23
24#include "clockreg.h"
25
26/*
27 * Machine-dependent clock routines.
28 *
29 * Startrtclock restarts the real-time clock, which provides
30 * hardclock interrupts to kern_clock.c.
31 *
32 * Inittodr initializes the time of day hardware which provides
33 * date functions. Its primary function is to use some file
34 * system information in case the hardare clock lost state.
35 *
36 * Resettodr restores the time of day hardware after a time change.
37 */
38
6d429c8e
KB
39/*
40 * We assume newhz is either stathz or profhz, and that neither will
41 * change after being set up above. Could recalculate intervals here
42 * but that would be a drag.
43 */
44void
45setstatclockrate(newhz)
46 int newhz;
47{
48
49 /* KU:XXX do something! */
50}
51
af5295ff
KM
52/*
53 * Start the real-time clock.
54 */
6d429c8e 55static void
af5295ff
KM
56startrtclock()
57{
58
59 *(char *)ITIMER = IOCLOCK / 6144 / 100 - 1;
60}
61
62/*
63 * Enable the real-time clock.
64 */
6d429c8e 65static void
af5295ff
KM
66enablertclock()
67{
68
69 *(char *)INTEN0 |= (char)INTEN0_TIMINT;
70}
71
679d1338
KU
72/*
73 * Set up the real-time and statistics clocks. Leave stathz 0 only if
74 * no alternative timer is available.
75 *
76 */
77cpu_initclocks()
78{
79
80 startrtclock();
81 enablertclock();
82}
83
af5295ff
KM
84/*
85 * This code is defunct after 2099.
86 * Will Unix still be here then??
87 */
88static short dayyr[12] = {
89 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
90};
91
f8bea1d3 92#define bcd_to_int(BCD) (i = BCD, (((i) >> 4) & 0xf) * 10 + ((i) & 0xf))
af5295ff
KM
93#define int_to_bcd(INT) (i = INT, ((((i) / 10) % 10) << 4) + (i) % 10)
94
95/*
96 * Initialze the time of day register, based on the time base which is, e.g.
97 * from a filesystem. Base provides the time to within six months,
98 * and the time of year clock (if any) provides the rest.
99 */
100inittodr(base)
101 time_t base;
102{
103 register volatile u_char *rtc_port = (u_char *)RTC_PORT;
104 register volatile u_char *rtc_data = (u_char *)DATA_PORT;
105 register int days, yr;
106 int sec, min, hour, week, day, mon, year;
107 long deltat, badbase = 0;
f8bea1d3 108 register u_int i;
af5295ff
KM
109
110 if (base < 5*SECYR) {
111 printf("WARNING: preposterous time in file system\n");
112 /* read the system clock anyway */
113 base = 6*SECYR + 186*SECDAY + SECDAY/2;
114 badbase = 1;
115 }
116
117 *rtc_port = READ_CLOCK;
118 sec = bcd_to_int(*rtc_data++);
119 min = bcd_to_int(*rtc_data++);
120 hour = bcd_to_int(*rtc_data++);
121 week = bcd_to_int(*rtc_data++);
122 day = bcd_to_int(*rtc_data++);
123 mon = bcd_to_int(*rtc_data++);
124 year = bcd_to_int(*rtc_data++);
125 *rtc_port = 0;
126
127 /* simple sanity checks */
128 if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31 ||
129 hour > 23 || min > 59 || sec > 59) {
f8bea1d3 130 printf("WARNING: preposterous clock chip time\n");
af5295ff
KM
131 /*
132 * Believe the time in the file system for lack of
133 * anything better, resetting the TODR.
134 */
135 time.tv_sec = base;
136 if (!badbase)
137 resettodr();
138 return (0);
139 }
140 days = 0;
141 for (yr = 70; yr < year; yr++)
142 days += LEAPYEAR(yr) ? 366 : 365;
143 days += dayyr[mon - 1] + day - 1;
144 if (LEAPYEAR(yr) && mon > 2)
145 days++;
146 /* now have days since Jan 1, 1970; the rest is easy... */
147 time.tv_sec = days * SECDAY + hour * 3600 + min * 60 + sec;
148
149 if (!badbase) {
150 /*
151 * See if we gained/lost two or more days;
152 * if so, assume something is amiss.
153 */
154 deltat = time.tv_sec - base;
155 if (deltat < 0)
156 deltat = -deltat;
157 if (deltat < 2 * SECDAY)
158 return;
159 printf("WARNING: clock %s %d days",
160 time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
161 }
162 printf(" -- CHECK AND RESET THE DATE!\n");
163}
164
165/*
166 * Reset the TODR based on the time value; used when the TODR
167 * has a preposterous value and also when the time is reset
168 * by the stime system call. Also called when the TODR goes past
169 * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
170 * to wrap the TODR around.
171 */
172resettodr()
173{
174 register volatile u_char *rtc_port = (u_char *)RTC_PORT;
175 register volatile u_char *rtc_data = (u_char *)DATA_PORT;
176 int sec, min, hour, week, day, mon, year;
177 register int t, t2, t3;
178 register int i;
179
180 /* compute the year */
181 t2 = time.tv_sec / SECDAY;
182 t = 69;
183 while (t2 >= 0) { /* whittle off years */
184 t3 = t2;
185 t++;
186 t2 -= LEAPYEAR(t) ? 366 : 365;
187 }
188
189 year = t;
190
191 /* t3 = month + day; separate */
192 t = LEAPYEAR(t);
193 for (t2 = 1; t2 < 12; t2++)
194 if (t3 < dayyr[t2] + (t && t2 > 1))
195 break;
196
197 /* t2 is month */
198 mon = t2;
199 t3 = t3 - dayyr[t2 - 1] + 1;
200 if (t && t2 > 2)
201 t3--;
202 day = t3;
203
204 week = 0;
205
206 /* the rest is easy */
207 t = time.tv_sec % SECDAY;
208 hour = t / 3600;
209 t %= 3600;
210 min = t / 60;
211 sec = t % 60;
212
213 *rtc_port = SET_CLOCK;
214 *rtc_data++ = int_to_bcd(sec);
215 *rtc_data++ = int_to_bcd(min);
216 *rtc_data++ = int_to_bcd(hour);
217 *rtc_data++ = int_to_bcd(week);
218 *rtc_data++ = int_to_bcd(day);
219 *rtc_data++ = int_to_bcd(mon);
220 *rtc_data = int_to_bcd(year);
221 *rtc_port = 0;
222}