summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2007-02-06 14:57:22 -0800
committerKeith Packard <keithp@guitar.keithp.com>2007-02-17 17:15:56 -0800
commitd3f507c2a2cc190d417a257b40a49a4a2926e3d3 (patch)
tree26c65866addfe8afdfb0c1f1f409313e40db5602
parent8a16682892dd73e1b17955ded89a74c077d54f7f (diff)
Add an RDTSC implementation to the x86 emulator.
This instruction is being used in some debug VBIOSes. This implementation doesn't even try to be accurate. Instead, it just increments the counter by a fixed amount every time an rdtsc instruction in encountered, to avoid divides by zero.
-rw-r--r--hw/xfree86/x86emu/ops2.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/hw/xfree86/x86emu/ops2.c b/hw/xfree86/x86emu/ops2.c
index 7b0156aaa..8c6c53539 100644
--- a/hw/xfree86/x86emu/ops2.c
+++ b/hw/xfree86/x86emu/ops2.c
@@ -65,6 +65,40 @@ static void x86emuOp2_illegal_op(
/****************************************************************************
REMARKS:
+Handles opcode 0x0f,0x31
+****************************************************************************/
+static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
+{
+#ifdef __HAS_LONG_LONG__
+ static u64 counter = 0;
+#else
+ static u32 counter = 0;
+#endif
+
+ counter += 0x10000;
+
+ /* read timestamp counter */
+ /*
+ * Note that instead of actually trying to accurately measure this, we just
+ * increase the counter by a fixed amount every time we hit one of these
+ * instructions. Feel free to come up with a better method.
+ */
+ START_OF_INSTR();
+ DECODE_PRINTF("RDTSC\n");
+ TRACE_AND_STEP();
+#ifdef __HAS_LONG_LONG__
+ M.x86.R_EAX = counter & 0xffffffff;
+ M.x86.R_EDX = counter >> 32;
+#else
+ M.x86.R_EAX = counter;
+ M.x86.R_EDX = 0;
+#endif
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
Handles opcode 0x0f,0x80-0x8F
****************************************************************************/
static void x86emuOp2_long_jump(u8 op2)
@@ -2580,7 +2614,7 @@ void (*x86emu_optab2[256])(u8) =
/* 0x2f */ x86emuOp2_illegal_op,
/* 0x30 */ x86emuOp2_illegal_op,
-/* 0x31 */ x86emuOp2_illegal_op,
+/* 0x31 */ x86emuOp2_rdtsc,
/* 0x32 */ x86emuOp2_illegal_op,
/* 0x33 */ x86emuOp2_illegal_op,
/* 0x34 */ x86emuOp2_illegal_op,