Overhaul lock_test.R
[akaros.git] / kern / include / trap.h
1 /* See COPYRIGHT for copyright information. */
2
3 #pragma once
4
5 #define ROS_KERN_TRAP_H
6
7 #include <ros/trapframe.h>
8 #include <arch/arch.h>
9 #include <arch/mmu.h>
10 #include <sys/queue.h>
11 #include <arch/trap.h>
12
13 // func ptr for interrupt service routines
14 typedef void (*isr_t)(struct hw_trapframe *hw_tf, void *data);
15
16 void idt_init(void);
17 struct irq_handler *register_irq(int irq, isr_t handler, void *irq_arg,
18                                  uint32_t tbdf);
19 int deregister_irq(int vector, uint32_t tbdf);
20 int route_irqs(int cpu_vec, int coreid);
21 int get_irq_vector(void);
22 void put_irq_vector(int vec);
23
24 void print_trapframe(struct hw_trapframe *hw_tf);
25 void print_swtrapframe(struct sw_trapframe *sw_tf);
26 void print_vmtrapframe(struct vm_trapframe *vm_tf);
27 void print_user_ctx(struct user_context *ctx);
28 /* Generic per-core timer interrupt handler.  set_percore_timer() will fire the
29  * timer_interrupt(). */
30 void set_core_timer(uint32_t usec, bool periodic);
31 void timer_interrupt(struct hw_trapframe *hw_tf, void *data);
32
33 extern inline void save_fp_state(struct ancillary_state *silly);
34 extern inline void restore_fp_state(struct ancillary_state *silly);
35 extern inline void init_fp_state(void);
36 /* Set stacktop for the current core to be the stack the kernel will start on
37  * when trapping/interrupting from userspace */
38 void set_stack_top(uintptr_t stacktop);
39 uintptr_t get_stack_top(void);
40
41 void send_nmi(uint32_t os_coreid);
42 int reflect_current_context(void);
43 void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
44                             unsigned long aux);
45 void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
46                               unsigned int err, unsigned long aux);
47
48 uintptr_t get_user_ctx_pc(struct user_context *ctx);
49 uintptr_t get_user_ctx_fp(struct user_context *ctx);
50 uintptr_t get_user_ctx_sp(struct user_context *ctx);
51
52 /* Partial contexts are those where the full context is split between the parts
53  * in the struct and the parts still loaded in hardware.
54  *
55  * Finalizing a context ensures that the full context is saved in the struct and
56  * nothing remains in hardware.  Finalize does two things: makes sure the
57  * context can be run again on another core and makes sure the core can run
58  * another context.
59  *
60  * arch_finalize_ctx() must be idempotent and have no effect on a full context.
61  * It is up to the architecture to keep track of whether or not a context is
62  * full or partial and handle finalize calls on a context that might not be
63  * partial.  They can do so in the ctx itself, in their own arch-dependent
64  * manner.
65  *
66  * The kernel's guarantee to the arches is that:
67  * - finalize will be called after proc_pop_ctx (i.e. after it runs) at least
68  * once, before that context is used again on another core or before another
69  * context is used on this core.
70  * - the arches can store the partial status and anything else it wants in the
71  * *ctx without fear of it being tampered with.
72  * - user-provided contexts will be passed to proc_secure_ctx, and those
73  * contexts are full/finalized already.  Anything else is a user bug.  The
74  * arches enforce this.
75  * - an arch will never be asked to pop a partial context that was not already
76  * loaded onto the current core.
77  * - contexts will be finalized before handing them back to the user. */
78 extern inline void arch_finalize_ctx(struct user_context *ctx);
79 extern inline bool arch_ctx_is_partial(struct user_context *ctx);
80 void copy_current_ctx_to(struct user_context *to_ctx);
81
82 /* Kernel messages.  This is an in-order 'active message' style messaging
83  * subsystem, where you can instruct other cores (including your own) to execute
84  * a function (with arguments), either immediately or whenever the kernel is
85  * able to abandon its context/stack (permanent swap).
86  *
87  * These are different (for now) than the smp_calls in smp.h, since
88  * they will be executed immediately (for urgent messages), and in the order in
89  * which they are sent.  smp_calls are currently not run in order, and they must
90  * return (possibly passing the work to a workqueue, which is really just a
91  * routine message, so they really need to just return).
92  *
93  * Eventually, smp_call will be replaced by these.
94  *
95  * Also, a big difference is that smp_calls can use the same message (registered
96  * in the interrupt_handlers[] for x86) for every recipient, but the kernel
97  * messages require a unique message.  Also for now, but it might be like that
98  * for a while on x86 (til we have a broadcast). */
99
100 #define KMSG_IMMEDIATE                  1
101 #define KMSG_ROUTINE                    2
102
103 typedef void (*amr_t)(uint32_t srcid, long a0, long a1, long a2);
104
105 struct kernel_message
106 {
107         STAILQ_ENTRY(kernel_message) link;
108         uint32_t srcid;
109         uint32_t dstid;
110         amr_t pc;
111         long arg0;
112         long arg1;
113         long arg2;
114 }__attribute__((aligned(8)));
115
116 STAILQ_HEAD(kernel_msg_list, kernel_message);
117 typedef struct kernel_message kernel_message_t;
118
119 void kernel_msg_init(void);
120 uint32_t send_kernel_message(uint32_t dst, amr_t pc, long arg0, long arg1,
121                              long arg2, int type);
122 void handle_kmsg_ipi(struct hw_trapframe *hw_tf, void *data);
123 bool has_routine_kmsg(void);
124 void process_routine_kmsg(void);
125 void print_kmsgs(uint32_t coreid);
126
127 /* Runs a function with up to two arguments as a routine kernel message.  Kernel
128  * messages can have three arguments, but the deferred function pointer counts
129  * as one.  Note the arguments to the function will be treated as longs. */
130 #define run_as_rkm(f, ...) do {                                                \
131         static_assert(MACRO_NR_ARGS(__VA_ARGS__) <= 2);                        \
132         PASTE(__run_as_rkm_, MACRO_NR_ARGS(__VA_ARGS__))(f, ##__VA_ARGS__);    \
133 } while (0)
134
135 #define __run_as_rkm_0(f) \
136         send_kernel_message(core_id(), __kmsg_trampoline, (long)f, 0xcafebabe, \
137                             0xcafebabe, KMSG_ROUTINE)
138 #define __run_as_rkm_1(f, a1) \
139         send_kernel_message(core_id(), __kmsg_trampoline, (long)f, (long)a1, \
140                             0xcafebabe, KMSG_ROUTINE)
141 #define __run_as_rkm_2(f, a1, a2) \
142         send_kernel_message(core_id(), __kmsg_trampoline, (long)f, (long)a1, \
143                             (long)a2, KMSG_ROUTINE)
144 void __kmsg_trampoline(uint32_t srcid, long a0, long a1, long a2);
145
146 /* Kernel context depths.  IRQ depth is how many nested IRQ stacks/contexts we
147  * are working on.  Kernel trap depth is how many nested kernel traps (not
148  * user-space traps) we have.
149  *
150  * Some examples:
151  *      (original context in parens, +(x, y) is the change to IRQ and ktrap
152  *      depth):
153  * - syscall (user): +(0, 0)
154  * - trap (user): +(0, 0)
155  * - irq (user): +(1, 0)
156  * - irq (kernel, handling syscall): +(1, 0)
157  * - trap (kernel, regardless of context): +(0, 1)
158  * - NMI (kernel): it's actually a kernel trap, even though it is
159  *   sent by IPI.  +(0, 1)
160  * - NMI (user): just a trap.  +(0, 0)
161  *
162  * So if the user traps in for a syscall (0, 0), then the kernel takes an IRQ
163  * (1, 0), and then another IRQ (2, 0), and then the kernel page faults (a
164  * trap), we're at (2, 1).
165  *
166  * Or if we're in userspace, then an IRQ arrives, we're in the kernel at (1, 0).
167  * Note that regardless of whether or not we are in userspace or the kernel when
168  * an irq arrives, we still are only at level 1 irq depth.  We don't care if we
169  * have one or 0 kernel contexts under us.  (The reason for this is that I care
170  * if it is *possible* for us to interrupt the kernel, not whether or not it
171  * actually happened). */
172
173 /* uint32_t __ctx_depth is laid out like so:
174  *
175  * +------8------+------8------+------8------+------8------+
176  * |    Flags    |    Unused   | Kernel Trap |  IRQ Depth  |
177  * |             |             |    Depth    |             |
178  * +-------------+-------------+-------------+-------------+
179  *
180  */
181 #define __CTX_IRQ_D_SHIFT               0
182 #define __CTX_KTRAP_D_SHIFT             8
183 #define __CTX_FLAG_SHIFT                24
184 #define __CTX_IRQ_D_MASK                ((1 << 8) - 1)
185 #define __CTX_KTRAP_D_MASK              ((1 << 8) - 1)
186 #define __CTX_NESTED_CTX_MASK           ((1 << 16) - 1)
187 #define __CTX_CANNOT_BLOCK              (1 << (__CTX_FLAG_SHIFT + 0))
188
189 /* Basic functions to get or change depths */
190
191 #define irq_depth(pcpui)                                                       \
192         (((pcpui)->__ctx_depth >> __CTX_IRQ_D_SHIFT) & __CTX_IRQ_D_MASK)
193
194 #define ktrap_depth(pcpui)                                                     \
195         (((pcpui)->__ctx_depth >> __CTX_KTRAP_D_SHIFT) & __CTX_KTRAP_D_MASK)
196
197 #define inc_irq_depth(pcpui)                                                   \
198         ((pcpui)->__ctx_depth += 1 << __CTX_IRQ_D_SHIFT)
199
200 #define dec_irq_depth(pcpui)                                                   \
201         ((pcpui)->__ctx_depth -= 1 << __CTX_IRQ_D_SHIFT)
202
203 #define inc_ktrap_depth(pcpui)                                                 \
204         ((pcpui)->__ctx_depth += 1 << __CTX_KTRAP_D_SHIFT)
205
206 #define dec_ktrap_depth(pcpui)                                                 \
207         ((pcpui)->__ctx_depth -= 1 << __CTX_KTRAP_D_SHIFT)
208
209 #define set_cannot_block(pcpui)                                                \
210         ((pcpui)->__ctx_depth |= __CTX_CANNOT_BLOCK)
211
212 #define clear_cannot_block(pcpui)                                              \
213         ((pcpui)->__ctx_depth &= ~__CTX_CANNOT_BLOCK)
214
215 /* Functions to query the kernel context depth/state.  I haven't fully decided
216  * on whether or not 'default' context includes RKMs or not.  Will depend on
217  * how we use it.  Check the code below to see what the latest is. */
218
219 #define in_irq_ctx(pcpui)                                                      \
220         (irq_depth(pcpui))
221
222 /* Right now, anything (KTRAP, IRQ, or RKM) makes us not 'default' */
223 #define in_default_ctx(pcpui)                                                  \
224         (!(pcpui)->__ctx_depth)
225
226 /* Can block only if we have no nested contexts (ktraps or irqs, (which are
227  * potentially nested contexts)) and not in an explicit CANNOT_BLOCK. */
228 #define can_block(pcpui)                                                       \
229         (!((pcpui)->__ctx_depth & (__CTX_NESTED_CTX_MASK | __CTX_CANNOT_BLOCK)))
230
231 /* TRUE if we are allowed to spin, given that the 'lock' was declared as not
232  * grabbable from IRQ context.  Meaning, we can't grab the lock from any nested
233  * context.  (And for most locks, we can never grab them from a kernel trap
234  * handler).
235  *
236  * Example is a lock that is not declared as irqsave, but we later grab it from
237  * irq context.  This could deadlock the system, even if it doesn't do it this
238  * time.  This function will catch that. */
239 #define can_spinwait_noirq(pcpui)                                              \
240         (!((pcpui)->__ctx_depth & __CTX_NESTED_CTX_MASK))
241
242 /* TRUE if we are allowed to spin, given that the 'lock' was declared as
243  * potentially grabbable by IRQ context (such as with an irqsave lock).  We can
244  * never grab from a ktrap, since there is no way to prevent that.  And we must
245  * have IRQs disabled, since an IRQ handler could attempt to grab the lock. */
246 #define can_spinwait_irq(pcpui)                                                \
247         ((!ktrap_depth(pcpui) && !irq_is_enabled()))
248
249 /* Debugging */
250 void print_kctx_depths(const char *str);