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