x86_64/structures/paging/mapper/
offset_page_table.rs1#![cfg(target_pointer_width = "64")]
2
3use crate::structures::paging::{mapper::*, page_table::PageTable};
4
5#[derive(Debug)]
8pub struct OffsetPageTable<'a> {
9 inner: MappedPageTable<'a, PhysOffset>,
10}
11
12impl<'a> OffsetPageTable<'a> {
13 #[inline]
29 pub unsafe fn new(level_4_table: &'a mut PageTable, phys_offset: VirtAddr) -> Self {
30 let phys_offset = PhysOffset {
31 offset: phys_offset,
32 };
33 Self {
34 inner: unsafe { MappedPageTable::new(level_4_table, phys_offset) },
35 }
36 }
37
38 pub fn level_4_table(&self) -> &PageTable {
40 self.inner.level_4_table()
41 }
42
43 pub fn level_4_table_mut(&mut self) -> &mut PageTable {
45 self.inner.level_4_table_mut()
46 }
47
48 pub fn phys_offset(&self) -> VirtAddr {
50 self.inner.page_table_frame_mapping().offset
51 }
52}
53
54#[derive(Debug)]
55struct PhysOffset {
56 offset: VirtAddr,
57}
58
59unsafe impl PageTableFrameMapping for PhysOffset {
60 fn frame_to_pointer(&self, frame: PhysFrame) -> *mut PageTable {
61 let virt = self.offset + frame.start_address().as_u64();
62 virt.as_mut_ptr()
63 }
64}
65
66impl Mapper<Size1GiB> for OffsetPageTable<'_> {
69 #[inline]
70 unsafe fn map_to_with_table_flags<A>(
71 &mut self,
72 page: Page<Size1GiB>,
73 frame: PhysFrame<Size1GiB>,
74 flags: PageTableFlags,
75 parent_table_flags: PageTableFlags,
76 allocator: &mut A,
77 ) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>
78 where
79 A: FrameAllocator<Size4KiB> + ?Sized,
80 {
81 unsafe {
82 self.inner
83 .map_to_with_table_flags(page, frame, flags, parent_table_flags, allocator)
84 }
85 }
86
87 #[inline]
88 fn unmap(
89 &mut self,
90 page: Page<Size1GiB>,
91 ) -> Result<(PhysFrame<Size1GiB>, MapperFlush<Size1GiB>), UnmapError> {
92 self.inner.unmap(page)
93 }
94
95 #[inline]
96 unsafe fn update_flags(
97 &mut self,
98 page: Page<Size1GiB>,
99 flags: PageTableFlags,
100 ) -> Result<MapperFlush<Size1GiB>, FlagUpdateError> {
101 unsafe { self.inner.update_flags(page, flags) }
102 }
103
104 #[inline]
105 unsafe fn set_flags_p4_entry(
106 &mut self,
107 page: Page<Size1GiB>,
108 flags: PageTableFlags,
109 ) -> Result<MapperFlushAll, FlagUpdateError> {
110 unsafe { self.inner.set_flags_p4_entry(page, flags) }
111 }
112
113 #[inline]
114 unsafe fn set_flags_p3_entry(
115 &mut self,
116 page: Page<Size1GiB>,
117 flags: PageTableFlags,
118 ) -> Result<MapperFlushAll, FlagUpdateError> {
119 unsafe { self.inner.set_flags_p3_entry(page, flags) }
120 }
121
122 #[inline]
123 unsafe fn set_flags_p2_entry(
124 &mut self,
125 page: Page<Size1GiB>,
126 flags: PageTableFlags,
127 ) -> Result<MapperFlushAll, FlagUpdateError> {
128 unsafe { self.inner.set_flags_p2_entry(page, flags) }
129 }
130
131 #[inline]
132 fn translate_page(&self, page: Page<Size1GiB>) -> Result<PhysFrame<Size1GiB>, TranslateError> {
133 self.inner.translate_page(page)
134 }
135}
136
137impl Mapper<Size2MiB> for OffsetPageTable<'_> {
138 #[inline]
139 unsafe fn map_to_with_table_flags<A>(
140 &mut self,
141 page: Page<Size2MiB>,
142 frame: PhysFrame<Size2MiB>,
143 flags: PageTableFlags,
144 parent_table_flags: PageTableFlags,
145 allocator: &mut A,
146 ) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>
147 where
148 A: FrameAllocator<Size4KiB> + ?Sized,
149 {
150 unsafe {
151 self.inner
152 .map_to_with_table_flags(page, frame, flags, parent_table_flags, allocator)
153 }
154 }
155
156 #[inline]
157 fn unmap(
158 &mut self,
159 page: Page<Size2MiB>,
160 ) -> Result<(PhysFrame<Size2MiB>, MapperFlush<Size2MiB>), UnmapError> {
161 self.inner.unmap(page)
162 }
163
164 #[inline]
165 unsafe fn update_flags(
166 &mut self,
167 page: Page<Size2MiB>,
168 flags: PageTableFlags,
169 ) -> Result<MapperFlush<Size2MiB>, FlagUpdateError> {
170 unsafe { self.inner.update_flags(page, flags) }
171 }
172
173 #[inline]
174 unsafe fn set_flags_p4_entry(
175 &mut self,
176 page: Page<Size2MiB>,
177 flags: PageTableFlags,
178 ) -> Result<MapperFlushAll, FlagUpdateError> {
179 unsafe { self.inner.set_flags_p4_entry(page, flags) }
180 }
181
182 #[inline]
183 unsafe fn set_flags_p3_entry(
184 &mut self,
185 page: Page<Size2MiB>,
186 flags: PageTableFlags,
187 ) -> Result<MapperFlushAll, FlagUpdateError> {
188 unsafe { self.inner.set_flags_p3_entry(page, flags) }
189 }
190
191 #[inline]
192 unsafe fn set_flags_p2_entry(
193 &mut self,
194 page: Page<Size2MiB>,
195 flags: PageTableFlags,
196 ) -> Result<MapperFlushAll, FlagUpdateError> {
197 unsafe { self.inner.set_flags_p2_entry(page, flags) }
198 }
199
200 #[inline]
201 fn translate_page(&self, page: Page<Size2MiB>) -> Result<PhysFrame<Size2MiB>, TranslateError> {
202 self.inner.translate_page(page)
203 }
204}
205
206impl Mapper<Size4KiB> for OffsetPageTable<'_> {
207 #[inline]
208 unsafe fn map_to_with_table_flags<A>(
209 &mut self,
210 page: Page<Size4KiB>,
211 frame: PhysFrame<Size4KiB>,
212 flags: PageTableFlags,
213 parent_table_flags: PageTableFlags,
214 allocator: &mut A,
215 ) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>
216 where
217 A: FrameAllocator<Size4KiB> + ?Sized,
218 {
219 unsafe {
220 self.inner
221 .map_to_with_table_flags(page, frame, flags, parent_table_flags, allocator)
222 }
223 }
224
225 #[inline]
226 fn unmap(
227 &mut self,
228 page: Page<Size4KiB>,
229 ) -> Result<(PhysFrame<Size4KiB>, MapperFlush<Size4KiB>), UnmapError> {
230 self.inner.unmap(page)
231 }
232
233 #[inline]
234 unsafe fn update_flags(
235 &mut self,
236 page: Page<Size4KiB>,
237 flags: PageTableFlags,
238 ) -> Result<MapperFlush<Size4KiB>, FlagUpdateError> {
239 unsafe { self.inner.update_flags(page, flags) }
240 }
241
242 #[inline]
243 unsafe fn set_flags_p4_entry(
244 &mut self,
245 page: Page<Size4KiB>,
246 flags: PageTableFlags,
247 ) -> Result<MapperFlushAll, FlagUpdateError> {
248 unsafe { self.inner.set_flags_p4_entry(page, flags) }
249 }
250
251 #[inline]
252 unsafe fn set_flags_p3_entry(
253 &mut self,
254 page: Page<Size4KiB>,
255 flags: PageTableFlags,
256 ) -> Result<MapperFlushAll, FlagUpdateError> {
257 unsafe { self.inner.set_flags_p3_entry(page, flags) }
258 }
259
260 #[inline]
261 unsafe fn set_flags_p2_entry(
262 &mut self,
263 page: Page<Size4KiB>,
264 flags: PageTableFlags,
265 ) -> Result<MapperFlushAll, FlagUpdateError> {
266 unsafe { self.inner.set_flags_p2_entry(page, flags) }
267 }
268
269 #[inline]
270 fn translate_page(&self, page: Page<Size4KiB>) -> Result<PhysFrame<Size4KiB>, TranslateError> {
271 self.inner.translate_page(page)
272 }
273}
274
275impl Translate for OffsetPageTable<'_> {
276 #[inline]
277 fn translate(&self, addr: VirtAddr) -> TranslateResult {
278 self.inner.translate(addr)
279 }
280}
281
282impl CleanUp for OffsetPageTable<'_> {
283 #[inline]
284 unsafe fn clean_up<D>(&mut self, frame_deallocator: &mut D)
285 where
286 D: FrameDeallocator<Size4KiB>,
287 {
288 unsafe { self.inner.clean_up(frame_deallocator) }
289 }
290
291 #[inline]
292 unsafe fn clean_up_addr_range<D>(
293 &mut self,
294 range: PageRangeInclusive,
295 frame_deallocator: &mut D,
296 ) where
297 D: FrameDeallocator<Size4KiB>,
298 {
299 unsafe { self.inner.clean_up_addr_range(range, frame_deallocator) }
300 }
301}