Skip to content

Commit e9a9ea0

Browse files
committed
feat(mapper): make PhysOffset public
1 parent 77715a6 commit e9a9ea0

3 files changed

Lines changed: 35 additions & 7 deletions

File tree

src/structures/paging/mapper/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
pub use self::mapped_page_table::{MappedPageTable, PageTableFrameMapping};
44
#[cfg(target_pointer_width = "64")]
5-
pub use self::offset_page_table::OffsetPageTable;
5+
pub use self::offset_page_table::{OffsetPageTable, PhysOffset};
66
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
77
pub use self::recursive_page_table::{InvalidPageTable, RecursivePageTable};
88

src/structures/paging/mapper/offset_page_table.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl<'a> OffsetPageTable<'a> {
2727
/// by writing to an illegal memory location.
2828
#[inline]
2929
pub unsafe fn new(level_4_table: &'a mut PageTable, phys_offset: VirtAddr) -> Self {
30-
let phys_offset = PhysOffset { phys_offset };
30+
let phys_offset = unsafe { PhysOffset::new(phys_offset) };
3131
Self {
3232
inner: unsafe { MappedPageTable::new(level_4_table, phys_offset) },
3333
}
@@ -45,15 +45,43 @@ impl<'a> OffsetPageTable<'a> {
4545

4646
/// Returns the offset used for converting virtual to physical addresses.
4747
pub fn phys_offset(&self) -> VirtAddr {
48-
self.inner.page_table_frame_mapping().phys_offset
48+
self.inner.page_table_frame_mapping().phys_offset()
4949
}
5050
}
5151

52+
/// A [`PageTableFrameMapping`] implementation that requires that the complete physical memory is mapped at some
53+
/// offset in the virtual address space.
5254
#[derive(Debug)]
53-
struct PhysOffset {
55+
pub struct PhysOffset {
5456
phys_offset: VirtAddr,
5557
}
5658

59+
impl PhysOffset {
60+
/// Creates a new `PhysOffset` that uses the given offset for converting virtual
61+
/// to physical addresses.
62+
///
63+
/// The complete physical memory must be mapped in the virtual address space starting at
64+
/// address `phys_offset`. This means that for example physical address `0x5000` can be
65+
/// accessed through virtual address `phys_offset + 0x5000`. This mapping is required because
66+
/// the mapper needs to access page tables, which are not mapped into the virtual address
67+
/// space by default.
68+
///
69+
/// ## Safety
70+
///
71+
/// This function is unsafe because the caller must guarantee that the passed `phys_offset`
72+
/// is correct. Otherwise this function might break memory safety, e.g. by writing to an
73+
/// illegal memory location.
74+
#[inline]
75+
pub unsafe fn new(phys_offset: VirtAddr) -> Self {
76+
Self { phys_offset }
77+
}
78+
79+
/// Returns the offset used for converting virtual to physical addresses.
80+
pub fn phys_offset(&self) -> VirtAddr {
81+
self.phys_offset
82+
}
83+
}
84+
5785
unsafe impl PageTableFrameMapping for PhysOffset {
5886
fn frame_to_pointer(&self, frame: PhysFrame) -> *mut PageTable {
5987
let virt = self.phys_offset + frame.start_address().as_u64();

src/structures/paging/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ pub use self::frame::PhysFrame;
66
pub use self::frame_alloc::{FrameAllocator, FrameDeallocator};
77
#[doc(no_inline)]
88
pub use self::mapper::MappedPageTable;
9-
#[cfg(target_pointer_width = "64")]
10-
#[doc(no_inline)]
11-
pub use self::mapper::OffsetPageTable;
129
#[cfg(all(feature = "instructions", target_arch = "x86_64"))]
1310
#[doc(no_inline)]
1411
pub use self::mapper::RecursivePageTable;
1512
pub use self::mapper::{Mapper, Translate};
13+
#[cfg(target_pointer_width = "64")]
14+
#[doc(no_inline)]
15+
pub use self::mapper::{OffsetPageTable, PhysOffset};
1616
pub use self::page::{Page, PageSize, Size1GiB, Size2MiB, Size4KiB};
1717
pub use self::page_table::{PageOffset, PageTable, PageTableFlags, PageTableIndex};
1818

0 commit comments

Comments
 (0)