aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/qemu/timer.h29
1 files changed, 26 insertions, 3 deletions
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 1766b2d6c7..f67e731f9b 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -171,11 +171,34 @@ static inline int64_t cpu_get_real_ticks(void)
#elif defined(__i386__)
+#include "qemu/cpuid.h"
+
static inline int64_t cpu_get_real_ticks(void)
{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
+ /* There is no convenient GCC define to let us find out whether
+ * the target CPU has 'rdtsc', so we must do an initial runtime
+ * check. Our fallback is the same kind of simple monotonic count
+ * as the default cpu_get_real_ticks implementation.
+ */
+ static int64_t ticks = 0;
+
+#if defined(CONFIG_CPUID_H)
+ static bool checked_rdtsc;
+ static bool have_rdtsc;
+
+ if (!checked_rdtsc) {
+ unsigned int a, b, c, d;
+ have_rdtsc = (__get_cpuid(1, &a, &b, &c, &d) && (d & (1 << 4)));
+ checked_rdtsc = true;
+ }
+ if (have_rdtsc) {
+ int64_t val;
+ asm volatile ("rdtsc" : "=A" (val));
+ return val;
+ }
+ /* Otherwise fall through into no-rdtsc code */
+#endif
+ return ticks++;
}
#elif defined(__x86_64__)