On Thu, Jan 13, 2000 at 05:03:39PM +0100, Geert Uytterhoeven wrote:
> I used the R5000 CP0_COUNTER/CP0_COMPARE registers for the timer interrupt. I
> know it's not accurate, but it's better than nothing. I still have to figure
> out how more complex interrupts work in the MIPS source tree.
It is accurate as driven by the CPU's clock. It is just somewhat tricky to
handle and even more tricky on some broken CPUs. From an old email written
by Bill Earl:
As far as I know, all R4000 processors, and possibly some R4400 processors,
are affected. The bug is that, if you read $count exactly when it equals
$compare, the count/compare interrupt for that count/compare crossing is
discarded. The workaround from IRIX is appended. The variable
r4000_clock_war is set to 1 if the system is an Indy with an R4000 processor.
The r4k_compare_shadow is set to the same value as $compare whenever $compare
is updated (with interrupts masked while the variable and $compare are
Just calibrating the internal timer's value 100% exact is somewhat tricky.
The code used by the Indy generates a value that is somewhat off the
theoretical value. In practice I think it may be a good idea to meassure
the clock rate, the round it to the nearest frequency that is known to
be used with that system. Like rounding meassured 151MHz to 150MHz.
As for the time sources I think you best use a two-timer based scheme as
Intel or the Cobalt Qube 1/2. That will give you the low overhead of the
internal timer combined with the (hopefully!) higher precission of the
> Now we just have to do interrupts and PCI probing, and we're finished :-)
> The board has the 16 standard i8259 interrupts, and 15 additional interrupts
> on the host bridge. The i8259 is cascaded through one interrupt of the host
> bridge, similar to the cascading through the OpenPIC on my CHRP board.
> PCI is not connected to the i8259, but to the host bridge.
> I can program the host bridge to map any interrupt to any of the CPU
> interrupts (#0-#5 or NMI). I think the simplest way is to route them all
> through #0. Or do you think it's better not to do that, and e.g. route the
> timer interrupt (after I moved it from CP0_COUNTER/CP0_COMPARE to the PC
> style timer) to a different interrupt? Instead of the PC style timer, I
> could also use the general purpose timer in the host bridge.
What you want to do is to optimize the whole thing for the least interrupt
overhead. An uncached read from the bridge chip is probably reasonably fast
but polling c0_cause is faster. Given that the best thing to do will depend
on how many interrupts from what device you expect. In any case you should
consider that the i8259 is supposed to be slow even though I guess that's no
longer correct for modern implementations. Also the timer interrupt will
have to be the highest priority interrupt or you may deadlock, so your
arrangements should to ensure that this will be easy.