page_walker/walkers/
copy.rs1use core::marker::PhantomData;
4use core::ops::Range;
5use crate::address_space::PageTableMapper;
6use crate::{PageFormat, PteType};
7use num_traits::{FromPrimitive, PrimInt, Unsigned};
8
9pub struct CopyFromWalker<'a, PTE, Mapper, Error>
16where
17 PTE: FromPrimitive + PrimInt + Unsigned,
18 Mapper: PageTableMapper<PTE, Error>,
19{
20 pub mapper: &'a Mapper,
22 pub offset: usize,
24 pub data: &'a mut [u8],
26 pub format: &'a PageFormat<'a, PTE>,
28 pub error: PhantomData<Error>,
30}
31
32impl<'a, PTE, Mapper, Error> crate::PageWalker<PTE, Error> for CopyFromWalker<'a, PTE, Mapper, Error>
33where
34 PTE: FromPrimitive + PrimInt + Unsigned,
35 Mapper: PageTableMapper<PTE, Error>,
36{
37 fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error> {
39 self.mapper.read_pte(phys_addr)
40 }
41
42 fn handle_pte(&mut self, pte_type: PteType, range: Range<usize>, pte: &PTE) -> Result<(), Error> {
44 let level = match pte_type {
45 PteType::Page(level) => level,
46 _ => return Ok(()),
47 };
48
49 let level = &self.format.levels[level];
50
51 if !level.is_present(*pte) {
52 return Err(Mapper::PAGE_NOT_PRESENT);
53 }
54
55 let phys_addr = *pte & self.format.physical_mask;
57
58 let offset = PTE::from_usize(range.start & (level.page_size() - 1)).unwrap();
60
61 let size = (self.data.len() - self.offset).min(level.page_size());
63
64 self.mapper.read_bytes(&mut self.data[self.offset..self.offset + size], phys_addr + offset)?;
66 self.offset += size;
67
68 Ok(())
69 }
70}
71
72pub struct CopyToWalker<'a, PTE, Mapper, Error>
79where
80 PTE: FromPrimitive + PrimInt + Unsigned,
81 Mapper: PageTableMapper<PTE, Error>,
82{
83 pub mapper: &'a mut Mapper,
85 pub offset: usize,
87 pub data: &'a [u8],
89 pub format: &'a PageFormat<'a, PTE>,
91 pub error: PhantomData<Error>,
93}
94
95impl<'a, PTE, Mapper, Error> crate::PageWalker<PTE, Error> for CopyToWalker<'a, PTE, Mapper, Error>
96where
97 PTE: FromPrimitive + PrimInt + Unsigned,
98 Mapper: PageTableMapper<PTE, Error>,
99{
100 fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error> {
102 self.mapper.read_pte(phys_addr)
103 }
104
105 fn handle_pte(&mut self, pte_type: PteType, range: Range<usize>, pte: &PTE) -> Result<(), Error> {
107 let level = match pte_type {
108 PteType::Page(level) => level,
109 _ => return Ok(()),
110 };
111
112 let level = &self.format.levels[level];
113
114 if !level.is_present(*pte) {
115 return Err(Mapper::PAGE_NOT_PRESENT);
116 }
117
118 let phys_addr = *pte & self.format.physical_mask;
120
121 let offset = PTE::from_usize(range.start & (level.page_size() - 1)).unwrap();
123
124 let size = (self.data.len() - self.offset).min(level.page_size());
126
127 self.mapper.write_bytes(phys_addr + offset, &self.data[self.offset..self.offset + size])?;
129 self.offset += size;
130
131 Ok(())
132 }
133}