Page 1 of 1
PIT and Keyboard causing crashes?
Posted: Sun Dec 01, 2013 2:45 pm
by PearOs
Edit: Its PIT not PIC. Didn't get my coffee this morning
Hey guys, this is by far one of the most annoying and worst bugs I have ever encountered in my system. So I have a GDT setup, and a IDT, and Interrupts are enabled and working. Everything works. If I set the PIT to run super faster, no issues. My code gets called, nothing crashes, I can switch tasks, the works. But the second I pressed a ton of keyboard keys, Bochs prints out "fetch_raw_descriptor: LDTR.valid=0" and it doesn't always happen. I can press a ton and it never happens and then it does. But whats odd is if I set the PIT to a slower speed and do that it takes a much longer time to actually cause a crash. But here's the annoying part, the keyboard code is super basic. I pretty much wiped it to nothing thinking it was a issue with the stack. I don't think it is.
In my main interrupt function that gets called in my ISR is my keyboard code.
Code: Select all
push 0x60
call IOPort_Read_8
pop eax
That's all of it, IOPort_Read_8 looks like this
Code: Select all
;Input:
; - (int) Address
;Ouput:
; - (int) Data
;Description: Reads data from an ioport.
IOPort_Read_8_Return: db 0,0,0,0
IOPort_Read_8:
call Thread_Lock
pop dword[IOPort_Read_8_Return] ;Save the return address
pop edx ;Address
in al, dx
MOVZX eax, al
push eax
push dword[IOPort_Read_8_Return] ;Restore the return address
call Thread_Unlock
ret ;Return
There is no stack leaks anywhere. Any ideas as to whats going on here?
Thanks, Matt
Re: PIT and Keyboard causing crashes?
Posted: Sun Dec 01, 2013 4:22 pm
by Nable
> Any ideas as to whats going on here?
Some race condition in your code (although there's a very little but non-zero probability of bug in Bochs, about 2 years ago I've found a reproducable bug^W strange behaviour on invalid code that nobody could debug).
> call Thread_Lock
> pop dword[IOPort_Read_8_Return] ;Save the return address
Why are you doing this? You have too little stack space? This is not ARM with its link-register, so you don't have to save return address before calling another routine.
So, just use [esp+4] memory access.
> push eax
So, you are replacing the argument on stack with return data. Why are you using such a strange calling convention?
I don't know how good is your implementation of Thread_Lock but you are definitely doing things in a strange way.
(btw: avoid pop'ing return address, each 'call' should have its 'ret', else processor's call trace optimizations won't work)
Re: PIT and Keyboard causing crashes?
Posted: Sun Dec 01, 2013 4:49 pm
by PearOs
Nable wrote:> Any ideas as to whats going on here?
Some race condition in your code (although there's a very little but non-zero probability of bug in Bochs, about 2 years ago I've found a reproducable bug^W strange behaviour on invalid code that nobody could debug).
> call Thread_Lock
> pop dword[IOPort_Read_8_Return] ;Save the return address
Why are you doing this? You have too little stack space? This is not ARM with its link-register, so you don't have to save return address before calling another routine.
So, just use [esp+4] memory access.
> push eax
So, you are replacing the argument on stack with return data. Why are you using such a strange calling convention?
I don't know how good is your implementation of Thread_Lock but you are definitely doing things in a strange way.
(btw: avoid pop'ing return address, each 'call' should have its 'ret', else processor's call trace optimizations won't work)
Ok so that is the backend code to my system. The rest is in C#. I use pop dword[return address] to get them off the stack so I can
access the parameter. Thread_Lock prevents interrupts from happening so that I can do such a thing. This is so that I can write easy code
without having to think and functions like IOPort_Read_8 don't need to have local variables and such. So that's why. There's no problem doing it that way as my whole Os was once 100% assembly and written that way and worked just fine.
Re: PIT and Keyboard causing crashes?
Posted: Sun Dec 01, 2013 6:10 pm
by Brendan
Hi,
PearOs wrote:If I set the PIT to run super faster, no issues. My code gets called, nothing crashes, I can switch tasks, the works. But the second I pressed a ton of keyboard keys, Bochs prints out "fetch_raw_descriptor: LDTR.valid=0" and it doesn't always happen. I can press a ton and it never happens and then it does. But whats odd is if I set the PIT to a slower speed and do that it takes a much longer time to actually cause a crash. But here's the annoying part, the keyboard code is super basic. I pretty much wiped it to nothing thinking it was a issue with the stack. I don't think it is.
I'd be tempted to assume that your PIT IRQ handler trashes some registers. When not much is happening the PIT interrupts "not much" and trashes a register that wasn't being used anyway; but when PIT interrupts the keyboard's IRQ handler the register is being used and causes the keyboard's IRQ handler to crash in some strange (potentially "random" way).
Cheers,
Brendan
Re: PIT and Keyboard causing crashes?
Posted: Sun Dec 01, 2013 8:20 pm
by PearOs
Brendan wrote:Hi,
PearOs wrote:If I set the PIT to run super faster, no issues. My code gets called, nothing crashes, I can switch tasks, the works. But the second I pressed a ton of keyboard keys, Bochs prints out "fetch_raw_descriptor: LDTR.valid=0" and it doesn't always happen. I can press a ton and it never happens and then it does. But whats odd is if I set the PIT to a slower speed and do that it takes a much longer time to actually cause a crash. But here's the annoying part, the keyboard code is super basic. I pretty much wiped it to nothing thinking it was a issue with the stack. I don't think it is.
I'd be tempted to assume that your PIT IRQ handler trashes some registers. When not much is happening the PIT interrupts "not much" and trashes a register that wasn't being used anyway; but when PIT interrupts the keyboard's IRQ handler the register is being used and causes the keyboard's IRQ handler to crash in some strange (potentially "random" way).
Cheers,
Brendan
Huh. But lets say a Keyboard IRQ raises and calls my ISR code which then goes to handle the keyboard code, a PIT interrupt can't be fired until the ISR finishes right? Here's my current ISR code.
Code: Select all
irq_int: dd 0
irq_common_stub:
pop dword[irq_int]
mov byte[0xB8000], '0'
;Save all the registers
;to the stack
;pushad
push eax
push ebx
push ecx
push edx
push ebp
push edi
push esi
push esp
;Prevent interrupts from being
;started again
call Thread_Ignore
;Try to save the current stack
;to the thread running
;mov eax, esp
;push eax
;call iPear.Multitasking.Core.SaveStack_U32
;Now try to run Masked IRQ's
push dword[irq_int]
call iPear.Hardware.IRQ.Invoke_U32
.skip:
;Now attempt to switch threads
;if we can.
;call iPear.Multitasking.Core.Switch
;pop eax
;cmp eax, 0
;je .end ;Not a valid stack
;Otherwise set our new stack
;mov esp, eax
.end:
;Now send our end of interrupt
mov eax, dword[irq_int]
add eax, 32
push eax
call PIC_EOI
;Now unignore threads
call Thread_UnIgnore
;Ok now we have to restore all the registers.
;popad
pop esp
pop esi
pop edi
pop ebp
pop edx
pop ecx
pop ebx
pop eax
;Restore interrupts.
sti
;Now just return.
iret
The moving 0 to the screen was a test for me to be able to tell that the IRQ handler is still being called. Oddly that runs fine in VMWare so far as I can tell, but in Bochs, the second I press a key the whole thing crashes. Sometimes VMWare would crash if I pressed a lot of keys quickly, but with the current code that isn't happening as far as I can tell. Any idea?
Thanks, Matt
Re: PIT and Keyboard causing crashes?
Posted: Mon Dec 02, 2013 12:42 am
by PearOs
I fixed it! My Thread_Lock and Thread_Unlock code were flawed! Yay! So basically what was happening was one interrupt would run, then while were processing that one, another would run! Major problem.
- Matt
Re: PIT and Keyboard causing crashes?
Posted: Mon Dec 02, 2013 3:33 am
by Combuster
Code: Select all
;Restore interrupts.
sti
;Now just return.
iret
You realize what IRET does to IF?
Re: PIT and Keyboard causing crashes?
Posted: Mon Dec 02, 2013 3:58 am
by Antti
Combuster wrote:You realize what IRET does to IF?
If interrupts are disabled before executing an interrupt handler (e.g. software interrupt triggered) and we want to enable them, executing "sti" before "iret" could actually make sense. I have not tested it but "interrupts are enabled at the end of the next instruction".
Re: PIT and Keyboard causing crashes?
Posted: Mon Dec 02, 2013 5:17 am
by brighteningeyes
when you write iret in the asm code, it enable's interrupt again
you must not write sti before iret
Re: PIT and Keyboard causing crashes?
Posted: Mon Dec 02, 2013 12:13 pm
by jnc100
Antti wrote:If interrupts are disabled before executing an interrupt handler (e.g. software interrupt triggered) and we want to enable them, executing "sti" before "iret" could actually make sense. I have not tested it but "interrupts are enabled at the end of the next instruction".
From the docs, IF is set immediately. The response to IF being set (i.e. enabling interrupts) is what is delayed until after the next instruction. If iret clears IF, I'd imagine there is no time for an interrupt to occur as the docs for CLI do not suggest that clearing IF also incorporates a delay before allowing interrupts. Again though, I haven't tested this.
may be a more reliable way to achieve this effect.
Regards,
John.