1
1
//! Types for the Global Descriptor Table and segment selectors.
2
2
3
- use crate :: structures:: tss:: TaskStateSegment ;
3
+ use crate :: structures:: { tss:: TaskStateSegment , DescriptorTablePointer } ;
4
4
use crate :: PrivilegeLevel ;
5
5
use bit_field:: BitField ;
6
6
use bitflags:: bitflags;
@@ -105,33 +105,35 @@ impl GlobalDescriptorTable {
105
105
}
106
106
}
107
107
108
- /// Adds the given segment descriptor to the GDT, returning the segment selector.
109
- ///
110
- /// Panics if the GDT has no free entries left.
111
- #[ inline]
112
- pub fn add_entry ( & mut self , entry : Descriptor ) -> SegmentSelector {
113
- let index = match entry {
114
- Descriptor :: UserSegment ( value) => self . push ( value) ,
115
- Descriptor :: SystemSegment ( value_low, value_high) => {
116
- let index = self . push ( value_low) ;
117
- self . push ( value_high) ;
118
- index
119
- }
120
- } ;
121
-
122
- let rpl = match entry {
123
- Descriptor :: UserSegment ( value) => {
124
- if DescriptorFlags :: from_bits_truncate ( value) . contains ( DescriptorFlags :: DPL_RING_3 )
125
- {
126
- PrivilegeLevel :: Ring3
127
- } else {
128
- PrivilegeLevel :: Ring0
108
+ const_fn ! {
109
+ /// Adds the given segment descriptor to the GDT, returning the segment selector.
110
+ ///
111
+ /// Panics if the GDT has no free entries left.
112
+ #[ inline]
113
+ pub fn add_entry( & mut self , entry: Descriptor ) -> SegmentSelector {
114
+ let index = match entry {
115
+ Descriptor :: UserSegment ( value) => self . push( value) ,
116
+ Descriptor :: SystemSegment ( value_low, value_high) => {
117
+ let index = self . push( value_low) ;
118
+ self . push( value_high) ;
119
+ index
129
120
}
130
- }
131
- Descriptor :: SystemSegment ( _, _) => PrivilegeLevel :: Ring0 ,
132
- } ;
121
+ } ;
122
+
123
+ let rpl = match entry {
124
+ Descriptor :: UserSegment ( value) => {
125
+ if DescriptorFlags :: from_bits_truncate( value) . contains( DescriptorFlags :: DPL_RING_3 )
126
+ {
127
+ PrivilegeLevel :: Ring3
128
+ } else {
129
+ PrivilegeLevel :: Ring0
130
+ }
131
+ }
132
+ Descriptor :: SystemSegment ( _, _) => PrivilegeLevel :: Ring0 ,
133
+ } ;
133
134
134
- SegmentSelector :: new ( index as u16 , rpl)
135
+ SegmentSelector :: new( index as u16 , rpl)
136
+ }
135
137
}
136
138
137
139
/// Loads the GDT in the CPU using the `lgdt` instruction. This does **not** alter any of the
@@ -142,26 +144,33 @@ impl GlobalDescriptorTable {
142
144
#[ cfg( feature = "instructions" ) ]
143
145
#[ inline]
144
146
pub fn load ( & ' static self ) {
145
- use crate :: instructions:: tables:: { lgdt, DescriptorTablePointer } ;
146
- use core:: mem:: size_of;
147
-
148
- let ptr = DescriptorTablePointer {
149
- base : self . table . as_ptr ( ) as u64 ,
150
- limit : ( self . table . len ( ) * size_of :: < u64 > ( ) - 1 ) as u16 ,
151
- } ;
147
+ use crate :: instructions:: tables:: lgdt;
148
+ // SAFETY: static lifetime ensures no modification after loading.
149
+ unsafe { lgdt ( & self . pointer ( ) ) } ;
150
+ }
152
151
153
- unsafe { lgdt ( & ptr) } ;
152
+ const_fn ! {
153
+ #[ inline]
154
+ fn push( & mut self , value: u64 ) -> usize {
155
+ if self . next_free < self . table. len( ) {
156
+ let index = self . next_free;
157
+ self . table[ index] = value;
158
+ self . next_free += 1 ;
159
+ index
160
+ } else {
161
+ panic!( "GDT full" ) ;
162
+ }
163
+ }
154
164
}
155
165
156
- #[ inline]
157
- fn push ( & mut self , value : u64 ) -> usize {
158
- if self . next_free < self . table . len ( ) {
159
- let index = self . next_free ;
160
- self . table [ index] = value;
161
- self . next_free += 1 ;
162
- index
163
- } else {
164
- panic ! ( "GDT full" ) ;
166
+ /// Creates the descriptor pointer for this table. This pointer can only be
167
+ /// safely used if the table is never modified or destroyed while in use.
168
+ #[ cfg( feature = "instructions" ) ]
169
+ fn pointer ( & self ) -> DescriptorTablePointer {
170
+ use core:: mem:: size_of;
171
+ DescriptorTablePointer {
172
+ base : self . table . as_ptr ( ) as u64 ,
173
+ limit : ( self . next_free * size_of :: < u64 > ( ) - 1 ) as u16 ,
165
174
}
166
175
}
167
176
}
0 commit comments