11#![ cfg( target_pointer_width = "64" ) ]
22
3- use crate :: structures:: paging:: { mapper:: * , page_table :: PageTable } ;
3+ use crate :: structures:: paging:: { mapper:: * , PageTable } ;
44
55/// A Mapper implementation that requires that the complete physical memory is mapped at some
66/// offset in the virtual address space.
7- #[ derive( Debug ) ]
8- pub struct OffsetPageTable < ' a > {
9- inner : MappedPageTable < ' a , PhysOffset > ,
10- }
7+ pub type OffsetPageTable < ' a > = MappedPageTable < ' a , PhysOffset > ;
118
129impl < ' a > OffsetPageTable < ' a > {
1310 /// Creates a new `OffsetPageTable` that uses the given offset for converting virtual
@@ -26,291 +23,56 @@ impl<'a> OffsetPageTable<'a> {
2623 /// of a valid page table hierarchy. Otherwise this function might break memory safety, e.g.
2724 /// by writing to an illegal memory location.
2825 #[ 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- /// Returns an immutable reference to the wrapped level 4 `PageTable` instance.
39- pub fn level_4_table ( & self ) -> & PageTable {
40- self . inner . level_4_table ( )
41- }
42-
43- /// Returns a mutable reference to the wrapped level 4 `PageTable` instance.
44- pub fn level_4_table_mut ( & mut self ) -> & mut PageTable {
45- self . inner . level_4_table_mut ( )
26+ pub unsafe fn from_phys_offset (
27+ level_4_table : & ' a mut PageTable ,
28+ phys_offset : VirtAddr ,
29+ ) -> Self {
30+ let phys_offset = unsafe { PhysOffset :: new ( phys_offset) } ;
31+ unsafe { MappedPageTable :: new ( level_4_table, phys_offset) }
4632 }
4733
4834 /// Returns the offset used for converting virtual to physical addresses.
4935 pub fn phys_offset ( & self ) -> VirtAddr {
50- self . inner . page_table_frame_mapping ( ) . offset
36+ self . page_table_frame_mapping ( ) . phys_offset ( )
5137 }
5238}
5339
40+ /// A [`PageTableFrameMapping`] implementation that requires that the complete physical memory is mapped at some
41+ /// offset in the virtual address space.
5442#[ derive( Debug ) ]
55- struct PhysOffset {
56- offset : VirtAddr ,
57- }
58-
59- unsafe 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-
66- // delegate all trait implementations to inner
67-
68- impl 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 > , PageTableFlags , MapperFlush < Size1GiB > ) , UnmapError > {
92- self . inner . unmap ( page)
93- }
94-
95- #[ inline]
96- fn clear ( & mut self , page : Page < Size1GiB > ) -> Result < UnmappedFrame < Size1GiB > , UnmapError > {
97- self . inner . clear ( page)
98- }
99-
100- #[ inline]
101- unsafe fn update_flags (
102- & mut self ,
103- page : Page < Size1GiB > ,
104- flags : PageTableFlags ,
105- ) -> Result < MapperFlush < Size1GiB > , FlagUpdateError > {
106- unsafe { self . inner . update_flags ( page, flags) }
107- }
108-
109- #[ inline]
110- unsafe fn set_flags_p4_entry (
111- & mut self ,
112- page : Page < Size1GiB > ,
113- flags : PageTableFlags ,
114- ) -> Result < MapperFlushAll , FlagUpdateError > {
115- unsafe { self . inner . set_flags_p4_entry ( page, flags) }
116- }
117-
118- #[ inline]
119- unsafe fn set_flags_p3_entry (
120- & mut self ,
121- page : Page < Size1GiB > ,
122- flags : PageTableFlags ,
123- ) -> Result < MapperFlushAll , FlagUpdateError > {
124- unsafe { self . inner . set_flags_p3_entry ( page, flags) }
125- }
126-
127- #[ inline]
128- unsafe fn set_flags_p2_entry (
129- & mut self ,
130- page : Page < Size1GiB > ,
131- flags : PageTableFlags ,
132- ) -> Result < MapperFlushAll , FlagUpdateError > {
133- unsafe { self . inner . set_flags_p2_entry ( page, flags) }
134- }
135-
136- #[ inline]
137- fn translate_page ( & self , page : Page < Size1GiB > ) -> Result < PhysFrame < Size1GiB > , TranslateError > {
138- self . inner . translate_page ( page)
139- }
43+ pub struct PhysOffset {
44+ phys_offset : VirtAddr ,
14045}
14146
142- impl Mapper < Size2MiB > for OffsetPageTable < ' _ > {
143- #[ inline]
144- unsafe fn map_to_with_table_flags < A > (
145- & mut self ,
146- page : Page < Size2MiB > ,
147- frame : PhysFrame < Size2MiB > ,
148- flags : PageTableFlags ,
149- parent_table_flags : PageTableFlags ,
150- allocator : & mut A ,
151- ) -> Result < MapperFlush < Size2MiB > , MapToError < Size2MiB > >
152- where
153- A : FrameAllocator < Size4KiB > + ?Sized ,
154- {
155- unsafe {
156- self . inner
157- . map_to_with_table_flags ( page, frame, flags, parent_table_flags, allocator)
158- }
159- }
160-
161- #[ inline]
162- fn unmap (
163- & mut self ,
164- page : Page < Size2MiB > ,
165- ) -> Result < ( PhysFrame < Size2MiB > , PageTableFlags , MapperFlush < Size2MiB > ) , UnmapError > {
166- self . inner . unmap ( page)
167- }
168-
169- #[ inline]
170- fn clear ( & mut self , page : Page < Size2MiB > ) -> Result < UnmappedFrame < Size2MiB > , UnmapError > {
171- self . inner . clear ( page)
172- }
173-
174- #[ inline]
175- unsafe fn update_flags (
176- & mut self ,
177- page : Page < Size2MiB > ,
178- flags : PageTableFlags ,
179- ) -> Result < MapperFlush < Size2MiB > , FlagUpdateError > {
180- unsafe { self . inner . update_flags ( page, flags) }
181- }
182-
183- #[ inline]
184- unsafe fn set_flags_p4_entry (
185- & mut self ,
186- page : Page < Size2MiB > ,
187- flags : PageTableFlags ,
188- ) -> Result < MapperFlushAll , FlagUpdateError > {
189- unsafe { self . inner . set_flags_p4_entry ( page, flags) }
190- }
191-
192- #[ inline]
193- unsafe fn set_flags_p3_entry (
194- & mut self ,
195- page : Page < Size2MiB > ,
196- flags : PageTableFlags ,
197- ) -> Result < MapperFlushAll , FlagUpdateError > {
198- unsafe { self . inner . set_flags_p3_entry ( page, flags) }
199- }
200-
201- #[ inline]
202- unsafe fn set_flags_p2_entry (
203- & mut self ,
204- page : Page < Size2MiB > ,
205- flags : PageTableFlags ,
206- ) -> Result < MapperFlushAll , FlagUpdateError > {
207- unsafe { self . inner . set_flags_p2_entry ( page, flags) }
208- }
209-
210- #[ inline]
211- fn translate_page ( & self , page : Page < Size2MiB > ) -> Result < PhysFrame < Size2MiB > , TranslateError > {
212- self . inner . translate_page ( page)
213- }
214- }
215-
216- impl Mapper < Size4KiB > for OffsetPageTable < ' _ > {
217- #[ inline]
218- unsafe fn map_to_with_table_flags < A > (
219- & mut self ,
220- page : Page < Size4KiB > ,
221- frame : PhysFrame < Size4KiB > ,
222- flags : PageTableFlags ,
223- parent_table_flags : PageTableFlags ,
224- allocator : & mut A ,
225- ) -> Result < MapperFlush < Size4KiB > , MapToError < Size4KiB > >
226- where
227- A : FrameAllocator < Size4KiB > + ?Sized ,
228- {
229- unsafe {
230- self . inner
231- . map_to_with_table_flags ( page, frame, flags, parent_table_flags, allocator)
232- }
233- }
234-
235- #[ inline]
236- fn unmap (
237- & mut self ,
238- page : Page < Size4KiB > ,
239- ) -> Result < ( PhysFrame < Size4KiB > , PageTableFlags , MapperFlush < Size4KiB > ) , UnmapError > {
240- self . inner . unmap ( page)
241- }
242-
243- #[ inline]
244- fn clear ( & mut self , page : Page < Size4KiB > ) -> Result < UnmappedFrame < Size4KiB > , UnmapError > {
245- self . inner . clear ( page)
246- }
247-
248- #[ inline]
249- unsafe fn update_flags (
250- & mut self ,
251- page : Page < Size4KiB > ,
252- flags : PageTableFlags ,
253- ) -> Result < MapperFlush < Size4KiB > , FlagUpdateError > {
254- unsafe { self . inner . update_flags ( page, flags) }
255- }
256-
257- #[ inline]
258- unsafe fn set_flags_p4_entry (
259- & mut self ,
260- page : Page < Size4KiB > ,
261- flags : PageTableFlags ,
262- ) -> Result < MapperFlushAll , FlagUpdateError > {
263- unsafe { self . inner . set_flags_p4_entry ( page, flags) }
264- }
265-
266- #[ inline]
267- unsafe fn set_flags_p3_entry (
268- & mut self ,
269- page : Page < Size4KiB > ,
270- flags : PageTableFlags ,
271- ) -> Result < MapperFlushAll , FlagUpdateError > {
272- unsafe { self . inner . set_flags_p3_entry ( page, flags) }
273- }
274-
275- #[ inline]
276- unsafe fn set_flags_p2_entry (
277- & mut self ,
278- page : Page < Size4KiB > ,
279- flags : PageTableFlags ,
280- ) -> Result < MapperFlushAll , FlagUpdateError > {
281- unsafe { self . inner . set_flags_p2_entry ( page, flags) }
282- }
283-
47+ impl PhysOffset {
48+ /// Creates a new `PhysOffset` that uses the given offset for converting virtual
49+ /// to physical addresses.
50+ ///
51+ /// The complete physical memory must be mapped in the virtual address space starting at
52+ /// address `phys_offset`. This means that for example physical address `0x5000` can be
53+ /// accessed through virtual address `phys_offset + 0x5000`. This mapping is required because
54+ /// the mapper needs to access page tables, which are not mapped into the virtual address
55+ /// space by default.
56+ ///
57+ /// ## Safety
58+ ///
59+ /// This function is unsafe because the caller must guarantee that the passed `phys_offset`
60+ /// is correct. Otherwise this function might break memory safety, e.g. by writing to an
61+ /// illegal memory location.
28462 #[ inline]
285- fn translate_page ( & self , page : Page < Size4KiB > ) -> Result < PhysFrame < Size4KiB > , TranslateError > {
286- self . inner . translate_page ( page )
63+ pub unsafe fn new ( phys_offset : VirtAddr ) -> Self {
64+ Self { phys_offset }
28765 }
288- }
28966
290- impl Translate for OffsetPageTable < ' _ > {
291- #[ inline]
292- fn translate ( & self , addr : VirtAddr ) -> TranslateResult {
293- self . inner . translate ( addr)
67+ /// Returns the offset used for converting virtual to physical addresses.
68+ pub fn phys_offset ( & self ) -> VirtAddr {
69+ self . phys_offset
29470 }
29571}
29672
297- impl CleanUp for OffsetPageTable < ' _ > {
298- #[ inline]
299- unsafe fn clean_up < D > ( & mut self , frame_deallocator : & mut D )
300- where
301- D : FrameDeallocator < Size4KiB > ,
302- {
303- unsafe { self . inner . clean_up ( frame_deallocator) }
304- }
305-
306- #[ inline]
307- unsafe fn clean_up_addr_range < D > (
308- & mut self ,
309- range : PageRangeInclusive ,
310- frame_deallocator : & mut D ,
311- ) where
312- D : FrameDeallocator < Size4KiB > ,
313- {
314- unsafe { self . inner . clean_up_addr_range ( range, frame_deallocator) }
73+ unsafe impl PageTableFrameMapping for PhysOffset {
74+ fn frame_to_pointer ( & self , frame : PhysFrame ) -> * mut PageTable {
75+ let virt = self . phys_offset + frame. start_address ( ) . as_u64 ( ) ;
76+ virt. as_mut_ptr ( )
31577 }
31678}
0 commit comments