Merge branch 'master' of github.com:Minep/lunaix-os
[lunaix-os.git] / lunaix-os / kernel / asm / x86 / interrupts.c
1 #include <arch/x86/interrupts.h>
2 #include <arch/x86/tss.h>
3 #include <hal/apic.h>
4 #include <hal/cpu.h>
5 #include <lunaix/mm/page.h>
6 #include <lunaix/mm/vmm.h>
7 #include <lunaix/process.h>
8 #include <lunaix/sched.h>
9 #include <lunaix/syslog.h>
10 #include <lunaix/tty/tty.h>
11
12 LOG_MODULE("intr")
13
14 static int_subscriber subscribers[256];
15
16 static int_subscriber fallback = (int_subscriber)0;
17
18 void
19 intr_subscribe(const uint8_t vector, int_subscriber subscriber)
20 {
21     subscribers[vector] = subscriber;
22 }
23
24 void
25 intr_unsubscribe(const uint8_t vector, int_subscriber subscriber)
26 {
27     if (subscribers[vector] == subscriber) {
28         subscribers[vector] = (int_subscriber)0;
29     }
30 }
31
32 void
33 intr_set_fallback_handler(int_subscriber subscribers)
34 {
35     fallback = subscribers;
36 }
37
38 extern x86_page_table* __kernel_ptd;
39
40 void
41 intr_handler(isr_param* param)
42 {
43     __current->intr_ctx = *param;
44
45     isr_param* lparam = &__current->intr_ctx;
46
47     if (lparam->vector <= 255) {
48         int_subscriber subscriber = subscribers[lparam->vector];
49         if (subscriber) {
50             subscriber(param);
51             goto done;
52         }
53     }
54
55     if (fallback) {
56         fallback(lparam);
57         goto done;
58     }
59
60     kprint_panic("INT %u: (%x) [%p: %p] Unknown",
61                  lparam->vector,
62                  lparam->err_code,
63                  lparam->cs,
64                  lparam->eip);
65
66 done:
67     // for all external interrupts except the spurious interrupt
68     //  this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
69     if (lparam->vector >= EX_INTERRUPT_BEGIN &&
70         lparam->vector != APIC_SPIV_IV) {
71         apic_done_servicing();
72     }
73
74     return;
75 }