1 /* $NetBSD: clock.c,v 1.89 2002/05/02 13:01:45 martin 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 * Common timer, clock and eeprom routines. 59 * 60 * Overview of timer and time-of-day devices on sparc machines: 61 * 62 * sun4/100 & sun4/200 63 * have the Intersil 7170 time-of-day and timer chip (oclock.c) 64 * eeprom device in OBIO space (eeprom.c) 65 * 66 * sun4/300 & sun4/400 67 * Mostek MK48T02 clock/nvram device, includes eeprom (mkclock.c) 68 * 2 system timers (timer.c) 69 * 70 * sun4c 71 * Mostek MK48T02 or MK48T08 clock/nvram device (mkclock.c) 72 * system timer in OBIO space 73 * 2 system timers (timer.c) 74 * 75 * sun4m 76 * Mostek MK48T08 clock/nvram device (mkclock.c) 77 * 1 global system timer (timer.c) 78 * 1 configurable counter/timer per CPU (timer.c) 79 * 80 * microSPARC-IIep: 81 * DS1287A time-of-day chip on EBUS (dev/rtc.c) 82 * the system timer is part of the PCI controller (timer.c) 83 * 84 * All system use the timer interrupt (at IPL 10) to drive hardclock(). 85 * The second or per-CPU timer interrupt (at IPL 14) is used to drive 86 * statclock() (except on sun4/100 and sun4/200 machines, which don't 87 * have a spare timer device). 88 */ 89 90 #include "opt_sparc_arch.h" 91 92 #include <sys/param.h> 93 #include <sys/kernel.h> 94 #include <sys/device.h> 95 #include <sys/proc.h> 96 #include <sys/malloc.h> 97 #include <sys/systm.h> 98 99 #include <machine/bus.h> 100 #include <machine/autoconf.h> 101 #include <machine/eeprom.h> 102 #include <machine/cpu.h> 103 #include <machine/idprom.h> 104 105 #include <dev/clock_subr.h> 106 107 /* Variables shared with timer.c, mkclock.c, oclock.c */ 108 int timerblurb = 10; /* Guess a value; used before clock is attached */ 109 int oldclk = 0; 110 111 void (*timer_init)(void); /* Called from cpu_initclocks() */ 112 int (*eeprom_nvram_wenable)(int); 113 114 /* 115 * Statistics clock interval and variance, in usec. Variance must be a 116 * power of two. Since this gives us an even number, not an odd number, 117 * we discard one case and compensate. That is, a variance of 1024 would 118 * give us offsets in [0..1023]. Instead, we take offsets in [1..1023]. 119 * This is symmetric about the point 512, or statvar/2, and thus averages 120 * to that value (assuming uniform random numbers). 121 */ 122 /* XXX fix comment to match value */ 123 int statvar = 8192; 124 int statmin; /* statclock interval - 1/2*variance */ 125 int statint; 126 127 128 /* 129 * Common eeprom I/O routines. 130 */ 131 char *eeprom_va = NULL; 132 #if defined(SUN4) 133 static int eeprom_busy = 0; 134 static int eeprom_wanted = 0; 135 static int eeprom_take(void); 136 static void eeprom_give(void); 137 static int eeprom_update(char *, int, int); 138 #endif 139 140 /* Global TOD clock handle & idprom pointer */ 141 todr_chip_handle_t todr_handle; 142 struct idprom *idprom; 143 144 void establish_hostid(struct idprom *); 145 void myetheraddr(u_char *); 146 147 148 /* 149 * XXX this belongs elsewhere 150 */ 151 void 152 myetheraddr(cp) 153 u_char *cp; 154 { 155 struct idprom *idp = idprom; 156 157 cp[0] = idp->id_ether[0]; 158 cp[1] = idp->id_ether[1]; 159 cp[2] = idp->id_ether[2]; 160 cp[3] = idp->id_ether[3]; 161 cp[4] = idp->id_ether[4]; 162 cp[5] = idp->id_ether[5]; 163 } 164 165 void 166 establish_hostid(idp) 167 struct idprom *idp; 168 { 169 u_long h; 170 171 h = idp->id_machine << 24; 172 h |= idp->id_hostid[0] << 16; 173 h |= idp->id_hostid[1] << 8; 174 h |= idp->id_hostid[2]; 175 176 printf(": hostid %lx\n", h); 177 178 /* Save IDPROM pointer and Host ID in globals */ 179 idprom = idp; 180 hostid = h; 181 } 182 183 184 /* 185 * Set up the real-time and statistics clocks. 186 * Leave stathz 0 only if no alternative timer is available. 187 * 188 * The frequencies of these clocks must be an even number of microseconds. 189 */ 190 void 191 cpu_initclocks() 192 { 193 int minint; 194 195 if (1000000 % hz) { 196 printf("cannot get %d Hz clock; using 100 Hz\n", hz); 197 hz = 100; 198 tick = 1000000 / hz; 199 } 200 if (stathz == 0) 201 stathz = hz; 202 if (1000000 % stathz) { 203 printf("cannot get %d Hz statclock; using 100 Hz\n", stathz); 204 stathz = 100; 205 } 206 profhz = stathz; /* always */ 207 208 statint = 1000000 / stathz; 209 minint = statint / 2 + 100; 210 while (statvar > minint) 211 statvar >>= 1; 212 statmin = statint - (statvar >> 1); 213 214 if (timer_init != NULL) 215 (*timer_init)(); 216 } 217 218 /* 219 * Dummy setstatclockrate(), since we know profhz==hz. 220 */ 221 /* ARGSUSED */ 222 void 223 setstatclockrate(newhz) 224 int newhz; 225 { 226 /* nothing */ 227 } 228 229 230 /* 231 * `sparc_clock_time_is_ok' is used in cpu_reboot() to determine 232 * whether it is appropriate to call resettodr() to consolidate 233 * pending time adjustments. 234 */ 235 int sparc_clock_time_is_ok; 236 237 /* 238 * Set up the system's time, given a `reasonable' time value. 239 */ 240 void 241 inittodr(base) 242 time_t base; 243 { 244 int badbase = 0, waszero = base == 0; 245 246 if (base < 5 * SECYR) { 247 /* 248 * If base is 0, assume filesystem time is just unknown 249 * in stead of preposterous. Don't bark. 250 */ 251 if (base != 0) 252 printf("WARNING: preposterous time in file system\n"); 253 /* not going to use it anyway, if the chip is readable */ 254 base = 21*SECYR + 186*SECDAY + SECDAY/2; 255 badbase = 1; 256 } 257 258 if (todr_gettime(todr_handle, (struct timeval *)&time) != 0 || 259 time.tv_sec == 0) { 260 261 printf("WARNING: bad date in battery clock"); 262 /* 263 * Believe the time in the file system for lack of 264 * anything better, resetting the clock. 265 */ 266 time.tv_sec = base; 267 if (!badbase) 268 resettodr(); 269 } else { 270 int deltat = time.tv_sec - base; 271 272 sparc_clock_time_is_ok = 1; 273 274 if (deltat < 0) 275 deltat = -deltat; 276 if (waszero || deltat < 2 * SECDAY) 277 return; 278 printf("WARNING: clock %s %d days", 279 time.tv_sec < base ? "lost" : "gained", deltat / SECDAY); 280 } 281 printf(" -- CHECK AND RESET THE DATE!\n"); 282 } 283 284 /* 285 * Reset the clock based on the current time. 286 * Used when the current clock is preposterous, when the time is changed, 287 * and when rebooting. Do nothing if the time is not yet known, e.g., 288 * when crashing during autoconfig. 289 */ 290 void 291 resettodr() 292 { 293 294 if (time.tv_sec == 0) 295 return; 296 297 sparc_clock_time_is_ok = 1; 298 if (todr_settime(todr_handle, (struct timeval *)&time) != 0) 299 printf("Cannot set time in time-of-day clock\n"); 300 } 301 302 #if defined(SUN4) 303 /* 304 * Return the best possible estimate of the time in the timeval 305 * to which tvp points. We do this by returning the current time 306 * plus the amount of time since the last clock interrupt. 307 * 308 * Check that this time is no less than any previously-reported time, 309 * which could happen around the time of a clock adjustment. Just for 310 * fun, we guarantee that the time will be greater than the value 311 * obtained by a previous call. 312 */ 313 void 314 microtime(tvp) 315 struct timeval *tvp; 316 { 317 int s; 318 static struct timeval lasttime; 319 static struct timeval oneusec = {0, 1}; 320 321 if (!oldclk) { 322 lo_microtime(tvp); 323 return; 324 } 325 326 s = splhigh(); 327 *tvp = time; 328 splx(s); 329 330 if (timercmp(tvp, &lasttime, <=)) 331 timeradd(&lasttime, &oneusec, tvp); 332 333 lasttime = *tvp; 334 } 335 #endif /* SUN4 */ 336 337 /* 338 * XXX: these may actually belong somewhere else, but since the 339 * EEPROM is so closely tied to the clock on some models, perhaps 340 * it needs to stay here... 341 */ 342 int 343 eeprom_uio(uio) 344 struct uio *uio; 345 { 346 #if defined(SUN4) 347 int error; 348 int off; /* NOT off_t */ 349 u_int cnt, bcnt; 350 caddr_t buf = NULL; 351 352 if (!CPU_ISSUN4) 353 return (ENODEV); 354 355 if (eeprom_va == NULL) { 356 error = ENXIO; 357 goto out; 358 } 359 360 off = uio->uio_offset; 361 if (off > EEPROM_SIZE) 362 return (EFAULT); 363 364 cnt = uio->uio_resid; 365 if (cnt > (EEPROM_SIZE - off)) 366 cnt = (EEPROM_SIZE - off); 367 368 if ((error = eeprom_take()) != 0) 369 return (error); 370 371 /* 372 * The EEPROM can only be accessed one byte at a time, yet 373 * uiomove() will attempt long-word access. To circumvent 374 * this, we byte-by-byte copy the eeprom contents into a 375 * temporary buffer. 376 */ 377 buf = malloc(EEPROM_SIZE, M_DEVBUF, M_WAITOK); 378 if (buf == NULL) { 379 error = EAGAIN; 380 goto out; 381 } 382 383 if (uio->uio_rw == UIO_READ) 384 for (bcnt = 0; bcnt < EEPROM_SIZE; ++bcnt) 385 *(char *)(buf + bcnt) = *(char *)(eeprom_va + bcnt); 386 387 if ((error = uiomove(buf + off, (int)cnt, uio)) != 0) 388 goto out; 389 390 if (uio->uio_rw != UIO_READ) 391 error = eeprom_update(buf, off, cnt); 392 393 out: 394 if (buf) 395 free(buf, M_DEVBUF); 396 eeprom_give(); 397 return (error); 398 #else /* ! SUN4 */ 399 return (ENODEV); 400 #endif /* SUN4 */ 401 } 402 403 #if defined(SUN4) 404 /* 405 * Update the EEPROM from the passed buf. 406 */ 407 static int 408 eeprom_update(buf, off, cnt) 409 char *buf; 410 int off, cnt; 411 { 412 int error = 0; 413 volatile char *ep; 414 char *bp; 415 416 if (eeprom_va == NULL) 417 return (ENXIO); 418 419 ep = eeprom_va + off; 420 bp = buf + off; 421 422 if (eeprom_nvram_wenable != NULL) 423 (*eeprom_nvram_wenable)(1); 424 425 while (cnt > 0) { 426 /* 427 * DO NOT WRITE IT UNLESS WE HAVE TO because the 428 * EEPROM has a limited number of write cycles. 429 * After some number of writes it just fails! 430 */ 431 if (*ep != *bp) { 432 *ep = *bp; 433 /* 434 * We have written the EEPROM, so now we must 435 * sleep for at least 10 milliseconds while 436 * holding the lock to prevent all access to 437 * the EEPROM while it recovers. 438 */ 439 (void)tsleep(eeprom_va, PZERO - 1, "eeprom", hz/50); 440 } 441 /* Make sure the write worked. */ 442 if (*ep != *bp) { 443 error = EIO; 444 goto out; 445 } 446 ++ep; 447 ++bp; 448 --cnt; 449 } 450 out: 451 if (eeprom_nvram_wenable != NULL) 452 (*eeprom_nvram_wenable)(0); 453 454 return (error); 455 } 456 457 /* Take a lock on the eeprom. */ 458 static int 459 eeprom_take() 460 { 461 int error = 0; 462 463 while (eeprom_busy) { 464 eeprom_wanted = 1; 465 error = tsleep(&eeprom_busy, PZERO | PCATCH, "eeprom", 0); 466 eeprom_wanted = 0; 467 if (error) /* interrupted */ 468 goto out; 469 } 470 eeprom_busy = 1; 471 out: 472 return (error); 473 } 474 475 /* Give a lock on the eeprom away. */ 476 static void 477 eeprom_give() 478 { 479 480 eeprom_busy = 0; 481 if (eeprom_wanted) { 482 eeprom_wanted = 0; 483 wakeup(&eeprom_busy); 484 } 485 } 486 #endif /* SUN4 */ 487