Re: Everything you want to know about time (Was: Cyrix 6x86MX and Centaur C6 CPUs in 2.1.102)

=?ISO-8859-1?Q?Andr=E9?= Derrick Balsa (andrebalsa@altern.org)
Thu, 21 May 1998 16:47:41 -0100


This is a multi-part message in MIME format.

--------------1CDCB4473A2BF4884F8BF26A
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

Hi Scott,

C. Scott Ananian wrote:
...
> It still doesn't really change the variable-clock-speed problem, though.
> (CPU halt, a turbo button, APM slowing the clock...)
> But I guess if you screw with your CPU speed you deserve the timing
> problems you get.

If we had adequate hardware (i.e. an accurate, easy to use, microsecond
or better resolution, battery backed real time clock, totally
independent of CPU speed), then we wouldn't have to worry about CPU
speed in timing measurements.

Unfortunately with do_fast_gettimeoffset() we are using a CPU clock
cycle counter to get a high-resolution real time base. Inevitably, it is
affected by CPU clock speed.
...
> Sorry, but I *am* right. Look carefully at the code. It is *impossible*
> for the Cyrix to generate a divide-by-zero Oops (which has been
> experimentally verified by numerous sources)

I was the first person to report this oops on the kernel mailing list,
about 7 months ago :)

> *unless* the Cyrix is
> zero-ing the top 32 bits of the TSC on HLT. I call that "destroying the
> TSC".

OK, here are a few TSC readings of a 6x86MX machine, using Rafael
Reilova's neat code (slightly modified, see attached source). You can
see that all counts are > 2^32, which means the top 32 bits are _not_
affected by Suspend states (the kernel going idle).

[root@lw2l /root]# ./test
This is a 6x86MX with Suspend on Halt enabled
5528048284543 TSC reading at 1 second intervals.
5528049109927 TSC reading at 1 second intervals.
5528049854185 TSC reading at 1 second intervals.
5528050448925 TSC reading at 1 second intervals.
5528051464460 TSC reading at 1 second intervals.
This is a 6x86MX with Suspend on Halt disabled
5528239392036 TSC reading at 1 second intervals.
5528427321392 TSC reading at 1 second intervals.
5528615251937 TSC reading at 1 second intervals.
5528803178887 TSC reading at 1 second intervals.
5528991108384 TSC reading at 1 second intervals.
[root@lw2l /root]#

There has to be another explanation for the divide by zero oops.

...
> I'll believe you there. *BUT* this needs to be documented in big red
> letter somewhere: DON'T SUSPEND-ON-HALT.

Yeah, Cyrix goofed by wrongly documenting this. I really lost many hours
tracking this problem. The red letters should say: *the TSC will stop
counting when the 6x86MX goes in Suspend state*. Their Data Book says
precisely the contrary! I already wrote to them about it.
...
> See above. The Cyrix is trashing the TSC. There's no other way it can
> Oops.
>
> On the same note, if people are seeing Oopsen with the Centaur chips,
> which allegedly merely halt the CPU, I'd be very interested to hear about
> it.

The Centaur C6 PDF Data Sheet documents this in their errata. The
Centaur C6 step 0 will generate divide by zero faults, just like the
Cyrix 6x86MX with Suspend-on-Halt enabled.

I am certain you will find the exact cause of the divide by zero oops,
but please, please don't blame it on a Cyrix 6x86MX bug. :)

Cheers,
------------------------
André Balsa
andrebalsa@altern.org

--------------1CDCB4473A2BF4884F8BF26A
Content-Type: text/plain; charset=us-ascii; name="test.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="test.c"

/* Program to test the TSC on Cyrix 6x86MX and MII processors */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <asm/io.h>
#include <sys/ioctl.h>

/* asm macro to read the tsc */
#define rdtsc(LSB, MSB) asm("rdtsc" : "=a" (LSB), "=d" (MSB) )

/* define to test suspend-on-halt, needs root perms */
#define SUSP_OHALT 1

void loop_test(int times)
{
unsigned long msb, lsb;
unsigned long long tsc;

for (; times; times--) {
sleep(1);
rdtsc(lsb, msb);
tsc = ((unsigned long long)msb << 32) + lsb;
printf("%qu TSC reading at 1 second intervals.\n", tsc);
}
}

int main() {

#ifdef SUSP_OHALT
char data;

if (ioperm(0x22, 2, 1) != 0)
exit(1);

/* enable suspend on halt */
outb(0xc2, 0x22);
data = inb(0x23);
outb(0xc2, 0x22);
outb(data | 8, 0x23);
printf("This is a 6x86MX with Suspend on Halt enabled\n");
loop_test(5);

/* disable suspend on halt */
outb(0xc2, 0x22);
data = inb(0x23);
outb(0xc2, 0x22);
outb(data & ~8, 0x23);
#endif
printf("This is a 6x86MX with Suspend on Halt disabled\n");
loop_test(5);
exit(0);
}

--------------1CDCB4473A2BF4884F8BF26A--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu