Page 1 of 1

Bochs' RTC Periodic Interrupt (aka IRQ 8) going nuts

Posted: Sun Dec 29, 2013 10:31 pm
by zhiayang
Hello. I've had this problem before with Bochs's PIT before -- basically, it sends more interrupts than it should. I understand Bochs is not designed to emulate realtime execution, but for timekeeping it would be nice.

To fix the PIT problem I used

Code: Select all

clock: sync=realtime, time0=utc, rtc_sync=1
Which fixed it. Since then, I have moved wall clock timekeeping to the RTC periodic interrupt service. It works fine on VBox and QEMU, but again the interrupts are too fast.

What's the setting to fix it?


EDIT:

Code: Select all

void InitialiseTimer()
{
	Kernel::HardwareAbstraction::Interrupts::SetGate(32 + 8, (uint64_t)Time::RTCHandler, 0x08, 0xEE);

	IOPort::WriteByte(0x70, 0x8B);					// select register B, and disable NMI
	uint8_t prev = IOPort::ReadByte(0x71);			// read the current value of register B

	IOPort::WriteByte(0x70, 0x8B);					// set the index again (a read will reset the index to register D)
	IOPort::WriteByte(0x71, prev | 0x40);			// write the previous value ORed with 0x40. This turns on bit 6 of register B

	uint8_t rate = RTCTImerShiftAmt;				// rate must be above 2 and not over 15
	IOPort::WriteByte(0x70, 0x8A);					// set index to register A, disable NMI
	prev = IOPort::ReadByte(0x71);					// get initial value of register A
	IOPort::WriteByte(0x70, 0x8A);					// reset index to A
	IOPort::WriteByte(0x71, (prev & 0xF0) | rate);	//write only our rate to A. Note, rate is the bottom 4 bits.

	IOPort::WriteByte(0x70, 0x0C);
	IOPort::ReadByte(0x71);
}

Re: Bochs' RTC Periodic Interrupt (aka IRQ 8) going nuts

Posted: Thu Jan 02, 2014 6:59 am
by Combuster
Based on the documentation I'd expect that rtc_sync should do exactly what you want. However, you can try the "accurate" emulation mode first:

Code: Select all

sync=slowdown
If that magically fixes things, it might be worth investigating bochs specifics more deeply.

Re: Bochs' RTC Periodic Interrupt (aka IRQ 8) going nuts

Posted: Fri Jan 03, 2014 9:59 am
by zhiayang
Thanks Combuster for replying.
Unfortunately, slowdown does exactly what it says, it slows down simulation -- too much IMO, booting takes like 20 seconds now.

Also it doesn't appear to actually synchronise the interrupt rates, now they're coming in too slow and my timekeeping is falling behind.

Re: Bochs' RTC Periodic Interrupt (aka IRQ 8) going nuts

Posted: Fri Jan 03, 2014 2:37 pm
by Brendan
Hi,

For Bochs there's basically 3 options:
  • realtime - the clock/s are kept in sync with real time, but the emulation is not deterministic (timer IRQs can occur at "random" times making it impossible to get the same result twice in a row if there's any sort of race conditions, etc)
  • slowdown - the emulator is deterministic, and the clock/s are kept in sync with real time by slowing emulation down when virtual time gets ahead of real time. The "IPS" setting determines how fast the emulator tries to emulate, so by setting that correctly you can reduce the time Bochs spends waiting for real time to catch up to virtual time
  • none - the emulator is deterministic, but the clock/s aren't kept in sync with real time at all. The "IPS" setting determines how fast the emulator tries to emulate, so by setting that correctly you can get virtual time "close enough" to real time
My guess is that you haven't set the "IPS" setting properly (and it's currently set much lower than it could be), which makes "slowdown" very slow, and also makes "none" very inaccurate (e.g. 1000 timer IRQs per virtual second ends up being a lot more timer IRQs per real second because 1 virtual second is a small fraction of a real second).


Cheers,

Brendan

Re: Bochs' RTC Periodic Interrupt (aka IRQ 8) going nuts

Posted: Fri Jan 03, 2014 9:55 pm
by zhiayang
Brendan wrote:Hi,

For Bochs there's basically 3 options:
  • realtime - the clock/s are kept in sync with real time, but the emulation is not deterministic (timer IRQs can occur at "random" times making it impossible to get the same result twice in a row if there's any sort of race conditions, etc)
  • slowdown - the emulator is deterministic, and the clock/s are kept in sync with real time by slowing emulation down when virtual time gets ahead of real time. The "IPS" setting determines how fast the emulator tries to emulate, so by setting that correctly you can reduce the time Bochs spends waiting for real time to catch up to virtual time
  • none - the emulator is deterministic, but the clock/s aren't kept in sync with real time at all. The "IPS" setting determines how fast the emulator tries to emulate, so by setting that correctly you can get virtual time "close enough" to real time
My guess is that you haven't set the "IPS" setting properly (and it's currently set much lower than it could be), which makes "slowdown" very slow, and also makes "none" very inaccurate (e.g. 1000 timer IRQs per virtual second ends up being a lot more timer IRQs per real second because 1 virtual second is a small fraction of a real second).


Cheers,

Brendan

Thanks for your explanation Brendan, I guess I'll have to go fiddle with the IPS setting.