qtime

Information about the timebase present on the system, as well as other time-related information.

nsec and nsec_tod_adjust

The startup library's init_qtime() fills the qtime data structures, which consist of the the following:

cycles_per_sec
For ClockCycles().
nsec_tod_adjust
When added to the value in nsec, gives the number of nanoseconds from the start of the epoch (1970).
nsec
The number of nanoseconds since the system was booted.
nsec_inc
The number of nanoseconds deemed to have elapsed each time the clock triggers an interrupt.
boot_time
Seconds since Jan 1 1970 00:00:00 GMT when the system was booted.
If you call ClockTime() to set the time of day, the kernel checks to see if this field is zero. If it is zero, the kernel sets it to the appropriate value. All startup programs support a -T option that prevents the setting of this field, so that the kernel sets it the first time you call ClockTime() to change the time of day. This feature is useful if the RTC hardware isn't in UTC.
adjust
Set to zero at startup. Contains any current timebase adjustment runtime parameters (as specified by the kernel call ClockAdjust()).
timer_rate
Used in conjunction with timer_scale (see timer_load below).
timer_scale
See timer_load below.
timer_load
Timer chip divisor value. The startup program leaves this zero. The kernel sets it based on the last ClockPeriod() and timer_rate/timer_scale values to a number, which is then put into the timer chip by the timer_load/timer_reload kernel callouts.
intr
Contains the interrupt vector that the clock chip uses to interrupt the processor.
epoch
Currently set to 1970, but not used.
flags
Indicates when timer hardware is specific to CPU0 (see flags below).
rr_interval_mul
Reserved.
spare0
Not used.
nsec_stable
Reserved.
spare
Not used.

The nsec field is always increasing monotonically. It is never affected by setting the current time of day via ClockTime() or ClockAdjust().

Since both nsec and nsec_tod_adjust are modified in the kernel's timer interrupt handler and are too big to load in an atomic read operation, to inspect them you must either:

timer_rate and timer_scale

The values in the timer_rate and timer_scale fields relate to the external counter chip's input frequency, in Hz, as follows:

Yes, this relationship does imply that timer_scale is a negative number. The goal when expressing the relationship is to make timer_rate as large as possible in order to maximize the number of significant digits available during calculations.

For example, on an x86 system the values might be 838095345UL for the timer_rate and -15 for the timer_scale. This indicates that the timer value is specified in femtoseconds (the -15 means “ten to the power of negative fifteen”); the actual value is 838,095,345 femtoseconds (approximately 838 nanoseconds).

If the clock on your system drifts, you should make sure that the startup code specifies the correct clock frequency. You can use the -f option in the startup command to override the setting in the code.

flags

This bit: Means that:
QTIME_FLAG_TIMER_ON_CPU0 Timer hardware is specific to CPU0.
QTIME_FLAG_CHECK_STABLE  
QTIME_FLAG_TICKLESS Tickless operation is supported. For more information, see "Clocks, timers, and power management" in the Tick, Tock: Understanding the Microkernel's Concept of Time chapter of the Programmer's Guide.
QTIME_FLAG_GLOBAL_CLOCKCYCLES Clockcycles is synchronized between all processors on the system.