1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-13 10:02:38 +00:00

Fixed the machdep.i8254_freq and machdep.i586_freq sysctls. Writes were

handled bogusly.

Centralized the setting of all the frequency variables.  Set these
variables atomically.  Some new ones aren't used yet.
This commit is contained in:
Bruce Evans 1996-07-30 19:26:55 +00:00
parent bbd17bf8e1
commit 33ded19fc2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17353
7 changed files with 217 additions and 94 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
* $Id: clock.c,v 1.64 1996/07/20 18:47:23 joerg Exp $
* $Id: clock.c,v 1.65 1996/07/21 08:20:51 joerg Exp $
*/
/*
@ -102,7 +102,9 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
unsigned i586_ctr_rate;
long long i586_ctr_bias;
long long i586_last_tick;
@ -144,6 +146,10 @@ static u_char timer0_state;
static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
#if defined(I586_CPU) || defined(I686_CPU)
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
#endif
static void
clkintr(struct clockframe frame)
{
@ -553,11 +559,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock.
*/
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count;
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), tot_count);
printf("i586 clock: %u Hz, ", i586_ctr_freq);
}
#endif
@ -651,12 +653,9 @@ startrtclock()
* clock failed. Do a less accurate calibration relative
* to the i8254 clock.
*/
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif
@ -861,10 +860,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/
freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != timer_freq) {
if (error == 0 && req->newptr != NULL) {
if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
}
return (error);
}
@ -873,21 +875,42 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU)
static void
set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
{
u_int comultiplier, multiplier, rate;
u_long ef;
if (i586_freq == 0) {
i586_ctr_freq = i586_freq;
i586_ctr_rate = 0;
return;
}
comultiplier = ((unsigned long long)i586_freq
<< I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
rate = ((unsigned long long)i586_freq << I586_CTR_RATE_SHIFT) / 1000000;
ef = read_eflags();
disable_intr();
i586_ctr_freq = i586_freq;
i586_ctr_comultiplier = comultiplier;
i586_ctr_multiplier = multiplier;
i586_ctr_rate = rate;
write_eflags(ef);
}
static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{
int error;
u_int freq;
if (i586_ctr_rate == 0)
if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP);
freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) {
i586_ctr_freq = freq;
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
if (error == 0 && req->newptr != NULL)
set_i586_ctr_freq(freq, timer_freq);
return (error);
}

View File

