NIX mode.
[akaros.git] / kern / arch / x86 / trap64.h
index 88e3476..21a87e8 100644 (file)
 #error "Do not include arch/trap64.h directly."
 #endif
 
+void print_swtrapframe(struct sw_trapframe *sw_tf);
+
 static inline bool in_kernel(struct hw_trapframe *hw_tf)
 {
        return (hw_tf->tf_cs & ~3) == GD_KT;
 }
 
-static inline void save_kernel_ctx(struct kernel_ctx *ctx)
+static inline uintptr_t get_hwtf_pc(struct hw_trapframe *hw_tf)
+{
+       return hw_tf->tf_rip;
+}
+
+static inline uintptr_t get_hwtf_fp(struct hw_trapframe *hw_tf)
 {
-       #if 0
-       /* Save the regs and the future esp. */
-       asm volatile("movl %%esp,(%0);       " /* save esp in it's slot*/
-                    "pushl %%eax;           " /* temp save eax */
-                    "leal 1f,%%eax;         " /* get future eip */
-                    "movl %%eax,(%1);       " /* store future eip */
-                    "popl %%eax;            " /* restore eax */
-                    "movl %2,%%esp;         " /* move to the beginning of the tf */
-                    "addl $0x20,%%esp;      " /* move to after the push_regs */
-                    "pushal;                " /* save regs */
-                    "addl $0x44,%%esp;      " /* move to esp slot */
-                    "popl %%esp;            " /* restore esp */
-                    "1:                     " /* where this tf will restart */
-                    : 
-                    : "r"(&ctx->hw_tf.tf_esp), "r"(&ctx->hw_tf.tf_eip),
-                      "g"(&ctx->hw_tf)
-                    : "eax", "memory", "cc");
-       #endif
+       return hw_tf->tf_rbp;
 }
 
 static inline uintptr_t x86_get_ip_hw(struct hw_trapframe *hw_tf)
 {
-       return hw_tf->tf_eip;
+       return hw_tf->tf_rip;
 }
 
 static inline void x86_advance_ip(struct hw_trapframe *hw_tf, size_t bytes)
 {
-               hw_tf->tf_eip += bytes;
+       hw_tf->tf_rip += bytes;
 }
 
 static inline void x86_fake_rdtscp(struct hw_trapframe *hw_tf)
 {
        uint64_t tsc_time = read_tsc();
-       hw_tf->tf_eip += 3;
-       hw_tf->tf_regs.reg_eax = tsc_time & 0xffffffff;
-       hw_tf->tf_regs.reg_edx = tsc_time >> 32;
-       hw_tf->tf_regs.reg_ecx = core_id();
+       hw_tf->tf_rip += 3;
+       hw_tf->tf_rax = tsc_time & 0xffffffff;
+       hw_tf->tf_rdx = tsc_time >> 32;
+       hw_tf->tf_rcx = core_id();
+}
+
+static inline void x86_sysenter_init(uintptr_t stacktop)
+{
+       /* check amd 2:6.1.1 for details.  they have some expectations about the GDT
+        * layout. */
+       write_msr(MSR_STAR, ((((uint64_t)GD_UD - 8) | 0x3) << 48) |
+                           ((uint64_t)GD_KT << 32));
+       write_msr(MSR_LSTAR, (uintptr_t)&sysenter_handler);
+       /* Masking all flags.  when we syscall, we'll get rflags = 0 */
+       write_msr(MSR_SFMASK, 0xffffffff);
+       write_msr(IA32_EFER_MSR, read_msr(IA32_EFER_MSR) | IA32_EFER_SYSCALL);
+       asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
 }
 
+/* these are used for both sysenter and traps on 32 bit */
 static inline void x86_set_sysenter_stacktop(uintptr_t stacktop)
 {
-       write_msr(MSR_IA32_SYSENTER_ESP, stacktop);
+       asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
 }
 
 static inline long x86_get_sysenter_arg0(struct hw_trapframe *hw_tf)
 {
-       return hw_tf->tf_regs.reg_eax;
+       return hw_tf->tf_rdi;
 }
 
 static inline long x86_get_sysenter_arg1(struct hw_trapframe *hw_tf)
 {
-       return hw_tf->tf_regs.reg_esi;
+       return hw_tf->tf_rsi;
+}
+
+static inline long x86_get_systrap_arg0(struct hw_trapframe *hw_tf)
+{
+       return hw_tf->tf_rdi;
+}
+
+static inline long x86_get_systrap_arg1(struct hw_trapframe *hw_tf)
+{
+       return hw_tf->tf_rsi;
 }
 
 static inline uintptr_t x86_get_stacktop_tss(struct taskstate *tss)