Subject: [simonb-timecounters] branch updated & status
To: None <tech-kern@netbsd.org>
From: Frank Kardel <kardel@netbsd.org>
List: tech-kern
Date: 06/03/2006 13:24:54
Status update:

The simonb-timecounters branch was synced to head on 20060531.
Currently the ports i386, amd64, sparc and sparc64 have been converted
to timecounters.
I am out of test-accessible hardware now... so...

I sketched what is needed to convert a port to timecounters.
A current version of the description and the current status
of the time counter project can be found on
http://www.kardel.name/timecounters-status.html.

below is a copy if the section describing the conversion:


                  Converting a port to Timecounters

Ideally all ports should be converted to timecounters so that the old
microtime implementation can be completely retired and we can get rid of
the dual code (__HAVE_TIMECOUNTER). The requirements for timecounter
support are minimal. The porting strategies are as follows:

Common steps to perform:

    1. #define __HAVE_TIMECOUNTER in arch/<arch>/include/types.h
    2. register a struct timecounter timecountername with
       tc_init(&timecountername) during/close to clock interrupt
       initialization
    3. implement the timecounter reading function (referred to in
       timecountername)
    4. remove any support/references to cc_microtime/kern_microtime.c
    5. correct initial time setting (eg. inittodr()).
       struct time is gone. the current second is found in time_second,
       the mono time seconds value is in time_uptime.
       time setting is achieved by calling tc_setclock(struct timespec *)
    6. compile & test.

Requirements for timecounter implementations:

     * fixed frequency incrementing counter wrapping at a power of two.
     * counter must not wrap within 2/hz - if the counter is wrapping too
       fast consider increasing hz (e.g. ELAN SC520 boards need a HZ of
       150 to utililze the counter in that architecture)
     * if no hardware counters exist for microtime interpolation then a
       port may quickly be converted by fixing the setting of the clock
       and defining __HAVE_TIMECOUNTER as a default timecounter
       "clockinterrupt" based on clock ticks is always registered.
     * count down counters must be converted to up counting ones (result
       = MAX_COUNT - current_count). see arch/i386/isa/clock.c for the
       i8254 implementation.
     * counters not wrapping at a power of two need to be converted. see
       also arch/i386/isa/clock.c for examples.
     * you need splhigh() guards when you need to manipulate/access state
       that is updated by clock interrupts or by counter reading. This
       includes chip access (address, data phases) and local state
       manipulation for emulation of power of two timers.
     * for MP operation you need to insure that the returned counter
       values are consistent across cpus. either a single and atomically
       readable hw counter is available or the cpu local counter can be
       scaled to match the counter on CPU_PRIMARY(ci). see
       arch/x86/x86/tsc.c for example. otherwise locking needs to be
       used.

regards
  Frank