00001
00007
00008
00009
00010
00011 #ifndef __l4_rdtsc_h
00012 #define __l4_rdtsc_h
00013
00014 #include <l4/sys/compiler.h>
00015 #include <l4/sys/l4int.h>
00016
00017 EXTERN_C_BEGIN
00018
00019
00020
00021 #define L4_TSC_INIT_AUTO 0
00022 #define L4_TSC_INIT_KERNEL 1
00023 #define L4_TSC_INIT_CALIBRATE 2
00024
00027 extern l4_uint32_t l4_scaler_tsc_to_ns;
00028 extern l4_uint32_t l4_scaler_tsc_to_us;
00029 extern l4_uint32_t l4_scaler_ns_to_tsc;
00030 extern l4_uint32_t l4_scaler_tsc_linux;
00031
00035 L4_INLINE l4_cpu_time_t
00036 l4_rdtsc (void);
00037
00042 L4_INLINE l4_cpu_time_t
00043 l4_rdpmc (int nr);
00044
00045
00046
00047 L4_INLINE
00048 l4_uint32_t l4_rdpmc_32(int nr);
00049
00055 L4_INLINE l4_uint64_t
00056 l4_tsc_to_ns (l4_cpu_time_t tsc);
00057
00063 L4_INLINE l4_uint64_t
00064 l4_tsc_to_us (l4_cpu_time_t tsc);
00065
00072 L4_INLINE void
00073 l4_tsc_to_s_and_ns (l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns);
00074
00080 L4_INLINE l4_cpu_time_t
00081 l4_ns_to_tsc (l4_uint64_t ns);
00082
00087 L4_INLINE void
00088 l4_busy_wait_ns (l4_uint64_t ns);
00089
00094 L4_INLINE void
00095 l4_busy_wait_us (l4_uint64_t us);
00096
00097 EXTERN_C_BEGIN
00098
00105 L4_INLINE l4_uint32_t
00106 l4_calibrate_tsc (void);
00107
00130 L4_CV l4_uint32_t
00131 l4_tsc_init (int constraint);
00132
00137 L4_CV l4_uint32_t
00138 l4_get_hz (void);
00139
00140 EXTERN_C_END
00141
00142
00143
00144 L4_INLINE l4_uint32_t
00145 l4_calibrate_tsc (void)
00146 {
00147 return l4_tsc_init(L4_TSC_INIT_AUTO);
00148 }
00149
00150 L4_INLINE l4_cpu_time_t
00151 l4_rdtsc (void)
00152 {
00153 l4_cpu_time_t v;
00154
00155 __asm__ __volatile__
00156 (".byte 0x0f, 0x31 \n\t"
00157 "mov $0xffffffff, %%rcx \n\t"
00158 "and %%rcx,%%rax \n\t"
00159 "shlq $32,%%rdx \n\t"
00160 "orq %%rdx,%%rax \n\t"
00161 :
00162 "=a" (v)
00163 :
00164 :"rdx", "rcx"
00165 );
00166
00167 return v;
00168 }
00169
00170 L4_INLINE l4_cpu_time_t
00171 l4_rdpmc (int nr)
00172 {
00173 l4_cpu_time_t v;
00174 l4_uint64_t dummy;
00175
00176 __asm__ __volatile__ (
00177 "rdpmc \n\t"
00178 "mov $0xffffffff, %%rcx \n\t"
00179 "and %%rcx,%%rax \n\t"
00180 "shlq $32,%%rdx \n\t"
00181 "orq %%rdx,%%rax \n\t"
00182 :
00183 "=a" (v), "=c"(dummy)
00184 : "c" (nr)
00185 : "rdx"
00186 );
00187
00188 return v;
00189 }
00190
00191
00192 L4_INLINE
00193 l4_uint32_t l4_rdpmc_32(int nr)
00194 {
00195 l4_uint32_t x;
00196 l4_uint64_t dummy;
00197
00198 __asm__ __volatile__ (
00199 "rdpmc \n\t"
00200 "mov $0xffffffff, %%rcx \n\t"
00201 "and %%rcx,%%rax \n\t"
00202 : "=a" (x), "=c"(dummy)
00203 : "c" (nr)
00204 : "rdx");
00205
00206 return x;
00207 }
00208
00209
00210
00211 static inline
00212 l4_uint32_t l4_rdtsc_32(void)
00213 {
00214 l4_uint32_t x;
00215
00216 __asm__ __volatile__ (
00217 ".byte 0x0f, 0x31\n\t"
00218 : "=a" (x)
00219 :
00220 : "rdx");
00221
00222 return x;
00223 }
00224
00225 L4_INLINE l4_uint64_t
00226 l4_tsc_to_ns (l4_cpu_time_t tsc)
00227 {
00228 l4_uint64_t ns, dummy;
00229 __asm__
00230 (" \n\t"
00231 "mulq %3 \n\t"
00232 "shrd $27, %%rdx, %%rax \n\t"
00233 :"=a" (ns), "=d"(dummy)
00234 :"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns)
00235 );
00236 return ns;
00237 }
00238
00239 L4_INLINE l4_uint64_t
00240 l4_tsc_to_us (l4_cpu_time_t tsc)
00241 {
00242 l4_uint64_t ns, dummy;
00243 __asm__
00244 (" \n\t"
00245 "mulq %3 \n\t"
00246 "shrd $32, %%rdx, %%rax \n\t"
00247 :"=a" (ns), "=d" (dummy)
00248 :"a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_us)
00249 );
00250 return ns;
00251 }
00252
00253 L4_INLINE void
00254 l4_tsc_to_s_and_ns (l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns)
00255 {
00256 __asm__
00257 (" \n\t"
00258 "mulq %3 \n\t"
00259 "shrd $27, %%rdx, %%rax \n\t"
00260 "xorq %%rdx, %%rdx \n\t"
00261 "divq %4 \n\t"
00262 :"=a" (*s), "=&d" (*ns)
00263 : "a" (tsc), "r" ((l4_uint64_t)l4_scaler_tsc_to_ns),
00264 "rm"(1000000000ULL)
00265 );
00266 }
00267
00268 L4_INLINE l4_cpu_time_t
00269 l4_ns_to_tsc (l4_uint64_t ns)
00270 {
00271 l4_uint64_t tsc, dummy;
00272 __asm__
00273 (" \n\t"
00274 "mulq %3 \n\t"
00275 "shrd $27, %%rdx, %%rax \n\t"
00276 :"=a" (tsc), "=d" (dummy)
00277 :"a" (ns), "r" ((l4_uint64_t)l4_scaler_ns_to_tsc)
00278 );
00279 return tsc;
00280 }
00281
00282 L4_INLINE void
00283 l4_busy_wait_ns (l4_uint64_t ns)
00284 {
00285 l4_cpu_time_t stop = l4_rdtsc();
00286 stop += l4_ns_to_tsc(ns);
00287
00288 while (l4_rdtsc() < stop)
00289 ;
00290 }
00291
00292 L4_INLINE void
00293 l4_busy_wait_us (l4_uint64_t us)
00294 {
00295 l4_cpu_time_t stop = l4_rdtsc ();
00296 stop += l4_ns_to_tsc(us*1000ULL);
00297
00298 while (l4_rdtsc() < stop)
00299 ;
00300 }
00301
00302 EXTERN_C_END
00303
00304 #endif
00305