summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2012-07-26 15:15:38 -0700
committerPatrick Georgi <patrick@georgi-clan.de>2012-07-27 14:41:20 +0200
commit911f446d32283676dee7546be4015dac25fe463b (patch)
treec9091def1defd8456ac7180ea1e4d9f69f1357a6
parent08ef498d0bfd5d3cfaf70cdad1a8780d9dd2143e (diff)
downloadcoreboot-911f446d32283676dee7546be4015dac25fe463b.tar.xz
x86emu: 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. Imported from: http://cgit.freedesktop.org/xorg/xserver/commit/?id=c4b7e9d1c16797c3e4b1200b40aceab5696a7fb8 Change-Id: I8fba1a060c57ccb7bbd44aa321dd349bc56bf574 Signed-off-by: Stefan Reinauer <reinauer@google.com> Reviewed-on: http://review.coreboot.org/1362 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
-rw-r--r--src/devices/oprom/x86emu/ops2.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/devices/oprom/x86emu/ops2.c b/src/devices/oprom/x86emu/ops2.c
index 29c2a64054..113ac0a498 100644
--- a/src/devices/oprom/x86emu/ops2.c
+++ b/src/devices/oprom/x86emu/ops2.c
@@ -156,6 +156,40 @@ static void x86emuOp2_wrmsr(u8 op2)
}
/****************************************************************************
+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,0x32
* ****************************************************************************/
@@ -1728,7 +1762,7 @@ void (*x86emu_optab2[256])(u8) =
/* 0x2f */ x86emuOp2_illegal_op,
/* 0x30 */ x86emuOp2_wrmsr,
-/* 0x31 */ x86emuOp2_illegal_op,
+/* 0x31 */ x86emuOp2_rdtsc,
/* 0x32 */ x86emuOp2_rdmsr,
/* 0x33 */ x86emuOp2_illegal_op,
/* 0x34 */ x86emuOp2_illegal_op,