PIT timer on real hardware?

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.
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

PIT timer on real hardware?

Post by YDeeps1 »

I tested my OS on real hardware by flashing it to a flash drive and it works great (PIC/GDT/IDT sets up correctly); however one problem is that the PIT timer does not acknowledge my set channel 0 frequency request:

Code: Select all

uint16_t ct_number = 1193180 / 100;
io_port::bit_8::out(0x43, 0x36);    
io_port::bit_8::out(0x40, ct_number & 0xFF);  
io_port::bit_8::out(0x40, ct_number >> 8);
as it runs at a much lower frequency when testing on real hardware. Perhaps I would have to use APIC? (testing on CPU Intel Q6600).

On VirtualBox the timer runs at the expected frequency and I do not have any leads to go on.

Would love some information on this! Thank you.
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: PIT timer on real hardware?

Post by 8infy »

YDeeps1 wrote:I tested my OS on real hardware by flashing it to a flash drive and it works great (PIC/GDT/IDT sets up correctly); however one problem is that the PIT timer does not acknowledge my set channel 0 frequency request:

Code: Select all

uint16_t ct_number = 1193180 / 100;
io_port::bit_8::out(0x43, 0x36);    
io_port::bit_8::out(0x40, ct_number & 0xFF);  
io_port::bit_8::out(0x40, ct_number >> 8);
as it runs at a much lower frequency when testing on real hardware. Perhaps I would have to use APIC? (testing on CPU Intel Q6600).

On VirtualBox the timer runs at the expected frequency and I do not have any leads to go on.

Would love some information on this! Thank you.
I don't know what your actual problem is but PIT runs quite well on real hardware, at least from my experience.
Perhaps try other emulators, like VMware or QEMU and see if it works there.
As for LAPIC, you could use it but you would need some other timer to calibrate it.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: PIT timer on real hardware?

Post by Octocontrabass »

YDeeps1 wrote:it runs at a much lower frequency when testing on real hardware.
How are you measuring the frequency?
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

Octocontrabass wrote:
YDeeps1 wrote:it runs at a much lower frequency when testing on real hardware.
How are you measuring the frequency?
If you're referring to how I came to the conclusion, I setup a small text update every time an IRQ0 interrupt came and added them to the total. The frequency was roughly 16-18 which lines up with the default PIT frequency as opposed to the 100x/s set (which works correctly on VirtualBox).

Other than that everything else works fine such as the EOI and everything data line wise.
Last edited by YDeeps1 on Tue Sep 21, 2021 4:31 pm, edited 1 time in total.
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

8infy wrote:
YDeeps1 wrote:I tested my OS on real hardware by flashing it to a flash drive and it works great (PIC/GDT/IDT sets up correctly); however one problem is that the PIT timer does not acknowledge my set channel 0 frequency request:

Code: Select all

uint16_t ct_number = 1193180 / 100;
io_port::bit_8::out(0x43, 0x36);    
io_port::bit_8::out(0x40, ct_number & 0xFF);  
io_port::bit_8::out(0x40, ct_number >> 8);
as it runs at a much lower frequency when testing on real hardware. Perhaps I would have to use APIC? (testing on CPU Intel Q6600).

On VirtualBox the timer runs at the expected frequency and I do not have any leads to go on.

Would love some information on this! Thank you.
I don't know what your actual problem is but PIT runs quite well on real hardware, at least from my experience.
Perhaps try other emulators, like VMware or QEMU and see if it works there.
As for LAPIC, you could use it but you would need some other timer to calibrate it.
Emulators work fine. It's just that the PIT will not change the frequency to my requested value on real hardware.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: PIT timer on real hardware?

Post by Octocontrabass »

YDeeps1 wrote:If you're referring to how I came to the conclusion, I setup a small text update every time an IRQ0 interrupt came and added them to the total.
Are you sure you're not missing any ticks? Updating the screen on every tick might take long enough that you miss some.

What motherboard are you using? Maybe the chipset doesn't contain a complete i8254, or maybe the BIOS configures a different timer as the IRQ0 source by default.
foliagecanine
Member
Member
Posts: 148
Joined: Sun Aug 23, 2020 4:35 pm

Re: PIT timer on real hardware?

Post by foliagecanine »

YDeeps1 wrote:On VirtualBox the timer runs at the expected frequency and I do not have any leads to go on.
How did you manage to get VirtualBox to run at "expected" speeds? In my experience VirtualBox is horrible with the PIT, often running at 10% speed. VMware is fine, QEMU is fine, Bochs is fine, but not VirtualBox.

Here's how I init the PIT. It runs fine on all the hardware I've tested.

Code: Select all

void init_pit(uint32_t freq) {
	frequency = freq; // frequency is a global variable
	uint32_t pitfreq = 1193181 / freq;
	outb(0x43, 0x34);
	outb(0x40, (uint8_t)(pitfreq));
	outb(0x40, (uint8_t)(pitfreq >> 8));
}
Also, is there a reason you are using Mode 3 (square wave generator) rather than Mode 2 (rate generator)?
My OS: TritiumOS
https://github.com/foliagecanine/tritium-os
void warranty(laptop_t laptop) { if (laptop.broken) return laptop; }
I don't get it: Why's the warranty void?
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

Octocontrabass wrote:
YDeeps1 wrote:If you're referring to how I came to the conclusion, I setup a small text update every time an IRQ0 interrupt came and added them to the total.
Are you sure you're not missing any ticks? Updating the screen on every tick might take long enough that you miss some.

