Keyboard IRQs Squelching the PIT
Posted: Mon Jan 06, 2014 1:01 pm
Hello!
So, my timer code works perfectly, and my IRQ0 handler gets called regularly and on time.. until I start typing. Then my handler only gets called when an IRQ1 comes through from the keyboard. My keyboard IRQs work just fine, and I know there are no issues with the IDT; I've remapped the PIC properly, and I do reset it after IRQs come through.
So, I initialize all my interrupts and whatnot, then do this in main (some is snipped out, but it's trivial):
I run asm("sti") before this, and my console happily prints 'a's off into the sunset at 20Hz.
Then I start typing; 'a's don't get printed anymore, QEMU begins nomming up 100% CPU, and the number of ticks displayed (how many times IRQ0 has been run) only increments upon a keypress.
My IRQ1 handler code follows, and is called by my generic IRQ handling function; I reset the master (and slave, if necessary) PIC chips properly at the end of this function.
Any thoughts on this? Any and all input is greatly appreciated!
UPDATE: It appears that the timer only stops firing when a key becomes unpressed (so, a keyup event)
So, my timer code works perfectly, and my IRQ0 handler gets called regularly and on time.. until I start typing. Then my handler only gets called when an IRQ1 comes through from the keyboard. My keyboard IRQs work just fine, and I know there are no issues with the IDT; I've remapped the PIC properly, and I do reset it after IRQs come through.
So, I initialize all my interrupts and whatnot, then do this in main (some is snipped out, but it's trivial):
Code: Select all
while(true){
asm volatile ("hlt");
console_putChar('a');
}
Then I start typing; 'a's don't get printed anymore, QEMU begins nomming up 100% CPU, and the number of ticks displayed (how many times IRQ0 has been run) only increments upon a keypress.
My IRQ1 handler code follows, and is called by my generic IRQ handling function; I reset the master (and slave, if necessary) PIC chips properly at the end of this function.
Code: Select all
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_COMM_PORT 0x64
#define KEYBOARD_STAT_PORT 0x64
#define KEYBOARD_READ_READY 0x1
#define KEYBOARD_WRITE_READY 0x2
#define KEYBOARD_COMM_ACK 0xFA
#define KEYBOARD_COMM_NACK 0xFE
static bool irq1(__UNUSED registers_t regs){
char c = keyboard_getc();
if(c)
console_putChar(c);
return true;
}
char keyboard_getc(void){
// snip snip. Basically just calls keyboard_scanByte and messes with its output to get a character instead of a scancode.
}
uint8_t keyboard_scanByte(void){
uint8_t b;
do{
b = inb(KEYBOARD_STAT_PORT);
}while((b & KEYBOARD_READ_READY) == 0);
return inb(KEYBOARD_DATA_PORT);
}
UPDATE: It appears that the timer only stops firing when a key becomes unpressed (so, a keyup event)