summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/sys/tsc.h
blob: d0511b9f096382cf9cf3daff4c0964ce0213ca3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2020 Joyent, Inc.
 */

#ifndef _TSC_H
#define	_TSC_H

#ifndef _ASM
#include <sys/linker_set.h>
#include <sys/types.h>
#endif

/*
 * flags to patch tsc_read routine.
 */
#define	TSC_NONE		0x0
#define	TSC_RDTSC_CPUID		0x1
/* formerly TSC_RDTSC_MFENCE	0x2 */
#define	TSC_RDTSC_LFENCE	0x3
#define	TSC_TSCP		0x4

#ifndef _ASM

/*
 * To register a TSC calibration source, a tsc_calibrate_t instance
 * should be created for the source, and then use
 * `TSC_CALIBRATION_SOURCE(<name_of_tsc_calibrate_t_instance_for_source>);`
 * to include it in the list of known sources.
 */
typedef struct tsc_calibrate {
	/*
	 * A descriptive name for the source. While this is mostly for the
	 * benefit of an operator, it may also be used to explicitly pick
	 * a specific source (vs. trying sources in order of preference).
	 * Each name should be unique (ignoring case).
	 */
	const char	*tscc_source;

	/*
	 * A preference value for this source. These values are largely
	 * arbitrary and are just to impose an order the sequence of
	 * sources to try (higher values of preference are tried before
	 * lower values of preference).
	 *
	 * Typically, any hypervisor provided sources will be preferred
	 * over hardware provided sources (i.e. cpuid), and higher precision
	 * hardware counters will be preferred over lower precision counters
	 * (e.g. HPET over PIT).
	 */
	uint_t		tscc_preference;

	/*
	 * The function that attempts calibration of the TSC. If the source
	 * cannot calibrate the TSC for any reason (e.g. the calibration source
	 * is not present or not supported on this machine), it should return
	 * B_FALSE.
	 *
	 * If the source is successful in measuring the TSC frequency, it
	 * should write the frequency of the TSC (in Hz) into the argument
	 * passed, e.g.
	 *
	 * boolean_t
	 * my_source(uint64_t *freq)
	 * {
	 *	...
	 *	*freq = measured_tsc_frequency;
	 *	return (B_TRUE);
	 * }
	 *
	 */
	boolean_t	(*tscc_calibrate)(uint64_t *);
} tsc_calibrate_t;
#define	TSC_CALIBRATION_SOURCE(x) DATA_SET(tsc_calibration_set, x)

uint64_t tsc_calibrate(void);
uint64_t tsc_get_freq(void);

#endif /* _ASM */

#endif /* _TSC_H */