Page 1 of 6

Issues with interrupts

Posted: Thu Aug 04, 2022 1:01 pm
by Techflash
Before I even start, I want to say that: Yes, I have read the GDT and IDT and "Why are my interrupts not working?" page on the Wiki. My code is hosted on https://github.com/techflashYT/Techflash-OS
It does not crash. It makes it to the inf loop at the end of the kernel, but nothing happens at all, neither the PIT interrupt, nor the keyboard works at all.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 1:04 pm
by Octocontrabass
Where do you enable interrupts?

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 1:32 pm
by Techflash
Octocontrabass wrote:Where do you enable interrupts?
I found the `sti` instruction in both ISRASM.S and IDTASM.S

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 1:33 pm
by Octocontrabass
In ISRASM the STI instruction occurs immediately before IRETQ, so it does nothing. Delete it.

In IDTASM the STI instruction occurs in the function IDTFlush. Where do you call IDTFlush?

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 3:31 pm
by Techflash
Octocontrabass wrote:In ISRASM the STI instruction occurs immediately before IRETQ, so it does nothing. Delete it.

In IDTASM the STI instruction occurs in the function IDTFlush. Where do you call IDTFlush?
Crap, the file must not have saved right last time, hang on.

UPDATE: Fixed the broken IDT code, still doesn't work.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 3:45 pm
by Octocontrabass
Where do you initialize the interrupt controller?

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 3:49 pm
by Techflash
Octocontrabass wrote:Where do you initialize the interrupt controller?
I've heard that it doesn't need to be; GRUB already initializes it. If that's incorrect I can do that.

Also, wouldn't it triple fault if I tried to send commands to it before initialization?

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 3:55 pm
by Octocontrabass
Where on earth did you hear that? Neither Multiboot nor Multiboot2 mention anything about it.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 4:07 pm
by Techflash
Octocontrabass wrote:Where on earth did you hear that? Neither Multiboot nor Multiboot2 mention anything about it.
I don't remember anymore, it was a while ago.
UPDATE: Found a function on the Wiki for initializing the PIC, but I can't seem to find anywhere what parameters to call it with.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 5:10 pm
by Octocontrabass
Techflash wrote:Found a function on the Wiki for initializing the PIC, but I can't seem to find anywhere what parameters to call it with.
If you're talking about the code on this page, it writes those values to the PICs during initialization. You can refer to the 8259A datasheet to see exactly how each 8259A will interpret those values.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 6:03 pm
by Techflash
Octocontrabass wrote:
Techflash wrote:Found a function on the Wiki for initializing the PIC, but I can't seem to find anywhere what parameters to call it with.
If you're talking about the code on this page, it writes those values to the PICs during initialization. You can refer to the 8259A datasheet to see exactly how each 8259A will interpret those values.
Alright, I'll do that then, I need to take a break for a few hours though.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 9:03 pm
by Techflash
UPDATE: It really seems like it's already being initialized somewhere... somehow. Not sure where in the code it is, but since I'm definitely already receiving interrupts, I think that the PIC is fine. But now after some tweaking to my IDT code, I'm getting this error in Bochs:

Code: Select all

06958696000e[CPU0  ] interrupt(long mode): must be 64 bit segment
06958696000e[CPU0  ] interrupt(long mode): must be 64 bit segment
06958696000e[CPU0  ] interrupt(long mode): must be 64 bit segment
(0).[6958696000] [0x000000113f30] 0008:ffffffffffe03f30 (unk. ctxt): test ecx, edx             ; 85d1
06958696000p[CPU0  ] >>PANIC<< exception(): 3rd (13) exception with no resolution
My code segment (0x08) according to Bochs is 64-bit:

Code: Select all

cs:0x0008, dh=0x00209900, dl=0x0000ffff, valid=1
        Code segment, base=0x00000000, limit=0x0000ffff, Execute-Only, Non-Conforming, Accessed, 64-bit
The only thing that I can think of is the IDT is messed up and it's reading some garbage data when it's trying to find where the CS to switch to is

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 9:35 pm
by Octocontrabass
Techflash wrote:UPDATE: It really seems like it's already being initialized somewhere... somehow.
It isn't. Your OS will fail to receive interrupts on some PCs because the interrupt controllers are not initialized.
Techflash wrote:But now after some tweaking to my IDT code,
It's hard to spot bugs in your code when I can't see the current version of your code.
Techflash wrote:The only thing that I can think of is the IDT is messed up and it's reading some garbage data when it's trying to find where the CS to switch to is
Perhaps. Try using "info idt" in the Bochs debugger.

Re: Issues with interrupts

Posted: Thu Aug 04, 2022 11:55 pm
by Techflash
Octocontrabass wrote:It isn't. Your OS will fail to receive interrupts on some PCs because the interrupt controllers are not initialized.
Hmm... I wouldn't have though that Bochs would init them by default but maybe.
Octocontrabass wrote:It's hard to spot bugs in your code when I can't see the current version of your code.
The latest version of my code has been available at https://github.com/techflashYT/Techflash-OS since the beginning.
Octocontrabass wrote:Perhaps. Try using "info idt" in the Bochs debugger.
Will try in a second.
Log of this is at: https://gist.github.com/techflashYT/3c5 ... 7f08cfffe7
Perhaps I should fill out the entire rest of the IDT with stub entries instead of just zeroes?

Re: Issues with interrupts

Posted: Fri Aug 05, 2022 9:40 am
by nullplan
Techflash wrote:Perhaps I should fill out the entire rest of the IDT with stub entries instead of just zeroes?
That is generally a good idea. Between IOAPIC, local APIC, and MSI, you can generally not know how many interrupts you will have ahead of time these days. Filling the entire IDT can be done as simply as:

Code: Select all

.align 8
.global external_interrupt
external_interrupt:
.set interrupt,32
.rept 256-32
  pushq interrupt-128
  jmpq interrupt_common
.align 8
.set interrupt, interrupt+1
.endr
This defines a new symbol, "external interrupt", that handles interrupt 32. You need to define your own function "interrupt_common". It is entered with an IRET frame and the interrupt number less 128 on the stack. The encoding is chosen such that for all possible values of "interrupt", the encoding of the push instruction is the short encoding. This means that all interrupt handlers are exactly 8 bytes apart from one another (you have 2 bytes for the push and at most 5 for the jump, makes 7 in total, aligned to 8). So now you can define in C:

Code: Select all

extern const char external_interrupt[];
for (int i = 0; i < 256-32; i++)
  set_idt_entry(i + 32, external_interrupt + 8 * i);
Your "interrupt_common" function will then need to save all registers, probably fix up the interrupt number on stack, then call whatever interrupt handler you need to. Then restore registers and do whatever work is required when returning from interrupt.