3 * \brief time stamp counter related functions
5 * \date Frank Mehnert <fm3@os.inf.tu-dresden.de>
10 * (c) 2003-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
11 * economic rights: Technische Universität Dresden (Germany)
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU Lesser General Public License 2.1.
14 * Please see the COPYING-LGPL-2.1 file for details.
21 * \defgroup l4util_tsc Timestamp Counter
25 #include <l4/sys/compiler.h>
26 #include <l4/sys/l4int.h>
27 #include <l4/sys/kip.h>
32 extern l4_uint32_t l4_scaler_tsc_to_us;
33 extern l4_uint32_t l4_scaler_timer_to_tsc;
37 * \addtogroup l4util_tsc
41 #define L4_TSC_INIT_AUTO 0 ///< Automatic init
42 #define L4_TSC_INIT_KERNEL 1 ///< Initialized by kernel
43 #define L4_TSC_INIT_CALIBRATE 2 ///< Initialized by user-level
46 * \brief Read current value of CPU-internal time stamp counter.
47 * \return 64-bit time stamp
49 L4_INLINE l4_cpu_time_t
53 * \brief Read the lest significant 32 bit of the TSC.
55 * Useful for smaller differences, needs less cycles.
58 l4_uint32_t l4_rdtsc_32(void);
60 /** Convert time stamp into micro seconds value.
61 * \param tsc time value in CPU ticks
62 * \return time value in micro seconds
65 l4_tsc_to_us (l4_cpu_time_t tsc);
70 * \brief Calibrate scalers for time stamp calculations.
72 * Determine some scalers to be able to convert between real time and CPU
73 * ticks. This test uses channel 0 of the PIT (i8254) or the kernel KIP,
74 * depending on availability.
75 * Just calls l4_tsc_init(L4_TSC_INIT_AUTO).
78 l4_calibrate_tsc (l4_kernel_info_t *kip);
81 * \brief Initialitze scaler for TSC calicaltions.
83 * Initialize the scalers needed by l4_tsc_to_ns()/l4_ns_to_tsc() and so on.
84 * Current versions of Fiasco export these scalers from kernel into userland.
85 * The programmer may decide whether he allows to use these scalers or if an
86 * calibration should be performed.
87 * \param constraint programmers constraint:
88 * - #L4_TSC_INIT_AUTO if the kernel exports the scalers
89 * then use them. If not, perform calibration using
90 * channel 0 of the PIT (i8254). The latter case may
91 * lead into short (unpredictable) periods where
92 * interrupts are disabled.
93 * - #L4_TSC_INIT_KERNEL depend on retrieving the scalers
94 * from kernel. If the scalers are not available,
96 * - #L4_TSC_INIT_CALIBRATE Ignore possible scalers
97 * exported by the scaler, instead insist on
98 * calibration using the PIT.
99 * \param kip KIP pointer
100 * \return 0 on error (no scalers exported by kernel, calibrating failed ...)
101 * otherwise returns (2^32 / (tsc per µsec)). This value has the
102 * same semantics as the value returned by the calibrate_delay_loop()
103 * function of the Linux kernel.
106 l4_tsc_init (int constraint, l4_kernel_info_t *kip);
113 L4_INLINE l4_uint32_t
114 l4_calibrate_tsc (l4_kernel_info_t *kip)
116 return l4_tsc_init(0, kip);
119 L4_INLINE l4_cpu_time_t
122 l4_uint32_t upper = 0, lower = 0;
130 " cmpw %[upper], %%r12 \n"
132 : [upper] "=r" (upper),
139 tb = (tb << 32 | lower);
140 return tb * l4_scaler_timer_to_tsc;
144 l4_uint32_t l4_rdtsc_32(void)
150 : [lower] "=r" (lower));
152 return lower * l4_scaler_timer_to_tsc;
155 L4_INLINE l4_uint64_t
156 l4_tsc_to_us (l4_cpu_time_t tsc)
158 return tsc / l4_scaler_tsc_to_us;
162 #endif /* __l4_rdtsc_h */