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