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