clock.c (254373) | clock.c (263008) |
---|---|
1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org> 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz and Don Ahn. 8 * --- 20 unchanged lines hidden (view full) --- 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 34 */ 35 36#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org> 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz and Don Ahn. 8 * --- 20 unchanged lines hidden (view full) --- 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 34 */ 35 36#include <sys/cdefs.h> |
37__FBSDID("$FreeBSD: head/sys/x86/isa/clock.c 254373 2013-08-15 17:21:06Z brooks $"); | 37__FBSDID("$FreeBSD: head/sys/x86/isa/clock.c 263008 2014-03-11 10:20:42Z royger $"); |
38 39/* 40 * Routines to handle clock hardware. 41 */ 42 43#include "opt_clock.h" 44#include "opt_isa.h" 45#include "opt_mca.h" --- 14 unchanged lines hidden (view full) --- 60#include <sys/timeet.h> 61#include <sys/timetc.h> 62 63#include <machine/clock.h> 64#include <machine/cpu.h> 65#include <machine/intr_machdep.h> 66#include <machine/ppireg.h> 67#include <machine/timerreg.h> | 38 39/* 40 * Routines to handle clock hardware. 41 */ 42 43#include "opt_clock.h" 44#include "opt_isa.h" 45#include "opt_mca.h" --- 14 unchanged lines hidden (view full) --- 60#include <sys/timeet.h> 61#include <sys/timetc.h> 62 63#include <machine/clock.h> 64#include <machine/cpu.h> 65#include <machine/intr_machdep.h> 66#include <machine/ppireg.h> 67#include <machine/timerreg.h> |
68#include <x86/init.h> |
|
68 69#ifdef PC98 70#include <pc98/pc98/pc98_machdep.h> 71#else 72#include <isa/rtc.h> 73#endif 74#ifdef DEV_ISA 75#ifdef PC98 --- 58 unchanged lines hidden (view full) --- 134#define ACQUIRED 2 135#define ACQUIRE_PENDING 3 136 137static u_char timer2_state; 138 139static unsigned i8254_get_timecount(struct timecounter *tc); 140static void set_i8254_freq(int mode, uint32_t period); 141 | 69 70#ifdef PC98 71#include <pc98/pc98/pc98_machdep.h> 72#else 73#include <isa/rtc.h> 74#endif 75#ifdef DEV_ISA 76#ifdef PC98 --- 58 unchanged lines hidden (view full) --- 135#define ACQUIRED 2 136#define ACQUIRE_PENDING 3 137 138static u_char timer2_state; 139 140static unsigned i8254_get_timecount(struct timecounter *tc); 141static void set_i8254_freq(int mode, uint32_t period); 142 |
143void 144clock_init(void) 145{ 146 /* Init the clock lock */ 147 mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); 148 /* Init the clock in order to use DELAY */ 149 init_ops.early_clock_source_init(); 150} 151 |
|
142static int 143clkintr(void *arg) 144{ 145 struct attimer_softc *sc = (struct attimer_softc *)arg; 146 147 if (i8254_timecounter && sc->period != 0) { 148 mtx_lock_spin(&clock_lock); 149 if (i8254_ticked) --- 92 unchanged lines hidden (view full) --- 242 243 low = inb(TIMER_CNTR0); 244 high = inb(TIMER_CNTR0); 245 246 mtx_unlock_spin(&clock_lock); 247 return ((high << 8) | low); 248} 249 | 152static int 153clkintr(void *arg) 154{ 155 struct attimer_softc *sc = (struct attimer_softc *)arg; 156 157 if (i8254_timecounter && sc->period != 0) { 158 mtx_lock_spin(&clock_lock); 159 if (i8254_ticked) --- 92 unchanged lines hidden (view full) --- 252 253 low = inb(TIMER_CNTR0); 254 high = inb(TIMER_CNTR0); 255 256 mtx_unlock_spin(&clock_lock); 257 return ((high << 8) | low); 258} 259 |
250#ifndef DELAYDEBUG 251static u_int 252get_tsc(__unused struct timecounter *tc) 253{ 254 255 return (rdtsc32()); 256} 257 258static __inline int 259delay_tc(int n) 260{ 261 struct timecounter *tc; 262 timecounter_get_t *func; 263 uint64_t end, freq, now; 264 u_int last, mask, u; 265 266 tc = timecounter; 267 freq = atomic_load_acq_64(&tsc_freq); 268 if (tsc_is_invariant && freq != 0) { 269 func = get_tsc; 270 mask = ~0u; 271 } else { 272 if (tc->tc_quality <= 0) 273 return (0); 274 func = tc->tc_get_timecount; 275 mask = tc->tc_counter_mask; 276 freq = tc->tc_frequency; 277 } 278 now = 0; 279 end = freq * n / 1000000; 280 if (func == get_tsc) 281 sched_pin(); 282 last = func(tc) & mask; 283 do { 284 cpu_spinwait(); 285 u = func(tc) & mask; 286 if (u < last) 287 now += mask - last + u + 1; 288 else 289 now += u - last; 290 last = u; 291 } while (now < end); 292 if (func == get_tsc) 293 sched_unpin(); 294 return (1); 295} 296#endif 297 | |
298/* 299 * Wait "n" microseconds. 300 * Relies on timer 1 counting down from (i8254_freq / hz) 301 * Note: timer had better have been programmed before this is first used! 302 */ 303void | 260/* 261 * Wait "n" microseconds. 262 * Relies on timer 1 counting down from (i8254_freq / hz) 263 * Note: timer had better have been programmed before this is first used! 264 */ 265void |
304DELAY(int n) | 266i8254_delay(int n) |
305{ 306 int delta, prev_tick, tick, ticks_left; 307#ifdef DELAYDEBUG 308 int getit_calls = 1; 309 int n1; 310 static int state = 0; 311 312 if (state == 0) { 313 state = 1; 314 for (n1 = 1; n1 <= 10000000; n1 *= 10) 315 DELAY(n1); 316 state = 2; 317 } 318 if (state == 1) 319 printf("DELAY(%d)...", n); | 267{ 268 int delta, prev_tick, tick, ticks_left; 269#ifdef DELAYDEBUG 270 int getit_calls = 1; 271 int n1; 272 static int state = 0; 273 274 if (state == 0) { 275 state = 1; 276 for (n1 = 1; n1 <= 10000000; n1 *= 10) 277 DELAY(n1); 278 state = 2; 279 } 280 if (state == 1) 281 printf("DELAY(%d)...", n); |
320#else 321 if (delay_tc(n)) 322 return; | |
323#endif 324 /* 325 * Read the counter first, so that the rest of the setup overhead is 326 * counted. Guess the initial overhead is 20 usec (on most systems it 327 * takes about 1.5 usec for each of the i/o's in getit(). The loop 328 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 329 * multiplications and divisions to scale the count take a while). 330 * --- 163 unchanged lines hidden (view full) --- 494} 495#endif 496 497/* This is separate from startrtclock() so that it can be called early. */ 498void 499i8254_init(void) 500{ 501 | 282#endif 283 /* 284 * Read the counter first, so that the rest of the setup overhead is 285 * counted. Guess the initial overhead is 20 usec (on most systems it 286 * takes about 1.5 usec for each of the i/o's in getit(). The loop 287 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The 288 * multiplications and divisions to scale the count take a while). 289 * --- 163 unchanged lines hidden (view full) --- 453} 454#endif 455 456/* This is separate from startrtclock() so that it can be called early. */ 457void 458i8254_init(void) 459{ 460 |
502 mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); | |
503#ifdef PC98 504 if (pc98_machine_type & M_8M) 505 i8254_freq = 1996800L; /* 1.9968 MHz */ 506#endif 507 set_i8254_freq(MODE_STOP, 0); 508} 509 510void --- 287 unchanged lines hidden --- | 461#ifdef PC98 462 if (pc98_machine_type & M_8M) 463 i8254_freq = 1996800L; /* 1.9968 MHz */ 464#endif 465 set_i8254_freq(MODE_STOP, 0); 466} 467 468void --- 287 unchanged lines hidden --- |