tsc.c revision 15345
1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz and Don Ahn. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 37 * $Id: clock.c,v 1.56 1996/04/05 18:56:10 ache Exp $ 38 */ 39 40/* 41 * inittodr, settodr and support routines written 42 * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at> 43 * 44 * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94 45 */ 46 47/* 48 * Primitive clock interrupt routines. 49 */ 50#include "opt_ddb.h" 51 52#include <sys/param.h> 53#include <sys/systm.h> 54#include <sys/time.h> 55#include <sys/kernel.h> 56#include <machine/clock.h> 57#include <machine/frame.h> 58#include <i386/isa/icu.h> 59#include <i386/isa/isa.h> 60#include <i386/isa/isa_device.h> 61#include <i386/isa/rtc.h> 62#include <i386/isa/timerreg.h> 63 64/* 65 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 66 * can use a simple formula for leap years. 67 */ 68#define LEAPYEAR(y) ((u_int)(y) % 4 == 0) 69#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) 70 71/* X-tals being what they are, it's nice to be able to fudge this one... */ 72#ifndef TIMER_FREQ 73#define TIMER_FREQ 1193182 /* XXX - should be in isa.h */ 74#endif 75#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x)) 76 77/* 78 * Time in timer cycles that it takes for microtime() to disable interrupts 79 * and latch the count. microtime() currently uses "cli; outb ..." so it 80 * normally takes less than 2 timer cycles. Add a few for cache misses. 81 * Add a few more to allow for latency in bogus calls to microtime() with 82 * interrupts already disabled. 83 */ 84#define TIMER0_LATCH_COUNT 20 85 86/* 87 * Minimum maximum count that we are willing to program into timer0. 88 * Must be large enough to guarantee that the timer interrupt handler 89 * returns before the next timer interrupt. Must be larger than 90 * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in 91 * the calculation of timer0_overflow_threshold. 92 */ 93#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000) 94 95int adjkerntz; /* local offset from GMT in seconds */ 96int disable_rtc_set; /* disable resettodr() if != 0 */ 97int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 98 99u_int idelayed; 100#if defined(I586_CPU) || defined(I686_CPU) 101unsigned i586_ctr_rate; 102long long i586_ctr_bias; 103long long i586_last_tick; 104unsigned long i586_avg_tick; 105#endif 106int statclock_disable; 107u_int stat_imask = SWI_CLOCK_MASK; 108int timer0_max_count; 109u_int timer0_overflow_threshold; 110u_int timer0_prescaler_count; 111 112static int beeping = 0; 113static u_int clk_imask = HWI_MASK | SWI_MASK; 114static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 115static u_int hardclock_max_count; 116/* 117 * XXX new_function and timer_func should not handle clockframes, but 118 * timer_func currently needs to hold hardclock to handle the 119 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 120 * to switch between clkintr() and a slightly different timerintr(). 121 * This will require locking when acquiring and releasing timer0 - the 122 * current (nonexistent) locking doesn't seem to be adequate even now. 123 */ 124static void (*new_function) __P((struct clockframe *frame)); 125static u_int new_rate; 126static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 127static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 128static char timer0_state = 0; 129static char timer2_state = 0; 130static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 131 132#if 0 133void 134clkintr(struct clockframe frame) 135{ 136 hardclock(&frame); 137 setdelayed(); 138} 139#else 140static void 141clkintr(struct clockframe frame) 142{ 143 timer_func(&frame); 144 switch (timer0_state) { 145 case 0: 146 setdelayed(); 147 break; 148 case 1: 149 if ((timer0_prescaler_count += timer0_max_count) 150 >= hardclock_max_count) { 151 hardclock(&frame); 152 setdelayed(); 153 timer0_prescaler_count -= hardclock_max_count; 154 } 155 break; 156 case 2: 157 setdelayed(); 158 timer0_max_count = TIMER_DIV(new_rate); 159 timer0_overflow_threshold = 160 timer0_max_count - TIMER0_LATCH_COUNT; 161 disable_intr(); 162 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 163 outb(TIMER_CNTR0, timer0_max_count & 0xff); 164 outb(TIMER_CNTR0, timer0_max_count >> 8); 165 enable_intr(); 166 timer0_prescaler_count = 0; 167 timer_func = new_function; 168 timer0_state = 1; 169 break; 170 case 3: 171 if ((timer0_prescaler_count += timer0_max_count) 172 >= hardclock_max_count) { 173 hardclock(&frame); 174 setdelayed(); 175 timer0_max_count = hardclock_max_count; 176 timer0_overflow_threshold = 177 timer0_max_count - TIMER0_LATCH_COUNT; 178 disable_intr(); 179 outb(TIMER_MODE, 180 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 181 outb(TIMER_CNTR0, timer0_max_count & 0xff); 182 outb(TIMER_CNTR0, timer0_max_count >> 8); 183 enable_intr(); 184 /* 185 * See microtime.s for this magic. 186 */ 187 time.tv_usec += (27645 * 188 (timer0_prescaler_count - hardclock_max_count)) 189 >> 15; 190 if (time.tv_usec >= 1000000) 191 time.tv_usec -= 1000000; 192 timer0_prescaler_count = 0; 193 timer_func = hardclock;; 194 timer0_state = 0; 195 } 196 break; 197 } 198} 199#endif 200 201int 202acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 203{ 204 if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT || 205 !function) 206 return -1; 207 new_function = function; 208 new_rate = rate; 209 timer0_state = 2; 210 return 0; 211} 212 213int 214acquire_timer2(int mode) 215{ 216 if (timer2_state) 217 return -1; 218 timer2_state = 1; 219 outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f)); 220 return 0; 221} 222 223int 224release_timer0() 225{ 226 if (!timer0_state) 227 return -1; 228 timer0_state = 3; 229 return 0; 230} 231 232int 233release_timer2() 234{ 235 if (!timer2_state) 236 return -1; 237 timer2_state = 0; 238 outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT); 239 return 0; 240} 241 242/* 243 * This routine receives statistical clock interrupts from the RTC. 244 * As explained above, these occur at 128 interrupts per second. 245 * When profiling, we receive interrupts at a rate of 1024 Hz. 246 * 247 * This does not actually add as much overhead as it sounds, because 248 * when the statistical clock is active, the hardclock driver no longer 249 * needs to keep (inaccurate) statistics on its own. This decouples 250 * statistics gathering from scheduling interrupts. 251 * 252 * The RTC chip requires that we read status register C (RTC_INTR) 253 * to acknowledge an interrupt, before it will generate the next one. 254 */ 255static void 256rtcintr(struct clockframe frame) 257{ 258 u_char stat; 259 stat = rtcin(RTC_INTR); 260 if(stat & RTCIR_PERIOD) { 261 statclock(&frame); 262 } 263} 264 265#ifdef DDB 266static void 267DDB_printrtc(void) 268{ 269 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n", 270 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY), 271 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC), 272 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 273} 274#endif 275 276static int 277getit(void) 278{ 279 int high, low; 280 281 disable_intr(); 282 /* select timer0 and latch counter value */ 283 outb(TIMER_MODE, TIMER_SEL0); 284 low = inb(TIMER_CNTR0); 285 high = inb(TIMER_CNTR0); 286 enable_intr(); 287 return ((high << 8) | low); 288} 289 290#if defined(I586_CPU) || defined(I686_CPU) 291/* 292 * Figure out how fast the cyclecounter runs. This must be run with 293 * clock interrupts disabled, but with the timer/counter programmed 294 * and running. 295 */ 296void 297calibrate_cyclecounter(void) 298{ 299 /* 300 * Don't need volatile; should always use unsigned if 2's 301 * complement arithmetic is desired. 302 */ 303 unsigned long long count; 304 305#define howlong 131072UL 306 __asm __volatile(".byte 0x0f, 0x30" : : "A"(0LL), "c" (0x10)); 307 DELAY(howlong); 308 __asm __volatile(".byte 0xf,0x31" : "=A" (count)); 309 310 i586_ctr_rate = (count << I586_CTR_RATE_SHIFT) / howlong; 311#undef howlong 312} 313#endif 314 315/* 316 * Wait "n" microseconds. 317 * Relies on timer 1 counting down from (TIMER_FREQ / hz) 318 * Note: timer had better have been programmed before this is first used! 319 */ 320void 321DELAY(int n) 322{ 323 int prev_tick, tick, ticks_left, sec, usec; 324 325#ifdef DELAYDEBUG 326 int getit_calls = 1; 327 int n1; 328 static int state = 0; 329 330 if (state == 0) { 331 state = 1; 332 for (n1 = 1; n1 <= 10000000; n1 *= 10) 333 DELAY(n1); 334 state = 2; 335 } 336 if (state == 1) 337 printf("DELAY(%d)...", n); 338#endif 339 /* 340 * Read the counter first, so that the rest of the setup overhead is 341 * counted. Guess the initial overhead is 20 usec (on most systems it 342 * takes about 1.5 usec for each of the i/o's in getit(). The loop 343 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 344 * multiplications and divisions to scale the count take a while). 345 */ 346 prev_tick = getit(); 347 n -= 20; 348 /* 349 * Calculate (n * (TIMER_FREQ / 1e6)) without using floating point 350 * and without any avoidable overflows. 351 */ 352 sec = n / 1000000; 353 usec = n - sec * 1000000; 354 ticks_left = sec * TIMER_FREQ 355 + usec * (TIMER_FREQ / 1000000) 356 + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000 357 + usec * (TIMER_FREQ % 1000) / 1000000; 358 359 while (ticks_left > 0) { 360 tick = getit(); 361#ifdef DELAYDEBUG 362 ++getit_calls; 363#endif 364 if (tick > prev_tick) 365 ticks_left -= prev_tick - (tick - timer0_max_count); 366 else 367 ticks_left -= prev_tick - tick; 368 prev_tick = tick; 369 } 370#ifdef DELAYDEBUG 371 if (state == 1) 372 printf(" %d calls to getit() at %d usec each\n", 373 getit_calls, (n + 5) / getit_calls); 374#endif 375} 376 377static void 378sysbeepstop(void *chan) 379{ 380 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ 381 release_timer2(); 382 beeping = 0; 383} 384 385int 386sysbeep(int pitch, int period) 387{ 388 389 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 390 return -1; 391 disable_intr(); 392 outb(TIMER_CNTR2, pitch); 393 outb(TIMER_CNTR2, (pitch>>8)); 394 enable_intr(); 395 if (!beeping) { 396 outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */ 397 beeping = period; 398 timeout(sysbeepstop, (void *)NULL, period); 399 } 400 return 0; 401} 402 403/* 404 * RTC support routines 405 */ 406 407int 408rtcin(reg) 409 int reg; 410{ 411 u_char val; 412 413 outb(IO_RTC, reg); 414 inb(0x84); 415 val = inb(IO_RTC + 1); 416 inb(0x84); 417 return (val); 418} 419 420static __inline void 421writertc(u_char reg, u_char val) 422{ 423 outb(IO_RTC, reg); 424 outb(IO_RTC + 1, val); 425} 426 427static __inline int 428readrtc(int port) 429{ 430 return(bcd2bin(rtcin(port))); 431} 432 433/* 434 * Initialize 8253 timer 0 early so that it can be used in DELAY(). 435 * XXX initialization of other timers is unintentionally left blank. 436 */ 437void 438startrtclock() 439{ 440 timer0_max_count = hardclock_max_count = TIMER_DIV(hz); 441 timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; 442 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 443 outb(TIMER_CNTR0, timer0_max_count & 0xff); 444 outb(TIMER_CNTR0, timer0_max_count >> 8); 445} 446 447/* 448 * Initialize the time of day register, based on the time base which is, e.g. 449 * from a filesystem. 450 */ 451void 452inittodr(time_t base) 453{ 454 unsigned long sec, days; 455 int yd; 456 int year, month; 457 int y, m, s; 458 459 s = splclock(); 460 time.tv_sec = base; 461 time.tv_usec = 0; 462 splx(s); 463 464 /* Look if we have a RTC present and the time is valid */ 465 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 466 goto wrong_time; 467 468 /* wait for time update to complete */ 469 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 470 while (rtcin(RTC_STATUSA) & RTCSA_TUP); 471 472 days = 0; 473#ifdef USE_RTC_CENTURY 474 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 475#else 476 year = readrtc(RTC_YEAR) + 1900; 477 if (year < 1970) 478 year += 100; 479#endif 480 if (year < 1970) 481 goto wrong_time; 482 month = readrtc(RTC_MONTH); 483 for (m = 1; m < month; m++) 484 days += daysinmonth[m-1]; 485 if ((month > 2) && LEAPYEAR(year)) 486 days ++; 487 days += readrtc(RTC_DAY) - 1; 488 yd = days; 489 for (y = 1970; y < year; y++) 490 days += DAYSPERYEAR + LEAPYEAR(y); 491 sec = ((( days * 24 + 492 readrtc(RTC_HRS)) * 60 + 493 readrtc(RTC_MIN)) * 60 + 494 readrtc(RTC_SEC)); 495 /* sec now contains the number of seconds, since Jan 1 1970, 496 in the local time zone */ 497 498 sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 499 500 s = splclock(); 501 time.tv_sec = sec; 502 splx(s); 503 return; 504 505wrong_time: 506 printf("Invalid time in real time clock.\n"); 507 printf("Check and reset the date immediately!\n"); 508} 509 510/* 511 * Write system time back to RTC 512 */ 513void 514resettodr() 515{ 516 unsigned long tm; 517 int y, m, s; 518 519 if (disable_rtc_set) 520 return; 521 522 s = splclock(); 523 tm = time.tv_sec; 524 splx(s); 525 526 /* Disable RTC updates and interrupts. */ 527 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 528 529 /* Calculate local time to put in RTC */ 530 531 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 532 533 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 534 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 535 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 536 537 /* We have now the days since 01-01-1970 in tm */ 538 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */ 539 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 540 tm >= m; 541 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 542 tm -= m; 543 544 /* Now we have the years in y and the day-of-the-year in tm */ 545 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */ 546#ifdef USE_RTC_CENTURY 547 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */ 548#endif 549 for (m = 0; ; m++) { 550 int ml; 551 552 ml = daysinmonth[m]; 553 if (m == 1 && LEAPYEAR(y)) 554 ml++; 555 if (tm < ml) 556 break; 557 tm -= ml; 558 } 559 560 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */ 561 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */ 562 563 /* Reenable RTC updates and interrupts. */ 564 writertc(RTC_STATUSB, rtc_statusb); 565} 566 567/* 568 * Start both clocks running. 569 */ 570void 571cpu_initclocks() 572{ 573 int diag; 574 575 if (statclock_disable) { 576 /* 577 * The stat interrupt mask is different without the 578 * statistics clock. Also, don't set the interrupt 579 * flag which would normally cause the RTC to generate 580 * interrupts. 581 */ 582 stat_imask = HWI_MASK | SWI_MASK; 583 rtc_statusb = RTCSB_24HR; 584 } else { 585 /* Setting stathz to nonzero early helps avoid races. */ 586 stathz = RTC_NOPROFRATE; 587 profhz = RTC_PROFRATE; 588 } 589 590 /* Finish initializing 8253 timer 0. */ 591 register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, 592 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 593 /* unit */ 0); 594 INTREN(IRQ0); 595#if defined(I586_CPU) || defined(I686_CPU) 596 /* 597 * Finish setting up anti-jitter measures. 598 */ 599 if (i586_ctr_rate) { 600 I586_CYCLECTR(i586_last_tick); 601 i586_ctr_bias = i586_last_tick; 602 } 603#endif 604 605 /* Initialize RTC. */ 606 writertc(RTC_STATUSA, rtc_statusa); 607 writertc(RTC_STATUSB, RTCSB_24HR); 608 609 /* Don't bother enabling the statistics clock. */ 610 if (statclock_disable) 611 return; 612 diag = rtcin(RTC_DIAG); 613 if (diag != 0) 614 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); 615 register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, 616 /* XXX */ (inthand2_t *)rtcintr, &stat_imask, 617 /* unit */ 0); 618 INTREN(IRQ8); 619 writertc(RTC_STATUSB, rtc_statusb); 620} 621 622void 623setstatclockrate(int newhz) 624{ 625 if (newhz == RTC_PROFRATE) 626 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF; 627 else 628 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 629 writertc(RTC_STATUSA, rtc_statusa); 630} 631