tsc.c revision 16299
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.58 1996/05/01 08:39:02 bde 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#include "opt_clock.h" 52 53#include <sys/param.h> 54#include <sys/systm.h> 55#include <sys/time.h> 56#include <sys/kernel.h> 57#include <sys/sysctl.h> 58 59#include <machine/clock.h> 60#ifdef CLK_CALIBRATION_LOOP 61#include <machine/cons.h> 62#endif 63#include <machine/cpu.h> 64#include <machine/frame.h> 65 66#include <i386/isa/icu.h> 67#include <i386/isa/isa.h> 68#include <i386/isa/isa_device.h> 69#include <i386/isa/rtc.h> 70#include <i386/isa/timerreg.h> 71 72/* 73 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 74 * can use a simple formula for leap years. 75 */ 76#define LEAPYEAR(y) ((u_int)(y) % 4 == 0) 77#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) 78 79#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x)) 80 81/* 82 * Time in timer cycles that it takes for microtime() to disable interrupts 83 * and latch the count. microtime() currently uses "cli; outb ..." so it 84 * normally takes less than 2 timer cycles. Add a few for cache misses. 85 * Add a few more to allow for latency in bogus calls to microtime() with 86 * interrupts already disabled. 87 */ 88#define TIMER0_LATCH_COUNT 20 89 90/* 91 * Minimum maximum count that we are willing to program into timer0. 92 * Must be large enough to guarantee that the timer interrupt handler 93 * returns before the next timer interrupt. Must be larger than 94 * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in 95 * the calculation of timer0_overflow_threshold. 96 */ 97#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000) 98 99int adjkerntz; /* local offset from GMT in seconds */ 100int disable_rtc_set; /* disable resettodr() if != 0 */ 101int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 102 103u_int idelayed; 104#if defined(I586_CPU) || defined(I686_CPU) 105unsigned i586_ctr_freq; 106unsigned i586_ctr_rate; 107long long i586_ctr_bias; 108long long i586_last_tick; 109unsigned long i586_avg_tick; 110#endif 111int statclock_disable; 112u_int stat_imask = SWI_CLOCK_MASK; 113int timer0_max_count; 114u_int timer0_overflow_threshold; 115u_int timer0_prescaler_count; 116 117static int beeping = 0; 118static u_int clk_imask = HWI_MASK | SWI_MASK; 119static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 120static u_int hardclock_max_count; 121/* 122 * XXX new_function and timer_func should not handle clockframes, but 123 * timer_func currently needs to hold hardclock to handle the 124 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 125 * to switch between clkintr() and a slightly different timerintr(). 126 * This will require locking when acquiring and releasing timer0 - the 127 * current (nonexistent) locking doesn't seem to be adequate even now. 128 */ 129static void (*new_function) __P((struct clockframe *frame)); 130static u_int new_rate; 131static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 132static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 133#ifdef TIMER_FREQ 134static u_int timer_freq = TIMER_FREQ; 135#else 136static u_int timer_freq = 1193182; 137#endif 138static char timer0_state = 0; 139static char timer2_state = 0; 140static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 141 142#if 0 143void 144clkintr(struct clockframe frame) 145{ 146 hardclock(&frame); 147 setdelayed(); 148} 149#else 150static void 151clkintr(struct clockframe frame) 152{ 153 timer_func(&frame); 154 switch (timer0_state) { 155 case 0: 156 setdelayed(); 157 break; 158 case 1: 159 if ((timer0_prescaler_count += timer0_max_count) 160 >= hardclock_max_count) { 161 hardclock(&frame); 162 setdelayed(); 163 timer0_prescaler_count -= hardclock_max_count; 164 } 165 break; 166 case 2: 167 setdelayed(); 168 timer0_max_count = TIMER_DIV(new_rate); 169 timer0_overflow_threshold = 170 timer0_max_count - TIMER0_LATCH_COUNT; 171 disable_intr(); 172 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 173 outb(TIMER_CNTR0, timer0_max_count & 0xff); 174 outb(TIMER_CNTR0, timer0_max_count >> 8); 175 enable_intr(); 176 timer0_prescaler_count = 0; 177 timer_func = new_function; 178 timer0_state = 1; 179 break; 180 case 3: 181 if ((timer0_prescaler_count += timer0_max_count) 182 >= hardclock_max_count) { 183 hardclock(&frame); 184 setdelayed(); 185 timer0_max_count = hardclock_max_count; 186 timer0_overflow_threshold = 187 timer0_max_count - TIMER0_LATCH_COUNT; 188 disable_intr(); 189 outb(TIMER_MODE, 190 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 191 outb(TIMER_CNTR0, timer0_max_count & 0xff); 192 outb(TIMER_CNTR0, timer0_max_count >> 8); 193 enable_intr(); 194 /* 195 * See microtime.s for this magic. 196 */ 197 time.tv_usec += (27645 * 198 (timer0_prescaler_count - hardclock_max_count)) 199 >> 15; 200 if (time.tv_usec >= 1000000) 201 time.tv_usec -= 1000000; 202 timer0_prescaler_count = 0; 203 timer_func = hardclock;; 204 timer0_state = 0; 205 } 206 break; 207 } 208} 209#endif 210 211int 212acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 213{ 214 if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT || 215 !function) 216 return -1; 217 new_function = function; 218 new_rate = rate; 219 timer0_state = 2; 220 return 0; 221} 222 223int 224acquire_timer2(int mode) 225{ 226 if (timer2_state) 227 return -1; 228 timer2_state = 1; 229 outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f)); 230 return 0; 231} 232 233int 234release_timer0() 235{ 236 if (!timer0_state) 237 return -1; 238 timer0_state = 3; 239 return 0; 240} 241 242int 243release_timer2() 244{ 245 if (!timer2_state) 246 return -1; 247 timer2_state = 0; 248 outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT); 249 return 0; 250} 251 252/* 253 * This routine receives statistical clock interrupts from the RTC. 254 * As explained above, these occur at 128 interrupts per second. 255 * When profiling, we receive interrupts at a rate of 1024 Hz. 256 * 257 * This does not actually add as much overhead as it sounds, because 258 * when the statistical clock is active, the hardclock driver no longer 259 * needs to keep (inaccurate) statistics on its own. This decouples 260 * statistics gathering from scheduling interrupts. 261 * 262 * The RTC chip requires that we read status register C (RTC_INTR) 263 * to acknowledge an interrupt, before it will generate the next one. 264 */ 265static void 266rtcintr(struct clockframe frame) 267{ 268 u_char stat; 269 stat = rtcin(RTC_INTR); 270 if(stat & RTCIR_PERIOD) { 271 statclock(&frame); 272 } 273} 274 275#ifdef DDB 276static void 277DDB_printrtc(void) 278{ 279 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n", 280 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY), 281 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC), 282 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 283} 284#endif 285 286static int 287getit(void) 288{ 289 int high, low; 290 291 disable_intr(); 292 /* select timer0 and latch counter value */ 293 outb(TIMER_MODE, TIMER_SEL0); 294 low = inb(TIMER_CNTR0); 295 high = inb(TIMER_CNTR0); 296 enable_intr(); 297 return ((high << 8) | low); 298} 299 300/* 301 * Wait "n" microseconds. 302 * Relies on timer 1 counting down from (timer_freq / hz) 303 * Note: timer had better have been programmed before this is first used! 304 */ 305void 306DELAY(int n) 307{ 308 int prev_tick, tick, ticks_left, sec, usec; 309 310#ifdef DELAYDEBUG 311 int getit_calls = 1; 312 int n1; 313 static int state = 0; 314 315 if (state == 0) { 316 state = 1; 317 for (n1 = 1; n1 <= 10000000; n1 *= 10) 318 DELAY(n1); 319 state = 2; 320 } 321 if (state == 1) 322 printf("DELAY(%d)...", n); 323#endif 324 /* 325 * Read the counter first, so that the rest of the setup overhead is 326 * counted. Guess the initial overhead is 20 usec (on most systems it 327 * takes about 1.5 usec for each of the i/o's in getit(). The loop 328 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 329 * multiplications and divisions to scale the count take a while). 330 */ 331 prev_tick = getit(); 332 n -= 20; 333 /* 334 * Calculate (n * (timer_freq / 1e6)) without using floating point 335 * and without any avoidable overflows. 336 */ 337 sec = n / 1000000; 338 usec = n - sec * 1000000; 339 ticks_left = sec * timer_freq 340 + usec * (timer_freq / 1000000) 341 + usec * ((timer_freq % 1000000) / 1000) / 1000 342 + usec * (timer_freq % 1000) / 1000000; 343 if (n < 0) 344 ticks_left = 0; /* XXX timer_freq is unsigned */ 345 346 while (ticks_left > 0) { 347 tick = getit(); 348#ifdef DELAYDEBUG 349 ++getit_calls; 350#endif 351 if (tick > prev_tick) 352 ticks_left -= prev_tick - (tick - timer0_max_count); 353 else 354 ticks_left -= prev_tick - tick; 355 prev_tick = tick; 356 } 357#ifdef DELAYDEBUG 358 if (state == 1) 359 printf(" %d calls to getit() at %d usec each\n", 360 getit_calls, (n + 5) / getit_calls); 361#endif 362} 363 364static void 365sysbeepstop(void *chan) 366{ 367 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ 368 release_timer2(); 369 beeping = 0; 370} 371 372int 373sysbeep(int pitch, int period) 374{ 375 376 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 377 return -1; 378 disable_intr(); 379 outb(TIMER_CNTR2, pitch); 380 outb(TIMER_CNTR2, (pitch>>8)); 381 enable_intr(); 382 if (!beeping) { 383 outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */ 384 beeping = period; 385 timeout(sysbeepstop, (void *)NULL, period); 386 } 387 return 0; 388} 389 390/* 391 * RTC support routines 392 */ 393 394int 395rtcin(reg) 396 int reg; 397{ 398 u_char val; 399 400 outb(IO_RTC, reg); 401 inb(0x84); 402 val = inb(IO_RTC + 1); 403 inb(0x84); 404 return (val); 405} 406 407static __inline void 408writertc(u_char reg, u_char val) 409{ 410 outb(IO_RTC, reg); 411 outb(IO_RTC + 1, val); 412} 413 414static __inline int 415readrtc(int port) 416{ 417 return(bcd2bin(rtcin(port))); 418} 419 420static u_int 421calibrate_clocks(void) 422{ 423 u_int count, prev_count, tot_count; 424 int sec, start_sec, timeout; 425 426 printf("Calibrating clock(s) relative to mc146818A clock ... "); 427 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 428 goto fail; 429 timeout = 100000000; 430 431 /* Read the mc146818A seconds counter. */ 432 for (;;) { 433 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 434 sec = rtcin(RTC_SEC); 435 break; 436 } 437 if (--timeout == 0) 438 goto fail; 439 } 440 441 /* Wait for the mC146818A seconds counter to change. */ 442 start_sec = sec; 443 for (;;) { 444 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 445 sec = rtcin(RTC_SEC); 446 if (sec != start_sec) 447 break; 448 } 449 if (--timeout == 0) 450 goto fail; 451 } 452 453 /* Start keeping track of the i8254 counter. */ 454 prev_count = getit(); 455 if (prev_count == 0 || prev_count > timer0_max_count) 456 goto fail; 457 tot_count = 0; 458 459#if defined(I586_CPU) || defined(I686_CPU) 460 if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) 461 wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ 462#endif 463 464 /* 465 * Wait for the mc146818A seconds counter to change. Read the i8254 466 * counter for each iteration since this is convenient and only 467 * costs a few usec of inaccuracy. The timing of the final reads 468 * of the counters almost matches the timing of the initial reads, 469 * so the main cause of inaccuracy is the varying latency from 470 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the 471 * rtcin(RTC_SEC) that returns a changed seconds count. The 472 * maximum inaccuracy from this cause is < 10 usec on 486's. 473 */ 474 start_sec = sec; 475 for (;;) { 476 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) 477 sec = rtcin(RTC_SEC); 478 count = getit(); 479 if (count == 0 || count > timer0_max_count) 480 goto fail; 481 if (count > prev_count) 482 tot_count += prev_count - (count - timer0_max_count); 483 else 484 tot_count += prev_count - count; 485 prev_count = count; 486 if (sec != start_sec) 487 break; 488 if (--timeout == 0) 489 goto fail; 490 } 491 492#if defined(I586_CPU) || defined(I686_CPU) 493 /* 494 * Read the cpu cycle counter. The timing considerations are 495 * similar to those for the i8254 clock. 496 */ 497 if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { 498 unsigned long long i586_count; 499 500 i586_count = rdtsc(); 501 i586_ctr_freq = i586_count; 502 i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; 503 printf("i586 clock: %u Hz, ", i586_ctr_freq); 504 } 505#endif 506 507 printf("i8254 clock: %u Hz\n", tot_count); 508 return (tot_count); 509 510fail: 511 printf("failed, using default i8254 clock of %u Hz\n", timer_freq); 512 return (timer_freq); 513} 514 515static void 516set_timer_freq(u_int freq, int intr_freq) 517{ 518 u_long ef; 519 520 ef = read_eflags(); 521 timer_freq = freq; 522 timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 523 timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; 524 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 525 outb(TIMER_CNTR0, timer0_max_count & 0xff); 526 outb(TIMER_CNTR0, timer0_max_count >> 8); 527 write_eflags(ef); 528} 529 530/* 531 * Initialize 8253 timer 0 early so that it can be used in DELAY(). 532 * XXX initialization of other timers is unintentionally left blank. 533 */ 534void 535startrtclock() 536{ 537 u_int delta, freq; 538 539 writertc(RTC_STATUSA, rtc_statusa); 540 writertc(RTC_STATUSB, RTCSB_24HR); 541 542 /* 543 * Temporarily calibrate with a high intr_freq to get a low 544 * timer0_max_count to help detect bogus i8254 counts. 545 */ 546 set_timer_freq(timer_freq, 20000); 547 freq = calibrate_clocks(); 548#ifdef CLK_CALIBRATION_LOOP 549 if (bootverbose) { 550 printf( 551 "Press a key on the console to abort clock calibration\n"); 552 while (!cncheckc()) 553 calibrate_clocks(); 554 } 555#endif 556 557 /* 558 * Use the calibrated i8254 frequency if it seems reasonable. 559 * Otherwise use the default, and don't use the calibrated i586 560 * frequency. 561 */ 562 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 563 if (delta < timer_freq / 100) { 564#ifndef CLK_USE_I8254_CALIBRATION 565 printf( 566"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 567 freq = timer_freq; 568#endif 569 timer_freq = freq; 570 } else { 571 printf("%d Hz differs from default of %d Hz by more than 1%%\n", 572 freq, timer_freq); 573#if defined(I586_CPU) || defined(I686_CPU) 574 i586_ctr_freq = 0; 575 i586_ctr_rate = 0; 576#endif 577 } 578 579 set_timer_freq(timer_freq, hz); 580 581#if defined(I586_CPU) || defined(I686_CPU) 582#ifndef CLK_USE_I586_CALIBRATION 583 if (i586_ctr_rate != 0) { 584 printf( 585"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); 586 i586_ctr_freq = 0; 587 i586_ctr_rate = 0; 588 } 589#endif 590 if (i586_ctr_rate == 0 && 591 (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { 592 /* 593 * Calibration of the i586 clock relative to the mc146818A 594 * clock failed. Do a less accurate calibration relative 595 * to the i8254 clock. 596 */ 597 unsigned long long i586_count; 598 599 wrmsr(0x10, 0LL); /* XXX */ 600 DELAY(1000000); 601 i586_count = rdtsc(); 602 i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; 603 printf("i586 clock: %u Hz\n", i586_ctr_freq); 604 } 605#endif 606} 607 608/* 609 * Initialize the time of day register, based on the time base which is, e.g. 610 * from a filesystem. 611 */ 612void 613inittodr(time_t base) 614{ 615 unsigned long sec, days; 616 int yd; 617 int year, month; 618 int y, m, s; 619 620 s = splclock(); 621 time.tv_sec = base; 622 time.tv_usec = 0; 623 splx(s); 624 625 /* Look if we have a RTC present and the time is valid */ 626 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 627 goto wrong_time; 628 629 /* wait for time update to complete */ 630 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 631 while (rtcin(RTC_STATUSA) & RTCSA_TUP); 632 633 days = 0; 634#ifdef USE_RTC_CENTURY 635 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 636#else 637 year = readrtc(RTC_YEAR) + 1900; 638 if (year < 1970) 639 year += 100; 640#endif 641 if (year < 1970) 642 goto wrong_time; 643 month = readrtc(RTC_MONTH); 644 for (m = 1; m < month; m++) 645 days += daysinmonth[m-1]; 646 if ((month > 2) && LEAPYEAR(year)) 647 days ++; 648 days += readrtc(RTC_DAY) - 1; 649 yd = days; 650 for (y = 1970; y < year; y++) 651 days += DAYSPERYEAR + LEAPYEAR(y); 652 sec = ((( days * 24 + 653 readrtc(RTC_HRS)) * 60 + 654 readrtc(RTC_MIN)) * 60 + 655 readrtc(RTC_SEC)); 656 /* sec now contains the number of seconds, since Jan 1 1970, 657 in the local time zone */ 658 659 sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 660 661 s = splclock(); 662 time.tv_sec = sec; 663 splx(s); 664 return; 665 666wrong_time: 667 printf("Invalid time in real time clock.\n"); 668 printf("Check and reset the date immediately!\n"); 669} 670 671/* 672 * Write system time back to RTC 673 */ 674void 675resettodr() 676{ 677 unsigned long tm; 678 int y, m, s; 679 680 if (disable_rtc_set) 681 return; 682 683 s = splclock(); 684 tm = time.tv_sec; 685 splx(s); 686 687 /* Disable RTC updates and interrupts. */ 688 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 689 690 /* Calculate local time to put in RTC */ 691 692 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 693 694 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 695 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 696 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 697 698 /* We have now the days since 01-01-1970 in tm */ 699 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */ 700 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 701 tm >= m; 702 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 703 tm -= m; 704 705 /* Now we have the years in y and the day-of-the-year in tm */ 706 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */ 707#ifdef USE_RTC_CENTURY 708 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */ 709#endif 710 for (m = 0; ; m++) { 711 int ml; 712 713 ml = daysinmonth[m]; 714 if (m == 1 && LEAPYEAR(y)) 715 ml++; 716 if (tm < ml) 717 break; 718 tm -= ml; 719 } 720 721 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */ 722 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */ 723 724 /* Reenable RTC updates and interrupts. */ 725 writertc(RTC_STATUSB, rtc_statusb); 726} 727 728/* 729 * Start both clocks running. 730 */ 731void 732cpu_initclocks() 733{ 734 int diag; 735 736 if (statclock_disable) { 737 /* 738 * The stat interrupt mask is different without the 739 * statistics clock. Also, don't set the interrupt 740 * flag which would normally cause the RTC to generate 741 * interrupts. 742 */ 743 stat_imask = HWI_MASK | SWI_MASK; 744 rtc_statusb = RTCSB_24HR; 745 } else { 746 /* Setting stathz to nonzero early helps avoid races. */ 747 stathz = RTC_NOPROFRATE; 748 profhz = RTC_PROFRATE; 749 } 750 751 /* Finish initializing 8253 timer 0. */ 752 register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, 753 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 754 /* unit */ 0); 755 INTREN(IRQ0); 756#if defined(I586_CPU) || defined(I686_CPU) 757 /* 758 * Finish setting up anti-jitter measures. 759 */ 760 if (i586_ctr_rate) { 761 i586_last_tick = rdtsc(); 762 i586_ctr_bias = i586_last_tick; 763 } 764#endif 765 766 /* Initialize RTC. */ 767 writertc(RTC_STATUSA, rtc_statusa); 768 writertc(RTC_STATUSB, RTCSB_24HR); 769 770 /* Don't bother enabling the statistics clock. */ 771 if (statclock_disable) 772 return; 773 diag = rtcin(RTC_DIAG); 774 if (diag != 0) 775 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); 776 register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, 777 /* XXX */ (inthand2_t *)rtcintr, &stat_imask, 778 /* unit */ 0); 779 INTREN(IRQ8); 780 writertc(RTC_STATUSB, rtc_statusb); 781} 782 783void 784setstatclockrate(int newhz) 785{ 786 if (newhz == RTC_PROFRATE) 787 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF; 788 else 789 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 790 writertc(RTC_STATUSA, rtc_statusa); 791} 792 793static int 794sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS 795{ 796 int error; 797 u_int freq; 798 799 /* 800 * Use `i8254' instead of `timer' in external names because `timer' 801 * is is too generic. Should use it everywhere. 802 */ 803 freq = timer_freq; 804 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 805 if (error == 0 && freq != timer_freq) { 806 if (timer0_state != 0) 807 return (EBUSY); /* too much trouble to handle */ 808 set_timer_freq(freq, hz); 809 } 810 return (error); 811} 812 813SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 814 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); 815 816#if defined(I586_CPU) || defined(I686_CPU) 817static int 818sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS 819{ 820 int error; 821 u_int freq; 822 823 if (i586_ctr_rate == 0) 824 return (EOPNOTSUPP); 825 freq = i586_ctr_freq; 826 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 827 if (error == 0 && freq != i586_ctr_freq) { 828 i586_ctr_freq = freq; 829 i586_ctr_rate = ((unsigned long long)freq << 830 I586_CTR_RATE_SHIFT) / 1000000; 831 } 832 return (error); 833} 834 835SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW, 836 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", ""); 837#endif /* defined(I586_CPU) || defined(I686_CPU) */ 838