pit called once

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.
Post Reply
MonkeyMan

pit called once

Post 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
drizzt

Re:pit called once

Post 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?!
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:pit called once

Post 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 ?
MonkeyMan

Re:pit called once

Post 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
bkilgore

Re:pit called once

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:pit called once

Post 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.
drizzt

Re:pit called once

Post 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);
    }
}
drizzt

Re:pit called once

Post 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!!!
Post Reply