From owner-svn-src-head@FreeBSD.ORG Sun Sep 12 11:11:53 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 922A91065672; Sun, 12 Sep 2010 11:11:53 +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 810B68FC13; Sun, 12 Sep 2010 11:11:53 +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 o8CBBrpw025915; Sun, 12 Sep 2010 11:11:53 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o8CBBrW0025912; Sun, 12 Sep 2010 11:11:53 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201009121111.o8CBBrW0025912@svn.freebsd.org> From: Alexander Motin Date: Sun, 12 Sep 2010 11:11:53 +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: r212491 - head/sys/dev/acpica X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Sep 2010 11:11:53 -0000 Author: mav Date: Sun Sep 12 11:11:53 2010 New Revision: 212491 URL: http://svn.freebsd.org/changeset/base/212491 Log: Instead of storing last event timestamp, store the next event timestamp. It corrects handling of the first event offset in emulated periodic mode. Modified: head/sys/dev/acpica/acpi_hpet.c Modified: head/sys/dev/acpica/acpi_hpet.c ============================================================================== --- head/sys/dev/acpica/acpi_hpet.c Sun Sep 12 06:19:35 2010 (r212490) +++ head/sys/dev/acpica/acpi_hpet.c Sun Sep 12 11:11:53 2010 (r212491) @@ -98,7 +98,7 @@ struct hpet_softc { uint32_t caps; uint32_t vectors; uint32_t div; - uint32_t last; + uint32_t next; char name[8]; } t[32]; int num_timers; @@ -149,7 +149,7 @@ hpet_start(struct eventtimer *et, struct hpet_timer *mt = (struct hpet_timer *)et->et_priv; struct hpet_timer *t; struct hpet_softc *sc = mt->sc; - uint32_t fdiv, cmp; + uint32_t fdiv, now; t = (mt->pcpu_master < 0) ? mt : &sc->t[mt->pcpu_slaves[curcpu]]; if (period != NULL) { @@ -170,24 +170,28 @@ hpet_start(struct eventtimer *et, if (t->irq < 0) bus_write_4(sc->mem_res, HPET_ISR, 1 << t->num); t->caps |= HPET_TCNF_INT_ENB; - t->last = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); + now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); restart: - cmp = t->last + fdiv; + t->next = now + fdiv; if (t->mode == 1 && (t->caps & HPET_TCAP_PER_INT)) { t->caps |= HPET_TCNF_TYPE; bus_write_4(sc->mem_res, HPET_TIMER_CAP_CNF(t->num), t->caps | HPET_TCNF_VAL_SET); - bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), cmp); - bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), t->div); + bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), + t->next); + bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), + t->div); } else { t->caps &= ~HPET_TCNF_TYPE; - bus_write_4(sc->mem_res, HPET_TIMER_CAP_CNF(t->num), t->caps); - bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), cmp); + bus_write_4(sc->mem_res, HPET_TIMER_CAP_CNF(t->num), + t->caps); + bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), + t->next); } if (fdiv < 5000) { bus_read_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num)); - t->last = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); - if ((int32_t)(t->last - cmp) >= 0) { + now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); + if ((int32_t)(now - t->next) >= 0) { fdiv *= 2; goto restart; } @@ -217,6 +221,8 @@ hpet_intr_single(void *arg) struct hpet_softc *sc = t->sc; uint32_t now; + if (t->mode == 0) + return (FILTER_STRAY); /* Check that per-CPU timer interrupt reached right CPU. */ if (t->pcpu_cpu >= 0 && t->pcpu_cpu != curcpu) { if ((++t->pcpu_misrouted) % 32 == 0) { @@ -231,20 +237,21 @@ hpet_intr_single(void *arg) */ if ((t->mode == 1 && (t->caps & HPET_TCAP_PER_INT) == 0) || t->mode == 2) { - t->last = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); + t->next = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER) + + sc->freq / 8; bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), - t->last + sc->freq / 8); + t->next); } return (FILTER_HANDLED); } if (t->mode == 1 && (t->caps & HPET_TCAP_PER_INT) == 0) { - t->last += t->div; + t->next += t->div; now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); - if ((int32_t)(now - (t->last + t->div / 2)) > 0) - t->last = now - t->div / 2; + if ((int32_t)((now + t->div / 2) - t->next) > 0) + t->next = now + t->div / 2; bus_write_4(sc->mem_res, - HPET_TIMER_COMPARATOR(t->num), t->last + t->div); + HPET_TIMER_COMPARATOR(t->num), t->next); } else if (t->mode == 2) t->mode = 0; mt = (t->pcpu_master < 0) ? t : &sc->t[t->pcpu_master]; @@ -713,19 +720,21 @@ hpet_resume(device_t dev) #endif if (t->mode == 0) continue; - t->last = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); + t->next = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); if (t->mode == 1 && (t->caps & HPET_TCAP_PER_INT)) { t->caps |= HPET_TCNF_TYPE; + t->next += t->div; bus_write_4(sc->mem_res, HPET_TIMER_CAP_CNF(t->num), t->caps | HPET_TCNF_VAL_SET); bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), - t->last + t->div); + t->next); bus_read_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num)); bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), t->div); } else { + t->next += sc->freq / 1024; bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), - t->last + sc->freq / 1024); + t->next); } bus_write_4(sc->mem_res, HPET_ISR, 1 << t->num); bus_write_4(sc->mem_res, HPET_TIMER_CAP_CNF(t->num), t->caps);