Cyclic Backend - Timers - Counters
Status 06/06/2007
The decrementer exception and firing of the cyclic subsystem is functional. The rollover of the decrementer for a 10ms tick is set during the cbe_init, clock_init execution in main. The creation of an specific do_dec_interrupt() in intr.c was thought to be a way of keeping the operations seperate for debugging purposes. The dec irq functionality could easily be folded back into do_interrupt() once both are up.
The decrementer exception is taken in locore and clock_intr does a small bit of housekeeping before jumping to do_dec_interrupt(). It returns to locore to execute the _sys_rtt. This process takes you through the cyclic backend and interrupt processing for the 3 distinct clock related priorities.
Overview
Solaris has a concept of a cyclic subsystem, which has been designed to take advantage of chip architectures with the capacity to interrupt based on absolute, high resolution values of time.
Subsystem Overview: The cyclic subsystem is a low-level kernel subsystem designed to provide arbitrarily high resolution, per-CPU interval timers (to avoid colliding with existing terms, we dub such an interval timer a “cyclic”). Cyclics can be specified to fire at high, lock or low interrupt level, and may be optionally bound to a CPU or a CPU partition. A cyclic’s CPU or CPU partition binding may be changed dynamically; the cyclic will be “juggled” to a CPU which satisfies the new binding. Alternatively, a cyclic may be specified to be “omnipresent”, denoting firing on all online CPUs.
In the book Solaris Internals 2nd Ed the cyclic subsystem is covered in some detail but those who want to dive right into this would be better served to look at uts/common/os/cyclic.c and the overview that is embedded there.
Implementation
For the PPC architecture you have a decrementer that is programmable in it's count to generate an exception. The EE bit in the MSR, when set, will allow this processing to occur. Once a rollover has transpired the decrementer exception is pending and there is no way to clear it. The exception must be taken.
Addtionally there is a 64 bit Time Based Unit which is a free running counter sync'd in time with the decrementer count. They both run at 1/4 the bus frequency of the cpu. In the case of the ODW this is 33.333mhz.
So we use the decrementer to generate the exception but the TBU is similar to the x86 time stamp counter, much of the same approach was taken in processing the time gathered was done by subtituting the TBU for the TSC.
The two main files created are in chrp/io - cbe.c, hardclk.c. Initally started with the SPARC based files but ended up with an x86 like implementation. Some of the cyclic DTrace related funcs are temporarily located there. Also in hardclk.c the TOD and other periodic funcs.
TOD and other related items
The integration of the TOD functionality is pending. A small framework of TOD code was located in hardclk.c in order to get cbe up. The ODW does have an PC type TOD chip that hangs off of the southbridge so that bringing this is not an issue. The EFIKA and a number of other embedded type processors do not typically include them so alternative approaches need to be investigated.
The Host processor family (32 bit PPC) from Freescale require a Northbridge to be functional. The Marvell 64360 / 64460 family are utilized on the ODW target. These parts are targeted towards networking based applications and have multiple counters, timers that could be utilized in certain situations.