pcrtc.c revision 120799
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 * $FreeBSD: head/sys/pc98/cbus/pcrtc.c 120799 2003-10-05 08:56:49Z nyan $ 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 "opt_isa.h" 57#include "opt_mca.h" 58 59#include <sys/param.h> 60#include <sys/systm.h> 61#include <sys/bus.h> 62#include <sys/limits.h> 63#include <sys/lock.h> 64#include <sys/mutex.h> 65#include <sys/proc.h> 66#include <sys/time.h> 67#include <sys/timetc.h> 68#include <sys/kernel.h> 69#include <sys/sysctl.h> 70#include <sys/cons.h> 71#include <sys/power.h> 72 73#include <machine/clock.h> 74#include <machine/cputypes.h> 75#include <machine/frame.h> 76#include <machine/md_var.h> 77#include <machine/psl.h> 78#ifdef APIC_IO 79#include <machine/segments.h> 80#endif 81#if defined(SMP) || defined(APIC_IO) 82#include <machine/smp.h> 83#endif /* SMP || APIC_IO */ 84#include <machine/specialreg.h> 85 86#include <i386/isa/icu.h> 87#include <pc98/pc98/pc98.h> 88#include <pc98/pc98/pc98_machdep.h> 89#include <i386/isa/isa_device.h> 90#ifdef DEV_ISA 91#include <isa/isavar.h> 92#endif 93#include <i386/isa/timerreg.h> 94 95#include <i386/isa/intr_machdep.h> 96 97#ifdef APIC_IO 98#include <i386/isa/intr_machdep.h> 99/* The interrupt triggered by the 8254 (timer) chip */ 100int apic_8254_intr; 101static u_long read_intr_count(int vec); 102static void setup_8254_mixed_mode(void); 103#endif 104 105/* 106 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 107 * can use a simple formula for leap years. 108 */ 109#define LEAPYEAR(y) (((u_int)(y) % 4 == 0) ? 1 : 0) 110#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) 111 112#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x)) 113 114#ifndef BURN_BRIDGES 115/* 116 * Time in timer cycles that it takes for microtime() to disable interrupts 117 * and latch the count. microtime() currently uses "cli; outb ..." so it 118 * normally takes less than 2 timer cycles. Add a few for cache misses. 119 * Add a few more to allow for latency in bogus calls to microtime() with 120 * interrupts already disabled. 121 */ 122#define TIMER0_LATCH_COUNT 20 123 124/* 125 * Maximum frequency that we are willing to allow for timer0. Must be 126 * low enough to guarantee that the timer interrupt handler returns 127 * before the next timer interrupt. 128 */ 129#define TIMER0_MAX_FREQ 20000 130#endif 131 132int adjkerntz; /* local offset from GMT in seconds */ 133int clkintr_pending; 134int disable_rtc_set; /* disable resettodr() if != 0 */ 135int pscnt = 1; 136int psdiv = 1; 137int statclock_disable; 138#ifndef TIMER_FREQ 139#define TIMER_FREQ 2457600 140#endif 141u_int timer_freq = TIMER_FREQ; 142int timer0_max_count; 143int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 144struct mtx clock_lock; 145 146static int beeping = 0; 147static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 148static u_int hardclock_max_count; 149static u_int32_t i8254_lastcount; 150static u_int32_t i8254_offset; 151static int i8254_ticked; 152#ifndef BURN_BRIDGES 153/* 154 * XXX new_function and timer_func should not handle clockframes, but 155 * timer_func currently needs to hold hardclock to handle the 156 * timer0_state == 0 case. We should use inthand_add()/inthand_remove() 157 * to switch between clkintr() and a slightly different timerintr(). 158 */ 159static void (*new_function)(struct clockframe *frame); 160static u_int new_rate; 161static u_int timer0_prescaler_count; 162static u_char timer0_state; 163#endif 164 165/* Values for timerX_state: */ 166#define RELEASED 0 167#define RELEASE_PENDING 1 168#define ACQUIRED 2 169#define ACQUIRE_PENDING 3 170 171static u_char timer1_state; 172static u_char timer2_state; 173static void (*timer_func)(struct clockframe *frame) = hardclock; 174static void rtc_serialcombit(int); 175static void rtc_serialcom(int); 176static int rtc_inb(void); 177static void rtc_outb(int); 178 179static unsigned i8254_get_timecount(struct timecounter *tc); 180static void set_timer_freq(u_int freq, int intr_freq); 181 182static struct timecounter i8254_timecounter = { 183 i8254_get_timecount, /* get_timecount */ 184 0, /* no poll_pps */ 185 ~0u, /* counter_mask */ 186 0, /* frequency */ 187 "i8254", /* name */ 188 0 /* quality */ 189}; 190 191static void 192clkintr(struct clockframe frame) 193{ 194 195 if (timecounter->tc_get_timecount == i8254_get_timecount) { 196 mtx_lock_spin(&clock_lock); 197 if (i8254_ticked) 198 i8254_ticked = 0; 199 else { 200 i8254_offset += timer0_max_count; 201 i8254_lastcount = 0; 202 } 203 clkintr_pending = 0; 204 mtx_unlock_spin(&clock_lock); 205 } 206 timer_func(&frame); 207#ifdef SMP 208 if (timer_func == hardclock) 209 forward_hardclock(); 210#endif 211#ifndef BURN_BRIDGES 212 switch (timer0_state) { 213 214 case RELEASED: 215 break; 216 217 case ACQUIRED: 218 if ((timer0_prescaler_count += timer0_max_count) 219 >= hardclock_max_count) { 220 timer0_prescaler_count -= hardclock_max_count; 221 hardclock(&frame); 222#ifdef SMP 223 forward_hardclock(); 224#endif 225 } 226 break; 227 228 case ACQUIRE_PENDING: 229 mtx_lock_spin(&clock_lock); 230 i8254_offset = i8254_get_timecount(NULL); 231 i8254_lastcount = 0; 232 timer0_max_count = TIMER_DIV(new_rate); 233 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 234 outb(TIMER_CNTR0, timer0_max_count & 0xff); 235 outb(TIMER_CNTR0, timer0_max_count >> 8); 236 mtx_unlock_spin(&clock_lock); 237 timer_func = new_function; 238 timer0_state = ACQUIRED; 239 break; 240 241 case RELEASE_PENDING: 242 if ((timer0_prescaler_count += timer0_max_count) 243 >= hardclock_max_count) { 244 mtx_lock_spin(&clock_lock); 245 i8254_offset = i8254_get_timecount(NULL); 246 i8254_lastcount = 0; 247 timer0_max_count = hardclock_max_count; 248 outb(TIMER_MODE, 249 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 250 outb(TIMER_CNTR0, timer0_max_count & 0xff); 251 outb(TIMER_CNTR0, timer0_max_count >> 8); 252 mtx_unlock_spin(&clock_lock); 253 timer0_prescaler_count = 0; 254 timer_func = hardclock; 255 timer0_state = RELEASED; 256 hardclock(&frame); 257#ifdef SMP 258 forward_hardclock(); 259#endif 260 } 261 break; 262 } 263#endif 264} 265 266#ifndef BURN_BRIDGES 267/* 268 * The acquire and release functions must be called at ipl >= splclock(). 269 */ 270int 271acquire_timer0(int rate, void (*function)(struct clockframe *frame)) 272{ 273 static int old_rate; 274 275 if (rate <= 0 || rate > TIMER0_MAX_FREQ) 276 return (-1); 277 switch (timer0_state) { 278 279 case RELEASED: 280 timer0_state = ACQUIRE_PENDING; 281 break; 282 283 case RELEASE_PENDING: 284 if (rate != old_rate) 285 return (-1); 286 /* 287 * The timer has been released recently, but is being 288 * re-acquired before the release completed. In this 289 * case, we simply reclaim it as if it had not been 290 * released at all. 291 */ 292 timer0_state = ACQUIRED; 293 break; 294 295 default: 296 return (-1); /* busy */ 297 } 298 new_function = function; 299 old_rate = new_rate = rate; 300 return (0); 301} 302#endif 303 304int 305acquire_timer1(int mode) 306{ 307 308 if (timer1_state != RELEASED) 309 return (-1); 310 timer1_state = ACQUIRED; 311 312 /* 313 * This access to the timer registers is as atomic as possible 314 * because it is a single instruction. We could do better if we 315 * knew the rate. Use of splclock() limits glitches to 10-100us, 316 * and this is probably good enough for timer2, so we aren't as 317 * careful with it as with timer0. 318 */ 319 outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f)); 320 321 return (0); 322} 323 324int 325acquire_timer2(int mode) 326{ 327 328 if (timer2_state != RELEASED) 329 return (-1); 330 timer2_state = ACQUIRED; 331 332 /* 333 * This access to the timer registers is as atomic as possible 334 * because it is a single instruction. We could do better if we 335 * knew the rate. Use of splclock() limits glitches to 10-100us, 336 * and this is probably good enough for timer2, so we aren't as 337 * careful with it as with timer0. 338 */ 339 outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f)); 340 341 return (0); 342} 343 344#ifndef BURN_BRIDGES 345int 346release_timer0() 347{ 348 switch (timer0_state) { 349 350 case ACQUIRED: 351 timer0_state = RELEASE_PENDING; 352 break; 353 354 case ACQUIRE_PENDING: 355 /* Nothing happened yet, release quickly. */ 356 timer0_state = RELEASED; 357 break; 358 359 default: 360 return (-1); 361 } 362 return (0); 363} 364#endif 365 366int 367release_timer1() 368{ 369 370 if (timer1_state != ACQUIRED) 371 return (-1); 372 timer1_state = RELEASED; 373 outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT); 374 return (0); 375} 376 377int 378release_timer2() 379{ 380 381 if (timer2_state != ACQUIRED) 382 return (-1); 383 timer2_state = RELEASED; 384 outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT); 385 return (0); 386} 387 388 389static int 390getit(void) 391{ 392 int high, low; 393 394 mtx_lock_spin(&clock_lock); 395 396 /* Select timer0 and latch counter value. */ 397 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 398 399 low = inb(TIMER_CNTR0); 400 high = inb(TIMER_CNTR0); 401 402 mtx_unlock_spin(&clock_lock); 403 return ((high << 8) | low); 404} 405 406/* 407 * Wait "n" microseconds. 408 * Relies on timer 1 counting down from (timer_freq / hz) 409 * Note: timer had better have been programmed before this is first used! 410 */ 411void 412DELAY(int n) 413{ 414 int delta, prev_tick, tick, ticks_left; 415 416#ifdef DELAYDEBUG 417 int getit_calls = 1; 418 int n1; 419 static int state = 0; 420 421 if (state == 0) { 422 state = 1; 423 for (n1 = 1; n1 <= 10000000; n1 *= 10) 424 DELAY(n1); 425 state = 2; 426 } 427 if (state == 1) 428 printf("DELAY(%d)...", n); 429#endif 430 /* 431 * Guard against the timer being uninitialized if we are called 432 * early for console i/o. 433 */ 434 if (timer0_max_count == 0) 435 set_timer_freq(timer_freq, hz); 436 437 /* 438 * Read the counter first, so that the rest of the setup overhead is 439 * counted. Guess the initial overhead is 20 usec (on most systems it 440 * takes about 1.5 usec for each of the i/o's in getit(). The loop 441 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 442 * multiplications and divisions to scale the count take a while). 443 * 444 * However, if ddb is active then use a fake counter since reading 445 * the i8254 counter involves acquiring a lock. ddb must not go 446 * locking for many reasons, but it calls here for at least atkbd 447 * input. 448 */ 449#ifdef DDB 450 if (db_active) 451 prev_tick = 0; 452 else 453#endif 454 prev_tick = getit(); 455 n -= 0; /* XXX actually guess no initial overhead */ 456 /* 457 * Calculate (n * (timer_freq / 1e6)) without using floating point 458 * and without any avoidable overflows. 459 */ 460 if (n <= 0) 461 ticks_left = 0; 462 else if (n < 256) 463 /* 464 * Use fixed point to avoid a slow division by 1000000. 465 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest. 466 * 2^15 is the first power of 2 that gives exact results 467 * for n between 0 and 256. 468 */ 469 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15; 470 else 471 /* 472 * Don't bother using fixed point, although gcc-2.7.2 473 * generates particularly poor code for the long long 474 * division, since even the slow way will complete long 475 * before the delay is up (unless we're interrupted). 476 */ 477 ticks_left = ((u_int)n * (long long)timer_freq + 999999) 478 / 1000000; 479 480 while (ticks_left > 0) { 481#ifdef DDB 482 if (db_active) { 483 outb(0x5f, 0); 484 tick = prev_tick + 1; 485 } else 486#endif 487 tick = getit(); 488#ifdef DELAYDEBUG 489 ++getit_calls; 490#endif 491 delta = prev_tick - tick; 492 prev_tick = tick; 493 if (delta < 0) { 494 delta += timer0_max_count; 495 /* 496 * Guard against timer0_max_count being wrong. 497 * This shouldn't happen in normal operation, 498 * but it may happen if set_timer_freq() is 499 * traced. 500 */ 501 if (delta < 0) 502 delta = 0; 503 } 504 ticks_left -= delta; 505 } 506#ifdef DELAYDEBUG 507 if (state == 1) 508 printf(" %d calls to getit() at %d usec each\n", 509 getit_calls, (n + 5) / getit_calls); 510#endif 511} 512 513static void 514sysbeepstop(void *chan) 515{ 516 outb(IO_PPI, inb(IO_PPI)|0x08); /* disable counter1 output to speaker */ 517 release_timer1(); 518 beeping = 0; 519} 520 521int 522sysbeep(int pitch, int period) 523{ 524 int x = splclock(); 525 526 if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT)) 527 if (!beeping) { 528 /* Something else owns it. */ 529 splx(x); 530 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 531 } 532 disable_intr(); 533 outb(0x3fdb, pitch); 534 outb(0x3fdb, (pitch>>8)); 535 enable_intr(); 536 if (!beeping) { 537 /* enable counter1 output to speaker */ 538 outb(IO_PPI, (inb(IO_PPI) & 0xf7)); 539 beeping = period; 540 timeout(sysbeepstop, (void *)NULL, period); 541 } 542 splx(x); 543 return (0); 544} 545 546 547unsigned int delaycount; 548#define FIRST_GUESS 0x2000 549static void findcpuspeed(void) 550{ 551 int i; 552 int remainder; 553 554 /* Put counter in count down mode */ 555 outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN); 556 outb(TIMER_CNTR0, 0xff); 557 outb(TIMER_CNTR0, 0xff); 558 for (i = FIRST_GUESS; i; i--) 559 ; 560 remainder = getit(); 561 delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff - remainder); 562} 563 564static u_int 565calibrate_clocks(void) 566{ 567 int timeout; 568 u_int count, prev_count, tot_count; 569 u_short sec, start_sec; 570 571 if (bootverbose) 572 printf("Calibrating clock(s) ... "); 573 /* Check ARTIC. */ 574 if (!(PC98_SYSTEM_PARAMETER(0x458) & 0x80) && 575 !(PC98_SYSTEM_PARAMETER(0x45b) & 0x04)) 576 goto fail; 577 timeout = 100000000; 578 579 /* Read the ARTIC. */ 580 sec = inw(0x5e); 581 582 /* Wait for the ARTIC to changes. */ 583 start_sec = sec; 584 for (;;) { 585 sec = inw(0x5e); 586 if (sec != start_sec) 587 break; 588 if (--timeout == 0) 589 goto fail; 590 } 591 prev_count = getit(); 592 if (prev_count == 0 || prev_count > timer0_max_count) 593 goto fail; 594 tot_count = 0; 595 596 start_sec = sec; 597 for (;;) { 598 sec = inw(0x5e); 599 count = getit(); 600 if (count == 0 || count > timer0_max_count) 601 goto fail; 602 if (count > prev_count) 603 tot_count += prev_count - (count - timer0_max_count); 604 else 605 tot_count += prev_count - count; 606 prev_count = count; 607 if ((sec == start_sec + 1200) || 608 (sec < start_sec && 609 (u_int)sec + 0x10000 == (u_int)start_sec + 1200)) 610 break; 611 if (--timeout == 0) 612 goto fail; 613 } 614 615 if (bootverbose) { 616 printf("i8254 clock: %u Hz\n", tot_count); 617 } 618 return (tot_count); 619 620fail: 621 if (bootverbose) 622 printf("failed, using default i8254 clock of %u Hz\n", 623 timer_freq); 624 return (timer_freq); 625} 626 627static void 628set_timer_freq(u_int freq, int intr_freq) 629{ 630 int new_timer0_max_count; 631 632 mtx_lock_spin(&clock_lock); 633 timer_freq = freq; 634 new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 635 if (new_timer0_max_count != timer0_max_count) { 636 timer0_max_count = new_timer0_max_count; 637 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 638 outb(TIMER_CNTR0, timer0_max_count & 0xff); 639 outb(TIMER_CNTR0, timer0_max_count >> 8); 640 } 641 mtx_unlock_spin(&clock_lock); 642} 643 644static void 645i8254_restore(void) 646{ 647 648 mtx_lock_spin(&clock_lock); 649 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 650 outb(TIMER_CNTR0, timer0_max_count & 0xff); 651 outb(TIMER_CNTR0, timer0_max_count >> 8); 652 mtx_unlock_spin(&clock_lock); 653} 654 655 656/* 657 * Restore all the timers non-atomically (XXX: should be atomically). 658 * 659 * This function is called from pmtimer_resume() to restore all the timers. 660 * This should not be necessary, but there are broken laptops that do not 661 * restore all the timers on resume. 662 */ 663void 664timer_restore(void) 665{ 666 667 i8254_restore(); /* restore timer_freq and hz */ 668} 669 670/* 671 * Initialize 8254 timer 0 early so that it can be used in DELAY(). 672 * XXX initialization of other timers is unintentionally left blank. 673 */ 674void 675startrtclock() 676{ 677 u_int delta, freq; 678 679 findcpuspeed(); 680 if (pc98_machine_type & M_8M) 681 timer_freq = 1996800L; /* 1.9968 MHz */ 682 else 683 timer_freq = 2457600L; /* 2.4576 MHz */ 684 685 set_timer_freq(timer_freq, hz); 686 freq = calibrate_clocks(); 687#ifdef CLK_CALIBRATION_LOOP 688 if (bootverbose) { 689 printf( 690 "Press a key on the console to abort clock calibration\n"); 691 while (cncheckc() == -1) 692 calibrate_clocks(); 693 } 694#endif 695 696 /* 697 * Use the calibrated i8254 frequency if it seems reasonable. 698 * Otherwise use the default, and don't use the calibrated i586 699 * frequency. 700 */ 701 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 702 if (delta < timer_freq / 100) { 703#ifndef CLK_USE_I8254_CALIBRATION 704 if (bootverbose) 705 printf( 706"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 707 freq = timer_freq; 708#endif 709 timer_freq = freq; 710 } else { 711 if (bootverbose) 712 printf( 713 "%d Hz differs from default of %d Hz by more than 1%%\n", 714 freq, timer_freq); 715 } 716 717 set_timer_freq(timer_freq, hz); 718 i8254_timecounter.tc_frequency = timer_freq; 719 tc_init(&i8254_timecounter); 720 721 init_TSC(); 722} 723 724static void 725rtc_serialcombit(int i) 726{ 727 outb(IO_RTC, ((i&0x01)<<5)|0x07); 728 DELAY(1); 729 outb(IO_RTC, ((i&0x01)<<5)|0x17); 730 DELAY(1); 731 outb(IO_RTC, ((i&0x01)<<5)|0x07); 732 DELAY(1); 733} 734 735static void 736rtc_serialcom(int i) 737{ 738 rtc_serialcombit(i&0x01); 739 rtc_serialcombit((i&0x02)>>1); 740 rtc_serialcombit((i&0x04)>>2); 741 rtc_serialcombit((i&0x08)>>3); 742 outb(IO_RTC, 0x07); 743 DELAY(1); 744 outb(IO_RTC, 0x0f); 745 DELAY(1); 746 outb(IO_RTC, 0x07); 747 DELAY(1); 748} 749 750static void 751rtc_outb(int val) 752{ 753 int s; 754 int sa = 0; 755 756 for (s=0;s<8;s++) { 757 sa = ((val >> s) & 0x01) ? 0x27 : 0x07; 758 outb(IO_RTC, sa); /* set DI & CLK 0 */ 759 DELAY(1); 760 outb(IO_RTC, sa | 0x10); /* CLK 1 */ 761 DELAY(1); 762 } 763 outb(IO_RTC, sa & 0xef); /* CLK 0 */ 764} 765 766static int 767rtc_inb(void) 768{ 769 int s; 770 int sa = 0; 771 772 for (s=0;s<8;s++) { 773 sa |= ((inb(0x33) & 0x01) << s); 774 outb(IO_RTC, 0x17); /* CLK 1 */ 775 DELAY(1); 776 outb(IO_RTC, 0x07); /* CLK 0 */ 777 DELAY(2); 778 } 779 return sa; 780} 781 782/* 783 * Initialize the time of day register, based on the time base which is, e.g. 784 * from a filesystem. 785 */ 786void 787inittodr(time_t base) 788{ 789 unsigned long sec, days; 790 int year, month; 791 int y, m, s; 792 struct timespec ts; 793 int second, min, hour; 794 795 if (base) { 796 s = splclock(); 797 ts.tv_sec = base; 798 ts.tv_nsec = 0; 799 tc_setclock(&ts); 800 splx(s); 801 } 802 803 rtc_serialcom(0x03); /* Time Read */ 804 rtc_serialcom(0x01); /* Register shift command. */ 805 DELAY(20); 806 807 second = bcd2bin(rtc_inb() & 0xff); /* sec */ 808 min = bcd2bin(rtc_inb() & 0xff); /* min */ 809 hour = bcd2bin(rtc_inb() & 0xff); /* hour */ 810 days = bcd2bin(rtc_inb() & 0xff) - 1; /* date */ 811 812 month = (rtc_inb() >> 4) & 0x0f; /* month */ 813 for (m = 1; m < month; m++) 814 days += daysinmonth[m-1]; 815 year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */ 816 /* 2000 year problem */ 817 if (year < 1995) 818 year += 100; 819 if (year < 1970) 820 goto wrong_time; 821 for (y = 1970; y < year; y++) 822 days += DAYSPERYEAR + LEAPYEAR(y); 823 if ((month > 2) && LEAPYEAR(year)) 824 days ++; 825 sec = ((( days * 24 + 826 hour) * 60 + 827 min) * 60 + 828 second); 829 /* sec now contains the number of seconds, since Jan 1 1970, 830 in the local time zone */ 831 832 s = splhigh(); 833 834 sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 835 836 y = time_second - sec; 837 if (y <= -2 || y >= 2) { 838 /* badly off, adjust it */ 839 ts.tv_sec = sec; 840 ts.tv_nsec = 0; 841 tc_setclock(&ts); 842 } 843 splx(s); 844 return; 845 846wrong_time: 847 printf("Invalid time in real time clock.\n"); 848 printf("Check and reset the date immediately!\n"); 849} 850 851/* 852 * Write system time back to RTC 853 */ 854void 855resettodr() 856{ 857 unsigned long tm; 858 int y, m, s; 859 int wd; 860 861 if (disable_rtc_set) 862 return; 863 864 s = splclock(); 865 tm = time_second; 866 splx(s); 867 868 rtc_serialcom(0x01); /* Register shift command. */ 869 870 /* Calculate local time to put in RTC */ 871 872 tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 873 874 rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 875 rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 876 rtc_outb(bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 877 878 /* We have now the days since 01-01-1970 in tm */ 879 wd = (tm + 4) % 7 + 1; /* Write back Weekday */ 880 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 881 tm >= m; 882 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 883 tm -= m; 884 885 /* Now we have the years in y and the day-of-the-year in tm */ 886 for (m = 0; ; m++) { 887 int ml; 888 889 ml = daysinmonth[m]; 890 if (m == 1 && LEAPYEAR(y)) 891 ml++; 892 if (tm < ml) 893 break; 894 tm -= ml; 895 } 896 897 m++; 898 rtc_outb(bin2bcd(tm+1)); /* Write back Day */ 899 rtc_outb((m << 4) | wd); /* Write back Month & Weekday */ 900 rtc_outb(bin2bcd(y%100)); /* Write back Year */ 901 902 rtc_serialcom(0x02); /* Time set & Counter hold command. */ 903 rtc_serialcom(0x00); /* Register hold command. */ 904} 905 906 907/* 908 * Start both clocks running. 909 */ 910void 911cpu_initclocks() 912{ 913#ifdef APIC_IO 914 int apic_8254_trial; 915 void *clkdesc; 916#endif /* APIC_IO */ 917 register_t crit; 918 919 920 /* Finish initializing 8253 timer 0. */ 921#ifdef APIC_IO 922 923 apic_8254_intr = isa_apic_irq(0); 924 apic_8254_trial = 0; 925 if (apic_8254_intr >= 0 ) { 926 if (apic_int_type(0, 0) == 3) 927 apic_8254_trial = 1; 928 } else { 929 /* look for ExtInt on pin 0 */ 930 if (apic_int_type(0, 0) == 3) { 931 apic_8254_intr = apic_irq(0, 0); 932 setup_8254_mixed_mode(); 933 } else 934 panic("APIC_IO: Cannot route 8254 interrupt to CPU"); 935 } 936 937 inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, 938 INTR_TYPE_CLK | INTR_FAST, &clkdesc); 939 crit = intr_disable(); 940 mtx_lock_spin(&icu_lock); 941 INTREN(1 << apic_8254_intr); 942 mtx_unlock_spin(&icu_lock); 943 intr_restore(crit); 944 945#else /* APIC_IO */ 946 947 /* 948 * XXX Check the priority of this interrupt handler. I 949 * couldn't find anything suitable in the BSD/OS code (grog, 950 * 19 July 2000). 951 */ 952 inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, 953 INTR_TYPE_CLK | INTR_FAST, NULL); 954 crit = intr_disable(); 955 mtx_lock_spin(&icu_lock); 956 INTREN(IRQ0); 957 mtx_unlock_spin(&icu_lock); 958 intr_restore(crit); 959 960#endif /* APIC_IO */ 961 962 963 964#ifdef APIC_IO 965 if (apic_8254_trial) { 966 967 printf("APIC_IO: Testing 8254 interrupt delivery\n"); 968 while (read_intr_count(8) < 6) 969 ; /* nothing */ 970 if (read_intr_count(apic_8254_intr) < 3) { 971 /* 972 * The MP table is broken. 973 * The 8254 was not connected to the specified pin 974 * on the IO APIC. 975 * Workaround: Limited variant of mixed mode. 976 */ 977 978 crit = intr_disable(); 979 mtx_lock_spin(&icu_lock); 980 INTRDIS(1 << apic_8254_intr); 981 mtx_unlock_spin(&icu_lock); 982 intr_restore(crit); 983 inthand_remove(clkdesc); 984 printf("APIC_IO: Broken MP table detected: " 985 "8254 is not connected to " 986 "IOAPIC #%d intpin %d\n", 987 int_to_apicintpin[apic_8254_intr].ioapic, 988 int_to_apicintpin[apic_8254_intr].int_pin); 989 /* 990 * Revoke current ISA IRQ 0 assignment and 991 * configure a fallback interrupt routing from 992 * the 8254 Timer via the 8259 PIC to the 993 * an ExtInt interrupt line on IOAPIC #0 intpin 0. 994 * We reuse the low level interrupt handler number. 995 */ 996 if (apic_irq(0, 0) < 0) { 997 revoke_apic_irq(apic_8254_intr); 998 assign_apic_irq(0, 0, apic_8254_intr); 999 } 1000 apic_8254_intr = apic_irq(0, 0); 1001 setup_8254_mixed_mode(); 1002 inthand_add("clk", apic_8254_intr, 1003 (driver_intr_t *)clkintr, NULL, 1004 INTR_TYPE_CLK | INTR_FAST, NULL); 1005 crit = intr_disable(); 1006 mtx_lock_spin(&icu_lock); 1007 INTREN(1 << apic_8254_intr); 1008 mtx_unlock_spin(&icu_lock); 1009 intr_restore(crit); 1010 } 1011 1012 } 1013 if (apic_int_type(0, 0) != 3 || 1014 int_to_apicintpin[apic_8254_intr].ioapic != 0 || 1015 int_to_apicintpin[apic_8254_intr].int_pin != 0) 1016 printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n", 1017 int_to_apicintpin[apic_8254_intr].ioapic, 1018 int_to_apicintpin[apic_8254_intr].int_pin); 1019 else 1020 printf("APIC_IO: " 1021 "routing 8254 via 8259 and IOAPIC #0 intpin 0\n"); 1022#endif 1023 1024 init_TSC_tc(); 1025} 1026 1027#ifdef APIC_IO 1028static u_long 1029read_intr_count(int vec) 1030{ 1031 u_long *up; 1032 up = intr_countp[vec]; 1033 if (up) 1034 return *up; 1035 return 0UL; 1036} 1037 1038static void 1039setup_8254_mixed_mode() 1040{ 1041 /* 1042 * Allow 8254 timer to INTerrupt 8259: 1043 * re-initialize master 8259: 1044 * reset; prog 4 bytes, single ICU, edge triggered 1045 */ 1046 outb(IO_ICU1, 0x13); 1047 outb(IO_ICU1 + 2, NRSVIDT); /* start vector (unused) */ 1048 outb(IO_ICU1 + 2, 0x00); /* ignore slave */ 1049 outb(IO_ICU1 + 2, 0x03); /* auto EOI, 8086 */ 1050 outb(IO_ICU1 + 2, 0xfe); /* unmask INT0 */ 1051 1052 /* program IO APIC for type 3 INT on INT0 */ 1053 if (ext_int_setup(0, 0) < 0) 1054 panic("8254 redirect via APIC pin0 impossible!"); 1055} 1056#endif 1057 1058void 1059cpu_startprofclock(void) 1060{ 1061} 1062 1063void 1064cpu_stopprofclock(void) 1065{ 1066} 1067 1068static int 1069sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS) 1070{ 1071 int error; 1072 u_int freq; 1073 1074 /* 1075 * Use `i8254' instead of `timer' in external names because `timer' 1076 * is is too generic. Should use it everywhere. 1077 */ 1078 freq = timer_freq; 1079 error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); 1080 if (error == 0 && req->newptr != NULL) { 1081#ifndef BURN_BRIDGES 1082 if (timer0_state != RELEASED) 1083 return (EBUSY); /* too much trouble to handle */ 1084#endif 1085 set_timer_freq(freq, hz); 1086 i8254_timecounter.tc_frequency = freq; 1087 } 1088 return (error); 1089} 1090 1091SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 1092 0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", ""); 1093 1094static unsigned 1095i8254_get_timecount(struct timecounter *tc) 1096{ 1097 u_int count; 1098 u_int high, low; 1099 u_int eflags; 1100 1101 eflags = read_eflags(); 1102 mtx_lock_spin(&clock_lock); 1103 1104 /* Select timer0 and latch counter value. */ 1105 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 1106 1107 low = inb(TIMER_CNTR0); 1108 high = inb(TIMER_CNTR0); 1109 count = timer0_max_count - ((high << 8) | low); 1110 if (count < i8254_lastcount || 1111 (!i8254_ticked && (clkintr_pending || 1112 ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) && 1113#ifdef APIC_IO 1114#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ 1115 /* XXX this assumes that apic_8254_intr is < 24. */ 1116 (lapic_irr1 & (1 << apic_8254_intr)))) 1117#else 1118 (inb(IO_ICU1) & 1))) 1119#endif 1120 )) { 1121 i8254_ticked = 1; 1122 i8254_offset += timer0_max_count; 1123 } 1124 i8254_lastcount = count; 1125 count += i8254_offset; 1126 mtx_unlock_spin(&clock_lock); 1127 return (count); 1128} 1129 1130#ifdef DEV_ISA 1131/* 1132 * Attach to the ISA PnP descriptors for the timer and realtime clock. 1133 */ 1134static struct isa_pnp_id attimer_ids[] = { 1135 { 0x0001d041 /* PNP0100 */, "AT timer" }, 1136 { 0x000bd041 /* PNP0B00 */, "AT realtime clock" }, 1137 { 0 } 1138}; 1139 1140static int 1141attimer_probe(device_t dev) 1142{ 1143 int result; 1144 1145 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0) 1146 device_quiet(dev); 1147 return(result); 1148} 1149 1150static int 1151attimer_attach(device_t dev) 1152{ 1153 return(0); 1154} 1155 1156static device_method_t attimer_methods[] = { 1157 /* Device interface */ 1158 DEVMETHOD(device_probe, attimer_probe), 1159 DEVMETHOD(device_attach, attimer_attach), 1160 DEVMETHOD(device_detach, bus_generic_detach), 1161 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1162 DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX stop statclock? */ 1163 DEVMETHOD(device_resume, bus_generic_resume), /* XXX restart statclock? */ 1164 { 0, 0 } 1165}; 1166 1167static driver_t attimer_driver = { 1168 "attimer", 1169 attimer_methods, 1170 1, /* no softc */ 1171}; 1172 1173static devclass_t attimer_devclass; 1174 1175DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0); 1176#endif /* DEV_ISA */ 1177