> > The 32-bit register is both readable and writable through the MTC0 and MFC0
> > instructions as CP0 register 9. Upon reset, the Count register is set to 0.
> > Count and Compare together make up Timer_1 in the PR4450 (see Section 3.12).
> > The timer is active by default. When active, Count register contains a free
> > running counter; on each processor clock-tick, the value in the register
> > increments
> > by one. However, when bit ST1 bit[3] in the CP0 Configuration register is
> > enabled,
> > the timer is stopped. When the ST1 bit is disabled, the timer returns to
> > its default
> > state. Timer_1 is active when the PR4450 is in Sleep mode, but is switched
> > off when
> > the PR4450 is in Coma mode.
> > When active, the register can be reset with the assertion of the
> > TerminalCount
> > (TC_1) signal, which is asserted when the values in the Count and Compare
> > registers match. After the Count register is reset, it restarts its count
> > on the next
> > processor clock-tick.
> > In the PR4450, the TC_1 signal is fed to the external hardware interrupt
> > signal to invoke an interrupt handler e.g., the timer interrupt. The TC_1
> > signal can
> > only be reset to 0 when the interrupt handler performs a write to the
> > Compare
> > register.
> > Consecutive writes to Count will result in undefined contents. At least one
> > instruction must be inserted between consecutive writes to Count.
>
> > This seems to suggest that writing to the compare register does in fact
> > clear count.
>
> It actually doesn't suggest anything alike. All it says is that "the
> register *can* be reset with the assertion of the Terminal Count (TC_1)
> signal
> which is asserted when the values in the Count and Compare registers match".
> Whtat it doesn't say is what determines if it's really reset by TC_1
> assertion
> or not.
In all fairness, the spec can be read to state that the assertion of TC_1 clears
the Count register. Or rather that it "can" - there seems to be some assumed
mode of behavior that's not otherwise described. I wonder if they're not
talking about behavior specifc to "Coma mode", which was perhaps what
they are referring to when they begin the next sentence with "When active".
I can see how someone might think it advantageous to have a mode where
the Count register auto-resets on a timer tick, so that there's no need to
recalcuate Compare values. But I've never seen that implemented on a
MIPS processor. Free-running Count registers have other uses that can
be shared with the timer interrupts, so long as it's Compare and not Count
that gets reprogrammed on an interrupt. I have a hard time believing that
the 8550 has the auto-reset as default behavior.
> > If I do the following:
> > static void __init c0_hpt_timer_init(void)
> > {
> > #ifdef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */
> > expirelo = cycles_per_jiffy;
> > #else
> > expirelo = read_c0_count() + cycles_per_jiffy;
> > #endif
> > write_c0_compare(expirelo);
> > write_c0_count(cycles_per_jiffy); //Added DJL
> > }
First of all, I think the conditional code is broken, even if you
believe that Count is reset to zero on every interrupt. This is
the *init* code, that's getting called once at boot time to set
up the clock. It's not a clock interrupt handler.
It is highly likely that the Count register has already gone
beyond the value of cycles_per_jiffy by the time this code
gets hit. If that's true, programming Compare to zero+delta
means waiting for the counter to wrap around before the first
interrupt is delivered - a 10-second-ish hang. Writing the same
value to Count that you just wrote to Compare will, on many
cores, cause a Count=Compare state and a prompt interrupt.
But the real fix is almost certainly to get rid of the conditional.
Regards,
Kevin K.
|