pcrtc.c (16359) | pcrtc.c (17256) |
---|---|
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 --- 20 unchanged lines hidden (view full) --- 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 --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 |
37 * $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $ | 37 * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami 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 * modified for PC98 | 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 * modified for PC98 |
49 * $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $ | 49 * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ |
50 */ 51 52/* 53 * Primitive clock interrupt routines. 54 */ 55#include "opt_ddb.h" | 50 */ 51 52/* 53 * Primitive clock interrupt routines. 54 */ 55#include "opt_ddb.h" |
56#include "opt_clock.h" |
|
56 57#include <sys/param.h> 58#include <sys/systm.h> 59#include <sys/time.h> 60#include <sys/kernel.h> 61#include <sys/sysctl.h> 62 63#include <machine/clock.h> --- 31 unchanged lines hidden (view full) --- 95 * and latch the count. microtime() currently uses "cli; outb ..." so it 96 * normally takes less than 2 timer cycles. Add a few for cache misses. 97 * Add a few more to allow for latency in bogus calls to microtime() with 98 * interrupts already disabled. 99 */ 100#define TIMER0_LATCH_COUNT 20 101 102/* | 57 58#include <sys/param.h> 59#include <sys/systm.h> 60#include <sys/time.h> 61#include <sys/kernel.h> 62#include <sys/sysctl.h> 63 64#include <machine/clock.h> --- 31 unchanged lines hidden (view full) --- 96 * and latch the count. microtime() currently uses "cli; outb ..." so it 97 * normally takes less than 2 timer cycles. Add a few for cache misses. 98 * Add a few more to allow for latency in bogus calls to microtime() with 99 * interrupts already disabled. 100 */ 101#define TIMER0_LATCH_COUNT 20 102 103/* |
103 * Minimum maximum count that we are willing to program into timer0. 104 * Must be large enough to guarantee that the timer interrupt handler 105 * returns before the next timer interrupt. Must be larger than 106 * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in 107 * the calculation of timer0_overflow_threshold. | 104 * Maximum frequency that we are willing to allow for timer0. Must be 105 * low enough to guarantee that the timer interrupt handler returns 106 * before the next timer interrupt. Must result in a lower TIMER_DIV 107 * value than TIMER0_LATCH_COUNT so that we don't have to worry about 108 * underflow in the calculation of timer0_overflow_threshold. |
108 */ | 109 */ |
109#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000) | 110#define TIMER0_MAX_FREQ 20000 |
110 111int adjkerntz; /* local offset from GMT in seconds */ 112int disable_rtc_set; /* disable resettodr() if != 0 */ 113int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 114 115u_int idelayed; 116#if defined(I586_CPU) || defined(I686_CPU) 117unsigned i586_ctr_freq; 118unsigned i586_ctr_rate; 119long long i586_ctr_bias; 120long long i586_last_tick; 121unsigned long i586_avg_tick; 122#endif 123int statclock_disable; 124u_int stat_imask = SWI_CLOCK_MASK; | 111 112int adjkerntz; /* local offset from GMT in seconds */ 113int disable_rtc_set; /* disable resettodr() if != 0 */ 114int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ 115 116u_int idelayed; 117#if defined(I586_CPU) || defined(I686_CPU) 118unsigned i586_ctr_freq; 119unsigned i586_ctr_rate; 120long long i586_ctr_bias; 121long long i586_last_tick; 122unsigned long i586_avg_tick; 123#endif 124int statclock_disable; 125u_int stat_imask = SWI_CLOCK_MASK; |
126#ifdef TIMER_FREQ 127static u_int timer_freq = TIMER_FREQ; 128#else 129#ifdef PC98 130#ifndef AUTO_CLOCK 131#ifndef PC98_8M 132static u_int timer_freq = 2457600; 133#else /* !PC98_8M */ 134static u_int timer_freq = 1996800; 135#endif /* PC98_8M */ 136#else /* AUTO_CLOCK */ 137static u_int timer_freq = 2457600; 138#endif /* AUTO_CLOCK */ 139#else /* IBM-PC */ 140static u_int timer_freq = 1193182; 141#endif /* PC98 */ 142#endif |
|
125int timer0_max_count; 126u_int timer0_overflow_threshold; 127u_int timer0_prescaler_count; 128 129static int beeping = 0; 130static u_int clk_imask = HWI_MASK | SWI_MASK; 131static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 132static u_int hardclock_max_count; 133/* 134 * XXX new_function and timer_func should not handle clockframes, but 135 * timer_func currently needs to hold hardclock to handle the 136 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 137 * to switch between clkintr() and a slightly different timerintr(). | 143int timer0_max_count; 144u_int timer0_overflow_threshold; 145u_int timer0_prescaler_count; 146 147static int beeping = 0; 148static u_int clk_imask = HWI_MASK | SWI_MASK; 149static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 150static u_int hardclock_max_count; 151/* 152 * XXX new_function and timer_func should not handle clockframes, but 153 * timer_func currently needs to hold hardclock to handle the 154 * timer0_state == 0 case. We should use register_intr()/unregister_intr() 155 * to switch between clkintr() and a slightly different timerintr(). |
138 * This will require locking when acquiring and releasing timer0 - the 139 * current (nonexistent) locking doesn't seem to be adequate even now. | |
140 */ 141static void (*new_function) __P((struct clockframe *frame)); 142static u_int new_rate; 143#ifndef PC98 144static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 145static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 146#endif | 156 */ 157static void (*new_function) __P((struct clockframe *frame)); 158static u_int new_rate; 159#ifndef PC98 160static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 161static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR; 162#endif |
147#ifdef TIMER_FREQ 148static u_int timer_freq = TIMER_FREQ; 149#else 150#ifdef PC98 151#ifndef AUTO_CLOCK 152#ifndef PC98_8M 153static u_int timer_freq = 2457600; 154#else /* !PC98_8M */ 155static u_int timer_freq = 1996800; 156#endif /* PC98_8M */ 157#else /* AUTO_CLOCK */ 158static u_int timer_freq = 2457600; 159#endif /* AUTO_CLOCK */ 160#else /* IBM-PC */ 161static u_int timer_freq = 1193182; 162#endif /* PC98 */ 163#endif 164static char timer0_state = 0; | 163 164/* Values for timerX_state: */ 165#define RELEASED 0 166#define RELEASE_PENDING 1 167#define ACQUIRED 2 168#define ACQUIRE_PENDING 3 169 170static u_char timer0_state; |
165#ifdef PC98 | 171#ifdef PC98 |
166static char timer1_state = 0; | 172static u_char timer1_state; |
167#endif | 173#endif |
168static char timer2_state = 0; | 174static u_char timer2_state; |
169static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 170int rtc_inb __P((void)); 171 | 175static void (*timer_func) __P((struct clockframe *frame)) = hardclock; 176int rtc_inb __P((void)); 177 |
172#if 0 173void 174clkintr(struct clockframe frame) 175{ 176 hardclock(&frame); 177 setdelayed(); 178} 179#else | |
180static void 181clkintr(struct clockframe frame) 182{ 183 timer_func(&frame); 184 switch (timer0_state) { | 178static void 179clkintr(struct clockframe frame) 180{ 181 timer_func(&frame); 182 switch (timer0_state) { |
185 case 0: | 183 184 case RELEASED: |
186 setdelayed(); 187 break; | 185 setdelayed(); 186 break; |
188 case 1: | 187 188 case ACQUIRED: |
189 if ((timer0_prescaler_count += timer0_max_count) 190 >= hardclock_max_count) { 191 hardclock(&frame); 192 setdelayed(); 193 timer0_prescaler_count -= hardclock_max_count; 194 } 195 break; | 189 if ((timer0_prescaler_count += timer0_max_count) 190 >= hardclock_max_count) { 191 hardclock(&frame); 192 setdelayed(); 193 timer0_prescaler_count -= hardclock_max_count; 194 } 195 break; |
196 case 2: | 196 197 case ACQUIRE_PENDING: |
197 setdelayed(); 198 timer0_max_count = TIMER_DIV(new_rate); 199 timer0_overflow_threshold = 200 timer0_max_count - TIMER0_LATCH_COUNT; 201 disable_intr(); 202 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 203 outb(TIMER_CNTR0, timer0_max_count & 0xff); 204 outb(TIMER_CNTR0, timer0_max_count >> 8); 205 enable_intr(); 206 timer0_prescaler_count = 0; 207 timer_func = new_function; | 198 setdelayed(); 199 timer0_max_count = TIMER_DIV(new_rate); 200 timer0_overflow_threshold = 201 timer0_max_count - TIMER0_LATCH_COUNT; 202 disable_intr(); 203 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 204 outb(TIMER_CNTR0, timer0_max_count & 0xff); 205 outb(TIMER_CNTR0, timer0_max_count >> 8); 206 enable_intr(); 207 timer0_prescaler_count = 0; 208 timer_func = new_function; |
208 timer0_state = 1; | 209 timer0_state = ACQUIRED; |
209 break; | 210 break; |
210 case 3: | 211 212 case RELEASE_PENDING: |
211 if ((timer0_prescaler_count += timer0_max_count) 212 >= hardclock_max_count) { 213 hardclock(&frame); 214 setdelayed(); 215 timer0_max_count = hardclock_max_count; 216 timer0_overflow_threshold = 217 timer0_max_count - TIMER0_LATCH_COUNT; 218 disable_intr(); --- 24 unchanged lines hidden (view full) --- 243 hardclock_max_count)) >> 15; 244 } else { 245 time.tv_usec += (6667 * 246 (timer0_prescaler_count - 247 hardclock_max_count)) >> 14; 248 } 249#endif /* AUTO_CLOCK */ 250#else /* IBM-PC */ | 213 if ((timer0_prescaler_count += timer0_max_count) 214 >= hardclock_max_count) { 215 hardclock(&frame); 216 setdelayed(); 217 timer0_max_count = hardclock_max_count; 218 timer0_overflow_threshold = 219 timer0_max_count - TIMER0_LATCH_COUNT; 220 disable_intr(); --- 24 unchanged lines hidden (view full) --- 245 hardclock_max_count)) >> 15; 246 } else { 247 time.tv_usec += (6667 * 248 (timer0_prescaler_count - 249 hardclock_max_count)) >> 14; 250 } 251#endif /* AUTO_CLOCK */ 252#else /* IBM-PC */ |
251 time.tv_usec += (27645 * | 253 time.tv_usec += (27465 * |
252 (timer0_prescaler_count - hardclock_max_count)) 253 >> 15; 254#endif /* PC98 */ 255 if (time.tv_usec >= 1000000) 256 time.tv_usec -= 1000000; 257 timer0_prescaler_count = 0; | 254 (timer0_prescaler_count - hardclock_max_count)) 255 >> 15; 256#endif /* PC98 */ 257 if (time.tv_usec >= 1000000) 258 time.tv_usec -= 1000000; 259 timer0_prescaler_count = 0; |
258 timer_func = hardclock;; 259 timer0_state = 0; | 260 timer_func = hardclock; 261 timer0_state = RELEASED; |
260 } 261 break; 262 } 263} | 262 } 263 break; 264 } 265} |
264#endif | |
265 | 266 |
267/* 268 * The acquire and release functions must be called at ipl >= splclock(). 269 */ |
|
266int 267acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 268{ | 270int 271acquire_timer0(int rate, void (*function) __P((struct clockframe *frame))) 272{ |
269 if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT || 270 !function) 271 return -1; | 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 } |
272 new_function = function; | 298 new_function = function; |
273 new_rate = rate; 274 timer0_state = 2; 275 return 0; | 299 old_rate = new_rate = rate; 300 return (0); |
276} 277 278#ifdef PC98 279int 280acquire_timer1(int mode) 281{ | 301} 302 303#ifdef PC98 304int 305acquire_timer1(int mode) 306{ |
282 if (timer1_state) 283 return -1; 284 timer1_state = 1; 285 outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f)); 286 return 0; | 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); |
287} 288#endif 289 290int 291acquire_timer2(int mode) 292{ | 322} 323#endif 324 325int 326acquire_timer2(int mode) 327{ |
293 if (timer2_state) 294 return -1; 295 timer2_state = 1; 296 outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f)); 297 return 0; | 328 329 if (timer2_state != RELEASED) 330 return (-1); 331 timer2_state = ACQUIRED; 332 333 /* 334 * This access to the timer registers is as atomic as possible 335 * because it is a single instruction. We could do better if we 336 * knew the rate. Use of splclock() limits glitches to 10-100us, 337 * and this is probably good enough for timer2, so we aren't as 338 * careful with it as with timer0. 339 */ 340 outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f)); 341 342 return (0); |
298} 299 300int 301release_timer0() 302{ | 343} 344 345int 346release_timer0() 347{ |
303 if (!timer0_state) 304 return -1; 305 timer0_state = 3; 306 return 0; | 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); |
307} 308 309#ifdef PC98 310int 311release_timer1() 312{ | 363} 364 365#ifdef PC98 366int 367release_timer1() 368{ |
313 if (!timer1_state) 314 return -1; 315 timer1_state = 0; 316 outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT); 317 return 0; | 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); |
318} 319#endif 320 321int 322release_timer2() 323{ | 375} 376#endif 377 378int 379release_timer2() 380{ |
324 if (!timer2_state) 325 return -1; 326 timer2_state = 0; 327 outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT); 328 return 0; | 381 382 if (timer2_state != ACQUIRED) 383 return (-1); 384 timer2_state = RELEASED; 385 outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT); 386 return (0); |
329} 330 331#ifndef PC98 332/* 333 * This routine receives statistical clock interrupts from the RTC. 334 * As explained above, these occur at 128 interrupts per second. 335 * When profiling, we receive interrupts at a rate of 1024 Hz. 336 * --- 25 unchanged lines hidden (view full) --- 362 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 363} 364#endif 365#endif /* for PC98 */ 366 367static int 368getit(void) 369{ | 387} 388 389#ifndef PC98 390/* 391 * This routine receives statistical clock interrupts from the RTC. 392 * As explained above, these occur at 128 interrupts per second. 393 * When profiling, we receive interrupts at a rate of 1024 Hz. 394 * --- 25 unchanged lines hidden (view full) --- 420 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); 421} 422#endif 423#endif /* for PC98 */ 424 425static int 426getit(void) 427{ |
428 u_long ef; |
|
370 int high, low; 371 | 429 int high, low; 430 |
431 ef = read_eflags(); |
|
372 disable_intr(); | 432 disable_intr(); |
373 /* select timer0 and latch counter value */ | 433 434 /* Select timer0 and latch counter value. */ |
374 outb(TIMER_MODE, TIMER_SEL0); | 435 outb(TIMER_MODE, TIMER_SEL0); |
436 |
|
375 low = inb(TIMER_CNTR0); 376 high = inb(TIMER_CNTR0); | 437 low = inb(TIMER_CNTR0); 438 high = inb(TIMER_CNTR0); |
377 enable_intr(); | 439 440 write_eflags(ef); |
378 return ((high << 8) | low); 379} 380 381/* 382 * Wait "n" microseconds. 383 * Relies on timer 1 counting down from (timer_freq / hz) 384 * Note: timer had better have been programmed before this is first used! 385 */ --- 68 unchanged lines hidden (view full) --- 454 release_timer2(); 455#endif 456 beeping = 0; 457} 458 459int 460sysbeep(int pitch, int period) 461{ | 441 return ((high << 8) | low); 442} 443 444/* 445 * Wait "n" microseconds. 446 * Relies on timer 1 counting down from (timer_freq / hz) 447 * Note: timer had better have been programmed before this is first used! 448 */ --- 68 unchanged lines hidden (view full) --- 517 release_timer2(); 518#endif 519 beeping = 0; 520} 521 522int 523sysbeep(int pitch, int period) 524{ |
525 int x = splclock(); 526 |
|
462#ifdef PC98 463 if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT)) | 527#ifdef PC98 528 if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT)) |
464 return -1; | 529 if (!beeping) { 530 /* Something else owns it. */ 531 splx(x); 532 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 533 } |
465 disable_intr(); 466 outb(0x3fdb, pitch); 467 outb(0x3fdb, (pitch>>8)); 468 enable_intr(); 469 if (!beeping) { | 534 disable_intr(); 535 outb(0x3fdb, pitch); 536 outb(0x3fdb, (pitch>>8)); 537 enable_intr(); 538 if (!beeping) { |
470 outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */ | 539 /* enable counter1 output to speaker */ 540 outb(IO_PPI, (inb(IO_PPI) & 0xf7)); |
471 beeping = period; 472 timeout(sysbeepstop, (void *)NULL, period); 473 } 474#else | 541 beeping = period; 542 timeout(sysbeepstop, (void *)NULL, period); 543 } 544#else |
475 | |
476 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) | 545 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) |
477 return -1; | 546 if (!beeping) { 547 /* Something else owns it. */ 548 splx(x); 549 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 550 } |
478 disable_intr(); 479 outb(TIMER_CNTR2, pitch); 480 outb(TIMER_CNTR2, (pitch>>8)); 481 enable_intr(); 482 if (!beeping) { | 551 disable_intr(); 552 outb(TIMER_CNTR2, pitch); 553 outb(TIMER_CNTR2, (pitch>>8)); 554 enable_intr(); 555 if (!beeping) { |
483 outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */ | 556 /* enable counter2 output to speaker */ 557 outb(IO_PPI, inb(IO_PPI) | 3); |
484 beeping = period; 485 timeout(sysbeepstop, (void *)NULL, period); 486 } 487#endif | 558 beeping = period; 559 timeout(sysbeepstop, (void *)NULL, period); 560 } 561#endif |
488 return 0; | 562 splx(x); 563 return (0); |
489} 490 491#ifndef PC98 492/* 493 * RTC support routines 494 */ 495 496int --- 44 unchanged lines hidden (view full) --- 541 542#ifndef PC98 543static u_int 544calibrate_clocks(void) 545{ 546 u_int count, prev_count, tot_count; 547 int sec, start_sec, timeout; 548 | 564} 565 566#ifndef PC98 567/* 568 * RTC support routines 569 */ 570 571int --- 44 unchanged lines hidden (view full) --- 616 617#ifndef PC98 618static u_int 619calibrate_clocks(void) 620{ 621 u_int count, prev_count, tot_count; 622 int sec, start_sec, timeout; 623 |
549 printf("Calibrating clock(s) relative to mc146818A clock ... "); | 624 printf("Calibrating clock(s) relative to mc146818A clock...\n"); |
550 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 551 goto fail; 552 timeout = 100000000; 553 554 /* Read the mc146818A seconds counter. */ 555 for (;;) { 556 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 557 sec = rtcin(RTC_SEC); --- 76 unchanged lines hidden (view full) --- 634 printf("failed, using default i8254 clock of %u Hz\n", timer_freq); 635 return (timer_freq); 636} 637#endif /* !PC98 */ 638 639static void 640set_timer_freq(u_int freq, int intr_freq) 641{ | 625 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) 626 goto fail; 627 timeout = 100000000; 628 629 /* Read the mc146818A seconds counter. */ 630 for (;;) { 631 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) { 632 sec = rtcin(RTC_SEC); --- 76 unchanged lines hidden (view full) --- 709 printf("failed, using default i8254 clock of %u Hz\n", timer_freq); 710 return (timer_freq); 711} 712#endif /* !PC98 */ 713 714static void 715set_timer_freq(u_int freq, int intr_freq) 716{ |
642 u_long ef; | 717 u_long ef; |
643 644 ef = read_eflags(); | 718 719 ef = read_eflags(); |
720 disable_intr(); |
|
645 timer_freq = freq; 646 timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 647 timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; 648 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 649 outb(TIMER_CNTR0, timer0_max_count & 0xff); 650 outb(TIMER_CNTR0, timer0_max_count >> 8); 651 write_eflags(ef); 652} --- 30 unchanged lines hidden (view full) --- 683#endif /* PC98 */ 684 685#ifndef PC98 686 writertc(RTC_STATUSA, rtc_statusa); 687 writertc(RTC_STATUSB, RTCSB_24HR); 688#endif 689 690#ifndef PC98 | 721 timer_freq = freq; 722 timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 723 timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; 724 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 725 outb(TIMER_CNTR0, timer0_max_count & 0xff); 726 outb(TIMER_CNTR0, timer0_max_count >> 8); 727 write_eflags(ef); 728} --- 30 unchanged lines hidden (view full) --- 759#endif /* PC98 */ 760 761#ifndef PC98 762 writertc(RTC_STATUSA, rtc_statusa); 763 writertc(RTC_STATUSB, RTCSB_24HR); 764#endif 765 766#ifndef PC98 |
691 /* 692 * Temporarily calibrate with a high intr_freq to get a low 693 * timer0_max_count to help detect bogus i8254 counts. 694 */ 695 set_timer_freq(timer_freq, 20000); | 767 set_timer_freq(timer_freq, hz); |
696 freq = calibrate_clocks(); 697#ifdef CLK_CALIBRATION_LOOP 698 if (bootverbose) { 699 printf( 700 "Press a key on the console to abort clock calibration\n"); 701 while (!cncheckc()) 702 calibrate_clocks(); 703 } 704#endif 705 706 /* 707 * Use the calibrated i8254 frequency if it seems reasonable. 708 * Otherwise use the default, and don't use the calibrated i586 709 * frequency. 710 */ 711 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 712 if (delta < timer_freq / 100) { 713#ifndef CLK_USE_I8254_CALIBRATION | 768 freq = calibrate_clocks(); 769#ifdef CLK_CALIBRATION_LOOP 770 if (bootverbose) { 771 printf( 772 "Press a key on the console to abort clock calibration\n"); 773 while (!cncheckc()) 774 calibrate_clocks(); 775 } 776#endif 777 778 /* 779 * Use the calibrated i8254 frequency if it seems reasonable. 780 * Otherwise use the default, and don't use the calibrated i586 781 * frequency. 782 */ 783 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq; 784 if (delta < timer_freq / 100) { 785#ifndef CLK_USE_I8254_CALIBRATION |
714 printf( | 786 if (bootverbose) 787 printf( |
715"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 716 freq = timer_freq; 717#endif 718 timer_freq = freq; 719 } else { 720 printf("%d Hz differs from default of %d Hz by more than 1%%\n", 721 freq, timer_freq); 722#if defined(I586_CPU) || defined(I686_CPU) 723 i586_ctr_freq = 0; 724 i586_ctr_rate = 0; 725#endif 726 } 727#endif 728 729 set_timer_freq(timer_freq, hz); 730 731#if defined(I586_CPU) || defined(I686_CPU) 732#ifndef CLK_USE_I586_CALIBRATION 733 if (i586_ctr_rate != 0) { | 788"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n"); 789 freq = timer_freq; 790#endif 791 timer_freq = freq; 792 } else { 793 printf("%d Hz differs from default of %d Hz by more than 1%%\n", 794 freq, timer_freq); 795#if defined(I586_CPU) || defined(I686_CPU) 796 i586_ctr_freq = 0; 797 i586_ctr_rate = 0; 798#endif 799 } 800#endif 801 802 set_timer_freq(timer_freq, hz); 803 804#if defined(I586_CPU) || defined(I686_CPU) 805#ifndef CLK_USE_I586_CALIBRATION 806 if (i586_ctr_rate != 0) { |
734 printf( | 807 if (bootverbose) 808 printf( |
735"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); 736 i586_ctr_freq = 0; 737 i586_ctr_rate = 0; 738 } 739#endif 740 if (i586_ctr_rate == 0 && 741 (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { 742 /* 743 * Calibration of the i586 clock relative to the mc146818A 744 * clock failed. Do a less accurate calibration relative 745 * to the i8254 clock. 746 */ 747 unsigned long long i586_count; 748 749 wrmsr(0x10, 0LL); /* XXX */ 750 DELAY(1000000); 751 i586_count = rdtsc(); 752 i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; | 809"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); 810 i586_ctr_freq = 0; 811 i586_ctr_rate = 0; 812 } 813#endif 814 if (i586_ctr_rate == 0 && 815 (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { 816 /* 817 * Calibration of the i586 clock relative to the mc146818A 818 * clock failed. Do a less accurate calibration relative 819 * to the i8254 clock. 820 */ 821 unsigned long long i586_count; 822 823 wrmsr(0x10, 0LL); /* XXX */ 824 DELAY(1000000); 825 i586_count = rdtsc(); 826 i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; |
827#ifdef CLK_USE_I586_CALIBRATION |
|
753 printf("i586 clock: %u Hz\n", i586_ctr_freq); | 828 printf("i586 clock: %u Hz\n", i586_ctr_freq); |
829#endif |
|
754 } 755#endif 756} 757 758#ifdef PC98 759void 760rtc_serialcombit(int i) 761{ --- 368 unchanged lines hidden --- | 830 } 831#endif 832} 833 834#ifdef PC98 835void 836rtc_serialcombit(int i) 837{ --- 368 unchanged lines hidden --- |