1use core::marker::PhantomData;
5use core::ops::Range;
6use crate::PageFormat;
7use crate::walkers::*;
8use num_traits::{FromPrimitive, PrimInt, Unsigned};
9
10pub trait PageTableMapper<PTE, Error>
13where
14 PTE: FromPrimitive + PrimInt + Unsigned,
15{
16 const PTE_NOT_FOUND: Error;
18
19 const PAGE_NOT_PRESENT: Error;
21
22 const NOT_IMPLEMENTED: Error;
24
25 fn read_pte(&self, phys_addr: PTE) -> Result<PTE, Error>;
27
28 fn write_pte(&mut self, phys_addr: PTE, value: PTE) -> Result<(), Error>;
30
31 fn read_bytes(&self, _bytes: &mut [u8], _phys_addr: PTE) -> Result<usize, Error> {
33 Err(Self::NOT_IMPLEMENTED)
34 }
35
36 fn write_bytes(&mut self, _phys_addr: PTE, _bytes: &[u8]) -> Result<usize, Error> {
38 Err(Self::NOT_IMPLEMENTED)
39 }
40
41 fn alloc_page(&mut self) -> Result<PTE, Error> {
43 Err(Self::NOT_IMPLEMENTED)
44 }
45
46 fn free_page(&mut self, _pte: PTE) {
48 }
49}
50
51pub struct AddressSpace<'a, PTE, Mapper, Error>
53where
54 PTE: FromPrimitive + PrimInt + Unsigned,
55 Mapper: PageTableMapper<PTE, Error>,
56{
57 format: PageFormat<'a, PTE>,
59
60 root: PTE,
62
63 mapper: &'a mut Mapper,
65
66 error: core::marker::PhantomData<Error>,
68}
69
70impl<'a, PTE, Mapper, Error> AddressSpace<'a, PTE, Mapper, Error>
71where
72 PTE: FromPrimitive + PrimInt + Unsigned,
73 Mapper: PageTableMapper<PTE, Error>,
74{
75 pub fn new(format: PageFormat<'a, PTE>, mapper: &'a mut Mapper, root: PTE) -> Self {
79 Self {
80 format,
81 mapper,
82 root,
83 error: PhantomData,
84 }
85 }
86
87 pub fn read_pte(&self, virt_addr: usize) -> Result<PTE, Error> {
89 let mut walker = PteReader {
90 mapper: self.mapper,
91 pte: None,
92 error: PhantomData,
93 };
94
95 self.format.walk(self.root, virt_addr..virt_addr + 1, &mut walker)?;
96
97 match walker.pte {
98 Some(pte) => Ok(pte),
99 _ => Err(Mapper::PTE_NOT_FOUND),
100 }
101 }
102
103 pub fn write_pte(&mut self, virt_addr: usize, pte: PTE) -> Result<(), Error> {
105 let mut walker = PteWriter {
106 mapper: self.mapper,
107 pte,
108 error: PhantomData,
109 };
110
111 self.format.walk_mut(self.root, virt_addr..virt_addr + 1, &mut walker)?;
112
113 Ok(())
114 }
115
116 pub fn allocate_range(&mut self, range: Range<usize>, mask: PTE) -> Result<(), Error> {
119 let mut walker = PteAllocator {
120 mapper: self.mapper,
121 mask: Some(mask),
122 format: &self.format,
123 error: PhantomData,
124 };
125
126 self.format.walk_mut(self.root, range, &mut walker)?;
127
128 Ok(())
129 }
130
131 pub fn map_range(&mut self, range: Range<usize>, mask: PTE) -> Result<(), Error> {
135 let mut walker = PteMapper {
136 mapper: self.mapper,
137 mask,
138 format: &self.format,
139 error: PhantomData,
140 };
141
142 self.format.walk_mut(self.root, range, &mut walker)?;
143
144 Ok(())
145 }
146
147 pub fn protect_range(&mut self, range: Range<usize>, mask: (PTE, PTE)) -> Result<(), Error> {
151 let mut walker = PteProtector {
152 mapper: self.mapper,
153 mask,
154 format: &self.format,
155 error: PhantomData,
156 };
157
158 self.format.walk_mut(self.root, range, &mut walker)?;
159
160 Ok(())
161 }
162
163 pub fn free_range(&mut self, range: Range<usize>) -> Result<(), Error> {
166 let flags = PteRemovalFlags::all();
167
168 let mut walker = PteRemover {
169 mapper: self.mapper,
170 flags,
171 format: &self.format,
172 error: PhantomData,
173 };
174
175 self.format.walk_mut(self.root, range, &mut walker)?;
176
177 Ok(())
178 }
179
180 pub fn unmap_range(&mut self, range: Range<usize>) -> Result<(), Error> {
183 let flags = PteRemovalFlags::empty();
184
185 let mut walker = PteRemover {
186 mapper: self.mapper,
187 flags,
188 format: &self.format,
189 error: PhantomData,
190 };
191
192 self.format.walk_mut(self.root, range, &mut walker)?;
193
194 Ok(())
195 }
196
197 pub fn copy_from(&mut self, data: &mut [u8], address: usize) -> Result<(), Error> {
199 let range = address..address + data.len();
200
201 let mut walker = CopyFromWalker {
202 mapper: self.mapper,
203 offset: 0,
204 data,
205 format: &self.format,
206 error: PhantomData,
207 };
208
209 self.format.walk(self.root, range, &mut walker)?;
210
211 Ok(())
212 }
213
214 pub fn copy_to(&mut self, address: usize, data: &[u8]) -> Result<(), Error> {
216 let range = address..address + data.len();
217
218 let mut walker = CopyToWalker {
219 mapper: self.mapper,
220 offset: 0,
221 data,
222 format: &self.format,
223 error: PhantomData,
224 };
225
226 self.format.walk(self.root, range, &mut walker)?;
227
228 Ok(())
229 }
230}