f6b55389ae68d8e43fd35db574f93301cdfb7528
[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 #include <lunaix/process.h>
7 #include <lunaix/sched.h>
8
9 LOG_MODULE("intr")
10
11 static int_subscriber subscribers[256];
12
13 static int_subscriber fallback = (int_subscriber) 0;
14
15 void
16 intr_subscribe(const uint8_t vector, int_subscriber subscriber) {
17     subscribers[vector] = subscriber;
18 }
19
20 void
21 intr_unsubscribe(const uint8_t vector, int_subscriber subscriber) {
22     if (subscribers[vector] == subscriber) {
23         subscribers[vector] = (int_subscriber) 0;
24     }
25 }
26
27 void
28 intr_set_fallback_handler(int_subscriber subscribers) {
29     fallback = subscribers;
30 }
31
32
33 void
34 intr_handler(isr_param* param)
35 {
36     // if (param->vector == LUNAIX_SYS_CALL) {
37     //     kprintf(KDEBUG "%p", param->registers.esp);
38     // }
39     __current->intr_ctx = *param;
40     
41     if (param->vector <= 255) {
42         int_subscriber subscriber = subscribers[param->vector];
43         if (subscriber) {
44             subscriber(param);
45             goto done;
46         }
47     }
48
49     if (fallback) {
50         fallback(param);
51         goto done;
52     }
53     
54     kprint_panic("INT %u: (%x) [%p: %p] Unknown",
55             param->vector,
56             param->err_code,
57             param->cs,
58             param->eip);
59
60 done:
61
62     // if (__current->state != PROC_RUNNING) {
63     //     schedule();
64     // }
65
66     // for all external interrupts except the spurious interrupt
67     //  this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
68     if (param->vector >= EX_INTERRUPT_BEGIN && param->vector != APIC_SPIV_IV) {
69         apic_done_servicing();
70     }
71
72     *param = __current->intr_ctx;
73
74     return;
75 }