From owner-svn-src-all@FreeBSD.ORG Sat Sep 18 07:36:43 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CB9061065673; Sat, 18 Sep 2010 07:36:43 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A0AFD8FC18; Sat, 18 Sep 2010 07:36:43 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o8I7ahMN056057; Sat, 18 Sep 2010 07:36:43 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o8I7ahMB056054; Sat, 18 Sep 2010 07:36:43 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201009180736.o8I7ahMB056054@svn.freebsd.org> From: Alexander Motin Date: Sat, 18 Sep 2010 07:36:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212812 - head/sys/x86/isa X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Sep 2010 07:36:43 -0000 Author: mav Date: Sat Sep 18 07:36:43 2010 New Revision: 212812 URL: http://svn.freebsd.org/changeset/base/212812 Log: Restore pre-r212778 optimization, skipping timer reprogramming when it is not neccessary. It allows to avoid time counter jump of up to 1/18s, when base frequency slightly tuned via machdep.i8254_freq sysctl. Fix few style things. Suggested by: bde Modified: head/sys/x86/isa/clock.c Modified: head/sys/x86/isa/clock.c ============================================================================== --- head/sys/x86/isa/clock.c Sat Sep 18 07:18:30 2010 (r212811) +++ head/sys/x86/isa/clock.c Sat Sep 18 07:36:43 2010 (r212812) @@ -124,6 +124,8 @@ struct attimer_softc { }; static struct attimer_softc *attimer_sc = NULL; +static int timer0_period = -2; + /* Values for timerX_state: */ #define RELEASED 0 #define RELEASE_PENDING 1 @@ -367,36 +369,41 @@ DELAY(int n) static void set_i8254_freq(int mode, uint32_t period) { - int val; + int new_count; mtx_lock_spin(&clock_lock); - if (period == 0) - val = 0x10000; - else - val = min(((uint64_t)i8254_freq * period) >> 32, 0x10000); - if (val == 0x10000) - i8254_max_count = 0xffff; - else - i8254_max_count = val; - if (mode == MODE_STOP && i8254_timecounter) - mode = MODE_PERIODIC; + if (mode == MODE_STOP) { + if (i8254_timecounter) { + mode = MODE_PERIODIC; + new_count = 0x10000; + } else + new_count = -1; + } else { + new_count = min(((uint64_t)i8254_freq * period + + 0x80000000LLU) >> 32, 0x10000); + } + if (new_count == timer0_period) + goto out; + i8254_max_count = ((new_count & ~0xffff) != 0) ? 0xffff : new_count; + timer0_period = (mode == MODE_PERIODIC) ? new_count : -1; switch (mode) { case MODE_STOP: outb(TIMER_MODE, TIMER_SEL0 | TIMER_INTTC | TIMER_16BIT); - outb(TIMER_CNTR0, 0xff); - outb(TIMER_CNTR0, 0xff); + outb(TIMER_CNTR0, 0); + outb(TIMER_CNTR0, 0); break; case MODE_PERIODIC: outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); - outb(TIMER_CNTR0, val & 0xff); - outb(TIMER_CNTR0, val >> 8); + outb(TIMER_CNTR0, new_count & 0xff); + outb(TIMER_CNTR0, new_count >> 8); break; case MODE_ONESHOT: outb(TIMER_MODE, TIMER_SEL0 | TIMER_INTTC | TIMER_16BIT); - outb(TIMER_CNTR0, val & 0xff); - outb(TIMER_CNTR0, val >> 8); + outb(TIMER_CNTR0, new_count & 0xff); + outb(TIMER_CNTR0, new_count >> 8); break; } +out: mtx_unlock_spin(&clock_lock); } @@ -404,7 +411,8 @@ static void i8254_restore(void) { - if (attimer_sc) + timer0_period = -2; + if (attimer_sc != NULL) set_i8254_freq(attimer_sc->mode, attimer_sc->period); else set_i8254_freq(0, 0); @@ -473,7 +481,7 @@ sysctl_machdep_i8254_freq(SYSCTL_HANDLER error = sysctl_handle_int(oidp, &freq, 0, req); if (error == 0 && req->newptr != NULL) { i8254_freq = freq; - if (attimer_sc) { + if (attimer_sc != NULL) { set_i8254_freq(attimer_sc->mode, attimer_sc->period); attimer_sc->tc.tc_frequency = freq; } else {