I've been trying to get IRQs working following this https://github.com/cfenollosa/os-tutorial (based on James Molloy) and I've encountered some strange errors. I got the IDT set up and remapped PIC to spaces 32-47, and i also have an assembly routine which handles IRQ and ISR requests. Im using a pointer to a struct to represent the register state as the tutorial suggests.
Code: Select all
irq_common_stub:
pusha
mov ax,ds
push eax
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
push esp
cld
call irq_handler
pop ebx
pop ebx
mov ds,bx
mov es,bx
mov fs,bx
mov gs,bx
popa
add esp, 8
iret
; ......
irq0:
push byte 0
push byte 32
jmp irq_common_stub
; etc ...
Code: Select all
extern "C" void irq_handler(registers_t *r){
// send end of interrupt to pics after each interrupt
// or they wont send another one
//kprint("recevied irq\n");
if(r->int_no > 33){
kprint("error: ");
char st[3];
int_to_ascii(r->int_no,st);
kprint(st);
kprint("\n");
return;
}
if(r->int_no >= 40) port_byte_out(0xA0, 0x20); //slave
port_byte_out(0x20,0x20); //master
if(interrupt_handlers[r->int_no] != 0){
isr_t handler = interrupt_handlers[r->int_no];
handler(r);
}
}
Code: Select all
void init_keyboard(){
register_interrupt_handler(IRQ1, keyboard_callback);
}
Code: Select all
void init_timer(uint32_t freq){
//register handler
register_interrupt_handler(IRQ0, timer_callback);
//get the PIT value, hardware clock is 1193180 Hz
uint32_t divisor = 1193180 / freq;
uint8_t low = (uint8_t) (divisor & 0xFF);
uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF);
//send the command
port_byte_out(0x43, 0x36);
port_byte_out(0x40,low);
port_byte_out(0x40,high);
//port_byte_out(0x20,0x20);
}
The tutorial I'm following is aware of the "irq_common_stub" problem in Molloy's code and tries to fix it, but I can't tell if it's successful in doing that. I read https://wiki.osdev.org/James_Molloy's_T ... Known_Bugs to see for myself but I was unsuccesful.