| #ifndef _GPXE_RDTSC_TIMER_H |
| #define _GPXE_RDTSC_TIMER_H |
| |
| /** @file |
| * |
| * RDTSC timer |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER ); |
| |
| #ifdef TIMER_RDTSC |
| #define TIMER_PREFIX_rdtsc |
| #else |
| #define TIMER_PREFIX_rdtsc __rdtsc_ |
| #endif |
| |
| /** |
| * RDTSC values can easily overflow an unsigned long. We discard the |
| * low-order bits in order to obtain sensibly-scaled values. |
| */ |
| #define TSC_SHIFT 8 |
| |
| /** |
| * Get current system time in ticks |
| * |
| * @ret ticks Current time, in ticks |
| */ |
| static inline __always_inline unsigned long |
| TIMER_INLINE ( rdtsc, currticks ) ( void ) { |
| unsigned long ticks; |
| |
| __asm__ __volatile__ ( "rdtsc\n\t" |
| "shrdl %1, %%edx, %%eax\n\t" |
| : "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" ); |
| return ticks; |
| } |
| |
| #endif /* _GPXE_RDTSC_TIMER_H */ |