OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:53 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 80 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 10:31 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Techflash wrote:

Looks like your IDT should work well enough to at least catch exceptions, although it definitely was not created by the code on your Github. Check your GDT with "info gdt" next.

Techflash wrote:
Perhaps I should fill out the entire rest of the IDT with stub entries instead of just zeroes?

Eventually, yes, but you don't need it right now.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 11:52 am 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
nullplan wrote:
you have 2 bytes for the push and at most 5 for the jump, makes 7 in total, aligned to 8


This seems like a major hassle, and could possibly change with newer versions of GCC. I vaguely remember there being some way to force (a section?) to align to x bytes no matter what using GNU AS directives (I think it was something along the lines of ".align"?) I would need to look into that more.

In regards to your other statement:
nullpan wrote:
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.

I think I already have such a function like "interrupt_common": ISRCommonStub for ISRs and IRQCommonStub for IRQs (both defined in [IRQ/ISR]ASM.S. However I'm not certain that they work correctly, as I have yet to know when they trigger.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 12:08 pm 
Offline
Member
Member
User avatar

Joined: Fri Jun 11, 2021 6:02 am
Posts: 96
Location: Belgium
nullplan wrote:
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:
.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:
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.


You can save some code with two tricks:

  • Instead of using push + jmp, you can use call and calculate the index from the offset ($rip - external_interrupt) (example). Each call instruction is always exactly 5 bytes.
  • You can avoid the setup loop at runtime by putting the table at a known location and calculating the offset from a constant. Personally, I put it at the start address of the kernel. (example link.ld, example compile time loop)

_________________
My OS is Norost B (website, Github, sourcehut)
My filesystem is NRFS (Github, sourcehut)


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 7:08 pm 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
UPDATE: new IDT with max entries sent to a stub ISR handler. bochs 'info idt' can be found here: https://gist.github.com/techflashYT/65e8189a6581b517f0102d2d0d8af37d

Still crashes though. Surely something is horribly wrong then. Even at the instruction that caused the crash, 'info idt' is the same, and 'sreg' shows the CS as still at 0x08, and 64-bit.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 7:09 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
As I mentioned in my previous post, that suggests a problem with your GDT. Use "info gdt" to check it.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 7:11 pm 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
Octocontrabass wrote:
As I mentioned in my previous post, that suggests a problem with your GDT. Use "info gdt" to check it.

#-o Looks like I read it wrong, my bad! I thought you had said to run "info IDT". Will update with results in a sec.
UPDATE: WOAAAH! That's all sorts of wrong:
Code:
Global Descriptor Table (base=0xffffffffffe07120, limit=39):
GDT[0x0000]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x0008]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, 32-bit
GDT[0x0010]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
GDT[0x0018]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, 32-bit
GDT[0x0020]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
You can list individual entries with 'info gdt [NUM]' or groups with 'info gdt [NUM] [NUM]'

Can't really tell myself, but it looks like it's basically reading a bunch of 0x0s and 0xFs at random. Likely the GDT pointer is messed up? Either that or something went horribly wrong while creating it.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 7:21 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Looks mostly correct to me. The only problem with your GDT is that your code segments are 32-bit instead of 64-bit.

This also means that your code to reload the segment registers is not reloading CS, since the CPU doesn't switch to 32-bit mode!


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 7:41 pm 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
Octocontrabass wrote:
Looks mostly correct to me. The only problem with your GDT is that your code segments are 32-bit instead of 64-bit.

This also means that your code to reload the segment registers is not reloading CS, since the CPU doesn't switch to 32-bit mode!

Huh. I can't seem to figure out why it's 32-bit. No matter what I change it always breaks more. Also all of the "base" parts are 64-bit.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 7:52 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Techflash wrote:
I can't seem to figure out why it's 32-bit.

You've set the granularity byte to 0xCF. A 64-bit code segment would use the value 0xAF here.

You should also take a closer look at this instruction since it isn't loading CS.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 9:21 pm 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
Octocontrabass wrote:
Techflash wrote:
I can't seem to figure out why it's 32-bit.

