Page 1 of 1

IRQ1 (keyboard) won't fire!

Posted: Sat Mar 05, 2011 1:36 am
by pranjas
Hitting the walls to no end with this, so finally coming to ask for help.

Here's my code i've used to remap PIC, rest assured my IDT is setup and up.

Code: Select all


#define PIC_MASTER_COMMAND_PORT		0x20
#define PIC_MASTER_DATA_PORT		PIC_MASTER_COMMAND_PORT+1
#define PIC_SLAVE_COMMAND_PORT		0xA0
#define PIC_SLAVE_DATA_PORT		PIC_SLAVE_COMMAND_PORT+1
#define PIC_ICW1_COMMAND		0x11
#define PIC_ICW4_SLAVE			0x01
#define PIC_ICW4_MASTER			0x05

#define PIC_ICW2_MASTER			0x20
#define PIC_ICW2_SLAVE			0x28
#define PIC_ICW3_MASTER			0x04 //SLAVE's PIN NO. 
#define PIC_ICW3_SLAVE			0x02 //Master's PIN NO, connected to slave.

outb(PIC_MASTER_COMMAND_PORT,PIC_ICW1_COMMAND);
  outb(PIC_SLAVE_COMMAND_PORT,PIC_ICW1_COMMAND);
  outb(PIC_MASTER_DATA_PORT,PIC_ICW2_MASTER);
  outb(PIC_SLAVE_DATA_PORT,PIC_ICW2_SLAVE);
  outb(PIC_MASTER_DATA_PORT,PIC_ICW3_MASTER);
  outb(PIC_SLAVE_DATA_PORT,PIC_ICW3_SLAVE);
  
  outb(PIC_MASTER_DATA_PORT,PIC_ICW4_MASTER);
  outb(PIC_SLAVE_DATA_PORT,PIC_ICW4_SLAVE);
  
  //enable all interrupts
  outb(PIC_MASTER_DATA_PORT,0xFD);
  outb(PIC_SLAVE_DATA_PORT,0x00);
PIT does fires with this code when I write 0x00 to PIC_MASTER_DATA_PORT. I can see it appearing again and again for this interrupt hence i disabled timer to concentrate on keyboard.

Here's how i handler interrupts, through a common isr_routine.

Code: Select all

void isr_handler(PushRegisters *regs)
{
  unsigned int intrnum=regs->procpushed.intr_num;
  //printk("Will execute interrupt %d\n",intrnum);
  if( handlers[intrnum].handler!=NULL)
  {
      handlers[intrnum].regs=*regs;
      //Put a spinlock above this line when handling SMP.
      handlers[intrnum].flags=ISR_BUSY;
      //this handler shall be scheduled based on the flags.
      //if(!handlers[intr_num].flags==ISR_BUSY)
      handlers[intrnum].handler(&handlers[intrnum].regs); //call isr.
      //we'll need to find a way to declare that an isr is free to be reloaded 
      //with another ISR handler or that it may be called.
      //currently since interrupts get disabled so ISR gets executed always.
      handlers[intrnum].flags=ISR_FREE;
  }
  else
  {
      handleExceptions(regs);
  }
  if(intrnum >31 && intrnum <40)
  {
    printk("sending master eoi and masking forever.\n");
    if(intrnum==33) inb(0x60);//read from keyboard.
    //outb(PIC_MASTER_DATA_PORT,1<<(intrnum-32));
    outb(PIC_MASTER_COMMAND_PORT,0x20); //send EOI to master.
  }
  else if(intrnum >=40)
  {
    printk("sending both eoi\n");
    outb(PIC_SLAVE_COMMAND_PORT,0x20); //Send EOI to slave.
    outb(PIC_MASTER_COMMAND_PORT,0x20); //Send EOI to master.
  }
}
Kindly help me! i wish to make it working by weekend otherwise it'll take another week for me to return to this :(

I'm using
Bochs x86 Emulator 2.4.5
Build from CVS snapshot, on April 25, 2010

Re: IRQ1 (keyboard) won't fire!

Posted: Sat Mar 05, 2011 6:16 am
by Peterbjornx
Have you enabled interrupts (with STI)?

Re: IRQ1 (keyboard) won't fire!

Posted: Sat Mar 05, 2011 8:58 am
by bewing
If there is more than one byte in the keyboard queue, you will only get a single IRQ1. In your code, you will only read one byte from the keyboard, and you will never get another IRQ1. There are other possible problems -- I am not sure if this will fix your issue. But to test this, after you check for INT33 and do one IN on port 0x60, try doing an IN on port 0x64, looping while bit 0 on that port is set, and reading more bytes from port 0x60. If this is the problem, there are several ways to fix it.

Re: IRQ1 (keyboard) won't fire!

Posted: Sat Mar 05, 2011 1:17 pm
by ~
Maybe it would be good for you to start with the keyboard controller and keyboard basics and retry only after you fully understand what you are doing or need to do.

Here is a partial tutorial on some basic aspects about that (written in assembly but with rather generic explanations):
http://126.sytes.net/tutorials/KBC_SourceDoc/


Here is a floppy image with a stand-alone test "kernel" you can boot (based on the previous tutorial). It just shows the make (when you press) and break (when you release) key codes it reads from the keyboard through the keyboard controller as you know, and using IRQs for that. Based on a timer, all scan code bytes belonging to one same key are printed with the same color and the last byte of the scan code with another color so you can read the results easily (unless you press a lot of keys very rapidly):
http://126.sytes.net/tutorials/KBC_Sour ... _image.img

And the source code:
http://126.sytes.net/tutorials/KBC_Sour ... rc/src.zip
http://126.sytes.net/tutorials/KBC_Sour ... ntest/src/

Re: IRQ1 (keyboard) won't fire!

Posted: Sat Mar 05, 2011 7:40 pm
by pranjas
INT 33 instruction does call upon the handler. What i don't get is the keyboard interrupt should fire at least once even if i don't read from the keyboard port.
Software INT works for all the interrupts including keyboard. So is there something with bochs? do i need to change or enable something in it?

Re: IRQ1 (keyboard) won't fire!

Posted: Sun Mar 06, 2011 12:14 pm
by pranjas
Finally got it working. The problem wasn't the code but the order of initialization.

What i had earlier was, install IDT then ISRs then remap PIC. Apparently this order didn't seemed to worked working with bochs.

So now i did,
Remap PIC, install ISRs (in place for the handlers), Install IDT and then enable interrupts... Voilla... It Works!!

Felt awesome, i wished i had done this earlier so i could work during weekend on my kernel... damn :(

Re: IRQ1 (keyboard) won't fire!

Posted: Mon Mar 07, 2011 3:27 am
by Combuster
Why am I missing "enable interrupts" in the first sequence of events? #-o