Main Page   File List  

rdtsc.h

Go to the documentation of this file.
00001 
00007 /* (c) 2003 Technische Universitaet Dresden
00008  * This file is part of DROPS, which is distributed under the terms of the
00009  * GNU General Public License 2. Please see the COPYING file for details. */
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 /* interface */
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 /* the same, but only 32 bit. Useful for smaller differences,
00039    needs less cycles. */
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 /* the same, but only 32 bit. Useful for smaller differences,
00051    needs less cycles. */
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 /* implementaion */
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         /*"rdtsc\n\t"*/
00165         :
00166         "=A" (v)
00167         : /* no inputs */
00168         );
00169 
00170     return v;
00171 }
00172 
00173 /* the same, but only 32 bit. Useful for smaller differences,
00174    needs less cycles. */
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"   // rdtsc
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 /* the same, but only 32 bit. Useful for smaller differences,
00205    needs less cycles. */
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 /* __l4_rdtsc_h */
00335 

L4 Utilities, part of DROPS  © 2000-2003