@ -3,7 +3,7 @@
* Garrett Wollman, September 1994.
* This file is in the public domain.
*
* $Id: clock.h,v 1.13 1996/05/01 08:38:50 bde Exp $
* $Id: clock.h,v 1.14 1996/06/14 11:00:56 asami Exp $
*/
#ifndef _MACHINE_CLOCK_H_
@ -38,6 +38,8 @@
#define CPU_THISTICKLEN(dflt) dflt
#endif
#define I586_CTR_COMULTIPLIER_SHIFT 20
#define I586_CTR_MULTIPLIER_SHIFT 32
#define I586_CTR_RATE_SHIFT 8
#if defined(KERNEL) && !defined(LOCORE)
@ -55,7 +57,9 @@ extern int statclock_disable;
extern int wall_cmos_clock;
#if defined(I586_CPU) || defined(I686_CPU)
extern unsigned i586_ctr_freq;
extern u_int i586_ctr_comultiplier;
extern u_int i586_ctr_freq;
extern u_int i586_ctr_multiplier;
extern unsigned i586_ctr_rate; /* fixed point */
extern long long i586_last_tick;
extern long long i586_ctr_bias;

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
* $Id: clock.c,v 1.64 1996/07/20 18:47:23 joerg Exp $
* $Id: clock.c,v 1.65 1996/07/21 08:20:51 joerg Exp $
*/
/*
@ -102,7 +102,9 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
unsigned i586_ctr_rate;
long long i586_ctr_bias;
long long i586_last_tick;
@ -144,6 +146,10 @@ static u_char timer0_state;
static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
#if defined(I586_CPU) || defined(I686_CPU)
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
#endif
static void
clkintr(struct clockframe frame)
{
@ -553,11 +559,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock.
*/
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count;
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), tot_count);
printf("i586 clock: %u Hz, ", i586_ctr_freq);
}
#endif
@ -651,12 +653,9 @@ startrtclock()
* clock failed. Do a less accurate calibration relative
* to the i8254 clock.
*/
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif
@ -861,10 +860,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/
freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != timer_freq) {
if (error == 0 && req->newptr != NULL) {
if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
}
return (error);
}
@ -873,21 +875,42 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU)
static void
set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
{
u_int comultiplier, multiplier, rate;
u_long ef;
if (i586_freq == 0) {
i586_ctr_freq = i586_freq;
i586_ctr_rate = 0;
return;
}
comultiplier = ((unsigned long long)i586_freq
<< I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
rate = ((unsigned long long)i586_freq << I586_CTR_RATE_SHIFT) / 1000000;
ef = read_eflags();
disable_intr();
i586_ctr_freq = i586_freq;
i586_ctr_comultiplier = comultiplier;
i586_ctr_multiplier = multiplier;
i586_ctr_rate = rate;
write_eflags(ef);
}
static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{
int error;
u_int freq;
if (i586_ctr_rate == 0)
if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP);
freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) {
i586_ctr_freq = freq;
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
if (error == 0 && req->newptr != NULL)
set_i586_ctr_freq(freq, timer_freq);
return (error);
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
* $Id: clock.c,v 1.64 1996/07/20 18:47:23 joerg Exp $
* $Id: clock.c,v 1.65 1996/07/21 08:20:51 joerg Exp $
*/
/*
@ -102,7 +102,9 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
unsigned i586_ctr_rate;
long long i586_ctr_bias;
long long i586_last_tick;
@ -144,6 +146,10 @@ static u_char timer0_state;
static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
#if defined(I586_CPU) || defined(I686_CPU)
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
#endif
static void
clkintr(struct clockframe frame)
{
@ -553,11 +559,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock.
*/
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count;
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), tot_count);
printf("i586 clock: %u Hz, ", i586_ctr_freq);
}
#endif
@ -651,12 +653,9 @@ startrtclock()
* clock failed. Do a less accurate calibration relative
* to the i8254 clock.
*/
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif
@ -861,10 +860,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/
freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != timer_freq) {
if (error == 0 && req->newptr != NULL) {
if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
}
return (error);
}
@ -873,21 +875,42 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU)
static void
set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
{
u_int comultiplier, multiplier, rate;
u_long ef;
if (i586_freq == 0) {
i586_ctr_freq = i586_freq;
i586_ctr_rate = 0;
return;
}
comultiplier = ((unsigned long long)i586_freq
<< I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
rate = ((unsigned long long)i586_freq << I586_CTR_RATE_SHIFT) / 1000000;
ef = read_eflags();
disable_intr();
i586_ctr_freq = i586_freq;
i586_ctr_comultiplier = comultiplier;
i586_ctr_multiplier = multiplier;
i586_ctr_rate = rate;
write_eflags(ef);
}
static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{
int error;
u_int freq;
if (i586_ctr_rate == 0)
if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP);
freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) {
i586_ctr_freq = freq;
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
if (error == 0 && req->newptr != NULL)
set_i586_ctr_freq(freq, timer_freq);
return (error);
}

View File

