Skip to main content

ahrightos_process/
context.rs

1#[repr(C)]
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub struct ProcessContext {
4    pub x: [usize; 31],
5    pub sepc: usize,
6    pub sstatus: usize,
7    pub satp: usize,
8}
9
10pub const PROCESS_CONTEXT_X_OFFSET: usize = core::mem::offset_of!(ProcessContext, x);
11pub const PROCESS_CONTEXT_SEPC_OFFSET: usize = core::mem::offset_of!(ProcessContext, sepc);
12pub const PROCESS_CONTEXT_SSTATUS_OFFSET: usize = core::mem::offset_of!(ProcessContext, sstatus);
13pub const PROCESS_CONTEXT_SATP_OFFSET: usize = core::mem::offset_of!(ProcessContext, satp);
14pub const PROCESS_CONTEXT_SIZE: usize = core::mem::size_of::<ProcessContext>();
15
16const _: [(); 31 * core::mem::size_of::<usize>()] = [(); PROCESS_CONTEXT_SEPC_OFFSET];
17const _: [(); 32 * core::mem::size_of::<usize>()] = [(); PROCESS_CONTEXT_SSTATUS_OFFSET];
18const _: [(); 33 * core::mem::size_of::<usize>()] = [(); PROCESS_CONTEXT_SATP_OFFSET];
19const _: [(); 34 * core::mem::size_of::<usize>()] = [(); PROCESS_CONTEXT_SIZE];
20
21impl ProcessContext {
22    pub fn new() -> Self {
23        Self {
24            x: [0; 31],
25            sepc: 0,
26            sstatus: 0,
27            satp: 0,
28        }
29    }
30
31    pub fn set_ra(&mut self, ra: usize) {
32        self.x[0] = ra;
33    }
34
35    pub fn set_sp(&mut self, sp: usize) {
36        self.x[1] = sp;
37    }
38
39    pub fn ra(&self) -> usize {
40        self.x[0]
41    }
42
43    pub fn sp(&self) -> usize {
44        self.x[1]
45    }
46
47    pub fn set_sepc(&mut self, sepc: usize) {
48        self.sepc = sepc;
49    }
50
51    pub fn set_sstatus(&mut self, sstatus: usize) {
52        self.sstatus = sstatus;
53    }
54
55    pub fn set_satp(&mut self, satp: usize) {
56        self.satp = satp;
57    }
58}
59
60impl Default for ProcessContext {
61    fn default() -> Self {
62        Self::new()
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn context_helpers_set_arch_registers() {
72        let mut ctx = ProcessContext::new();
73        ctx.set_ra(0x8020_0000);
74        ctx.set_sp(0x8030_0000);
75        ctx.set_sepc(0x8040_0000);
76        ctx.set_sstatus(0x20);
77        ctx.set_satp(0x8000);
78        assert_eq!(ctx.ra(), 0x8020_0000);
79        assert_eq!(ctx.sp(), 0x8030_0000);
80        assert_eq!(ctx.sepc, 0x8040_0000);
81        assert_eq!(ctx.sstatus, 0x20);
82        assert_eq!(ctx.satp, 0x8000);
83    }
84
85    #[test]
86    fn context_layout_matches_switch_abi() {
87        assert_eq!(PROCESS_CONTEXT_X_OFFSET, 0);
88        assert_eq!(PROCESS_CONTEXT_SEPC_OFFSET, 248);
89        assert_eq!(PROCESS_CONTEXT_SSTATUS_OFFSET, 256);
90        assert_eq!(PROCESS_CONTEXT_SATP_OFFSET, 264);
91        assert_eq!(PROCESS_CONTEXT_SIZE, 272);
92    }
93}