atrtc.c (71797) | atrtc.c (72200) |
---|---|
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 * $FreeBSD: head/sys/isa/atrtc.c 71797 2001-01-29 11:57:27Z peter $ | 37 * $FreeBSD: head/sys/isa/atrtc.c 72200 2001-02-09 06:11:45Z bmilekic $ |
38 */ 39 40/* 41 * Routines to handle clock hardware. 42 */ 43 44/* 45 * inittodr, settodr and support routines written --- 156 unchanged lines hidden (view full) --- 202SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 203 &i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); 204 205static void 206clkintr(struct clockframe frame) 207{ 208 209 if (timecounter->tc_get_timecount == i8254_get_timecount) { | 38 */ 39 40/* 41 * Routines to handle clock hardware. 42 */ 43 44/* 45 * inittodr, settodr and support routines written --- 156 unchanged lines hidden (view full) --- 202SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 203 &i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); 204 205static void 206clkintr(struct clockframe frame) 207{ 208 209 if (timecounter->tc_get_timecount == i8254_get_timecount) { |
210 mtx_enter(&clock_lock, MTX_SPIN); | 210 mtx_lock_spin(&clock_lock); |
211 if (i8254_ticked) 212 i8254_ticked = 0; 213 else { 214 i8254_offset += timer0_max_count; 215 i8254_lastcount = 0; 216 } 217 clkintr_pending = 0; | 211 if (i8254_ticked) 212 i8254_ticked = 0; 213 else { 214 i8254_offset += timer0_max_count; 215 i8254_lastcount = 0; 216 } 217 clkintr_pending = 0; |
218 mtx_exit(&clock_lock, MTX_SPIN); | 218 mtx_unlock_spin(&clock_lock); |
219 } 220 timer_func(&frame); 221 switch (timer0_state) { 222 223 case RELEASED: 224 break; 225 226 case ACQUIRED: 227 if ((timer0_prescaler_count += timer0_max_count) 228 >= hardclock_max_count) { 229 timer0_prescaler_count -= hardclock_max_count; 230 hardclock(&frame); 231 } 232 break; 233 234 case ACQUIRE_PENDING: | 219 } 220 timer_func(&frame); 221 switch (timer0_state) { 222 223 case RELEASED: 224 break; 225 226 case ACQUIRED: 227 if ((timer0_prescaler_count += timer0_max_count) 228 >= hardclock_max_count) { 229 timer0_prescaler_count -= hardclock_max_count; 230 hardclock(&frame); 231 } 232 break; 233 234 case ACQUIRE_PENDING: |
235 mtx_enter(&clock_lock, MTX_SPIN); | 235 mtx_lock_spin(&clock_lock); |
236 i8254_offset = i8254_get_timecount(NULL); 237 i8254_lastcount = 0; 238 timer0_max_count = TIMER_DIV(new_rate); 239 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 240 outb(TIMER_CNTR0, timer0_max_count & 0xff); 241 outb(TIMER_CNTR0, timer0_max_count >> 8); | 236 i8254_offset = i8254_get_timecount(NULL); 237 i8254_lastcount = 0; 238 timer0_max_count = TIMER_DIV(new_rate); 239 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 240 outb(TIMER_CNTR0, timer0_max_count & 0xff); 241 outb(TIMER_CNTR0, timer0_max_count >> 8); |
242 mtx_exit(&clock_lock, MTX_SPIN); | 242 mtx_unlock_spin(&clock_lock); |
243 timer_func = new_function; 244 timer0_state = ACQUIRED; 245 break; 246 247 case RELEASE_PENDING: 248 if ((timer0_prescaler_count += timer0_max_count) 249 >= hardclock_max_count) { | 243 timer_func = new_function; 244 timer0_state = ACQUIRED; 245 break; 246 247 case RELEASE_PENDING: 248 if ((timer0_prescaler_count += timer0_max_count) 249 >= hardclock_max_count) { |
250 mtx_enter(&clock_lock, MTX_SPIN); | 250 mtx_lock_spin(&clock_lock); |
251 i8254_offset = i8254_get_timecount(NULL); 252 i8254_lastcount = 0; 253 timer0_max_count = hardclock_max_count; 254 outb(TIMER_MODE, 255 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 256 outb(TIMER_CNTR0, timer0_max_count & 0xff); 257 outb(TIMER_CNTR0, timer0_max_count >> 8); | 251 i8254_offset = i8254_get_timecount(NULL); 252 i8254_lastcount = 0; 253 timer0_max_count = hardclock_max_count; 254 outb(TIMER_MODE, 255 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 256 outb(TIMER_CNTR0, timer0_max_count & 0xff); 257 outb(TIMER_CNTR0, timer0_max_count >> 8); |
258 mtx_exit(&clock_lock, MTX_SPIN); | 258 mtx_unlock_spin(&clock_lock); |
259 timer0_prescaler_count = 0; 260 timer_func = hardclock; 261 timer0_state = RELEASED; 262 hardclock(&frame); 263 } 264 break; 265 } 266#ifdef DEV_MCA --- 131 unchanged lines hidden (view full) --- 398} 399#endif /* DDB */ 400 401static int 402getit(void) 403{ 404 int high, low; 405 | 259 timer0_prescaler_count = 0; 260 timer_func = hardclock; 261 timer0_state = RELEASED; 262 hardclock(&frame); 263 } 264 break; 265 } 266#ifdef DEV_MCA --- 131 unchanged lines hidden (view full) --- 398} 399#endif /* DDB */ 400 401static int 402getit(void) 403{ 404 int high, low; 405 |
406 mtx_enter(&clock_lock, MTX_SPIN); | 406 mtx_lock_spin(&clock_lock); |
407 408 /* Select timer0 and latch counter value. */ 409 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 410 411 low = inb(TIMER_CNTR0); 412 high = inb(TIMER_CNTR0); 413 | 407 408 /* Select timer0 and latch counter value. */ 409 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 410 411 low = inb(TIMER_CNTR0); 412 high = inb(TIMER_CNTR0); 413 |
414 mtx_exit(&clock_lock, MTX_SPIN); | 414 mtx_unlock_spin(&clock_lock); |
415 return ((high << 8) | low); 416} 417 418/* 419 * Wait "n" microseconds. 420 * Relies on timer 1 counting down from (timer_freq / hz) 421 * Note: timer had better have been programmed before this is first used! 422 */ --- 97 unchanged lines hidden (view full) --- 520 int x = splclock(); 521 522 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 523 if (!beeping) { 524 /* Something else owns it. */ 525 splx(x); 526 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 527 } | 415 return ((high << 8) | low); 416} 417 418/* 419 * Wait "n" microseconds. 420 * Relies on timer 1 counting down from (timer_freq / hz) 421 * Note: timer had better have been programmed before this is first used! 422 */ --- 97 unchanged lines hidden (view full) --- 520 int x = splclock(); 521 522 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT)) 523 if (!beeping) { 524 /* Something else owns it. */ 525 splx(x); 526 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ 527 } |
528 mtx_enter(&clock_lock, MTX_SPIN); | 528 mtx_lock_spin(&clock_lock); |
529 outb(TIMER_CNTR2, pitch); 530 outb(TIMER_CNTR2, (pitch>>8)); | 529 outb(TIMER_CNTR2, pitch); 530 outb(TIMER_CNTR2, (pitch>>8)); |
531 mtx_exit(&clock_lock, MTX_SPIN); | 531 mtx_unlock_spin(&clock_lock); |
532 if (!beeping) { 533 /* enable counter2 output to speaker */ 534 outb(IO_PPI, inb(IO_PPI) | 3); 535 beeping = period; 536 timeout(sysbeepstop, (void *)NULL, period); 537 } 538 splx(x); 539 return (0); --- 134 unchanged lines hidden (view full) --- 674 return (timer_freq); 675} 676 677static void 678set_timer_freq(u_int freq, int intr_freq) 679{ 680 int new_timer0_max_count; 681 | 532 if (!beeping) { 533 /* enable counter2 output to speaker */ 534 outb(IO_PPI, inb(IO_PPI) | 3); 535 beeping = period; 536 timeout(sysbeepstop, (void *)NULL, period); 537 } 538 splx(x); 539 return (0); --- 134 unchanged lines hidden (view full) --- 674 return (timer_freq); 675} 676 677static void 678set_timer_freq(u_int freq, int intr_freq) 679{ 680 int new_timer0_max_count; 681 |
682 mtx_enter(&clock_lock, MTX_SPIN); | 682 mtx_lock_spin(&clock_lock); |
683 timer_freq = freq; 684 new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 685 if (new_timer0_max_count != timer0_max_count) { 686 timer0_max_count = new_timer0_max_count; 687 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 688 outb(TIMER_CNTR0, timer0_max_count & 0xff); 689 outb(TIMER_CNTR0, timer0_max_count >> 8); 690 } | 683 timer_freq = freq; 684 new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); 685 if (new_timer0_max_count != timer0_max_count) { 686 timer0_max_count = new_timer0_max_count; 687 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 688 outb(TIMER_CNTR0, timer0_max_count & 0xff); 689 outb(TIMER_CNTR0, timer0_max_count >> 8); 690 } |
691 mtx_exit(&clock_lock, MTX_SPIN); | 691 mtx_unlock_spin(&clock_lock); |
692} 693 694/* 695 * i8254_restore is called from apm_default_resume() to reload 696 * the countdown register. 697 * this should not be necessary but there are broken laptops that 698 * do not restore the countdown register on resume. 699 * when it happnes, it messes up the hardclock interval and system clock, 700 * which leads to the infamous "calcru: negative time" problem. 701 */ 702void 703i8254_restore(void) 704{ 705 | 692} 693 694/* 695 * i8254_restore is called from apm_default_resume() to reload 696 * the countdown register. 697 * this should not be necessary but there are broken laptops that 698 * do not restore the countdown register on resume. 699 * when it happnes, it messes up the hardclock interval and system clock, 700 * which leads to the infamous "calcru: negative time" problem. 701 */ 702void 703i8254_restore(void) 704{ 705 |
706 mtx_enter(&clock_lock, MTX_SPIN); | 706 mtx_lock_spin(&clock_lock); |
707 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 708 outb(TIMER_CNTR0, timer0_max_count & 0xff); 709 outb(TIMER_CNTR0, timer0_max_count >> 8); | 707 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); 708 outb(TIMER_CNTR0, timer0_max_count & 0xff); 709 outb(TIMER_CNTR0, timer0_max_count >> 8); |
710 mtx_exit(&clock_lock, MTX_SPIN); | 710 mtx_unlock_spin(&clock_lock); |
711} 712 713/* 714 * Initialize 8254 timer 0 early so that it can be used in DELAY(). 715 * XXX initialization of other timers is unintentionally left blank. 716 */ 717void 718startrtclock() --- 470 unchanged lines hidden (view full) --- 1189static unsigned 1190i8254_get_timecount(struct timecounter *tc) 1191{ 1192 u_int count; 1193 u_int high, low; 1194 u_int eflags; 1195 1196 eflags = read_eflags(); | 711} 712 713/* 714 * Initialize 8254 timer 0 early so that it can be used in DELAY(). 715 * XXX initialization of other timers is unintentionally left blank. 716 */ 717void 718startrtclock() --- 470 unchanged lines hidden (view full) --- 1189static unsigned 1190i8254_get_timecount(struct timecounter *tc) 1191{ 1192 u_int count; 1193 u_int high, low; 1194 u_int eflags; 1195 1196 eflags = read_eflags(); |
1197 mtx_enter(&clock_lock, MTX_SPIN); | 1197 mtx_lock_spin(&clock_lock); |
1198 1199 /* Select timer0 and latch counter value. */ 1200 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 1201 1202 low = inb(TIMER_CNTR0); 1203 high = inb(TIMER_CNTR0); 1204 count = timer0_max_count - ((high << 8) | low); 1205 if (count < i8254_lastcount || --- 7 unchanged lines hidden (view full) --- 1213 (inb(IO_ICU1) & 1))) 1214#endif 1215 )) { 1216 i8254_ticked = 1; 1217 i8254_offset += timer0_max_count; 1218 } 1219 i8254_lastcount = count; 1220 count += i8254_offset; | 1198 1199 /* Select timer0 and latch counter value. */ 1200 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 1201 1202 low = inb(TIMER_CNTR0); 1203 high = inb(TIMER_CNTR0); 1204 count = timer0_max_count - ((high << 8) | low); 1205 if (count < i8254_lastcount || --- 7 unchanged lines hidden (view full) --- 1213 (inb(IO_ICU1) & 1))) 1214#endif 1215 )) { 1216 i8254_ticked = 1; 1217 i8254_offset += timer0_max_count; 1218 } 1219 i8254_lastcount = count; 1220 count += i8254_offset; |
1221 mtx_exit(&clock_lock, MTX_SPIN); | 1221 mtx_unlock_spin(&clock_lock); |
1222 return (count); 1223} 1224 1225static unsigned 1226tsc_get_timecount(struct timecounter *tc) 1227{ 1228 return (rdtsc()); 1229} --- 46 unchanged lines hidden --- | 1222 return (count); 1223} 1224 1225static unsigned 1226tsc_get_timecount(struct timecounter *tc) 1227{ 1228 return (rdtsc()); 1229} --- 46 unchanged lines hidden --- |