IRQ1 continuous loop?
IRQ1 continuous loop?
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!
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!
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: IRQ1 continuous loop?
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.
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.
Re: IRQ1 continuous loop?
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!
Re: IRQ1 continuous loop?
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).
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: IRQ1 continuous loop?
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.)
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.)
Re: IRQ1 continuous loop?
Actually after analysing it more, I'm actually getting more like 5 per second which definitely doesn't sound like the 18/s default.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.)
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!
Re: IRQ1 continuous loop?
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?
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: IRQ1 continuous loop?
Or VirtualBox has issues keeping time accurately, like most virtual machines.YDeeps1 wrote:Maybe the defaults are funky with VirtualBox?
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 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?
Re: IRQ1 continuous loop?
Thanks!
-
- Member
- Posts: 426
- Joined: Tue Apr 03, 2018 2:44 am
Re: IRQ1 continuous loop?
Exactly.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?
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
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.