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 
67 L4_INLINE l4_cpu_time_t
68 l4_rdpmc (int nr);
69 
75 L4_INLINE
76 l4_uint32_t l4_rdpmc_32(int nr);
77 
82 L4_INLINE l4_uint64_t
84 
89 L4_INLINE l4_uint64_t
91 
97 L4_INLINE void
99 
105 L4_INLINE l4_cpu_time_t
107 
113 L4_INLINE void
115 
121 L4_INLINE void
123 
125 
134 L4_INLINE l4_uint32_t
136 
163 l4_tsc_init (int constraint, l4_kernel_info_t *kip);
164 
170 l4_get_hz (void);
171 
175 
176 /* implementaion */
177 
178 L4_INLINE l4_uint32_t
180 {
181  return l4_tsc_init(L4_TSC_INIT_AUTO, kip);
182 }
183 
184 L4_INLINE l4_cpu_time_t
185 l4_rdtsc (void)
186 {
187  l4_cpu_time_t v;
188 
189  __asm__ __volatile__
190  (".byte 0x0f, 0x31 \n\t"
191  "mov $0xffffffff, %%rcx \n\t" /* clears the upper 32 bits! */
192  "and %%rcx,%%rax \n\t"
193  "shlq $32,%%rdx \n\t"
194  "orq %%rdx,%%rax \n\t"
195  :
196  "=a" (v)
197  : /* no inputs */
198  :"rdx", "rcx"
199  );
200 
201  return v;
202 }
203 
204 L4_INLINE l4_cpu_time_t
205 l4_rdpmc (int nr)
206 {
207  l4_cpu_time_t v;
208  l4_uint64_t dummy;
209 
210  __asm__ __volatile__ (
211  "rdpmc \n\t"
212  "mov $0xffffffff, %%rcx \n\t" /* clears the upper 32 bits! */
213  "and %%rcx,%%rax \n\t"
214  "shlq $32,%%rdx \n\t"
215  "orq %%rdx,%%rax \n\t"
216  :
217  "=a" (v), "=c"(dummy)
218  : "c" (nr)
219  : "rdx"
220  );
221 
222  return v;
223 }
224 
225 /* the same, but only 32 bit. Useful for smaller differences */
226 L4_INLINE
228 {
229  l4_uint32_t x;
230  l4_uint64_t dummy;
231 
232  __asm__ __volatile__ (
233  "rdpmc \n\t"
234  "mov $0xffffffff, %%rcx \n\t" /* clears the upper 32 bits! */
235  "and %%rcx,%%rax \n\t"
236  : "=a" (x), "=c"(dummy)
237  : "c" (nr)
238  : "rdx");
239 
240  return x;
241 }
242 
243 /* the same, but only 32 bit. Useful for smaller differences,
244  needs less cycles. */
245 L4_INLINE
247 {
248  l4_uint32_t x;
249 
250  __asm__ __volatile__ (
251  ".byte 0x0f, 0x31\n\t" // rdtsc
252  : "=a" (x)
253  :
254  : "rdx");
255 
256  return x;
257 }
258 
259 L4_INLINE l4_uint64_t
261 {
262  l4_uint64_t ns, dummy;
263  __asm__
264  (" \n\t"
265  "mulq %3 \n\t"
266  "shrd $27, %%rdx, %%rax \n\t"
267  :"=a" (ns), "=d"(dummy)
268  :"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns)
269  );
270  return ns;
271 }
272 
273 L4_INLINE l4_uint64_t
275 {
276  l4_uint64_t ns, dummy;
277  __asm__
278  (" \n\t"
279  "mulq %3 \n\t"
280  "shrd $32, %%rdx, %%rax \n\t"
281  :"=a" (ns), "=d" (dummy)
282  :"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_us)
283  );
284  return ns;
285 }
286 
287 L4_INLINE void
289 {
290  __asm__
291  (" \n\t"
292  "mulq %3 \n\t"
293  "shrd $27, %%rdx, %%rax \n\t"
294  "xorq %%rdx, %%rdx \n\t"
295  "divq %4 \n\t"
296  :"=a" (*s), "=&d" (*ns)
297  : "a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns),
298  "rm"(1000000000ULL)
299  );
300 }
301 
302 L4_INLINE l4_cpu_time_t
304 {
305  l4_uint64_t tsc, dummy;
306  __asm__
307  (" \n\t"
308  "mulq %3 \n\t"
309  "shrd $27, %%rdx, %%rax \n\t"
310  :"=a" (tsc), "=d" (dummy)
311  :"a" (ns), "r" ((l4_uint64_t)l4_scaler_ns_to_tsc)
312  );
313  return tsc;
314 }
315 
316 L4_INLINE void
318 {
319  l4_cpu_time_t stop = l4_rdtsc();
320  stop += l4_ns_to_tsc(ns);
321 
322  while (l4_rdtsc() < stop)
323  ;
324 }
325 
326 L4_INLINE void
328 {
329  l4_cpu_time_t stop = l4_rdtsc ();
330  stop += l4_ns_to_tsc(us*1000ULL);
331 
332  while (l4_rdtsc() < stop)
333  ;
334 }
335 
337 
338 #endif /* __l4_rdtsc_h */
339 
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:39
#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