pcrtc.c revision 49558
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.74 1999/07/30 11:43:10 kato Exp $ 38 */ 39 40/* 41 * Routines to handle clock hardware. 42 */ 43 44/* 45 * inittodr, settodr and support routines written 46 * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at> 47 * 48 * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94 49 */ 50 51/* 52 * modified for PC98 by Kakefuda 53 */ 54 55#include "opt_clock.h" 56#include "apm.h" 57 58#include <sys/param.h> 59#include <sys/systm.h> 60#include <sys/time.h> 61#include <sys/kernel.h> 62#ifndef SMP 63#include <sys/lock.h> 64#endif 65#include <sys/sysctl.h> 66#include <sys/cons.h> 67 68#include <machine/clock.h> 69#ifdef CLK_CALIBRATION_LOOP 70#endif 71#include <machine/cputypes.h> 72#include <machine/frame.h> 73#include <machine/ipl.h> 74#include <machine/limits.h> 75#include <machine/md_var.h> 76#include <machine/psl.h> 77#ifdef APIC_IO 78#include <machine/segments.h> 79#endif 80#if defined(SMP) || defined(APIC_IO) 81#include <machine/smp.h> 82#endif /* SMP || APIC_IO */ 83#include <machine/specialreg.h> 84 85#include <i386/isa/icu.h> 86#ifdef PC98 87#include <pc98/pc98/pc98.h> 88#include <pc98/pc98/pc98_machdep.h> 89#include <i386/isa/isa_device.h> 90#else 91#include <i386/isa/isa.h> 92#include <isa/rtc.h> 93#endif 94#include <i386/isa/timerreg.h> 95 96#include <i386/isa/intr_machdep.h> 97 98#ifdef SMP 99#define disable_intr() CLOCK_DISABLE_INTR() 100#define enable_intr() CLOCK_ENABLE_INTR() 101 102#ifdef APIC_IO 103#include <i386/isa/intr_machdep.h> 104/* The interrupt triggered by the 8254 (timer) chip */ 105int apic_8254_intr; 106static u_long read_intr_count __P((int vec)); 107static void setup_8254_mixed_mode __P((void)); 108#endif 109#endif /* SMP */ 110 111/* 112 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 113 * can use a simple formula for leap years. 114 */ 115#define LEAPYEAR(y) ((u_int)(y) % 4 == 0) 116#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) 117 118#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x)) 119 120/* 121 * Time in timer cycles that it takes for microtime() to disable interrupts 122 * and latch the count. microtime() currently uses "cli; outb ..." so it 123 * normally takes less than 2 timer cycles. Add a few for cache misses. 124 * Add a few more to allow for latency in bogus calls to microtime() with 125 * interrupts already disabled. 126 */ 127#define TIMER0_LATCH_COUNT 20 128 129/* 130 * Maximum frequency that we are willing to allow for timer0. Must be 131 * low enough to guarantee that the timer interrupt handler returns 132 * before the next timer interrupt. 133 */ 134#define TIMER0_MAX_FREQ 20000 135 136int adjkerntz; /* local offset from GMT in seconds */ 137int clkintr_pending; 138int disable_rtc_set; /* disable resettodr() if != 0 */ 139volatile u_int idelayed; 140int statclock_disable; 141u_int stat_imask = SWI_CLOCK_MASK; 142#ifndef TIMER_FREQ 143#ifdef PC98 144#define TIMER_FREQ 2457600; 145#else /* IBM-PC */ 146#define TIMER_FREQ 1193182; 147#endif /* PC98 */ 148#endif 149u_int timer_freq = TIMER_FREQ; 150int timer0_max_count; 151u_int tsc_freq; 152int tsc_is_broken; 153int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 154 155static int beeping = 0; 156static u_int clk_imask = HWI_MASK | SWI_MASK; 157static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 158static u_int hardclock_max_count; 159static u_int32_t i8254_lastcount; 160static u_int32_t i8254_offset; 161static int i8254_ticked; 162/* 163 * XXX new_function and timer_func should not handle clockframes, but 164 * timer_func currently needs to hold hardclock to handle the 165 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 166 * to switch between clkintr() and a slightly different timerintr(). 167 */ 168static void (*new_function) __P((struct clockframe *frame)); 169static u_int new_rate; 170#ifndef PC98 171static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 172static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 173#endif 174static u_int timer0_prescaler_count; 175 176/* Values for timerX_state: */ 177#define RELEASED 0 178#define RELEASE_PENDING 1 179#define ACQUIRED 2 180#define ACQUIRE_PENDING 3 181 182static u_char timer0_state; 183#ifdef PC98 184static u_char timer1_state; 185#endif 186static u_char timer2_state; 187static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 188#ifdef PC98 189static void rtc_serialcombit __P((int)); 190static void rtc_serialcom __P((int)); 191static int rtc_inb __P((void)); 192static void rtc_outb __P((int)); 193#endif 194static u_int tsc_present; 195 196static unsigned i8254_get_timecount __P((struct timecounter *tc)); 197static unsigned tsc_get_timecount __P((struct timecounter *tc)); 198static void set_timer_freq(u_int freq, int intr_freq); 199 200static struct timecounter tsc_timecounter = { 201 tsc_get_timecount, /* get_timecount */ 202 0, /* no poll_pps */ 203 ~0u, /* counter_mask */ 204 0, /* frequency */ 205 "TSC" /* name */ 206}; 207 208SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD, 209 &tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", ""); 210 211static struct timecounter i8254_timecounter = { 212 i8254_get_timecount, /* get_timecount */ 213 0, /* no poll_pps */ 214 ~0u, /* counter_mask */ 215 0, /* frequency */ 216 "i8254" /* name */ 217}; 218 219SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 220 &i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); 221 222static void 223clkintr(struct clockframe frame) 224{ 225 if (timecounter->tc_get_timecount == i8254_get_timecount) { 226 disable_intr(); 227 if (i8254_ticked) 228 i8254_ticked = 0; 229 else { 230 i8254_offset += timer0_max_count; 231 i8254_lastcount = 0; 232 } 233 clkintr_pending = 0; 234 enable_intr(); 235 } 236 timer_func(&frame); 237 switch (timer0_state) { 238 239 case RELEASED: 240 setdelayed(); 241 break; 242 243 case ACQUIRED: 244 if ((timer0_prescaler_count += timer0_max_count) 245 >= hardclock_max_count) { 246 timer0_prescaler_count -= hardclock_max_count; 247 hardclock(&frame); 248 setdelayed(); 249 } 250 break; 251 252 case ACQUIRE_PENDING: 253 disable_intr(); 254 i8254_offset = i8254_get_timecount(NULL); 255 i8254_lastcount = 0; 256 timer0_max_count = TIMER_DIV(new_rate); 257 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 258 outb(TIMER_CNTR0, timer0_max_count & 0xff); 259 outb(TIMER_CNTR0, timer0_max_count >> 8); 260 enable_intr(); 261 timer_func = new_function; 262 timer0_state = ACQUIRED; 263 setdelayed(); 264 break; 265 266 case RELEASE_PENDING: 267 if ((timer0_prescaler_count += timer0_max_count) 268 >= hardclock_max_count) { 269 disable_intr(); 270 i8254_offset = i8254_get_timecount(NULL); 271 i8254_lastcount = 0; 272 timer0_max_count = hardclock_max_count; 273 outb(TIMER_MODE, 274 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 275 outb(TIMER_CNTR0, timer0_max_count & 0xff); 276 outb(TIMER_CNTR0, timer0_max_count >> 8); 277 enable_intr(); 278 timer0_prescaler_count = 0; 279 timer_func = hardclock; 280 timer0_state = RELEASED; 281 hardclock(&frame); 282 setdelayed(); 283 } 284 break; 285 } 286} 287 288/* 289 * The acquire and release functions must be called at ipl >= splclock(). 290 */ 291int 292acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 293{ 294 static int old_rate; 295 296 if (rate <= 0 || rate > TIMER0_MAX_FREQ) 297 return (-1); 298 switch (timer0_state) { 299 300 case RELEASED: 301 timer0_state = ACQUIRE_PENDING; 302 break; 303 304 case RELEASE_PENDING: 305 if (rate != old_rate) 306 return (-1); 307 /* 308 * The timer has been released recently, but is being 309 * re-acquired before the release completed. In this 310 * case, we simply reclaim it as if it had not been 311 * released at all. 312 */ 313 timer0_state = ACQUIRED; 314 break; 315 316 default: 317 return (-1); /* busy */ 318 } 319 new_function = function; 320 old_rate = new_rate = rate; 321 return (0); 322} 323 324#ifdef PC98 325int 326acquire_timer1(int mode) 327{ 328 329 if (timer1_state != RELEASED) 330 return (-1); 331 timer1_state = ACQUIRED; 332 333 /* 334 * This access to the timer registers is as atomic as possible 335 * because it is a single instruction. We could do better if we 336 * knew the rate. Use of splclock() limits glitches to 10-100us, 337 * and this is probably good enough for timer2, so we aren't as 338 * careful with it as with timer0. 339 */ 340 outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f)); 341 342 return (0); 343} 344#endif 345 346int 347acquire_timer2(int mode) 348{ 349 350 if (timer2_state != RELEASED) 351 return (-1); 352 timer2_state = ACQUIRED; 353 354 /* 355 * This access to the timer registers is as atomic as possible 356 * because it is a single instruction. We could do better if we 357 * knew the rate. Use of splclock() limits glitches to 10-100us, 358 * and this is probably good enough for timer2, so we aren't as 359 * careful with it as with timer0. 360 */ 361 outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f)); 362 363 return (0); 364} 365 366int 367release_timer0() 368{ 369 switch (timer0_state) { 370 371 case ACQUIRED: 372 timer0_state = RELEASE_PENDING; 373 break; 374 375 case ACQUIRE_PENDING: 376 /* Nothing happened yet, release quickly. */ 377 timer0_state = RELEASED; 378 break; 379 380 default: 381 return (-1); 382 } 383 return (0); 384} 385 386#ifdef PC98 387int 388release_timer1() 389{ 390 391 if (timer1_state != ACQUIRED) 392 return (-1); 393 timer1_state = RELEASED; 394 outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT); 395 return (0); 396} 397#endif 398 399int 400release_timer2() 401{ 402 403 if (timer2_state != ACQUIRED) 404 return (-1); 405 timer2_state = RELEASED; 406 outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT); 407 return (0); 408} 409 410#ifndef PC98 411/* 412 * This routine receives statistical clock interrupts from the RTC. 413 * As explained above, these occur at 128 interrupts per second. 414 * When profiling, we receive interrupts at a rate of 1024 Hz. 415 * 416 * This does not actually add as much overhead as it sounds, because 417 * when the statistical clock is active, the hardclock driver no longer 418 * needs to keep (inaccurate) statistics on its own. This decouples 419 * statistics gathering from scheduling interrupts. 420 * 421 * The RTC chip requires that we read status register C (RTC_INTR) 422 * to acknowledge an interrupt, before it will generate the next one. 423 * Under high interrupt load, rtcintr() can be indefinitely delayed and 424 * the clock can tick immediately after the read from RTC_INTR. In this 425 * case, the mc146818A interrupt signal will not drop for long enough 426 * to register with the 8259 PIC. If an interrupt is missed, the stat 427 * clock will halt, considerably degrading system performance. This is 428 * why we use 'while' rather than a more straightforward 'if' below. 429 * Stat clock ticks can still be lost, causing minor loss of accuracy 430 * in the statistics, but the stat clock will no longer stop. 431 */ 432static void 433rtcintr(struct clockframe frame) 434{ 435 while (rtcin(RTC_INTR) & RTCIR_PERIOD) 436 statclock(&frame); 437} 438 439#include "opt_ddb.h" 440#ifdef DDB 441#include <ddb/ddb.h> 442 443DB_SHOW_COMMAND(rtc, rtc) 444{ 445 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n", 446 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY), 447 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC), 448 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 449} 450#endif /* DDB */ 451#endif /* for PC98 */ 452 453static int 454getit(void) 455{ 456 u_long ef; 457 int high, low; 458 459 ef = read_eflags(); 460 disable_intr(); 461 462 /* Select timer0 and latch counter value. */ 463 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 464 465 low = inb(TIMER_CNTR0); 466 high = inb(TIMER_CNTR0); 467 468 CLOCK_UNLOCK(); 469 write_eflags(ef); 470 return ((high << 8) | low); 471} 472 473/* 474 * Wait "n" microseconds. 475 * Relies on timer 1 counting down from (timer_freq / hz) 476 * Note: timer had better have been programmed before this is first used! 477 */ 478void 479DELAY(int n) 480{ 481 int delta, prev_tick, tick, ticks_left; 482 483#ifdef DELAYDEBUG 484 int getit_calls = 1; 485 int n1; 486 static int state = 0; 487 488 if (state == 0) { 489 state = 1; 490 for (n1 = 1; n1 <= 10000000; n1 *= 10) 491 DELAY(n1); 492 state = 2; 493 } 494 if (state == 1) 495 printf("DELAY(%d)...", n); 496#endif 497 /* 498 * Guard against the timer being uninitialized if we are called 499 * early for console i/o. 500 */ 501 if (timer0_max_count == 0) 502 set_timer_freq(timer_freq, hz); 503 504 /* 505 * Read the counter first, so that the rest of the setup overhead is 506 * counted. Guess the initial overhead is 20 usec (on most systems it 507 * takes about 1.5 usec for each of the i/o's in getit(). The loop 508 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 509 * multiplications and divisions to scale the count take a while). 510 */ 511 prev_tick = getit(); 512 n -= 0; /* XXX actually guess no initial overhead */ 513 /* 514 * Calculate (n * (timer_freq / 1e6)) without using floating point 515 * and without any avoidable overflows. 516 */ 517 if (n <= 0) 518 ticks_left = 0; 519 else if (n < 256) 520 /* 521 * Use fixed point to avoid a slow division by 1000000. 522 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest. 523 * 2^15 is the first power of 2 that gives exact results 524 * for n between 0 and 256. 525 */ 526 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15; 527 else 528 /* 529 * Don't bother using fixed point, although gcc-2.7.2 530 * generates particularly poor code for the long long 531 * division, since even the slow way will complete long 532 * before the delay is up (unless we're interrupted). 533 */ 534 ticks_left = ((u_int)n * (long long)timer_freq + 999999) 535 / 1000000; 536 537 while (ticks_left > 0) { 538 tick = getit(); 539#ifdef DELAYDEBUG 540 ++getit_calls; 541#endif 542 delta = prev_tick - tick; 543 prev_tick = tick; 544 if (delta < 0) { 545 delta += timer0_max_count; 546 /* 547 * Guard against timer0_max_count being wrong. 548 * This shouldn't happen in normal operation, 549 * but it may happen if set_timer_freq() is 550 * traced. 551 */ 552 if (delta < 0) 553 delta = 0; 554 } 555 ticks_left -= delta; 556 } 557#ifdef DELAYDEBUG 558 if (state == 1) 559 printf(" %d calls to getit() at %d usec each\n", 560 getit_calls, (n + 5) / getit_calls); 561#endif 562} 563 564static void 565sysbeepstop(void *chan) 566{ 567#ifdef PC98 /* PC98 */ 568 outb(IO_PPI, inb(IO_PPI)|0x08); /* disable counter1 output to speaker */ 569 release_timer1(); 570#else 571 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ 572 release_timer2(); 573#endif 574 beeping = 0; 575} 576 577int 578sysbeep(int pitch, int period) 579{ 580 int x = splclock(); 581 582#ifdef PC98 583 if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT)) 584 if (!beeping) { 585 /* Something else owns it. */ 586 splx(x); 587 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 588 } 589 disable_intr(); 590 outb(0x3fdb, pitch); 591 outb(0x3fdb, (pitch>>8)); 592 enable_intr(); 593 if (!beeping) { 594 /* enable counter1 output to speaker */ 595 outb(IO_PPI, (inb(IO_PPI) & 0xf7)); 596 beeping = period; 597 timeout(sysbeepstop, (void *)NULL, period); 598 } 599#else 600 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 601 if (!beeping) { 602 /* Something else owns it. */ 603 splx(x); 604 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 605 } 606 disable_intr(); 607 outb(TIMER_CNTR2, pitch); 608 outb(TIMER_CNTR2, (pitch>>8)); 609 enable_intr(); 610 if (!beeping) { 611 /* enable counter2 output to speaker */ 612 outb(IO_PPI, inb(IO_PPI) | 3); 613 beeping = period; 614 timeout(sysbeepstop, (void *)NULL, period); 615 } 616#endif 617 splx(x); 618 return (0); 619} 620 621#ifndef PC98 622/* 623 * RTC support routines 624 */ 625 626int 627rtcin(reg) 628 int reg; 629{ 630 u_char val; 631 632 outb(IO_RTC, reg); 633 inb(0x84); 634 val = inb(IO_RTC + 1); 635 inb(0x84); 636 return (val); 637} 638 639static __inline void 640writertc(u_char reg, u_char val) 641{ 642 inb(0x84); 643 outb(IO_RTC, reg); 644 inb(0x84); 645 outb(IO_RTC + 1, val); 646 inb(0x84); /* XXX work around wrong order in rtcin() */ 647} 648 649static __inline int 650readrtc(int port) 651{ 652 return(bcd2bin(rtcin(port))); 653} 654#endif 655 656#ifdef PC98 657unsigned int delaycount; 658#define FIRST_GUESS 0x2000 659static void findcpuspeed(void) 660{ 661 int i; 662 int remainder; 663 664 /* Put counter in count down mode */ 665 outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN); 666 outb(TIMER_CNTR0, 0xff); 667 outb(TIMER_CNTR0, 0xff); 668 for (i = FIRST_GUESS; i; i--) 669 ; 670 remainder = getit(); 671 delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff - remainder); 672} 673#endif 674 675#ifdef PC98 676static u_int 677calibrate_clocks(void) 678{ 679 int timeout; 680 u_int count, prev_count, tot_count; 681 u_short sec, start_sec; 682 683 if (bootverbose) 684 printf("Calibrating clock(s) ... "); 685 /* Check ARTIC. */ 686 if (!(PC98_SYSTEM_PARAMETER(0x458) & 0x80) && 687 !(PC98_SYSTEM_PARAMETER(0x45b) & 0x04)) 688 goto fail; 689 timeout = 100000000; 690 691 /* Read the ARTIC. */ 692 sec = inw(0x5e); 693 694 /* Wait for the ARTIC to changes. */ 695 start_sec = sec; 696 for (;;) { 697 sec = inw(0x5e); 698 if (sec != start_sec) 699 break; 700 if (--timeout == 0) 701 goto fail; 702 } 703 prev_count = getit(); 704 if (prev_count == 0 || prev_count > timer0_max_count) 705 goto fail; 706 tot_count = 0; 707 708 if (tsc_present) 709 wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ 710 start_sec = sec; 711 for (;;) { 712 sec = inw(0x5e); 713 count = getit(); 714 if (count == 0 || count > timer0_max_count) 715 goto fail; 716 if (count > prev_count) 717 tot_count += prev_count - (count - timer0_max_count); 718 else 719 tot_count += prev_count - count; 720 prev_count = count; 721 if ((sec == start_sec + 1200) || 722 (sec < start_sec && 723 (u_int)sec + 0x10000 == (u_int)start_sec + 1200)) 724 break; 725 if (--timeout == 0) 726 goto fail; 727 } 728 /* 729 * Read the cpu cycle counter. The timing considerations are 730 * similar to those for the i8254 clock. 731 */ 732 if (tsc_present) 733 tsc_freq = rdtsc(); 734 735 if (bootverbose) { 736 if (tsc_present) 737 printf("TSC clock: %u Hz, ", tsc_freq); 738 printf("i8254 clock: %u Hz\n", tot_count); 739 } 740 return (tot_count); 741 742fail: 743 if (bootverbose) 744 printf("failed, using default i8254 clock of %u Hz\n", 745 timer_freq); 746 return (timer_freq); 747} 748#else 749static u_int 750calibrate_clocks(void) 751{ 752 u_int64_t old_tsc; 753 u_int count, prev_count, tot_count; 754 int sec, start_sec, timeout; 755 756 if (bootverbose) 757 printf("Calibrating clock(s) ... "); 758 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 759 goto fail; 760 timeout = 100000000; 761 762 /* Read the mc146818A seconds counter. */ 763 for (;;) { 764 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 765 sec = rtcin(RTC_SEC); 766 break; 767 } 768 if (--timeout == 0) 769 goto fail; 770 } 771 772 /* Wait for the mC146818A seconds counter to change. */ 773 start_sec = sec; 774 for (;;) { 775 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 776 sec = rtcin(RTC_SEC); 777 if (sec != start_sec) 778 break; 779 } 780 if (--timeout == 0) 781 goto fail; 782 } 783 784 /* Start keeping track of the i8254 counter. */ 785 prev_count = getit(); 786 if (prev_count == 0 || prev_count > timer0_max_count) 787 goto fail; 788 tot_count = 0; 789 790 if (tsc_present) 791 old_tsc = rdtsc(); 792 else 793 old_tsc = 0; /* shut up gcc */ 794 795 /* 796 * Wait for the mc146818A seconds counter to change. Read the i8254 797 * counter for each iteration since this is convenient and only 798 * costs a few usec of inaccuracy. The timing of the final reads 799 * of the counters almost matches the timing of the initial reads, 800 * so the main cause of inaccuracy is the varying latency from 801 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the 802 * rtcin(RTC_SEC) that returns a changed seconds count. The 803 * maximum inaccuracy from this cause is < 10 usec on 486's. 804 */ 805 start_sec = sec; 806 for (;;) { 807 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) 808 sec = rtcin(RTC_SEC); 809 count = getit(); 810 if (count == 0 || count > timer0_max_count) 811 goto fail; 812 if (count > prev_count) 813 tot_count += prev_count - (count - timer0_max_count); 814 else 815 tot_count += prev_count - count; 816 prev_count = count; 817 if (sec != start_sec) 818 break; 819 if (--timeout == 0) 820 goto fail; 821 } 822 823 /* 824 * Read the cpu cycle counter. The timing considerations are 825 * similar to those for the i8254 clock. 826 */ 827 if (tsc_present) 828 tsc_freq = rdtsc() - old_tsc; 829 830 if (bootverbose) { 831 if (tsc_present) 832 printf("TSC clock: %u Hz, ", tsc_freq); 833 printf("i8254 clock: %u Hz\n", tot_count); 834 } 835 return (tot_count); 836 837fail: 838 if (bootverbose) 839 printf("failed, using default i8254 clock of %u Hz\n", 840 timer_freq); 841 return (timer_freq); 842} 843#endif /* !PC98 */ 844 845static void 846set_timer_freq(u_int freq, int intr_freq) 847{ 848 u_long ef; 849 int new_timer0_max_count; 850 851 ef = read_eflags(); 852 disable_intr(); 853 timer_freq = freq; 854 new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 855 if (new_timer0_max_count != timer0_max_count) { 856 timer0_max_count = new_timer0_max_count; 857 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 858 outb(TIMER_CNTR0, timer0_max_count & 0xff); 859 outb(TIMER_CNTR0, timer0_max_count >> 8); 860 } 861 CLOCK_UNLOCK(); 862 write_eflags(ef); 863} 864 865/* 866 * Initialize 8254 timer 0 early so that it can be used in DELAY(). 867 * XXX initialization of other timers is unintentionally left blank. 868 */ 869void 870startrtclock() 871{ 872 u_int delta, freq; 873 874#ifdef PC98 875 findcpuspeed(); 876 if (pc98_machine_type & M_8M) 877 timer_freq = 1996800L; /* 1.9968 MHz */ 878 else 879 timer_freq = 2457600L; /* 2.4576 MHz */ 880#endif /* PC98 */ 881 882 if (cpu_feature & CPUID_TSC) 883 tsc_present = 1; 884 else 885 tsc_present = 0; 886 887#ifndef PC98 888 writertc(RTC_STATUSA, rtc_statusa); 889 writertc(RTC_STATUSB, RTCSB_24HR); 890#endif 891 892 set_timer_freq(timer_freq, hz); 893 freq = calibrate_clocks(); 894#ifdef CLK_CALIBRATION_LOOP 895 if (bootverbose) { 896 printf( 897 "Press a key on the console to abort clock calibration\n"); 898 while (cncheckc() == -1) 899 calibrate_clocks(); 900 } 901#endif 902 903 /* 904 * Use the calibrated i8254 frequency if it seems reasonable. 905 * Otherwise use the default, and don't use the calibrated i586 906 * frequency. 907 */ 908 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 909 if (delta < timer_freq / 100) { 910#ifndef CLK_USE_I8254_CALIBRATION 911 if (bootverbose) 912 printf( 913"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 914 freq = timer_freq; 915#endif 916 timer_freq = freq; 917 } else { 918 if (bootverbose) 919 printf( 920 "%d Hz differs from default of %d Hz by more than 1%%\n", 921 freq, timer_freq); 922 tsc_freq = 0; 923 } 924 925 set_timer_freq(timer_freq, hz); 926 i8254_timecounter.tc_frequency = timer_freq; 927 init_timecounter(&i8254_timecounter); 928 929#ifndef CLK_USE_TSC_CALIBRATION 930 if (tsc_freq != 0) { 931 if (bootverbose) 932 printf( 933"CLK_USE_TSC_CALIBRATION not specified - using old calibration method\n"); 934 tsc_freq = 0; 935 } 936#endif 937 if (tsc_present && tsc_freq == 0) { 938 /* 939 * Calibration of the i586 clock relative to the mc146818A 940 * clock failed. Do a less accurate calibration relative 941 * to the i8254 clock. 942 */ 943 u_int64_t old_tsc = rdtsc(); 944 945 DELAY(1000000); 946 tsc_freq = rdtsc() - old_tsc; 947#ifdef CLK_USE_TSC_CALIBRATION 948 if (bootverbose) 949 printf("TSC clock: %u Hz (Method B)\n", tsc_freq); 950#endif 951 } 952 953#if !defined(SMP) 954 /* 955 * We can not use the TSC in SMP mode, until we figure out a 956 * cheap (impossible), reliable and precise (yeah right!) way 957 * to synchronize the TSCs of all the CPUs. 958 * Curse Intel for leaving the counter out of the I/O APIC. 959 */ 960 961#if NAPM > 0 962 /* 963 * We can not use the TSC if we support APM. Precise timekeeping 964 * on an APM'ed machine is at best a fools pursuit, since 965 * any and all of the time spent in various SMM code can't 966 * be reliably accounted for. Reading the RTC is your only 967 * source of reliable time info. The i8254 looses too of course 968 * but we need to have some kind of time... 969 * We don't know at this point whether APM is going to be used 970 * or not, nor when it might be activated. Play it safe. 971 */ 972 return; 973#endif /* NAPM > 0 */ 974 975 if (tsc_present && tsc_freq != 0 && !tsc_is_broken) { 976 tsc_timecounter.tc_frequency = tsc_freq; 977 init_timecounter(&tsc_timecounter); 978 } 979 980#endif /* !defined(SMP) */ 981} 982 983#ifdef PC98 984static void 985rtc_serialcombit(int i) 986{ 987 outb(IO_RTC, ((i&0x01)<<5)|0x07); 988 DELAY(1); 989 outb(IO_RTC, ((i&0x01)<<5)|0x17); 990 DELAY(1); 991 outb(IO_RTC, ((i&0x01)<<5)|0x07); 992 DELAY(1); 993} 994 995static void 996rtc_serialcom(int i) 997{ 998 rtc_serialcombit(i&0x01); 999 rtc_serialcombit((i&0x02)>>1); 1000 rtc_serialcombit((i&0x04)>>2); 1001 rtc_serialcombit((i&0x08)>>3); 1002 outb(IO_RTC, 0x07); 1003 DELAY(1); 1004 outb(IO_RTC, 0x0f); 1005 DELAY(1); 1006 outb(IO_RTC, 0x07); 1007 DELAY(1); 1008} 1009 1010static void 1011rtc_outb(int val) 1012{ 1013 int s; 1014 int sa = 0; 1015 1016 for (s=0;s<8;s++) { 1017 sa = ((val >> s) & 0x01) ? 0x27 : 0x07; 1018 outb(IO_RTC, sa); /* set DI & CLK 0 */ 1019 DELAY(1); 1020 outb(IO_RTC, sa | 0x10); /* CLK 1 */ 1021 DELAY(1); 1022 } 1023 outb(IO_RTC, sa & 0xef); /* CLK 0 */ 1024} 1025 1026static int 1027rtc_inb(void) 1028{ 1029 int s; 1030 int sa = 0; 1031 1032 for (s=0;s<8;s++) { 1033 sa |= ((inb(0x33) & 0x01) << s); 1034 outb(IO_RTC, 0x17); /* CLK 1 */ 1035 DELAY(1); 1036 outb(IO_RTC, 0x07); /* CLK 0 */ 1037 DELAY(2); 1038 } 1039 return sa; 1040} 1041#endif /* PC-98 */ 1042 1043/* 1044 * Initialize the time of day register, based on the time base which is, e.g. 1045 * from a filesystem. 1046 */ 1047void 1048inittodr(time_t base) 1049{ 1050 unsigned long sec, days; 1051#ifndef PC98 1052 int yd; 1053#endif 1054 int year, month; 1055 int y, m, s; 1056 struct timespec ts; 1057#ifdef PC98 1058 int second, min, hour; 1059#endif 1060 1061 if (base) { 1062 s = splclock(); 1063 ts.tv_sec = base; 1064 ts.tv_nsec = 0; 1065 set_timecounter(&ts); 1066 splx(s); 1067 } 1068 1069#ifdef PC98 1070 rtc_serialcom(0x03); /* Time Read */ 1071 rtc_serialcom(0x01); /* Register shift command. */ 1072 DELAY(20); 1073 1074 second = bcd2bin(rtc_inb() & 0xff); /* sec */ 1075 min = bcd2bin(rtc_inb() & 0xff); /* min */ 1076 hour = bcd2bin(rtc_inb() & 0xff); /* hour */ 1077 days = bcd2bin(rtc_inb() & 0xff) - 1; /* date */ 1078 1079 month = (rtc_inb() >> 4) & 0x0f; /* month */ 1080 for (m = 1; m < month; m++) 1081 days += daysinmonth[m-1]; 1082 year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */ 1083 /* 2000 year problem */ 1084 if (year < 1995) 1085 year += 100; 1086 if (year < 1970) 1087 goto wrong_time; 1088 for (y = 1970; y < year; y++) 1089 days += DAYSPERYEAR + LEAPYEAR(y); 1090 if ((month > 2) && LEAPYEAR(year)) 1091 days ++; 1092 sec = ((( days * 24 + 1093 hour) * 60 + 1094 min) * 60 + 1095 second); 1096 /* sec now contains the number of seconds, since Jan 1 1970, 1097 in the local time zone */ 1098#else /* IBM-PC */ 1099 /* Look if we have a RTC present and the time is valid */ 1100 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 1101 goto wrong_time; 1102 1103 /* wait for time update to complete */ 1104 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 1105 while (rtcin(RTC_STATUSA) & RTCSA_TUP); 1106 1107 days = 0; 1108#ifdef USE_RTC_CENTURY 1109 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 1110#else 1111 year = readrtc(RTC_YEAR) + 1900; 1112 if (year < 1970) 1113 year += 100; 1114#endif 1115 if (year < 1970) 1116 goto wrong_time; 1117 month = readrtc(RTC_MONTH); 1118 for (m = 1; m < month; m++) 1119 days += daysinmonth[m-1]; 1120 if ((month > 2) && LEAPYEAR(year)) 1121 days ++; 1122 days += readrtc(RTC_DAY) - 1; 1123 yd = days; 1124 for (y = 1970; y < year; y++) 1125 days += DAYSPERYEAR + LEAPYEAR(y); 1126 sec = ((( days * 24 + 1127 readrtc(RTC_HRS)) * 60 + 1128 readrtc(RTC_MIN)) * 60 + 1129 readrtc(RTC_SEC)); 1130 /* sec now contains the number of seconds, since Jan 1 1970, 1131 in the local time zone */ 1132#endif 1133 1134 sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 1135 1136 y = time_second - sec; 1137 if (y <= -2 || y >= 2) { 1138 /* badly off, adjust it */ 1139 s = splclock(); 1140 ts.tv_sec = sec; 1141 ts.tv_nsec = 0; 1142 set_timecounter(&ts); 1143 splx(s); 1144 } 1145 return; 1146 1147wrong_time: 1148 printf("Invalid time in real time clock.\n"); 1149 printf("Check and reset the date immediately!\n"); 1150} 1151 1152/* 1153 * Write system time back to RTC 1154 */ 1155void 1156resettodr() 1157{ 1158 unsigned long tm; 1159 int y, m, s; 1160#ifdef PC98 1161 int wd; 1162#endif 1163 1164 if (disable_rtc_set) 1165 return; 1166 1167 s = splclock(); 1168 tm = time_second; 1169 splx(s); 1170 1171#ifdef PC98 1172 rtc_serialcom(0x01); /* Register shift command. */ 1173 1174 /* Calculate local time to put in RTC */ 1175 1176 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 1177 1178 rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 1179 rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 1180 rtc_outb(bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 1181 1182 /* We have now the days since 01-01-1970 in tm */ 1183 wd = (tm+4)%7; 1184 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 1185 tm >= m; 1186 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 1187 tm -= m; 1188 1189 /* Now we have the years in y and the day-of-the-year in tm */ 1190 for (m = 0; ; m++) { 1191 int ml; 1192 1193 ml = daysinmonth[m]; 1194 if (m == 1 && LEAPYEAR(y)) 1195 ml++; 1196 if (tm < ml) 1197 break; 1198 tm -= ml; 1199 } 1200 1201 m++; 1202 rtc_outb(bin2bcd(tm+1)); /* Write back Day */ 1203 rtc_outb((m << 4) | wd); /* Write back Month & Weekday */ 1204 rtc_outb(bin2bcd(y%100)); /* Write back Year */ 1205 1206 rtc_serialcom(0x02); /* Time set & Counter hold command. */ 1207 rtc_serialcom(0x00); /* Register hold command. */ 1208#else 1209 /* Disable RTC updates and interrupts. */ 1210 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 1211 1212 /* Calculate local time to put in RTC */ 1213 1214 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 1215 1216 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 1217 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 1218 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 1219 1220 /* We have now the days since 01-01-1970 in tm */ 1221 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */ 1222 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 1223 tm >= m; 1224 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 1225 tm -= m; 1226 1227 /* Now we have the years in y and the day-of-the-year in tm */ 1228 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */ 1229#ifdef USE_RTC_CENTURY 1230 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */ 1231#endif 1232 for (m = 0; ; m++) { 1233 int ml; 1234 1235 ml = daysinmonth[m]; 1236 if (m == 1 && LEAPYEAR(y)) 1237 ml++; 1238 if (tm < ml) 1239 break; 1240 tm -= ml; 1241 } 1242 1243 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */ 1244 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */ 1245 1246 /* Reenable RTC updates and interrupts. */ 1247 writertc(RTC_STATUSB, rtc_statusb); 1248#endif 1249} 1250 1251 1252/* 1253 * Start both clocks running. 1254 */ 1255void 1256cpu_initclocks() 1257{ 1258#ifdef APIC_IO 1259 int apic_8254_trial; 1260 struct intrec *clkdesc; 1261#endif /* APIC_IO */ 1262#ifndef PC98 1263 int diag; 1264 1265 if (statclock_disable) { 1266 /* 1267 * The stat interrupt mask is different without the 1268 * statistics clock. Also, don't set the interrupt 1269 * flag which would normally cause the RTC to generate 1270 * interrupts. 1271 */ 1272 stat_imask = HWI_MASK | SWI_MASK; 1273 rtc_statusb = RTCSB_24HR; 1274 } else { 1275 /* Setting stathz to nonzero early helps avoid races. */ 1276 stathz = RTC_NOPROFRATE; 1277 profhz = RTC_PROFRATE; 1278 } 1279#endif 1280 1281 /* Finish initializing 8253 timer 0. */ 1282#ifdef APIC_IO 1283 1284 apic_8254_intr = isa_apic_irq(0); 1285 apic_8254_trial = 0; 1286 if (apic_8254_intr >= 0 ) { 1287 if (apic_int_type(0, 0) == 3) 1288 apic_8254_trial = 1; 1289 } else { 1290 /* look for ExtInt on pin 0 */ 1291 if (apic_int_type(0, 0) == 3) { 1292 apic_8254_intr = 0; 1293 setup_8254_mixed_mode(); 1294 } else 1295 panic("APIC_IO: Cannot route 8254 interrupt to CPU"); 1296 } 1297 1298 clkdesc = inthand_add("clk", apic_8254_intr, (inthand2_t *)clkintr, 1299 NULL, &clk_imask, INTR_EXCL); 1300 INTREN(1 << apic_8254_intr); 1301 1302#else /* APIC_IO */ 1303 1304 inthand_add("clk", 0, (inthand2_t *)clkintr, NULL, &clk_imask, 1305 INTR_EXCL); 1306 INTREN(IRQ0); 1307 1308#endif /* APIC_IO */ 1309 1310#ifndef PC98 1311 /* Initialize RTC. */ 1312 writertc(RTC_STATUSA, rtc_statusa); 1313 writertc(RTC_STATUSB, RTCSB_24HR); 1314 1315 /* Don't bother enabling the statistics clock. */ 1316 if (statclock_disable) 1317 return; 1318 diag = rtcin(RTC_DIAG); 1319 if (diag != 0) 1320 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); 1321 1322#ifdef APIC_IO 1323 if (isa_apic_irq(8) != 8) 1324 panic("APIC RTC != 8"); 1325#endif /* APIC_IO */ 1326 1327 inthand_add("rtc", 8, (inthand2_t *)rtcintr, NULL, &stat_imask, 1328 INTR_EXCL); 1329 1330#ifdef APIC_IO 1331 INTREN(APIC_IRQ8); 1332#else 1333 INTREN(IRQ8); 1334#endif /* APIC_IO */ 1335 1336 writertc(RTC_STATUSB, rtc_statusb); 1337#endif /* !PC98 */ 1338 1339#ifdef APIC_IO 1340 if (apic_8254_trial) { 1341 1342 printf("APIC_IO: Testing 8254 interrupt delivery\n"); 1343 while (read_intr_count(8) < 6) 1344 ; /* nothing */ 1345 if (read_intr_count(apic_8254_intr) < 3) { 1346 /* 1347 * The MP table is broken. 1348 * The 8254 was not connected to the specified pin 1349 * on the IO APIC. 1350 * Workaround: Limited variant of mixed mode. 1351 */ 1352 INTRDIS(1 << apic_8254_intr); 1353 inthand_remove(clkdesc); 1354 printf("APIC_IO: Broken MP table detected: " 1355 "8254 is not connected to IO APIC int pin %d\n", 1356 apic_8254_intr); 1357 1358 apic_8254_intr = 0; 1359 setup_8254_mixed_mode(); 1360 inthand_add("clk", apic_8254_intr,(inthand2_t *)clkintr, 1361 NULL, &clk_imask, INTR_EXCL); 1362 INTREN(1 << apic_8254_intr); 1363 } 1364 1365 } 1366 if (apic_8254_intr) 1367 printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr); 1368 else 1369 printf("APIC_IO: routing 8254 via 8259 on pin 0\n"); 1370#endif 1371 1372} 1373 1374#ifdef APIC_IO 1375static u_long 1376read_intr_count(int vec) 1377{ 1378 u_long *up; 1379 up = intr_countp[vec]; 1380 if (up) 1381 return *up; 1382 return 0UL; 1383} 1384 1385static void 1386setup_8254_mixed_mode() 1387{ 1388 /* 1389 * Allow 8254 timer to INTerrupt 8259: 1390 * re-initialize master 8259: 1391 * reset; prog 4 bytes, single ICU, edge triggered 1392 */ 1393 outb(IO_ICU1, 0x13); 1394#ifdef PC98 1395 outb(IO_ICU1 + 2, NRSVIDT); /* start vector (unused) */ 1396 outb(IO_ICU1 + 2, 0x00); /* ignore slave */ 1397 outb(IO_ICU1 + 2, 0x03); /* auto EOI, 8086 */ 1398 outb(IO_ICU1 + 2, 0xfe); /* unmask INT0 */ 1399#else 1400 outb(IO_ICU1 + 1, NRSVIDT); /* start vector (unused) */ 1401 outb(IO_ICU1 + 1, 0x00); /* ignore slave */ 1402 outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ 1403 outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ 1404#endif 1405 /* program IO APIC for type 3 INT on INT0 */ 1406 if (ext_int_setup(0, 0) < 0) 1407 panic("8254 redirect via APIC pin0 impossible!"); 1408} 1409#endif 1410 1411void 1412setstatclockrate(int newhz) 1413{ 1414#ifndef PC98 1415 if (newhz == RTC_PROFRATE) 1416 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF; 1417 else 1418 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 1419 writertc(RTC_STATUSA, rtc_statusa); 1420#endif 1421} 1422 1423static int 1424sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS 1425{ 1426 int error; 1427 u_int freq; 1428 1429 /* 1430 * Use `i8254' instead of `timer' in external names because `timer' 1431 * is is too generic. Should use it everywhere. 1432 */ 1433 freq = timer_freq; 1434 error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); 1435 if (error == 0 && req->newptr != NULL) { 1436 if (timer0_state != RELEASED) 1437 return (EBUSY); /* too much trouble to handle */ 1438 set_timer_freq(freq, hz); 1439 i8254_timecounter.tc_frequency = freq; 1440 update_timecounter(&i8254_timecounter); 1441 } 1442 return (error); 1443} 1444 1445SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 1446 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); 1447 1448static int 1449sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS 1450{ 1451 int error; 1452 u_int freq; 1453 1454 if (tsc_timecounter.tc_frequency == 0) 1455 return (EOPNOTSUPP); 1456 freq = tsc_freq; 1457 error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); 1458 if (error == 0 && req->newptr != NULL) { 1459 tsc_freq = freq; 1460 tsc_timecounter.tc_frequency = tsc_freq; 1461 update_timecounter(&tsc_timecounter); 1462 } 1463 return (error); 1464} 1465 1466SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, 1467 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); 1468 1469static unsigned 1470i8254_get_timecount(struct timecounter *tc) 1471{ 1472 u_int count; 1473 u_long ef; 1474 u_int high, low; 1475 1476 ef = read_eflags(); 1477 disable_intr(); 1478 1479 /* Select timer0 and latch counter value. */ 1480 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 1481 1482 low = inb(TIMER_CNTR0); 1483 high = inb(TIMER_CNTR0); 1484 count = timer0_max_count - ((high << 8) | low); 1485 if (count < i8254_lastcount || 1486 (!i8254_ticked && (clkintr_pending || 1487 ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / 2u)) && 1488#ifdef APIC_IO 1489#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ 1490 /* XXX this assumes that apic_8254_intr is < 24. */ 1491 (lapic_irr1 & (1 << apic_8254_intr)))) 1492#else 1493 (inb(IO_ICU1) & 1))) 1494#endif 1495 )) { 1496 i8254_ticked = 1; 1497 i8254_offset += timer0_max_count; 1498 } 1499 i8254_lastcount = count; 1500 count += i8254_offset; 1501 CLOCK_UNLOCK(); 1502 write_eflags(ef); 1503 return (count); 1504} 1505 1506static unsigned 1507tsc_get_timecount(struct timecounter *tc) 1508{ 1509 return (rdtsc()); 1510} 1511