1 /* Copyright (c) 2009-13 The Regents of the University of California
2 * Barret Rhoden <brho@cs.berkeley.edu>
3 * See LICENSE for details.
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. */
10 #ifndef ROS_KERN_ARCH_TRAP64_H
11 #define ROS_KERN_ARCH_TRAP64_H
13 #ifndef ROS_KERN_ARCH_TRAP_H
14 #error "Do not include arch/trap64.h directly."
17 /* For kernel contexts, when we save/restore/move them around. */
19 struct sw_trapframe sw_tf;
22 void print_swtrapframe(struct sw_trapframe *sw_tf);
24 static inline bool in_kernel(struct hw_trapframe *hw_tf)
26 return (hw_tf->tf_cs & ~3) == GD_KT;
29 /* Using SW contexts for now, for x86_64 */
30 static inline void save_kernel_ctx(struct kernel_ctx *ctx)
33 /* not bothering with the FP fields */
34 asm volatile("mov %%rsp, 0x48(%0); " /* save rsp in its slot*/
35 "leaq 1f, %%rax; " /* get future rip */
36 "mov %%rax, 0x40(%0); " /* save rip in its slot*/
37 "mov %%r15, 0x38(%0); "
38 "mov %%r14, 0x30(%0); "
39 "mov %%r13, 0x28(%0); "
40 "mov %%r12, 0x20(%0); "
41 "mov %%rbp, 0x18(%0); "
42 "mov %%rbx, 0x10(%0); "
43 "1: " /* where this tf will restart */
44 : "=D"(dummy) /* force rdi clobber */
46 : "rax", "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11",
50 static inline uintptr_t x86_get_ip_hw(struct hw_trapframe *hw_tf)
55 static inline void x86_advance_ip(struct hw_trapframe *hw_tf, size_t bytes)
57 hw_tf->tf_rip += bytes;
60 static inline void x86_fake_rdtscp(struct hw_trapframe *hw_tf)
62 uint64_t tsc_time = read_tsc();
64 hw_tf->tf_rax = tsc_time & 0xffffffff;
65 hw_tf->tf_rdx = tsc_time >> 32;
66 hw_tf->tf_rcx = core_id();
69 static inline void x86_sysenter_init(uintptr_t stacktop)
71 /* check amd 2:6.1.1 for details. they have some expectations about the GDT
73 write_msr(MSR_STAR, ((((uint64_t)GD_UD - 8) | 0x3) << 48) |
74 ((uint64_t)GD_KT << 32));
75 write_msr(MSR_LSTAR, (uintptr_t)&sysenter_handler);
76 /* Masking all flags. when we syscall, we'll get rflags = 0 */
77 write_msr(MSR_SFMASK, 0xffffffff);
78 write_msr(IA32_EFER_MSR, read_msr(IA32_EFER_MSR) | IA32_EFER_SYSCALL);
79 asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
82 /* these are used for both sysenter and traps on 32 bit */
83 static inline void x86_set_sysenter_stacktop(uintptr_t stacktop)
85 asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
88 static inline long x86_get_sysenter_arg0(struct hw_trapframe *hw_tf)
93 static inline long x86_get_sysenter_arg1(struct hw_trapframe *hw_tf)
98 static inline long x86_get_systrap_arg0(struct hw_trapframe *hw_tf)
100 return hw_tf->tf_rdi;
103 static inline long x86_get_systrap_arg1(struct hw_trapframe *hw_tf)
105 return hw_tf->tf_rsi;
108 static inline uintptr_t x86_get_stacktop_tss(struct taskstate *tss)
113 static inline void x86_set_stacktop_tss(struct taskstate *tss, uintptr_t top)
118 static inline uintptr_t x86_get_hwtf_pc(struct hw_trapframe *hw_tf)
120 return hw_tf->tf_rip;
123 static inline uintptr_t x86_get_hwtf_fp(struct hw_trapframe *hw_tf)
125 return hw_tf->tf_rbp;
128 #endif /* ROS_KERN_ARCH_TRAP64_H */