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
00038
00039
00040 L4_INLINE
00041 l4_uint32_t l4_rdtsc_32(void);
00042
00047 L4_INLINE l4_cpu_time_t
00048 l4_rdpmc (int nr);
00049
00050
00051
00052 L4_INLINE
00053 l4_uint32_t l4_rdpmc_32(int nr);
00054
00055
00061 L4_INLINE l4_uint64_t
00062 l4_tsc_to_ns (l4_cpu_time_t tsc);
00063
00069 L4_INLINE l4_uint64_t
00070 l4_tsc_to_us (l4_cpu_time_t tsc);
00071
00078 L4_INLINE void
00079 l4_tsc_to_s_and_ns (l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns);
00080
00086 L4_INLINE l4_cpu_time_t
00087 l4_ns_to_tsc (l4_uint64_t ns);
00088
00093 L4_INLINE void
00094 l4_busy_wait_ns (l4_uint64_t ns);
00095
00100 L4_INLINE void
00101 l4_busy_wait_us (l4_uint64_t us);
00102
00103 EXTERN_C_BEGIN
00104
00111 L4_INLINE l4_uint32_t
00112 l4_calibrate_tsc (void);
00113
00136 L4_CV l4_uint32_t
00137 l4_tsc_init (int constraint);
00138
00143 L4_CV l4_uint32_t
00144 l4_get_hz (void);
00145
00146 EXTERN_C_END
00147
00148
00149
00150 L4_INLINE l4_uint32_t
00151 l4_calibrate_tsc (void)
00152 {
00153 return l4_tsc_init(L4_TSC_INIT_AUTO);
00154 }
00155
00156 L4_INLINE l4_cpu_time_t
00157 l4_rdtsc (void)
00158 {
00159 l4_cpu_time_t v;
00160
00161 __asm__ __volatile__
00162 (" \n\t"
00163 ".byte 0x0f, 0x31 \n\t"
00164
00165 :
00166 "=A" (v)
00167 :
00168 );
00169
00170 return v;
00171 }
00172
00173
00174
00175 L4_INLINE
00176 l4_uint32_t l4_rdtsc_32(void)
00177 {
00178 l4_uint32_t x;
00179
00180 __asm__ __volatile__ (
00181 ".byte 0x0f, 0x31\n\t"
00182 : "=a" (x)
00183 :
00184 : "edx");
00185
00186 return x;
00187 }
00188
00189 L4_INLINE l4_cpu_time_t
00190 l4_rdpmc (int nr)
00191 {
00192 l4_cpu_time_t v;
00193
00194 __asm__ __volatile__ (
00195 "rdpmc \n\t"
00196 :
00197 "=A" (v)
00198 : "c" (nr)
00199 );
00200
00201 return v;
00202 }
00203
00204
00205
00206 L4_INLINE
00207 l4_uint32_t l4_rdpmc_32(int nr)
00208 {
00209 l4_uint32_t x;
00210
00211 __asm__ __volatile__ (
00212 "rdpmc \n\t"
00213 : "=a" (x)
00214 : "c" (nr)
00215 : "edx");
00216
00217 return x;
00218 }
00219
00220 L4_INLINE l4_uint64_t
00221 l4_tsc_to_ns (l4_cpu_time_t tsc)
00222 {
00223 l4_uint32_t dummy;
00224 l4_uint64_t ns;
00225 __asm__
00226 (" \n\t"
00227 "movl %%edx, %%ecx \n\t"
00228 "mull %3 \n\t"
00229 "movl %%ecx, %%eax \n\t"
00230 "movl %%edx, %%ecx \n\t"
00231 "mull %3 \n\t"
00232 "addl %%ecx, %%eax \n\t"
00233 "adcl $0, %%edx \n\t"
00234 "shld $5, %%eax, %%edx \n\t"
00235 "shll $5, %%eax \n\t"
00236 :"=A" (ns),
00237 "=&c" (dummy)
00238 :"0" (tsc),
00239 "g" (l4_scaler_tsc_to_ns)
00240 );
00241 return ns;
00242 }
00243
00244 L4_INLINE l4_uint64_t
00245 l4_tsc_to_us (l4_cpu_time_t tsc)
00246 {
00247 l4_uint32_t dummy;
00248 l4_uint64_t us;
00249 __asm__
00250 (" \n\t"
00251 "movl %%edx, %%ecx \n\t"
00252 "mull %3 \n\t"
00253 "movl %%ecx, %%eax \n\t"
00254 "movl %%edx, %%ecx \n\t"
00255 "mull %3 \n\t"
00256 "addl %%ecx, %%eax \n\t"
00257 "adcl $0, %%edx \n\t"
00258 :"=A" (us),
00259 "=&c" (dummy)
00260 :"0" (tsc),
00261 "g" (l4_scaler_tsc_to_us)
00262 );
00263 return us;
00264 }
00265
00266 L4_INLINE void
00267 l4_tsc_to_s_and_ns (l4_cpu_time_t tsc, l4_uint32_t *s, l4_uint32_t *ns)
00268 {
00269 l4_uint32_t dummy;
00270 __asm__
00271 (" \n\t"
00272 "movl %%edx, %%ecx \n\t"
00273 "mull %4 \n\t"
00274 "movl %%ecx, %%eax \n\t"
00275 "movl %%edx, %%ecx \n\t"
00276 "mull %4 \n\t"
00277 "addl %%ecx, %%eax \n\t"
00278 "adcl $0, %%edx \n\t"
00279 "movl $1000000000, %%ecx \n\t"
00280 "shld $5, %%eax, %%edx \n\t"
00281 "shll $5, %%eax \n\t"
00282 "divl %%ecx \n\t"
00283 :"=a" (*s), "=d" (*ns), "=&c" (dummy)
00284 : "A" (tsc), "g" (l4_scaler_tsc_to_ns)
00285 );
00286 }
00287
00288 L4_INLINE l4_cpu_time_t
00289 l4_ns_to_tsc (l4_uint64_t ns)
00290 {
00291 l4_uint32_t dummy;
00292 l4_cpu_time_t tsc;
00293 __asm__
00294 (" \n\t"
00295 "movl %%edx, %%ecx \n\t"
00296 "mull %3 \n\t"
00297 "movl %%ecx, %%eax \n\t"
00298 "movl %%edx, %%ecx \n\t"
00299 "mull %3 \n\t"
00300 "addl %%ecx, %%eax \n\t"
00301 "adcl $0, %%edx \n\t"
00302 "shld $5, %%eax, %%edx \n\t"
00303 "shll $5, %%eax \n\t"
00304 :"=A" (tsc),
00305 "=&c" (dummy)
00306 :"0" (ns),
00307 "g" (l4_scaler_ns_to_tsc)
00308 );
00309 return tsc;
00310 }
00311
00312 L4_INLINE void
00313 l4_busy_wait_ns (l4_uint64_t ns)
00314 {
00315 l4_cpu_time_t stop = l4_rdtsc();
00316 stop += l4_ns_to_tsc(ns);
00317
00318 while (l4_rdtsc() < stop)
00319 ;
00320 }
00321
00322 L4_INLINE void
00323 l4_busy_wait_us (l4_uint64_t us)
00324 {
00325 l4_cpu_time_t stop = l4_rdtsc ();
00326 stop += l4_ns_to_tsc(us*1000ULL);
00327
00328 while (l4_rdtsc() < stop)
00329 ;
00330 }
00331
00332 EXTERN_C_END
00333
00334 #endif
00335