#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)
static inline void x86_advance_ip(struct hw_trapframe *hw_tf, size_t bytes)
{
- hw_tf->tf_rip += bytes;
+ hw_tf->tf_rip += bytes;
}
static inline void x86_fake_rdtscp(struct hw_trapframe *hw_tf)
hw_tf->tf_rcx = core_id();
}
-/* TODO: use syscall. all of this sysenter stuff is wrong */
static inline void x86_sysenter_init(uintptr_t stacktop)
{
- //write_msr(MSR_IA32_SYSENTER_CS, GD_KT);
- //write_msr(MSR_IA32_SYSENTER_EIP, (uintptr_t) &sysenter_handler);
+ /* 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)
{
asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
static inline long x86_get_sysenter_arg0(struct hw_trapframe *hw_tf)
{
- return hw_tf->tf_rax; // XXX probably wrong
+ return hw_tf->tf_rdi;
}
static inline long x86_get_sysenter_arg1(struct hw_trapframe *hw_tf)
{
- return hw_tf->tf_rsi; // XXX probably wrong
+ 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)