1/*-
  2 * SPDX-License-Identifier: BSD-2-Clause
  3 *
  4 * Copyright 2012 Konstantin Belousov <kib@FreeBSD.ORG>.
  5 * All rights reserved.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions
  9 * are met:
 10 * 1. Redistributions of source code must retain the above copyright
 11 *    notice, this list of conditions and the following disclaimer.
 12 * 2. Redistributions in binary form must reproduce the above copyright
 13 *    notice, this list of conditions and the following disclaimer in the
 14 *    documentation and/or other materials provided with the distribution.
 15 *
 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 26 */
 27
 28#ifndef _SYS_VDSO_H
 29#define	_SYS_VDSO_H
 30
 31#include <sys/types.h>
 32#include <machine/vdso.h>
 33
 34struct vdso_timehands {
 35	uint32_t	th_algo;
 36	uint32_t	th_gen;
 37	uint64_t	th_scale;
 38	uint32_t 	th_offset_count;
 39	uint32_t	th_counter_mask;
 40	struct bintime	th_offset;
 41	struct bintime	th_boottime;
 42	VDSO_TIMEHANDS_MD
 43};
 44
 45struct vdso_timekeep {
 46	uint32_t	tk_ver;
 47	uint32_t	tk_enabled;
 48	uint32_t	tk_current;
 49	struct vdso_timehands	tk_th[];
 50};
 51
 52#define	VDSO_TK_CURRENT_BUSY	0xffffffff
 53#define	VDSO_TK_VER_1		0x1
 54#define	VDSO_TK_VER_CURR	VDSO_TK_VER_1
 55#define	VDSO_TH_ALGO_1		0x1
 56#define	VDSO_TH_ALGO_2		0x2
 57#define	VDSO_TH_ALGO_3		0x3
 58#define	VDSO_TH_ALGO_4		0x4
 59
 60struct vdso_fxrng_generation_1 {
 61	uint32_t	fx_vdso_version;	/* 1 */
 62	uint32_t	fx_generation32;
 63	uint64_t	_fx_reserved;
 64};
 65_Static_assert(sizeof(struct vdso_fxrng_generation_1) == 16, "");
 66#define	vdso_fxrng_generation	vdso_fxrng_generation_1
 67
 68/* fx_vdso_version values: */
 69#define	VDSO_FXRNG_VER_1	0x1
 70#define	VDSO_FXRNG_VER_CURR	VDSO_FXRNG_VER_1
 71
 72#ifndef _KERNEL
 73
 74struct timespec;
 75struct timeval;
 76struct timezone;
 77
 78int __vdso_clock_gettime(clockid_t clock_id, struct timespec *ts);
 79int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz);
 80int __vdso_gettc(const struct vdso_timehands *vdso_th, u_int *tc);
 81int __vdso_gettimekeep(struct vdso_timekeep **tk);
 82
 83#endif
 84
 85#ifdef _KERNEL
 86
 87struct timecounter;
 88
 89struct vdso_sv_tk {
 90	int		sv_timekeep_off;
 91	int		sv_timekeep_curr;
 92	uint32_t	sv_timekeep_gen;
 93};
 94
 95#ifdef RANDOM_FENESTRASX
 96void fxrng_push_seed_generation(uint64_t gen);
 97#endif
 98void timekeep_push_vdso(void);
 99
100uint32_t tc_fill_vdso_timehands(struct vdso_timehands *vdso_th);
101
102/*
103 * The cpu_fill_vdso_timehands() function should fill MD-part of the
104 * struct vdso_timehands, which is both machine- and
105 * timecounter-depended. The return value should be 1 if fast
106 * userspace timecounter is enabled by hardware, and 0 otherwise. The
107 * global sysctl enable override is handled by machine-independed code
108 * after cpu_fill_vdso_timehands() call is made.
109 */
110uint32_t cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th,
111    struct timecounter *tc);
112
113struct vdso_sv_tk *alloc_sv_tk(void);
114
115#define	VDSO_TH_NUM	4
116
117#ifdef COMPAT_FREEBSD32
118
119/*
120 * i386 is the only arch with a 32 bit time_t.
121 */
122struct bintime32 {
123#if defined(__amd64__)
124	uint32_t	sec;
125#else
126	uint64_t	sec;
127#endif
128	uint32_t	frac[2];
129};
130
131struct vdso_timehands32 {
132	uint32_t	th_algo;
133	uint32_t	th_gen;
134	uint32_t	th_scale[2];
135	uint32_t 	th_offset_count;
136	uint32_t	th_counter_mask;
137	struct bintime32	th_offset;
138	struct bintime32	th_boottime;
139	VDSO_TIMEHANDS_MD32
140};
141
142struct vdso_timekeep32 {
143	uint32_t	tk_ver;
144	uint32_t	tk_enabled;
145	uint32_t	tk_current;
146	struct vdso_timehands32	tk_th[];
147};
148
149uint32_t tc_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32);
150uint32_t cpu_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32,
151    struct timecounter *tc);
152struct vdso_sv_tk *alloc_sv_tk_compat32(void);
153
154#endif
155#endif
156
157#endif