diff options
author | mav <mav@FreeBSD.org> | 2009-05-03 17:47:21 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2009-05-03 17:47:21 +0000 |
commit | 98565a1214eb4106f0a1b76ff6696b9980497195 (patch) | |
tree | ce5adc34e083eefdd76b28a61134b800569d7b6e /sys/isa | |
parent | 77cd1e9862e8b7f432feb7272c92e04d5b0f47fd (diff) | |
download | FreeBSD-src-98565a1214eb4106f0a1b76ff6696b9980497195.zip FreeBSD-src-98565a1214eb4106f0a1b76ff6696b9980497195.tar.gz |
Rename statclock_disable variable to atrtcclock_disable that it actually is,
and hide it inside of atrtc driver. Add new tunable hint.atrtc.0.clock
controlling it. Setting it to 0 disables using RTC clock as stat-/
profclock sources.
Teach i386 and amd64 SMP platforms to emulate stat-/profclocks using i8254
hardclock, when LAPIC and RTC clocks are disabled.
This allows to reduce global interrupt rate of idle system down to about
100 interrupts per core, permitting C3 and deeper C-states provide maximum
CPU power efficiency.
Diffstat (limited to 'sys/isa')
-rw-r--r-- | sys/isa/atrtc.c | 26 | ||||
-rw-r--r-- | sys/isa/rtc.h | 2 |
2 files changed, 28 insertions, 0 deletions
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 990c1ee..777c720 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -49,6 +49,8 @@ __FBSDID("$FreeBSD$"); #define RTC_LOCK mtx_lock_spin(&clock_lock) #define RTC_UNLOCK mtx_unlock_spin(&clock_lock) +int atrtcclock_disable = 0; + static int rtc_reg = -1; static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; static u_char rtc_statusb = RTCSB_24HR; @@ -133,6 +135,27 @@ atrtc_restore(void) rtcin(RTC_INTR); } +int +atrtc_setup_clock(void) +{ + int diag; + + if (atrtcclock_disable) + return (0); + + diag = rtcin(RTC_DIAG); + if (diag != 0) { + printf("RTC BIOS diagnostic error %b\n", + diag, RTCDG_BITS); + return (0); + } + + stathz = RTC_NOPROFRATE; + profhz = RTC_PROFRATE; + + return (1); +} + /********************************************************************** * RTC driver for subr_rtc */ @@ -173,6 +196,7 @@ static int atrtc_attach(device_t dev) { struct atrtc_softc *sc; + int i; /* * Not that we need them or anything, but grab our resources @@ -187,6 +211,8 @@ atrtc_attach(device_t dev) &sc->intr_rid, 8, 8, 1, RF_ACTIVE))) device_printf(dev,"Warning: Couldn't map Interrupt.\n"); clock_register(dev, 1000000); + if (resource_int_value("atrtc", 0, "clock", &i) == 0 && i == 0) + atrtcclock_disable = 1; return(0); } diff --git a/sys/isa/rtc.h b/sys/isa/rtc.h index c802b0b..018a4ed 100644 --- a/sys/isa/rtc.h +++ b/sys/isa/rtc.h @@ -113,6 +113,8 @@ #ifdef _KERNEL extern struct mtx clock_lock; +extern int atrtcclock_disable; +int atrtc_setup_clock(void); int rtcin(int reg); void atrtc_start(void); void atrtc_rate(unsigned rate); |