linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Strange macros set HZ value for timer channel zero
@ 2001-08-17 13:23 Richard B. Johnson
  2001-08-17 19:27 ` george anzinger
  0 siblings, 1 reply; 6+ messages in thread
From: Richard B. Johnson @ 2001-08-17 13:23 UTC (permalink / raw)
  To: Linux kernel


To whomever maintains the timer code, greetings.

When using Linux on the AMD SC520 chip, the system time will
not be correct because the PIT clock is 1.1882 MHz instead of
the usual 1.19318 MHz. Therefore, I put a conditional value
in ../linux/include/asm/timex.h .

#ifndef _ASMi386_TIMEX_H
#define _ASMi386_TIMEX_H

#include <linux/config.h>
#include <asm/msr.h>
#ifdef SC520
#define CLOCK_TICK_RATE	1188200 /* Underlying HZ */
#else
#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
#endif

Something is wrong! I now gain 3 hours in a 12 hour period. There
are some calculations performed somewhere that result in the
wrong divisor for the timer (PIT). I don't understand any of the
SHIFT stuff, nor FINE_TUNE stuff. It all seems bogus although
it might be the "new math" that's biting me.

The correct value for 100 Hz should be 1188200/100 = 11882 = 0x2e6a
for the divisor. If I hard-code the value as a divisor in
/usr/src/linux/arch/i386/kernel/i8259.c,  it works. If I use the
#defines and macros in the headers, it doesn't.


Cheers,
Dick Johnson

Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).

    I was going to compile a list of innovations that could be
    attributed to Microsoft. Once I realized that Ctrl-Alt-Del
    was handled in the BIOS, I found that there aren't any.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Strange macros set HZ value for timer channel zero
  2001-08-17 13:23 Strange macros set HZ value for timer channel zero Richard B. Johnson
@ 2001-08-17 19:27 ` george anzinger
  2001-08-17 21:13   ` george anzinger
  2001-08-20 14:22   ` Richard B. Johnson
  0 siblings, 2 replies; 6+ messages in thread
From: george anzinger @ 2001-08-17 19:27 UTC (permalink / raw)
  To: root; +Cc: Linux kernel

"Richard B. Johnson" wrote:
> 
> To whomever maintains the timer code, greetings.
> 
> When using Linux on the AMD SC520 chip, the system time will
> not be correct because the PIT clock is 1.1882 MHz instead of
> the usual 1.19318 MHz. Therefore, I put a conditional value
> in ../linux/include/asm/timex.h .
> 
> #ifndef _ASMi386_TIMEX_H
> #define _ASMi386_TIMEX_H
> 
> #include <linux/config.h>
> #include <asm/msr.h>
> #ifdef SC520
> #define CLOCK_TICK_RATE 1188200 /* Underlying HZ */
> #else
> #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
> #endif
> 
> Something is wrong! I now gain 3 hours in a 12 hour period. There
> are some calculations performed somewhere that result in the
> wrong divisor for the timer (PIT). I don't understand any of the
> SHIFT stuff, nor FINE_TUNE stuff. It all seems bogus although
> it might be the "new math" that's biting me.
> 
> The correct value for 100 Hz should be 1188200/100 = 11882 = 0x2e6a
> for the divisor. If I hard-code the value as a divisor in
> /usr/src/linux/arch/i386/kernel/i8259.c,  it works. If I use the
> #defines and macros in the headers, it doesn't.
> 
Seems hard to believe.  Try this:

cd ../arch/i386/kernel
gcc -D__KERNEL__ -I/usr/src/linux-2.4.7-hr/include -Wall
-Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer
-fno-strict-aliasing -fno-common -pipe  -march=i586    -c -o i8259.o
i8259.c -E

(note the -E, the rest of the line is just cut from the make output, I
usually make from a shell in emacs so all this output is available... 
If you are cutting this line from this message, make sure you change the
-I path to match your kernel location.)

now exit i8259.c and search for your new number, i.e. 118820.  (Or if
that fails search for "init_IRQ" and look at the outb_p in there.)  For
the old 1192180 I find:

	outb_p(0x34,0x43);		 
	outb_p(((1193180  + 100 /2) / 100 )  & 0xff , 0x40);	 
	outb(((1193180  + 100 /2) / 100 )  >> 8 , 0x40);	 

Seems like the new number should do just what you need here.  The
calibration in time.c is a little wonky, but that will not give the
errors you are seeing, nor would your change of LATCH (I assume this is
what you changed in i8259.c) affect that wonky stuff.

Oh, by the way, you will want to purge i8259.o as make will assume it is
up to date and try to merge it as a *.o file, which will fail rather
badly.

