Kthread infrastructure
[akaros.git] / kern / include / trap.h
1 /* See COPYRIGHT for copyright information. */
2
3 #ifndef ROS_KERN_TRAP_H
4 #define ROS_KERN_TRAP_H
5 #ifndef ROS_KERNEL
6 # error "This is an ROS kernel header; user programs should not #include it"
7 #endif
8
9 #include <arch/arch.h>
10 #include <arch/mmu.h>
11 #include <arch/trap.h>
12 #include <sys/queue.h>
13
14 // func ptr for interrupt service routines
15 typedef void ( *poly_isr_t)(trapframe_t* tf, TV(t) data);
16 typedef void (*isr_t)(trapframe_t* tf, void * data);
17 typedef struct InterruptHandler {
18         poly_isr_t isr;
19         TV(t) data;
20 } handler_t;
21
22 #ifdef __IVY__
23 #pragma cilnoremove("iht_lock")
24 extern spinlock_t iht_lock;
25 #endif
26 extern handler_t LCKD(&iht_lock) (CT(NUM_INTERRUPT_HANDLERS) RO interrupt_handlers)[];
27
28 void idt_init(void);
29 void
30 register_interrupt_handler(handler_t SSOMELOCK (CT(NUM_INTERRUPT_HANDLERS)table)[],
31                            uint8_t int_num,
32                            poly_isr_t handler, TV(t) data);
33 void print_trapframe(trapframe_t *tf);
34 void page_fault_handler(trapframe_t *tf);
35 /* Generic per-core timer interrupt handler.  set_percore_timer() will fire the
36  * timer_interrupt(). */
37 void set_core_timer(uint32_t usec);
38 void timer_interrupt(struct trapframe *tf, void *data);
39
40 void sysenter_init(void);
41 extern void sysenter_handler();
42
43 void save_fp_state(struct ancillary_state *silly);
44 void restore_fp_state(struct ancillary_state *silly);
45 /* Set stacktop for the current core to be the stack the kernel will start on
46  * when trapping/interrupting from userspace */
47 void set_stack_top(uintptr_t stacktop);
48 uintptr_t get_stack_top(void);
49
50 /* It's important that this is inline and that tf is not a stack variable */
51 static inline void save_kernel_tf(struct trapframe *tf)
52                    __attribute__((always_inline));
53 void pop_kernel_tf(struct trapframe *tf) __attribute__((noreturn));
54
55 /* Kernel messages.  Each arch implements them in their own way.  Both should be
56  * guaranteeing in-order delivery.  Kept here in trap.h, since sparc is using
57  * trap.h for KMs.  Eventually, both arches will use the same implementation.
58  *
59  * These are different (for now) than the smp_calls in smp.h, since
60  * they will be executed immediately (for urgent messages), and in the order in
61  * which they are sent.  smp_calls are currently not run in order, and they must
62  * return (possibly passing the work to a workqueue, which is really just a
63  * routine message, so they really need to just return).
64  *
65  * Eventually, smp_call will be replaced by these.
66  *
67  * Also, a big difference is that smp_calls can use the same message (registered
68  * in the interrupt_handlers[] for x86) for every recipient, but the kernel
69  * messages require a unique message.  Also for now, but it might be like that
70  * for a while on x86 (til we have a broadcast). */
71
72 #define KMSG_IMMEDIATE                  1
73 #define KMSG_ROUTINE                    2
74 void kernel_msg_init(void);
75 typedef void (*amr_t)(trapframe_t* tf, uint32_t srcid,
76                       TV(a0t) a0, TV(a1t) a1, TV(a2t) a2);
77
78 struct kernel_message
79 {
80         STAILQ_ENTRY(kernel_message NTPTV(a0t) NTPTV(a1t) NTPTV(a2t))
81                 NTPTV(a0t) NTPTV(a1t) NTPTV(a2t) link;
82         uint32_t srcid;
83         amr_t pc;
84         TV(a0t) arg0;
85         TV(a1t) arg1;
86         TV(a2t) arg2;
87 };
88 STAILQ_HEAD(kernel_msg_list, kernel_message NTPTV(a0t) NTPTV(a1t) NTPTV(a2t));
89 typedef struct kernel_message NTPTV(a0t) NTPTV(a1t) NTPTV(a2t) kernel_message_t;
90
91 uint32_t send_kernel_message(uint32_t dst, amr_t pc, TV(a0t) arg0, TV(a1t) arg1,
92                              TV(a2t) arg2, int type);
93 void process_routine_kmsg(void);
94
95 #endif /* ROS_KERN_TRAP_H */