Page 1 of 1

At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 9:15 am
by psjarlo
I'm trying to get the CMOS RTC clock going and I'm up against it a bit.

This is a 64bit kernel, running as an UEFI application, and I run it in Qemu and VirtualBox.

I'm following the instructions from https://wiki.osdev.org/RTC to enable irq8 @ 1KHz.

My version looks like this:

Code: Select all

static void _enable_rtc_timer(void) {
    x86_64_cli();
    x86_64_outb(0x70, 0x8b);        //< also disable NMI
    x86_64_io_wait();
    uint8_t prev = x86_64_inb(0x71);
    x86_64_outb(0x70, 0x8b);
    x86_64_outb(0x71, prev | 0x40);
    x86_64_sti();
}
I've initialized PIC1 and PIC2, and I can confirm that I'm servicing IRQs from the PIT and keyboard correctly.
I've followed the PIC setup procedure from https://wiki.osdev.org/PIC .

When I enable the RTC, and I install an IRQ8 handler, I get nothing. Everything else works but I don't get IRQ8.

There are two possible causes here; one is that PIC2 isn't wired up correctly to serve IRQ>=8 , the other is that IRQ8 isn't firing at all.

So my questions are:
* is there a *known* good reason why this wouldn't just work (as in; "oh, didn't you know that X needs to be divided by Pi first")?
* can anyone recommend a way to narrow this down? I can't trigger an IRQ from software to test if it's actually working (or can I...?), and I can't use Bochs for debugging since it's 64 bit and UEFI...
* other inspired ideas?


cheers,
Jarl

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 11:01 am
by austanss
You can trigger any interrupt with:

Code: Select all

int 0xXX
in this case, to test your handler, use:

Code: Select all

int 0x28

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 11:07 am
by psjarlo
yes, sorry, I wasn't being clear; I was wondering if I could trigger it so that it had to be sent via the PIC.
I know the handler works, and a simple "int" will of course do that. What I'm trying to root cause is why IRQ8 isn't firing.

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 12:11 pm
by nullplan
Is IRQ 2 masked? IRQ 2 is the chaining IRQ, if it is masked then nothing from PIC2 will get through.

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 1:05 pm
by psjarlo
Good point, but I believe it is unmasked, at least the last thing I do in my 8269 init is this;

Code: Select all

// enable IRQ2
x86_64_outb(0x20+1, ~0x2);
x86_64_io_wait();   
// mask all IRQs on PIC2 for now
x86_64_outb(0x0a+1, 0xff);
x86_64_io_wait();
Looks about right?

When I install a handler for an IRQ I unmask the respective handler, so IRQ8 is unmasked on PIC2.

Btw, I found the relevant section in the Linux kernel so I'm going to dig into it a bit more but it may take a while....linux\arch\x86\kernel\i8259.c

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 1:15 pm
by nexos
On the QEMU monitor, run info pic to see what is masked and unmasked. The PIC info is at the top.

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 2:27 pm
by psjarlo
I did, and I'm probably misreading it but it looks ok...
Screenshot 2021-02-17 202621.png

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 2:42 pm
by nexos
A couple things I got from the screenshot
As Octocontrabass was saying, IRQ 2 is masked. This is why the IRQ isn't being raised. Also, it doesn't look like you remapped PIC 1. irq_base is 70, which is the default. Generally, PIC 1 is mapped to ISR 28.
That is my suggestion for this :)

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 2:43 pm
by nullplan

Code: Select all

x86_64_outb(0x0a+1, 0xff);
That probably should have been port 0xa0+1. Doesn't much matter, though, as per your picture, PIC0 has an IMR of 0xFC. So IRQ 0 and IRQ 1 are unmasked, but IRQ 2 is masked. Therefore none of the higher IRQs can get through. I was puzzled by this for a moment, then it hit me:

Code: Select all

x86_64_outb(0x20+1, ~0x2);
That is unmasking IRQ 1, not IRQ 2. To do that you need

Code: Select all

x86_64_outb(0x20+1, ~(1 << 2));
or

Code: Select all

x86_64_outb(0x20+1, 0xfb);

Re: At loss: seeing no IRQ's from PIC2 (testing RTC)

Posted: Wed Feb 17, 2021 3:57 pm
by psjarlo
Thanks both! I can't believe it came down to a classic off by one error and it was staring me in the face all the time. #-o