No longer builds, but this is a good intermediate save point.
[akaros.git] / kern / arch / x86 / trap64.h
1 /* Copyright (c) 2009-13 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * x86 trap.h bit-specific functions.  This is included by trap.h, do not
6  * include it directly.  Any function beginning with x86_ is internal to x86,
7  * and not to be called by the main kernel.  Other functions are part of the
8  * kernel-arch interface. */
9
10 #ifndef ROS_KERN_ARCH_TRAP64_H
11 #define ROS_KERN_ARCH_TRAP64_H
12
13 #ifndef ROS_KERN_ARCH_TRAP_H
14 #error "Do not include arch/trap64.h directly."
15 #endif
16
17 void print_swtrapframe(struct sw_trapframe *sw_tf);
18
19 static inline bool in_kernel(struct hw_trapframe *hw_tf)
20 {
21         return (hw_tf->tf_cs & ~3) == GD_KT;
22 }
23
24 static inline uintptr_t get_hwtf_pc(struct hw_trapframe *hw_tf)
25 {
26         return hw_tf->tf_rip;
27 }
28
29 static inline uintptr_t get_hwtf_fp(struct hw_trapframe *hw_tf)
30 {
31         return hw_tf->tf_rbp;
32 }
33
34 static inline uintptr_t x86_get_ip_hw(struct hw_trapframe *hw_tf)
35 {
36         return hw_tf->tf_rip;
37 }
38
39 static inline void x86_advance_ip(struct hw_trapframe *hw_tf, size_t bytes)
40 {
41         hw_tf->tf_rip += bytes;
42 }
43
44 static inline void x86_fake_rdtscp(struct hw_trapframe *hw_tf)
45 {
46         uint64_t tsc_time = read_tsc();
47         hw_tf->tf_rip += 3;
48         hw_tf->tf_rax = tsc_time & 0xffffffff;
49         hw_tf->tf_rdx = tsc_time >> 32;
50         hw_tf->tf_rcx = core_id();
51 }
52
53 static inline void x86_sysenter_init(uintptr_t stacktop)
54 {
55         /* check amd 2:6.1.1 for details.  they have some expectations about the GDT
56          * layout. */
57         write_msr(MSR_STAR, ((((uint64_t)GD_UD - 8) | 0x3) << 48) |
58                             ((uint64_t)GD_KT << 32));
59         write_msr(MSR_LSTAR, (uintptr_t)&sysenter_handler);
60         /* Masking all flags.  when we syscall, we'll get rflags = 0 */
61         write_msr(MSR_SFMASK, 0xffffffff);
62         write_msr(IA32_EFER_MSR, read_msr(IA32_EFER_MSR) | IA32_EFER_SYSCALL);
63         asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
64 }
65
66 /* these are used for both sysenter and traps on 32 bit */
67 static inline void x86_set_sysenter_stacktop(uintptr_t stacktop)
68 {
69         asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
70 }
71
72 static inline long x86_get_sysenter_arg0(struct hw_trapframe *hw_tf)
73 {
74         return hw_tf->tf_rdi;
75 }
76
77 static inline long x86_get_sysenter_arg1(struct hw_trapframe *hw_tf)
78 {
79         return hw_tf->tf_rsi;
80 }
81
82 static inline long x86_get_systrap_arg0(struct hw_trapframe *hw_tf)
83 {
84         return hw_tf->tf_rdi;
85 }
86
87 static inline long x86_get_systrap_arg1(struct hw_trapframe *hw_tf)
88 {
89         return hw_tf->tf_rsi;
90 }
91
92 static inline uintptr_t x86_get_stacktop_tss(struct taskstate *tss)
93 {
94         return tss->ts_rsp0;
95 }
96
97 static inline void x86_set_stacktop_tss(struct taskstate *tss, uintptr_t top)
98 {
99         tss->ts_rsp0 = top;
100 }
101
102 #endif /* ROS_KERN_ARCH_TRAP64_H */