Page 1 of 1

Keyboard Interrupt

Posted: Wed Sep 25, 2002 7:40 am
by Whatever5k
I have built my own IDT with all interrupts having the same ISR (common_isr). common_isr does nothing then print a message "Key pressed"
on the screen...
Ok, I first disable interrupts, unmask IRQ1(keyboard) and enable interrupts...
When I call bochs, there is just one "Key pressed" on the screen. And when I press on the keyboard, no more messages appear. I suppose, that the one message comes even not from the keyboard, but from another interrupt (since every IDT descriptor has the same interrupt
handler).
Why do I not get the "Key pressed" messages?

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 7:43 am
by Curufir
Are you clearing the interrupt off the PIC.

Ie.

MOV AL, 0x20
OUT 0x20, AL

Or something similar. Think it won't process another IRQ until that is done.

Curufir

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 9:17 am
by Whatever5k
Ouch!
I forgot that! Ok, but then, there were endless messages printed out. I figured out, that it was the system clock and disabled that. So now I have the system clock disabled and the keyboard enabled, but when I press a key, no message is printed. Actually, no message of "key pressed" is printed out...
Why?

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 9:49 am
by PlayOS
Need to see some code for this one I think. :)

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 9:54 am
by Whatever5k
Ok, this is the common_isr:

Code: Select all

common_isr:
            extern testfunc
   call testfunc
   iret
This is the function testfunc():

Code: Select all

void testfunc(void)
{
   asm("cli");
   printk("key pressed/released\n");
   send_eoi(1);
   asm("sti");
}
And this here enables everything:

Code: Select all

/* first, remap the PICs to avoid conflicts with exceptions */
   remap_pics(0x20, 0x28);
   printk("PICs remapped: IRQs starting at interrupt 0x20\n");

   asm("cli");
   disable_irq(0);
   enable_irq(1);
   printk("Enabled IRQ1\n");
   printk("Enabling interrupts\n");
   asm("sti");
Any ideas?

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:04 am
by PlayOS
I cant really see a problem, sorry.

However I dont know why you disable/enable interrupts inside of your ISR. Try removing them. I am pretty sure that only exceptions (int0-31) can happen here. :)

Also what is the state of your second PIC are those IRQ's masked out?

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:09 am
by Whatever5k
Removing "sti" and "cli" does not help...
I do nothing with the second PIC. So they are all unmasked (enabled)

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:14 am
by PlayOS
Well if one of them goes off then you need to send an End Of Interrupt to PIC2 as well as PIC1.

mov al, 0x20
out 0xa0, al

None of the second lot of IRQs should be going off, but it is worth the try, just disable bit 2 'disable_irq(2)' to disable them and see what happens then.

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:21 am
by Whatever5k
Well, maybe it's helpful to look at the enable/disable_irq() code:

Code: Select all

unsigned short int ocw1 = 0xFFFF;   /* short int = 16 bits */

void remap_pics(int pic1, int pic2)
{
   /* send ICW1 */
   outb(PIC1, ICW1);
   outb(PIC2, ICW1);

   /* send ICW2 */
   outb(PIC1 + 1, pic1);   /* remap
   outb(PIC2 + 2, pic2);      pics */

   /* send ICW3 */
   outb(PIC1 + 1, 4);   /* IRQ2 -> connection to slave */
   outb(PIC2 + 2, 2);

   /* send ICW4 */
   outb(PIC1 + 1, ICW4);
   outb(PIC2 + 1, ICW4);

   /* disable all IRQs */
   outb(PIC1 + 1, 0xFF);
}

/* enable_irq()
 * sends command to PIC to enable an IRQ
 */
void enable_irq(int irq)
{
   ocw1 &= ~(1 << irq);   /* enable propriate bit with shifting to left
               invert the thing to enable the interrupt
               use AND operation to leave the other bits
               as they are
             */
   if (irq < 8)
      outb(PIC1 + 1, ocw1&0xFF);   /* AND with 0xFF to clear the high 8 
                       bits because we send to PIC1
                   */
   else
      outb(PIC2 + 1, ocw1 >> 8);   /* move high 8 bits to low 8 bits
                     since we send to PIC2
                   */
}

/* disable_irq()
 * sends a command to PIC to disable an IRQ
 */
void disable_irq(int irq)
{
   ocw1 |= (1 << irq);   /* shift left to disable the propriate bit
               OR to not change the mask
             */

   if (irq < 8)
      outb(PIC1 + 1, ocw1&0xFF);   /* AND with 0xFF to clear the
                     high 8 bits since we send to PIC1
                   */
   else
      outb(PIC2 + 1, ocw1 >> 8);   /* move high 8 bits to low 8 bits since
                     we send to PIC2
                   */
}

/* send_eoi()
 * sends a EOI to the PICs involved in the IRQ operation
 */
void send_eoi(int irq)
{
   if (irq > 7)
      outb(PIC2, 0x20);
   outb(PIC1, 0x20);
}
What do you think, this should work, shouldn't it?

When I compile it with that code and disable irq 2, there's ONE message printed out, but no more...

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:28 am
by PlayOS
Whatever5k wrote: void remap_pics(int pic1, int pic2)
{
......

???/* send ICW2 */
???outb(PIC1 + 1, pic1);???/* remap
???outb(PIC2 + 2, pic2);??? pics */

???/* send ICW3 */
???outb(PIC1 + 1, 4);???/* IRQ2 -> connection to slave */
???outb(PIC2 + 2, 2);

.......
}
shouldn't outb(PIC2 + 2, 2); be outb(PIC2 + 1, 2);

Thats just a first observation (typo's just hate em'), still looking at the rest. :)

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:34 am
by Whatever5k
Ah right...
And...I got it!
Do you know what was wrong? Actually nothing! But: I need to tell the keyboard that I have succesfully received the code...
I did it like that (copy&paste from s.o.'s code):

Code: Select all

int scan;
   register int i;
   
   printk("key pressed/released\n");
   scan = inb(0x60);
   i = inb(0x61);
   outb(0x61, i|0x80);
   outb(0x61, i);
   send_eoi(1);
That's it, now I get a message for every press&release!
Thanks for your help!

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:36 am
by PlayOS
Your very welcome, now I can go to bed, its like 2:38am in the morning over here in australia. :)

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:38 am
by Whatever5k
Hehe, sorry for have having kept you so long awaken.
But I'll keep that in mind, I won't forget...

Re:Keyboard Interrupt

Posted: Wed Sep 25, 2002 10:41 am
by PlayOS
Thats ok, I'm just glad that I could help you. ;D