2.2.18pre17 again
Gabriel Paubert
paubert at iram.es
Wed Nov 1 04:20:08 EST 2000
On Tue, 31 Oct 2000, Benjamin Herrenschmidt wrote:
> >
> >Why isn't udelay based on the timebase then ? Easy to scale
> >microseconds to timebase.
>
> Because you didn't implement it yet ? :)
Perhaps...
>
> >There is a multiplier for mulhwu somewhere in a global variable, I should
> >remember the name since I wrote the code, tb_to_us if I'm not messing up.
>
> Do we have that code in 2.2 ? Your time management patches are in 2.4
> only AFAIK (nice code BTW).
Well, maybe. I'm sure they are in my local 2.2 tree, which is still at
2.2.12, because I absolutely needed them for production: otherwise clocks
were drifting randomly by up to several milliseconds even when controlled
by NTP. In my case a clock off by 5 milliseconds is basically the same as
no clock ;-)
> >It needs some care for 601 because of the different registers (RTC) that
> >has the bad habit of jumping from 1e9 to 0. It is trivial to implement as
> >a subroutine and check for CPU inside the subroutine. After all it's a
> >delay, so performance should not be critical.
> >
> >udelay:
> > lis r4,tb_to_us at ha
> > mfpvr r5
> > lwz r4,tb_to_us at l(r4)
> > srwi r5,r5,16
> > mulhwu r4,r3,r4
> > cmpwi cr0,r5,1
> > beq 2f
> > mftbl r5
> >1: mftbl r3
> > sub r3,r3,r5
> > cmplw cr0,r3,r4 # works for delays of up to almost 2^32 tb ticks
> > blt cr0,1b
> > blr
> >
> >2: mfrtcl r5
> >3: mfrtcl r3
> > sub. r3,r3,r5 # if wraparound has occurred
> > bnl+ 4f # bump elapsed time by one second
> > addis r3,r3,1000000000 at ha
> > addi r3,r3,1000000000 at l
> >4: cmplw cr0,r3,r4 # works for delays of up to almost 1 second
> > blt cr0,3b
> > blr
> >
>
> What is the max delay supported ? I beleive we should implement it as
> __udelay and keept the macro mecanism to catch too high delays.
It's in the comments: 1 second for 601, 2^32 timebase ticks for the other
(minus maximum interrupt + bh running time if interrupts are enabled).
Catching too long delays in the macros is ok, but the code can also catch
it at runtime since it's only a few instructions in the subroutine:
andis. r0,r3,0xfffe; bne- what_are_you_smoking
will limit the udelay constant to about 0.13 second (131072 microseconds
to be exact). Of course at what_are_you_smoking the kernel starts a
complex process to find the author of the offending code and fulminate
him/her ;-): udelay values above a few hundred are almost always the
result of laziness or careless programming.
Even with a 33 MHz timebase (keep dreaming), the maximal delay for non
601 CPUs is over 100 seconds. However, there is one problem if we start
having preemptible kernels, especially for 601: a preempted udelay
could be lengthened by multiples of 1 second. There is a solution to this
problem, but it requires reading the rtcu and doing all the math on every
iteration. I just did not feel like writing it, especially since I
can't test it. Put a big warning in a comment if necessary. It should also
be properly ifdefed so that when CONFIG_6XX is off, the 601 check and code
is removed.
Gabriel.
BTW: is anybody interested in high resolution timers ? (Higher resolution
than one jiffy I mean). It should be relatively easy now that timing code
is cleaned up. But I won't have time to look at it for a few weeks...
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list