Made ros_pop_tf work on SPARC
[akaros.git] / user / include / sparc / vcore.h
1 #ifndef PARLIB_ARCH_VCORE_H
2 #define PARLIB_ARCH_VCORE_H
3
4 #include <ros/common.h>
5 #include <ros/arch/trapframe.h>
6 #include <arch/arch.h>
7 #include <ros/syscall.h>
8 #include <ros/procdata.h>
9
10 /* Pops an ROS kernel-provided TF, reanabling notifications at the same time.
11  * A Userspace scheduler can call this when transitioning off the transition
12  * stack.
13  *
14  * Make sure you clear the notif_pending flag, and then check the queue before
15  * calling this.  If notif_pending is not clear, this will self_notify this
16  * core, since it should be because we missed a notification message while
17  * notifs were disabled. 
18  *
19  * The important thing is that it can a notification after it enables
20  * notifications, and when it gets resumed it can ultimately run the new
21  * context.  Enough state is saved in the running context and stack to continue
22  * running. */
23 static inline void pop_ros_tf(struct user_trapframe *tf, uint32_t vcoreid)
24 {
25         // since we're changing the stack, move stuff into regs for now
26         register uint32_t _vcoreid = _vcoreid;
27         register struct user_trapframe* _tf = tf;
28
29         set_stack_pointer((void*)tf->gpr[14]);
30
31         tf = _tf;
32         vcoreid = _vcoreid;
33         struct preempt_data* vcpd = &__procdata.vcore_preempt_data[vcoreid];
34
35         vcpd->notif_enabled = true;
36         if(vcpd->notif_pending)
37                 ros_syscall(SYS_self_notify,vcoreid,0,0,0,0);
38
39         // tell the kernel to load the new trapframe
40         asm volatile ("mov %0, %%o0; ta 4" : : "r"(tf) : "memory");
41 }
42
43 /* Feel free to ignore vcoreid.  It helps x86 to avoid a call to
44  * sys_getvcoreid() if we pass it in. */
45 static inline void *get_tls_desc(uint32_t vcoreid)
46 {
47         void *tmp;
48         asm volatile ("mov %%g7,%0" : "=r"(tmp));
49         return tmp;
50 }
51
52 static inline void set_tls_desc(void *tls_desc, uint32_t vcoreid)
53 {
54         asm volatile ("mov %0,%%g7" : : "r"(tls_desc) : "memory");
55 }
56
57 #define __vcore_id_on_entry (__vcore_id())
58
59 static inline int
60 __vcore_id()
61 {
62         int id;
63         asm ("mov %%asr13,%0" : "=r"(id));
64         return id;
65 }
66
67 #endif /* PARLIB_ARCH_VCORE_H */