@@ -10,30 +10,55 @@ use core::fmt;
1010#[ cfg( doc) ]
1111use crate :: registers:: segmentation:: { Segment , CS , SS } ;
1212
13+ #[ cfg( feature = "instructions" ) ]
14+ use core:: sync:: atomic:: { AtomicU64 as EntryValue , Ordering } ;
15+ #[ cfg( not( feature = "instructions" ) ) ]
16+ use u64 as EntryValue ;
17+
1318/// 8-byte entry in a descriptor table.
1419///
1520/// A [`GlobalDescriptorTable`] (or LDT) is an array of these entries, and
1621/// [`SegmentSelector`]s index into this array. Each [`Descriptor`] in the table
1722/// uses either 1 Entry (if it is a [`UserSegment`](Descriptor::UserSegment)) or
1823/// 2 Entries (if it is a [`SystemSegment`](Descriptor::SystemSegment)). This
1924/// type exists to give users access to the raw entry bits in a GDT.
20- #[ derive( Clone , PartialEq , Eq ) ]
2125#[ repr( transparent) ]
22- pub struct Entry ( u64 ) ;
26+ pub struct Entry ( EntryValue ) ;
2327
2428impl Entry {
2529 // Create a new Entry from a raw value.
2630 const fn new ( raw : u64 ) -> Self {
31+ #[ cfg( feature = "instructions" ) ]
32+ let raw = EntryValue :: new ( raw) ;
2733 Self ( raw)
2834 }
2935
3036 /// The raw bits for this entry. Depending on the [`Descriptor`] type, these
3137 /// bits may correspond to those in [`DescriptorFlags`].
3238 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
3445 }
3546}
3647
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+
3762impl fmt:: Debug for Entry {
3863 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3964 // Display inner value as hex
@@ -99,6 +124,9 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
99124 // TODO: Replace with compiler error when feature(generic_const_exprs) is stable.
100125 assert ! ( MAX > 0 , "A GDT cannot have 0 entries" ) ;
101126 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) ]
102130 const NULL : Entry = Entry :: new ( 0 ) ;
103131 Self {
104132 table : [ NULL ; MAX ] ,
@@ -195,7 +223,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
195223 /// [`SS::set_reg()`] and [`CS::set_reg()`].
196224 #[ cfg( feature = "instructions" ) ]
197225 #[ inline]
198- pub fn load ( & ' static mut self ) {
226+ pub fn load ( & ' static self ) {
199227 // SAFETY: static lifetime ensures no modification after loading.
200228 unsafe { self . load_unsafe ( ) } ;
201229 }
@@ -213,7 +241,7 @@ impl<const MAX: usize> GlobalDescriptorTable<MAX> {
213241 ///
214242 #[ cfg( feature = "instructions" ) ]
215243 #[ inline]
216- pub unsafe fn load_unsafe ( & mut self ) {
244+ pub unsafe fn load_unsafe ( & self ) {
217245 use crate :: instructions:: tables:: lgdt;
218246 unsafe {
219247 lgdt ( & self . pointer ( ) ) ;
0 commit comments