George

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Strange macros set HZ value for timer channel zero
  2001-08-17 19:27 ` george anzinger
@ 2001-08-17 21:13   ` george anzinger
  2001-08-20  1:11     ` Richard B. Johnson
  2001-08-20 14:22   ` Richard B. Johnson
  1 sibling, 1 reply; 6+ messages in thread
From: george anzinger @ 2001-08-17 21:13 UTC (permalink / raw)
  To: root, Linux kernel

george anzinger wrote:
> 
> "Richard B. Johnson" wrote:
> >
> > To whomever maintains the timer code, greetings.
> >
> > When using Linux on the AMD SC520 chip, the system time will
> > not be correct because the PIT clock is 1.1882 MHz instead of
> > the usual 1.19318 MHz. Therefore, I put a conditional value
> > in ../linux/include/asm/timex.h .
> >
> > #ifndef _ASMi386_TIMEX_H
> > #define _ASMi386_TIMEX_H
> >
> > #include <linux/config.h>
> > #include <asm/msr.h>
> > #ifdef SC520
> > #define CLOCK_TICK_RATE 1188200 /* Underlying HZ */
> > #else
> > #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
> > #endif
> >
> > Something is wrong! I now gain 3 hours in a 12 hour period. There
> > are some calculations performed somewhere that result in the
> > wrong divisor for the timer (PIT). I don't understand any of the
> > SHIFT stuff, nor FINE_TUNE stuff. It all seems bogus although
> > it might be the "new math" that's biting me.
> >
> > The correct value for 100 Hz should be 1188200/100 = 11882 = 0x2e6a
> > for the divisor. If I hard-code the value as a divisor in
> > /usr/src/linux/arch/i386/kernel/i8259.c,  it works. If I use the
> > #defines and macros in the headers, it doesn't.
> >
> Seems hard to believe.  Try this:
> 
> cd ../arch/i386/kernel
> gcc -D__KERNEL__ -I/usr/src/linux-2.4.7-hr/include -Wall
> -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer
> -fno-strict-aliasing -fno-common -pipe  -march=i586    -c -o i8259.o
> i8259.c -E
> 
> (note the -E, the rest of the line is just cut from the make output, I
> usually make from a shell in emacs so all this output is available...
> If you are cutting this line from this message, make sure you change the
> -I path to match your kernel location.)
> 
> now exit i8259.c and search for your new number, i.e. 118820.  (Or if
      ^^^^ gosh, that should be "edit", don't know who grabbed my
fingers there...
> that fails search for "init_IRQ" and look at the outb_p in there.)  For
> the old 1192180 I find:
> 
>         outb_p(0x34,0x43);
>         outb_p(((1193180  + 100 /2) / 100 )  & 0xff , 0x40);
>         outb(((1193180  + 100 /2) / 100 )  >> 8 , 0x40);
> 
> Seems like the new number should do just what you need here.  The
> calibration in time.c is a little wonky, but that will not give the
> errors you are seeing, nor would your change of LATCH (I assume this is
> what you changed in i8259.c) affect that wonky stuff.
> 
> Oh, by the way, you will want to purge i8259.o as make will assume it is
> up to date and try to merge it as a *.o file, which will fail rather
> badly.
> 
> George
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Strange macros set HZ value for timer channel zero
  2001-08-17 21:13   ` george anzinger
@ 2001-08-20  1:11     ` Richard B. Johnson
  0 siblings, 0 replies; 6+ messages in thread
From: Richard B. Johnson @ 2001-08-20  1:11 UTC (permalink / raw)
  To: george anzinger; +Cc: Linux kernel

On Fri, 17 Aug 2001, george anzinger wrote:

> george anzinger wrote:
> > 
> > "Richard B. Johnson" wrote:
> > >
> > > To whomever maintains the timer code, greetings.
[SNIPPED...]

I will get to the soon. I had to take a "work break".


Cheers,
Dick Johnson

Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).

    I was going to compile a list of innovations that could be
    attributed to Microsoft. Once I realized that Ctrl-Alt-Del
    was handled in the BIOS, I found that there aren't any.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Strange macros set HZ value for timer channel zero
  2001-08-17 19:27 ` george anzinger
  2001-08-17 21:13   ` george anzinger
@ 2001-08-20 14:22   ` Richard B. Johnson
  2001-08-20 16:55     ` george anzinger
  1 sibling, 1 reply; 6+ messages in thread
From: Richard B. Johnson @ 2001-08-20 14:22 UTC (permalink / raw)
  To: george anzinger; +Cc: Linux kernel

On Fri, 17 Aug 2001, george anzinger wrote:

