tsc.c revision 13402
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.45 1996/01/08 18:50:14 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 = 0; /* offset from CMOS clock */ 96int disable_rtc_set = 0; /* disable resettodr() if != 0 */ 97u_int idelayed; 98#if defined(I586_CPU) || defined(I686_CPU) 99unsigned i586_ctr_rate; 100long long i586_ctr_bias; 101long long i586_last_tick; 102#endif 103u_int stat_imask = SWI_CLOCK_MASK; 104int timer0_max_count; 105u_int timer0_overflow_threshold; 106u_int timer0_prescaler_count; 107 108static int beeping = 0; 109static u_int clk_imask = HWI_MASK | SWI_MASK; 110static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 111static u_int hardclock_max_count; 112/* 113 * XXX new_function and timer_func should not handle clockframes, but 114 * timer_func currently needs to hold hardclock to handle the 115 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 116 * to switch between clkintr() and a slightly different timerintr(). 117 * This will require locking when acquiring and releasing timer0 - the 118 * current (nonexistent) locking doesn't seem to be adequate even now. 119 */ 120static void (*new_function) __P((struct clockframe *frame)); 121static u_int new_rate; 122static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 123static char timer0_state = 0; 124static char timer2_state = 0; 125static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 126 127#if 0 128void 129clkintr(struct clockframe frame) 130{ 131 hardclock(&frame); 132 setdelayed(); 133} 134#else 135static void 136clkintr(struct clockframe frame) 137{ 138 timer_func(&frame); 139 switch (timer0_state) { 140 case 0: 141 setdelayed(); 142 break; 143 case 1: 144 if ((timer0_prescaler_count += timer0_max_count) 145 >= hardclock_max_count) { 146 hardclock(&frame); 147 setdelayed(); 148 timer0_prescaler_count -= hardclock_max_count; 149 } 150 break; 151 case 2: 152 setdelayed(); 153 timer0_max_count = TIMER_DIV(new_rate); 154 timer0_overflow_threshold = 155 timer0_max_count - TIMER0_LATCH_COUNT; 156 disable_intr(); 157 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 158 outb(TIMER_CNTR0, timer0_max_count & 0xff); 159 outb(TIMER_CNTR0, timer0_max_count >> 8); 160 enable_intr(); 161 timer0_prescaler_count = 0; 162 timer_func = new_function; 163 timer0_state = 1; 164 break; 165 case 3: 166 if ((timer0_prescaler_count += timer0_max_count) 167 >= hardclock_max_count) { 168 hardclock(&frame); 169 setdelayed(); 170 timer0_max_count = hardclock_max_count; 171 timer0_overflow_threshold = 172 timer0_max_count - TIMER0_LATCH_COUNT; 173 disable_intr(); 174 outb(TIMER_MODE, 175 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 176 outb(TIMER_CNTR0, timer0_max_count & 0xff); 177 outb(TIMER_CNTR0, timer0_max_count >> 8); 178 enable_intr(); 179 /* 180 * See microtime.s for this magic. 181 */ 182 time.tv_usec += (27645 * 183 (timer0_prescaler_count - hardclock_max_count)) 184 >> 15; 185 if (time.tv_usec >= 1000000) 186 time.tv_usec -= 1000000; 187 timer0_prescaler_count = 0; 188 timer_func = hardclock;; 189 timer0_state = 0; 190 } 191 break; 192 } 193} 194#endif 195 196int 197acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 198{ 199 if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT || 200 !function) 201 return -1; 202 new_function = function; 203 new_rate = rate; 204 timer0_state = 2; 205 return 0; 206} 207 208int 209acquire_timer2(int mode) 210{ 211 if (timer2_state) 212 return -1; 213 timer2_state = 1; 214 outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f)); 215 return 0; 216} 217 218int 219release_timer0() 220{ 221 if (!timer0_state) 222 return -1; 223 timer0_state = 3; 224 return 0; 225} 226 227int 228release_timer2() 229{ 230 if (!timer2_state) 231 return -1; 232 timer2_state = 0; 233 outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT); 234 return 0; 235} 236 237/* 238 * This routine receives statistical clock interrupts from the RTC. 239 * As explained above, these occur at 128 interrupts per second. 240 * When profiling, we receive interrupts at a rate of 1024 Hz. 241 * 242 * This does not actually add as much overhead as it sounds, because 243 * when the statistical clock is active, the hardclock driver no longer 244 * needs to keep (inaccurate) statistics on its own. This decouples 245 * statistics gathering from scheduling interrupts. 246 * 247 * The RTC chip requires that we read status register C (RTC_INTR) 248 * to acknowledge an interrupt, before it will generate the next one. 249 */ 250static void 251rtcintr(struct clockframe frame) 252{ 253 u_char stat; 254 stat = rtcin(RTC_INTR); 255 if(stat & RTCIR_PERIOD) { 256 statclock(&frame); 257 } 258} 259 260#ifdef DDB 261static void 262DDB_printrtc(void) 263{ 264 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n", 265 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY), 266 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC), 267 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 268} 269#endif 270 271static int 272getit(void) 273{ 274 int high, low; 275 276 disable_intr(); 277 /* select timer0 and latch counter value */ 278 outb(TIMER_MODE, TIMER_SEL0); 279 low = inb(TIMER_CNTR0); 280 high = inb(TIMER_CNTR0); 281 enable_intr(); 282 return ((high << 8) | low); 283} 284 285#if defined(I586_CPU) || defined(I686_CPU) 286/* 287 * Figure out how fast the cyclecounter runs. This must be run with 288 * clock interrupts disabled, but with the timer/counter programmed 289 * and running. 290 */ 291void 292calibrate_cyclecounter(void) 293{ 294 /* 295 * Don't need volatile; should always use unsigned if 2's 296 * complement arithmetic is desired. 297 */ 298 unsigned long long count; 299 300#define howlong 131072UL 301 __asm __volatile(".byte 0x0f, 0x30" : : "A"(0LL), "c" (0x10)); 302 DELAY(howlong); 303 __asm __volatile(".byte 0xf,0x31" : "=A" (count)); 304 305 i586_ctr_rate = (count << I586_CTR_RATE_SHIFT) / howlong; 306#undef howlong 307} 308#endif 309 310/* 311 * Wait "n" microseconds. 312 * Relies on timer 1 counting down from (TIMER_FREQ / hz) 313 * Note: timer had better have been programmed before this is first used! 314 */ 315void 316DELAY(int n) 317{ 318 int prev_tick, tick, ticks_left, sec, usec; 319 320#ifdef DELAYDEBUG 321 int getit_calls = 1; 322 int n1; 323 static int state = 0; 324 325 if (state == 0) { 326 state = 1; 327 for (n1 = 1; n1 <= 10000000; n1 *= 10) 328 DELAY(n1); 329 state = 2; 330 } 331 if (state == 1) 332 printf("DELAY(%d)...", n); 333#endif 334 /* 335 * Read the counter first, so that the rest of the setup overhead is 336 * counted. Guess the initial overhead is 20 usec (on most systems it 337 * takes about 1.5 usec for each of the i/o's in getit(). The loop 338 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 339 * multiplications and divisions to scale the count take a while). 340 */ 341 prev_tick = getit(); 342 n -= 20; 343 /* 344 * Calculate (n * (TIMER_FREQ / 1e6)) without using floating point 345 * and without any avoidable overflows. 346 */ 347 sec = n / 1000000; 348 usec = n - sec * 1000000; 349 ticks_left = sec * TIMER_FREQ 350 + usec * (TIMER_FREQ / 1000000) 351 + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000 352 + usec * (TIMER_FREQ % 1000) / 1000000; 353 354 while (ticks_left > 0) { 355 tick = getit(); 356#ifdef DELAYDEBUG 357 ++getit_calls; 358#endif 359 if (tick > prev_tick) 360 ticks_left -= prev_tick - (tick - timer0_max_count); 361 else 362 ticks_left -= prev_tick - tick; 363 prev_tick = tick; 364 } 365#ifdef DELAYDEBUG 366 if (state == 1) 367 printf(" %d calls to getit() at %d usec each\n", 368 getit_calls, (n + 5) / getit_calls); 369#endif 370} 371 372static void 373sysbeepstop(void *chan) 374{ 375 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ 376 release_timer2(); 377 beeping = 0; 378} 379 380int 381sysbeep(int pitch, int period) 382{ 383 384 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 385 return -1; 386 disable_intr(); 387 outb(TIMER_CNTR2, pitch); 388 outb(TIMER_CNTR2, (pitch>>8)); 389 enable_intr(); 390 if (!beeping) { 391 outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */ 392 beeping = period; 393 timeout(sysbeepstop, (void *)NULL, period); 394 } 395 return 0; 396} 397 398/* 399 * RTC support routines 400 */ 401static int 402bcd2int(int bcd) 403{ 404 return(bcd/16 * 10 + bcd%16); 405} 406 407static int 408int2bcd(int dez) 409{ 410 return(dez/10 * 16 + dez%10); 411} 412 413static inline void 414writertc(u_char reg, u_char val) 415{ 416 outb(IO_RTC, reg); 417 outb(IO_RTC + 1, val); 418} 419 420static int 421readrtc(int port) 422{ 423 return(bcd2int(rtcin(port))); 424} 425 426/* 427 * Initialize 8253 timer 0 early so that it can be used in DELAY(). 428 * XXX initialization of other timers is unintentionally left blank. 429 */ 430void 431startrtclock() 432{ 433 timer0_max_count = hardclock_max_count = TIMER_DIV(hz); 434 timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; 435 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 436 outb(TIMER_CNTR0, timer0_max_count & 0xff); 437 outb(TIMER_CNTR0, timer0_max_count >> 8); 438} 439 440/* 441 * Initialize the time of day register, based on the time base which is, e.g. 442 * from a filesystem. 443 */ 444void 445inittodr(time_t base) 446{ 447 unsigned long sec, days; 448 int yd; 449 int year, month; 450 int y, m, s; 451 452 s = splclock(); 453 time.tv_sec = base; 454 time.tv_usec = 0; 455 splx(s); 456 457 /* Look if we have a RTC present and the time is valid */ 458 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 459 goto wrong_time; 460 461 /* wait for time update to complete */ 462 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 463 while (rtcin(RTC_STATUSA) & RTCSA_TUP); 464 465 days = 0; 466#ifdef USE_RTC_CENTURY 467 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 468#else 469 year = readrtc(RTC_YEAR) + 1900; 470 if (year < 1970) 471 year += 100; 472#endif 473 if (year < 1970) 474 goto wrong_time; 475 month = readrtc(RTC_MONTH); 476 for (m = 1; m < month; m++) 477 days += daysinmonth[m-1]; 478 if ((month > 2) && LEAPYEAR(year)) 479 days ++; 480 days += readrtc(RTC_DAY) - 1; 481 yd = days; 482 for (y = 1970; y < year; y++) 483 days += DAYSPERYEAR + LEAPYEAR(y); 484 sec = ((( days * 24 + 485 readrtc(RTC_HRS)) * 60 + 486 readrtc(RTC_MIN)) * 60 + 487 readrtc(RTC_SEC)); 488 /* sec now contains the number of seconds, since Jan 1 1970, 489 in the local time zone */ 490 491 sec += tz.tz_minuteswest * 60 + adjkerntz; 492 493 s = splclock(); 494 time.tv_sec = sec; 495 splx(s); 496 return; 497 498wrong_time: 499 printf("Invalid time in real time clock.\n"); 500 printf("Check and reset the date immediately!\n"); 501} 502 503/* 504 * Write system time back to RTC 505 */ 506void 507resettodr() 508{ 509 unsigned long tm; 510 int y, m, s; 511 512 if (disable_rtc_set) 513 return; 514 515 s = splclock(); 516 tm = time.tv_sec; 517 splx(s); 518 519 /* Disable RTC updates and interrupts. */ 520 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 521 522 /* Calculate local time to put in RTC */ 523 524 tm -= tz.tz_minuteswest * 60 + adjkerntz; 525 526 writertc(RTC_SEC, int2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 527 writertc(RTC_MIN, int2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 528 writertc(RTC_HRS, int2bcd(tm%24)); tm /= 24; /* Write back Hours */ 529 530 /* We have now the days since 01-01-1970 in tm */ 531 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */ 532 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 533 tm >= m; 534 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 535 tm -= m; 536 537 /* Now we have the years in y and the day-of-the-year in tm */ 538#ifdef USE_RTC_CENTURY 539 writertc(RTC_YEAR, int2bcd(y%100)); /* Write back Year */ 540 writertc(RTC_CENTURY, int2bcd(y/100)); /* ... and Century */ 541#else 542 writertc(RTC_YEAR, int2bcd(y - 1900)); /* Write back Year */ 543#endif 544 for (m = 0; ; m++) { 545 int ml; 546 547 ml = daysinmonth[m]; 548 if (m == 1 && LEAPYEAR(y)) 549 ml++; 550 if (tm < ml) 551 break; 552 tm -= ml; 553 } 554 555 writertc(RTC_MONTH, int2bcd(m + 1)); /* Write back Month */ 556 writertc(RTC_DAY, int2bcd(tm + 1)); /* Write back Month Day */ 557 558 /* Reenable RTC updates and interrupts. */ 559 writertc(RTC_STATUSB, RTCSB_24HR | RTCSB_PINTR); 560} 561 562/* 563 * Start both clocks running. 564 */ 565void 566cpu_initclocks() 567{ 568 int diag; 569 570 stathz = RTC_NOPROFRATE; 571 profhz = RTC_PROFRATE; 572 573 /* Finish initializing 8253 timer 0. */ 574 register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, 575 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 576 /* unit */ 0); 577 INTREN(IRQ0); 578#if defined(I586_CPU) || defined(I686_CPU) 579 /* 580 * Finish setting up anti-jitter measures. 581 */ 582 if (i586_ctr_rate) { 583 I586_CYCLECTR(i586_last_tick); 584 i586_ctr_bias = i586_last_tick; 585 } 586#endif 587 588 /* Initialize RTC. */ 589 writertc(RTC_STATUSA, rtc_statusa); 590 writertc(RTC_STATUSB, RTCSB_24HR); 591 diag = rtcin(RTC_DIAG); 592 if (diag != 0) 593 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); 594 register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, 595 /* XXX */ (inthand2_t *)rtcintr, &stat_imask, 596 /* unit */ 0); 597 INTREN(IRQ8); 598 writertc(RTC_STATUSB, RTCSB_24HR | RTCSB_PINTR); 599} 600 601void 602setstatclockrate(int newhz) 603{ 604 if (newhz == RTC_PROFRATE) 605 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF; 606 else 607 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 608 writertc(RTC_STATUSA, rtc_statusa); 609} 610