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:
parent
bbd17bf8e1
commit
33ded19fc2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17353
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user