Loading...
Searching...
No Matches
rdtsc.h
Go to the documentation of this file.
/*
* (c) 2003-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>,
* Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#ifndef __l4_rdtsc_h
#define __l4_rdtsc_h
#include <l4/sys/compiler.h>
#include <l4/sys/l4int.h>
#include <l4/sys/kip.h>
L4_BEGIN_DECLS
/* interface */
extern l4_uint32_t l4_scaler_tsc_to_ns;
extern l4_uint32_t l4_scaler_tsc_to_us;
extern l4_uint32_t l4_scaler_ns_to_tsc;
extern l4_uint32_t l4_scaler_tsc_linux;
L4_INLINE l4_cpu_time_t
l4_rdtsc (void);
L4_INLINE
l4_uint32_t l4_rdtsc_32(void);
L4_INLINE l4_uint64_t
l4_rdpmc (int ecx);
L4_INLINE
l4_uint32_t l4_rdpmc_32(int ecx);
L4_INLINE l4_uint64_t
l4_tsc_to_ns (l4_cpu_time_t tsc);
L4_INLINE l4_uint64_t
l4_tsc_to_us (l4_cpu_time_t tsc);
L4_INLINE void
l4_tsc_to_s_and_ns (l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns);
L4_INLINE l4_cpu_time_t
l4_ns_to_tsc (l4_uint64_t ns);
L4_INLINE void
l4_busy_wait_ns (l4_uint64_t ns);
L4_INLINE void
l4_busy_wait_us (l4_uint64_t us);
L4_INLINE l4_uint32_t
l4_calibrate_tsc(l4_kernel_info_t const *kip);
L4_CV l4_uint32_t
l4_tsc_init(l4_kernel_info_t const *kip);
L4_CV l4_uint32_t
l4_get_hz (void);
L4_END_DECLS
/* implementation */
L4_INLINE l4_uint32_t
l4_calibrate_tsc(l4_kernel_info_t const *kip)
{
return l4_tsc_init(kip);
}
L4_INLINE l4_cpu_time_t
l4_rdtsc (void)
{
l4_umword_t lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ((l4_cpu_time_t)hi << 32) | lo;
}
L4_INLINE l4_uint64_t
l4_rdpmc (int ecx)
{
l4_umword_t lo, hi;
__asm__ __volatile__ ("rdpmc" : "=a"(lo), "=d"(hi) : "c"(ecx));
return ((l4_cpu_time_t)hi << 32) | lo;
}
L4_INLINE
l4_uint32_t l4_rdtsc_32(void)
{
l4_umword_t lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return lo;
}
L4_INLINE
l4_uint32_t l4_rdpmc_32(int ecx)
{
l4_umword_t lo, hi;
__asm__ __volatile__ ("rdpmc" : "=a"(lo), "=d"(hi) : "c"(ecx));
return lo;
}
L4_INLINE l4_uint64_t
l4_tsc_to_ns (l4_cpu_time_t tsc)
{
l4_uint64_t ns, dummy;
__asm__
(" \n\t"
"mulq %3 \n\t"
"shrd $27, %%rdx, %%rax \n\t"
:"=a" (ns), "=d"(dummy)
:"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns)
);
return ns;
}
L4_INLINE l4_uint64_t
l4_tsc_to_us (l4_cpu_time_t tsc)
{
l4_uint64_t ns, dummy;
__asm__
(" \n\t"
"mulq %3 \n\t"
"shrd $32, %%rdx, %%rax \n\t"
:"=a" (ns), "=d" (dummy)
:"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_us)
);
return ns;
}
L4_INLINE void
l4_tsc_to_s_and_ns (l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns)
{
__asm__
(" \n\t"
"mulq %3 \n\t"
"shrd $27, %%rdx, %%rax \n\t"
"xorq %%rdx, %%rdx \n\t"
"divq %4 \n\t"
:"=a" (*s), "=&d" (*ns)
: "a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns),
"rm"(1000000000ULL)
);
}
L4_INLINE l4_cpu_time_t
l4_ns_to_tsc (l4_uint64_t ns)
{
l4_uint64_t tsc, dummy;
__asm__
(" \n\t"
"mulq %3 \n\t"
"shrd $27, %%rdx, %%rax \n\t"
:"=a" (tsc), "=d" (dummy)
:"a" (ns), "r" ((l4_uint64_t)l4_scaler_ns_to_tsc)
);
return tsc;
}
L4_INLINE void
l4_busy_wait_ns (l4_uint64_t ns)
{
l4_cpu_time_t stop = l4_rdtsc();
stop += l4_ns_to_tsc(ns);
while (l4_rdtsc() < stop)
;
}
L4_INLINE void
l4_busy_wait_us (l4_uint64_t us)
{
l4_cpu_time_t stop = l4_rdtsc ();
stop += l4_ns_to_tsc(us*1000ULL);
while (l4_rdtsc() < stop)
;
}
#endif /* __l4_rdtsc_h */
compiler.h
L4 compiler related defines.
l4_umword_t
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
l4_cpu_time_t
l4_uint64_t l4_cpu_time_t
CPU clock type.
Definition l4int.h:47
l4_uint32_t
unsigned int l4_uint32_t
Unsigned 32bit value.
Definition l4int.h:29
l4_uint64_t
unsigned long long l4_uint64_t
Unsigned 64bit value.
Definition l4int.h:31
L4_CV
#define L4_CV
Define calling convention.
Definition linkage.h:33
L4_INLINE
#define L4_INLINE
L4 Inline function attribute.
Definition compiler.h:51
L4_BEGIN_DECLS
#define L4_BEGIN_DECLS
Start section with C types and functions.
Definition compiler.h:165
L4_END_DECLS
#define L4_END_DECLS
End section with C types and functions.
Definition compiler.h:166
l4_tsc_to_s_and_ns
void l4_tsc_to_s_and_ns(l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns)
Convert timestamp to s.ns value.
Definition rdtsc.h:233
l4_get_hz
l4_uint32_t l4_get_hz(void)
Get CPU frequency in Hz.
l4_tsc_init
l4_uint32_t l4_tsc_init(l4_kernel_info_t const *kip)
Initialize scaler for TSC calibrations from the kernel.
l4_tsc_to_ns
l4_uint64_t l4_tsc_to_ns(l4_cpu_time_t tsc)
Convert timestamp to ns value.
Definition rdtsc.h:205
l4_tsc_to_us
l4_uint64_t l4_tsc_to_us(l4_cpu_time_t tsc)
Convert timestamp into micro seconds value.
Definition rdtsc.h:219
l4_calibrate_tsc
l4_uint32_t l4_calibrate_tsc(l4_kernel_info_t const *kip)
Determine scalers for timestamp calculations.
Definition rdtsc.h:159
l4_rdtsc
l4_cpu_time_t l4_rdtsc(void)
Read current value of CPU-internal timestamp counter.
Definition rdtsc.h:165
l4_ns_to_tsc
l4_cpu_time_t l4_ns_to_tsc(l4_uint64_t ns)
Convert nano seconds into CPU ticks.
Definition rdtsc.h:248
l4_busy_wait_us
void l4_busy_wait_us(l4_uint64_t us)
Wait busy for a small amount of time.
Definition rdtsc.h:272
l4_rdpmc_32
l4_uint32_t l4_rdpmc_32(int ecx)
Return the least significant 32 bit of a performance counter.
Definition rdtsc.h:195
l4_rdpmc
l4_uint64_t l4_rdpmc(int ecx)
Return current value of CPU-internal performance measurement counter.
Definition rdtsc.h:175
l4_busy_wait_ns
void l4_busy_wait_ns(l4_uint64_t ns)
Wait busy for a small amount of time.
Definition rdtsc.h:262
l4_rdtsc_32
l4_uint32_t l4_rdtsc_32(void)
Read the lest significant 32 bit of the TSC.
Definition rdtsc.h:185
l4int.h
Fixed sized integer types, generic version.
l4_kernel_info_t
L4 Kernel Interface Page.
Definition kip.h:37
kip.h
Kernel Info Page access functions.