What motherboard are you using? Maybe the chipset doesn't contain a complete i8254, or maybe the BIOS configures a different timer as the IRQ0 source by default.
I am certain. In fact I tested it on a semi-ancient machine I have from the 2000s and it worked just fine. The ticks go up about every hundred per second and on the machine I tested on previously, it only went up by about 20 ticks per second (it's very difficult to confuse these).

The machine I tested on is a cheap MSI motherboard (G41M-S03). I did also initially think there is something funky going on with the implementations. If all else fails I may give the APIC a go and go through with the configurations.
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

foliagecanine wrote:
YDeeps1 wrote:On VirtualBox the timer runs at the expected frequency and I do not have any leads to go on.
How did you manage to get VirtualBox to run at "expected" speeds? In my experience VirtualBox is horrible with the PIT, often running at 10% speed. VMware is fine, QEMU is fine, Bochs is fine, but not VirtualBox.

Here's how I init the PIT. It runs fine on all the hardware I've tested.

Code: Select all

void init_pit(uint32_t freq) {
	frequency = freq; // frequency is a global variable
	uint32_t pitfreq = 1193181 / freq;
	outb(0x43, 0x34);
	outb(0x40, (uint8_t)(pitfreq));
	outb(0x40, (uint8_t)(pitfreq >> 8));
}
Also, is there a reason you are using Mode 3 (square wave generator) rather than Mode 2 (rate generator)?
No reason really other than I must've misread/misset the bits. I changed it to rate generators now though (not that it matters in this issue though).
(I did test it to make sure before I sounded stupid :lol:)
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: PIT timer on real hardware?

Post by Octocontrabass »

YDeeps1 wrote:In fact I tested it on a semi-ancient machine I have from the 2000s and it worked just fine.
That doesn't mean the newer machine is fast enough to update the display 100 times per second. (I don't think this is actually the issue, but you should still try to rule it out - for example, wait for five ticks before updating the display.)
YDeeps1 wrote:The machine I tested on is a cheap MSI motherboard (G41M-S03).
This board has an ICH7 southbridge, so any issues with the PIT should be fairly well-known (to OS developers at least), but I can't find any. Maybe there's a problem with io_port::bit_8::out()? I don't know what could be wrong with it, though.

Incidentally, the ICH7 datasheet mentions that timer 0 is typically programmed for mode 3, so it should still work even if mode 2 makes more sense.
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

Octocontrabass wrote:
YDeeps1 wrote:In fact I tested it on a semi-ancient machine I have from the 2000s and it worked just fine.
That doesn't mean the newer machine is fast enough to update the display 100 times per second. (I don't think this is actually the issue, but you should still try to rule it out - for example, wait for five ticks before updating the display.)
YDeeps1 wrote:The machine I tested on is a cheap MSI motherboard (G41M-S03).
This board has an ICH7 southbridge, so any issues with the PIT should be fairly well-known (to OS developers at least), but I can't find any. Maybe there's a problem with io_port::bit_8::out()? I don't know what could be wrong with it, though.

Incidentally, the ICH7 datasheet mentions that timer 0 is typically programmed for mode 3, so it should still work even if mode 2 makes more sense.
Oh I did actually initially try updating it every 50 ticks but it was still very slow so that's ruled out.
I'll also try playing around with the modes and different settings in case this makes a difference and to check if the PIT is actually acknowledging anything I'm sending it.
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

So strange. I performed a read-back on both before setting and after setting and the results come back as expected (bits change + matches with VM) so there should be no reason for it not to change the ticking frequency. It may indeed be faulty but I just haven't noticed since all operating systems I've ever used on it used APIC instead?
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: PIT timer on real hardware?

Post by YDeeps1 »

Turns out I was looking in the wrong place all along. There's nothing wrong with the PIT, but with doing math operations on floating point numbers. For some reason dividing the base frequency to get the desired frequency and casting it to an unsigned number, it just returns 0 on the real machine while the VM does the calculation without a problem? Is there something I missed which results in me not being able to do float operations correctly?

On another test when simply declaring a floating point number and casting it to an integer, it goes to far side of a negative 32 bit number.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: PIT timer on real hardware?

Post by Octocontrabass »

YDeeps1 wrote:Is there something I missed which results in me not being able to do float operations correctly?
Sounds like you missed initializing the CPU's float units. Without proper initialization, float operations may either cause exceptions or silently return the wrong values.

Kernels are usually written and compiled to avoid operations that require extended registers the way floating-point operations do. Using extended registers in your kernel means your kernel has to save and restore those registers on every entry and exit, which can be a lot of overhead (especially since some x86 CPUs have over 2kiB of extended registers).

The code you provided to demonstrate the problem doesn't have any float operations.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: PIT timer on real hardware?

Post by h0bby1 »

I had this issue before, the floating point working in virtual box, but not other vm or hardware.

You need to initialize fpu first there are codes for this on the wiki, essentially enabling it, setting control Word flags etc

For some reason it worked fine in virtual box without this.

Maybe you can use sse instead.

Its true its probably not very good to use floats in kernel, but from what i could see the timer is the only place float is really going to be useful to compute precise timer , there are not much other place where you deal with fractional numbers, and timer is only initialized at first most likely before the task manager or userland kicks in so it should be harmless on the task switching side.
Post Reply