PCI device locking and synchronization
[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 /* Starts running the current TF, just using ret. */
27 void pop_kernel_ctx(struct kernel_ctx *ctx)
28 {
29         struct sw_trapframe *tf = &ctx->sw_tf;
30         /* We're starting at rbx's spot in the sw_tf */
31         asm volatile ("movq %0, %%rsp;          "
32                                   "popq %%rbx;              "
33                                   "popq %%rbp;              "
34                                   "popq %%r12;              "
35                                   "popq %%r13;              "
36                                   "popq %%r14;              "
37                                   "popq %%r15;              "
38                                   "popq %%rax;              " /* pop rip */
39                                   "popq %%rsp;              "
40                                   "jmp *%%rax;              " /* stored rip */
41                                   : : "g"(&ctx->sw_tf.tf_rbx) : "memory");
42         panic("ret failed");
43 }
44
45 void print_trapframe(struct hw_trapframe *hw_tf)
46 {
47         static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
48
49         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
50         /* This is only called in debug scenarios, and often when the kernel trapped
51          * and needs to tell us about it.  Disable the lock checker so it doesn't go
52          * nuts when we print/panic */
53         pcpui->__lock_checking_enabled--;
54         spin_lock_irqsave(&ptf_lock);
55         printk("HW TRAP frame at %p on core %d\n", hw_tf, core_id());
56         printk("  rax  0x%016lx\n",           hw_tf->tf_rax);
57         printk("  rbx  0x%016lx\n",           hw_tf->tf_rbx);
58         printk("  rcx  0x%016lx\n",           hw_tf->tf_rcx);
59         printk("  rdx  0x%016lx\n",           hw_tf->tf_rdx);
60         printk("  rbp  0x%016lx\n",           hw_tf->tf_rbp);
61         printk("  rsi  0x%016lx\n",           hw_tf->tf_rsi);
62         printk("  rdi  0x%016lx\n",           hw_tf->tf_rdi);
63         printk("  r8   0x%016lx\n",           hw_tf->tf_r8);
64         printk("  r9   0x%016lx\n",           hw_tf->tf_r9);
65         printk("  r10  0x%016lx\n",           hw_tf->tf_r10);
66         printk("  r11  0x%016lx\n",           hw_tf->tf_r11);
67         printk("  r12  0x%016lx\n",           hw_tf->tf_r12);
68         printk("  r13  0x%016lx\n",           hw_tf->tf_r13);
69         printk("  r14  0x%016lx\n",           hw_tf->tf_r14);
70         printk("  r15  0x%016lx\n",           hw_tf->tf_r15);
71         printk("  trap 0x%08x %s\n",          hw_tf->tf_trapno,
72                                               x86_trapname(hw_tf->tf_trapno));
73         /* FYI: these aren't physically adjacent to trap and err */
74         if (hw_tf->tf_cs == GD_KT)
75                 printk("  gsbs 0x%016lx\n",       read_msr(MSR_GS_BASE));
76         else
77                 printk("  gsbs 0x%016lx\n",       hw_tf->tf_gsbase);
78         printk("  fsbs 0x%016lx\n",           hw_tf->tf_fsbase);
79         printk("  err  0x--------%08x\n",     hw_tf->tf_err);
80         printk("  rip  0x%016lx\n",           hw_tf->tf_rip);
81         printk("  cs   0x------------%04x\n", hw_tf->tf_cs);
82         printk("  flag 0x%016lx\n",           hw_tf->tf_rflags);
83         printk("  rsp  0x%016lx\n",           hw_tf->tf_rsp);
84         printk("  ss   0x------------%04x\n", hw_tf->tf_ss);
85         spin_unlock_irqsave(&ptf_lock);
86         pcpui->__lock_checking_enabled++;
87
88         /* Used in trapentry64.S */
89         static_assert(offsetof(struct hw_trapframe, tf_cs) - 
90                       offsetof(struct hw_trapframe, tf_rax) == 0x90);
91         /* Used in trap64.h */
92         static_assert(offsetof(struct per_cpu_info, stacktop) == 0);
93 }
94
95 void print_swtrapframe(struct sw_trapframe *sw_tf)
96 {
97         static spinlock_t ptf_lock = SPINLOCK_INITIALIZER_IRQSAVE;
98         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
99         pcpui->__lock_checking_enabled--;
100         spin_lock_irqsave(&ptf_lock);
101         printk("SW TRAP frame at %p on core %d\n", sw_tf, core_id());
102         printk("  rbx  0x%016lx\n",           sw_tf->tf_rbx);
103         printk("  rbp  0x%016lx\n",           sw_tf->tf_rbp);
104         printk("  r12  0x%016lx\n",           sw_tf->tf_r12);
105         printk("  r13  0x%016lx\n",           sw_tf->tf_r13);
106         printk("  r14  0x%016lx\n",           sw_tf->tf_r14);
107         printk("  r15  0x%016lx\n",           sw_tf->tf_r15);
108         printk("  gsbs 0x%016lx\n",           sw_tf->tf_gsbase);
109         printk("  fsbs 0x%016lx\n",           sw_tf->tf_fsbase);
110         printk("  rip  0x%016lx\n",           sw_tf->tf_rip);
111         printk("  rsp  0x%016lx\n",           sw_tf->tf_rsp);
112         printk(" mxcsr 0x%08x\n",             sw_tf->tf_mxcsr);
113         printk(" fpucw 0x%04x\n",             sw_tf->tf_fpucw);
114         spin_unlock_irqsave(&ptf_lock);
115         pcpui->__lock_checking_enabled++;
116 }
117
118 void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
119                               unsigned int err, unsigned long aux)
120 {
121         hw_tf->tf_trapno = trap_nr;
122         /* this can be necessary, since hw_tf is the pcpui one, and the err that
123          * came in probably came from the kernel stack's hw_tf. */
124         hw_tf->tf_err = err;
125         hw_tf->tf_padding4 = (uint32_t)(aux);
126         hw_tf->tf_padding5 = (uint32_t)(aux >> 32);
127         hw_tf->tf_padding3 = ROS_ARCH_REFL_ID;
128 }