1/* 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 * ---------------------------------------------------------------------------- 8 *
| 1/* 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 * ---------------------------------------------------------------------------- 8 *
|
9 * $FreeBSD: head/sys/sys/timetc.h 95530 2002-04-26 21:51:08Z phk $
| 9 * $FreeBSD: head/sys/sys/timetc.h 95661 2002-04-28 18:24:21Z phk $
|
10 */ 11 12#ifndef _SYS_TIMETC_H_ 13#define _SYS_TIMETC_H_ 14 15/*
| 10 */ 11 12#ifndef _SYS_TIMETC_H_ 13#define _SYS_TIMETC_H_ 14 15/*
|
16 * Structure used to interface to the machine dependent hardware support 17 * for timekeeping.
| 16 * Struct timecounter is the interface between the hardware which implements 17 * a timecounter and the MI code which uses this to keep track of time.
|
18 *
| 18 *
|
19 * A timecounter is a (hard or soft) binary counter which has two properties:
| 19 * A timecounter is a binary counter which has two properties:
|
20 * * it runs at a fixed, known frequency.
| 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.
| 21 * * it has sufficient bits to not roll over in faster than approx 22 * 2 msec or 2/hz, whichever is faster. (The value of 2 here is 23 * really 1 + delta, for some indeterminate value of delta).
|
24 *
| 24 *
|
25 * get_timecount() reads the counter. 26 * 27 * counter_mask removes unimplemented bits from the count value. 28 * 29 * frequency is the counter frequency in hz. 30 * 31 * name is a short mnemonic name for this counter. 32 * 33 * cost is a measure of how long time it takes to read the counter. 34 * 35 * adjustment [PPM << 16] which means that the smallest unit of correction 36 * you can apply amounts to 481.5 usec/year. 37 * 38 * scale_micro [2^32 * usec/tick]. 39 * scale_nano_i [ns/tick]. 40 * scale_nano_f [(ns/2^32)/tick]. 41 * 42 * offset_count is the contents of the counter which corresponds to the 43 * rest of the offset_* values. 44 * 45 * offset_sec [s]. 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. 50 * 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. 56 * 57 * 'tc_avail' points to the next available (external) timecounter in a 58 * circular queue. This is only valid for index 0. 59 * 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. 63 * 64 * `tc_tweak' points to index 0.
| |
65 */ 66 67struct timecounter;
| 25 */ 26 27struct timecounter;
|
68typedef unsigned timecounter_get_t(struct timecounter *);
| 28typedef u_int timecounter_get_t(struct timecounter *);
|
69typedef void timecounter_pps_t(struct timecounter *); 70 71struct timecounter {
| 29typedef void timecounter_pps_t(struct timecounter *); 30 31struct timecounter {
|
72 /* These fields must be initialized by the driver. */
| |
73 timecounter_get_t *tc_get_timecount;
| 32 timecounter_get_t *tc_get_timecount;
|
| 33 /* 34 * This function reads the counter. It is not required to 35 * mask any unimplemented bits out, as long as they are 36 * constant. 37 */
|
74 timecounter_pps_t *tc_poll_pps;
| 38 timecounter_pps_t *tc_poll_pps;
|
75 unsigned tc_counter_mask;
| 39 /* 40 * This function is optional, it will be called whenever the 41 * timecounter is rewound, and is intended to check for PPS 42 * events. Most hardware do not need it. 43 */ 44 u_int tc_counter_mask; 45 /* This mask should mask off any unimplemnted bits. */
|
76 u_int32_t tc_frequency;
| 46 u_int32_t tc_frequency;
|
| 47 /* Frequency of the counter in Hz. */
|
77 char *tc_name;
| 48 char *tc_name;
|
| 49 /* Name of the counter. */
|
78 void *tc_priv;
| 50 void *tc_priv;
|
| 51 /* Pointer to the counters private parts. */
|
79 struct timecounter *tc_next;
| 52 struct timecounter *tc_next;
|
| 53 /* Initialize this to NUL */
|
80}; 81 82#ifdef _KERNEL 83extern struct timecounter *timecounter; 84 85u_int32_t tc_getfrequency(void); 86void tc_init(struct timecounter *tc); 87void tc_setclock(struct timespec *ts); 88#endif /* !_KERNEL */ 89 90#endif /* !_SYS_TIMETC_H_ */
| 54}; 55 56#ifdef _KERNEL 57extern struct timecounter *timecounter; 58 59u_int32_t tc_getfrequency(void); 60void tc_init(struct timecounter *tc); 61void tc_setclock(struct timespec *ts); 62#endif /* !_KERNEL */ 63 64#endif /* !_SYS_TIMETC_H_ */
|