good_os_framework/task/
context.rs

1use x86_64::structures::gdt::SegmentSelector;
2use x86_64::{PhysAddr, VirtAddr};
3
4#[derive(Debug, Clone, Copy, Default)]
5#[repr(packed)]
6pub struct Context {
7    pub cr3: usize,
8    pub r15: usize,
9    pub r14: usize,
10    pub r13: usize,
11
12    pub r12: usize,
13    pub r11: usize,
14    pub r10: usize,
15    pub r9: usize,
16
17    pub r8: usize,
18    pub rbp: usize,
19    pub rsi: usize,
20    pub rdi: usize,
21
22    pub rdx: usize,
23    pub rcx: usize,
24    pub rbx: usize,
25    pub rax: usize,
26
27    pub rip: usize,
28    pub cs: usize,
29    pub rflags: usize,
30    pub rsp: usize,
31    pub ss: usize,
32}
33
34impl Context {
35    pub fn init(
36        &mut self,
37        entry_point: usize,
38        stack_end_address: VirtAddr,
39        page_table_address: PhysAddr,
40        segment_selectors: (SegmentSelector, SegmentSelector),
41    ) {
42        self.rflags = 0x200;
43        self.rip = entry_point;
44        self.rsp = stack_end_address.as_u64() as usize;
45        self.cr3 = page_table_address.as_u64() as usize;
46
47        let (code_selector, data_selector) = segment_selectors;
48        self.cs = code_selector.0 as usize;
49        self.ss = data_selector.0 as usize;
50    }
51
52    #[inline]
53    pub fn address(&self) -> VirtAddr {
54        VirtAddr::new(self as *const Context as u64)
55    }
56
57    #[inline]
58    pub fn from_address(address: VirtAddr) -> Context {
59        unsafe { *&mut *(address.as_u64() as *mut Context) }
60    }
61}
62
63#[macro_export]
64macro_rules! push_context {
65    () => {
66        concat!(
67            r#"
68			push rax
69            push rbx
70            push rcx
71            push rdx
72            push rdi
73            push rsi
74            push rbp
75            push r8
76            push r9
77            push r10
78            push r11
79            push r12
80            push r13
81            push r14
82            push r15
83            mov r15, cr3
84            push r15
85			"#,
86        )
87    };
88}
89
90#[macro_export]
91macro_rules! pop_context {
92    () => {
93        concat!(
94            r#"
95			pop r15
96            mov cr3, r15
97            pop r15
98            pop r14
99            pop r13
100            pop r12
101            pop r11
102            pop r10
103            pop r9
104            pop r8
105            pop rbp
106            pop rsi
107            pop rdi
108            pop rdx
109            pop rcx
110            pop rbx
111            pop rax
112			"#
113        )
114    };
115}