2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
12 #ifndef _SYS_TIMETC_H_
13 #define _SYS_TIMETC_H_
16 * Structure used to interface to the machine dependent hardware support
19 * A timecounter is a (hard or soft) binary counter which has two properties:
20 * * it runs at a fixed, known frequency.
21 * * it must not roll over in less than (1 + delta)/HZ seconds. "delta"
22 * is expected to be less than 20 msec, but no hard data has been
23 * collected on this. 16 bit at 5 MHz (31 msec) is known to work.
25 * get_timecount() reads the counter.
27 * counter_mask removes unimplemented bits from the count value.
29 * frequency is the counter frequency in hz.
31 * name is a short mnemonic name for this counter.
33 * cost is a measure of how long time it takes to read the counter.
35 * adjustment [PPM << 16] which means that the smallest unit of correction
36 * you can apply amounts to 481.5 usec/year.
38 * scale_micro [2^32 * usec/tick].
39 * scale_nano_i [ns/tick].
40 * scale_nano_f [(ns/2^32)/tick].
42 * offset_count is the contents of the counter which corresponds to the
43 * rest of the offset_* values.
46 * offset_micro [usec].
47 * offset_nano [ns/2^32] is misnamed, the real unit is .23283064365...
48 * attoseconds (10E-18) and before you ask: yes, they are in fact
49 * called attoseconds, it comes from "atten" for 18 in Danish/Swedish.
51 * Each timecounter must supply an array of three timecounters, this is needed
52 * to guarantee atomicity in the code. Index zero is used to transport
53 * modifications, for instance done with sysctl, into the timecounter being
54 * used in a safe way. Such changes may be adopted with a delay of up to 1/HZ,
55 * index one & two are used alternately for the actual timekeeping.
57 * 'tc_avail' points to the next available (external) timecounter in a
58 * circular queue. This is only valid for index 0.
60 * `tc_other' points to the next "work" timecounter in a circular queue,
61 * i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER.
62 * We also use it to point from index 0 to index 1.
64 * `tc_tweak' points to index 0.
68 typedef unsigned timecounter_get_t(struct timecounter *);
69 typedef void timecounter_pps_t(struct timecounter *);
72 /* These fields must be initialized by the driver. */
73 timecounter_get_t *tc_get_timecount;
74 timecounter_pps_t *tc_poll_pps;
75 unsigned tc_counter_mask;
76 u_int32_t tc_frequency;
79 /* These fields will be managed by the generic code. */
80 int64_t tc_adjustment;
82 unsigned tc_offset_count;
83 struct bintime tc_offset;
84 struct timeval tc_microtime;
85 struct timespec tc_nanotime;
86 struct timecounter *tc_avail;
87 struct timecounter *tc_tweak;
88 /* Fields not to be copied in tc_windup start with tc_generation */
89 volatile unsigned tc_generation;
90 struct timecounter *tc_next;
94 extern struct timecounter *volatile timecounter;
96 void tc_init(struct timecounter *tc);
97 void tc_setclock(struct timespec *ts);
99 void tc_update(struct timecounter *tc);
100 #endif /* !_KERNEL */
102 #endif /* !_SYS_TIMETC_H_ */