Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Feb 2002 15:18:01 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Michael Smith <msmith@FreeBSD.ORG>
Cc:        Poul-Henning Kamp <phk@critter.freebsd.dk>, Bruce Evans <bde@zeta.org.au>, freebsd-current@FreeBSD.ORG
Subject:   ACPI timer is screwed... (was Re: 'microuptime() went backwards ...' using ACPI timer. Shouldn't that be impossible? )
Message-ID:  <200202172318.g1HNI1I02804@apollo.backplane.com>
References:   <200202172225.g1HMPKA01422@mass.dis.org>

next in thread | previous in thread | raw e-mail | index | archive | help

:I would like to see "the PIIX problem" caught on camera, personally.  
:We're aware of one errata for it already, and we work around it.  If 
:there's another problem, or ideally if someone has some relatively quick 
:code to test it, that would be much better.

    Holy shit.  We are screwed.  It's a free-running counter with NO
    synchronization whatsoever.  None.  Zip.  Zero.

ACPI TIMER LSB MISREAD 128ababd 128abaa2 128abaa4
ACPI TIMER LSB MISREAD 128ea0cd 128ea0c9 128ea0cb
ACPI TIMER LSB MISREAD 129427fd 129425ff 12942801

    So, for example:  ABD AA2 AA4

	ABD	101010111101
		      ^ probably should be a 0
	AA2	101010100010
	AA2	101010100100

    Another example:  0CD 0C9 0CB

	0CD	000011001101
			^ probably should be a 0

	0C9	000011001001
	0CB	000011001011

    It looks like the hardware is using an adder with fast carry
    (basically a forward looking carry calculation), which can result in a
    later bit being set before the earlier bits are updated.  However, if
    this is the case then it is almost certain that you can catch the ripple
    as well, or even catch the counter while the bit states are changing.

    The only way to get a guarenteed accurate sample under these circumstances
    is something like this, where you calculate a mask that results in
    reasonable accurancy without causing the cpu to go into an infinite
    loop and then read the timer until you get two samples that are the same:

    u1 = TIMER_READ;
    u2 = TIMER_READ;
    while ((u1 ^ u2) & 0xFFFFFFF0) {	<<<<<<<< mask must be chosen
	u1 = u2;
	u2 = TIMER_READ;
    }
    return(u2 & 0xFFFFFFF0)		<<<<<<<< same mask here

    Here are some more from my debug output:

ACPI TIMER LSB MISREAD 2cb0f97d 2cb0f961 2cb0f963
ACPI TIMER LSB MISREAD 2fad1ced 2fad1ce9 2fad1ceb
ACPI TIMER LSB MISREAD 33ed26ff 33ed2681 33ed2683
ACPI TIMER LSB MISREAD 34184d1d 34184d19 34184d1c
ACPI TIMER LSB MISREAD 344516ff 344516e1 344516e3
ACPI TIMER LSB MISREAD 392b2c6d 392b2c69 392b2c6b
ACPI TIMER LSB MISREAD 39c9073d 39c90739 39c9073b
ACPI TIMER LSB MISREAD 39f3161d 39f3161a 39f3161c
ACPI TIMER LSB MISREAD 3ad04bbf 3ad04bb1 3ad04bb3
ACPI TIMER LSB MISREAD 39f3161d 39f3161a 39f3161c

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202172318.g1HNI1I02804>