@@ -17,9 +17,13 @@ mod offset_page_table;
17
17
#[ cfg( feature = "instructions" ) ]
18
18
mod recursive_page_table;
19
19
20
- /// This trait defines page table operations that work for all page sizes of the x86_64
21
- /// architecture.
22
- pub trait MapperAllSizes : Mapper < Size4KiB > + Mapper < Size2MiB > + Mapper < Size1GiB > {
20
+ /// An empty convencience trait that requires the `Mapper` trait for all page sizes.
21
+ pub trait MapperAllSizes : Mapper < Size4KiB > + Mapper < Size2MiB > + Mapper < Size1GiB > { }
22
+
23
+ impl < T > MapperAllSizes for T where T : Mapper < Size4KiB > + Mapper < Size2MiB > + Mapper < Size1GiB > { }
24
+
25
+ /// Provides methods for translating virtual addresses.
26
+ pub trait Translate {
23
27
/// Return the frame that the given virtual address is mapped to and the offset within that
24
28
/// frame.
25
29
///
@@ -38,14 +42,8 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
38
42
#[ inline]
39
43
fn translate_addr ( & self , addr : VirtAddr ) -> Option < PhysAddr > {
40
44
match self . translate ( addr) {
41
- TranslateResult :: PageNotMapped | TranslateResult :: InvalidFrameAddress ( _) => None ,
42
- TranslateResult :: Frame4KiB { frame, offset, .. } => {
43
- Some ( frame. start_address ( ) + offset)
44
- }
45
- TranslateResult :: Frame2MiB { frame, offset, .. } => {
46
- Some ( frame. start_address ( ) + offset)
47
- }
48
- TranslateResult :: Frame1GiB { frame, offset, .. } => {
45
+ TranslateResult :: NotMapped | TranslateResult :: InvalidFrameAddress ( _) => None ,
46
+ TranslateResult :: Mapped { frame, offset, .. } => {
49
47
Some ( frame. start_address ( ) + offset)
50
48
}
51
49
}
@@ -58,39 +56,46 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
58
56
/// is returned, depending on the size of the mapped page. The remaining variants indicate errors.
59
57
#[ derive( Debug ) ]
60
58
pub enum TranslateResult {
61
- /// The page is mapped to a physical frame of size 4KiB.
62
- Frame4KiB {
63
- /// The mapped frame.
64
- frame : PhysFrame < Size4KiB > ,
65
- /// The offset whithin the mapped frame.
66
- offset : u64 ,
67
- /// The flags for the frame.
68
- flags : PageTableFlags ,
69
- } ,
70
- /// The page is mapped to a physical frame of size 2MiB.
71
- Frame2MiB {
72
- /// The mapped frame.
73
- frame : PhysFrame < Size2MiB > ,
74
- /// The offset whithin the mapped frame.
75
- offset : u64 ,
76
- /// The flags for the frame.
77
- flags : PageTableFlags ,
78
- } ,
79
- /// The page is mapped to a physical frame of size 2MiB.
80
- Frame1GiB {
59
+ /// The virtual address is mapped to a physical frame.
60
+ Mapped {
81
61
/// The mapped frame.
82
- frame : PhysFrame < Size1GiB > ,
62
+ frame : MappedFrame ,
83
63
/// The offset whithin the mapped frame.
84
64
offset : u64 ,
85
- /// The flags for the frame.
65
+ /// The entry flags in the lowest-level page table.
66
+ ///
67
+ /// Flags of higher-level page table entries are not included here, but they can still
68
+ /// affect the effective flags for an address, for example when the WRITABLE flag is not
69
+ /// set for a level 3 entry.
86
70
flags : PageTableFlags ,
87
71
} ,
88
- /// The given page is not mapped to a physical frame.
89
- PageNotMapped ,
90
- /// The page table entry for the given page points to an invalid physical address.
72
+ /// The given virtual address is not mapped to a physical frame.
73
+ NotMapped ,
74
+ /// The page table entry for the given virtual address points to an invalid physical address.
91
75
InvalidFrameAddress ( PhysAddr ) ,
92
76
}
93
77
78
+ /// Represents a physical frame mapped in a page table.
79
+ #[ derive( Debug ) ]
80
+ pub enum MappedFrame {
81
+ /// The virtual address is mapped to a 4KiB frame.
82
+ Size4KiB ( PhysFrame < Size4KiB > ) ,
83
+ /// The virtual address is mapped to a "large" 2MiB frame.
84
+ Size2MiB ( PhysFrame < Size2MiB > ) ,
85
+ /// The virtual address is mapped to a "huge" 1GiB frame.
86
+ Size1GiB ( PhysFrame < Size1GiB > ) ,
87
+ }
88
+
89
+ impl MappedFrame {
90
+ fn start_address ( & self ) -> PhysAddr {
91
+ match self {
92
+ MappedFrame :: Size4KiB ( frame) => frame. start_address ( ) ,
93
+ MappedFrame :: Size2MiB ( frame) => frame. start_address ( ) ,
94
+ MappedFrame :: Size1GiB ( frame) => frame. start_address ( ) ,
95
+ }
96
+ }
97
+ }
98
+
94
99
/// A trait for common page table operations on pages of size `S`.
95
100
pub trait Mapper < S : PageSize > {
96
101
/// Creates a new mapping in the page table.
@@ -460,4 +465,4 @@ pub enum TranslateError {
460
465
InvalidFrameAddress ( PhysAddr ) ,
461
466
}
462
467
463
- static _ASSERT_OBJECT_SAFE: Option < & ( dyn MapperAllSizes + Sync ) > = None ;
468
+ static _ASSERT_OBJECT_SAFE: Option < & ( dyn Translate + Sync ) > = None ;
0 commit comments