@ -3,7 +3,7 @@
* Garrett Wollman, September 1994.
* This file is in the public domain.
*
* $Id: clock.h,v 1.13 1996/05/01 08:38:50 bde Exp $
* $Id: clock.h,v 1.14 1996/06/14 11:00:56 asami Exp $
*/
#ifndef _MACHINE_CLOCK_H_
@ -38,6 +38,8 @@
#define CPU_THISTICKLEN(dflt) dflt
#endif
#define I586_CTR_COMULTIPLIER_SHIFT 20
#define I586_CTR_MULTIPLIER_SHIFT 32
#define I586_CTR_RATE_SHIFT 8
#if defined(KERNEL) && !defined(LOCORE)
@ -55,7 +57,9 @@ extern int statclock_disable;
extern int wall_cmos_clock;
#if defined(I586_CPU) || defined(I686_CPU)
extern unsigned i586_ctr_freq;
extern u_int i586_ctr_comultiplier;
extern u_int i586_ctr_freq;
extern u_int i586_ctr_multiplier;
extern unsigned i586_ctr_rate; /* fixed point */
extern long long i586_last_tick;
extern long long i586_ctr_bias;

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
* $Id: clock.c,v 1.64 1996/07/20 18:47:23 joerg Exp $
* $Id: clock.c,v 1.65 1996/07/21 08:20:51 joerg Exp $
*/
/*
@ -102,7 +102,9 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
unsigned i586_ctr_rate;
long long i586_ctr_bias;
long long i586_last_tick;
@ -144,6 +146,10 @@ static u_char timer0_state;
static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
#if defined(I586_CPU) || defined(I686_CPU)
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
#endif
static void
clkintr(struct clockframe frame)
{
@ -553,11 +559,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock.
*/
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count;
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), tot_count);
printf("i586 clock: %u Hz, ", i586_ctr_freq);
}
#endif
@ -651,12 +653,9 @@ startrtclock()
* clock failed. Do a less accurate calibration relative
* to the i8254 clock.
*/
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif
@ -861,10 +860,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/
freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != timer_freq) {
if (error == 0 && req->newptr != NULL) {
if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
}
return (error);
}
@ -873,21 +875,42 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU)
static void
set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
{
u_int comultiplier, multiplier, rate;
u_long ef;
if (i586_freq == 0) {
i586_ctr_freq = i586_freq;
i586_ctr_rate = 0;
return;
}
comultiplier = ((unsigned long long)i586_freq
<< I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
rate = ((unsigned long long)i586_freq << I586_CTR_RATE_SHIFT) / 1000000;
ef = read_eflags();
disable_intr();
i586_ctr_freq = i586_freq;
i586_ctr_comultiplier = comultiplier;
i586_ctr_multiplier = multiplier;
i586_ctr_rate = rate;
write_eflags(ef);
}
static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{
int error;
u_int freq;
if (i586_ctr_rate == 0)
if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP);
freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) {
i586_ctr_freq = freq;
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
if (error == 0 && req->newptr != NULL)
set_i586_ctr_freq(freq, timer_freq);
return (error);
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
* $Id: clock.c,v 1.64 1996/07/20 18:47:23 joerg Exp $
* $Id: clock.c,v 1.65 1996/07/21 08:20:51 joerg Exp $
*/
/*
@ -102,7 +102,9 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
unsigned i586_ctr_rate;
long long i586_ctr_bias;
long long i586_last_tick;
@ -144,6 +146,10 @@ static u_char timer0_state;
static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
#if defined(I586_CPU) || defined(I686_CPU)
static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
#endif
static void
clkintr(struct clockframe frame)
{
@ -553,11 +559,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock.
*/
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count;
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), tot_count);
printf("i586 clock: %u Hz, ", i586_ctr_freq);
}
#endif
@ -651,12 +653,9 @@ startrtclock()
* clock failed. Do a less accurate calibration relative
* to the i8254 clock.
*/
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000);
i586_count = rdtsc();
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
#ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif
@ -861,10 +860,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/
freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != timer_freq) {
if (error == 0 && req->newptr != NULL) {
if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
}
return (error);
}
@ -873,21 +875,42 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU)
static void
set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
{
u_int comultiplier, multiplier, rate;
u_long ef;
if (i586_freq == 0) {
i586_ctr_freq = i586_freq;
i586_ctr_rate = 0;
return;
}
comultiplier = ((unsigned long long)i586_freq
<< I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
rate = ((unsigned long long)i586_freq << I586_CTR_RATE_SHIFT) / 1000000;
ef = read_eflags();
disable_intr();
i586_ctr_freq = i586_freq;
i586_ctr_comultiplier = comultiplier;
i586_ctr_multiplier = multiplier;
i586_ctr_rate = rate;
write_eflags(ef);
}
static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{
int error;
u_int freq;
if (i586_ctr_rate == 0)
if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP);
freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) {
i586_ctr_freq = freq;
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
if (error == 0 && req->newptr != NULL)
set_i586_ctr_freq(freq, timer_freq);
return (error);
}