Timer re-worked!
[lunaix-os.git] / lunaix-os / kernel / asm / x86 / interrupts.c
1 #include <arch/x86/interrupts.h>
2 #include <hal/apic.h>
3 #include <hal/cpu.h>
4 #include <lunaix/syslog.h>
5 #include <lunaix/tty/tty.h>
6
7 static int_subscriber subscribers[256];
8
9 static int_subscriber fallback = (int_subscriber) 0;
10
11 void
12 intr_subscribe(const uint8_t vector, int_subscriber subscriber) {
13     subscribers[vector] = subscriber;
14 }
15
16 void
17 intr_unsubscribe(const uint8_t vector, int_subscriber subscriber) {
18     if (subscribers[vector] == subscriber) {
19         subscribers[vector] = (int_subscriber) 0;
20     }
21 }
22
23 void
24 intr_set_fallback_handler(int_subscriber subscribers) {
25     fallback = subscribers;
26 }
27
28 void
29 intr_handler(isr_param* param)
30 {
31     if (param->vector <= 255) {
32         int_subscriber subscriber = subscribers[param->vector];
33         if (subscriber) {
34             subscriber(param);
35             goto done;
36         }
37     }
38
39     if (fallback) {
40         fallback(param);
41         goto done;
42     }
43     
44     kprint_panic("INT %u: (%x) [%p: %p] Unknown",
45             param->vector,
46             param->err_code,
47             param->cs,
48             param->eip);
49
50 done:
51     // for all external interrupts except the spurious interrupt
52     //  this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
53     if (param->vector >= EX_INTERRUPT_BEGIN && param->vector != APIC_SPIV_IV) {
54         apic_done_servicing();
55     }
56     return;
57 }