@@ -10,30 +10,55 @@ use core::fmt;
10
10
#[ cfg( doc) ]
11
11
use crate :: registers:: segmentation:: { Segment , CS , SS } ;
12
12
13
+ #[ cfg( feature = "instructions" ) ]
14
+ use core:: sync:: atomic:: { AtomicU64 as EntryValue , Ordering } ;
15
+ #[ cfg( not( feature = "instructions" ) ) ]
16
+ use u64 as EntryValue ;
17
+
13
18
/// 8-byte entry in a descriptor table.
14
19
///
15
20
/// A [`GlobalDescriptorTable`] (or LDT) is an array of these entries, and
16
21
/// [`SegmentSelector`]s index into this array. Each [`Descriptor`] in the table
17
22
/// uses either 1 Entry (if it is a [`UserSegment`](Descriptor::UserSegment)) or
18
23
/// 2 Entries (if it is a [`SystemSegment`](Descriptor::SystemSegment)). This
19
24
/// type exists to give users access to the raw entry bits in a GDT.
20
- #[ derive( Clone , PartialEq , Eq ) ]
21
25
#[ repr( transparent) ]
22
- pub struct Entry ( u64 ) ;
26
+ pub struct Entry ( EntryValue ) ;
23
27
24
28
impl Entry {
25
29
// Create a new Entry from a raw value.
26
30
const fn new ( raw : u64 ) -> Self {
31
+ #[ cfg( feature = "instructions" ) ]
32
+ let raw = EntryValue :: new ( raw) ;
27
33
Self ( raw)
28
34
}
29
35
30
36
/// The raw bits for this entry. Depending on the [`Descriptor`] type, these
31
37
/// bits may correspond to those in [`DescriptorFlags`].
32
38
pub fn raw ( & self ) -> u64 {
33
- self . 0
39
+ // TODO: Make this const fn when AtomicU64::load is const.
40
+ #[ cfg( feature = "instructions" ) ]
41
+ let raw = self . 0 . load ( Ordering :: SeqCst ) ;
42
+ #[ cfg( not( feature = "instructions" ) ) ]
43
+ let raw = self . 0 ;
44
+ raw
34
45
}
35
46
}
36
47
48
+ impl Clone for Entry {
49
+ fn clone ( & self ) -> Self {
50
+ Self :: new ( self . raw ( ) )
51
+ }
52
+ }
53
+
54
+ impl PartialEq for Entry {
55
+ fn eq ( & self , other : & Self ) -> bool {
56
+ self . raw ( ) == other. raw ( )
57
+ }
58
+ }
59
+
60
+ impl Eq for Entry { }
61
+
37
62
impl fmt:: Debug for Entry {
38
63
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
39
64
// Display inner value as hex
@@ -99,6 +124,9 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
99
124
// TODO: Replace with compiler error when feature(generic_const_exprs) is stable.
100
125
assert ! ( MAX > 0 , "A GDT cannot have 0 entries" ) ;
101
126
assert ! ( MAX <= ( 1 << 13 ) , "A GDT can only have at most 2^13 entries" ) ;
127
+
128
+ // TODO: Replace with inline_const when it's stable.
129
+ #[ allow( clippy:: declare_interior_mutable_const) ]
102
130
const NULL : Entry = Entry :: new ( 0 ) ;
103
131
Self {
104
132
table : [ NULL ; MAX ] ,
@@ -195,7 +223,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
195
223
/// [`SS::set_reg()`] and [`CS::set_reg()`].
196
224
#[ cfg( feature = "instructions" ) ]
197
225
#[ inline]
198
- pub fn load ( & ' static mut self ) {
226
+ pub fn load ( & ' static self ) {
199
227
// SAFETY: static lifetime ensures no modification after loading.
200
228
unsafe { self . load_unsafe ( ) } ;
201
229
}
@@ -213,7 +241,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
213
241
///
214
242
#[ cfg( feature = "instructions" ) ]
215
243
#[ inline]
216
- pub unsafe fn load_unsafe ( & mut self ) {
244
+ pub unsafe fn load_unsafe ( & self ) {
217
245
use crate :: instructions:: tables:: lgdt;
218
246
unsafe {
219
247
lgdt ( & self . pointer ( ) ) ;
0 commit comments