Deleted Added
full compact
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 ---