Page 2 of 2

PostPosted: Thu Apr 10, 2008 3:33 pm
by Mike
Oh, wow... o_o I did not realized you have updated this post. Sorry about not replying sooner.

Hardware interrupt problem solved. I put "_asm cli;" at the beginning of my handler and "outportb(0x20,0x20); _asm sti;" at the end, and it works now. However, I'm still having an issue with firing the same software interrupt back-to-back.


I am glad that you managed to solve the hardware interrupt problem. Sending the EOI command (Setting but 4 of the PIC command register) is required for all hardware interrupts.

Remember that the PIC uses several internal registers to determine the status of the interrupts. By sending EOI, the PIC will reset the appropriate bit in the In Service Register (ISR). This will tell the PIC to signal the completion of the interrupt request.

Not doing this will result in what you were experiencing. The interrupt was competed, but the bit was never reset. Hence, both the IR line on the PIC and CPU are still active. Hence, it will work the first time, but no more after that.

All of this is inside of the Programmable Interrupt Controller tutorial.

---

With regards to your software interrupt problem, I am going to do some testing with the current code to insure there is no problems with it.

I will post again if I find any problems.

PostPosted: Fri Apr 11, 2008 10:04 pm
by Mike
Please try the following interrupt handler:
Code: Select all
char debugPrint[] = "interrupt!\n";

int i86_irq_divide0 (void) {

   DebugPrintf (debugPrint);

   _asm   iretd
}

The interrupt handler was tested with the following code:
Code: Select all
   i86_install_ir (0, I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32, 0x8, i86_irq_divide0);

   _asm int 0
   geninterrupt (0);
   _asm int 0

Please let me know if the above works or not. It should display the debugging message three times, and halt at the end of the kernel. Note the use of the iretd instruction.

PostPosted: Fri Apr 11, 2008 10:49 pm
by pathos
Thanks for your work. I won't be able to test it until Monday, but I'll let you know if it fixes the problem.

PostPosted: Mon Apr 14, 2008 3:41 pm
by pathos
Mike wrote:Please let me know if the above works or not. It should display the debugging message three times, and halt at the end of the kernel. Note the use of the iretd instruction.


Using iretd causes Bochs to panic. If I tell it to continue, it causes a GPF and an invalid op code.

PostPosted: Mon Apr 14, 2008 6:33 pm
by Mike
pathos wrote:Using iretd causes Bochs to panic. If I tell it to continue, it causes a GPF and an invalid op code.
Is this with the int handler I gave you? The code I used was tested and verified to work with software interrupts.

If not, can you please post your int handler and the bochs log message? It will be almost impossible to resolve this problem without them.

iret/iretd pops the return cs:eip from the stack to return from the interrupt. If the stack was modified or corrupt, it will return to bogus memory, which can lead to gpf's and invalid opcodes. I suspect your stack is getting corrupt.

PostPosted: Mon Apr 14, 2008 9:50 pm
by pathos
Mike wrote:iret/iretd pops the return cs:eip from the stack to return from the interrupt. If the stack was modified or corrupt, it will return to bogus memory, which can lead to gpf's and invalid opcodes. I suspect your stack is getting corrupt.


That was the problem. I took everything out of the handler except an error message, and it works now. Thanks.

PostPosted: Mon Apr 14, 2008 10:21 pm
by Mike
pathos wrote:That was the problem. I took everything out of the handler except an error message, and it works now. Thanks.

Glad you got it working! :) I hope your find the error in your handler. Feel free to let me know if there are any further issues.