@@ -101,27 +101,45 @@ impl<'a> SDT<'a> {
101101 }
102102}
103103
104- /// The Root System Descriptor Table.
105- pub struct RSDT < ' a > ( SDT < ' a > ) ;
104+ /// The Root System Description Table.
105+ /// Two variants to support 32 bit RSDT and 64 bit XSDT.
106+ pub enum RSDT < ' a > {
107+ /// Root System Description Table.
108+ RSDT ( SDT < ' a > ) ,
109+ /// Extended System Description Table.
110+ XSDT ( SDT < ' a > ) ,
111+ }
106112
107113impl < ' a > RSDT < ' a > {
108- /// Create a new SDT .
109- pub fn new ( rsdt_addr : u32 ) -> Result < RSDT < ' a > > {
114+ /// Create a new RSDT .
115+ pub fn new_rsdt ( rsdt_addr : usize ) -> Result < RSDT < ' a > > {
110116 let sdt = unsafe { SDT :: new ( rsdt_addr as * const u8 ) ? } ;
111- Ok ( RSDT ( sdt) )
117+ Ok ( RSDT :: RSDT ( sdt) )
118+ }
119+
120+ /// Create a new XSDT.
121+ pub fn new_xsdt ( xsdt_addr : usize ) -> Result < RSDT < ' a > > {
122+ let sdt = unsafe { SDT :: new ( xsdt_addr as * const u8 ) ? } ;
123+ Ok ( RSDT :: XSDT ( sdt) )
112124 }
113125
114126 /// Return the number of entries in the table.
115127 ///
116128 /// Note: This is not the same as the length value of the header.
117129 /// the the length value _includes_ the header.
118130 pub fn num_entries ( & self ) -> usize {
119- self . 0 . len ( ) / 4
131+ match self {
132+ RSDT :: XSDT ( sdt) => sdt. len ( ) / 8 ,
133+ RSDT :: RSDT ( sdt) => sdt. len ( ) / 4 ,
134+ }
120135 }
121136
122137 /// Return an iterator for the SDT entries.
123138 pub fn entries ( & self ) -> RSDTIterator < ' a > {
124- RSDTIterator :: new ( self . 0 . table )
139+ match self {
140+ RSDT :: RSDT ( sdt) => RSDTIterator :: new_rsdt ( sdt. table ) ,
141+ RSDT :: XSDT ( sdt) => RSDTIterator :: new_xsdt ( sdt. table ) ,
142+ }
125143 }
126144
127145 /// Returns the first matching SDT for a given signature.
@@ -137,41 +155,77 @@ impl<'a> RSDT<'a> {
137155
138156impl < ' a > fmt:: Debug for RSDT < ' a > {
139157 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
140- write ! ( f, "{:?}" , self . 0 )
158+ let my_sdt = match self {
159+ RSDT :: RSDT ( the_sdt) => the_sdt,
160+ RSDT :: XSDT ( the_sdt) => the_sdt,
161+ } ;
162+ write ! ( f, "{:?}" , my_sdt)
141163 }
142164}
143165
144- /// Iterator for the SDT entries found in the RSDT.
145- pub struct RSDTIterator < ' a > {
146- table : & ' a [ u8 ] ,
147- offset : usize ,
166+ /// Iterator for the SDT entries found in the RSDT/XSDT.
167+ pub enum RSDTIterator < ' a > {
168+ /// Iterates through 32 bit RSDT.
169+ RSDTIterator {
170+ /// Table of 32 bit SDT pointers.
171+ table : & ' a [ u8 ] ,
172+ /// Current offset to keep track of iteration.
173+ offset : usize ,
174+ } ,
175+ /// Iterates through 64 bit XSDT.
176+ XSDTIterator {
177+ /// Table of 64 bit SDT pointers.
178+ table : & ' a [ u8 ] ,
179+ /// Current offset to keep track of iteration.
180+ offset : usize ,
181+ } ,
148182}
149183
150184impl < ' a > RSDTIterator < ' a > {
151185 /// Create an iterator for the SDT entries in an RSDT.
152- pub fn new < ' b : ' a > ( table : & ' b [ u8 ] ) -> RSDTIterator < ' a > {
153- RSDTIterator { table, offset : 0 }
186+ pub fn new_rsdt < ' b : ' a > ( table : & ' b [ u8 ] ) -> RSDTIterator < ' a > {
187+ RSDTIterator :: RSDTIterator { table, offset : 0 }
188+ }
189+
190+ /// Create an iterator for the SDT entries in an XSDT.
191+ pub fn new_xsdt < ' b : ' a > ( table : & ' b [ u8 ] ) -> RSDTIterator < ' a > {
192+ RSDTIterator :: XSDTIterator { table, offset : 0 }
154193 }
155194}
156195
157196impl < ' a > Iterator for RSDTIterator < ' a > {
158197 type Item = Result < SDT < ' a > > ;
159198
160199 fn next ( & mut self ) -> Option < Self :: Item > {
161- let next = self . offset + 4 ;
162- if next <= self . table . len ( ) {
163- let item = unsafe {
164- // TODO(dlrobertson): We currently only support the 32-bit RSDT.
165- // When we support the 64-bit XSDT, the table may point to an
166- // array of 64-bit pointers.
167- let ptr =
168- NativeEndian :: read_u32 ( & self . table [ self . offset ..next] ) ;
169- self . offset = next;
170- SDT :: new ( ptr as * const u8 )
171- } ;
172- Some ( item)
173- } else {
174- None
200+ match self {
201+ RSDTIterator :: RSDTIterator { table, offset } => {
202+ let next = * offset + 4usize ;
203+ if next <= table. len ( ) {
204+ let item = unsafe {
205+ let ptr = NativeEndian :: read_u32 ( & table[ * offset..next] )
206+ as usize ;
207+ * offset = next;
208+ SDT :: new ( ptr as * const u8 )
209+ } ;
210+ Some ( item)
211+ } else {
212+ None
213+ }
214+ }
215+ RSDTIterator :: XSDTIterator { table, offset } => {
216+ let next = * offset + 8usize ;
217+ if next <= table. len ( ) {
218+ let item = unsafe {
219+ let ptr = NativeEndian :: read_u64 ( & table[ * offset..next] )
220+ as usize ;
221+ * offset = next;
222+ SDT :: new ( ptr as * const u8 )
223+ } ;
224+ Some ( item)
225+ } else {
226+ None
227+ }
228+ }
175229 }
176230 }
177231}
0 commit comments