@@ -101,27 +101,45 @@ impl<'a> SDT<'a> {
101
101
}
102
102
}
103
103
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
+ }
106
112
107
113
impl < ' 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 > > {
110
116
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) )
112
124
}
113
125
114
126
/// Return the number of entries in the table.
115
127
///
116
128
/// Note: This is not the same as the length value of the header.
117
129
/// the the length value _includes_ the header.
118
130
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
+ }
120
135
}
121
136
122
137
/// Return an iterator for the SDT entries.
123
138
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
+ }
125
143
}
126
144
127
145
/// Returns the first matching SDT for a given signature.
@@ -137,41 +155,77 @@ impl<'a> RSDT<'a> {
137
155
138
156
impl < ' a > fmt:: Debug for RSDT < ' a > {
139
157
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)
141
163
}
142
164
}
143
165
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
+ } ,
148
182
}
149
183
150
184
impl < ' a > RSDTIterator < ' a > {
151
185
/// 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 }
154
193
}
155
194
}
156
195
157
196
impl < ' a > Iterator for RSDTIterator < ' a > {
158
197
type Item = Result < SDT < ' a > > ;
159
198
160
199
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
+ }
175
229
}
176
230
}
177
231
}
0 commit comments