IRQ1 continuous loop?

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

IRQ1 continuous loop?

Post by YDeeps1 »

I recently setup exception interrupts and have now setup IRQs and (hopefully) mapped them to offsets 0x20 and 0x28 on the IDT with the help of the wiki (https://wiki.osdev.org/8259_PIC) post.

However, on offset 0x21 (index 33 in IDT which should be IRQ1), a continuous loop of IRQ1 interrupts occur right after acknowledging one after the other with a noticeable delay in between each interrupt log (around 70-130ms fluctuating off of the top of my head) which leads me to believe it may be a misconfigured PIT (I haven't touched the PIT yet)? Just curious if this is normal and/or if it can be adjusted/disabled. (I tried to find any sources on this but I couldn't which is why I'm making this post).

Thanks!
Octocontrabass
Member
Member
Posts: 5567
Joined: Mon Mar 25, 2013 7:01 pm

Re: IRQ1 continuous loop?

Post by Octocontrabass »

The PIT is attached to IRQ0, not IRQ1, so it's definitely not the PIT.

It sounds like you've configured the PIC for level-triggered inputs (usually it should be edge-triggered) and you're also not acknowledging the device that drives the IRQ1 line: the keyboard controller.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: IRQ1 continuous loop?

Post by nullplan »

One more note: You should probably mask out all interrupts (except IRQ 2, which is the cascading IRQ), and only unmask them in the drivers of the devices connected to them. This way, if you get an IRQ, you have some way to handle it, rather than just shrug. In the case of interrupt sharing, this can still leave you in an interrupting state, so the common advice is to mask out an interrupt that is occurring and only unmask it once it has been handled. If the interrupt handlers shrug at you, leave the interrupt disabled and continue booting. Hopefully you will drive the other devices on the line soon enough.
Carpe diem!
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: IRQ1 continuous loop?

Post by YDeeps1 »

Thank you for your inputs! And I apologise but it turns out I stupidly set the indexes wrong so those interrupts are actually from IRQ0, not IRQ1 (I have confirmed this with some test inputs). So could it still be the PIT (I masked it for now to avoid interruptions until I need them).
Octocontrabass
Member
Member
Posts: 5567
Joined: Mon Mar 25, 2013 7:01 pm

Re: IRQ1 continuous loop?

Post by Octocontrabass »

In that case, it is the PIT.

Still, you should receive only one interrupt per tick, for a total of about 18 interrupts per second. From your description, it sounds like you were getting a lot more than that, which could mean you've configured the PIC for level-triggered interrupts when you were supposed to configure it for edge-triggered interrupts. (It's hard to say for sure since some virtual machines aren't very good at keeping time.)
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: IRQ1 continuous loop?

Post by YDeeps1 »

Octocontrabass wrote:In that case, it is the PIT.

Still, you should receive only one interrupt per tick, for a total of about 18 interrupts per second. From your description, it sounds like you were getting a lot more than that, which could mean you've configured the PIC for level-triggered interrupts when you were supposed to configure it for edge-triggered interrupts. (It's hard to say for sure since some virtual machines aren't very good at keeping time.)
Actually after analysing it more, I'm actually getting more like 5 per second which definitely doesn't sound like the 18/s default.

I set the PIT to run at 18.222hz like it should anyways and it actually does speed up to the promised 18/s. Maybe the defaults are funky with VirtualBox? Anyways thank you guys!
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: IRQ1 continuous loop?

Post by YDeeps1 »

And I don't want to make a new thread for this but just to confirm, if I would like to go slower than ~54ms per interrupt, would I have to use one shots to set my desired count downs?
Octocontrabass
Member
Member
Posts: 5567
Joined: Mon Mar 25, 2013 7:01 pm

Re: IRQ1 continuous loop?

Post by Octocontrabass »

YDeeps1 wrote:Maybe the defaults are funky with VirtualBox?
Or VirtualBox has issues keeping time accurately, like most virtual machines.
YDeeps1 wrote:And I don't want to make a new thread for this but just to confirm, if I would like to go slower than ~54ms per interrupt, would I have to use one shots to set my desired count downs?
That's already the slowest it can go! If you need a longer delay, you'll have to either let the PIT interrupt you more than once or use a different timer.
YDeeps1
Member
Member
Posts: 69
Joined: Tue Aug 31, 2021 7:25 am
Discord: speedy.dev
Contact:

Re: IRQ1 continuous loop?

Post by YDeeps1 »

Thanks!
thewrongchristian
Member
Member
Posts: 426
Joined: Tue Apr 03, 2018 2:44 am

Re: IRQ1 continuous loop?

Post by thewrongchristian »

YDeeps1 wrote:And I don't want to make a new thread for this but just to confirm, if I would like to go slower than ~54ms per interrupt, would I have to use one shots to set my desired count downs?
Exactly.

My timer is two layered. I have a platform specific timer, which has a one shot API, and specifies how long in microseconds the next call back needs to be. The platform specific layer then programs the timing source to call the callback using whatever mechanism the platform provides.

I only have a PIT provider at the moment, and as you've noticed, the longest timer that can provide is ~54ms (65535 cycles of the PIT 1193182Hz clock, but it can be 65536 cycles) So every PIT interrupt, I just subtract 65535 from however many cycles I have left. When that remaining time is less than 65535 cycles, reprogram the PIT timer to that number of cycles, then next interrupt, I fire the callback.

So, for example, to wait 1 second, I use the following sequence of PIT 1 shot timeouts:
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 65535
  • 13552
After this last interrupt, the callback is called, having waited 1193182 cycles (= 1 second). This layer can be easily replaced with some other one shot timer, such as the APIC timer.

The higher layer is just an ordered list of pending timers, sorted by interval to next time out. The upper layer timer just programs the lower layer to the interval at the head of the list, and waits for the callback.

It gets a little complicated, if halfway through waiting for this 1 second callback, another timer is started that would expire before the 1 second timer. Then, the lower level one shot is cancelled (we get back how long is left), and the new timer is scheduled instead. Then we can restart the 1 second timer, based on how long the intermediate timer was and how long we had left.
Post Reply