Open Vort opened 6 months ago
May be you could attach the source code for this program. The Windows Defender doesn't let me download the test, says it is infected by Troyan
#include <windows.h>
#include <iostream>
#include <iomanip>
int main()
{
LARGE_INTEGER oldTicks = { 0 };
LARGE_INTEGER ticks = { 0 };
QueryPerformanceCounter(&oldTicks);
for (;;)
{
Sleep(1000);
QueryPerformanceCounter(&ticks);
std::cout << std::setw(20) << ticks.QuadPart <<
std::setw(20) << ticks.QuadPart - oldTicks.QuadPart << std::endl;
oldTicks = ticks;
}
return 0;
}
What timer settings do you use ? Realtime ? Slowdown ? I used to clock: sync=none, time0=local With this setting no issue at all:
What timer settings do you use ? Realtime ? Slowdown ?
I tried both slowdown
and none
- effect is the same.
Here is config which I use now: bochsrc_xp_tsc_test.zip.
Problem may be specific to Windows XP.
This is what image I was using to install it: ru_windows_xp_professional_with_service_pack_3_x86_cd_vl_x14-74146.iso
.
I tested 1 more Windows XP disc (problem appears) and 2 Windows 7 discs - no problem (and lower difference between ticks).
Looks like Windows XP uses ACPI Timer with frequency of 3579545 Hz, while Windows 7 uses frequency tied to IPS value (which probably means use of Timestamp Counter).
Article about ACPI timer states that its counter may have 24 bit range. When I subtract values, visible on my first screenshot: 3589865
and -13199701
, I get 16789566
, which is very close to 2^24 (16777216
), maybe this property is related to the bug somehow.
After Windows XP starts, bx_acpi_ctrl_c::set_irq_level(true)
gets called only once.
Looks like in case of correct timer functioning, interrupts should occur periodically.
Windows XP uses IRQ 9 for ACPI, making such change allows timer to tick properly:
diff --git a/bochs/iodev/acpi.cc b/bochs/iodev/acpi.cc
index 2fa0168d8..43f26dd94 100644
--- a/bochs/iodev/acpi.cc
+++ b/bochs/iodev/acpi.cc
@@ -240,7 +240,8 @@ void bx_acpi_ctrl_c::after_restore_state(void)
void bx_acpi_ctrl_c::set_irq_level(bool level)
{
- DEV_pci_set_irq(BX_ACPI_THIS s.devfunc, BX_ACPI_THIS pci_conf[0x3d], level);
+ if (level)
+ DEV_pic_raise_irq(9);
}
Bit32u bx_acpi_ctrl_c::get_pmtmr(void)
But, of course, this is not proper solution. Just confirmation that problems with QueryPerformanceCounter
are related to interrupt processing for Power Management Timer.
Values from
And this is how output should look like (VirtualBox and real hardware):
![image](https://github.com/bochs-emu/Bochs/assets/1242858/05cffaeb-3d70-4442-b3d3-7bb0ca4393fe)
QueryPerformanceCounter
function should only advance forward, but in Bochs jumps back happen. I made test program which shows such behaviour: qpctest.zip. This is what it outputs in Bochs on Windows XP:Version: 326114f4e72a59fa8e3c6fb617510c444e3950ac.