hermit/mm/
mapped_page_box.rs1use core::alloc::AllocError;
2
3use free_list::{PageLayout, PageRange};
4use memory_addresses::{PhysAddr, VirtAddr};
5
6use crate::arch::mm::paging::{self, BasePageSize, PageSize, PageTableEntryFlags};
7use crate::mm::{FrameBox, PageBox};
8
9pub struct MappedPageBox {
11 _frames: Option<FrameBox>,
12 pages: PageBox,
13}
14
15impl MappedPageBox {
16 pub fn new(layout: PageLayout, flags: PageTableEntryFlags) -> Result<Self, AllocError> {
18 let frames = FrameBox::new(layout)?;
19 let pages = PageBox::new(layout)?;
20 let page_count = pages.len().get() / BasePageSize::SIZE as usize;
21 paging::map::<BasePageSize>(
22 VirtAddr::from(pages.start()),
23 PhysAddr::from(frames.start()),
24 page_count,
25 flags,
26 );
27
28 Ok(Self {
29 _frames: Some(frames),
30 pages,
31 })
32 }
33
34 pub unsafe fn map_phys(
40 phys_addr: PhysAddr,
41 layout: PageLayout,
42 flags: PageTableEntryFlags,
43 ) -> Result<Self, AllocError> {
44 let pages = PageBox::new(layout)?;
45 let page_count = pages.len().get() / BasePageSize::SIZE as usize;
46 paging::map::<BasePageSize>(VirtAddr::from(pages.start()), phys_addr, page_count, flags);
47
48 Ok(Self {
49 _frames: None,
50 pages,
51 })
52 }
53
54 pub fn pages(&self) -> &PageRange {
55 &self.pages
56 }
57}
58
59impl Drop for MappedPageBox {
60 fn drop(&mut self) {
61 let page_count = self.pages.len().get() / BasePageSize::SIZE as usize;
62 paging::unmap::<BasePageSize>(VirtAddr::from(self.pages.start()), page_count);
63 }
64}