diff options
Diffstat (limited to 'kernel/interrupts.c')
| -rw-r--r-- | kernel/interrupts.c | 62 |
1 files changed, 24 insertions, 38 deletions
diff --git a/kernel/interrupts.c b/kernel/interrupts.c index b0a473a..5a788c8 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -13,15 +13,11 @@ #include "apic.h" #include "ringbuffer.h" -ringbuffer mouse_in; -ringbuffer kb_in; - -// - /** The size of our interrupts table */ #define INT_MAX 256 // 0-255 -static uint32_t handlers[INT_MAX]; // addresses of interrupt handlers. +/** Addresses of the registered interrupt handlers */ +static uint32_t handlers[INT_MAX]; /** The interrupt descriptor table */ struct int_desc @@ -53,7 +49,8 @@ static void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr) idt[irq].sel=sel; } -void interrupt_handler_register(uint32_t irq, uint32_t func_addr) +/** register an interrupt handler for given irq number */ +void interrupt_register(uint32_t irq, uint32_t func_addr) { if(irq<128||irq>160)kpanic("irq number out of range!"); if(handlers[irq]!=0)kpanic("handler already registered!"); @@ -62,41 +59,38 @@ void interrupt_handler_register(uint32_t irq, uint32_t func_addr) /* * Interrupt dispatcher - * * Remeber that we are inside an interrupt here! - * */ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) { + uint32_t *stack; - // process irq - switch(irq) + if(handlers[irq]!=0) { - case INTERRUPT_PIT_TIMER: - asm_pit_tick(); - break; - - case INTERRUPT_KEYBOARD: - ringbuffer_put(&kb_in,x86_inb(0x60)); - break; + uint32_t (*f)(uint32_t esp)=handlers[irq]; + esp=f(esp); + apic_eoi(); + } + else if(irq!=INTERRUPT_SYSCALL&&irq!=INTERRUPT_IPI&&irq!=INTERRUPT_APIC_TIMER) + { + kpanic("unhandled interrupt %d",irq); + } - case INTERRUPT_MOUSE: - ringbuffer_put(&mouse_in,x86_inb(0x60)); - break; + // process IRQ + switch(irq) + { case INTERRUPT_SYSCALL: stack=esp; task_syscall(stack[11],stack[8],stack[10],stack[9]); //eax,ebx,ecx,edx + esp=scheduler_wake_worker(esp); break; - case INTERRUPT_E1000: - e1000_irq(INTERRUPT_E1000); - break; - - case INTERRUPT_APIC_TIMER: - case INTERRUPT_IPI: + case INTERRUPT_APIC_TIMER: // frequency is configured in smp.c + case INTERRUPT_IPI: // inter process interrupt esp=scheduler_run(esp,0); + apic_eoi(); break; case 255: // default or spurious @@ -107,29 +101,21 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // reschedule to kernel worker on these if(irq==INTERRUPT_SYSCALL||irq==INTERRUPT_KEYBOARD||irq==INTERRUPT_MOUSE) { - esp=scheduler_wake_worker(esp); } - // ack all to LAPIC, except software syscalls - if(irq!=INTERRUPT_SYSCALL) - apic_eoi(); + // Ack all to LAPIC, except software syscalls return esp; + } /** - * init interrupt descriptor table + * init interrupt descriptor table (TODO; do we seriously have to hardcode this?) */ void interrupts_init() { - // TODO???? - klog("Initializing Mouse and Kb input buffers"); - fixme("use a regular pipe-file"); - kb_in=ringbuffer_init(1);// 4096 bytes ringbuffer; - mouse_in=ringbuffer_init(1);// 4096 bytes ringbuffer; klog("Initializing. IDT: 0x%08x, IDTD: 0x%08X",&idt,&idtd); - // // Default interrupt handling for(int i=0; i<INT_MAX; i++) |
