Page 1 of 1

pit called once

Posted: Wed Sep 10, 2003 6:19 am
by MonkeyMan
Can anyone share some thoughts on how my pit handler is getting called only once?

This is what I have so far:

Code: Select all

extern pitHandler
global pit
pit:
     pusha
     push ds
     push es
     push fs
     push gs

     mov eax,0x10       ; Data segment
     mov ds,eax
     mov es,eax
     mov eax,0
     mov fs,eax
     mov gs,eax

     call pitHandler

     pop gs
     pop fs
     pop es
     pop ds
     popa
     iret

and

Code: Select all

void pitHandler()
{
        kprintf("pit called\t");
        outb(0x20,0x20);
}
I continue to receive normal keyboard interrupts after unmasking irq0. But irq0 only fires once thus prints "pit called" only once... can anyone please shed some light on this??

thanks

Re:pit called once

Posted: Wed Sep 10, 2003 6:44 am
by drizzt
The keyboard is on the IRQ line #1. The IRQ 0 is the system timer. What about your IDT and your unmasking routine?!

Re:pit called once

Posted: Wed Sep 10, 2003 7:01 am
by Pype.Clicker
possible options are:
[*] you reprogrammed the channel 0 of the PIT the wrong way and it is in "single-shot more"
[*] your printing function is overwriting the same video area again and again
[*] interrupts were disabled (or IRQ0 was masked back) just after the first PIT is handled. One possible cause is a "cli: hlt" that occurs too early (in which case keyboard should respond any longer) or you disabled IRQ0 while unmasking some other IRQ. I would say your IDT should be good if those handlers were called correctly. But indeed, what about the unmasking routine ?

Re:pit called once

Posted: Wed Sep 10, 2003 9:19 am
by MonkeyMan
Shouldn't the unmasking and IDT be counted out as my keyboard interrupt works. ..

Here is the unmasking.:

Code: Select all

void unmaskIRQ(int irq)
{
        unsigned short int ocw1 = 0xffff;
        ocw1 &= ~(1 << irq);     // enable propriate bit with shifting to left
                                 // invert to enable the interrupt
                                 // use & to not disturb other bits
        if (irq < 8)
                outb(MASTER + 1, ocw1 & 0xFF);  // AND with 0xFF to clear the high 8
                                                 //  bits because we send to PIC1
        else
                outb(SLAVE + 1, ocw1 >> 8);     // move high 8 bits to low 8 bits
                                                // since we send to PIC2
}
your printing function is overwriting the same video area again and again
No my kprintf function takes care of that.
interrupts were disabled (or IRQ0 was masked back) just after the first PIT is handled.
After I unmask irq0 and irq1 its just a simple:

Code: Select all

while(1) 
  asm("hlt");

thanks for your help

Re:pit called once

Posted: Wed Sep 10, 2003 7:07 pm
by bkilgore
It might just be me (I've been away for a little while, I'm probably rusty), but isn't your unmasking function only unmasking the last irq you pass to it and masking the rest? I'm getting this from the line

Code: Select all

unsigned short int ocw1 = 0xffff;
I think this should be static, so it remembers the last mask, but defaults to 0xffff on the first run, like this:

Code: Select all

static unsigned short int ocw1 = 0xffff;
Otherwise, each time you call the function you're telling it to mask everything except the irq you are passing, as opposed to leaving everything the same and just unmasking that irq.

Re:pit called once

Posted: Thu Sep 11, 2003 1:20 am
by Pype.Clicker
bkilgore wrote: It might just be me (I've been away for a little while, I'm probably rusty), but isn't your unmasking function only unmasking the last irq you pass to it and masking the rest?
True. That was just the mistake i expected him to make ... So as soon as you enable IRQ0, you get the interrupt that was pending from a loooong time, then the timer ISR returns and you'll unmask the keyboard, masking back the timer.

Re:pit called once

Posted: Thu Sep 11, 2003 7:39 am
by drizzt
bkilgore wrote:

Code: Select all

unsigned short int ocw1 = 0xffff;
I think this should be static, so it remembers the last mask, but defaults to 0xffff on the first run, like this:

Code: Select all

static unsigned short int ocw1 = 0xffff;
...or, if you want to be more sure you can first read from the interrupt mask port the value of the current mask. For example:

Code: Select all

void unmaskIRQ(int irq)
{
    unsigned int mask;

    if (irq > 15) return;

    if (irq < 8)
    {
        // Master //
        mask = inportb(0x21);
        mask &= ~(1 << irq);
        outportb(0x21, mask & 0xFF);
    }
    else
    {
        // Slave //
        mask = inportb(0xA1);
        mask &= ~(1 << (irq-8));
        outportb(0xA1, mask & 0xFF);
    }
}

Re:pit called once

Posted: Thu Sep 11, 2003 7:41 am
by drizzt
P.S. and remember to unmask also the IRQ line #2 of the PIC master if you want to unmask an IRQ line on the PIC slave!!!