xref: /netbsd/sys/arch/sparc64/sparc64/clock.c (revision c4a72b64)
1 /*	$NetBSD: clock.c,v 1.53 2002/10/02 16:02:21 thorpej Exp $ */
2 
3 /*
4  * Copyright (c) 1992, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  * Copyright (c) 1994 Gordon W. Ross
7  * Copyright (c) 1993 Adam Glass
8  * Copyright (c) 1996 Paul Kranenburg
9  * Copyright (c) 1996
10  * 	The President and Fellows of Harvard College. All rights reserved.
11  *
12  * This software was developed by the Computer Systems Engineering group
13  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
14  * contributed to Berkeley.
15  *
16  * All advertising materials mentioning features or use of this software
17  * must display the following acknowledgement:
18  *	This product includes software developed by Harvard University.
19  *	This product includes software developed by the University of
20  *	California, Lawrence Berkeley Laboratory.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  *
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *	This product includes software developed by the University of
34  *	California, Berkeley and its contributors.
35  *	This product includes software developed by Paul Kranenburg.
36  *	This product includes software developed by Harvard University.
37  * 4. Neither the name of the University nor the names of its contributors
38  *    may be used to endorse or promote products derived from this software
39  *    without specific prior written permission.
40  *
41  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  *	@(#)clock.c	8.1 (Berkeley) 6/11/93
54  *
55  */
56 
57 /*
58  * Clock driver.  This is the id prom and eeprom driver as well
59  * and includes the timer register functions too.
60  */
61 
62 /* Define this for a 1/4s clock to ease debugging */
63 /* #define INTR_DEBUG */
64 
65 #include <sys/param.h>
66 #include <sys/kernel.h>
67 #include <sys/device.h>
68 #include <sys/proc.h>
69 #include <sys/resourcevar.h>
70 #include <sys/malloc.h>
71 #include <sys/systm.h>
72 #ifdef GPROF
73 #include <sys/gmon.h>
74 #endif
75 
76 #include <uvm/uvm_extern.h>
77 
78 #include <machine/bus.h>
79 #include <machine/autoconf.h>
80 #include <machine/eeprom.h>
81 #include <machine/cpu.h>
82 #include <machine/idprom.h>
83 
84 #include <dev/clock_subr.h>
85 #include <dev/ic/mk48txxreg.h>
86 #include <dev/ic/mc146818reg.h>
87 
88 #include <sparc64/sparc64/intreg.h>
89 #include <sparc64/sparc64/timerreg.h>
90 #include <sparc64/dev/iommureg.h>
91 #include <sparc64/dev/sbusreg.h>
92 #include <dev/sbus/sbusvar.h>
93 #include <dev/ebus/ebusreg.h>
94 #include <dev/ebus/ebusvar.h>
95 
96 extern u_int64_t cpu_clockrate;
97 
98 struct rtc_info {
99 	bus_space_tag_t	rtc_bt;		/* bus tag & handle */
100 	bus_space_handle_t rtc_bh;	/* */
101 	u_int		rtc_year0;	/* What year is represented on the system
102 					   by the chip's year counter at 0 */
103 };
104 
105 /*
106  * Statistics clock interval and variance, in usec.  Variance must be a
107  * power of two.  Since this gives us an even number, not an odd number,
108  * we discard one case and compensate.  That is, a variance of 1024 would
109  * give us offsets in [0..1023].  Instead, we take offsets in [1..1023].
110  * This is symmetric about the point 512, or statvar/2, and thus averages
111  * to that value (assuming uniform random numbers).
112  */
113 /* XXX fix comment to match value */
114 int statvar = 8192;
115 int statmin;			/* statclock interval - 1/2*variance */
116 int timerok;
117 
118 static long tick_increment;
119 int schedintr __P((void *));
120 
121 static struct intrhand level10 = { clockintr };
122 static struct intrhand level0 = { tickintr };
123 static struct intrhand level14 = { statintr };
124 static struct intrhand schedint = { schedintr };
125 
126 /*
127  * clock (eeprom) attaches at the sbus or the ebus (PCI)
128  */
129 static int	clockmatch_sbus __P((struct device *, struct cfdata *, void *));
130 static void	clockattach_sbus __P((struct device *, struct device *, void *));
131 static int	clockmatch_ebus __P((struct device *, struct cfdata *, void *));
132 static void	clockattach_ebus __P((struct device *, struct device *, void *));
133 static int	clockmatch_rtc __P((struct device *, struct cfdata *, void *));
134 static void	clockattach_rtc __P((struct device *, struct device *, void *));
135 static void	clockattach __P((int, bus_space_tag_t, bus_space_handle_t));
136 
137 
138 CFATTACH_DECL(clock_sbus, sizeof(struct device),
139     clockmatch_sbus, clockattach_sbus, NULL, NULL);
140 
141 CFATTACH_DECL(clock_ebus, sizeof(struct device),
142     clockmatch_ebus, clockattach_ebus, NULL, NULL);
143 
144 CFATTACH_DECL(rtc_ebus, sizeof(struct device),
145     clockmatch_rtc, clockattach_rtc, NULL, NULL);
146 
147 extern struct cfdriver clock_cd;
148 
149 /* Global TOD clock handle & idprom pointer */
150 static todr_chip_handle_t todr_handle = NULL;
151 static struct idprom *idprom;
152 
153 static int	timermatch __P((struct device *, struct cfdata *, void *));
154 static void	timerattach __P((struct device *, struct device *, void *));
155 
156 struct timerreg_4u	timerreg_4u;	/* XXX - need more cleanup */
157 
158 CFATTACH_DECL(timer, sizeof(struct device),
159     timermatch, timerattach, NULL, NULL);
160 
161 int clock_wenable __P((struct todr_chip_handle *, int));
162 struct chiptime;
163 void myetheraddr __P((u_char *));
164 int chiptotime __P((int, int, int, int, int, int));
165 void timetochip __P((struct chiptime *));
166 void stopcounter __P((struct timer_4u *));
167 
168 int timerblurb = 10; /* Guess a value; used before clock is attached */
169 
170 u_int8_t rtc_read_reg(bus_space_tag_t, bus_space_handle_t, int);
171 void rtc_write_reg(bus_space_tag_t, bus_space_handle_t, int, u_int8_t);
172 int rtc_gettime(todr_chip_handle_t, struct timeval *);
173 int rtc_settime(todr_chip_handle_t, struct timeval *);
174 int rtc_getcal(todr_chip_handle_t, int *);
175 int rtc_setcal(todr_chip_handle_t, int);
176 
177 int rtc_auto_century_adjust = 1;
178 
179 /*
180  * The OPENPROM calls the clock the "eeprom", so we have to have our
181  * own special match function to call it the "clock".
182  */
183 static int
184 clockmatch_sbus(parent, cf, aux)
185 	struct device *parent;
186 	struct cfdata *cf;
187 	void *aux;
188 {
189 	struct sbus_attach_args *sa = aux;
190 
191 	return (strcmp("eeprom", sa->sa_name) == 0);
192 }
193 
194 static int
195 clockmatch_ebus(parent, cf, aux)
196 	struct device *parent;
197 	struct cfdata *cf;
198 	void *aux;
199 {
200 	struct ebus_attach_args *ea = aux;
201 
202 	return (strcmp("eeprom", ea->ea_name) == 0);
203 }
204 
205 static int
206 clockmatch_rtc(parent, cf, aux)
207 	struct device *parent;
208 	struct cfdata *cf;
209 	void *aux;
210 {
211 	struct ebus_attach_args *ea = aux;
212 
213 	return (strcmp("rtc", ea->ea_name) == 0);
214 }
215 
216 /*
217  * Attach a clock (really `eeprom') to the sbus or ebus.
218  *
219  * We ignore any existing virtual address as we need to map
220  * this read-only and make it read-write only temporarily,
221  * whenever we read or write the clock chip.  The clock also
222  * contains the ID ``PROM'', and I have already had the pleasure
223  * of reloading the cpu type, Ethernet address, etc, by hand from
224  * the console FORTH interpreter.  I intend not to enjoy it again.
225  *
226  * the MK48T02 is 2K.  the MK48T08 is 8K, and the MK48T59 is
227  * supposed to be identical to it.
228  *
229  * This is *UGLY*!  We probably have multiple mappings.  But I do
230  * know that this all fits inside an 8K page, so I'll just map in
231  * once.
232  *
233  * What we really need is some way to record the bus attach args
234  * so we can call *_bus_map() later with BUS_SPACE_MAP_READONLY
235  * or not to write enable/disable the device registers.  This is
236  * a non-trivial operation.
237  */
238 
239 /* Somewhere to keep info that clock_wenable() needs */
240 static struct clock_info {
241 	bus_space_tag_t		ci_bt;
242 	bus_space_handle_t	ci_bh;
243 } ci;
244 
245 /* ARGSUSED */
246 static void
247 clockattach_sbus(parent, self, aux)
248 	struct device *parent, *self;
249 	void *aux;
250 {
251 	struct sbus_attach_args *sa = aux;
252 	bus_space_tag_t bt = sa->sa_bustag;
253 	int sz;
254 
255 	/* use sa->sa_regs[0].size? */
256 	sz = 8192;
257 
258 	if (sbus_bus_map(bt,
259 			 sa->sa_slot,
260 			 (sa->sa_offset & ~NBPG),
261 			 sz,
262 			 BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_READONLY,
263 			 &ci.ci_bh) != 0) {
264 		printf("%s: can't map register\n", self->dv_xname);
265 		return;
266 	}
267 	clockattach(sa->sa_node, bt, ci.ci_bh);
268 
269 	/* Save info for the clock wenable call. */
270 	ci.ci_bt = bt;
271 	todr_handle->bus_cookie = &ci;
272 	todr_handle->todr_setwen = clock_wenable;
273 }
274 
275 /*
276  * Write en/dis-able clock registers.  We coordinate so that several
277  * writers can run simultaneously.
278  */
279 int
280 clock_wenable(handle, onoff)
281 	struct todr_chip_handle *handle;
282 	int onoff;
283 {
284 	register int s, err = 0;
285 	register int prot;/* nonzero => change prot */
286 	static int writers;
287 
288 	s = splhigh();
289 	if (onoff)
290 		prot = writers++ == 0 ?
291 			VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED : 0;
292 	else
293 		prot = --writers == 0 ?
294 			VM_PROT_READ|PMAP_WIRED : 0;
295 	splx(s);
296 	if (prot) {
297 		struct clock_info *ci =
298 			(struct clock_info *)handle->bus_cookie;
299 		vaddr_t vaddr =
300 			(vaddr_t)bus_space_vaddr(ci->ci_bt, ci->ci_bh);
301 
302 		if (vaddr)
303 			pmap_protect(pmap_kernel(), vaddr, vaddr+NBPG, prot);
304 		else
305 			printf("clock_wenable: WARNING -- cannot get va\n");
306 	}
307 	return (err);
308 }
309 
310 
311 /* ARGSUSED */
312 static void
313 clockattach_ebus(parent, self, aux)
314 	struct device *parent, *self;
315 	void *aux;
316 {
317 	struct ebus_attach_args *ea = aux;
318 	bus_space_tag_t bt = ea->ea_bustag;
319 	int sz;
320 
321 	/* hard code to 8K? */
322 	sz = ea->ea_reg[0].size;
323 
324 	if (bus_space_map(bt,
325 			 EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
326 			 sz,
327 			 BUS_SPACE_MAP_LINEAR,
328 			 &ci.ci_bh) != 0) {
329 		printf("%s: can't map register\n", self->dv_xname);
330 		return;
331 	}
332 	clockattach(ea->ea_node, bt, ci.ci_bh);
333 
334 	/* Save info for the clock wenable call. */
335 	ci.ci_bt = bt;
336 	todr_handle->bus_cookie = &ci;
337 	todr_handle->todr_setwen = clock_wenable;
338 }
339 
340 
341 static void
342 clockattach(node, bt, bh)
343 	int node;
344 	bus_space_tag_t bt;
345 	bus_space_handle_t bh;
346 {
347 	char *model;
348 	struct idprom *idp;
349 	int h;
350 
351 	model = PROM_getpropstring(node, "model");
352 
353 #ifdef DIAGNOSTIC
354 	if (model == NULL)
355 		panic("clockattach: no model property");
356 #endif
357 
358 	/* Our TOD clock year 0 is 1968 */
359 	todr_handle = mk48txx_attach(bt, bh, model, 1968, NULL, NULL);
360 	if (todr_handle == NULL)
361 		panic("Can't attach %s tod clock", model);
362 
363 #define IDPROM_OFFSET (8*1024 - 40)	/* XXX - get nvram sz from driver */
364 	idp = (struct idprom *)((vaddr_t)bus_space_vaddr(bt, bh) +
365 		IDPROM_OFFSET);
366 
367 	h = idp->id_machine << 24;
368 	h |= idp->id_hostid[0] << 16;
369 	h |= idp->id_hostid[1] << 8;
370 	h |= idp->id_hostid[2];
371 	hostid = h;
372 	printf(": hostid %x\n", (u_int)hostid);
373 
374 	idprom = idp;
375 }
376 
377 /*
378  * `rtc' is a ds1287 on an ebus (actually an isa bus, but we use the
379  * ebus driver for isa.)  So we can use ebus_wenable() but need to do
380  * different attach work and use different todr routines.  It does not
381  * incorporate an IDPROM.
382  */
383 
384 /*
385  * XXX the stupid ds1287 is not mapped directly but uses an address
386  * and a data reg so we cannot access the stuuupid thing w/o having
387  * write access to the registers.
388  *
389  * XXXX We really need to mutex register access!
390  */
391 #define	RTC_ADDR	0
392 #define	RTC_DATA	1
393 u_int8_t
394 rtc_read_reg(bus_space_tag_t bt, bus_space_handle_t bh, int reg)
395 {
396 	bus_space_write_1(bt, bh, RTC_ADDR, reg);
397 	return (bus_space_read_1(bt, bh, RTC_DATA));
398 }
399 void
400 rtc_write_reg(bus_space_tag_t bt, bus_space_handle_t bh, int reg, u_int8_t val)
401 {
402 	bus_space_write_1(bt, bh, RTC_ADDR, reg);
403 	bus_space_write_1(bt, bh, RTC_DATA, val);
404 }
405 
406 /* ARGSUSED */
407 static void
408 clockattach_rtc(parent, self, aux)
409 	struct device *parent, *self;
410 	void *aux;
411 {
412 	struct ebus_attach_args *ea = aux;
413 	bus_space_tag_t bt = ea->ea_bustag;
414 	todr_chip_handle_t handle;
415 	struct rtc_info *rtc;
416 	char *model;
417 	int sz;
418 	static struct clock_info ci;
419 
420 	/* hard code to 8K? */
421 	sz = ea->ea_reg[0].size;
422 
423 	if (bus_space_map(bt,
424 			 EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
425 			 sz,
426 			 BUS_SPACE_MAP_LINEAR,
427 			 &ci.ci_bh) != 0) {
428 		printf("%s: can't map register\n", self->dv_xname);
429 		return;
430 	}
431 
432 	model = PROM_getpropstring(ea->ea_node, "model");
433 #ifdef DIAGNOSTIC
434 	if (model == NULL)
435 		panic("clockattach_rtc: no model property");
436 #endif
437 	printf(": %s\n", model);
438 
439 	/*
440 	 * Turn interrupts off, just in case. (Although they shouldn't
441 	 * be wired to an interrupt controller on sparcs).
442 	 */
443 	rtc_write_reg(bt, ci.ci_bh,
444 		MC_REGB, MC_REGB_BINARY | MC_REGB_24HR);
445 
446 	/* Setup our todr_handle */
447 	sz = ALIGN(sizeof(struct todr_chip_handle)) + sizeof(struct rtc_info);
448 	handle = malloc(sz, M_DEVBUF, M_NOWAIT);
449 	rtc = (struct rtc_info*)((u_long)handle +
450 				 ALIGN(sizeof(struct todr_chip_handle)));
451 	handle->cookie = rtc;
452 	handle->todr_gettime = rtc_gettime;
453 	handle->todr_settime = rtc_settime;
454 	handle->todr_getcal = rtc_getcal;
455 	handle->todr_setcal = rtc_setcal;
456 	/*
457 	 * Apparently on some machines the TOD registers are on the same
458 	 * physical page as the COM registers.  So we won't protect them.
459 	 */
460 	handle->todr_setwen = NULL;
461 	rtc->rtc_bt = bt;
462 	rtc->rtc_bh = ci.ci_bh;
463 	/* Our TOD clock year 0 is 0 */
464 	rtc->rtc_year0 = 0;
465 	todr_handle = handle;
466 }
467 
468 /*
469  * The sun4u OPENPROMs call the timer the "counter-timer", except for
470  * the lame UltraSPARC IIi PCI machines that don't have them.
471  */
472 static int
473 timermatch(parent, cf, aux)
474 	struct device *parent;
475 	struct cfdata *cf;
476 	void *aux;
477 {
478 	struct mainbus_attach_args *ma = aux;
479 
480 	return (strcmp("counter-timer", ma->ma_name) == 0);
481 }
482 
483 static void
484 timerattach(parent, self, aux)
485 	struct device *parent, *self;
486 	void *aux;
487 {
488 	struct mainbus_attach_args *ma = aux;
489 	u_int *va = ma->ma_address;
490 #if 0
491 	volatile int64_t *cnt = NULL, *lim = NULL;
492 #endif
493 
494 	/*
495 	 * What we should have are 3 sets of registers that reside on
496 	 * different parts of SYSIO or PSYCHO.  We'll use the prom
497 	 * mappings cause we can't get rid of them and set up appropriate
498 	 * pointers on the timerreg_4u structure.
499 	 */
500 	timerreg_4u.t_timer = (struct timer_4u *)(u_long)va[0];
501 	timerreg_4u.t_clrintr = (int64_t *)(u_long)va[1];
502 	timerreg_4u.t_mapintr = (int64_t *)(u_long)va[2];
503 
504 	/* Install the appropriate interrupt vector here */
505 	level10.ih_number = ma->ma_interrupts[0];
506 	level10.ih_clr = (void*)&timerreg_4u.t_clrintr[0];
507 	intr_establish(10, &level10);
508 	level14.ih_number = ma->ma_interrupts[1];
509 	level14.ih_clr = (void*)&timerreg_4u.t_clrintr[1];
510 
511 	intr_establish(14, &level14);
512 	printf(" irq vectors %lx and %lx",
513 	       (u_long)level10.ih_number,
514 	       (u_long)level14.ih_number);
515 
516 #if 0
517 	cnt = &(timerreg_4u.t_timer[0].t_count);
518 	lim = &(timerreg_4u.t_timer[0].t_limit);
519 
520 	/*
521 	 * Calibrate delay() by tweaking the magic constant
522 	 * until a delay(100) actually reads (at least) 100 us
523 	 * on the clock.  Since we're using the %tick register
524 	 * which should be running at exactly the CPU clock rate, it
525 	 * has a period of somewhere between 7ns and 3ns.
526 	 */
527 
528 #ifdef DEBUG
529 	printf("Delay calibrarion....\n");
530 #endif
531 	for (timerblurb = 1; timerblurb > 0; timerblurb++) {
532 		volatile int discard;
533 		register int t0, t1;
534 
535 		/* Reset counter register by writing some large limit value */
536 		discard = *lim;
537 		*lim = tmr_ustolim(TMR_MASK-1);
538 
539 		t0 = *cnt;
540 		delay(100);
541 		t1 = *cnt;
542 
543 		if (t1 & TMR_LIMIT)
544 			panic("delay calibration");
545 
546 		t0 = (t0 >> TMR_SHIFT) & TMR_MASK;
547 		t1 = (t1 >> TMR_SHIFT) & TMR_MASK;
548 
549 		if (t1 >= t0 + 100)
550 			break;
551 	}
552 
553 	printf(" delay constant %d\n", timerblurb);
554 #endif
555 	printf("\n");
556 	timerok = 1;
557 }
558 
559 void
560 stopcounter(creg)
561 	struct timer_4u *creg;
562 {
563 	/* Stop the clock */
564 	volatile int discard;
565 	discard = creg->t_limit;
566 	creg->t_limit = 0;
567 }
568 
569 /*
570  * XXX this belongs elsewhere
571  */
572 void
573 myetheraddr(cp)
574 	u_char *cp;
575 {
576 	struct idprom *idp;
577 
578 	if (((idp = idprom) == NULL) ||
579 		(((idp->id_ether[0] | idp->id_ether[1] | idp->id_ether[2] |
580 			idp->id_ether[3] | idp->id_ether[4] |
581 			idp->id_ether[5]) == 0))) {
582 		int node, n;
583 
584 		node = findroot();
585 		if (PROM_getprop(node, "idprom", sizeof *idp, &n, (void **)&idp) ||
586 		    n != 1) {
587 			printf("\nmyetheraddr: clock not setup yet, "
588 			       "and no idprom property in /\n");
589 			return;
590 		}
591 	}
592 
593 	cp[0] = idp->id_ether[0];
594 	cp[1] = idp->id_ether[1];
595 	cp[2] = idp->id_ether[2];
596 	cp[3] = idp->id_ether[3];
597 	cp[4] = idp->id_ether[4];
598 	cp[5] = idp->id_ether[5];
599 	if (idprom == NULL)
600 		free(idp, M_DEVBUF);
601 }
602 
603 /*
604  * Set up the real-time and statistics clocks.  Leave stathz 0 only if
605  * no alternative timer is available.
606  *
607  * The frequencies of these clocks must be an even number of microseconds.
608  */
609 void
610 cpu_initclocks()
611 {
612 	int statint, minint;
613 	static u_int64_t start_time;
614 #ifdef DEBUG
615 	extern int intrdebug;
616 #endif
617 
618 #ifdef DEBUG
619 	/* Set a 1s clock */
620 	if (intrdebug) {
621 		hz = 1;
622 		tick = 1000000 / hz;
623 		printf("intrdebug set: 1Hz clock\n");
624 	}
625 #endif
626 
627 	if (1000000 % hz) {
628 		printf("cannot get %d Hz clock; using 100 Hz\n", hz);
629 		hz = 100;
630 		tick = 1000000 / hz;
631 	}
632 
633 	/* Make sure we have a sane cpu_clockrate -- we'll need it */
634 	if (!cpu_clockrate)
635 		/* Default to 200MHz clock XXXXX */
636 		cpu_clockrate = 200000000;
637 
638 	/*
639 	 * Calculate the starting %tick value.  We set that to the same
640 	 * as time, scaled for the CPU clockrate.  This gets nasty, but
641 	 * we can handle it.  time.tv_usec is in microseconds.
642 	 * cpu_clockrate is in MHz.
643 	 */
644 	start_time = time.tv_sec * cpu_clockrate;
645 	/* Now fine tune the usecs */
646 	start_time += cpu_clockrate / 1000000 * time.tv_usec;
647 
648 	/* Initialize the %tick register */
649 #ifdef __arch64__
650 	__asm __volatile("wrpr %0, 0, %%tick" : : "r" (start_time));
651 #else
652 	{
653 		int start_hi = (start_time>>32), start_lo = start_time;
654 		__asm __volatile("sllx %1,32,%0; or %0,%2,%0; wrpr %0, 0, %%tick"
655 				 : "=&r" (start_hi) /* scratch register */
656 				 : "r" ((int)(start_hi)), "r" ((int)(start_lo)));
657 	}
658 #endif
659 
660 
661 	/*
662 	 * Now handle machines w/o counter-timers.
663 	 */
664 
665 	if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) {
666 
667 		printf("No counter-timer -- using %%tick at %ldMHz as system clock.\n",
668 			(long)(cpu_clockrate/1000000));
669 		/* We don't have a counter-timer -- use %tick */
670 		level0.ih_clr = 0;
671 		/*
672 		 * Establish a level 10 interrupt handler
673 		 *
674 		 * We will have a conflict with the softint handler,
675 		 * so we set the ih_number to 1.
676 		 */
677 		level0.ih_number = 1;
678 		intr_establish(10, &level0);
679 		/* We only have one timer so we have no statclock */
680 		stathz = 0;
681 
682 		/* set the next interrupt time */
683 		tick_increment = cpu_clockrate / hz;
684 #ifdef DEBUG
685 		printf("Using %%tick -- intr in %ld cycles...", tick_increment);
686 #endif
687 		next_tick(tick_increment);
688 #ifdef DEBUG
689 		printf("done.\n");
690 #endif
691 		return;
692 	}
693 
694 	if (stathz == 0)
695 		stathz = hz;
696 	if (1000000 % stathz) {
697 		printf("cannot get %d Hz statclock; using 100 Hz\n", stathz);
698 		stathz = 100;
699 	}
700 
701 	profhz = stathz;		/* always */
702 
703 	statint = 1000000 / stathz;
704 	minint = statint / 2 + 100;
705 	while (statvar > minint)
706 		statvar >>= 1;
707 
708 	/*
709 	 * Establish scheduler softint.
710 	 */
711 	schedint.ih_pil = PIL_SCHED;
712 	schedint.ih_clr = NULL;
713 	schedint.ih_arg = 0;
714 	schedint.ih_pending = 0;
715 	schedhz = stathz/4;
716 
717 	/*
718 	 * Enable timers
719 	 *
720 	 * Also need to map the interrupts cause we're not a child of the sbus.
721 	 * N.B. By default timer[0] is disabled and timer[1] is enabled.
722 	 */
723 	stxa((vaddr_t)&timerreg_4u.t_timer[0].t_limit, ASI_NUCLEUS,
724 	     tmr_ustolim(tick)|TMR_LIM_IEN|TMR_LIM_PERIODIC|TMR_LIM_RELOAD);
725 	stxa((vaddr_t)&timerreg_4u.t_mapintr[0], ASI_NUCLEUS,
726 	     timerreg_4u.t_mapintr[0]|INTMAP_V);
727 
728 #ifdef DEBUG
729 	if (intrdebug)
730 		/* Neglect to enable timer */
731 		stxa((vaddr_t)&timerreg_4u.t_timer[1].t_limit, ASI_NUCLEUS,
732 		     tmr_ustolim(statint)|TMR_LIM_RELOAD);
733 	else
734 #endif
735 		stxa((vaddr_t)&timerreg_4u.t_timer[1].t_limit, ASI_NUCLEUS,
736 		     tmr_ustolim(statint)|TMR_LIM_IEN|TMR_LIM_RELOAD);
737 	stxa((vaddr_t)&timerreg_4u.t_mapintr[1], ASI_NUCLEUS,
738 	     timerreg_4u.t_mapintr[1]|INTMAP_V);
739 
740 	statmin = statint - (statvar >> 1);
741 
742 }
743 
744 /*
745  * Dummy setstatclockrate(), since we know profhz==hz.
746  */
747 /* ARGSUSED */
748 void
749 setstatclockrate(newhz)
750 	int newhz;
751 {
752 	/* nothing */
753 }
754 
755 /*
756  * Level 10 (clock) interrupts.  If we are using the FORTH PROM for
757  * console input, we need to check for that here as well, and generate
758  * a software interrupt to read it.
759  */
760 #ifdef	DEBUG
761 static int clockcheck = 0;
762 #endif
763 int
764 clockintr(cap)
765 	void *cap;
766 {
767 #ifdef DEBUG
768 	static int64_t tick_base = 0;
769 	int64_t t = (u_int64_t)tick();
770 
771 	if (!tick_base) {
772 		tick_base = (time.tv_sec * 1000000LL + time.tv_usec)
773 			* 1000000LL / cpu_clockrate;
774 		tick_base -= t;
775 	} else if (clockcheck) {
776 		int64_t tk = t;
777 		int64_t clk = (time.tv_sec * 1000000LL + time.tv_usec);
778 		t -= tick_base;
779 		t = t * 1000000LL / cpu_clockrate;
780 		if (t - clk > hz) {
781 			printf("Clock lost an interrupt!\n");
782 			printf("Actual: %llx Expected: %llx tick %llx tick_base %llx\n",
783 			       (long long)t, (long long)clk, (long long)tk, (long long)tick_base);
784 			Debugger();
785 			tick_base = 0;
786 		}
787 	}
788 #endif
789 	/* Let locore.s clear the interrupt for us. */
790 	hardclock((struct clockframe *)cap);
791 	return (1);
792 }
793 
794 int poll_console = 0;
795 
796 /*
797  * Level 10 (clock) interrupts.  If we are using the FORTH PROM for
798  * console input, we need to check for that here as well, and generate
799  * a software interrupt to read it.
800  *
801  * %tick is really a level-14 interrupt.  We need to remap this in
802  * locore.s to a level 10.
803  */
804 int
805 tickintr(cap)
806 	void *cap;
807 {
808 	int s;
809 
810 #if	NKBD	> 0
811 	extern int cnrom __P((void));
812 	extern int rom_console_input;
813 #endif
814 
815 	hardclock((struct clockframe *)cap);
816 	if (poll_console)
817 		setsoftint();
818 
819 	s = splhigh();
820 	/* Reset the interrupt */
821 	next_tick(tick_increment);
822 	splx(s);
823 
824 	return (1);
825 }
826 
827 /*
828  * Level 14 (stat clock) interrupt handler.
829  */
830 int
831 statintr(cap)
832 	void *cap;
833 {
834 	register u_long newint, r, var;
835 	struct cpu_info *ci = curcpu();
836 
837 #ifdef NOT_DEBUG
838 	printf("statclock: count %x:%x, limit %x:%x\n",
839 	       timerreg_4u.t_timer[1].t_count, timerreg_4u.t_timer[1].t_limit);
840 #endif
841 #ifdef NOT_DEBUG
842 	prom_printf("!");
843 #endif
844 	statclock((struct clockframe *)cap);
845 #ifdef NOTDEF_DEBUG
846 	/* Don't re-schedule the IRQ */
847 	return 1;
848 #endif
849 	/*
850 	 * Compute new randomized interval.  The intervals are uniformly
851 	 * distributed on [statint - statvar / 2, statint + statvar / 2],
852 	 * and therefore have mean statint, giving a stathz frequency clock.
853 	 */
854 	var = statvar;
855 	do {
856 		r = random() & (var - 1);
857 	} while (r == 0);
858 	newint = statmin + r;
859 
860 	if (schedhz)
861 		if ((++ci->ci_schedstate.spc_schedticks & 3) == 0)
862 			send_softint(-1, PIL_SCHED, &schedint);
863 	stxa((vaddr_t)&timerreg_4u.t_timer[1].t_limit, ASI_NUCLEUS,
864 	     tmr_ustolim(newint)|TMR_LIM_IEN|TMR_LIM_RELOAD);
865 	return (1);
866 }
867 
868 int
869 schedintr(arg)
870 	void *arg;
871 {
872 	if (curproc)
873 		schedclock(curproc);
874 	return (1);
875 }
876 
877 
878 /*
879  * `sparc_clock_time_is_ok' is used in cpu_reboot() to determine
880  * whether it is appropriate to call resettodr() to consolidate
881  * pending time adjustments.
882  */
883 int sparc_clock_time_is_ok;
884 
885 /*
886  * Set up the system's time, given a `reasonable' time value.
887  */
888 void
889 inittodr(base)
890 	time_t base;
891 {
892 	int badbase = 0, waszero = base == 0;
893 
894 	if (base < 5 * SECYR) {
895 		/*
896 		 * If base is 0, assume filesystem time is just unknown
897 		 * in stead of preposterous. Don't bark.
898 		 */
899 		if (base != 0)
900 			printf("WARNING: preposterous time in file system\n");
901 		/* not going to use it anyway, if the chip is readable */
902 		base = 21*SECYR + 186*SECDAY + SECDAY/2;
903 		badbase = 1;
904 	}
905 
906 	if (todr_handle &&
907 		(todr_gettime(todr_handle, (struct timeval *)&time) != 0 ||
908 		time.tv_sec == 0)) {
909 		printf("WARNING: bad date in battery clock");
910 		/*
911 		 * Believe the time in the file system for lack of
912 		 * anything better, resetting the clock.
913 		 */
914 		time.tv_sec = base;
915 		if (!badbase)
916 			resettodr();
917 	} else {
918 		int deltat = time.tv_sec - base;
919 
920 		sparc_clock_time_is_ok = 1;
921 
922 		if (deltat < 0)
923 			deltat = -deltat;
924 		if (waszero || deltat < 2 * SECDAY)
925 			return;
926 		printf("WARNING: clock %s %d days",
927 		    time.tv_sec < base ? "lost" : "gained", deltat / SECDAY);
928 	}
929 	printf(" -- CHECK AND RESET THE DATE!\n");
930 }
931 
932 /*
933  * Reset the clock based on the current time.
934  * Used when the current clock is preposterous, when the time is changed,
935  * and when rebooting.  Do nothing if the time is not yet known, e.g.,
936  * when crashing during autoconfig.
937  */
938 void
939 resettodr()
940 {
941 
942 	if (time.tv_sec == 0)
943 		return;
944 
945 	sparc_clock_time_is_ok = 1;
946 	if (todr_handle == 0 ||
947 		todr_settime(todr_handle, (struct timeval *)&time) != 0)
948 		printf("Cannot set time in time-of-day clock\n");
949 }
950 
951 /*
952  * XXX: these may actually belong somewhere else, but since the
953  * EEPROM is so closely tied to the clock on some models, perhaps
954  * it needs to stay here...
955  */
956 int
957 eeprom_uio(uio)
958 	struct uio *uio;
959 {
960 	return (ENODEV);
961 }
962 
963 
964 /*
965  * RTC todr routines.
966  */
967 
968 /* Loooks like Sun stores the century info somewhere in CMOS RAM */
969 #define MC_CENT 0x32
970 
971 /*
972  * Get time-of-day and convert to a `struct timeval'
973  * Return 0 on success; an error number otherwise.
974  */
975 int
976 rtc_gettime(handle, tv)
977 	todr_chip_handle_t handle;
978 	struct timeval *tv;
979 {
980 	struct rtc_info *rtc = handle->cookie;
981 	bus_space_tag_t bt = rtc->rtc_bt;
982 	bus_space_handle_t bh = rtc->rtc_bh;
983 	struct clock_ymdhms dt;
984 	int year, cent;
985 	u_int8_t csr;
986 
987 	todr_wenable(handle, 1);
988 
989 	/* Stop updates. */
990 	csr = rtc_read_reg(bt, bh, MC_REGB);
991 	csr |= MC_REGB_SET;
992 	rtc_write_reg(bt, bh, MC_REGB, csr);
993 
994 	/* Read time */
995 	dt.dt_sec = rtc_read_reg(bt, bh, MC_SEC);
996 	dt.dt_min = rtc_read_reg(bt, bh, MC_MIN);
997 	dt.dt_hour = rtc_read_reg(bt, bh, MC_HOUR);
998 	dt.dt_day = rtc_read_reg(bt, bh, MC_DOM);
999 	dt.dt_wday = rtc_read_reg(bt, bh, MC_DOW);
1000 	dt.dt_mon = rtc_read_reg(bt, bh, MC_MONTH);
1001 	year = rtc_read_reg(bt, bh, MC_YEAR);
1002 	cent = rtc_read_reg(bt, bh, MC_CENT);
1003 printf("rtc_gettime: read c %x/%d y %x/%d m %x/%d wd %d d %x/%d "
1004 	"h %x/%d m %x/%d s %x/%d\n",
1005 	cent, cent, year, year, dt.dt_mon, dt.dt_mon, dt.dt_wday,
1006 	dt.dt_day, dt.dt_day, dt.dt_hour, dt.dt_hour,
1007 	dt.dt_min, dt.dt_min, dt.dt_sec, dt.dt_sec);
1008 
1009 	year += cent * 100;
1010 	dt.dt_year = year;
1011 
1012 	/* time wears on */
1013 	csr = rtc_read_reg(bt, bh, MC_REGB);
1014 	csr &= ~MC_REGB_SET;
1015 	rtc_write_reg(bt, bh, MC_REGB, csr);
1016 	todr_wenable(handle, 0);
1017 
1018 	/* simple sanity checks */
1019 	if (dt.dt_year < 1970 || dt.dt_mon > 12 || dt.dt_day > 31 ||
1020 	    dt.dt_hour >= 24 || dt.dt_min >= 60 || dt.dt_sec >= 60)
1021 		return (1);
1022 
1023 	tv->tv_sec = clock_ymdhms_to_secs(&dt);
1024 	tv->tv_usec = 0;
1025 	return (0);
1026 }
1027 
1028 /*
1029  * Set the time-of-day clock based on the value of the `struct timeval' arg.
1030  * Return 0 on success; an error number otherwise.
1031  */
1032 int
1033 rtc_settime(handle, tv)
1034 	todr_chip_handle_t handle;
1035 	struct timeval *tv;
1036 {
1037 	struct rtc_info *rtc = handle->cookie;
1038 	bus_space_tag_t bt = rtc->rtc_bt;
1039 	bus_space_handle_t bh = rtc->rtc_bh;
1040 	struct clock_ymdhms dt;
1041 	u_int8_t csr;
1042 	int year, cent;
1043 
1044 	/* Note: we ignore `tv_usec' */
1045 	clock_secs_to_ymdhms(tv->tv_sec, &dt);
1046 
1047 	year = dt.dt_year % 100;
1048 	cent = dt.dt_year / 100;
1049 
1050 	todr_wenable(handle, 1);
1051 	/* enable write */
1052 	csr = rtc_read_reg(bt, bh, MC_REGB);
1053 	csr |= MC_REGB_SET;
1054 	rtc_write_reg(bt, bh, MC_REGB, csr);
1055 
1056 	rtc_write_reg(bt, bh, MC_SEC, dt.dt_sec);
1057 	rtc_write_reg(bt, bh, MC_MIN, dt.dt_min);
1058 	rtc_write_reg(bt, bh, MC_HOUR, dt.dt_hour);
1059 	rtc_write_reg(bt, bh, MC_DOW, dt.dt_wday);
1060 	rtc_write_reg(bt, bh, MC_DOM, dt.dt_day);
1061 	rtc_write_reg(bt, bh, MC_MONTH, dt.dt_mon);
1062 	rtc_write_reg(bt, bh, MC_YEAR, year);
1063 	rtc_write_reg(bt, bh, MC_CENT, cent);
1064 
1065 	/* load them up */
1066 	csr = rtc_read_reg(bt, bh, MC_REGB);
1067 	csr &= ~MC_REGB_SET;
1068 	rtc_write_reg(bt, bh, MC_REGB, csr);
1069 	todr_wenable(handle, 0);
1070 	return (0);
1071 }
1072 
1073 int
1074 rtc_getcal(handle, vp)
1075 	todr_chip_handle_t handle;
1076 	int *vp;
1077 {
1078 	return (EOPNOTSUPP);
1079 }
1080 
1081 int
1082 rtc_setcal(handle, v)
1083 	todr_chip_handle_t handle;
1084 	int v;
1085 {
1086 	return (EOPNOTSUPP);
1087 }
1088 
1089