add timecounter support (from branch simonb-timecounters)
This commit is contained in:
parent
09b51ec920
commit
9af3ab6763
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lapic.c,v 1.15 2006/01/04 00:15:50 rpaulo Exp $ */
|
||||
/* $NetBSD: lapic.c,v 1.16 2006/06/07 22:41:09 kardel Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -39,11 +39,11 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.15 2006/01/04 00:15:50 rpaulo Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.16 2006/06/07 22:41:09 kardel Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
#include "opt_mpbios.h" /* for MPDEBUG */
|
||||
#include "opt_multiprocessor.h"
|
||||
#include "opt_ntp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -51,12 +51,14 @@ __KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.15 2006/01/04 00:15:50 rpaulo Exp $");
|
||||
#include <sys/user.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <dev/ic/i8253reg.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpu_counter.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/cpuvar.h>
|
||||
#include <machine/pmap.h>
|
||||
@ -65,6 +67,9 @@ __KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.15 2006/01/04 00:15:50 rpaulo Exp $");
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/segments.h>
|
||||
#ifdef _HAVE_TIMECOUNTER
|
||||
#include <x86/x86/tsc.h>
|
||||
#endif
|
||||
|
||||
#include <machine/apicvar.h>
|
||||
#include <machine/i82489reg.h>
|
||||
@ -236,20 +241,87 @@ void
|
||||
lapic_clockintr(void *arg, struct intrframe frame)
|
||||
{
|
||||
#if defined(I586_CPU) || defined(I686_CPU) || defined(__x86_64__)
|
||||
#ifndef __HAVE_TIMECOUNTER
|
||||
static int microset_iter; /* call cc_microset once/sec */
|
||||
#endif /* __HAVE_TIMECOUNTER */
|
||||
#if defined(TIMECOUNTER_DEBUG) && defined(__HAVE_TIMECOUNTER)
|
||||
static u_int last_count[X86_MAXPROCS],
|
||||
last_delta[X86_MAXPROCS],
|
||||
last_tsc[X86_MAXPROCS],
|
||||
last_tscdelta[X86_MAXPROCS],
|
||||
last_factor[X86_MAXPROCS];
|
||||
#endif /* TIMECOUNTER_DEBUG && __HAVE_TIMECOUNTER */
|
||||
struct cpu_info *ci = curcpu();
|
||||
|
||||
ci->ci_isources[LIR_TIMER]->is_evcnt.ev_count++;
|
||||
|
||||
#if defined(TIMECOUNTER_DEBUG) && defined(__HAVE_TIMECOUNTER)
|
||||
{
|
||||
int cid = ci->ci_cpuid;
|
||||
extern u_int i8254_get_timecount(struct timecounter *);
|
||||
u_int c_count = i8254_get_timecount(NULL);
|
||||
u_int c_tsc = cpu_counter32();
|
||||
u_int delta, ddelta, tsc_delta, factor = 0;
|
||||
int idelta;
|
||||
|
||||
if (c_count > last_count[cid])
|
||||
delta = c_count - last_count[cid];
|
||||
else
|
||||
delta = 0x100000000ULL - last_count[cid] + c_count;
|
||||
|
||||
if (delta > last_delta[cid])
|
||||
ddelta = delta - last_delta[cid];
|
||||
else
|
||||
ddelta = last_delta[cid] - delta;
|
||||
|
||||
if (c_tsc > last_tsc[cid])
|
||||
tsc_delta = c_tsc - last_tsc[cid];
|
||||
else
|
||||
tsc_delta = 0x100000000ULL - last_tsc[cid] + c_tsc;
|
||||
|
||||
idelta = tsc_delta - last_tscdelta[cid];
|
||||
if (idelta < 0)
|
||||
idelta = -idelta;
|
||||
|
||||
if (delta) {
|
||||
int fdelta = tsc_delta / delta - last_factor[cid];
|
||||
if (fdelta < 0)
|
||||
fdelta = -fdelta;
|
||||
|
||||
if (fdelta > last_factor[cid] / 10) {
|
||||
printf("cpu%d: freq skew exceeds 10%%: delta %u, factor %u, last %u\n", cid, fdelta, tsc_delta / delta, last_factor[cid]);
|
||||
}
|
||||
factor = tsc_delta / delta;
|
||||
}
|
||||
|
||||
if (ddelta > last_delta[cid] / 10) {
|
||||
printf("cpu%d: tick delta exceeds 10%%: delta %u, last %u, tick %u, last %u, factor %u, last %u\n",
|
||||
cid, ddelta, last_delta[cid], c_count, last_count[cid], factor, last_factor[cid]);
|
||||
}
|
||||
|
||||
if (last_count[cid] > c_count) {
|
||||
printf("cpu%d: tick wrapped/lost: delta %u, tick %u, last %u\n", cid, last_count[cid] - c_count, c_count, last_count[cid]);
|
||||
}
|
||||
|
||||
if (idelta > last_tscdelta[cid] / 10) {
|
||||
printf("cpu%d: TSC delta exceeds 10%%: delta %u, last %u, tsc %u, factor %u, last %u\n", cid, idelta, last_tscdelta[cid], last_tsc[cid],
|
||||
factor, last_factor[cid]);
|
||||
}
|
||||
|
||||
last_factor[cid] = factor;
|
||||
last_delta[cid] = delta;
|
||||
last_count[cid] = c_count;
|
||||
last_tsc[cid] = c_tsc;
|
||||
last_tscdelta[cid] = tsc_delta;
|
||||
}
|
||||
#endif /* TIMECOUNTER_DEBUG && __HAVE_TIMECOUNTER */
|
||||
|
||||
#ifndef __HAVE_TIMECOUNTER
|
||||
/*
|
||||
* If we have a cycle counter, do the microset thing.
|
||||
*/
|
||||
if (ci->ci_feature_flags & CPUID_TSC) {
|
||||
if (
|
||||
#if defined(MULTIPROCESSOR)
|
||||
CPU_IS_PRIMARY(ci) &&
|
||||
#endif
|
||||
(microset_iter--) == 0) {
|
||||
if (CPU_IS_PRIMARY(ci) && (microset_iter--) == 0) {
|
||||
microset_iter = hz - 1;
|
||||
cc_microset_time = time;
|
||||
#if defined(MULTIPROCESSOR)
|
||||
@ -258,26 +330,27 @@ lapic_clockintr(void *arg, struct intrframe frame)
|
||||
cc_microset(ci);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* !__HAVE_TIMECOUNTER */
|
||||
#endif /* I586_CPU || I686_CPU || __x86_64__ */
|
||||
|
||||
hardclock((struct clockframe *)&frame);
|
||||
}
|
||||
|
||||
#ifdef NTP
|
||||
#if !defined(__HAVE_TIMECOUNTER) && defined(NTP)
|
||||
extern int fixtick;
|
||||
#endif /* NTP */
|
||||
#endif /* !__HAVE_TIMECOUNTER && NTP */
|
||||
|
||||
void
|
||||
lapic_initclocks()
|
||||
{
|
||||
|
||||
#ifdef NTP
|
||||
#if !defined(__HAVE_TIMECOUNTER) && defined(NTP)
|
||||
/*
|
||||
* we'll actually get (lapic_per_second/lapic_tval) interrupts/sec.
|
||||
*/
|
||||
fixtick = 1000000 -
|
||||
((int64_t)tick * lapic_per_second + lapic_tval / 2) / lapic_tval;
|
||||
#endif /* NTP */
|
||||
#endif /* !__HAVE_TIMECOUNTER && NTP */
|
||||
|
||||
/*
|
||||
* Start local apic countdown timer running, in repeated mode.
|
||||
@ -400,6 +473,11 @@ lapic_calibrate_timer(ci)
|
||||
*/
|
||||
delay_func = lapic_delay;
|
||||
initclock_func = lapic_initclocks;
|
||||
#ifdef __HAVE_TIMECOUNTER
|
||||
initrtclock(0);
|
||||
#else
|
||||
initrtclock();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
313
sys/arch/x86/x86/tsc.c
Normal file
313
sys/arch/x86/x86/tsc.c
Normal file
@ -0,0 +1,313 @@
|
||||
/* $NetBSD: tsc.c,v 1.2 2006/06/07 22:41:09 kardel Exp $ */
|
||||
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* re-implementation of TSC for MP systems merging cc_microtime and
|
||||
* TSC for timecounters by Frank Kardel
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* basic calibration ideas are (kern_microtime.c): */
|
||||
/******************************************************************************
|
||||
* *
|
||||
* Copyright (c) David L. Mills 1993, 1994 *
|
||||
* *
|
||||
* Permission to use, copy, modify, and distribute this software and its *
|
||||
* documentation for any purpose and without fee is hereby granted, provided *
|
||||
* that the above copyright notice appears in all copies and that both the *
|
||||
* copyright notice and this permission notice appear in supporting *
|
||||
* documentation, and that the name University of Delaware not be used in *
|
||||
* advertising or publicity pertaining to distribution of the software *
|
||||
* without specific, written prior permission. The University of Delaware *
|
||||
* makes no representations about the suitability this software for any *
|
||||
* purpose. It is provided "as is" without express or implied warranty. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/* reminiscents from older version of this file are: */
|
||||
/*-
|
||||
* Copyright (c) 1998-2003 Poul-Henning Kamp
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
/* __FBSDID("$FreeBSD: src/sys/i386/i386/tsc.c,v 1.204 2003/10/21 18:28:34 silby Exp $"); */
|
||||
__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.2 2006/06/07 22:41:09 kardel Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timetc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/power.h>
|
||||
#include <sys/reboot.h> /* XXX for bootverbose */
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpu_counter.h>
|
||||
#include <x86/x86/tsc.h>
|
||||
#include <machine/specialreg.h>
|
||||
|
||||
uint64_t tsc_freq;
|
||||
u_int tsc_present;
|
||||
int tsc_is_broken = 0;
|
||||
|
||||
static int64_t tsc_cal_val; /* last calibrate time stamp */
|
||||
|
||||
static timecounter_get_t tsc_get_timecount;
|
||||
static timecounter_pps_t tsc_calibrate;
|
||||
|
||||
void tsc_calibrate_cpu(struct cpu_info *);
|
||||
|
||||
static struct timecounter tsc_timecounter = {
|
||||
tsc_get_timecount, /* get_timecount */
|
||||
tsc_calibrate, /* once per second - used to calibrate cpu TSC */
|
||||
~0u, /* counter_mask */
|
||||
0, /* frequency */
|
||||
"TSC", /* name */
|
||||
800, /* quality (adjusted in code) */
|
||||
};
|
||||
|
||||
void
|
||||
init_TSC(void)
|
||||
{
|
||||
u_int64_t tscval[2];
|
||||
|
||||
if (cpu_feature & CPUID_TSC)
|
||||
tsc_present = 1;
|
||||
else
|
||||
tsc_present = 0;
|
||||
|
||||
if (!tsc_present)
|
||||
return;
|
||||
|
||||
if (bootverbose)
|
||||
printf("Calibrating TSC clock ... ");
|
||||
|
||||
do {
|
||||
tscval[0] = rdtsc();
|
||||
DELAY(100000);
|
||||
tscval[1] = rdtsc();
|
||||
} while (tscval[1] < tscval[0]);
|
||||
|
||||
tsc_freq = 10 * (tscval[1] - tscval[0]);
|
||||
if (bootverbose)
|
||||
printf("TSC clock: %" PRId64 " Hz\n", tsc_freq);
|
||||
}
|
||||
|
||||
void
|
||||
init_TSC_tc(void)
|
||||
{
|
||||
if (tsc_present && tsc_freq != 0 && !tsc_is_broken) {
|
||||
tsc_timecounter.tc_frequency = tsc_freq;
|
||||
tc_init(&tsc_timecounter);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX make tsc_timecounter.tc_frequency settable by sysctl() */
|
||||
|
||||
/*
|
||||
* pick up tick count scaled to reference tick count
|
||||
*/
|
||||
static u_int
|
||||
tsc_get_timecount(struct timecounter *tc)
|
||||
{
|
||||
struct cpu_info *ci = curcpu();
|
||||
int64_t rcc, cc;
|
||||
u_int gen;
|
||||
|
||||
if (ci->ci_cc.cc_denom == 0) {
|
||||
/*
|
||||
* This is our first time here on this CPU. Just
|
||||
* start with reasonable initial values.
|
||||
*/
|
||||
ci->ci_cc.cc_cc = cpu_counter32();
|
||||
ci->ci_cc.cc_val = 0;
|
||||
if (ci->ci_cc.cc_gen == 0)
|
||||
ci->ci_cc.cc_gen++;
|
||||
|
||||
ci->ci_cc.cc_denom = cpu_frequency(ci);
|
||||
if (ci->ci_cc.cc_denom == 0)
|
||||
ci->ci_cc.cc_denom = tsc_freq;
|
||||
ci->ci_cc.cc_delta = ci->ci_cc.cc_denom;
|
||||
}
|
||||
|
||||
/* read counter and re-read when the re-calibration
|
||||
strikes inbetween */
|
||||
do {
|
||||
/* pick up current generation number */
|
||||
gen = ci->ci_cc.cc_gen;
|
||||
|
||||
/* determine local delta ticks */
|
||||
cc = cpu_counter32() - ci->ci_cc.cc_cc;
|
||||
if (cc < 0)
|
||||
cc += 0x100000000LL;
|
||||
|
||||
/* scale to primary */
|
||||
rcc = (cc * ci->ci_cc.cc_delta) / ci->ci_cc.cc_denom
|
||||
+ ci->ci_cc.cc_val;
|
||||
} while (gen == 0 || gen != ci->ci_cc.cc_gen);
|
||||
|
||||
return rcc;
|
||||
}
|
||||
|
||||
/*
|
||||
* called once per second via the pps callback
|
||||
* for the calibration of the TSC counters.
|
||||
* it is called only for the PRIMARY cpu. all
|
||||
* other cpus are called via a broadcast IPI
|
||||
*/
|
||||
static void
|
||||
tsc_calibrate(struct timecounter *tc)
|
||||
{
|
||||
struct cpu_info *ci = curcpu();
|
||||
|
||||
/* pick up reference ticks */
|
||||
tsc_cal_val = cpu_counter32();
|
||||
|
||||
#if defined(MULTIPROCESSOR)
|
||||
x86_broadcast_ipi(X86_IPI_MICROSET);
|
||||
#endif
|
||||
|
||||
tsc_calibrate_cpu(ci);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called about once per second directly by the master
|
||||
* processor and via an interprocessor interrupt for other processors.
|
||||
* It determines the CC frequency of each processor relative to the
|
||||
* master clock and the time this determination is made. These values
|
||||
* are used by tsc_get_timecount() to interpolate the ticks between
|
||||
* timer interrupts. Note that we assume the kernel variables have
|
||||
* been zeroed early in life.
|
||||
*/
|
||||
void
|
||||
tsc_calibrate_cpu(struct cpu_info *ci)
|
||||
{
|
||||
u_int gen;
|
||||
int64_t val;
|
||||
int64_t delta, denom;
|
||||
int s;
|
||||
#ifdef TIMECOUNTER_DEBUG
|
||||
int64_t factor, old_factor;
|
||||
#endif
|
||||
val = tsc_cal_val;
|
||||
|
||||
s = splhigh();
|
||||
/* create next generation number */
|
||||
gen = ci->ci_cc.cc_gen;
|
||||
gen++;
|
||||
if (gen == 0)
|
||||
gen++;
|
||||
/* update in progress */
|
||||
ci->ci_cc.cc_gen = 0;
|
||||
|
||||
denom = ci->ci_cc.cc_cc;
|
||||
ci->ci_cc.cc_cc = cpu_counter32();
|
||||
|
||||
if (ci->ci_cc.cc_denom == 0) {
|
||||
/*
|
||||
* This is our first time here on this CPU. Just
|
||||
* start with reasonable initial values.
|
||||
*/
|
||||
ci->ci_cc.cc_val = val;
|
||||
ci->ci_cc.cc_denom = cpu_frequency(ci);
|
||||
if (ci->ci_cc.cc_denom == 0)
|
||||
ci->ci_cc.cc_denom = tsc_freq;
|
||||
ci->ci_cc.cc_delta = ci->ci_cc.cc_denom;
|
||||
ci->ci_cc.cc_gen = gen;
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TIMECOUNTER_DEBUG
|
||||
old_factor = (ci->ci_cc.cc_delta * 1000 ) / ci->ci_cc.cc_denom;
|
||||
#endif
|
||||
|
||||
/* local ticks per period */
|
||||
denom = ci->ci_cc.cc_cc - denom;
|
||||
if (denom < 0)
|
||||
denom += 0x100000000LL;
|
||||
|
||||
ci->ci_cc.cc_denom = denom;
|
||||
|
||||
/* reference ticks per period */
|
||||
delta = val - ci->ci_cc.cc_val;
|
||||
if (delta < 0)
|
||||
delta += 0x100000000LL;
|
||||
|
||||
ci->ci_cc.cc_val = val;
|
||||
ci->ci_cc.cc_delta = delta;
|
||||
|
||||
/* publish new generation number */
|
||||
ci->ci_cc.cc_gen = gen;
|
||||
splx(s);
|
||||
|
||||
#ifdef TIMECOUNTER_DEBUG
|
||||
factor = (delta * 1000) / denom - old_factor;
|
||||
if (factor < 0)
|
||||
factor = -factor;
|
||||
|
||||
if (factor > old_factor / 10)
|
||||
printf("tsc_calibrate_cpu[%lu]: 10%% exceeded - delta %"
|
||||
PRId64 ", denom %" PRId64 ", factor %" PRId64
|
||||
", old factor %" PRId64"\n", ci->ci_cpuid,
|
||||
delta, denom, (delta * 1000) / denom, old_factor);
|
||||
#if 0
|
||||
printf("tsc_calibrate_cpu[%lu]: delta %" PRId64
|
||||
", denom %" PRId64 ", factor %" PRId64 "\n", ci->ci_cpuid, delta, denom, (delta * 1000) / denom);
|
||||
#endif
|
||||
#endif /* TIMECOUNTER_DEBUG */
|
||||
}
|
40
sys/arch/x86/x86/tsc.h
Normal file
40
sys/arch/x86/x86/tsc.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* $NetBSD: tsc.h,v 1.2 2006/06/07 22:41:09 kardel Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* initialization of timecounter interface
|
||||
*/
|
||||
void init_TSC(void);
|
||||
void init_TSC_tc(void);
|
Loading…
Reference in New Issue
Block a user