Issues with interrupts

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.
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote:That won't work for exceptions. You need to know which IDT entry the CPU used in order to tell which exception occurred.

It might work for IRQs, but it'll be a lot slower than looking up the interrupt number in your registers struct.
Alright then. That just sounds like a major size issue though.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

Techflash wrote:That just sounds like a major size issue though.
Instead of using 256 unique symbols for each of the stubs, you can make them all the same size and initialize your IDT with a loop. That should come out smaller overall. Borrowing some excellent ideas from earlier in this thread, I came up with this:

Code: Select all

.macro ISR_NOERR num
.align 8
	push $\num-128
	jmp ISRCommonStubNoErr
.align 8
.endm

.macro ISR_ERR num
.align 8
	push $\num-128
	jmp ISRCommonStubErr
.align 8
.endm

.global ISRStubArray

ISRStubArray:

ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR   8
ISR_NOERR 9
ISR_ERR   10
ISR_ERR   11
ISR_ERR   12
ISR_ERR   13
ISR_ERR   14
ISR_NOERR 15
ISR_NOERR 16
ISR_ERR   17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_ERR   21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_ERR   29
ISR_ERR   30
ISR_NOERR 31

.set i,32
.rept 256-32
ISR_NOERR i
.set i,i+1
.endr

ISRCommonStubNoErr:
    pushq (%rsp) # copy interrupt number to the correct location
ISRCommonStubErr:
    push %r15
    push %r14
    (etc)
The usual "I haven't actually tested this so no guarantees it's correct" applies. This code is subtracting 128 from the interrupt number before pushing it onto the stack - you'll have to take that into account when you use the interrupt number in your struct.

Also, while I was writing this post, I spotted a typo in your macros: you need a $ prefix on the three push instructions to use an immediate operand instead of a memory operand.
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote: Instead of using 256 unique symbols for each of the stubs, you can make them all the same size and initialize your IDT with a loop. That should come out smaller overall. Borrowing some excellent ideas from earlier in this thread, I came up with this:

Code: Select all

...
The usual "I haven't actually tested this so no guarantees it's correct" applies. This code is subtracting 128 from the interrupt number before pushing it onto the stack - you'll have to take that into account when you use the interrupt number in your struct.

