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

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

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

Post 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);
}
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

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

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

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

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

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

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

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

Post 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.
Post Reply