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
| 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.116 1998/03/14 03:11:50 tegge Exp $
| 37 * $Id: clock.c,v 1.117 1998/03/16 10:06:58 phk 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#include "opt_clock.h" 52#include "apm.h" 53 54#include <sys/param.h> 55#include <sys/systm.h> 56#include <sys/time.h> 57#include <sys/kernel.h> 58#ifndef SMP 59#include <sys/lock.h> 60#endif 61#include <sys/sysctl.h> 62 63#include <machine/clock.h> 64#ifdef CLK_CALIBRATION_LOOP 65#include <machine/cons.h> 66#endif 67#include <machine/cputypes.h> 68#include <machine/frame.h> 69#include <machine/ipl.h> 70#include <machine/limits.h> 71#include <machine/md_var.h> 72#if NAPM > 0 73#include <machine/apm_bios.h> 74#include <i386/apm/apm_setup.h> 75#endif 76#ifdef APIC_IO 77#include <machine/segments.h> 78#endif 79#if defined(SMP) || defined(APIC_IO) 80#include <machine/smp.h> 81#endif /* SMP || APIC_IO */ 82#include <machine/specialreg.h> 83 84#include <i386/isa/icu.h> 85#include <i386/isa/isa.h> 86#include <i386/isa/rtc.h> 87#include <i386/isa/timerreg.h> 88 89#include <sys/interrupt.h> 90 91#ifdef SMP 92#define disable_intr() CLOCK_DISABLE_INTR() 93#define enable_intr() CLOCK_ENABLE_INTR() 94 95#ifdef APIC_IO 96#include <i386/isa/intr_machdep.h> 97/* The interrupt triggered by the 8254 (timer) chip */ 98int apic_8254_intr; 99static u_long read_intr_count __P((int vec)); 100static void setup_8254_mixed_mode __P((void)); 101#endif 102#endif /* SMP */ 103 104/* 105 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 106 * can use a simple formula for leap years. 107 */ 108#define LEAPYEAR(y) ((u_int)(y) % 4 == 0) 109#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) 110 111#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x)) 112 113/* 114 * Time in timer cycles that it takes for microtime() to disable interrupts 115 * and latch the count. microtime() currently uses "cli; outb ..." so it 116 * normally takes less than 2 timer cycles. Add a few for cache misses. 117 * Add a few more to allow for latency in bogus calls to microtime() with 118 * interrupts already disabled. 119 */ 120#define TIMER0_LATCH_COUNT 20 121 122/* 123 * Maximum frequency that we are willing to allow for timer0. Must be 124 * low enough to guarantee that the timer interrupt handler returns 125 * before the next timer interrupt. 126 */ 127#define TIMER0_MAX_FREQ 20000 128 129int adjkerntz; /* local offset from GMT in seconds */ 130int disable_rtc_set; /* disable resettodr() if != 0 */ 131u_int idelayed; 132int statclock_disable; 133u_int stat_imask = SWI_CLOCK_MASK; 134#ifndef TIMER_FREQ 135#define TIMER_FREQ 1193182 136#endif 137u_int timer_freq = TIMER_FREQ; 138int timer0_max_count; 139u_int tsc_freq; 140int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 141 142static int beeping = 0; 143static u_int clk_imask = HWI_MASK | SWI_MASK; 144static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 145static u_int hardclock_max_count; 146static u_int32_t i8254_lastcount; 147static u_int32_t i8254_offset; 148static int i8254_ticked; 149/* 150 * XXX new_function and timer_func should not handle clockframes, but 151 * timer_func currently needs to hold hardclock to handle the 152 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 153 * to switch between clkintr() and a slightly different timerintr(). 154 */ 155static void (*new_function) __P((struct clockframe *frame)); 156static u_int new_rate; 157static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 158static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 159static u_int timer0_prescaler_count; 160 161/* Values for timerX_state: */ 162#define RELEASED 0 163#define RELEASE_PENDING 1 164#define ACQUIRED 2 165#define ACQUIRE_PENDING 3 166 167static u_char timer0_state; 168static u_char timer2_state; 169static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 170static u_int tsc_present; 171 172static u_int64_t i8254_get_timecount __P((void)); 173static void set_timer_freq(u_int freq, int intr_freq); 174static u_int64_t tsc_get_timecount __P((void)); 175static u_int32_t tsc_get_timedelta __P((struct timecounter *tc)); 176 177static struct timecounter tsc_timecounter[3] = { 178 tsc_get_timedelta, /* get_timedelta */ 179 tsc_get_timecount, /* get_timecount */ 180 ~0, /* counter_mask */ 181 0, /* frequency */ 182 "TSC" /* name */ 183}; 184 185SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD, 186 tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", ""); 187 188static struct timecounter i8254_timecounter[3] = { 189 0, /* get_timedelta */ 190 i8254_get_timecount, /* get_timecount */ 191 (1ULL << 32) - 1, /* counter_mask */ 192 0, /* frequency */ 193 "i8254" /* name */ 194}; 195 196SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 197 i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); 198 199static void 200clkintr(struct clockframe frame) 201{ 202 if (!i8254_ticked) 203 i8254_offset += timer0_max_count; 204 else 205 i8254_ticked = 0; 206 i8254_lastcount = 0; 207 timer_func(&frame); 208 switch (timer0_state) { 209 210 case RELEASED: 211 setdelayed(); 212 break; 213 214 case ACQUIRED: 215 if ((timer0_prescaler_count += timer0_max_count) 216 >= hardclock_max_count) { 217 timer0_prescaler_count -= hardclock_max_count; 218 hardclock(&frame); 219 setdelayed(); 220 } 221 break; 222 223 case ACQUIRE_PENDING: 224 setdelayed(); 225 timer0_max_count = TIMER_DIV(new_rate); 226 disable_intr(); 227 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 228 outb(TIMER_CNTR0, timer0_max_count & 0xff); 229 outb(TIMER_CNTR0, timer0_max_count >> 8); 230 enable_intr(); 231 timer0_prescaler_count = 0; 232 timer_func = new_function; 233 timer0_state = ACQUIRED; 234 break; 235 236 case RELEASE_PENDING: 237 if ((timer0_prescaler_count += timer0_max_count) 238 >= hardclock_max_count) { 239 timer0_prescaler_count -= hardclock_max_count;
| 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#include "opt_clock.h" 52#include "apm.h" 53 54#include <sys/param.h> 55#include <sys/systm.h> 56#include <sys/time.h> 57#include <sys/kernel.h> 58#ifndef SMP 59#include <sys/lock.h> 60#endif 61#include <sys/sysctl.h> 62 63#include <machine/clock.h> 64#ifdef CLK_CALIBRATION_LOOP 65#include <machine/cons.h> 66#endif 67#include <machine/cputypes.h> 68#include <machine/frame.h> 69#include <machine/ipl.h> 70#include <machine/limits.h> 71#include <machine/md_var.h> 72#if NAPM > 0 73#include <machine/apm_bios.h> 74#include <i386/apm/apm_setup.h> 75#endif 76#ifdef APIC_IO 77#include <machine/segments.h> 78#endif 79#if defined(SMP) || defined(APIC_IO) 80#include <machine/smp.h> 81#endif /* SMP || APIC_IO */ 82#include <machine/specialreg.h> 83 84#include <i386/isa/icu.h> 85#include <i386/isa/isa.h> 86#include <i386/isa/rtc.h> 87#include <i386/isa/timerreg.h> 88 89#include <sys/interrupt.h> 90 91#ifdef SMP 92#define disable_intr() CLOCK_DISABLE_INTR() 93#define enable_intr() CLOCK_ENABLE_INTR() 94 95#ifdef APIC_IO 96#include <i386/isa/intr_machdep.h> 97/* The interrupt triggered by the 8254 (timer) chip */ 98int apic_8254_intr; 99static u_long read_intr_count __P((int vec)); 100static void setup_8254_mixed_mode __P((void)); 101#endif 102#endif /* SMP */ 103 104/* 105 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we 106 * can use a simple formula for leap years. 107 */ 108#define LEAPYEAR(y) ((u_int)(y) % 4 == 0) 109#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) 110 111#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x)) 112 113/* 114 * Time in timer cycles that it takes for microtime() to disable interrupts 115 * and latch the count. microtime() currently uses "cli; outb ..." so it 116 * normally takes less than 2 timer cycles. Add a few for cache misses. 117 * Add a few more to allow for latency in bogus calls to microtime() with 118 * interrupts already disabled. 119 */ 120#define TIMER0_LATCH_COUNT 20 121 122/* 123 * Maximum frequency that we are willing to allow for timer0. Must be 124 * low enough to guarantee that the timer interrupt handler returns 125 * before the next timer interrupt. 126 */ 127#define TIMER0_MAX_FREQ 20000 128 129int adjkerntz; /* local offset from GMT in seconds */ 130int disable_rtc_set; /* disable resettodr() if != 0 */ 131u_int idelayed; 132int statclock_disable; 133u_int stat_imask = SWI_CLOCK_MASK; 134#ifndef TIMER_FREQ 135#define TIMER_FREQ 1193182 136#endif 137u_int timer_freq = TIMER_FREQ; 138int timer0_max_count; 139u_int tsc_freq; 140int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 141 142static int beeping = 0; 143static u_int clk_imask = HWI_MASK | SWI_MASK; 144static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 145static u_int hardclock_max_count; 146static u_int32_t i8254_lastcount; 147static u_int32_t i8254_offset; 148static int i8254_ticked; 149/* 150 * XXX new_function and timer_func should not handle clockframes, but 151 * timer_func currently needs to hold hardclock to handle the 152 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 153 * to switch between clkintr() and a slightly different timerintr(). 154 */ 155static void (*new_function) __P((struct clockframe *frame)); 156static u_int new_rate; 157static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 158static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 159static u_int timer0_prescaler_count; 160 161/* Values for timerX_state: */ 162#define RELEASED 0 163#define RELEASE_PENDING 1 164#define ACQUIRED 2 165#define ACQUIRE_PENDING 3 166 167static u_char timer0_state; 168static u_char timer2_state; 169static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 170static u_int tsc_present; 171 172static u_int64_t i8254_get_timecount __P((void)); 173static void set_timer_freq(u_int freq, int intr_freq); 174static u_int64_t tsc_get_timecount __P((void)); 175static u_int32_t tsc_get_timedelta __P((struct timecounter *tc)); 176 177static struct timecounter tsc_timecounter[3] = { 178 tsc_get_timedelta, /* get_timedelta */ 179 tsc_get_timecount, /* get_timecount */ 180 ~0, /* counter_mask */ 181 0, /* frequency */ 182 "TSC" /* name */ 183}; 184 185SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD, 186 tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", ""); 187 188static struct timecounter i8254_timecounter[3] = { 189 0, /* get_timedelta */ 190 i8254_get_timecount, /* get_timecount */ 191 (1ULL << 32) - 1, /* counter_mask */ 192 0, /* frequency */ 193 "i8254" /* name */ 194}; 195 196SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 197 i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); 198 199static void 200clkintr(struct clockframe frame) 201{ 202 if (!i8254_ticked) 203 i8254_offset += timer0_max_count; 204 else 205 i8254_ticked = 0; 206 i8254_lastcount = 0; 207 timer_func(&frame); 208 switch (timer0_state) { 209 210 case RELEASED: 211 setdelayed(); 212 break; 213 214 case ACQUIRED: 215 if ((timer0_prescaler_count += timer0_max_count) 216 >= hardclock_max_count) { 217 timer0_prescaler_count -= hardclock_max_count; 218 hardclock(&frame); 219 setdelayed(); 220 } 221 break; 222 223 case ACQUIRE_PENDING: 224 setdelayed(); 225 timer0_max_count = TIMER_DIV(new_rate); 226 disable_intr(); 227 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 228 outb(TIMER_CNTR0, timer0_max_count & 0xff); 229 outb(TIMER_CNTR0, timer0_max_count >> 8); 230 enable_intr(); 231 timer0_prescaler_count = 0; 232 timer_func = new_function; 233 timer0_state = ACQUIRED; 234 break; 235 236 case RELEASE_PENDING: 237 if ((timer0_prescaler_count += timer0_max_count) 238 >= hardclock_max_count) { 239 timer0_prescaler_count -= hardclock_max_count;
|
| 240#ifdef FIXME
|
240 /*
| 241 /*
|
| 242 * XXX: This magic doesn't work, but It shouldn't be 243 * needed now anyway since we will not be able to 244 * aquire the i8254 if it is used for timecounting. 245 */ 246 /*
|
241 * See microtime.s for this magic. 242 */ 243 time.tv_usec += (27465 * timer0_prescaler_count) >> 15; 244 if (time.tv_usec >= 1000000) 245 time.tv_usec -= 1000000;
| 247 * See microtime.s for this magic. 248 */ 249 time.tv_usec += (27465 * timer0_prescaler_count) >> 15; 250 if (time.tv_usec >= 1000000) 251 time.tv_usec -= 1000000;
|
| 252#endif
|
246 hardclock(&frame); 247 setdelayed(); 248 timer0_max_count = hardclock_max_count; 249 disable_intr(); 250 outb(TIMER_MODE, 251 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 252 outb(TIMER_CNTR0, timer0_max_count & 0xff); 253 outb(TIMER_CNTR0, timer0_max_count >> 8); 254 enable_intr(); 255 timer0_prescaler_count = 0; 256 timer_func = hardclock; 257 timer0_state = RELEASED; 258 } 259 break; 260 } 261} 262 263/* 264 * The acquire and release functions must be called at ipl >= splclock(). 265 */ 266int 267acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 268{ 269 static int old_rate; 270 271 if (rate <= 0 || rate > TIMER0_MAX_FREQ) 272 return (-1); 273 if (strcmp(timecounter->name, "i8254") == 0) 274 return (-1); 275 switch (timer0_state) { 276 277 case RELEASED: 278 timer0_state = ACQUIRE_PENDING; 279 break; 280 281 case RELEASE_PENDING: 282 if (rate != old_rate) 283 return (-1); 284 /* 285 * The timer has been released recently, but is being 286 * re-acquired before the release completed. In this 287 * case, we simply reclaim it as if it had not been 288 * released at all. 289 */ 290 timer0_state = ACQUIRED; 291 break; 292 293 default: 294 return (-1); /* busy */ 295 } 296 new_function = function; 297 old_rate = new_rate = rate; 298 return (0); 299} 300 301int 302acquire_timer2(int mode) 303{ 304 305 if (timer2_state != RELEASED) 306 return (-1); 307 timer2_state = ACQUIRED; 308 309 /* 310 * This access to the timer registers is as atomic as possible 311 * because it is a single instruction. We could do better if we 312 * knew the rate. Use of splclock() limits glitches to 10-100us, 313 * and this is probably good enough for timer2, so we aren't as 314 * careful with it as with timer0. 315 */ 316 outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f)); 317 318 return (0); 319} 320 321int 322release_timer0() 323{ 324 switch (timer0_state) { 325 326 case ACQUIRED: 327 timer0_state = RELEASE_PENDING; 328 break; 329 330 case ACQUIRE_PENDING: 331 /* Nothing happened yet, release quickly. */ 332 timer0_state = RELEASED; 333 break; 334 335 default: 336 return (-1); 337 } 338 return (0); 339} 340 341int 342release_timer2() 343{ 344 345 if (timer2_state != ACQUIRED) 346 return (-1); 347 timer2_state = RELEASED; 348 outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT); 349 return (0); 350} 351 352/* 353 * This routine receives statistical clock interrupts from the RTC. 354 * As explained above, these occur at 128 interrupts per second. 355 * When profiling, we receive interrupts at a rate of 1024 Hz. 356 * 357 * This does not actually add as much overhead as it sounds, because 358 * when the statistical clock is active, the hardclock driver no longer 359 * needs to keep (inaccurate) statistics on its own. This decouples 360 * statistics gathering from scheduling interrupts. 361 * 362 * The RTC chip requires that we read status register C (RTC_INTR) 363 * to acknowledge an interrupt, before it will generate the next one. 364 * Under high interrupt load, rtcintr() can be indefinitely delayed and 365 * the clock can tick immediately after the read from RTC_INTR. In this 366 * case, the mc146818A interrupt signal will not drop for long enough 367 * to register with the 8259 PIC. If an interrupt is missed, the stat 368 * clock will halt, considerably degrading system performance. This is 369 * why we use 'while' rather than a more straightforward 'if' below. 370 * Stat clock ticks can still be lost, causing minor loss of accuracy 371 * in the statistics, but the stat clock will no longer stop. 372 */ 373static void 374rtcintr(struct clockframe frame) 375{ 376 while (rtcin(RTC_INTR) & RTCIR_PERIOD) 377 statclock(&frame); 378} 379 380#include "opt_ddb.h" 381#ifdef DDB 382#include <ddb/ddb.h> 383 384DB_SHOW_COMMAND(rtc, rtc) 385{ 386 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n", 387 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY), 388 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC), 389 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 390} 391#endif /* DDB */ 392 393static int 394getit(void) 395{ 396 u_long ef; 397 int high, low; 398 399 ef = read_eflags(); 400 disable_intr(); 401 402 /* Select timer0 and latch counter value. */ 403 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 404 405 low = inb(TIMER_CNTR0); 406 high = inb(TIMER_CNTR0); 407 408 CLOCK_UNLOCK(); 409 write_eflags(ef); 410 return ((high << 8) | low); 411} 412 413/* 414 * Wait "n" microseconds. 415 * Relies on timer 1 counting down from (timer_freq / hz) 416 * Note: timer had better have been programmed before this is first used! 417 */ 418void 419DELAY(int n) 420{ 421 int delta, prev_tick, tick, ticks_left; 422 423#ifdef DELAYDEBUG 424 int getit_calls = 1; 425 int n1; 426 static int state = 0; 427 428 if (state == 0) { 429 state = 1; 430 for (n1 = 1; n1 <= 10000000; n1 *= 10) 431 DELAY(n1); 432 state = 2; 433 } 434 if (state == 1) 435 printf("DELAY(%d)...", n); 436#endif 437 /* 438 * Guard against the timer being uninitialized if we are called 439 * early for console i/o. 440 */ 441 if (timer0_max_count == 0) 442 set_timer_freq(timer_freq, hz); 443 444 /* 445 * Read the counter first, so that the rest of the setup overhead is 446 * counted. Guess the initial overhead is 20 usec (on most systems it 447 * takes about 1.5 usec for each of the i/o's in getit(). The loop 448 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 449 * multiplications and divisions to scale the count take a while). 450 */ 451 prev_tick = getit(); 452 n -= 0; /* XXX actually guess no initial overhead */ 453 /* 454 * Calculate (n * (timer_freq / 1e6)) without using floating point 455 * and without any avoidable overflows. 456 */ 457 if (n <= 0) 458 ticks_left = 0; 459 else if (n < 256) 460 /* 461 * Use fixed point to avoid a slow division by 1000000. 462 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest. 463 * 2^15 is the first power of 2 that gives exact results 464 * for n between 0 and 256. 465 */ 466 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15; 467 else 468 /* 469 * Don't bother using fixed point, although gcc-2.7.2 470 * generates particularly poor code for the long long 471 * division, since even the slow way will complete long 472 * before the delay is up (unless we're interrupted). 473 */ 474 ticks_left = ((u_int)n * (long long)timer_freq + 999999) 475 / 1000000; 476 477 while (ticks_left > 0) { 478 tick = getit(); 479#ifdef DELAYDEBUG 480 ++getit_calls; 481#endif 482 delta = prev_tick - tick; 483 prev_tick = tick; 484 if (delta < 0) { 485 delta += timer0_max_count; 486 /* 487 * Guard against timer0_max_count being wrong. 488 * This shouldn't happen in normal operation, 489 * but it may happen if set_timer_freq() is 490 * traced. 491 */ 492 if (delta < 0) 493 delta = 0; 494 } 495 ticks_left -= delta; 496 } 497#ifdef DELAYDEBUG 498 if (state == 1) 499 printf(" %d calls to getit() at %d usec each\n", 500 getit_calls, (n + 5) / getit_calls); 501#endif 502} 503 504static void 505sysbeepstop(void *chan) 506{ 507 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ 508 release_timer2(); 509 beeping = 0; 510} 511 512int 513sysbeep(int pitch, int period) 514{ 515 int x = splclock(); 516 517 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 518 if (!beeping) { 519 /* Something else owns it. */ 520 splx(x); 521 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 522 } 523 disable_intr(); 524 outb(TIMER_CNTR2, pitch); 525 outb(TIMER_CNTR2, (pitch>>8)); 526 enable_intr(); 527 if (!beeping) { 528 /* enable counter2 output to speaker */ 529 outb(IO_PPI, inb(IO_PPI) | 3); 530 beeping = period; 531 timeout(sysbeepstop, (void *)NULL, period); 532 } 533 splx(x); 534 return (0); 535} 536 537/* 538 * RTC support routines 539 */ 540 541int 542rtcin(reg) 543 int reg; 544{ 545 u_char val; 546 547 outb(IO_RTC, reg); 548 inb(0x84); 549 val = inb(IO_RTC + 1); 550 inb(0x84); 551 return (val); 552} 553 554static __inline void 555writertc(u_char reg, u_char val) 556{ 557 inb(0x84); 558 outb(IO_RTC, reg); 559 inb(0x84); 560 outb(IO_RTC + 1, val); 561 inb(0x84); /* XXX work around wrong order in rtcin() */ 562} 563 564static __inline int 565readrtc(int port) 566{ 567 return(bcd2bin(rtcin(port))); 568} 569 570static u_int 571calibrate_clocks(void) 572{ 573 u_int count, prev_count, tot_count; 574 int sec, start_sec, timeout; 575 576 if (bootverbose) 577 printf("Calibrating clock(s) ... "); 578 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 579 goto fail; 580 timeout = 100000000; 581 582 /* Read the mc146818A seconds counter. */ 583 for (;;) { 584 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 585 sec = rtcin(RTC_SEC); 586 break; 587 } 588 if (--timeout == 0) 589 goto fail; 590 } 591 592 /* Wait for the mC146818A seconds counter to change. */ 593 start_sec = sec; 594 for (;;) { 595 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 596 sec = rtcin(RTC_SEC); 597 if (sec != start_sec) 598 break; 599 } 600 if (--timeout == 0) 601 goto fail; 602 } 603 604 /* Start keeping track of the i8254 counter. */ 605 prev_count = getit(); 606 if (prev_count == 0 || prev_count > timer0_max_count) 607 goto fail; 608 tot_count = 0; 609 610 if (tsc_present) 611 wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ 612 613 /* 614 * Wait for the mc146818A seconds counter to change. Read the i8254 615 * counter for each iteration since this is convenient and only 616 * costs a few usec of inaccuracy. The timing of the final reads 617 * of the counters almost matches the timing of the initial reads, 618 * so the main cause of inaccuracy is the varying latency from 619 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the 620 * rtcin(RTC_SEC) that returns a changed seconds count. The 621 * maximum inaccuracy from this cause is < 10 usec on 486's. 622 */ 623 start_sec = sec; 624 for (;;) { 625 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) 626 sec = rtcin(RTC_SEC); 627 count = getit(); 628 if (count == 0 || count > timer0_max_count) 629 goto fail; 630 if (count > prev_count) 631 tot_count += prev_count - (count - timer0_max_count); 632 else 633 tot_count += prev_count - count; 634 prev_count = count; 635 if (sec != start_sec) 636 break; 637 if (--timeout == 0) 638 goto fail; 639 } 640 641 /* 642 * Read the cpu cycle counter. The timing considerations are 643 * similar to those for the i8254 clock. 644 */ 645 if (tsc_present) 646 tsc_freq = rdtsc(); 647 648 if (bootverbose) { 649 if (tsc_present) 650 printf("TSC clock: %u Hz, ", tsc_freq); 651 printf("i8254 clock: %u Hz\n", tot_count); 652 } 653 return (tot_count); 654 655fail: 656 if (bootverbose) 657 printf("failed, using default i8254 clock of %u Hz\n", 658 timer_freq); 659 return (timer_freq); 660} 661 662static void 663set_timer_freq(u_int freq, int intr_freq) 664{ 665 u_long ef; 666 int new_timer0_max_count; 667 668 ef = read_eflags(); 669 disable_intr(); 670 timer_freq = freq; 671 new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 672 if (new_timer0_max_count != timer0_max_count) { 673 timer0_max_count = new_timer0_max_count; 674 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 675 outb(TIMER_CNTR0, timer0_max_count & 0xff); 676 outb(TIMER_CNTR0, timer0_max_count >> 8); 677 } 678 CLOCK_UNLOCK(); 679 write_eflags(ef); 680} 681 682/* 683 * Initialize 8254 timer 0 early so that it can be used in DELAY(). 684 * XXX initialization of other timers is unintentionally left blank. 685 */ 686void 687startrtclock() 688{ 689 u_int delta, freq; 690 691 if (cpu_feature & CPUID_TSC) 692 tsc_present = 1; 693 else 694 tsc_present = 0; 695 696 writertc(RTC_STATUSA, rtc_statusa); 697 writertc(RTC_STATUSB, RTCSB_24HR); 698 699 set_timer_freq(timer_freq, hz); 700 freq = calibrate_clocks(); 701#ifdef CLK_CALIBRATION_LOOP 702 if (bootverbose) { 703 printf( 704 "Press a key on the console to abort clock calibration\n"); 705 while (cncheckc() == -1) 706 calibrate_clocks(); 707 } 708#endif 709 710 /* 711 * Use the calibrated i8254 frequency if it seems reasonable. 712 * Otherwise use the default, and don't use the calibrated i586 713 * frequency. 714 */ 715 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 716 if (delta < timer_freq / 100) { 717#ifndef CLK_USE_I8254_CALIBRATION 718 if (bootverbose) 719 printf( 720"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 721 freq = timer_freq; 722#endif 723 timer_freq = freq; 724 } else { 725 if (bootverbose) 726 printf( 727 "%d Hz differs from default of %d Hz by more than 1%%\n", 728 freq, timer_freq); 729 tsc_freq = 0; 730 } 731 732 set_timer_freq(timer_freq, hz); 733 i8254_timecounter[0].frequency = timer_freq; 734 init_timecounter(i8254_timecounter); 735 736#ifndef CLK_USE_TSC_CALIBRATION 737 if (tsc_freq != 0) { 738 if (bootverbose) 739 printf( 740"CLK_USE_TSC_CALIBRATION not specified - using old calibration method\n"); 741 tsc_freq = 0; 742 } 743#endif 744 if (tsc_present && tsc_freq == 0) { 745 /* 746 * Calibration of the i586 clock relative to the mc146818A 747 * clock failed. Do a less accurate calibration relative 748 * to the i8254 clock. 749 */ 750 wrmsr(0x10, 0LL); /* XXX */ 751 DELAY(1000000); 752 tsc_freq = rdtsc(); 753#ifdef CLK_USE_TSC_CALIBRATION 754 if (bootverbose) 755 printf("TSC clock: %u Hz (Method B)\n", tsc_freq); 756#endif 757 } 758 759#if !defined(SMP) 760 /* 761 * We can not use the TSC in SMP mode, until we figure out a 762 * cheap (impossible), reliable and precise (yeah right!) way 763 * to synchronize the TSCs of all the CPUs. 764 * Curse Intel for leaving the counter out of the I/O APIC. 765 */ 766 767#if NAPM > 0 768 /* 769 * We can not use the TSC if we found an APM bios. Too many 770 * of them lie about their ability&intention to fiddle the CPU 771 * clock for us to rely on this. Precise timekeeping on an 772 * APM'ed machine is at best a fools pursuit anyway, since 773 * any and all of the time spent in various SMM code can't 774 * be reliably accounted for. Reading the RTC is your only 775 * source of reliable time info. The i8254 looses too of course 776 * but we need to have some kind of time... 777 */ 778 if (apm_version != APMINI_CANTFIND) 779 return; 780#endif /* NAPM > 0 */ 781 782 if (tsc_present && tsc_freq != 0) { 783 tsc_timecounter[0].frequency = tsc_freq; 784 init_timecounter(tsc_timecounter); 785 } 786 787#endif /* !defined(SMP) */ 788} 789 790/* 791 * Initialize the time of day register, based on the time base which is, e.g. 792 * from a filesystem. 793 */ 794void 795inittodr(time_t base) 796{ 797 unsigned long sec, days; 798 int yd; 799 int year, month; 800 int y, m, s; 801 struct timespec ts; 802 803 if (base) { 804 s = splclock(); 805 ts.tv_sec = base; 806 ts.tv_nsec = 0; 807 set_timecounter(&ts); 808 splx(s); 809 } 810 811 /* Look if we have a RTC present and the time is valid */ 812 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 813 goto wrong_time; 814 815 /* wait for time update to complete */ 816 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 817 while (rtcin(RTC_STATUSA) & RTCSA_TUP); 818 819 days = 0; 820#ifdef USE_RTC_CENTURY 821 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 822#else 823 year = readrtc(RTC_YEAR) + 1900; 824 if (year < 1970) 825 year += 100; 826#endif 827 if (year < 1970) 828 goto wrong_time; 829 month = readrtc(RTC_MONTH); 830 for (m = 1; m < month; m++) 831 days += daysinmonth[m-1]; 832 if ((month > 2) && LEAPYEAR(year)) 833 days ++; 834 days += readrtc(RTC_DAY) - 1; 835 yd = days; 836 for (y = 1970; y < year; y++) 837 days += DAYSPERYEAR + LEAPYEAR(y); 838 sec = ((( days * 24 + 839 readrtc(RTC_HRS)) * 60 + 840 readrtc(RTC_MIN)) * 60 + 841 readrtc(RTC_SEC)); 842 /* sec now contains the number of seconds, since Jan 1 1970, 843 in the local time zone */ 844 845 sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 846
| 253 hardclock(&frame); 254 setdelayed(); 255 timer0_max_count = hardclock_max_count; 256 disable_intr(); 257 outb(TIMER_MODE, 258 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 259 outb(TIMER_CNTR0, timer0_max_count & 0xff); 260 outb(TIMER_CNTR0, timer0_max_count >> 8); 261 enable_intr(); 262 timer0_prescaler_count = 0; 263 timer_func = hardclock; 264 timer0_state = RELEASED; 265 } 266 break; 267 } 268} 269 270/* 271 * The acquire and release functions must be called at ipl >= splclock(). 272 */ 273int 274acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 275{ 276 static int old_rate; 277 278 if (rate <= 0 || rate > TIMER0_MAX_FREQ) 279 return (-1); 280 if (strcmp(timecounter->name, "i8254") == 0) 281 return (-1); 282 switch (timer0_state) { 283 284 case RELEASED: 285 timer0_state = ACQUIRE_PENDING; 286 break; 287 288 case RELEASE_PENDING: 289 if (rate != old_rate) 290 return (-1); 291 /* 292 * The timer has been released recently, but is being 293 * re-acquired before the release completed. In this 294 * case, we simply reclaim it as if it had not been 295 * released at all. 296 */ 297 timer0_state = ACQUIRED; 298 break; 299 300 default: 301 return (-1); /* busy */ 302 } 303 new_function = function; 304 old_rate = new_rate = rate; 305 return (0); 306} 307 308int 309acquire_timer2(int mode) 310{ 311 312 if (timer2_state != RELEASED) 313 return (-1); 314 timer2_state = ACQUIRED; 315 316 /* 317 * This access to the timer registers is as atomic as possible 318 * because it is a single instruction. We could do better if we 319 * knew the rate. Use of splclock() limits glitches to 10-100us, 320 * and this is probably good enough for timer2, so we aren't as 321 * careful with it as with timer0. 322 */ 323 outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f)); 324 325 return (0); 326} 327 328int 329release_timer0() 330{ 331 switch (timer0_state) { 332 333 case ACQUIRED: 334 timer0_state = RELEASE_PENDING; 335 break; 336 337 case ACQUIRE_PENDING: 338 /* Nothing happened yet, release quickly. */ 339 timer0_state = RELEASED; 340 break; 341 342 default: 343 return (-1); 344 } 345 return (0); 346} 347 348int 349release_timer2() 350{ 351 352 if (timer2_state != ACQUIRED) 353 return (-1); 354 timer2_state = RELEASED; 355 outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT); 356 return (0); 357} 358 359/* 360 * This routine receives statistical clock interrupts from the RTC. 361 * As explained above, these occur at 128 interrupts per second. 362 * When profiling, we receive interrupts at a rate of 1024 Hz. 363 * 364 * This does not actually add as much overhead as it sounds, because 365 * when the statistical clock is active, the hardclock driver no longer 366 * needs to keep (inaccurate) statistics on its own. This decouples 367 * statistics gathering from scheduling interrupts. 368 * 369 * The RTC chip requires that we read status register C (RTC_INTR) 370 * to acknowledge an interrupt, before it will generate the next one. 371 * Under high interrupt load, rtcintr() can be indefinitely delayed and 372 * the clock can tick immediately after the read from RTC_INTR. In this 373 * case, the mc146818A interrupt signal will not drop for long enough 374 * to register with the 8259 PIC. If an interrupt is missed, the stat 375 * clock will halt, considerably degrading system performance. This is 376 * why we use 'while' rather than a more straightforward 'if' below. 377 * Stat clock ticks can still be lost, causing minor loss of accuracy 378 * in the statistics, but the stat clock will no longer stop. 379 */ 380static void 381rtcintr(struct clockframe frame) 382{ 383 while (rtcin(RTC_INTR) & RTCIR_PERIOD) 384 statclock(&frame); 385} 386 387#include "opt_ddb.h" 388#ifdef DDB 389#include <ddb/ddb.h> 390 391DB_SHOW_COMMAND(rtc, rtc) 392{ 393 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n", 394 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY), 395 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC), 396 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 397} 398#endif /* DDB */ 399 400static int 401getit(void) 402{ 403 u_long ef; 404 int high, low; 405 406 ef = read_eflags(); 407 disable_intr(); 408 409 /* Select timer0 and latch counter value. */ 410 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 411 412 low = inb(TIMER_CNTR0); 413 high = inb(TIMER_CNTR0); 414 415 CLOCK_UNLOCK(); 416 write_eflags(ef); 417 return ((high << 8) | low); 418} 419 420/* 421 * Wait "n" microseconds. 422 * Relies on timer 1 counting down from (timer_freq / hz) 423 * Note: timer had better have been programmed before this is first used! 424 */ 425void 426DELAY(int n) 427{ 428 int delta, prev_tick, tick, ticks_left; 429 430#ifdef DELAYDEBUG 431 int getit_calls = 1; 432 int n1; 433 static int state = 0; 434 435 if (state == 0) { 436 state = 1; 437 for (n1 = 1; n1 <= 10000000; n1 *= 10) 438 DELAY(n1); 439 state = 2; 440 } 441 if (state == 1) 442 printf("DELAY(%d)...", n); 443#endif 444 /* 445 * Guard against the timer being uninitialized if we are called 446 * early for console i/o. 447 */ 448 if (timer0_max_count == 0) 449 set_timer_freq(timer_freq, hz); 450 451 /* 452 * Read the counter first, so that the rest of the setup overhead is 453 * counted. Guess the initial overhead is 20 usec (on most systems it 454 * takes about 1.5 usec for each of the i/o's in getit(). The loop 455 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 456 * multiplications and divisions to scale the count take a while). 457 */ 458 prev_tick = getit(); 459 n -= 0; /* XXX actually guess no initial overhead */ 460 /* 461 * Calculate (n * (timer_freq / 1e6)) without using floating point 462 * and without any avoidable overflows. 463 */ 464 if (n <= 0) 465 ticks_left = 0; 466 else if (n < 256) 467 /* 468 * Use fixed point to avoid a slow division by 1000000. 469 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest. 470 * 2^15 is the first power of 2 that gives exact results 471 * for n between 0 and 256. 472 */ 473 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15; 474 else 475 /* 476 * Don't bother using fixed point, although gcc-2.7.2 477 * generates particularly poor code for the long long 478 * division, since even the slow way will complete long 479 * before the delay is up (unless we're interrupted). 480 */ 481 ticks_left = ((u_int)n * (long long)timer_freq + 999999) 482 / 1000000; 483 484 while (ticks_left > 0) { 485 tick = getit(); 486#ifdef DELAYDEBUG 487 ++getit_calls; 488#endif 489 delta = prev_tick - tick; 490 prev_tick = tick; 491 if (delta < 0) { 492 delta += timer0_max_count; 493 /* 494 * Guard against timer0_max_count being wrong. 495 * This shouldn't happen in normal operation, 496 * but it may happen if set_timer_freq() is 497 * traced. 498 */ 499 if (delta < 0) 500 delta = 0; 501 } 502 ticks_left -= delta; 503 } 504#ifdef DELAYDEBUG 505 if (state == 1) 506 printf(" %d calls to getit() at %d usec each\n", 507 getit_calls, (n + 5) / getit_calls); 508#endif 509} 510 511static void 512sysbeepstop(void *chan) 513{ 514 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */ 515 release_timer2(); 516 beeping = 0; 517} 518 519int 520sysbeep(int pitch, int period) 521{ 522 int x = splclock(); 523 524 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 525 if (!beeping) { 526 /* Something else owns it. */ 527 splx(x); 528 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 529 } 530 disable_intr(); 531 outb(TIMER_CNTR2, pitch); 532 outb(TIMER_CNTR2, (pitch>>8)); 533 enable_intr(); 534 if (!beeping) { 535 /* enable counter2 output to speaker */ 536 outb(IO_PPI, inb(IO_PPI) | 3); 537 beeping = period; 538 timeout(sysbeepstop, (void *)NULL, period); 539 } 540 splx(x); 541 return (0); 542} 543 544/* 545 * RTC support routines 546 */ 547 548int 549rtcin(reg) 550 int reg; 551{ 552 u_char val; 553 554 outb(IO_RTC, reg); 555 inb(0x84); 556 val = inb(IO_RTC + 1); 557 inb(0x84); 558 return (val); 559} 560 561static __inline void 562writertc(u_char reg, u_char val) 563{ 564 inb(0x84); 565 outb(IO_RTC, reg); 566 inb(0x84); 567 outb(IO_RTC + 1, val); 568 inb(0x84); /* XXX work around wrong order in rtcin() */ 569} 570 571static __inline int 572readrtc(int port) 573{ 574 return(bcd2bin(rtcin(port))); 575} 576 577static u_int 578calibrate_clocks(void) 579{ 580 u_int count, prev_count, tot_count; 581 int sec, start_sec, timeout; 582 583 if (bootverbose) 584 printf("Calibrating clock(s) ... "); 585 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 586 goto fail; 587 timeout = 100000000; 588 589 /* Read the mc146818A seconds counter. */ 590 for (;;) { 591 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 592 sec = rtcin(RTC_SEC); 593 break; 594 } 595 if (--timeout == 0) 596 goto fail; 597 } 598 599 /* Wait for the mC146818A seconds counter to change. */ 600 start_sec = sec; 601 for (;;) { 602 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 603 sec = rtcin(RTC_SEC); 604 if (sec != start_sec) 605 break; 606 } 607 if (--timeout == 0) 608 goto fail; 609 } 610 611 /* Start keeping track of the i8254 counter. */ 612 prev_count = getit(); 613 if (prev_count == 0 || prev_count > timer0_max_count) 614 goto fail; 615 tot_count = 0; 616 617 if (tsc_present) 618 wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */ 619 620 /* 621 * Wait for the mc146818A seconds counter to change. Read the i8254 622 * counter for each iteration since this is convenient and only 623 * costs a few usec of inaccuracy. The timing of the final reads 624 * of the counters almost matches the timing of the initial reads, 625 * so the main cause of inaccuracy is the varying latency from 626 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the 627 * rtcin(RTC_SEC) that returns a changed seconds count. The 628 * maximum inaccuracy from this cause is < 10 usec on 486's. 629 */ 630 start_sec = sec; 631 for (;;) { 632 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) 633 sec = rtcin(RTC_SEC); 634 count = getit(); 635 if (count == 0 || count > timer0_max_count) 636 goto fail; 637 if (count > prev_count) 638 tot_count += prev_count - (count - timer0_max_count); 639 else 640 tot_count += prev_count - count; 641 prev_count = count; 642 if (sec != start_sec) 643 break; 644 if (--timeout == 0) 645 goto fail; 646 } 647 648 /* 649 * Read the cpu cycle counter. The timing considerations are 650 * similar to those for the i8254 clock. 651 */ 652 if (tsc_present) 653 tsc_freq = rdtsc(); 654 655 if (bootverbose) { 656 if (tsc_present) 657 printf("TSC clock: %u Hz, ", tsc_freq); 658 printf("i8254 clock: %u Hz\n", tot_count); 659 } 660 return (tot_count); 661 662fail: 663 if (bootverbose) 664 printf("failed, using default i8254 clock of %u Hz\n", 665 timer_freq); 666 return (timer_freq); 667} 668 669static void 670set_timer_freq(u_int freq, int intr_freq) 671{ 672 u_long ef; 673 int new_timer0_max_count; 674 675 ef = read_eflags(); 676 disable_intr(); 677 timer_freq = freq; 678 new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 679 if (new_timer0_max_count != timer0_max_count) { 680 timer0_max_count = new_timer0_max_count; 681 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 682 outb(TIMER_CNTR0, timer0_max_count & 0xff); 683 outb(TIMER_CNTR0, timer0_max_count >> 8); 684 } 685 CLOCK_UNLOCK(); 686 write_eflags(ef); 687} 688 689/* 690 * Initialize 8254 timer 0 early so that it can be used in DELAY(). 691 * XXX initialization of other timers is unintentionally left blank. 692 */ 693void 694startrtclock() 695{ 696 u_int delta, freq; 697 698 if (cpu_feature & CPUID_TSC) 699 tsc_present = 1; 700 else 701 tsc_present = 0; 702 703 writertc(RTC_STATUSA, rtc_statusa); 704 writertc(RTC_STATUSB, RTCSB_24HR); 705 706 set_timer_freq(timer_freq, hz); 707 freq = calibrate_clocks(); 708#ifdef CLK_CALIBRATION_LOOP 709 if (bootverbose) { 710 printf( 711 "Press a key on the console to abort clock calibration\n"); 712 while (cncheckc() == -1) 713 calibrate_clocks(); 714 } 715#endif 716 717 /* 718 * Use the calibrated i8254 frequency if it seems reasonable. 719 * Otherwise use the default, and don't use the calibrated i586 720 * frequency. 721 */ 722 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 723 if (delta < timer_freq / 100) { 724#ifndef CLK_USE_I8254_CALIBRATION 725 if (bootverbose) 726 printf( 727"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 728 freq = timer_freq; 729#endif 730 timer_freq = freq; 731 } else { 732 if (bootverbose) 733 printf( 734 "%d Hz differs from default of %d Hz by more than 1%%\n", 735 freq, timer_freq); 736 tsc_freq = 0; 737 } 738 739 set_timer_freq(timer_freq, hz); 740 i8254_timecounter[0].frequency = timer_freq; 741 init_timecounter(i8254_timecounter); 742 743#ifndef CLK_USE_TSC_CALIBRATION 744 if (tsc_freq != 0) { 745 if (bootverbose) 746 printf( 747"CLK_USE_TSC_CALIBRATION not specified - using old calibration method\n"); 748 tsc_freq = 0; 749 } 750#endif 751 if (tsc_present && tsc_freq == 0) { 752 /* 753 * Calibration of the i586 clock relative to the mc146818A 754 * clock failed. Do a less accurate calibration relative 755 * to the i8254 clock. 756 */ 757 wrmsr(0x10, 0LL); /* XXX */ 758 DELAY(1000000); 759 tsc_freq = rdtsc(); 760#ifdef CLK_USE_TSC_CALIBRATION 761 if (bootverbose) 762 printf("TSC clock: %u Hz (Method B)\n", tsc_freq); 763#endif 764 } 765 766#if !defined(SMP) 767 /* 768 * We can not use the TSC in SMP mode, until we figure out a 769 * cheap (impossible), reliable and precise (yeah right!) way 770 * to synchronize the TSCs of all the CPUs. 771 * Curse Intel for leaving the counter out of the I/O APIC. 772 */ 773 774#if NAPM > 0 775 /* 776 * We can not use the TSC if we found an APM bios. Too many 777 * of them lie about their ability&intention to fiddle the CPU 778 * clock for us to rely on this. Precise timekeeping on an 779 * APM'ed machine is at best a fools pursuit anyway, since 780 * any and all of the time spent in various SMM code can't 781 * be reliably accounted for. Reading the RTC is your only 782 * source of reliable time info. The i8254 looses too of course 783 * but we need to have some kind of time... 784 */ 785 if (apm_version != APMINI_CANTFIND) 786 return; 787#endif /* NAPM > 0 */ 788 789 if (tsc_present && tsc_freq != 0) { 790 tsc_timecounter[0].frequency = tsc_freq; 791 init_timecounter(tsc_timecounter); 792 } 793 794#endif /* !defined(SMP) */ 795} 796 797/* 798 * Initialize the time of day register, based on the time base which is, e.g. 799 * from a filesystem. 800 */ 801void 802inittodr(time_t base) 803{ 804 unsigned long sec, days; 805 int yd; 806 int year, month; 807 int y, m, s; 808 struct timespec ts; 809 810 if (base) { 811 s = splclock(); 812 ts.tv_sec = base; 813 ts.tv_nsec = 0; 814 set_timecounter(&ts); 815 splx(s); 816 } 817 818 /* Look if we have a RTC present and the time is valid */ 819 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 820 goto wrong_time; 821 822 /* wait for time update to complete */ 823 /* If RTCSA_TUP is zero, we have at least 244us before next update */ 824 while (rtcin(RTC_STATUSA) & RTCSA_TUP); 825 826 days = 0; 827#ifdef USE_RTC_CENTURY 828 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100; 829#else 830 year = readrtc(RTC_YEAR) + 1900; 831 if (year < 1970) 832 year += 100; 833#endif 834 if (year < 1970) 835 goto wrong_time; 836 month = readrtc(RTC_MONTH); 837 for (m = 1; m < month; m++) 838 days += daysinmonth[m-1]; 839 if ((month > 2) && LEAPYEAR(year)) 840 days ++; 841 days += readrtc(RTC_DAY) - 1; 842 yd = days; 843 for (y = 1970; y < year; y++) 844 days += DAYSPERYEAR + LEAPYEAR(y); 845 sec = ((( days * 24 + 846 readrtc(RTC_HRS)) * 60 + 847 readrtc(RTC_MIN)) * 60 + 848 readrtc(RTC_SEC)); 849 /* sec now contains the number of seconds, since Jan 1 1970, 850 in the local time zone */ 851 852 sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 853
|
847 y = time.tv_sec - sec;
| 854 y = time_second - sec;
|
848 if (y <= -2 || y >= 2) { 849 /* badly off, adjust it */ 850 s = splclock(); 851 ts.tv_sec = sec; 852 ts.tv_nsec = 0; 853 set_timecounter(&ts); 854 splx(s); 855 } 856 return; 857 858wrong_time: 859 printf("Invalid time in real time clock.\n"); 860 printf("Check and reset the date immediately!\n"); 861} 862 863/* 864 * Write system time back to RTC 865 */ 866void 867resettodr() 868{ 869 unsigned long tm; 870 int y, m, s; 871 872 if (disable_rtc_set) 873 return; 874 875 s = splclock();
| 855 if (y <= -2 || y >= 2) { 856 /* badly off, adjust it */ 857 s = splclock(); 858 ts.tv_sec = sec; 859 ts.tv_nsec = 0; 860 set_timecounter(&ts); 861 splx(s); 862 } 863 return; 864 865wrong_time: 866 printf("Invalid time in real time clock.\n"); 867 printf("Check and reset the date immediately!\n"); 868} 869 870/* 871 * Write system time back to RTC 872 */ 873void 874resettodr() 875{ 876 unsigned long tm; 877 int y, m, s; 878 879 if (disable_rtc_set) 880 return; 881 882 s = splclock();
|
876 tm = time.tv_sec;
| 883 tm = time_second;
|
877 splx(s); 878 879 /* Disable RTC updates and interrupts. */ 880 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 881 882 /* Calculate local time to put in RTC */ 883 884 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 885 886 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 887 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 888 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 889 890 /* We have now the days since 01-01-1970 in tm */ 891 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */ 892 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 893 tm >= m; 894 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 895 tm -= m; 896 897 /* Now we have the years in y and the day-of-the-year in tm */ 898 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */ 899#ifdef USE_RTC_CENTURY 900 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */ 901#endif 902 for (m = 0; ; m++) { 903 int ml; 904 905 ml = daysinmonth[m]; 906 if (m == 1 && LEAPYEAR(y)) 907 ml++; 908 if (tm < ml) 909 break; 910 tm -= ml; 911 } 912 913 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */ 914 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */ 915 916 /* Reenable RTC updates and interrupts. */ 917 writertc(RTC_STATUSB, rtc_statusb); 918} 919 920 921/* 922 * Start both clocks running. 923 */ 924void 925cpu_initclocks() 926{ 927 int diag; 928#ifdef APIC_IO 929 int apic_8254_trial; 930#endif /* APIC_IO */ 931 932 if (statclock_disable) { 933 /* 934 * The stat interrupt mask is different without the 935 * statistics clock. Also, don't set the interrupt 936 * flag which would normally cause the RTC to generate 937 * interrupts. 938 */ 939 stat_imask = HWI_MASK | SWI_MASK; 940 rtc_statusb = RTCSB_24HR; 941 } else { 942 /* Setting stathz to nonzero early helps avoid races. */ 943 stathz = RTC_NOPROFRATE; 944 profhz = RTC_PROFRATE; 945 } 946 947 /* Finish initializing 8253 timer 0. */ 948#ifdef APIC_IO 949 950 apic_8254_intr = isa_apic_pin(0); 951 apic_8254_trial = 0; 952 if (apic_8254_intr >= 0 ) { 953 if (apic_int_type(0, 0) == 3) 954 apic_8254_trial = 1; 955 } else { 956 /* look for ExtInt on pin 0 */ 957 if (apic_int_type(0, 0) == 3) { 958 apic_8254_intr = 0; 959 setup_8254_mixed_mode(); 960 } else 961 panic("APIC_IO: Cannot route 8254 interrupt to CPU"); 962 } 963 964 register_intr(/* irq */ apic_8254_intr, /* XXX id */ 0, /* flags */ 0, 965 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 966 /* unit */ 0); 967 INTREN(1 << apic_8254_intr); 968 969#else /* APIC_IO */ 970 971 register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, 972 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 973 /* unit */ 0); 974 INTREN(IRQ0); 975 976#endif /* APIC_IO */ 977 978 /* Initialize RTC. */ 979 writertc(RTC_STATUSA, rtc_statusa); 980 writertc(RTC_STATUSB, RTCSB_24HR); 981 982 /* Don't bother enabling the statistics clock. */ 983 if (statclock_disable) 984 return; 985 diag = rtcin(RTC_DIAG); 986 if (diag != 0) 987 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); 988 989#ifdef APIC_IO 990 if (isa_apic_pin(8) != 8) 991 panic("APIC RTC != 8"); 992#endif /* APIC_IO */ 993 994 register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, 995 /* XXX */ (inthand2_t *)rtcintr, &stat_imask, 996 /* unit */ 0); 997 998#ifdef APIC_IO 999 INTREN(APIC_IRQ8); 1000#else 1001 INTREN(IRQ8); 1002#endif /* APIC_IO */ 1003 1004 writertc(RTC_STATUSB, rtc_statusb); 1005 1006#ifdef APIC_IO 1007 if (apic_8254_trial) { 1008 1009 printf("APIC_IO: Testing 8254 interrupt delivery\n"); 1010 __asm __volatile("sti" : : : "memory"); 1011 while (read_intr_count(8) < 6) 1012 __asm __volatile("sti" : : : "memory"); 1013 if (read_intr_count(apic_8254_intr) < 3) { 1014 /* 1015 * The MP table is broken. 1016 * The 8254 was not connected to the specified pin 1017 * on the IO APIC. 1018 * Workaround: Limited variant of mixed mode. 1019 */ 1020 INTRDIS(1 << apic_8254_intr); 1021 unregister_intr(apic_8254_intr, 1022 /* XXX */ (inthand2_t *) clkintr); 1023 printf("APIC_IO: Broken MP table detected: " 1024 "8254 is not connected to IO APIC int pin %d\n", 1025 apic_8254_intr); 1026 1027 apic_8254_intr = 0; 1028 setup_8254_mixed_mode(); 1029 register_intr(/* irq */ apic_8254_intr, /* XXX id */ 0, /* flags */ 0, 1030 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 1031 /* unit */ 0); 1032 INTREN(1 << apic_8254_intr); 1033 } 1034 1035 } 1036 if (apic_8254_intr) 1037 printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr); 1038 else 1039 printf("APIC_IO: routing 8254 via 8259 on pin 0\n"); 1040#endif 1041 1042} 1043 1044#ifdef APIC_IO 1045static u_long 1046read_intr_count(int vec) 1047{ 1048 u_long *up; 1049 up = intr_countp[vec]; 1050 if (up) 1051 return *up; 1052 return 0UL; 1053} 1054 1055static void 1056setup_8254_mixed_mode() 1057{ 1058 /* 1059 * Allow 8254 timer to INTerrupt 8259: 1060 * re-initialize master 8259: 1061 * reset; prog 4 bytes, single ICU, edge triggered 1062 */ 1063 outb(IO_ICU1, 0x13); 1064 outb(IO_ICU1 + 1, NRSVIDT); /* start vector (unused) */ 1065 outb(IO_ICU1 + 1, 0x00); /* ignore slave */ 1066 outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ 1067 outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ 1068 1069 /* program IO APIC for type 3 INT on INT0 */ 1070 if (ext_int_setup(0, 0) < 0) 1071 panic("8254 redirect via APIC pin0 impossible!"); 1072} 1073#endif 1074 1075void 1076setstatclockrate(int newhz) 1077{ 1078 if (newhz == RTC_PROFRATE) 1079 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF; 1080 else 1081 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 1082 writertc(RTC_STATUSA, rtc_statusa); 1083} 1084 1085static int 1086sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS 1087{ 1088 int error; 1089 u_int freq; 1090 1091 /* 1092 * Use `i8254' instead of `timer' in external names because `timer' 1093 * is is too generic. Should use it everywhere. 1094 */ 1095 freq = timer_freq; 1096 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 1097 if (error == 0 && req->newptr != NULL) { 1098 if (timer0_state != RELEASED) 1099 return (EBUSY); /* too much trouble to handle */ 1100 set_timer_freq(freq, hz); 1101 i8254_timecounter[0].frequency = freq; 1102 } 1103 return (error); 1104} 1105 1106SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 1107 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); 1108 1109static int 1110sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS 1111{ 1112 int error; 1113 u_int freq; 1114 1115 if (!tsc_present) 1116 return (EOPNOTSUPP); 1117 freq = tsc_freq; 1118 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 1119 if (error == 0 && req->newptr != NULL) { 1120 tsc_freq = freq; 1121 tsc_timecounter[0].frequency = tsc_freq; 1122 } 1123 return (error); 1124} 1125 1126SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, 1127 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); 1128 1129static u_int64_t 1130i8254_get_timecount(void) 1131{ 1132 u_int32_t count; 1133 u_long ef; 1134 u_int high, low; 1135 1136 ef = read_eflags(); 1137 disable_intr(); 1138 1139 /* Select timer0 and latch counter value. */ 1140 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 1141 1142 low = inb(TIMER_CNTR0); 1143 high = inb(TIMER_CNTR0); 1144 1145 count = hardclock_max_count - ((high << 8) | low); 1146 if (count < i8254_lastcount) { 1147 i8254_ticked = 1; 1148 i8254_offset += hardclock_max_count; 1149 } 1150 1151 i8254_lastcount = count; 1152 count += i8254_offset; 1153 CLOCK_UNLOCK(); 1154 write_eflags(ef); 1155 return (count); 1156} 1157 1158static u_int64_t 1159tsc_get_timecount(void) 1160{ 1161 return ((u_int64_t)rdtsc()); 1162} 1163 1164static u_int32_t 1165tsc_get_timedelta(struct timecounter *tc) 1166{ 1167 return ((u_int64_t)rdtsc() - tc->offset_count); 1168}
| 884 splx(s); 885 886 /* Disable RTC updates and interrupts. */ 887 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 888 889 /* Calculate local time to put in RTC */ 890 891 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); 892 893 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */ 894 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */ 895 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */ 896 897 /* We have now the days since 01-01-1970 in tm */ 898 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */ 899 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); 900 tm >= m; 901 y++, m = DAYSPERYEAR + LEAPYEAR(y)) 902 tm -= m; 903 904 /* Now we have the years in y and the day-of-the-year in tm */ 905 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */ 906#ifdef USE_RTC_CENTURY 907 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */ 908#endif 909 for (m = 0; ; m++) { 910 int ml; 911 912 ml = daysinmonth[m]; 913 if (m == 1 && LEAPYEAR(y)) 914 ml++; 915 if (tm < ml) 916 break; 917 tm -= ml; 918 } 919 920 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */ 921 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */ 922 923 /* Reenable RTC updates and interrupts. */ 924 writertc(RTC_STATUSB, rtc_statusb); 925} 926 927 928/* 929 * Start both clocks running. 930 */ 931void 932cpu_initclocks() 933{ 934 int diag; 935#ifdef APIC_IO 936 int apic_8254_trial; 937#endif /* APIC_IO */ 938 939 if (statclock_disable) { 940 /* 941 * The stat interrupt mask is different without the 942 * statistics clock. Also, don't set the interrupt 943 * flag which would normally cause the RTC to generate 944 * interrupts. 945 */ 946 stat_imask = HWI_MASK | SWI_MASK; 947 rtc_statusb = RTCSB_24HR; 948 } else { 949 /* Setting stathz to nonzero early helps avoid races. */ 950 stathz = RTC_NOPROFRATE; 951 profhz = RTC_PROFRATE; 952 } 953 954 /* Finish initializing 8253 timer 0. */ 955#ifdef APIC_IO 956 957 apic_8254_intr = isa_apic_pin(0); 958 apic_8254_trial = 0; 959 if (apic_8254_intr >= 0 ) { 960 if (apic_int_type(0, 0) == 3) 961 apic_8254_trial = 1; 962 } else { 963 /* look for ExtInt on pin 0 */ 964 if (apic_int_type(0, 0) == 3) { 965 apic_8254_intr = 0; 966 setup_8254_mixed_mode(); 967 } else 968 panic("APIC_IO: Cannot route 8254 interrupt to CPU"); 969 } 970 971 register_intr(/* irq */ apic_8254_intr, /* XXX id */ 0, /* flags */ 0, 972 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 973 /* unit */ 0); 974 INTREN(1 << apic_8254_intr); 975 976#else /* APIC_IO */ 977 978 register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, 979 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 980 /* unit */ 0); 981 INTREN(IRQ0); 982 983#endif /* APIC_IO */ 984 985 /* Initialize RTC. */ 986 writertc(RTC_STATUSA, rtc_statusa); 987 writertc(RTC_STATUSB, RTCSB_24HR); 988 989 /* Don't bother enabling the statistics clock. */ 990 if (statclock_disable) 991 return; 992 diag = rtcin(RTC_DIAG); 993 if (diag != 0) 994 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); 995 996#ifdef APIC_IO 997 if (isa_apic_pin(8) != 8) 998 panic("APIC RTC != 8"); 999#endif /* APIC_IO */ 1000 1001 register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, 1002 /* XXX */ (inthand2_t *)rtcintr, &stat_imask, 1003 /* unit */ 0); 1004 1005#ifdef APIC_IO 1006 INTREN(APIC_IRQ8); 1007#else 1008 INTREN(IRQ8); 1009#endif /* APIC_IO */ 1010 1011 writertc(RTC_STATUSB, rtc_statusb); 1012 1013#ifdef APIC_IO 1014 if (apic_8254_trial) { 1015 1016 printf("APIC_IO: Testing 8254 interrupt delivery\n"); 1017 __asm __volatile("sti" : : : "memory"); 1018 while (read_intr_count(8) < 6) 1019 __asm __volatile("sti" : : : "memory"); 1020 if (read_intr_count(apic_8254_intr) < 3) { 1021 /* 1022 * The MP table is broken. 1023 * The 8254 was not connected to the specified pin 1024 * on the IO APIC. 1025 * Workaround: Limited variant of mixed mode. 1026 */ 1027 INTRDIS(1 << apic_8254_intr); 1028 unregister_intr(apic_8254_intr, 1029 /* XXX */ (inthand2_t *) clkintr); 1030 printf("APIC_IO: Broken MP table detected: " 1031 "8254 is not connected to IO APIC int pin %d\n", 1032 apic_8254_intr); 1033 1034 apic_8254_intr = 0; 1035 setup_8254_mixed_mode(); 1036 register_intr(/* irq */ apic_8254_intr, /* XXX id */ 0, /* flags */ 0, 1037 /* XXX */ (inthand2_t *)clkintr, &clk_imask, 1038 /* unit */ 0); 1039 INTREN(1 << apic_8254_intr); 1040 } 1041 1042 } 1043 if (apic_8254_intr) 1044 printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr); 1045 else 1046 printf("APIC_IO: routing 8254 via 8259 on pin 0\n"); 1047#endif 1048 1049} 1050 1051#ifdef APIC_IO 1052static u_long 1053read_intr_count(int vec) 1054{ 1055 u_long *up; 1056 up = intr_countp[vec]; 1057 if (up) 1058 return *up; 1059 return 0UL; 1060} 1061 1062static void 1063setup_8254_mixed_mode() 1064{ 1065 /* 1066 * Allow 8254 timer to INTerrupt 8259: 1067 * re-initialize master 8259: 1068 * reset; prog 4 bytes, single ICU, edge triggered 1069 */ 1070 outb(IO_ICU1, 0x13); 1071 outb(IO_ICU1 + 1, NRSVIDT); /* start vector (unused) */ 1072 outb(IO_ICU1 + 1, 0x00); /* ignore slave */ 1073 outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ 1074 outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ 1075 1076 /* program IO APIC for type 3 INT on INT0 */ 1077 if (ext_int_setup(0, 0) < 0) 1078 panic("8254 redirect via APIC pin0 impossible!"); 1079} 1080#endif 1081 1082void 1083setstatclockrate(int newhz) 1084{ 1085 if (newhz == RTC_PROFRATE) 1086 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF; 1087 else 1088 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 1089 writertc(RTC_STATUSA, rtc_statusa); 1090} 1091 1092static int 1093sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS 1094{ 1095 int error; 1096 u_int freq; 1097 1098 /* 1099 * Use `i8254' instead of `timer' in external names because `timer' 1100 * is is too generic. Should use it everywhere. 1101 */ 1102 freq = timer_freq; 1103 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 1104 if (error == 0 && req->newptr != NULL) { 1105 if (timer0_state != RELEASED) 1106 return (EBUSY); /* too much trouble to handle */ 1107 set_timer_freq(freq, hz); 1108 i8254_timecounter[0].frequency = freq; 1109 } 1110 return (error); 1111} 1112 1113SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 1114 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); 1115 1116static int 1117sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS 1118{ 1119 int error; 1120 u_int freq; 1121 1122 if (!tsc_present) 1123 return (EOPNOTSUPP); 1124 freq = tsc_freq; 1125 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 1126 if (error == 0 && req->newptr != NULL) { 1127 tsc_freq = freq; 1128 tsc_timecounter[0].frequency = tsc_freq; 1129 } 1130 return (error); 1131} 1132 1133SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW, 1134 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", ""); 1135 1136static u_int64_t 1137i8254_get_timecount(void) 1138{ 1139 u_int32_t count; 1140 u_long ef; 1141 u_int high, low; 1142 1143 ef = read_eflags(); 1144 disable_intr(); 1145 1146 /* Select timer0 and latch counter value. */ 1147 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 1148 1149 low = inb(TIMER_CNTR0); 1150 high = inb(TIMER_CNTR0); 1151 1152 count = hardclock_max_count - ((high << 8) | low); 1153 if (count < i8254_lastcount) { 1154 i8254_ticked = 1; 1155 i8254_offset += hardclock_max_count; 1156 } 1157 1158 i8254_lastcount = count; 1159 count += i8254_offset; 1160 CLOCK_UNLOCK(); 1161 write_eflags(ef); 1162 return (count); 1163} 1164 1165static u_int64_t 1166tsc_get_timecount(void) 1167{ 1168 return ((u_int64_t)rdtsc()); 1169} 1170 1171static u_int32_t 1172tsc_get_timedelta(struct timecounter *tc) 1173{ 1174 return ((u_int64_t)rdtsc() - tc->offset_count); 1175}
|