1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use alloc::boxed::Box;
use x86_64::{structures::paging::PageTableFlags, VirtAddr};

use crate::memory::{GeneralPageTable, MemoryManager};

const KERNEL_STACK_SIZE: usize = 16 * 1024;
const USER_STACK_END: usize = 0x0000_7fff_feff_f000;
const USER_STACK_SIZE: usize = 64 * 1024;

pub struct KernelStack(Box<[u8]>);

impl KernelStack {
    pub fn new() -> Self {
        Self(Box::from(alloc::vec![0; KERNEL_STACK_SIZE]))
    }

    pub fn end_address(&self) -> VirtAddr {
        VirtAddr::new(self.0.as_ptr_range().end as u64)
    }
}

pub struct UserStack {
    pub start_address: VirtAddr,
    pub end_address: VirtAddr,
}

impl UserStack {
    pub fn new(page_table: &mut GeneralPageTable) -> Self {
        let user_stack_end = VirtAddr::new(USER_STACK_END as u64);
        let user_stack_start = user_stack_end - USER_STACK_SIZE as u64;

        let flags = PageTableFlags::PRESENT
            | PageTableFlags::WRITABLE
            | PageTableFlags::USER_ACCESSIBLE
            | PageTableFlags::NO_EXECUTE;

        <MemoryManager>::alloc_range(user_stack_start, USER_STACK_SIZE as u64, flags, page_table)
            .unwrap();

        Self {
            start_address: user_stack_start,
            end_address: user_stack_end,
        }
    }
}