aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/examples/bochsrc1
-rw-r--r--tools/ioemu/include/pc_system.h27
-rw-r--r--tools/ioemu/iodev/cpu.cc7
-rw-r--r--tools/ioemu/iodev/pc_system.cc14
4 files changed, 43 insertions, 6 deletions
diff --git a/tools/examples/bochsrc b/tools/examples/bochsrc
index 860c5499eb..8075a7658b 100644
--- a/tools/examples/bochsrc
+++ b/tools/examples/bochsrc
@@ -16,4 +16,3 @@ error: action=report
panic: action=ask
mouse: enabled=0
-ips: 1500000
diff --git a/tools/ioemu/include/pc_system.h b/tools/ioemu/include/pc_system.h
index c35c35bf52..c8ea664577 100644
--- a/tools/ioemu/include/pc_system.h
+++ b/tools/ioemu/include/pc_system.h
@@ -45,6 +45,13 @@ BOCHSAPI extern class bx_pc_system_c bx_pc_system;
extern double m_ips;
#endif
+#ifdef BX_USE_VMX
+extern unsigned int tsc_per_bx_tick;
+
+#define rdtscll(val) \
+ __asm__ __volatile__("rdtsc" : "=A" (val))
+#endif
+
class BOCHSAPI bx_pc_system_c : private logfunctions {
private:
@@ -87,6 +94,26 @@ private:
double m_ips; // Millions of Instructions Per Second
#endif
+#ifdef BX_USE_VMX
+ static Bit64s get_clock(void) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000000LL + tv.tv_usec;
+ }
+
+ static Bit64u cpu_calibrate_ticks(void) {
+ Bit64s usec, t1, t2;
+
+ usec = get_clock();
+ rdtscll(t1);
+
+ usleep(50 * 1000);
+ usec = get_clock() - usec;
+ rdtscll(t2);
+
+ return (((t2 - t1) * 1000000LL + (usec >> 1)) / usec);
+ }
+#endif
// This handler is called when the function which decrements the clock
// ticks finds that an event has occurred.
void countdownEvent(void);
diff --git a/tools/ioemu/iodev/cpu.cc b/tools/ioemu/iodev/cpu.cc
index 11e761d774..71853afa61 100644
--- a/tools/ioemu/iodev/cpu.cc
+++ b/tools/ioemu/iodev/cpu.cc
@@ -167,9 +167,6 @@ bx_cpu_c::timer_handler(void)
#define rdtscl(low) \
__asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
-#define rdtscll(val) \
- __asm__ __volatile__("rdtsc" : "=A" (val))
-
void
bx_cpu_c::cpu_loop(int max_instr_count)
{
@@ -211,9 +208,9 @@ bx_cpu_c::cpu_loop(int max_instr_count)
#endif
if (t2 <= t1)
- BX_TICKN((t2 + ULONGLONG_MAX - t1));
+ BX_TICKN((t2 + ULONGLONG_MAX - t1) / tsc_per_bx_tick);
else
- BX_TICKN((t2 - t1));
+ BX_TICKN((t2 - t1) / tsc_per_bx_tick);
t1 = t2;
timer_handler();
diff --git a/tools/ioemu/iodev/pc_system.cc b/tools/ioemu/iodev/pc_system.cc
index 1b58fe775f..de34d9914b 100644
--- a/tools/ioemu/iodev/pc_system.cc
+++ b/tools/ioemu/iodev/pc_system.cc
@@ -44,6 +44,10 @@ unsigned long ips_count=0;
double m_ips; // Millions of Instructions Per Second
#endif
+#ifdef BX_USE_VMX
+unsigned int tsc_per_bx_tick;
+#endif
+
// Option for turning off BX_TIMER_DEBUG?
// Check out m_ips and ips
@@ -98,6 +102,16 @@ bx_pc_system_c::init_ips(Bit32u ips)
a20_mask = 0xffffffff;
#endif
+#ifdef BX_USE_VMX
+ Bit64u phy_cpu_freq = cpu_calibrate_ticks();
+
+ if (ips == 500000) { //default ips: we use fixed scaling factor to calulate ips
+ tsc_per_bx_tick = 2000;
+ ips = phy_cpu_freq / tsc_per_bx_tick;
+ } else //use uesr defined ips to calulate factor
+ tsc_per_bx_tick = ((phy_cpu_freq + (ips>>1)) / ips);
+#endif
+
// parameter 'ips' is the processor speed in Instructions-Per-Second
m_ips = double(ips) / 1000000.0L;