1 /*- 2 * Copyright (c) 2011 The University of Melbourne 3 * All rights reserved. 4 * 5 * This software was developed by Julien Ridoux at the University of Melbourne 6 * under sponsorship from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _SYS_TIMEFF_H_ 33 #define _SYS_TIMEFF_H_ 34 35 #include <sys/_ffcounter.h> 36 37 /* 38 * Feed-forward clock estimate 39 * Holds time mark as a ffcounter and conversion to bintime based on current 40 * timecounter period and offset estimate passed by the synchronization daemon. 41 * Provides time of last daemon update, clock status and bound on error. 42 */ 43 struct ffclock_estimate { 44 struct bintime update_time; /* Time of last estimates update. */ 45 ffcounter update_ffcount; /* Counter value at last update. */ 46 ffcounter leapsec_next; /* Counter value of next leap second. */ 47 uint64_t period; /* Estimate of counter period. */ 48 uint32_t errb_abs; /* Bound on absolute clock error [ns]. */ 49 uint32_t errb_rate; /* Bound on counter rate error [ps/s]. */ 50 uint32_t status; /* Clock status. */ 51 int16_t leapsec_total; /* All leap seconds seen so far. */ 52 int8_t leapsec; /* Next leap second (in {-1,0,1}). */ 53 }; 54 55 #if __BSD_VISIBLE 56 #ifdef _KERNEL 57 58 /* 59 * Parameters of counter characterisation required by feed-forward algorithms. 60 */ 61 #define FFCLOCK_SKM_SCALE 1024 62 63 /* 64 * Feed-forward clock status 65 */ 66 #define FFCLOCK_STA_UNSYNC 1 67 #define FFCLOCK_STA_WARMUP 2 68 69 /* 70 * Clock flags to select how the feed-forward counter is converted to absolute 71 * time by ffclock_convert_abs(). 72 * FAST: do not read the hardware counter, return feed-forward clock time 73 * at last tick. The time returned has the resolution of the kernel 74 * tick (1/hz [s]). 75 * LERP: linear interpolation of ffclock time to guarantee monotonic time. 76 * LEAPSEC: include leap seconds. 77 * UPTIME: removes time of boot. 78 */ 79 #define FFCLOCK_FAST 1 80 #define FFCLOCK_LERP 2 81 #define FFCLOCK_LEAPSEC 4 82 #define FFCLOCK_UPTIME 8 83 84 /* Resets feed-forward clock from RTC */ 85 void ffclock_reset_clock(struct timespec *ts); 86 87 /* 88 * Return the current value of the feed-forward clock counter. Essential to 89 * measure time interval in counter units. If a fast timecounter is used by the 90 * system, may also allow fast but accurate timestamping. 91 */ 92 void ffclock_read_counter(ffcounter *ffcount); 93 94 /* 95 * Retrieve feed-forward counter value and time of last kernel tick. This 96 * accepts the FFCLOCK_LERP flag. 97 */ 98 void ffclock_last_tick(ffcounter *ffcount, struct bintime *bt, uint32_t flags); 99 100 /* 101 * Low level routines to convert a counter timestamp into absolute time and a 102 * counter timestamp interval into an interval in seconds. The absolute time 103 * conversion accepts the FFCLOCK_LERP flag. 104 */ 105 void ffclock_convert_abs(ffcounter ffcount, struct bintime *bt, uint32_t flags); 106 void ffclock_convert_diff(ffcounter ffdelta, struct bintime *bt); 107 108 /* 109 * Feed-forward clock routines. 110 * 111 * These functions rely on the timecounters and ffclock_estimates stored in 112 * fftimehands. Note that the error_bound parameter is not the error of the 113 * clock but an upper bound on the error of the absolute time or time interval 114 * returned. 115 * 116 * ffclock_abstime(): retrieves current time as counter value and convert this 117 * timestamp in seconds. The value (in seconds) of the converted timestamp 118 * depends on the flags passed: for a given counter value, different 119 * conversions are possible. Different clock models can be selected by 120 * combining flags (for example (FFCLOCK_LERP|FFCLOCK_UPTIME) produces 121 * linearly interpolated uptime). 122 * ffclock_difftime(): computes a time interval in seconds based on an interval 123 * measured in ffcounter units. This should be the preferred way to measure 124 * small time intervals very accurately. 125 */ 126 void ffclock_abstime(ffcounter *ffcount, struct bintime *bt, 127 struct bintime *error_bound, uint32_t flags); 128 void ffclock_difftime(ffcounter ffdelta, struct bintime *bt, 129 struct bintime *error_bound); 130 131 #endif /* _KERNEL */ 132 #endif /* __BSD_VISIBLE */ 133 #endif /* _SYS_TIMEFF_H_ */ 134