FreeBSD/Linux Kernel Cross Reference
sys/sqt/clock.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991 Carnegie Mellon University
4 * Copyright (c) 1991 Sequent Computer Systems
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation.
12 *
13 * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
14 * THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON AND
15 * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29 /*
30 * HISTORY
31 * $Log: clock.c,v $
32 * Revision 2.3 91/07/31 18:00:21 dbg
33 * Changed copyright.
34 * [91/07/31 dbg]
35 *
36 * Revision 2.2 91/05/08 12:55:04 dbg
37 * Adapted from Sequent Symmetry sources.
38 * [91/04/26 14:50:24 dbg]
39 *
40 */
41
42 #ifndef lint
43 static char rcsid[] = "$Header: clock.c,v 2.3 91/07/31 18:00:21 dbg Exp $";
44 #endif
45
46 /*
47 * Machine-dependent clock routines.
48 *
49 * Included are the time-of-day clock initialization and
50 * the per processor real-time clock initialization.
51 */
52
53 /*
54 * Revision 1.2 89/07/20 18:05:38 kak
55 * moved balance includes
56 *
57 * Revision 1.1 89/07/05 13:15:27 kak
58 * Initial revision
59 *
60 */
61
62 #include <mach/boolean.h>
63
64 #include <kern/time_out.h>
65
66 #include <sys/time.h>
67
68 #include <sqt/cfg.h>
69 #include <sqt/clock.h>
70 #include <sqt/slic.h>
71
72 #include <sqt/ioconf.h>
73 #include <sqt/vm_defs.h>
74 #include <sqt/hwparam.h>
75 #include <sqt/intctl.h>
76
77 #include <sqtsec/sec.h>
78
79 extern u_char cons_scsi; /* console scsi slic address */
80
81 /* For time-of-day handling */
82 struct sec_cib *todcib;
83 struct sec_gmode todgm; /* getmodes command */
84 struct sec_smode todsm; /* setmodes command */
85
86 /*
87 * startrtclock()
88 * Start the real-time clock.
89 *
90 * Startrtclock restarts the real-time clock, which provides
91 * hardclock interrupts to kern_clock.c. On Sequent HW, this
92 * is one-time only per processor (eg, no restart, clock reprimes
93 * itself).
94 *
95 * Called by localinit() during selfinit().
96 * This turns on the processor-local SLIC timer.
97 *
98 * For testing/performance measurement convenience, enable_local_clock
99 * allows the per-processor clock to be left OFF. Need to patch the
100 * kernel binary or system memory to effect this.
101 */
102
103 static boolean_t enable_local_clock = TRUE; /* default ON */
104
105 startrtclock()
106 {
107 register struct cpuslic *sl = va_slic;
108
109 if (!enable_local_clock)
110 return;
111
112 sl->sl_trv = ((sys_clock_rate * 1000000) / (SL_TIMERDIV * hz)) - 1;
113 /* clear prescaler, load reload value */
114 sl->sl_tcont = 0;
115 sl->sl_tctl = SL_TIMERINT | LCLKBIN; /* timer on in given bin */
116 }
117
118 /*
119 * Routines to manipulate the SCED based time-of-day register.
120 * TOD clock interrupt handling done by todclock in kern_clock.c
121 *
122 *
123 * Inittodr initializes the time-of-day hardware which provides
124 * date functions. This starts the time-of-day clock.
125 *
126 */
127 void
128 inittodr()
129 {
130 time_value_t new_time;
131
132 register u_int todr;
133 register struct sec_gmode *todgmptr = &todgm;
134 register int i;
135 long deltat;
136 spl_t s_ipl;
137
138 new_time.seconds = 0;
139 new_time.microseconds = 0;
140
141 if (todcib == 0) {
142 printf("todcib null - inittodr returning!\n");
143 return;
144 }
145
146 /*
147 * Find console SCED and check if the TOD clock has
148 * failed powerup diagnostics.
149 */
150 for (i = 0; i < NSEC; i++) {
151 /* is SEC there? */
152 if ((SECvec & (1 << i)) == 0)
153 continue;
154
155 if (SEC_desc[i].sec_is_cons)
156 break;
157 }
158 if (SEC_desc[i].sec_diag_flags & CFG_S_TOD) {
159 /*
160 * Clear todr if TOD failed powerup diagnostics.
161 */
162 printf("WARNING: TOD failed powerup diagnostics\n");
163 todr = 0;
164 } else {
165 /*
166 * get the current time-of-day from the SCED tod clock.
167 */
168 todgmptr->gm_status = 0;
169 todcib->cib_inst = SINST_GETMODE;
170 todcib->cib_status = KVTOPHYS(&todgm, int *);
171 s_ipl = splhi();
172 mIntr(cons_scsi, TODCLKBIN, SDEV_TOD);
173 splx(s_ipl);
174
175 while ((todgmptr->gm_status & SINST_INSDONE) == 0)
176 continue;
177
178 if (todgmptr->gm_status != SINST_INSDONE)
179 panic("Cannot get TOD value");
180
181 todr = todgmptr->gm_un.gm_tod.tod_newtime;
182 }
183
184 if (todr < 13*SECYR) {
185 printf("WARNING: TOD value bad -- ");
186 printf("Setting TOD to default time\n");
187 todr = 13*SECYR + 19*SECDAY + (2*SECDAY)/3;
188 }
189
190 new_time.seconds = todr;
191 new_time.microseconds = 0;
192
193 /*
194 * Set the time.
195 */
196 {
197 int s = splhigh();
198 time = new_time;
199 splx(s);
200 }
201
202 resettodr(); /* restart the clock */
203 }
204
205 /*
206 * Resettodr restores the time-of-day hardware after a time change.
207 * Also, also called via inittodr to start todclock interrupts.
208 *
209 * Reset the TOD based on the time value; used when the TOD
210 * has a preposterous value and also when the time is reset
211 * by the stime system call.
212 */
213 resettodr()
214 {
215 register struct sec_smode *todsmptr = &todsm;
216 spl_t s_ipl;
217
218 todsmptr->sm_status = 0;
219 todsmptr->sm_un.sm_tod.tod_freq = TODFREQ;
220 todcib->cib_inst = SINST_SETMODE;
221 todcib->cib_status = KVTOPHYS(&todsm, int *);
222 s_ipl = splhi();
223 todsmptr->sm_un.sm_tod.tod_newtime = time.tv_sec;
224 /*
225 * Bin 3 is sufficient, helps avoid SLIC-bus lockup.
226 */
227 mIntr(cons_scsi, 3, SDEV_TOD);
228 splx(s_ipl);
229
230 while ((todsmptr->sm_status & SINST_INSDONE) == 0)
231 continue;
232
233 if (todsmptr->sm_status != SINST_INSDONE)
234 panic("Cannot set TOD value");
235 }
Cache object: 6ce68f55b9ed1f618fd65db57e831bfb
|