Also, while I was writing this post, I spotted a typo in your macros: you need a $ prefix on the three push instructions to use an immediate operand instead of a memory operand.
Few things to note:
1. Why does the code subtract 128 from the interrupt number? Is it needed for the stack alignment?
2. I fixed that typo already in the current version (not yet committed) it still seems broken [Although there's no more read memory errors, just the triple fault remains].
3. How would the "ISRStubsArray" not be ended immediately by the first macro? Don't labels in ASM typically end once there is another label definition?
4. How would the array be accessed in the C code for the loop that sets the IDT values?
Last edited by Techflash on Tue Aug 09, 2022 8:24 pm, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

Techflash wrote:1. Why does the code subtract 128 from the interrupt number? Is it needed for the stack alignment?
It's needed to keep all of the stubs under 8 bytes. The PUSH instruction is two bytes long when the immediate value is between -128 and 127, but five bytes long for immediate values outside that range.
Techflash wrote:2. I fixed that typo already in the current version (not yet committed) it still seems broken [Although there's no more read memory errors, just the triple fault remains].
I haven't gone out of my way to comb through the code looking for mistakes. I'd need more details about the exception to track it down. (This is why exception handlers are important!)
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote:It's needed to keep all of the stubs under 8 bytes. The PUSH instruction is two bytes long when the immediate value is between -128 and 127, but five bytes long for immediate values outside that range.
Ah, ok. I'll just need to add 128 to the value in the handler.
Octocontrabass wrote:I haven't gone out of my way to comb through the code looking for mistakes. I'd need more details about the exception to track it down. (This is why exception handlers are important!)
The triple fault wasn't with that code yet. I was just mentioning that fixing that typo alone fixed the errors, but not the triple fault.

Also, what about the other 2 questions:
How would the "ISRStubsArray" not be ended immediately by the first macro? Don't labels in ASM typically end once there is another label definition?
And: How would the array be accessed in the C code for the loop that sets the IDT values?
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

Techflash wrote:3. How would the "ISRStubsArray" not be ended immediately by the first macro? Don't labels in ASM typically end once there is another label definition?
There isn't another label definition. Even if there were, it wouldn't matter: the label only needs to provide a symbolic name for the address where it appears, I'm not using it for anything that depends on size or scope. (But now that you mention it, I think I forgot an ".align 8" directive before that label.)
Techflash wrote:4. How would the array be accessed in the C code for the loop that sets the IDT values?
Something like this:

Code: Select all

extern const uint64_t ISRStubArray[256];

(...)

    for( int i = 0; i < 256; i++ )
    {
        IDTSetGate(i, &ISRStubArray[i], 0x08, 0x8E);
    }
Feel free to define it as some other type if you want to make the pointer arithmetic more explicit.
Techflash wrote:The triple fault wasn't with that code yet. I was just mentioning that fixing that typo alone fixed the errors, but not the triple fault.
There are still errors if you're getting a triple fault, they just don't appear with your current log settings.
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote:There isn't another label definition. Even if there were, it wouldn't matter: the label only needs to provide a symbolic name for the address where it appears, I'm not using it for anything that depends on size or scope. (But now that you mention it, I think I forgot an ".align 8" directive before that label.)
Ah ok then. Also I will add that .align 8
Octocontrabass wrote:
Techflash wrote:4. How would the array be accessed in the C code for the loop that sets the IDT values?
Something like this:

Code: Select all

extern const uint64_t ISRStubArray[256];
...
        IDTSetGate(i, &ISRStubArray[i], 0x08, 0x8E);
    }
Ah. Thanks! I wasn't sure what type it should be and what I should put in the loop.
Octocontrabass wrote:There are still errors if you're getting a triple fault, they just don't appear with your current log settings.
Alright. I'll modify my Bochs log settings to show more info and I'll post the results.
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Well, it doesn't quite work. The exact code I'm using at the moment is live on GitHub if you want to check it out. But according to bochs:

Code: Select all

fetch_raw_descriptor: GDT: index (38d7) 71a > limit (27)
fetch_raw_descriptor: GDT: index (ff77) 1fee > limit (27)
fetch_raw_descriptor: GDT: index (fec7) 1fd8 > limit (27)
fetch_raw_descriptor: GDT: index (fe17) 1fc2 > limit (27)
fetch_raw_descriptor: GDT: index (fd67) 1fac > limit (27)
fetch_raw_descriptor: GDT: index (fcb7) 1f96 > limit (27)
fetch_raw_descriptor: GDT: index (fc07) 1f80 > limit (27)
fetch_raw_descriptor: GDT: index (fb57) 1f6a > limit (27)
fetch_raw_descriptor: GDT: index (faa7) 1f54 > limit (27)
fetch_raw_descriptor: GDT: index (f9f7) 1f3e > limit (27)
fetch_raw_descriptor: GDT: index (f947) 1f28 > limit (27)
fetch_raw_descriptor: GDT: index (f897) 1f12 > limit (27)
fetch_raw_descriptor: GDT: index (f7e7) 1efc > limit (27)
fetch_raw_descriptor: GDT: index (f737) 1ee6 > limit (27)
fetch_raw_descriptor: GDT: index (f687) 1ed0 > limit (27)
fetch_raw_descriptor: GDT: index (f5d7) 1eba > limit (27)
fetch_raw_descriptor: GDT: index (f527) 1ea4 > limit (27)
fetch_raw_descriptor: GDT: index (f477) 1e8e > limit (27)
fetch_raw_descriptor: GDT: index (f3c7) 1e78 > limit (27)
fetch_raw_descriptor: GDT: index (f317) 1e62 > limit (27)
fetch_raw_descriptor: GDT: index (f267) 1e4c > limit (27)
fetch_raw_descriptor: GDT: index (f1b7) 1e36 > limit (27)
fetch_raw_descriptor: GDT: index (f107) 1e20 > limit (27)
*triple fault*
So I think either me or my PC must be getting memory loss, because I could have sworn we already fixed the GDT somewhere in this thread. I really cannot say what any of these messages mean.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

You only have 31 out of the 256 ISR stubs in the array. You didn't copy the code to generate the ones above 31, and you have one missing here.

I don't know if that's the problem, though. It's hard to say what's going on with no information about what code caused those exceptions.
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote:You only have 31 out of the 256 ISR stubs in the array. You didn't copy the code to generate the ones above 31, and you have one missing here.

I don't know if that's the problem, though. It's hard to say what's going on with no information about what code caused those exceptions.
Fixed, those issues, same errors, here's the log you asked for with more info: Pastebin of everything from the moment the bootloader ends to the end of the log with everything but "debug" level events being logged
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

That log does not include a register dump from the first exception, so I can't tell what's going on. Does Bochs not have anything equivalent to QEMU's "-d int"?
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote:That log does not include a register dump from the first exception, so I can't tell what's going on. Does Bochs not have anything equivalent to QEMU's "-d int"?
I can't seem to find any way to make it halt on the first exception. Althought a quick google search shows that the "14" in the exception line means that somehow there's a page fault going on.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

Unfortunately, that only tells you that there's eventually a page fault.

You might be able to set a breakpoint on ISRHandler() to see what's up.
Techflash
Member
Member
Posts: 70
Joined: Sun May 08, 2022 2:10 am

Re: Issues with interrupts

Post by Techflash »

Octocontrabass wrote:Unfortunately, that only tells you that there's eventually a page fault.

You might be able to set a breakpoint on ISRHandler() to see what's up.
It just breaks once for every "fetch_raw_descriptor" error. It gives no info on when it triple faults.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Issues with interrupts

Post by Octocontrabass »

Okay... and what are the contents of the stack when you hit that breakpoint for the first time?
Post Reply