1 /* $NetBSD: timer.c,v 1.19 2004/02/13 11:36:18 wiz 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 * Kernel clocks provided by "timer" device. The hardclock is provided by 58 * the timer register (aka system counter). The statclock is provided by 59 * per CPU counter register(s) (aka processor counter(s)). 60 */ 61 62 #include <sys/cdefs.h> 63 __KERNEL_RCSID(0, "$NetBSD: timer.c,v 1.19 2004/02/13 11:36:18 wiz Exp $"); 64 65 #include <sys/param.h> 66 #include <sys/kernel.h> 67 #include <sys/device.h> 68 #include <sys/systm.h> 69 70 #include <machine/autoconf.h> 71 #include <machine/bus.h> 72 73 #include <sparc/sparc/timerreg.h> 74 #include <sparc/sparc/timervar.h> 75 76 static struct intrhand level10; 77 static struct intrhand level14; 78 79 80 /* 81 * sun4/sun4c/sun4m common timer attach code 82 */ 83 void 84 timerattach(cntreg, limreg) 85 volatile int *cntreg, *limreg; 86 { 87 88 /* 89 * Calibrate delay() by tweaking the magic constant 90 * until a delay(100) actually reads (at least) 100 us on the clock. 91 * Note: sun4m clocks tick with 500ns periods. 92 */ 93 for (timerblurb = 1; ; timerblurb++) { 94 volatile int discard; 95 int t0, t1; 96 97 /* Reset counter register by writing some large limit value */ 98 discard = *limreg; 99 *limreg = tmr_ustolim(TMR_MASK-1); 100 101 t0 = *cntreg; 102 delay(100); 103 t1 = *cntreg; 104 105 if (t1 & TMR_LIMIT) 106 panic("delay calibration"); 107 108 t0 = (t0 >> TMR_SHIFT) & TMR_MASK; 109 t1 = (t1 >> TMR_SHIFT) & TMR_MASK; 110 111 if (t1 >= t0 + 100) 112 break; 113 } 114 115 printf(": delay constant %d\n", timerblurb); 116 117 #if defined(SUN4) || defined(SUN4C) 118 if (CPU_ISSUN4 || CPU_ISSUN4C) { 119 timer_init = timer_init_4; 120 level10.ih_fun = clockintr_4; 121 level14.ih_fun = statintr_4; 122 } 123 #endif 124 #if defined(SUN4M) 125 if (CPU_ISSUN4M) { 126 timer_init = timer_init_4m; 127 level10.ih_fun = clockintr_4m; 128 level14.ih_fun = statintr_4m; 129 } 130 #endif 131 /* link interrupt handlers */ 132 intr_establish(10, 0, &level10, NULL); 133 intr_establish(14, 0, &level14, NULL); 134 135 /* Establish a soft interrupt at a lower level for schedclock */ 136 sched_cookie = softintr_establish(IPL_SCHED, schedintr, NULL); 137 if (sched_cookie == NULL) 138 panic("timerattach: cannot establish schedintr"); 139 } 140 141 /* 142 * Both sun4 and sun4m can attach a timer on obio. 143 * The sun4m OPENPROM calls the timer the "counter". 144 * The sun4 timer must be probed. 145 */ 146 static int 147 timermatch_obio(struct device *parent, struct cfdata *cf, void *aux) 148 { 149 #if defined(SUN4) || defined(SUN4M) 150 union obio_attach_args *uoba = aux; 151 #endif 152 #if defined(SUN4) 153 struct obio4_attach_args *oba; 154 #endif 155 156 #if defined(SUN4M) 157 if (uoba->uoba_isobio4 == 0) 158 return (strcmp("counter", uoba->uoba_sbus.sa_name) == 0); 159 #endif /* SUN4M */ 160 161 if (CPU_ISSUN4 == 0) { 162 printf("timermatch_obio: attach args mixed up\n"); 163 return (0); 164 } 165 166 #if defined(SUN4) 167 /* Only these sun4s have "timer" (others have "oclock") */ 168 if (cpuinfo.cpu_type != CPUTYP_4_300 && 169 cpuinfo.cpu_type != CPUTYP_4_400) 170 return (0); 171 172 /* Make sure there is something there */ 173 oba = &uoba->uoba_oba4; 174 return (bus_space_probe(oba->oba_bustag, oba->oba_paddr, 175 4, /* probe size */ 176 0, /* offset */ 177 0, /* flags */ 178 NULL, NULL)); 179 #endif /* SUN4 */ 180 panic("timermatch_obio: impossible"); 181 } 182 183 static void 184 timerattach_obio(struct device *parent, struct device *self, void *aux) 185 { 186 union obio_attach_args *uoba = aux; 187 188 if (uoba->uoba_isobio4 == 0) { 189 #if defined(SUN4M) 190 /* sun4m timer at obio */ 191 timerattach_obio_4m(parent, self, aux); 192 #endif /* SUN4M */ 193 return; 194 } 195 196 if (uoba->uoba_isobio4 != 0) { 197 #if defined(SUN4) 198 /* sun4 timer at obio */ 199 timerattach_obio_4(parent, self, aux); 200 #endif /* SUN4 */ 201 } 202 } 203 204 CFATTACH_DECL(timer_obio, sizeof(struct device), 205 timermatch_obio, timerattach_obio, NULL, NULL); 206 207 /* 208 * Only sun4c attaches a timer at mainbus 209 */ 210 static int 211 timermatch_mainbus(struct device *parent, struct cfdata *cf, void *aux) 212 { 213 #if defined(SUN4C) 214 struct mainbus_attach_args *ma = aux; 215 216 return (strcmp("counter-timer", ma->ma_name) == 0); 217 #else 218 return (0); 219 #endif 220 } 221 222 static void 223 timerattach_mainbus(struct device *parent, struct device *self, void *aux) 224 { 225 #if defined(SUN4C) 226 timerattach_mainbus_4c(parent, self, aux); 227 #endif /* SUN4C */ 228 } 229 230 CFATTACH_DECL(timer_mainbus, sizeof(struct device), 231 timermatch_mainbus, timerattach_mainbus, NULL, NULL); 232