blob: f1a2efb643782a1b979672c2268d7892aead23b8 [file] [log] [blame]
/* Copyright (c) 2009-13 The Regents of the University of California
* Barret Rhoden <brho@cs.berkeley.edu>
* See LICENSE for details.
*
* x86 trap.c bit-specific functions. */
#include <arch/mmu.h>
#include <arch/x86.h>
#include <arch/arch.h>
#include <arch/console.h>
#include <arch/apic.h>
#include <ros/common.h>
#include <smp.h>
#include <assert.h>
#include <pmap.h>
#include <trap.h>
#include <monitor.h>
#include <process.h>
#include <mm.h>
#include <stdio.h>
#include <slab.h>
#include <syscall.h>
#include <kdebug.h>
#include <kmalloc.h>
static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
void print_trapframe(struct hw_trapframe *hw_tf)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
/* This is only called in debug scenarios, and often when the kernel
* trapped and needs to tell us about it. Disable the lock checker so
* it doesn't go nuts when we print/panic */
pcpui->__lock_checking_enabled--;
spin_lock_irqsave(&ptf_lock);
printk("HW TRAP frame %sat %p on core %d\n",
x86_hwtf_is_partial(hw_tf) ? "(partial) " : "",
hw_tf, core_id());
printk(" rax 0x%016lx\n", hw_tf->tf_rax);
printk(" rbx 0x%016lx\n", hw_tf->tf_rbx);
printk(" rcx 0x%016lx\n", hw_tf->tf_rcx);
printk(" rdx 0x%016lx\n", hw_tf->tf_rdx);
printk(" rbp 0x%016lx\n", hw_tf->tf_rbp);
printk(" rsi 0x%016lx\n", hw_tf->tf_rsi);
printk(" rdi 0x%016lx\n", hw_tf->tf_rdi);
printk(" r8 0x%016lx\n", hw_tf->tf_r8);
printk(" r9 0x%016lx\n", hw_tf->tf_r9);
printk(" r10 0x%016lx\n", hw_tf->tf_r10);
printk(" r11 0x%016lx\n", hw_tf->tf_r11);
printk(" r12 0x%016lx\n", hw_tf->tf_r12);
printk(" r13 0x%016lx\n", hw_tf->tf_r13);
printk(" r14 0x%016lx\n", hw_tf->tf_r14);
printk(" r15 0x%016lx\n", hw_tf->tf_r15);
printk(" trap 0x%08x %s\n", hw_tf->tf_trapno,
x86_trapname(hw_tf->tf_trapno));
/* FYI: these aren't physically adjacent to trap and err */
if (hw_tf->tf_cs == GD_KT)
printk(" gsbs 0x%016lx\n", read_gsbase());
else
printk(" gsbs 0x%016lx\n", hw_tf->tf_gsbase);
printk(" fsbs 0x%016lx\n", hw_tf->tf_fsbase);
printk(" err 0x--------%08x\n", hw_tf->tf_err);
printk(" rip 0x%016lx\n", hw_tf->tf_rip);
printk(" cs 0x------------%04x\n", hw_tf->tf_cs);
printk(" flag 0x%016lx\n", hw_tf->tf_rflags);
printk(" rsp 0x%016lx\n", hw_tf->tf_rsp);
printk(" ss 0x------------%04x\n", hw_tf->tf_ss);
spin_unlock_irqsave(&ptf_lock);
pcpui->__lock_checking_enabled++;
/* Used in trapentry64.S */
static_assert(offsetof(struct hw_trapframe, tf_cs) -
offsetof(struct hw_trapframe, tf_rax) == 0x90);
static_assert(offsetof(struct hw_trapframe, tf_padding0) -
offsetof(struct hw_trapframe, tf_rax) == 0xac);
/* Used in trap64.h */
static_assert(offsetof(struct per_cpu_info, stacktop) == 0);
}
void print_swtrapframe(struct sw_trapframe *sw_tf)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
pcpui->__lock_checking_enabled--;
spin_lock_irqsave(&ptf_lock);
printk("SW TRAP frame %sat %p on core %d\n",
x86_swtf_is_partial(sw_tf) ? "(partial) " : "",
sw_tf, core_id());
printk(" rbx 0x%016lx\n", sw_tf->tf_rbx);
printk(" rbp 0x%016lx\n", sw_tf->tf_rbp);
printk(" r12 0x%016lx\n", sw_tf->tf_r12);
printk(" r13 0x%016lx\n", sw_tf->tf_r13);
printk(" r14 0x%016lx\n", sw_tf->tf_r14);
printk(" r15 0x%016lx\n", sw_tf->tf_r15);
printk(" gsbs 0x%016lx\n", sw_tf->tf_gsbase);
printk(" fsbs 0x%016lx\n", sw_tf->tf_fsbase);
printk(" rip 0x%016lx\n", sw_tf->tf_rip);
printk(" rsp 0x%016lx\n", sw_tf->tf_rsp);
printk(" mxcsr 0x%08x\n", sw_tf->tf_mxcsr);
printk(" fpucw 0x%04x\n", sw_tf->tf_fpucw);
spin_unlock_irqsave(&ptf_lock);
pcpui->__lock_checking_enabled++;
}
void print_vmtrapframe(struct vm_trapframe *vm_tf)
{
struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
pcpui->__lock_checking_enabled--;
spin_lock_irqsave(&ptf_lock);
printk("VM Trapframe %sat %p on core %d\n",
x86_vmtf_is_partial(vm_tf) ? "(partial) " : "",
vm_tf, core_id());
printk(" rax 0x%016lx\n", vm_tf->tf_rax);
printk(" rbx 0x%016lx\n", vm_tf->tf_rbx);
printk(" rcx 0x%016lx\n", vm_tf->tf_rcx);
printk(" rdx 0x%016lx\n", vm_tf->tf_rdx);
printk(" rbp 0x%016lx\n", vm_tf->tf_rbp);
printk(" rsi 0x%016lx\n", vm_tf->tf_rsi);
printk(" rdi 0x%016lx\n", vm_tf->tf_rdi);
printk(" r8 0x%016lx\n", vm_tf->tf_r8);
printk(" r9 0x%016lx\n", vm_tf->tf_r9);
printk(" r10 0x%016lx\n", vm_tf->tf_r10);
printk(" r11 0x%016lx\n", vm_tf->tf_r11);
printk(" r12 0x%016lx\n", vm_tf->tf_r12);
printk(" r13 0x%016lx\n", vm_tf->tf_r13);
printk(" r14 0x%016lx\n", vm_tf->tf_r14);
printk(" r15 0x%016lx\n", vm_tf->tf_r15);
printk(" rip 0x%016lx\n", vm_tf->tf_rip);
printk(" rflg 0x%016lx\n", vm_tf->tf_rflags);
printk(" rsp 0x%016lx\n", vm_tf->tf_rsp);
printk(" cr2 0x%016lx\n", vm_tf->tf_cr2);
printk(" cr3 0x%016lx\n", vm_tf->tf_cr3);
printk("Gpcore 0x%08x\n", vm_tf->tf_guest_pcoreid);
printk("Flags 0x%08x\n", vm_tf->tf_flags);
printk("Inject 0x%08x\n", vm_tf->tf_trap_inject);
printk("ExitRs 0x%08x\n", vm_tf->tf_exit_reason);
printk("ExitQl 0x%08x\n", vm_tf->tf_exit_qual);
printk("Intr1 0x%016lx\n", vm_tf->tf_intrinfo1);
printk("Intr2 0x%016lx\n", vm_tf->tf_intrinfo2);
printk("GIntr 0x----%04x\n", vm_tf->tf_guest_intr_status);
printk("GVA 0x%016lx\n", vm_tf->tf_guest_va);
printk("GPA 0x%016lx\n", vm_tf->tf_guest_pa);
spin_unlock_irqsave(&ptf_lock);
pcpui->__lock_checking_enabled++;
}
void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
unsigned int err, unsigned long aux)
{
hw_tf->tf_trapno = trap_nr;
/* this can be necessary, since hw_tf is the pcpui one, and the err that
* came in probably came from the kernel stack's hw_tf. */
hw_tf->tf_err = err;
hw_tf->tf_padding4 = (uint32_t)(aux);
hw_tf->tf_padding5 = (uint32_t)(aux >> 32);
hw_tf->tf_padding3 = ROS_ARCH_REFL_ID;
}