1use crate::lib::addr::VirtAddr;
7use crate::mm::layout;
8use crate::mm::mm_error::{MmError, MmResult};
9use crate::mm::pmm::FRAME_SIZE;
10use crate::mm::vmm::Vmm;
11use crate::mm::vmm::address_space::AddressSpace;
12use crate::mm::vmm::vma::VmaFlags;
13use crate::state::kstate::KSTATE;
14
15pub fn alloc(
20 addr_space: &mut AddressSpace,
21 fixed_addr: Option<VirtAddr>,
22 size: u64,
23 flags: VmaFlags
24) -> MmResult<VirtAddr> {
25 let size = VirtAddr::new(size).align_up(FRAME_SIZE).as_u64();
26
27 let virt = match fixed_addr {
28 Some(addr) => {
29 if !addr.is_aligned(FRAME_SIZE) {
30 return Err(MmError::MisalignedAddress);
31 }
32 addr
33 },
34 None => {
35 addr_space
36 .find_free_range(layout::USER_MMAP_BASE, layout::USER_STACK_TOP, size)
37 .ok_or(MmError::OutOfMemory)?
38 }
39 };
40
41 Vmm::lazy_map_region(addr_space, virt, size, flags | VmaFlags::USER)?;
42
43 Ok(virt)
44}
45
46pub unsafe fn free(
53 addr_space: &mut AddressSpace,
54 virt: VirtAddr
55) -> MmResult<()> {
56 let mut pmm = unsafe { KSTATE.mm.pmm().lock() };
58 unsafe { Vmm::unmap_region(&mut pmm, addr_space, virt)? };
59 Ok(())
60}
61
62pub unsafe fn remap_user_mem(
68 addr_space: &mut AddressSpace,
69 virt: VirtAddr,
70 new_flags: VmaFlags
71) -> MmResult<()> {
72 unsafe { Vmm::remap_region(addr_space, virt, new_flags | VmaFlags::USER)? };
73 Ok(())
74}