kernel/arch/riscv64/trap/
user.rs

1use core::arch::naked_asm;
2use core::{arch::asm, mem::transmute};
3
4use super::exception::arch_exception_handler;
5use super::interrupt::arch_interrupt_handler;
6
7use crate::arch::Trapframe;
8
9#[unsafe(link_section = ".trampoline.text")]
10#[unsafe(export_name = "_user_trap_entry")]
11#[unsafe(naked)]
12pub extern "C" fn _user_trap_entry() {
13    unsafe {
14        naked_asm!("
15        .option norvc
16        .option norelax
17        .align 8
18                /* Disable the interrupt */
19                csrci   sstatus, 0x2
20                /* Save the current a0 to sscratch and load the trapframe pointer */
21                csrrw   a0, sscratch, a0
22                /* Save the context of the current hart */
23                sd      x0, 0(a0)
24                sd      x1, 8(a0)
25                sd      x2, 16(a0)
26                sd      x3, 24(a0)
27                sd      x4, 32(a0)
28                sd      x5, 40(a0)
29                sd      x6, 48(a0)
30                sd      x7, 56(a0)
31                sd      x8, 64(a0)
32                sd      x9, 72(a0)
33                // sd      x10, 80(a0)
34                sd      x11, 88(a0)
35                sd      x12, 96(a0)
36                sd      x13, 104(a0)
37                sd      x14, 112(a0)
38                sd      x15, 120(a0)
39                sd      x16, 128(a0)
40                sd      x17, 136(a0)
41                sd      x18, 144(a0)
42                sd      x19, 152(a0)
43                sd      x20, 160(a0)
44                sd      x21, 168(a0)
45                sd      x22, 176(a0)
46                sd      x23, 184(a0)
47                sd      x24, 192(a0)
48                sd      x25, 200(a0)
49                sd      x26, 208(a0)
50                sd      x27, 216(a0)
51                sd      x28, 224(a0)
52                sd      x29, 232(a0)
53                sd      x30, 240(a0)
54                sd      x31, 248(a0)
55                csrr    t0, sepc
56                sd      t0, 256(a0)
57
58                // Load and store a0 to trapframe
59                csrr    t0, sscratch
60                // Restore sscratch from a0
61                csrw   sscratch, a0
62
63                sd      t0, 80(a0)
64
65                /* Load the satp for the kernel space from trapframe */
66                ld      t0, 272(a0)
67                /* Switch to kernel memory space */
68                csrrw   t0, satp, t0
69                sfence.vma zero, zero
70                /* Store the user memory space */
71                sd      t0, 272(a0)
72
73                // Load kernel stack pointer
74                ld      sp, 280(a0)
75
76                /* Call the user trap handler */
77                /* Load the function pointer from the trapframe */
78                ld      ra, 288(a0)
79                jalr    ra, 0(ra)
80
81                /* Restore the user memory space */
82                ld     t0, 272(a0)
83                csrrw  t0, satp, t0
84                sfence.vma zero, zero
85                /* Restore the kernel memory space to the trapframe */
86                sd     t0, 272(a0)
87
88                /* Restore the context of the current hart */ 
89                /* epc */
90                ld     t0, 256(a0)
91                csrw   sepc, t0
92                /* Register */
93                ld     x0, 0(a0)
94                ld     x1, 8(a0)
95                ld     x2, 16(a0)
96                ld     x3, 24(a0)
97                ld     x4, 32(a0)
98                ld     x5, 40(a0)
99                ld     x6, 48(a0)
100                ld     x7, 56(a0)
101                ld     x8, 64(a0)
102                ld     x9, 72(a0)
103                // ld     x10, 80(a0)
104                ld     x11, 88(a0)
105                ld     x12, 96(a0)
106                ld     x13, 104(a0)
107                ld     x14, 112(a0)
108                ld     x15, 120(a0)
109                ld     x16, 128(a0)
110                ld     x17, 136(a0)
111                ld     x18, 144(a0)
112                ld     x19, 152(a0)
113                ld     x20, 160(a0)
114                ld     x21, 168(a0)
115                ld     x22, 176(a0)
116                ld     x23, 184(a0)
117                ld     x24, 192(a0)
118                ld     x25, 200(a0)
119                ld     x26, 208(a0)
120                ld     x27, 216(a0)
121                ld     x28, 224(a0)
122                ld     x29, 232(a0)
123                ld     x30, 240(a0)
124                ld     x31, 248(a0)
125
126                /* Restore a0 from trapframe */
127                csrrw  zero, sscratch, a0
128                ld     a0, 80(a0)
129
130                sret
131            "
132        );
133    }
134}
135
136
137#[unsafe(export_name = "arch_user_trap_handler")]
138pub extern "C" fn arch_user_trap_handler(addr: usize) -> usize {
139    let trapframe: &mut Trapframe = unsafe { transmute(addr) };
140
141    let cause: usize;
142    unsafe {
143        asm!(
144            "csrr {0}, scause",
145            out(reg) cause,
146        );
147    }
148
149    /* Switch to kernel memory space */
150    // switch_to_kernel_vm();
151
152    let interrupt = cause & 0x8000000000000000 != 0;
153    if interrupt {
154        arch_interrupt_handler(trapframe, cause & !0x8000000000000000);
155    } else {
156        arch_exception_handler(trapframe, cause);
157    }
158
159    addr
160}