Page 2 of 2
Re: Newbie: Problem with fork() in Tutorial ?
Posted: Mon Jul 13, 2009 1:09 pm
by JamesM
frank wrote:Creature wrote:When I read about your problem, I immediately checked out your ISR.c function and I was right (had the same issue before): you're acknowledging the IRQ AFTER calling the IRQ handler, when multitasking, the processes would get switched before the IRQ is ever acknowledged, which would never happen.
Make sure the IRQ is acknowledged BEFORE you go into the ISR handler.
I would say that's not the correct way to do it. If you acknowledge the IRQ before the IRQ handler can run to deal with the device then you may end up with another interrupt. Take for example the hard drive. When the hard drive needs something it raises its interrupt line. The only way to disable that interrupt line is to read from the status register. Therefore if you were to acknowledge the IRQ before reading from the status register then the PIC would see the interrupt line as still raised and it will refire the IRQ.
Level-triggered IRQs should have the EOI run after the handler. Edge-triggered IRQs (like the PIT) should have their EOI sent before the handler.
Horses for courses.
Re: Newbie: Problem with fork() in Tutorial ?
Posted: Mon Jul 13, 2009 3:39 pm
by bpaterni
hmm, going on what has been discussed so far I've add an IRQ_ET macro in interrupt.S to call the irq_handler_ET for just the PIT. This handler sends EOI before the actual handler is called, but the thing is, I'm still not getting any output for process 1. The latest changes have been
pushed, and I have verified that the timer callback is getting called via interrupt now, so that would not be the problem.
Thanks for all the help
Re: Newbie: Problem with fork() in Tutorial ?
Posted: Mon Jul 13, 2009 7:46 pm
by Brendan
Hi,
JamesM wrote:frank wrote:I would say that's not the correct way to do it. If you acknowledge the IRQ before the IRQ handler can run to deal with the device then you may end up with another interrupt. Take for example the hard drive. When the hard drive needs something it raises its interrupt line. The only way to disable that interrupt line is to read from the status register. Therefore if you were to acknowledge the IRQ before reading from the status register then the PIC would see the interrupt line as still raised and it will refire the IRQ.
Level-triggered IRQs should have the EOI run after the handler. Edge-triggered IRQs (like the PIT) should have their EOI sent before the handler.
No.
There's an "interrupt in service" flag for each IRQ inside the PIC. This flag is a re-entrancy lock. When the PIC sends the interrupt to the CPU the PIC acquires the re-entrancy lock (sets the corresponding "interrupt in service" flag), and when the PIC receives the EOI it releases this re-entrancy lock (clears the corresponding "interrupt in service" flag).
If the ISR does anything after sending the EOI then it needs it's own additional re-entrancy protection. For single-CPU this could mean leaving all IRQs disabled; but this will not work multi-CPU. For multi-CPU you'd need to use a proper re-entrancy lock anyway (and there's no reason to disable IRQs at all).
For example:
Code: Select all
; Note: This runs with interrupts enabled
someIRQ:
push eax
; Do some stuff
call some_stuff
; Acquire the additional lock
call acquire_additional_lock
; Release the PIC's lock
mov al,0x20
out 0x20,al
; Do more stuff
call more_stuff
; Release the additional lock
call release_additional_lock
;Return
pop eax
iret
Cheers,
Brendan