L4Re – L4 Runtime Environment
rdtsc.h
Go to the documentation of this file.
1 
9 /*
10  * (c) 2003-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
11  * Alexander Warg <warg@os.inf.tu-dresden.de>,
12  * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
13  * economic rights: Technische Universität Dresden (Germany)
14  * This file is part of TUD:OS and distributed under the terms of the
15  * GNU Lesser General Public License 2.1.
16  * Please see the COPYING-LGPL-2.1 file for details.
17  */
18 
19 #ifndef __l4_rdtsc_h
20 #define __l4_rdtsc_h
21 
27 #include <l4/sys/compiler.h>
28 #include <l4/sys/l4int.h>
29 #include <l4/sys/kip.h>
30 
32 
33 /* interface */
38 
39 #define L4_TSC_INIT_AUTO 0
40 #define L4_TSC_INIT_KERNEL 1
41 #define L4_TSC_INIT_CALIBRATE 2
42 
43 extern l4_uint32_t l4_scaler_tsc_to_ns;
44 extern l4_uint32_t l4_scaler_tsc_to_us;
45 extern l4_uint32_t l4_scaler_ns_to_tsc;
46 extern l4_uint32_t l4_scaler_tsc_linux;
47 
52 L4_INLINE l4_cpu_time_t
53 l4_rdtsc (void);
54 
60 L4_INLINE
62 
69 L4_INLINE l4_uint64_t
70 l4_rdpmc (int ecx);
71 
77 L4_INLINE
78 l4_uint32_t l4_rdpmc_32(int ecx);
79 
84 L4_INLINE l4_uint64_t
86 
91 L4_INLINE l4_uint64_t
93 
99 L4_INLINE void
101 
107 L4_INLINE l4_cpu_time_t
109 
115 L4_INLINE void
117 
123 L4_INLINE void
125 
127 
136 L4_INLINE l4_uint32_t
138 
165 l4_tsc_init (int constraint, l4_kernel_info_t *kip);
166 
172 l4_get_hz (void);
173 
177 
178 /* implementation */
179 
180 L4_INLINE l4_uint32_t
182 {
183  return l4_tsc_init(L4_TSC_INIT_AUTO, kip);
184 }
185 
186 L4_INLINE l4_cpu_time_t
187 l4_rdtsc (void)
188 {
189  l4_cpu_time_t v;
190 
191  __asm__ __volatile__
192  (".byte 0x0f, 0x31 \n\t"
193  "mov $0xffffffff, %%rcx \n\t" /* clears the upper 32 bits! */
194  "and %%rcx,%%rax \n\t"
195  "shlq $32,%%rdx \n\t"
196  "orq %%rdx,%%rax \n\t"
197  :
198  "=a" (v)
199  : /* no inputs */
200  :"rdx", "rcx"
201  );
202 
203  return v;
204 }
205 
206 L4_INLINE l4_uint64_t
207 l4_rdpmc (int ecx)
208 {
209  l4_cpu_time_t v;
210  l4_uint64_t dummy;
211 
212  __asm__ __volatile__ (
213  "rdpmc \n\t"
214  "mov $0xffffffff, %%rcx \n\t" /* clears the upper 32 bits! */
215  "and %%rcx,%%rax \n\t"
216  "shlq $32,%%rdx \n\t"
217  "orq %%rdx,%%rax \n\t"
218  :
219  "=a" (v), "=c"(dummy)
220  : "c" (ecx)
221  : "rdx"
222  );
223 
224  return v;
225 }
226 
227 /* the same, but only 32 bit. Useful for smaller differences */
228 L4_INLINE
230 {
231  l4_uint32_t x;
232  l4_uint64_t dummy;
233 
234  __asm__ __volatile__ (
235  "rdpmc \n\t"
236  "mov $0xffffffff, %%rcx \n\t" /* clears the upper 32 bits! */
237  "and %%rcx,%%rax \n\t"
238  : "=a" (x), "=c"(dummy)
239  : "c" (ecx)
240  : "rdx");
241 
242  return x;
243 }
244 
245 /* the same, but only 32 bit. Useful for smaller differences,
246  needs less cycles. */
247 L4_INLINE
249 {
250  l4_uint32_t x;
251 
252  __asm__ __volatile__ (
253  ".byte 0x0f, 0x31\n\t" // rdtsc
254  : "=a" (x)
255  :
256  : "rdx");
257 
258  return x;
259 }
260 
261 L4_INLINE l4_uint64_t
263 {
264  l4_uint64_t ns, dummy;
265  __asm__
266  (" \n\t"
267  "mulq %3 \n\t"
268  "shrd $27, %%rdx, %%rax \n\t"
269  :"=a" (ns), "=d"(dummy)
270  :"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns)
271  );
272  return ns;
273 }
274 
275 L4_INLINE l4_uint64_t
277 {
278  l4_uint64_t ns, dummy;
279  __asm__
280  (" \n\t"
281  "mulq %3 \n\t"
282  "shrd $32, %%rdx, %%rax \n\t"
283  :"=a" (ns), "=d" (dummy)
284  :"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_us)
285  );
286  return ns;
287 }
288 
289 L4_INLINE void
291 {
292  __asm__
293  (" \n\t"
294  "mulq %3 \n\t"
295  "shrd $27, %%rdx, %%rax \n\t"
296  "xorq %%rdx, %%rdx \n\t"
297  "divq %4 \n\t"
298  :"=a" (*s), "=&d" (*ns)
299  : "a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns),
300  "rm"(1000000000ULL)
301  );
302 }
303 
304 L4_INLINE l4_cpu_time_t
306 {
307  l4_uint64_t tsc, dummy;
308  __asm__
309  (" \n\t"
310  "mulq %3 \n\t"
311  "shrd $27, %%rdx, %%rax \n\t"
312  :"=a" (tsc), "=d" (dummy)
313  :"a" (ns), "r" ((l4_uint64_t)l4_scaler_ns_to_tsc)
314  );
315  return tsc;
316 }
317 
318 L4_INLINE void
320 {
321  l4_cpu_time_t stop = l4_rdtsc();
322  stop += l4_ns_to_tsc(ns);
323 
324  while (l4_rdtsc() < stop)
325  ;
326 }
327 
328 L4_INLINE void
330 {
331  l4_cpu_time_t stop = l4_rdtsc ();
332  stop += l4_ns_to_tsc(us*1000ULL);
333 
334  while (l4_rdtsc() < stop)
335  ;
336 }
337 
339 
340 #endif /* __l4_rdtsc_h */
341 
void l4_tsc_to_s_and_ns(l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns)
Convert time stamp to s.ns value.
Definition: rdtsc.h:290
l4_uint32_t l4_get_hz(void)
Get CPU frequency in Hz.
l4_uint64_t l4_tsc_to_ns(l4_cpu_time_t tsc)
Convert time stamp to ns value.
Definition: rdtsc.h:262
l4_uint64_t l4_tsc_to_us(l4_cpu_time_t tsc)
Convert time stamp into micro seconds value.
Definition: rdtsc.h:276
l4_cpu_time_t l4_rdtsc(void)
Read current value of CPU-internal time stamp counter.
Definition: rdtsc.h:187
l4_cpu_time_t l4_ns_to_tsc(l4_uint64_t ns)
Convert nano seconds into CPU ticks.
Definition: rdtsc.h:305
l4_uint32_t l4_tsc_init(int constraint, l4_kernel_info_t *kip)
Initialize scaler for TSC calibrations.
l4_uint32_t l4_calibrate_tsc(l4_kernel_info_t *kip)
Calibrate scalers for time stamp calculations.
Definition: rdtsc.h:181
void l4_busy_wait_us(l4_uint64_t us)
Wait busy for a small amount of time.
Definition: rdtsc.h:329
l4_uint32_t l4_rdpmc_32(int ecx)
Return the least significant 32 bit of a performance counter.
Definition: rdtsc.h:229
l4_uint64_t l4_rdpmc(int ecx)
Return current value of CPU-internal performance measurement counter.
Definition: rdtsc.h:207
void l4_busy_wait_ns(l4_uint64_t ns)
Wait busy for a small amount of time.
Definition: rdtsc.h:319
#define L4_TSC_INIT_AUTO
Automatic init.
Definition: rdtsc.h:39
l4_uint32_t l4_rdtsc_32(void)
Read the lest significant 32 bit of the TSC.
Definition: rdtsc.h:248
L4 compiler related defines.
#define EXTERN_C_BEGIN
Start section with C types and functions.
Definition: compiler.h:190
#define EXTERN_C_END
End section with C types and functions.
Definition: compiler.h:191
l4_uint64_t l4_cpu_time_t
CPU clock type.
Definition: l4int.h:58
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition: l4int.h:40
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition: l4int.h:42
#define L4_CV
Define calling convention.
Definition: linkage.h:44
L4 Kernel Interface Page.
Definition: __kip-32bit.h:39
Kernel Info Page access functions.