> "Richard B. Johnson" wrote:
> > 
> > To whomever maintains the timer code, greetings.
> > 
> > When using Linux on the AMD SC520 chip, the system time will
> > not be correct because the PIT clock is 1.1882 MHz instead of
> > the usual 1.19318 MHz. Therefore, I put a conditional value
> > in ../linux/include/asm/timex.h .
> > 
> > #ifndef _ASMi386_TIMEX_H
> > #define _ASMi386_TIMEX_H
> > 
> > #include <linux/config.h>
> > #include <asm/msr.h>
> > #ifdef SC520
> > #define CLOCK_TICK_RATE 1188200 /* Underlying HZ */
> > #else
> > #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
> > #endif
> > 
[SNIPPED...]

Okay. I still don't know what's wrong. The following code
shows that your MACRO does produce the right stuff:
Script started on Mon Aug 20 10:02:58 2001

# cat xxx.c
#include <stdio.h>
#include <sys/time.h>
#define __KERNEL__
#include <linux/timex.h>


int main()
{
    printf("Divisor = %d\n", LATCH);
    printf("%02x %02x\n", LATCH & 0xff, LATCH >> 8);
}

# gcc -o xxx xxx.c
In file included from /usr/local/include/linux/timex.h:54,
                 from xxx.c:4:
/usr/local/include/asm/param.h:21: warning: `CLOCKS_PER_SEC' redefined
/usr/local/include/timebits.h:44: warning: this is the location of the previous definition
# xxx
Divisor = 11932
9c 2e
# gcc -DSC520 -o xxx xxx.c
In file included from /usr/local/include/linux/timex.h:54,
                 from xxx.c:4:
/usr/local/include/asm/param.h:21: warning: `CLOCKS_PER_SEC' redefined
/usr/local/include/timebits.h:44: warning: this is the location of the previous definition
# xxx
Divisor = 11882
6a 2e
# exit
exit

Script done on Mon Aug 20 10:03:50 2001


Ignoring the "multiple-defined" warnings, one can see that the
divisor and the stuff that will be put into the registers is
correct. Sorry to bother you.

It looks like this problem has to be fixed with a hammer. For some
reason, the chip doesn't like the new values.

I'm off by about 7 seconds per minute:

Connected to platinum, wait...
        platinum time was Mon Aug 20 10:10:10 2001
           chaos time was Mon Aug 20 10:10:03 2001
    Difference = 7 second(s)
        platinum time was Mon Aug 20 10:10:11 2001
           chaos time was Mon Aug 20 10:10:04 2001
    Difference = 7 second(s)
        platinum time was Mon Aug 20 10:10:11 2001
           chaos time was Mon Aug 20 10:10:04 2001
    Difference = 7 second(s)
        platinum time was Mon Aug 20 10:10:12 2001
           chaos time was Mon Aug 20 10:10:05 2001
    Difference = 7 second(s)
        platinum time was Mon Aug 20 10:10:12 2001
           chaos time was Mon Aug 20 10:10:05 2001
    Difference = 7 second(s)
        platinum time was Mon Aug 20 10:10:13 2001
           chaos time was Mon Aug 20 10:10:06 2001
    Difference = 7 second(s)
        platinum time was Mon Aug 20 10:10:13 2001
           chaos time was Mon Aug 20 10:10:06 2001
    Difference = 7 second(s)

Aborted by ^C

It gains time, meaning that the divisor is too small. Unfortunately,
I can't read what was written to the actual chip. I can only detect
its affect. 60 / 67 = 0.89 * 100 = 89. 1188200/89 = 13350 = 0x3426
as a divisor. It doesn't make sense because both LSB and MSB are
wrong. If one was wrong I could guess that the previous hadn't set
up properly and needs more delay.

Anyway. I will continue to search.

Cheers,
Dick Johnson

Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).

    I was going to compile a list of innovations that could be
    attributed to Microsoft. Once I realized that Ctrl-Alt-Del
    was handled in the BIOS, I found that there aren't any.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Strange macros set HZ value for timer channel zero
  2001-08-20 14:22   ` Richard B. Johnson
@ 2001-08-20 16:55     ` george anzinger
  0 siblings, 0 replies; 6+ messages in thread
From: george anzinger @ 2001-08-20 16:55 UTC (permalink / raw)
  To: root; +Cc: Linux kernel

