fix dangling pointer issues in ext2dr
[lunaix-os.git] / lunaix-os / arch / x86 / exceptions / interrupts.c
1 #include <asm/hart.h>
2 #include "asm/x86.h"
3
4 #include <lunaix/mm/vmm.h>
5 #include <lunaix/process.h>
6 #include <lunaix/sched.h>
7 #include <lunaix/syslog.h>
8 #include <lunaix/failsafe.h>
9
10 #include <hal/irq.h>
11
12 LOG_MODULE("INTR")
13
14 extern void
15 intr_routine_page_fault(const struct hart_state* state);
16
17 extern void
18 syscall_hndlr(const struct hart_state* hstate);
19
20 extern void
21 apic_ack_interrupt(irq_t irq);
22
23 static void noret
24 __set_panic(const char* msg, const struct hart_state* state)
25 {
26     ERROR("panic: %s", msg);
27     failsafe_diagnostic();
28 }
29
30 static inline void
31 update_thread_context(struct hart_state* state)
32 {
33     if (!current_thread) {
34         return;
35     }
36
37     struct hart_state* parent = current_thread->hstate;
38     hart_push_state(parent, state);
39     current_thread->hstate = state;
40
41     if (parent) {
42         state->depth = parent->depth + 1;
43     }
44 }
45
46
47 static bool
48 __handle_internal_vectors(const struct hart_state* state)
49 {
50     switch (hart_vector_stamp(state))
51     {
52     case FAULT_DIVISION_ERROR:
53         __set_panic("div zero", state);
54         break;
55
56     case FAULT_GENERAL_PROTECTION:
57         __set_panic("general protection", state);
58         break;
59
60     case FAULT_PAGE_FAULT:
61         intr_routine_page_fault(state);
62         break;
63
64     case FAULT_INVALID_OPCODE:
65         __set_panic("invalid opcode", state);;
66         break;
67
68     case LUNAIX_SCHED:
69         apic_ack_interrupt(NULL);
70         schedule();
71         break;
72
73     case APIC_SPIV_IV:
74         break;
75
76     case APIC_ERROR_IV:
77         __set_panic("apic error", state);;
78         break;
79
80     case LUNAIX_SYS_CALL:
81         syscall_hndlr(state);
82         break;
83     
84     default:
85         return false;
86     }
87
88     return true;
89 }
90
91 static bool
92 __handle_external_irq(const struct hart_state* state)
93 {
94     irq_t irq;
95     int ex_iv;
96
97     ex_iv = hart_vector_stamp(state);
98     irq   = irq_find(irq_get_default_domain(), ex_iv);
99
100     if (unlikely(!irq)) {
101         return false;
102     }
103
104     irq_serve(irq, state);
105     apic_ack_interrupt(irq);
106     return true;
107 }
108
109 struct hart_state*
110 intr_handler(struct hart_state* state)
111 {
112     update_thread_context(state);
113
114     volatile struct exec_param* execp = state->execp;
115     
116     if (__handle_internal_vectors(state)) {
117         return state;
118     }
119
120     if (__handle_external_irq(state)) {
121         return state;
122     }
123
124     __set_panic("unknown interrupt", state);
125 }