You've set the granularity byte to 0xCF. A 64-bit code segment would use the value 0xAF here.

You should also take a closer look at this instruction since it isn't loading CS.


After simply fixing the granularity byte, it does some goofy stuff.:
Out of nowhere after the IDT init it randomly jumps to 0x000..023? (an illegal instruction)
From there it jumps back to where it was
After letting it go, it barfs: "fetch_raw_descriptor: GDT: index (37) 6 > limit (27)" into the log a bunch then triple faults. Update to this: After tinkering with interrupt handlers it gives "access_read_linear(): canonical failure" every other interrupt handler..... weird.
I also noticed that it somehow managed to print "I4" onto the screen? (found out it's calling my ISRHandler function, and it's just because I have a very borked printf implementation)

Also what do you mean that the instruction isn't loading CS?


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 10:20 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Techflash wrote:
Out of nowhere after the IDT init it randomly jumps to 0x000..023? (an illegal instruction)

You're receiving an IRQ, and your IDT says that's where the handler is. No idea which IRQ though, you still haven't initialized the interrupt controllers.

Techflash wrote:
Also what do you mean that the instruction isn't loading CS?

It's not a far JMP, so CS doesn't change - it still contains the old descriptor from the bootloader's GDT. It's easier to see that it's not a far JMP after translating it to Intel syntax. There's no way to encode a far JMP with a 64-bit destination in long mode, so you'll have to use something else (far RET is the usual choice).


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 10:46 pm 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
Octocontrabass wrote:
Techflash wrote:
Out of nowhere after the IDT init it randomly jumps to 0x000..023? (an illegal instruction)

You're receiving an IRQ, and your IDT says that's where the handler is. No idea which IRQ though, you still haven't initialized the interrupt controllers.

Techflash wrote:
Also what do you mean that the instruction isn't loading CS?

It's not a far JMP, so CS doesn't change - it still contains the old descriptor from the bootloader's GDT. It's easier to see that it's not a far JMP after translating it to Intel syntax. There's no way to encode a far JMP with a 64-bit destination in long mode, so you'll have to use something else (far RET is the usual choice).


Just got code working for the PIC. Live on GitHub now. Still crashes with the same junk though.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 11:08 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
That's because you're still filling your IDT with something that isn't the addresses of your handlers.


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 11:33 pm 
Offline
Member
Member

Joined: Sun May 08, 2022 2:10 am
Posts: 70
Octocontrabass wrote:

Crap. I hate it when old parts of the project that were build off of a previous design come back and bite me in the @$$. Hang on let me go fix that.

UPDATE: NEW JUNK!!!
Bochs log (shortened a lot, "..." means the above repeats a lot)

Code:
07416545692e[CPU0  ] iret64: return CS selector null
07416545750e[CPU0  ] RET_Op64: canonical RIP violation
07416545772e[CPU0  ] access_read_linear(): canonical failure
...
*the following repeat A LOT*
07421046755p[APIC0 ] >>PANIC<< APIC read at address 0x0000fee000b0 spans 32-bit boundary !
...
07421046763p[APIC0 ] >>PANIC<< APIC write with len=8 (should be 4)
...
07421046787p[APIC0 ] >>PANIC<< APIC read at address 0x0000fee00030 spans 32-bit boundary !
*end of huge repeat*
07421292285e[HPET  ] read: timer id out of range
07421292285e[HPET  ] write: timer id out of range
...


Top
 Profile  
 
 Post subject: Re: Issues with interrupts
PostPosted: Fri Aug 05, 2022 11:47 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
Far jump in AT&T syntax uses a different mnemonic:
Code:
ljmp $<seg>, <label>
So for example:
Code:
ljmp $8, 1f
1:


Indirect far jump uses the same mnemonic, but has a memory reference as operand, and requires a * to be placed in front of that operand (like indirect near jump).

_________________
Carpe diem!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 80 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], DotBot [Bot], Google [Bot], SemrushBot [Bot] and 54 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group