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 
69 L4_INLINE l4_cpu_time_t
70 l4_rdpmc (int nr);
71 
77 L4_INLINE
78 l4_uint32_t l4_rdpmc_32(int nr);
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 /* implementaion */
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  (" \n\t"
193  ".byte 0x0f, 0x31 \n\t"
194  /*"rdtsc\n\t"*/
195  :
196  "=A" (v)
197  : /* no inputs */
198  );
199 
200  return v;
201 }
202 
203 /* the same, but only 32 bit. Useful for smaller differences,
204  needs less cycles. */
205 L4_INLINE
207 {
208  l4_uint32_t x;
209 
210  __asm__ __volatile__ (
211  ".byte 0x0f, 0x31\n\t" // rdtsc
212  : "=a" (x)
213  :
214  : "edx");
215 
216  return x;
217 }
218 
219 L4_INLINE l4_cpu_time_t
220 l4_rdpmc (int nr)
221 {
222  l4_cpu_time_t v;
223 
224  __asm__ __volatile__ (
225  "rdpmc \n\t"
226  :
227  "=A" (v)
228  : "c" (nr)
229  );
230 
231  return v;
232 }
233 
234 /* the same, but only 32 bit. Useful for smaller differences,
235  needs less cycles. */
236 L4_INLINE
237 l4_uint32_t l4_rdpmc_32(int nr)
238 {
239  l4_uint32_t x;
240 
241  __asm__ __volatile__ (
242  "rdpmc \n\t"
243  : "=a" (x)
244  : "c" (nr)
245  : "edx");
246 
247  return x;
248 }
249 
250 L4_INLINE l4_uint64_t
252 {
253  l4_uint32_t dummy;
254  l4_uint64_t ns;
255  __asm__
256  (" \n\t"
257  "movl %%edx, %%ecx \n\t"
258  "mull %3 \n\t"
259  "movl %%ecx, %%eax \n\t"
260  "movl %%edx, %%ecx \n\t"
261  "mull %3 \n\t"
262  "addl %%ecx, %%eax \n\t"
263  "adcl $0, %%edx \n\t"
264  "shld $5, %%eax, %%edx \n\t"
265  "shll $5, %%eax \n\t"
266  :"=A" (ns),
267  "=&c" (dummy)
268  :"0" (tsc),
269  "g" (l4_scaler_tsc_to_ns)
270  );
271  return ns;
272 }
273 
274 L4_INLINE l4_uint64_t
276 {
277  l4_uint32_t dummy;
278  l4_uint64_t us;
279  __asm__
280  (" \n\t"
281  "movl %%edx, %%ecx \n\t"
282  "mull %3 \n\t"
283  "movl %%ecx, %%eax \n\t"
284  "movl %%edx, %%ecx \n\t"
285  "mull %3 \n\t"
286  "addl %%ecx, %%eax \n\t"
287  "adcl $0, %%edx \n\t"
288  :"=A" (us),
289  "=&c" (dummy)
290  :"0" (tsc),
291  "g" (l4_scaler_tsc_to_us)
292  );
293  return us;
294 }
295 
296 L4_INLINE void
298 {
299  l4_uint32_t dummy;
300  __asm__
301  (" \n\t"
302  "movl %%edx, %%ecx \n\t"
303  "mull %4 \n\t"
304  "movl %%ecx, %%eax \n\t"
305  "movl %%edx, %%ecx \n\t"
306  "mull %4 \n\t"
307  "addl %%ecx, %%eax \n\t"
308  "adcl $0, %%edx \n\t"
309  "movl $1000000000, %%ecx \n\t"
310  "shld $5, %%eax, %%edx \n\t"
311  "shll $5, %%eax \n\t"
312  "divl %%ecx \n\t"
313  :"=a" (*s), "=d" (*ns), "=&c" (dummy)
314  : "A" (tsc), "g" (l4_scaler_tsc_to_ns)
315  );
316 }
317 
318 L4_INLINE l4_cpu_time_t
320 {
321  l4_uint32_t dummy;
322  l4_cpu_time_t tsc;
323  __asm__
324  (" \n\t"
325  "movl %%edx, %%ecx \n\t"
326  "mull %3 \n\t"
327  "movl %%ecx, %%eax \n\t"
328  "movl %%edx, %%ecx \n\t"
329  "mull %3 \n\t"
330  "addl %%ecx, %%eax \n\t"
331  "adcl $0, %%edx \n\t"
332  "shld $5, %%eax, %%edx \n\t"
333  "shll $5, %%eax \n\t"
334  :"=A" (tsc),
335  "=&c" (dummy)
336  :"0" (ns),
337  "g" (l4_scaler_ns_to_tsc)
338  );
339  return tsc;
340 }
341 
342 L4_INLINE void
344 {
345  l4_cpu_time_t stop = l4_rdtsc();
346  stop += l4_ns_to_tsc(ns);
347 
348  while (l4_rdtsc() < stop)
349  ;
350 }
351 
352 L4_INLINE void
354 {
355  l4_cpu_time_t stop = l4_rdtsc ();
356  stop += l4_ns_to_tsc(us*1000ULL);
357 
358  while (l4_rdtsc() < stop)
359  ;
360 }
361 
363 
364 #endif /* __l4_rdtsc_h */
365 
l4_cpu_time_t l4_rdpmc(int nr)
Return current value of CPU-internal performance measurement counter.
Definition: rdtsc.h:205
l4_uint32_t l4_calibrate_tsc(l4_kernel_info_t *kip)
Calibrate scalers for time stamp calculations.
Definition: rdtsc.h:179
l4_uint32_t l4_rdpmc_32(int nr)
Return the least significant 32 bit of a performance counter.
Definition: rdtsc.h:227
l4_cpu_time_t l4_ns_to_tsc(l4_uint64_t ns)
Convert nano seconds into CPU ticks.
Definition: rdtsc.h:303
#define EXTERN_C_END
End section with C types and functions.
Definition: compiler.h:187
l4_cpu_time_t l4_rdtsc(void)
Read current value of CPU-internal time stamp counter.
Definition: rdtsc.h:185
l4_uint64_t l4_tsc_to_us(l4_cpu_time_t tsc)
Convert time stamp into micro seconds value.
Definition: rdtsc.h:274
void l4_busy_wait_us(l4_uint64_t us)
Wait busy for a small amount of time.
Definition: rdtsc.h:327
L4 compiler related defines.
L4 Kernel Interface Page.
Definition: __kip-32bit.h:38
l4_uint64_t l4_cpu_time_t
CPU clock type.
Definition: l4int.h:59
Kernel Info Page access functions.
#define EXTERN_C_BEGIN
Start section with C types and functions.
Definition: compiler.h:186
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:288
#define L4_TSC_INIT_AUTO
Automatic init.
Definition: rdtsc.h:41
#define L4_CV
Define calling convention.
Definition: linkage.h:44
l4_uint32_t l4_tsc_init(int constraint, l4_kernel_info_t *kip)
Initialitze scaler for TSC calicaltions.
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:260
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition: l4int.h:42
l4_uint32_t l4_rdtsc_32(void)
Read the lest significant 32 bit of the TSC.
Definition: rdtsc.h:246
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition: l4int.h:40
void l4_busy_wait_ns(l4_uint64_t ns)
Wait busy for a small amount of time.
Definition: rdtsc.h:317