Kazu wrote:
If you set /proc/sys/dev/rtc/max-user-freq to 1024 and disable cpuspeed
service that is related to SpeedStep/PowerNow! on a host OS, the clock in
guest OS works fine.
I checked it on i686/x86_64 Linux host.
Mind saying how you checked this? I'm on a pentium-III mobile
processor and the only way I've seen so far to make qemu + rdtsc behave
100% is by disabling ACPI (boot with -noacpi). If I add a simple printf
to cpu_calibrate_ticks it doesn't seem fixed to me:
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 1126809000
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 17308857
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 103710852
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 15292604
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 96695295
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 1126761234
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 1126762522
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi
-kernel-kqemu -soundhw es1370
ticks_per_sec set as 49791263
The first entry is with the patch attached called
'ticks_from_proc.patch' applied (I've been using this for almost a
year). It sets the value ticks_per_sec, which happens to be used by a
lot of qemu's hardware emulation, using information in /proc/cpuinfo.
This doesn't fix the time issue as rdtsc is still used every time a
SIGALRM signal occurs for timing, but at least the guest's emulated
hardware runs to speed.
[EMAIL PROTECTED] /prog/qemu-cvs/qemu-acpi/qemu $ find . -type f -exec fgrep
-l 'ticks_per_sec' {} \;
./audio/audio.c
./audio/noaudio.c
./audio/wavaudio.c
./monitor.c
./vl.c
./vl.h
./hw/acpi.c
./hw/adlib.c
./hw/arm_timer.c
./hw/cuda.c
./hw/fdc.c
./hw/i8254.c
./hw/i8259.c
./hw/ide.c
./hw/mc146818rtc.c
./hw/mips_r4k.c
./hw/ppc.c
./hw/sb16.c
./hw/sh7750.c
./hw/slavio_timer.c
./hw/usb-uhci.c
The second patch adds the printf statement so you can see this for
yourself.
--- a/vl.c 2006-05-16 06:42:11.000000000 -0500
+++ b/vl.c 2006-05-16 06:35:25.000000000 -0500
@@ -637,6 +637,7 @@
usec = get_clock() - usec;
ticks = cpu_get_real_ticks() - ticks;
ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
+ printf("ticks_per_sec set as %lli\n", ticks_per_sec);
}
#endif /* !_WIN32 */
Index: qemu/vl.c
@@ -596,8 +596,43 @@
#endif
}
+uint64_t get_tps_from_proc()
+{
+ FILE *fp;
+ char buf[30];
+ double cpu_mhz;
+
+ if (!(fp = fopen("/proc/cpuinfo", "r")))
+ return 0;
+
+ /* find wanted line */
+ while (fgets(buf, 30, fp) != NULL)
+ if (!strncmp(buf, "cpu MHz", 7))
+ break;
+
+ /* line not found? */
+ if (feof(fp)) {
+ fclose(fp);
+ return 0;
+ }
+ fclose(fp);
+
+ /* put 'cpu MHz' value into cpu_mhz */
+ if (!sscanf(&buf[9], ": %lf", &cpu_mhz))
+ return 0;
+
+ /* return estimated ticks/sec value */
+ return (uint64_t)(cpu_mhz * 1000000.0);
+}
+
void cpu_calibrate_ticks(void)
{
+ if (!(ticks_per_sec = get_tps_from_proc()))
+ fprintf(stderr, "Could not obtain ticks/sec. from /proc/cpuinfo\n \
+ resorting to regular method (tsc)\n");
+ else /* value obtained, skip below */
+ return;
+
int64_t usec, ticks;
usec = get_clock();
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel