| /* 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; | 
 | } |