1use riscv::register::sstatus;
2
3use crate::uapi::signal::MContextT;
4
5#[repr(C)] #[derive(Debug, Clone, Copy)]
8pub struct TrapFrame {
9 pub sepc: usize, pub x1_ra: usize, pub x2_sp: usize, pub x3_gp: usize, pub x4_tp: usize, pub x5_t0: usize, pub x6_t1: usize, pub x7_t2: usize, pub x8_s0: usize, pub x9_s1: usize, pub x10_a0: usize, pub x11_a1: usize, pub x12_a2: usize, pub x13_a3: usize, pub x14_a4: usize, pub x15_a5: usize, pub x16_a6: usize, pub x17_a7: usize, pub x18_s2: usize, pub x19_s3: usize, pub x20_s4: usize, pub x21_s5: usize, pub x22_s6: usize, pub x23_s7: usize, pub x24_s8: usize, pub x25_s9: usize, pub x26_s10: usize, pub x27_s11: usize, pub x28_t3: usize, pub x29_t4: usize, pub x30_t5: usize, pub x31_t6: usize, pub sstatus: usize, pub kernel_sp: usize, }
48
49impl TrapFrame {
50 pub fn zero_init() -> Self {
52 TrapFrame {
53 sepc: 0,
54 x1_ra: 0,
55 x2_sp: 0,
56 x3_gp: 0,
57 x4_tp: 0,
58 x5_t0: 0,
59 x6_t1: 0,
60 x7_t2: 0,
61 x8_s0: 0,
62 x9_s1: 0,
63 x10_a0: 0,
64 x11_a1: 0,
65 x12_a2: 0,
66 x13_a3: 0,
67 x14_a4: 0,
68 x15_a5: 0,
69 x16_a6: 0,
70 x17_a7: 0,
71 x18_s2: 0,
72 x19_s3: 0,
73 x20_s4: 0,
74 x21_s5: 0,
75 x22_s6: 0,
76 x23_s7: 0,
77 x24_s8: 0,
78 x25_s9: 0,
79 x26_s10: 0,
80 x27_s11: 0,
81 x28_t3: 0,
82 x29_t4: 0,
83 x30_t5: 0,
84 x31_t6: 0,
85 sstatus: 0,
86 kernel_sp: 0,
87 }
89 }
90
91 #[inline]
95 pub fn get_sp(&self) -> usize {
96 self.x2_sp
97 }
98
99 #[inline]
101 pub fn set_sp(&mut self, val: usize) {
102 self.x2_sp = val;
103 }
104
105 #[inline]
107 pub fn get_a0(&self) -> usize {
108 self.x10_a0
109 }
110
111 #[inline]
113 pub fn set_a0(&mut self, val: usize) {
114 self.x10_a0 = val;
115 }
116
117 #[inline]
119 pub fn set_sepc(&mut self, pc: usize) {
120 self.sepc = pc;
121 }
122
123 #[inline]
125 pub fn get_sepc(&self) -> usize {
126 self.sepc
127 }
128
129 pub fn set_kernel_trap_frame(
135 &mut self,
136 entry: usize,
137 terminal: usize,
138 kernel_sp: usize,
139 ) {
142 let mut sstatus = sstatus::read();
143 sstatus.set_spp(sstatus::SPP::Supervisor);
144 sstatus.set_sie(false);
145 sstatus.set_spie(true);
146 self.sepc = entry;
147 self.sstatus = sstatus.bits();
148 self.kernel_sp = kernel_sp;
149 self.x1_ra = terminal;
150 self.x2_sp = kernel_sp;
151 }
154
155 pub unsafe fn set_clone_trap_frame(
169 &mut self,
170 parent_frame: &TrapFrame,
171 kernel_sp: usize,
172 user_sp: usize,
173 ) {
174 unsafe {
180 core::ptr::copy_nonoverlapping(
181 parent_frame as *const _ as *const u8,
182 self as *mut _ as *mut u8,
183 core::mem::size_of::<TrapFrame>(),
184 );
185 }
186 self.x10_a0 = 0;
188 self.kernel_sp = kernel_sp;
189 if user_sp != 0 {
191 self.x2_sp = user_sp;
192 }
193 }
195
196 pub fn set_exec_trap_frame(
206 &mut self,
207 entry: usize,
208 user_sp: usize,
209 kernel_sp: usize,
210 argc: usize,
211 argv: usize,
212 envp: usize,
213 ) {
214 let mut sstatus = sstatus::read();
215 sstatus.set_spp(sstatus::SPP::User);
216 sstatus.set_sie(false);
217 sstatus.set_spie(true);
218
219 *self = Self::zero_init();
221
222 self.sepc = entry;
223 self.sstatus = sstatus.bits();
224 self.kernel_sp = kernel_sp;
225 self.x2_sp = user_sp;
226
227 self.x10_a0 = argc;
229 self.x11_a1 = argv;
230 self.x12_a2 = envp;
231
232 }
234
235 pub unsafe fn set_fork_trap_frame(&mut self, parent_frame: &TrapFrame) {
245 unsafe {
251 core::ptr::copy_nonoverlapping(
252 parent_frame as *const _ as *const u8,
253 self as *mut _ as *mut u8,
254 core::mem::size_of::<TrapFrame>(),
255 );
256 }
257 self.x10_a0 = 0;
259 }
260
261 pub fn to_mcontext(&self) -> MContextT {
263 MContextT {
264 gregs: [
265 self.sepc as u64,
266 self.x1_ra as u64,
267 self.x2_sp as u64,
268 self.x3_gp as u64,
269 self.x4_tp as u64,
270 self.x5_t0 as u64,
271 self.x6_t1 as u64,
272 self.x7_t2 as u64,
273 self.x8_s0 as u64,
274 self.x9_s1 as u64,
275 self.x10_a0 as u64,
276 self.x11_a1 as u64,
277 self.x12_a2 as u64,
278 self.x13_a3 as u64,
279 self.x14_a4 as u64,
280 self.x15_a5 as u64,
281 self.x16_a6 as u64,
282 self.x17_a7 as u64,
283 self.x18_s2 as u64,
284 self.x19_s3 as u64,
285 self.x20_s4 as u64,
286 self.x21_s5 as u64,
287 self.x22_s6 as u64,
288 self.x23_s7 as u64,
289 self.x24_s8 as u64,
290 self.x25_s9 as u64,
291 self.x26_s10 as u64,
292 self.x27_s11 as u64,
293 self.x28_t3 as u64,
294 self.x29_t4 as u64,
295 self.x30_t5 as u64,
296 self.x31_t6 as u64,
297 ],
298 fpregs: [0; 66],
299 }
300 }
301
302 pub fn restore_from_mcontext(&mut self, mcontext: &MContextT) {
304 self.sepc = mcontext.gregs[0] as usize;
305 self.x1_ra = mcontext.gregs[1] as usize;
306 self.x2_sp = mcontext.gregs[2] as usize;
307 self.x3_gp = mcontext.gregs[3] as usize;
308 self.x4_tp = mcontext.gregs[4] as usize;
309 self.x5_t0 = mcontext.gregs[5] as usize;
310 self.x6_t1 = mcontext.gregs[6] as usize;
311 self.x7_t2 = mcontext.gregs[7] as usize;
312 self.x8_s0 = mcontext.gregs[8] as usize;
313 self.x9_s1 = mcontext.gregs[9] as usize;
314 self.x10_a0 = mcontext.gregs[10] as usize;
315 self.x11_a1 = mcontext.gregs[11] as usize;
316 self.x12_a2 = mcontext.gregs[12] as usize;
317 self.x13_a3 = mcontext.gregs[13] as usize;
318 self.x14_a4 = mcontext.gregs[14] as usize;
319 self.x15_a5 = mcontext.gregs[15] as usize;
320 self.x16_a6 = mcontext.gregs[16] as usize;
321 self.x17_a7 = mcontext.gregs[17] as usize;
322 self.x18_s2 = mcontext.gregs[18] as usize;
323 self.x19_s3 = mcontext.gregs[19] as usize;
324 self.x20_s4 = mcontext.gregs[20] as usize;
325 self.x21_s5 = mcontext.gregs[21] as usize;
326 self.x22_s6 = mcontext.gregs[22] as usize;
327 self.x23_s7 = mcontext.gregs[23] as usize;
328 self.x24_s8 = mcontext.gregs[24] as usize;
329 self.x25_s9 = mcontext.gregs[25] as usize;
330 self.x26_s10 = mcontext.gregs[26] as usize;
331 self.x27_s11 = mcontext.gregs[27] as usize;
332 self.x28_t3 = mcontext.gregs[28] as usize;
333 self.x29_t4 = mcontext.gregs[29] as usize;
334 self.x30_t5 = mcontext.gregs[30] as usize;
335 self.x31_t6 = mcontext.gregs[31] as usize;
336 }
337}