]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sys/timepps.h
ktrace: Record detailed ECAPMODE violations
[FreeBSD/FreeBSD.git] / sys / sys / timepps.h
1 /*-
2  * SPDX-License-Identifier: Beerware
3  *
4  * ----------------------------------------------------------------------------
5  * "THE BEER-WARE LICENSE" (Revision 42):
6  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
7  * can do whatever you want with this stuff. If we meet some day, and you think
8  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
9  * ----------------------------------------------------------------------------
10  *
11  * Copyright (c) 2011 The FreeBSD Foundation
12  *
13  * Portions of this software were developed by Julien Ridoux at the University
14  * of Melbourne under sponsorship from the FreeBSD Foundation.
15  *
16  * The is a FreeBSD version of the RFC 2783 API for Pulse Per Second 
17  * timing interfaces.  
18  */
19
20 #ifndef _SYS_TIMEPPS_H_
21 #define _SYS_TIMEPPS_H_
22
23 #include <sys/_ffcounter.h>
24 #include <sys/ioccom.h>
25 #include <sys/time.h>
26
27 #define PPS_API_VERS_1  1
28
29 typedef int pps_handle_t;       
30
31 typedef unsigned pps_seq_t;
32
33 typedef struct ntp_fp {
34         unsigned int    integral;
35         unsigned int    fractional;
36 } ntp_fp_t;
37
38 typedef union pps_timeu {
39         struct timespec tspec;
40         ntp_fp_t        ntpfp;
41         unsigned long   longpad[3];
42 } pps_timeu_t;
43
44 typedef struct {
45         pps_seq_t       assert_sequence;        /* assert event seq # */
46         pps_seq_t       clear_sequence;         /* clear event seq # */
47         pps_timeu_t     assert_tu;
48         pps_timeu_t     clear_tu;
49         int             current_mode;           /* current mode bits */
50 } pps_info_t;
51
52 typedef struct {
53         pps_seq_t       assert_sequence;        /* assert event seq # */
54         pps_seq_t       clear_sequence;         /* clear event seq # */
55         pps_timeu_t     assert_tu;
56         pps_timeu_t     clear_tu;
57         ffcounter       assert_ffcount;         /* ffcounter on assert event */
58         ffcounter       clear_ffcount;          /* ffcounter on clear event */
59         int             current_mode;           /* current mode bits */
60 } pps_info_ffc_t;
61
62 #define assert_timestamp        assert_tu.tspec
63 #define clear_timestamp         clear_tu.tspec
64
65 #define assert_timestamp_ntpfp  assert_tu.ntpfp
66 #define clear_timestamp_ntpfp   clear_tu.ntpfp
67
68 typedef struct {
69         int api_version;                        /* API version # */
70         int mode;                               /* mode bits */
71         pps_timeu_t assert_off_tu;
72         pps_timeu_t clear_off_tu;
73 } pps_params_t;
74
75 #define assert_offset   assert_off_tu.tspec
76 #define clear_offset    clear_off_tu.tspec
77
78 #define assert_offset_ntpfp     assert_off_tu.ntpfp
79 #define clear_offset_ntpfp      clear_off_tu.ntpfp
80
81 #define PPS_CAPTUREASSERT       0x01
82 #define PPS_CAPTURECLEAR        0x02
83 #define PPS_CAPTUREBOTH         0x03
84
85 #define PPS_OFFSETASSERT        0x10
86 #define PPS_OFFSETCLEAR         0x20
87
88 #define PPS_ECHOASSERT          0x40
89 #define PPS_ECHOCLEAR           0x80
90
91 #define PPS_CANWAIT             0x100
92 #define PPS_CANPOLL             0x200
93
94 #define PPS_TSFMT_TSPEC         0x1000
95 #define PPS_TSFMT_NTPFP         0x2000
96
97 #define PPS_TSCLK_FBCK          0x10000
98 #define PPS_TSCLK_FFWD          0x20000
99 #define PPS_TSCLK_MASK          0x30000
100
101 #define PPS_KC_HARDPPS          0
102 #define PPS_KC_HARDPPS_PLL      1
103 #define PPS_KC_HARDPPS_FLL      2
104
105 struct pps_fetch_args {
106         int tsformat;
107         pps_info_t      pps_info_buf;
108         struct timespec timeout;
109 };
110
111 struct pps_fetch_ffc_args {
112         int             tsformat;
113         pps_info_ffc_t  pps_info_buf_ffc;
114         struct timespec timeout;
115 };
116
117 struct pps_kcbind_args {
118         int kernel_consumer;
119         int edge;
120         int tsformat;
121 };
122
123 #define PPS_IOC_CREATE          _IO('1', 1)
124 #define PPS_IOC_DESTROY         _IO('1', 2)
125 #define PPS_IOC_SETPARAMS       _IOW('1', 3, pps_params_t)
126 #define PPS_IOC_GETPARAMS       _IOR('1', 4, pps_params_t)
127 #define PPS_IOC_GETCAP          _IOR('1', 5, int)
128 #define PPS_IOC_FETCH           _IOWR('1', 6, struct pps_fetch_args)
129 #define PPS_IOC_KCBIND          _IOW('1', 7, struct pps_kcbind_args)
130 #define PPS_IOC_FETCH_FFCOUNTER _IOWR('1', 8, struct pps_fetch_ffc_args)
131
132 #ifdef _KERNEL
133
134 struct mtx;
135
136 #define KCMODE_EDGEMASK         0x03
137 #define KCMODE_ABIFLAG          0x80000000 /* Internal use: abi-aware driver. */
138
139 #define PPS_ABI_VERSION         1
140
141 #define PPSFLAG_MTX_SPIN        0x01    /* Driver mtx is MTX_SPIN type. */
142
143 struct pps_state {
144         /* Capture information. */
145         struct timehands *capth;
146         struct fftimehands *capffth;
147         unsigned        capgen;
148         unsigned        capcount;
149
150         /* State information. */
151         pps_params_t    ppsparam;
152         pps_info_t      ppsinfo;
153         pps_info_ffc_t  ppsinfo_ffc;
154         int             kcmode;
155         int             ppscap;
156         struct timecounter *ppstc;
157         unsigned        ppscount[3];
158         /*
159          * The following fields are valid if the driver calls pps_init_abi().
160          */
161         uint16_t        driver_abi;     /* Driver sets before pps_init_abi(). */
162         uint16_t        kernel_abi;     /* Kernel sets during pps_init_abi(). */
163         struct mtx      *driver_mtx;    /* Optional, valid if non-NULL. */
164         uint32_t        flags;
165 };
166
167 void pps_capture(struct pps_state *pps);
168 void pps_event(struct pps_state *pps, int event);
169 void pps_init(struct pps_state *pps);
170 void pps_init_abi(struct pps_state *pps);
171 int pps_ioctl(unsigned long cmd, caddr_t data, struct pps_state *pps);
172 void hardpps(struct timespec *tsp, long nsec);
173
174 #else /* !_KERNEL */
175
176 static __inline int
177 time_pps_create(int filedes, pps_handle_t *handle)
178 {
179         int error;
180
181         *handle = -1;
182         error = ioctl(filedes, PPS_IOC_CREATE, 0);
183         if (error < 0) 
184                 return (-1);
185         *handle = filedes;
186         return (0);
187 }
188
189 static __inline int
190 time_pps_destroy(pps_handle_t handle)
191 {
192         return (ioctl(handle, PPS_IOC_DESTROY, 0));
193 }
194
195 static __inline int
196 time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams)
197 {
198         return (ioctl(handle, PPS_IOC_SETPARAMS, ppsparams));
199 }
200
201 static __inline int
202 time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams)
203 {
204         return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams));
205 }
206
207 static __inline int 
208 time_pps_getcap(pps_handle_t handle, int *mode)
209 {
210         return (ioctl(handle, PPS_IOC_GETCAP, mode));
211 }
212
213 static __inline int
214 time_pps_fetch(pps_handle_t handle, const int tsformat,
215         pps_info_t *ppsinfobuf, const struct timespec *timeout)
216 {
217         int error;
218         struct pps_fetch_args arg;
219
220         arg.tsformat = tsformat;
221         if (timeout == NULL) {
222                 arg.timeout.tv_sec = -1;
223                 arg.timeout.tv_nsec = -1;
224         } else
225                 arg.timeout = *timeout;
226         error = ioctl(handle, PPS_IOC_FETCH, &arg);
227         *ppsinfobuf = arg.pps_info_buf;
228         return (error);
229 }
230
231 static __inline int
232 time_pps_fetch_ffc(pps_handle_t handle, const int tsformat,
233         pps_info_ffc_t *ppsinfobuf, const struct timespec *timeout)
234 {
235         struct pps_fetch_ffc_args arg;
236         int error;
237
238         arg.tsformat = tsformat;
239         if (timeout == NULL) {
240                 arg.timeout.tv_sec = -1;
241                 arg.timeout.tv_nsec = -1;
242         } else {
243                 arg.timeout = *timeout;
244         }
245         error = ioctl(handle, PPS_IOC_FETCH_FFCOUNTER, &arg);
246         *ppsinfobuf = arg.pps_info_buf_ffc;
247         return (error);
248 }
249
250 static __inline int
251 time_pps_kcbind(pps_handle_t handle, const int kernel_consumer,
252         const int edge, const int tsformat)
253 {
254         struct pps_kcbind_args arg;
255
256         arg.kernel_consumer = kernel_consumer;
257         arg.edge = edge;
258         arg.tsformat = tsformat;
259         return (ioctl(handle, PPS_IOC_KCBIND, &arg));
260 }
261
262 #endif /* KERNEL */
263
264 #endif /* !_SYS_TIMEPPS_H_ */