aa64: finalise context switch, page fault handler and syscall
[lunaix-os.git] / lunaix-os / arch / aarch64 / exception / handler.c
1 #include <lunaix/process.h>
2 #include <asm/hart.h>
3 #include <asm/aa64_exception.h>
4
5 extern void 
6 handle_mm_abort(struct hart_state* state);
7
8 extern void
9 aa64_syscall(struct hart_state* hstate);
10
11 static inline void
12 update_thread_context(struct hart_state* state)
13 {
14     if (!current_thread) {
15         return;
16     }
17
18     struct hart_state* parent = current_thread->hstate;
19     hart_push_state(parent, state);
20
21     current_thread->hstate = state;
22     current_thread->ustack_top = state->execp.sp_el0;
23
24     if (parent) {
25         state->depth = parent->depth + 1;
26     }
27 }
28
29 static inline void
30 handle_sync_exception(struct hart_state* hstate)
31 {
32     unsigned int ec;
33
34     ec = esr_ec(hstate->execp.syndrome);
35
36     switch (ec)
37     {
38     case EC_I_ABORT:
39     case EC_D_ABORT:
40     case EC_I_ABORT_EL:
41     case EC_D_ABORT_EL:
42         handle_mm_abort(hstate);
43         break;
44     
45     case EC_SVC:
46         aa64_syscall(hstate);
47         break;
48     
49     default:
50         fail("unhandled exception (synced)");
51         break;
52     }
53 }
54
55 static inline void
56 handle_async_exception(struct hart_state* hstate)
57 {
58     int err = 0;
59     
60     err = gic_handle_irq(hstate);
61     if (!err) {
62         return;
63     }
64
65     // TODO do we have other cases of async exception?
66 }
67
68 struct hart_state*
69 handle_exception(struct hart_state* hstate)
70 {
71     update_thread_context(hstate);
72
73     if (hart_vector_stamp(hstate) == EXCEPTION_SYNC) {
74         handle_sync_exception(hstate);
75     } else {
76         handle_async_exception(hstate);
77     }
78
79     return hstate;
80 }