"Richard B. Johnson" wrote:
> 
> On Fri, 17 Aug 2001, george anzinger wrote:
> 
> > "Richard B. Johnson" wrote:
> > >
> > > To whomever maintains the timer code, greetings.
> > >
> > > When using Linux on the AMD SC520 chip, the system time will
> > > not be correct because the PIT clock is 1.1882 MHz instead of
> > > the usual 1.19318 MHz. Therefore, I put a conditional value
> > > in ../linux/include/asm/timex.h .
> > >
> > > #ifndef _ASMi386_TIMEX_H
> > > #define _ASMi386_TIMEX_H
> > >
> > > #include <linux/config.h>
> > > #include <asm/msr.h>
> > > #ifdef SC520
> > > #define CLOCK_TICK_RATE 1188200 /* Underlying HZ */
> > > #else
> > > #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
> > > #endif
> > >
> [SNIPPED...]
> 
> Okay. I still don't know what's wrong. The following code
> shows that your MACRO does produce the right stuff:
> Script started on Mon Aug 20 10:02:58 2001
> 
> # cat xxx.c
> #include <stdio.h>
> #include <sys/time.h>
> #define __KERNEL__
> #include <linux/timex.h>
> 
> int main()
> {
>     printf("Divisor = %d\n", LATCH);
>     printf("%02x %02x\n", LATCH & 0xff, LATCH >> 8);
> }
> 
> # gcc -o xxx xxx.c
> In file included from /usr/local/include/linux/timex.h:54,
>                  from xxx.c:4:
> /usr/local/include/asm/param.h:21: warning: `CLOCKS_PER_SEC' redefined
> /usr/local/include/timebits.h:44: warning: this is the location of the previous definition
> # xxx
> Divisor = 11932
> 9c 2e
> # gcc -DSC520 -o xxx xxx.c
> In file included from /usr/local/include/linux/timex.h:54,
>                  from xxx.c:4:
> /usr/local/include/asm/param.h:21: warning: `CLOCKS_PER_SEC' redefined
> /usr/local/include/timebits.h:44: warning: this is the location of the previous definition
> # xxx
> Divisor = 11882
> 6a 2e
> # exit
> exit
> 
> Script done on Mon Aug 20 10:03:50 2001
> 
> Ignoring the "multiple-defined" warnings, one can see that the
> divisor and the stuff that will be put into the registers is
> correct. Sorry to bother you.
> 
> It looks like this problem has to be fixed with a hammer. For some
> reason, the chip doesn't like the new values.
> 
> I'm off by about 7 seconds per minute:
> 
> Connected to platinum, wait...
>         platinum time was Mon Aug 20 10:10:10 2001
>            chaos time was Mon Aug 20 10:10:03 2001
>     Difference = 7 second(s)
>         platinum time was Mon Aug 20 10:10:11 2001
>            chaos time was Mon Aug 20 10:10:04 2001
>     Difference = 7 second(s)
>         platinum time was Mon Aug 20 10:10:11 2001
>            chaos time was Mon Aug 20 10:10:04 2001
>     Difference = 7 second(s)
>         platinum time was Mon Aug 20 10:10:12 2001
>            chaos time was Mon Aug 20 10:10:05 2001
>     Difference = 7 second(s)
>         platinum time was Mon Aug 20 10:10:12 2001
>            chaos time was Mon Aug 20 10:10:05 2001
>     Difference = 7 second(s)
>         platinum time was Mon Aug 20 10:10:13 2001
>            chaos time was Mon Aug 20 10:10:06 2001
>     Difference = 7 second(s)
>         platinum time was Mon Aug 20 10:10:13 2001
>            chaos time was Mon Aug 20 10:10:06 2001
>     Difference = 7 second(s)
> 
> Aborted by ^C
> 
> It gains time, meaning that the divisor is too small. Unfortunately,
> I can't read what was written to the actual chip. I can only detect
> its affect. 60 / 67 = 0.89 * 100 = 89. 1188200/89 = 13350 = 0x3426
> as a divisor. It doesn't make sense because both LSB and MSB are
> wrong. If one was wrong I could guess that the previous hadn't set
> up properly and needs more delay.
> 
> Anyway. I will continue to search.
> 
If you want to try, you can get close to what the chip is actually using
(with in 6-7 counts).  The counter if read back every interrupt by the
timer interrupt code and is used to compute:
		delay_at_last_interrupt = (count + LATCH/2) / LATCH;

This is done in ../arch/i386/kernel/time.c in the function
timer_interrupt().  To capture the value you could define a variable and
store count in it.  Possibly read this with /proc or more simply, use a
debugger to look at the value.  Or, even, set up a function to take the
max of several readings and printk the result.  The counter is reset to
the programmed value each interrupt (by hardware) and is counting down,
so it will be a few counts less than what was programmed.

George

P.S.  I wonder if the problem is related to other uses of LATCH...

G.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-08-20 16:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-17 13:23 Strange macros set HZ value for timer channel zero Richard B. Johnson
2001-08-17 19:27 ` george anzinger
2001-08-17 21:13   ` george anzinger
2001-08-20  1:11     ` Richard B. Johnson
2001-08-20 14:22   ` Richard B. Johnson
2001-08-20 16:55     ` george anzinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).