x86: Use a common lock for printing all trapframes
[akaros.git] / kern / arch / x86 / trap64.c
1 /* Copyright (c) 2009-13 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * x86 trap.c bit-specific functions. */
6
7 #include <arch/mmu.h>
8 #include <arch/x86.h>
9 #include <arch/arch.h>
10 #include <arch/console.h>
11 #include <arch/apic.h>
12 #include <ros/common.h>
13 #include <smp.h>
14 #include <assert.h>
15 #include <pmap.h>
16 #include <trap.h>
17 #include <monitor.h>
18 #include <process.h>
19 #include <mm.h>
20 #include <stdio.h>
21 #include <slab.h>
22 #include <syscall.h>
23 #include <kdebug.h>
24 #include <kmalloc.h>
25
26 static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
27
28 void print_trapframe(struct hw_trapframe *hw_tf)
29 {
30         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
31         /* This is only called in debug scenarios, and often when the kernel trapped
32          * and needs to tell us about it.  Disable the lock checker so it doesn't go
33          * nuts when we print/panic */
34         pcpui->__lock_checking_enabled--;
35         spin_lock_irqsave(&ptf_lock);
36         printk("HW TRAP frame %sat %p on core %d\n",
37                x86_hwtf_is_partial(hw_tf) ? "(partial) " : "",
38                hw_tf, core_id());
39         printk("  rax  0x%016lx\n",           hw_tf->tf_rax);
40         printk("  rbx  0x%016lx\n",           hw_tf->tf_rbx);
41         printk("  rcx  0x%016lx\n",           hw_tf->tf_rcx);
42         printk("  rdx  0x%016lx\n",           hw_tf->tf_rdx);
43         printk("  rbp  0x%016lx\n",           hw_tf->tf_rbp);
44         printk("  rsi  0x%016lx\n",           hw_tf->tf_rsi);
45         printk("  rdi  0x%016lx\n",           hw_tf->tf_rdi);
46         printk("  r8   0x%016lx\n",           hw_tf->tf_r8);
47         printk("  r9   0x%016lx\n",           hw_tf->tf_r9);
48         printk("  r10  0x%016lx\n",           hw_tf->tf_r10);
49         printk("  r11  0x%016lx\n",           hw_tf->tf_r11);
50         printk("  r12  0x%016lx\n",           hw_tf->tf_r12);
51         printk("  r13  0x%016lx\n",           hw_tf->tf_r13);
52         printk("  r14  0x%016lx\n",           hw_tf->tf_r14);
53         printk("  r15  0x%016lx\n",           hw_tf->tf_r15);
54         printk("  trap 0x%08x %s\n",          hw_tf->tf_trapno,
55                                               x86_trapname(hw_tf->tf_trapno));
56         /* FYI: these aren't physically adjacent to trap and err */
57         if (hw_tf->tf_cs == GD_KT)
58                 printk("  gsbs 0x%016lx\n",       read_msr(MSR_GS_BASE));
59         else
60                 printk("  gsbs 0x%016lx\n",       hw_tf->tf_gsbase);
61         printk("  fsbs 0x%016lx\n",           hw_tf->tf_fsbase);
62         printk("  err  0x--------%08x\n",     hw_tf->tf_err);
63         printk("  rip  0x%016lx\n",           hw_tf->tf_rip);
64         printk("  cs   0x------------%04x\n", hw_tf->tf_cs);
65         printk("  flag 0x%016lx\n",           hw_tf->tf_rflags);
66         printk("  rsp  0x%016lx\n",           hw_tf->tf_rsp);
67         printk("  ss   0x------------%04x\n", hw_tf->tf_ss);
68         spin_unlock_irqsave(&ptf_lock);
69         pcpui->__lock_checking_enabled++;
70
71         /* Used in trapentry64.S */
72         static_assert(offsetof(struct hw_trapframe, tf_cs) - 
73                       offsetof(struct hw_trapframe, tf_rax) == 0x90);
74         static_assert(offsetof(struct hw_trapframe, tf_padding0) -
75                       offsetof(struct hw_trapframe, tf_rax) == 0xac);
76         /* Used in trap64.h */
77         static_assert(offsetof(struct per_cpu_info, stacktop) == 0);
78 }
79
80 void print_swtrapframe(struct sw_trapframe *sw_tf)
81 {
82         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
83
84         pcpui->__lock_checking_enabled--;
85         spin_lock_irqsave(&ptf_lock);
86         printk("SW TRAP frame %sat %p on core %d\n",
87                x86_swtf_is_partial(sw_tf) ? "(partial) " : "",
88                sw_tf, core_id());
89         printk("  rbx  0x%016lx\n",           sw_tf->tf_rbx);
90         printk("  rbp  0x%016lx\n",           sw_tf->tf_rbp);
91         printk("  r12  0x%016lx\n",           sw_tf->tf_r12);
92         printk("  r13  0x%016lx\n",           sw_tf->tf_r13);
93         printk("  r14  0x%016lx\n",           sw_tf->tf_r14);
94         printk("  r15  0x%016lx\n",           sw_tf->tf_r15);
95         printk("  gsbs 0x%016lx\n",           sw_tf->tf_gsbase);
96         printk("  fsbs 0x%016lx\n",           sw_tf->tf_fsbase);
97         printk("  rip  0x%016lx\n",           sw_tf->tf_rip);
98         printk("  rsp  0x%016lx\n",           sw_tf->tf_rsp);
99         printk(" mxcsr 0x%08x\n",             sw_tf->tf_mxcsr);
100         printk(" fpucw 0x%04x\n",             sw_tf->tf_fpucw);
101         spin_unlock_irqsave(&ptf_lock);
102         pcpui->__lock_checking_enabled++;
103 }
104
105 void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
106                               unsigned int err, unsigned long aux)
107 {
108         hw_tf->tf_trapno = trap_nr;
109         /* this can be necessary, since hw_tf is the pcpui one, and the err that
110          * came in probably came from the kernel stack's hw_tf. */
111         hw_tf->tf_err = err;
112         hw_tf->tf_padding4 = (uint32_t)(aux);
113         hw_tf->tf_padding5 = (uint32_t)(aux >> 32);
114         hw_tf->tf_padding3 = ROS_ARCH_REFL_ID;
115 }