@@ -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
///
@@ -34,63 +38,76 @@ pub trait MapperAllSizes: Mapper<Size4KiB> + Mapper<Size2MiB> + Mapper<Size1GiB>
34
38
/// Returns `None` if there is no valid mapping for the given address.
35
39
///
36
40
/// This is a convenience method. For more information about a mapping see the
37
- /// [`translate`](MapperAllSizes ::translate) method.
41
+ /// [`translate`](Translate ::translate) method.
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, .. } => {
49
- Some ( frame. start_address ( ) + offset)
50
- }
45
+ TranslateResult :: NotMapped | TranslateResult :: InvalidFrameAddress ( _) => None ,
46
+ TranslateResult :: Mapped { frame, offset, .. } => Some ( frame. start_address ( ) + offset) ,
51
47
}
52
48
}
53
49
}
54
50
55
- /// The return value of the [`MapperAllSizes ::translate`] function.
51
+ /// The return value of the [`Translate ::translate`] function.
56
52
///
57
53
/// If the given address has a valid mapping, a `Frame4KiB`, `Frame2MiB`, or `Frame1GiB` variant
58
54
/// is returned, depending on the size of the mapped page. The remaining variants indicate errors.
59
55
#[ derive( Debug ) ]
60
56
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 {
57
+ /// The virtual address is mapped to a physical frame.
58
+ Mapped {
81
59
/// The mapped frame.
82
- frame : PhysFrame < Size1GiB > ,
60
+ frame : MappedFrame ,
83
61
/// The offset whithin the mapped frame.
84
62
offset : u64 ,
85
- /// The flags for the frame.
63
+ /// The entry flags in the lowest-level page table.
64
+ ///
65
+ /// Flags of higher-level page table entries are not included here, but they can still
66
+ /// affect the effective flags for an address, for example when the WRITABLE flag is not
67
+ /// set for a level 3 entry.
86
68
flags : PageTableFlags ,
87
69
} ,
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.
70
+ /// The given virtual address is not mapped to a physical frame.
71
+ NotMapped ,
72
+ /// The page table entry for the given virtual address points to an invalid physical address.
91
73
InvalidFrameAddress ( PhysAddr ) ,
92
74
}
93
75
76
+ /// Represents a physical frame mapped in a page table.
77
+ #[ derive( Debug ) ]
78
+ pub enum MappedFrame {
79
+ /// The virtual address is mapped to a 4KiB frame.
80
+ Size4KiB ( PhysFrame < Size4KiB > ) ,
81
+ /// The virtual address is mapped to a "large" 2MiB frame.
82
+ Size2MiB ( PhysFrame < Size2MiB > ) ,
83
+ /// The virtual address is mapped to a "huge" 1GiB frame.
84
+ Size1GiB ( PhysFrame < Size1GiB > ) ,
85
+ }
86
+
87
+ impl MappedFrame {
88
+ const_fn ! {
89
+ /// Returns the start address of the frame.
90
+ pub 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
+
99
+ const_fn ! {
100
+ /// Returns the size the frame (4KB, 2MB or 1GB).
101
+ pub fn size( & self ) -> u64 {
102
+ match self {
103
+ MappedFrame :: Size4KiB ( frame) => frame. size( ) ,
104
+ MappedFrame :: Size2MiB ( frame) => frame. size( ) ,
105
+ MappedFrame :: Size1GiB ( frame) => frame. size( ) ,
106
+ }
107
+ }
108
+ }
109
+ }
110
+
94
111
/// A trait for common page table operations on pages of size `S`.
95
112
pub trait Mapper < S : PageSize > {
96
113
/// Creates a new mapping in the page table.
@@ -460,4 +477,4 @@ pub enum TranslateError {
460
477
InvalidFrameAddress ( PhysAddr ) ,
461
478
}
462
479
463
- static _ASSERT_OBJECT_SAFE: Option < & ( dyn MapperAllSizes + Sync ) > = None ;
480
+ static _ASSERT_OBJECT_SAFE: Option < & ( dyn Translate + Sync ) > = None ;
0 commit comments