page_walker/walkers/
allocator.rs1use core::marker::PhantomData;
5use core::ops::Range;
6use crate::address_space::PageTableMapper;
7use crate::PageFormat;
8use num_traits::{FromPrimitive, PrimInt, Unsigned};
9
10pub struct PteAllocator<'a, PTE, Mapper, Error>
16where
17 PTE: FromPrimitive + PrimInt + Unsigned,
18 Mapper: PageTableMapper<PTE, Error>,
19{
20 pub mapper: &'a mut Mapper,
22 pub format: &'a PageFormat<'a, PTE>,
24 pub mask: Option<PTE>,
26 pub error: PhantomData<Error>,
28}
29
30impl<'a, PTE, Mapper, Error> crate::PageWalkerMut<PTE, Error> for PteAllocator<'a, PTE, Mapper, Error>
31where
32 PTE: FromPrimitive + PrimInt + Unsigned,
33 Mapper: PageTableMapper<PTE, Error>,
34{
35 fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error> {
37 self.mapper.read_pte(phys_addr)
38 }
39
40 fn write_pte(&mut self, phys_addr: PTE, value: PTE) -> Result<(), Error> {
42 self.mapper.write_pte(phys_addr, value)
43 }
44
45 fn handle_pte_hole(&mut self, index: usize, _range: Range<usize>, pte: &mut PTE) -> Result<(), Error> {
48 let level = &self.format.levels[index];
49
50 match index {
51 0 => {
52 if let Some(mask) = self.mask {
53 let page = self.mapper.alloc_page()?;
54
55 *pte = page | level.present_bit.1 | mask;
57 }
58 }
59 _ => {
60 let page_table = self.mapper.alloc_page()?;
61
62 *pte = page_table | level.present_bit.1 | level.page_table_mask |
65 ((level.huge_page_bit.0 ^ level.huge_page_bit.1) & level.huge_page_bit.0);
66 }
67 }
68
69 Ok(())
70 }
71}