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