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  * Frank Mehnert <fm3@os.inf.tu-dresden.de>,
13  * Jork Löser <jork@os.inf.tu-dresden.de>,
14  * Martin Pohlack <mp26@os.inf.tu-dresden.de>
15  * economic rights: Technische Universität Dresden (Germany)
16  * This file is part of TUD:OS and distributed under the terms of the
17  * GNU Lesser General Public License 2.1.
18  * Please see the COPYING-LGPL-2.1 file for details.
19  */
20 
21 #ifndef __l4_rdtsc_h
22 #define __l4_rdtsc_h
23 
29 #include <l4/sys/compiler.h>
30 #include <l4/sys/l4int.h>
31 #include <l4/sys/kip.h>
32 
34 
35 /* interface */
40 
41 #define L4_TSC_INIT_AUTO 0
42 #define L4_TSC_INIT_KERNEL 1
43 #define L4_TSC_INIT_CALIBRATE 2
44 
45 extern l4_uint32_t l4_scaler_tsc_to_ns;
46 extern l4_uint32_t l4_scaler_tsc_to_us;
47 extern l4_uint32_t l4_scaler_ns_to_tsc;
48 extern l4_uint32_t l4_scaler_tsc_linux;
49 
54 L4_INLINE l4_cpu_time_t
55 l4_rdtsc (void);
56 
62 L4_INLINE
64 
71 L4_INLINE l4_uint64_t
72 l4_rdpmc (int ecx);
73 
79 L4_INLINE
80 l4_uint32_t l4_rdpmc_32(int ecx);
81 
86 L4_INLINE l4_uint64_t
88 
93 L4_INLINE l4_uint64_t
95 
101 L4_INLINE void
103 
109 L4_INLINE l4_cpu_time_t
111 
117 L4_INLINE void
119 
125 L4_INLINE void
127 
129 
138 L4_INLINE l4_uint32_t
140 
167 l4_tsc_init (int constraint, l4_kernel_info_t *kip);
168 
174 l4_get_hz (void);
175 
179 
180 /* implementaion */
181 
182 L4_INLINE l4_uint32_t
184 {
185  return l4_tsc_init(L4_TSC_INIT_AUTO, kip);
186 }
187 
188 L4_INLINE l4_cpu_time_t
189 l4_rdtsc (void)
190 {
191  l4_cpu_time_t v;
192 
193  __asm__ __volatile__
194  (" \n\t"
195  ".byte 0x0f, 0x31 \n\t"
196  /*"rdtsc\n\t"*/
197  :
198  "=A" (v)
199  : /* no inputs */
200  );
201 
202  return v;
203 }
204 
205 /* the same, but only 32 bit. Useful for smaller differences,
206  needs less cycles. */
207 L4_INLINE
209 {
210  l4_uint32_t x;
211 
212  __asm__ __volatile__ (
213  ".byte 0x0f, 0x31\n\t" // rdtsc
214  : "=a" (x)
215  :
216  : "edx");
217 
218  return x;
219 }
220 
221 L4_INLINE l4_uint64_t
222 l4_rdpmc (int ecx)
223 {
224  l4_cpu_time_t v;
225 
226  __asm__ __volatile__ (
227  "rdpmc \n\t"
228  :
229  "=A" (v)
230  : "c" (ecx)
231  );
232 
233  return v;
234 }
235 
236 /* the same, but only 32 bit. Useful for smaller differences,
237  needs less cycles. */
238 L4_INLINE
240 {
241  l4_uint32_t x;
242 
243  __asm__ __volatile__ (
244  "rdpmc \n\t"
245  : "=a" (x)
246  : "c" (ecx)
247  : "edx");
248 
249  return x;
250 }
251 
252 L4_INLINE l4_uint64_t
254 {
255  l4_uint32_t dummy;
256  l4_uint64_t ns;
257  __asm__
258  (" \n\t"
259  "movl %%edx, %%ecx \n\t"
260  "mull %3 \n\t"
261  "movl %%ecx, %%eax \n\t"
262  "movl %%edx, %%ecx \n\t"
263  "mull %3 \n\t"
264  "addl %%ecx, %%eax \n\t"
265  "adcl $0, %%edx \n\t"
266  "shld $5, %%eax, %%edx \n\t"
267  "shll $5, %%eax \n\t"
268  :"=A" (ns),
269  "=&c" (dummy)
270  :"0" (tsc),
271  "g" (l4_scaler_tsc_to_ns)
272  );
273  return ns;
274 }
275 
276 L4_INLINE l4_uint64_t
278 {
279  l4_uint32_t dummy;
280  l4_uint64_t us;
281  __asm__
282  (" \n\t"
283  "movl %%edx, %%ecx \n\t"
284  "mull %3 \n\t"
285  "movl %%ecx, %%eax \n\t"
286  "movl %%edx, %%ecx \n\t"
287  "mull %3 \n\t"
288  "addl %%ecx, %%eax \n\t"
289  "adcl $0, %%edx \n\t"
290  :"=A" (us),
291  "=&c" (dummy)
292  :"0" (tsc),
293  "g" (l4_scaler_tsc_to_us)
294  );
295  return us;
296 }
297 
298 L4_INLINE void
300 {
301  l4_uint32_t dummy;
302  __asm__
303  (" \n\t"
304  "movl %%edx, %%ecx \n\t"
305  "mull %4 \n\t"
306  "movl %%ecx, %%eax \n\t"
307  "movl %%edx, %%ecx \n\t"
308  "mull %4 \n\t"
309  "addl %%ecx, %%eax \n\t"
310  "adcl $0, %%edx \n\t"
311  "movl $1000000000, %%ecx \n\t"
312  "shld $5, %%eax, %%edx \n\t"
313  "shll $5, %%eax \n\t"
314  "divl %%ecx \n\t"
315  :"=a" (*s), "=d" (*ns), "=&c" (dummy)
316  : "A" (tsc), "g" (l4_scaler_tsc_to_ns)
317  );
318 }
319 
320 L4_INLINE l4_cpu_time_t
322 {
323  l4_uint32_t dummy;
324  l4_cpu_time_t tsc;
325  __asm__
326  (" \n\t"
327  "movl %%edx, %%ecx \n\t"
328  "mull %3 \n\t"
329  "movl %%ecx, %%eax \n\t"
330  "movl %%edx, %%ecx \n\t"
331  "mull %3 \n\t"
332  "addl %%ecx, %%eax \n\t"
333  "adcl $0, %%edx \n\t"
334  "shld $5, %%eax, %%edx \n\t"
335  "shll $5, %%eax \n\t"
336  :"=A" (tsc),
337  "=&c" (dummy)
338  :"0" (ns),
339  "g" (l4_scaler_ns_to_tsc)
340  );
341  return tsc;
342 }
343 
344 L4_INLINE void
346 {
347  l4_cpu_time_t stop = l4_rdtsc();
348  stop += l4_ns_to_tsc(ns);
349 
350  while (l4_rdtsc() < stop)
351  ;
352 }
353 
354 L4_INLINE void
356 {
357  l4_cpu_time_t stop = l4_rdtsc ();
358  stop += l4_ns_to_tsc(us*1000ULL);
359 
360  while (l4_rdtsc() < stop)
361  ;
362 }
363 
365 
366 #endif /* __l4_rdtsc_h */
367 
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
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.
#define L4_TSC_INIT_AUTO
Automatic init.
Definition: rdtsc.h:41