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