Keyboard output buffer stuck at full

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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Keyboard output buffer stuck at full

Post by JamesM »

I'm writing my keyboard driver. It works great in bochs, but in qemu it dies a death after a while.

After some probing, I found that before it dies the status byte is generall 0x1c. After it dies, it's 0x1d. That's the LSB thats set - which corresponds to 'output buffer full'.

Now that's the problem - it reckons it's output buffer is full, so it doesn't send any more interrupts, so I can't clear the output buffer.

What's going on? am I missing interrupts? Is an IRQ being sent and I'm missing it or something? Not exactly sure how to rectify this...

Code, in case anyone wants some. Note I have stripped this to take out ALL my scancode mangement - i've commented it all out and the error is still happening.

tty/keyboard.cc

Code: Select all

void key_handler(int sig)
{
  while (Kernel::inb(0x64) & 0x01) // While there is data available.
  {
    u8int scancode = Kernel::inb(0x60);
  }
}
InterruptServiceRoutine.cc

Code: Select all

u32int irqHandler(Registers r)
{
  InterruptServiceRoutine *isr = descriptorTables.getIsr(r.int_no);
  s32int retVal = -1;
  
  if (isr)
  {
    bool inKernel = processManager.getProcess()->isInKernel();
    processManager.getProcess()->setRegistersPtr(&r);
    if (isr->run(r, &retVal))
    {
      r.eax = retVal;
    }
  }
  
  // If this process has an iopl of 3, tell the cpu!
  // set IOPL to 3 - 0b 00000000000000000011000000000000
  //              =  0x 0   0   0   0   3   0   0   0
  if(processManager.getProcess()->iopl == 3)
  {
    r.eflags |= 0x3000;     // if kernel or server, set IOPL to 3
  }
  else
  {
    r.eflags &= ~0x3000;    // else set it to 0 (unset it)
  }
  
  if (r.int_no >= 40)
  {
    // Send reset signal to slave.
    outb(0xA0, 0x20);
  }
  // Send reset signal to master. (As well as slave, if necessary).
  outb(0x20, 0x20);
  
  return retVal;
}
Any hints would be super-cool. Cheers guys!

JamesM
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Apparently it's my signal handling code.

Sorry.
Post Reply