1a9643ea8Slogwang /*- 2*22ce4affSfengbojiang * SPDX-License-Identifier: Beerware 3*22ce4affSfengbojiang * 4a9643ea8Slogwang * ---------------------------------------------------------------------------- 5a9643ea8Slogwang * "THE BEER-WARE LICENSE" (Revision 42): 6a9643ea8Slogwang * <[email protected]> wrote this file. As long as you retain this notice you 7a9643ea8Slogwang * can do whatever you want with this stuff. If we meet some day, and you think 8a9643ea8Slogwang * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 9a9643ea8Slogwang * ---------------------------------------------------------------------------- 10a9643ea8Slogwang * 11a9643ea8Slogwang * $FreeBSD$ 12a9643ea8Slogwang */ 13a9643ea8Slogwang 14a9643ea8Slogwang #ifndef _SYS_TIMETC_H_ 15a9643ea8Slogwang #define _SYS_TIMETC_H_ 16a9643ea8Slogwang 17a9643ea8Slogwang #ifndef _KERNEL 18a9643ea8Slogwang #error "no user-serviceable parts inside" 19a9643ea8Slogwang #endif 20a9643ea8Slogwang 21a9643ea8Slogwang /*- 22a9643ea8Slogwang * `struct timecounter' is the interface between the hardware which implements 23a9643ea8Slogwang * a timecounter and the MI code which uses this to keep track of time. 24a9643ea8Slogwang * 25a9643ea8Slogwang * A timecounter is a binary counter which has two properties: 26a9643ea8Slogwang * * it runs at a fixed, known frequency. 27a9643ea8Slogwang * * it has sufficient bits to not roll over in less than approximately 28a9643ea8Slogwang * max(2 msec, 2/HZ seconds). (The value 2 here is really 1 + delta, 29a9643ea8Slogwang * for some indeterminate value of delta.) 30a9643ea8Slogwang */ 31a9643ea8Slogwang 32a9643ea8Slogwang struct timecounter; 33*22ce4affSfengbojiang struct vdso_timehands; 34*22ce4affSfengbojiang struct vdso_timehands32; 35a9643ea8Slogwang typedef u_int timecounter_get_t(struct timecounter *); 36a9643ea8Slogwang typedef void timecounter_pps_t(struct timecounter *); 37*22ce4affSfengbojiang typedef uint32_t timecounter_fill_vdso_timehands_t(struct vdso_timehands *, 38*22ce4affSfengbojiang struct timecounter *); 39*22ce4affSfengbojiang typedef uint32_t timecounter_fill_vdso_timehands32_t(struct vdso_timehands32 *, 40*22ce4affSfengbojiang struct timecounter *); 41a9643ea8Slogwang 42a9643ea8Slogwang struct timecounter { 43a9643ea8Slogwang timecounter_get_t *tc_get_timecount; 44a9643ea8Slogwang /* 45a9643ea8Slogwang * This function reads the counter. It is not required to 46a9643ea8Slogwang * mask any unimplemented bits out, as long as they are 47a9643ea8Slogwang * constant. 48a9643ea8Slogwang */ 49a9643ea8Slogwang timecounter_pps_t *tc_poll_pps; 50a9643ea8Slogwang /* 51a9643ea8Slogwang * This function is optional. It will be called whenever the 52a9643ea8Slogwang * timecounter is rewound, and is intended to check for PPS 53a9643ea8Slogwang * events. Normal hardware does not need it but timecounters 54a9643ea8Slogwang * which latch PPS in hardware (like sys/pci/xrpu.c) do. 55a9643ea8Slogwang */ 56a9643ea8Slogwang u_int tc_counter_mask; 57a9643ea8Slogwang /* This mask should mask off any unimplemented bits. */ 58a9643ea8Slogwang uint64_t tc_frequency; 59a9643ea8Slogwang /* Frequency of the counter in Hz. */ 60a9643ea8Slogwang const char *tc_name; 61a9643ea8Slogwang /* Name of the timecounter. */ 62a9643ea8Slogwang int tc_quality; 63a9643ea8Slogwang /* 64a9643ea8Slogwang * Used to determine if this timecounter is better than 65a9643ea8Slogwang * another timecounter higher means better. Negative 66a9643ea8Slogwang * means "only use at explicit request". 67a9643ea8Slogwang */ 68a9643ea8Slogwang u_int tc_flags; 69a9643ea8Slogwang #define TC_FLAGS_C2STOP 1 /* Timer dies in C2+. */ 70a9643ea8Slogwang #define TC_FLAGS_SUSPEND_SAFE 2 /* 71a9643ea8Slogwang * Timer functional across 72a9643ea8Slogwang * suspend/resume. 73a9643ea8Slogwang */ 74a9643ea8Slogwang 75a9643ea8Slogwang void *tc_priv; 76a9643ea8Slogwang /* Pointer to the timecounter's private parts. */ 77a9643ea8Slogwang struct timecounter *tc_next; 78a9643ea8Slogwang /* Pointer to the next timecounter. */ 79*22ce4affSfengbojiang timecounter_fill_vdso_timehands_t *tc_fill_vdso_timehands; 80*22ce4affSfengbojiang timecounter_fill_vdso_timehands32_t *tc_fill_vdso_timehands32; 81a9643ea8Slogwang }; 82a9643ea8Slogwang 83a9643ea8Slogwang extern struct timecounter *timecounter; 84a9643ea8Slogwang extern int tc_min_ticktock_freq; /* 85a9643ea8Slogwang * Minimal tc_ticktock() call frequency, 86a9643ea8Slogwang * required to handle counter wraps. 87a9643ea8Slogwang */ 88a9643ea8Slogwang 89a9643ea8Slogwang u_int64_t tc_getfrequency(void); 90a9643ea8Slogwang void tc_init(struct timecounter *tc); 91a9643ea8Slogwang void tc_setclock(struct timespec *ts); 92a9643ea8Slogwang void tc_ticktock(int cnt); 93a9643ea8Slogwang void cpu_tick_calibration(void); 94a9643ea8Slogwang 95a9643ea8Slogwang #ifdef SYSCTL_DECL 96a9643ea8Slogwang SYSCTL_DECL(_kern_timecounter); 97a9643ea8Slogwang #endif 98a9643ea8Slogwang 99a9643ea8Slogwang #endif /* !_SYS_TIMETC_H_ */ 100