1use super::Table;
5use bitfield_struct::bitfield;
6use core::mem::size_of;
7use open_enum::open_enum;
8use size_of_val;
9use static_assertions::const_assert_eq;
10use thiserror::Error;
11use zerocopy::FromBytes;
12use zerocopy::FromZeros;
13use zerocopy::Immutable;
14use zerocopy::IntoBytes;
15use zerocopy::KnownLayout;
16use zerocopy::LE;
17use zerocopy::U16;
18use zerocopy::U32;
19use zerocopy::U64;
20use zerocopy::Unaligned;
21
22#[repr(C, packed)]
23#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)]
24pub struct Madt {
25 pub apic_addr: u32,
26 pub flags: u32,
27}
28
29impl Table for Madt {
30 const SIGNATURE: [u8; 4] = *b"APIC";
31}
32
33pub const MADT_PCAT_COMPAT: u32 = 1 << 0;
34
35open_enum! {
36 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)]
37 pub enum MadtType: u8 {
38 APIC = 0x0,
39 IO_APIC = 0x1,
40 INTERRUPT_SOURCE_OVERRIDE = 0x2,
41 X2APIC = 0x9,
42 GICC = 0xb,
43 GICD = 0xc,
44 }
45}
46
47#[repr(C, packed)]
48#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
49pub struct MadtEntryHeader {
50 pub typ: MadtType,
51 pub length: u8,
52}
53
54#[repr(C, packed)]
55#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
56pub struct MadtApic {
57 pub typ: MadtType,
58 pub length: u8,
59 pub acpi_processor_uid: u8,
60 pub apic_id: u8,
61 pub flags: u32,
62}
63
64const_assert_eq!(size_of::<MadtApic>(), 8);
65
66impl MadtApic {
67 pub fn new() -> Self {
68 Self {
69 typ: MadtType::APIC,
70 length: size_of::<Self>() as u8,
71 acpi_processor_uid: 0,
72 apic_id: 0,
73 flags: 0,
74 }
75 }
76}
77
78pub const MADT_APIC_ENABLED: u32 = 1 << 0;
79pub const MADT_APIC_ONLINE_CAPABLE: u32 = 1 << 1;
80
81#[repr(C, packed)]
82#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
83pub struct MadtX2Apic {
84 pub typ: MadtType,
85 pub length: u8,
86 pub reserved: u16,
87 pub x2_apic_id: u32,
88 pub flags: u32,
89 pub acpi_processor_uid: u32,
90}
91
92const_assert_eq!(size_of::<MadtX2Apic>(), 16);
93
94impl MadtX2Apic {
95 pub fn new() -> Self {
96 Self {
97 typ: MadtType::X2APIC,
98 length: size_of::<Self>() as u8,
99 reserved: 0,
100 x2_apic_id: 0,
101 flags: 0,
102 acpi_processor_uid: 0,
103 }
104 }
105}
106
107#[repr(C, packed)]
108#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
109pub struct MadtIoApic {
110 pub typ: MadtType,
111 pub length: u8,
112 pub io_apic_id: u8,
113 pub rsvd: u8,
114 pub io_apic_address: u32,
115 pub global_system_interrupt_base: u32,
116}
117
118const_assert_eq!(size_of::<MadtIoApic>(), 12);
119
120impl MadtIoApic {
121 pub fn new() -> Self {
122 Self {
123 typ: MadtType::IO_APIC,
124 length: size_of::<Self>() as u8,
125 io_apic_id: 0,
126 rsvd: 0,
127 io_apic_address: 0,
128 global_system_interrupt_base: 0,
129 }
130 }
131}
132
133#[repr(C, packed)]
134#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
135pub struct MadtInterruptSourceOverride {
136 pub typ: MadtType,
137 pub length: u8,
138 pub bus: u8,
139 pub source: u8,
140 pub gsi: u32,
141 pub flags: u16,
142}
143
144const_assert_eq!(size_of::<MadtInterruptSourceOverride>(), 10);
145
146pub enum InterruptPolarity {
147 ActiveLow,
148 ActiveHigh,
149}
150
151pub enum InterruptTriggerMode {
152 Edge,
153 Level,
154}
155
156impl MadtInterruptSourceOverride {
157 pub fn new(
158 source: u8,
159 gsi: u32,
160 polarity: Option<InterruptPolarity>,
161 trigger_mode: Option<InterruptTriggerMode>,
162 ) -> Self {
163 Self {
164 typ: MadtType::INTERRUPT_SOURCE_OVERRIDE,
165 length: size_of::<Self>() as u8,
166 bus: 0,
167 source,
168 gsi,
169 flags: match polarity {
170 None => 0,
171 Some(InterruptPolarity::ActiveHigh) => 1,
172 Some(InterruptPolarity::ActiveLow) => 3,
173 } | (match trigger_mode {
174 None => 0,
175 Some(InterruptTriggerMode::Edge) => 1,
176 Some(InterruptTriggerMode::Level) => 3,
177 } << 2),
178 }
179 }
180}
181
182#[repr(C)]
183#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
184pub struct MadtGicd {
185 pub typ: MadtType,
186 pub length: u8,
187 pub reserved: u16,
188 pub gic_id: u32,
189 pub base_address: u64,
190 pub reserved2: u32,
191 pub gic_version: u8,
192 pub reserved3: [u8; 3],
193}
194
195const_assert_eq!(size_of::<MadtGicd>(), 24);
196
197impl MadtGicd {
198 pub fn new(gic_id: u32, base_address: u64, gic_version: u8) -> Self {
199 Self {
200 typ: MadtType::GICD,
201 length: size_of::<Self>() as u8,
202 reserved: 0,
203 gic_id,
204 base_address,
205 reserved2: 0,
206 gic_version,
207 reserved3: [0; 3],
208 }
209 }
210}
211
212#[repr(C)]
215#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)]
216pub struct MadtGicc {
217 pub typ: MadtType,
218 pub length: u8,
219 pub reserved: [u8; 2],
220 pub cpu_interface_number: U32<LE>,
221 pub acpi_processor_uid: U32<LE>,
222 pub flags: U32<LE>,
223 pub parking_protocol_version: U32<LE>,
224 pub performance_monitoring_gsiv: U32<LE>,
225 pub parked_address: U64<LE>,
226 pub base_address: U64<LE>,
227 pub gicv: U64<LE>,
228 pub gich: U64<LE>,
229 pub vgic_maintenance_interrupt: U32<LE>,
230 pub gicr_base_address: U64<LE>,
231 pub mpidr: U64<LE>,
232 pub processor_power_efficiency_class: u8,
233 pub reserved2: u8,
234 pub spe_overflow_interrupt: U16<LE>,
235}
236
237const_assert_eq!(size_of::<MadtGicc>(), 80);
238
239impl MadtGicc {
240 pub fn new(acpi_processor_uid: u32, mpidr: u64, gicr: u64) -> Self {
241 Self {
242 typ: MadtType::GICC,
243 length: size_of::<Self>() as u8,
244 flags: u32::from(MadtGiccFlags::new().with_enabled(true)).into(),
245 acpi_processor_uid: acpi_processor_uid.into(),
246 mpidr: mpidr.into(),
247 gicr_base_address: gicr.into(),
248 ..Self::new_zeroed()
249 }
250 }
251}
252
253#[bitfield(u32)]
254pub struct MadtGiccFlags {
255 pub enabled: bool,
256 #[bits(31)]
257 _reserved: u32,
258}
259
260pub struct MadtParser<'a>(&'a [u8]);
262
263impl<'a> MadtParser<'a> {
264 pub fn new(table: &'a [u8]) -> Result<Self, ParserError> {
266 let header = crate::Header::read_from_prefix(table)
267 .map_err(|_| ParserError)?
268 .0; if (header.length.get() as usize) < size_of::<Madt>() {
270 return Err(ParserError);
271 }
272 let off = size_of_val(&header);
273 let table = table
274 .get(off..header.length.get() as usize)
275 .ok_or(ParserError)?;
276 Ok(Self(table))
277 }
278
279 pub fn entries(&self) -> MadtIter<'_> {
281 MadtIter {
282 entries: &self.0[size_of::<Madt>()..],
283 }
284 }
285
286 #[cfg(feature = "alloc")]
289 pub fn parse_apic_ids(&self) -> Result<alloc::vec::Vec<Option<u32>>, ParseApicIdError> {
290 use alloc::vec::Vec;
291
292 let mut apic_ids: Vec<Option<u32>> = Vec::new();
293
294 for entry in self.entries() {
295 let (uid, apic_id) = match entry.map_err(ParseApicIdError::Parser)? {
296 MadtEntry::Apic(apic) => {
297 if apic.flags & MADT_APIC_ENABLED == MADT_APIC_ENABLED {
298 (apic.acpi_processor_uid as u32, apic.apic_id as u32)
299 } else {
300 continue;
301 }
302 }
303 MadtEntry::X2Apic(x2apic) => {
304 if x2apic.flags & MADT_APIC_ENABLED == MADT_APIC_ENABLED {
305 (x2apic.acpi_processor_uid, x2apic.x2_apic_id)
306 } else {
307 continue;
308 }
309 }
310 };
311
312 let index = uid as usize - 1;
314
315 if apic_ids.get(index).is_none() {
316 apic_ids.resize(index + 1, None);
317 }
318
319 if apic_ids[index].replace(apic_id).is_some() {
320 return Err(ParseApicIdError::ProcessorNotUnique(uid));
321 }
322 }
323
324 Ok(apic_ids)
325 }
326}
327
328#[derive(Debug, Error)]
330#[error("madt parsing failed")]
331pub struct ParserError;
332
333#[derive(Debug, thiserror::Error)]
335pub enum ParseApicIdError {
336 #[error("error parsing entry")]
337 Parser(#[source] ParserError),
338 #[error("processor_acpi_uid specified more than once in the MADT")]
339 ProcessorNotUnique(u32),
340}
341
342#[derive(Debug, Clone, Copy, PartialEq, Eq)]
344pub enum MadtEntry {
345 Apic(MadtApic),
347 X2Apic(MadtX2Apic),
349}
350
351pub struct MadtIter<'a> {
353 entries: &'a [u8],
354}
355
356impl MadtIter<'_> {
357 fn parse(&mut self) -> Result<Option<MadtEntry>, ParserError> {
358 while let Ok((header, _)) = MadtEntryHeader::read_from_prefix(self.entries) {
360 if self.entries.len() < header.length as usize {
362 return Err(ParserError);
363 }
364 let (buf, rest) = self.entries.split_at(header.length as usize);
365 self.entries = rest;
366 let entry = match header.typ {
367 MadtType::APIC => {
368 MadtEntry::Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0)
369 }
371 MadtType::X2APIC => {
372 MadtEntry::X2Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0)
373 }
375 _ => continue,
376 };
377 return Ok(Some(entry));
378 }
379 Ok(None)
380 }
381}
382
383impl Iterator for MadtIter<'_> {
384 type Item = Result<MadtEntry, ParserError>;
385
386 fn next(&mut self) -> Option<Self::Item> {
387 self.parse().transpose()
388 }
389}
390
391#[cfg(test)]
393mod test {
394 use super::*;
395 #[cfg(feature = "alloc")]
396 use alloc::vec;
397 #[cfg(feature = "alloc")]
398 use alloc::vec::Vec;
399
400 #[test]
402 #[cfg(feature = "alloc")]
403 fn sparse_madt() {
404 const DATA: &[u8] = &[
405 65, 80, 73, 67, 194, 0, 0, 0, 5, 195, 72, 86, 76, 73, 84, 69, 72, 86, 76, 73, 84, 69,
406 84, 66, 0, 0, 0, 0, 77, 83, 72, 86, 0, 0, 0, 0, 0, 0, 224, 254, 0, 0, 0, 0, 1, 12, 16,
407 0, 0, 0, 192, 254, 0, 0, 0, 0, 2, 10, 0, 2, 2, 0, 0, 0, 13, 0, 0, 8, 1, 0, 1, 0, 0, 0,
408 0, 8, 4, 1, 1, 0, 0, 0, 0, 8, 6, 2, 1, 0, 0, 0, 0, 8, 8, 3, 1, 0, 0, 0, 0, 8, 10, 4, 1,
409 0, 0, 0, 0, 8, 12, 5, 1, 0, 0, 0, 0, 8, 14, 6, 1, 0, 0, 0, 0, 8, 16, 7, 1, 0, 0, 0, 0,
410 8, 18, 8, 1, 0, 0, 0, 0, 8, 20, 9, 1, 0, 0, 0, 0, 8, 22, 10, 1, 0, 0, 0, 0, 8, 24, 11,
411 1, 0, 0, 0, 0, 8, 26, 12, 1, 0, 0, 0, 0, 8, 28, 13, 1, 0, 0, 0, 0, 8, 30, 14, 1, 0, 0,
412 0, 0, 8, 32, 15, 1, 0, 0, 0,
413 ];
414
415 let madt = MadtParser::new(DATA).unwrap();
416 let entries = madt.parse_apic_ids().unwrap();
417
418 assert_eq!(
419 entries,
420 vec![
421 Some(0),
422 None,
423 None,
424 Some(1),
425 None,
426 Some(2),
427 None,
428 Some(3),
429 None,
430 Some(4),
431 None,
432 Some(5),
433 None,
434 Some(6),
435 None,
436 Some(7),
437 None,
438 Some(8),
439 None,
440 Some(9),
441 None,
442 Some(10),
443 None,
444 Some(11),
445 None,
446 Some(12),
447 None,
448 Some(13),
449 None,
450 Some(14),
451 None,
452 Some(15)
453 ]
454 );
455 }
456
457 #[test]
458 fn single_apic() {
459 const DATA: &[u8] = &[
461 0x41, 0x50, 0x49, 0x43, 0x50, 0x00, 0x00, 0x00, 0x04, 0x23, 0x56, 0x52, 0x54, 0x55,
462 0x41, 0x4c, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00,
463 0x4d, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0x00, 0x00,
464 0x00, 0x00, 0x01, 0x0c, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
465 0x02, 0x0a, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x06, 0x01, 0x00,
466 0x00, 0x01, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
467 ];
468
469 let madt = MadtParser::new(DATA).unwrap();
470
471 let entries = madt.entries().collect::<Result<Vec<_>, _>>().unwrap();
472
473 assert_eq!(
474 entries[0],
475 MadtEntry::Apic(MadtApic {
476 typ: MadtType::APIC,
477 length: 8,
478 acpi_processor_uid: 1,
479 apic_id: 0,
480 flags: 1,
481 })
482 );
483 }
484
485 #[test]
486 #[cfg(feature = "alloc")]
487 fn madt_50_vps() {
488 const DATA: &[u8] = &[
489 0x41, 0x50, 0x49, 0x43, 0xd8, 0x01, 0x00, 0x00, 0x04, 0x06, 0x56, 0x52, 0x54, 0x55,
490 0x41, 0x4c, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x53,
492 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a,
494 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x06, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0c,
496 0x32, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00,
498 0x00, 0x00, 0x00, 0x08, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x02, 0x01, 0x00,
500 0x00, 0x00, 0x00, 0x08, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x04, 0x01, 0x00,
502 0x00, 0x00, 0x00, 0x08, 0x06, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x01, 0x00,
504 0x00, 0x00, 0x00, 0x08, 0x08, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x08, 0x01, 0x00,
506 0x00, 0x00, 0x00, 0x08, 0x0a, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x0a, 0x01, 0x00,
508 0x00, 0x00, 0x00, 0x08, 0x0c, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0x0c, 0x01, 0x00,
510 0x00, 0x00, 0x00, 0x08, 0x0e, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x11, 0x01, 0x00,
512 0x00, 0x00, 0x00, 0x08, 0x10, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x13, 0x01, 0x00,
514 0x00, 0x00, 0x00, 0x08, 0x12, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x13, 0x15, 0x01, 0x00,
516 0x00, 0x00, 0x00, 0x08, 0x14, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x15, 0x17, 0x01, 0x00,
518 0x00, 0x00, 0x00, 0x08, 0x16, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x17, 0x19, 0x01, 0x00,
520 0x00, 0x00, 0x00, 0x08, 0x18, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x1b, 0x01, 0x00,
522 0x00, 0x00, 0x00, 0x08, 0x1a, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1b, 0x20, 0x01, 0x00,
524 0x00, 0x00, 0x00, 0x08, 0x1c, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0x22, 0x01, 0x00,
526 0x00, 0x00, 0x00, 0x08, 0x1e, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1f, 0x24, 0x01, 0x00,
528 0x00, 0x00, 0x00, 0x08, 0x20, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x26, 0x01, 0x00,
530 0x00, 0x00, 0x00, 0x08, 0x22, 0x27, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x23, 0x28, 0x01, 0x00,
532 0x00, 0x00, 0x00, 0x08, 0x24, 0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x2a, 0x01, 0x00,
534 0x00, 0x00, 0x00, 0x08, 0x26, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x27, 0x30, 0x01, 0x00,
536 0x00, 0x00, 0x00, 0x08, 0x28, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x29, 0x32, 0x01, 0x00,
538 0x00, 0x00, 0x00, 0x08, 0x2a, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2b, 0x34, 0x01, 0x00,
540 0x00, 0x00, 0x00, 0x08, 0x2c, 0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2d, 0x36, 0x01, 0x00,
542 0x00, 0x00, 0x00, 0x08, 0x2e, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2f, 0x38, 0x01, 0x00,
544 0x00, 0x00, 0x00, 0x08, 0x30, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x3a, 0x01, 0x00,
546 0x00, 0x00, 0x00, 0x08, 0x32, 0x3b, 0x01, 0x00, 0x00, 0x00, ];
549
550 let madt = MadtParser::new(DATA).unwrap();
551
552 let entries = madt.entries().collect::<Result<Vec<_>, _>>().unwrap();
553
554 assert_eq!(entries.len(), 50);
555 assert!(matches!(
556 entries[0],
557 MadtEntry::Apic(MadtApic {
558 typ: MadtType::APIC,
559 length: 8,
560 acpi_processor_uid: 1,
561 apic_id: 0,
562 flags: 1
563 })
564 ));
565 assert!(matches!(
566 entries[49],
567 MadtEntry::Apic(MadtApic {
568 typ: MadtType::APIC,
569 length: 8,
570 acpi_processor_uid: 50,
571 apic_id: 59,
572 flags: 1
573 })
574 ));
575
576 let entries = madt.parse_apic_ids().unwrap();
577
578 assert_eq!(
579 entries,
580 (0..13)
581 .chain(16..29)
582 .chain(32..44)
583 .chain(48..60)
584 .map(Some)
585 .collect::<Vec<_>>()
586 );
587 }
588
589 #[test]
590 #[cfg(feature = "alloc")]
591 fn madt_256() {
592 const DATA: &[u8] = &[
593 0x41, 0x50, 0x49, 0x43, 0x50, 0x08, 0x00, 0x00, 0x04, 0x14, 0x56, 0x52, 0x54, 0x55,
594 0x41, 0x4c, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x53,
596 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a,
598 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x06, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0c,
600 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00,
602 0x00, 0x00, 0x00, 0x08, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x02, 0x01, 0x00,
604 0x00, 0x00, 0x00, 0x08, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x04, 0x01, 0x00,
606 0x00, 0x00, 0x00, 0x08, 0x06, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x01, 0x00,
608 0x00, 0x00, 0x00, 0x08, 0x08, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x08, 0x01, 0x00,
610 0x00, 0x00, 0x00, 0x08, 0x0a, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x0a, 0x01, 0x00,
612 0x00, 0x00, 0x00, 0x08, 0x0c, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0x0c, 0x01, 0x00,
614 0x00, 0x00, 0x00, 0x08, 0x0e, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x0e, 0x01, 0x00,
616 0x00, 0x00, 0x00, 0x08, 0x10, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x10, 0x01, 0x00,
618 0x00, 0x00, 0x00, 0x08, 0x12, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x13, 0x12, 0x01, 0x00,
620 0x00, 0x00, 0x00, 0x08, 0x14, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x15, 0x14, 0x01, 0x00,
622 0x00, 0x00, 0x00, 0x08, 0x16, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x17, 0x16, 0x01, 0x00,
624 0x00, 0x00, 0x00, 0x08, 0x18, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x18, 0x01, 0x00,
626 0x00, 0x00, 0x00, 0x08, 0x1a, 0x19, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1b, 0x1a, 0x01, 0x00,
628 0x00, 0x00, 0x00, 0x08, 0x1c, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0x1c, 0x01, 0x00,
630 0x00, 0x00, 0x00, 0x08, 0x1e, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1f, 0x1e, 0x01, 0x00,
632 0x00, 0x00, 0x00, 0x08, 0x20, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x20, 0x01, 0x00,
634 0x00, 0x00, 0x00, 0x08, 0x22, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x23, 0x22, 0x01, 0x00,
636 0x00, 0x00, 0x00, 0x08, 0x24, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x24, 0x01, 0x00,
638 0x00, 0x00, 0x00, 0x08, 0x26, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x27, 0x26, 0x01, 0x00,
640 0x00, 0x00, 0x00, 0x08, 0x28, 0x27, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x29, 0x28, 0x01, 0x00,
642 0x00, 0x00, 0x00, 0x08, 0x2a, 0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2b, 0x2a, 0x01, 0x00,
644 0x00, 0x00, 0x00, 0x08, 0x2c, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2d, 0x2c, 0x01, 0x00,
646 0x00, 0x00, 0x00, 0x08, 0x2e, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2f, 0x2e, 0x01, 0x00,
648 0x00, 0x00, 0x00, 0x08, 0x30, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x30, 0x01, 0x00,
650 0x00, 0x00, 0x00, 0x08, 0x32, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x01, 0x00,
652 0x00, 0x00, 0x00, 0x08, 0x34, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x35, 0x34, 0x01, 0x00,
654 0x00, 0x00, 0x00, 0x08, 0x36, 0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x37, 0x36, 0x01, 0x00,
656 0x00, 0x00, 0x00, 0x08, 0x38, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x39, 0x38, 0x01, 0x00,
658 0x00, 0x00, 0x00, 0x08, 0x3a, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3b, 0x3a, 0x01, 0x00,
660 0x00, 0x00, 0x00, 0x08, 0x3c, 0x3b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3d, 0x3c, 0x01, 0x00,
662 0x00, 0x00, 0x00, 0x08, 0x3e, 0x3d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3f, 0x3e, 0x01, 0x00,
664 0x00, 0x00, 0x00, 0x08, 0x40, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x41, 0x40, 0x01, 0x00,
666 0x00, 0x00, 0x00, 0x08, 0x42, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43, 0x42, 0x01, 0x00,
668 0x00, 0x00, 0x00, 0x08, 0x44, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x45, 0x44, 0x01, 0x00,
670 0x00, 0x00, 0x00, 0x08, 0x46, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x46, 0x01, 0x00,
672 0x00, 0x00, 0x00, 0x08, 0x48, 0x47, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x48, 0x01, 0x00,
674 0x00, 0x00, 0x00, 0x08, 0x4a, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x4a, 0x01, 0x00,
676 0x00, 0x00, 0x00, 0x08, 0x4c, 0x4b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x4c, 0x01, 0x00,
678 0x00, 0x00, 0x00, 0x08, 0x4e, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4f, 0x4e, 0x01, 0x00,
680 0x00, 0x00, 0x00, 0x08, 0x50, 0x4f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x51, 0x50, 0x01, 0x00,
682 0x00, 0x00, 0x00, 0x08, 0x52, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x53, 0x52, 0x01, 0x00,
684 0x00, 0x00, 0x00, 0x08, 0x54, 0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x55, 0x54, 0x01, 0x00,
686 0x00, 0x00, 0x00, 0x08, 0x56, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x57, 0x56, 0x01, 0x00,
688 0x00, 0x00, 0x00, 0x08, 0x58, 0x57, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x59, 0x58, 0x01, 0x00,
690 0x00, 0x00, 0x00, 0x08, 0x5a, 0x59, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5b, 0x5a, 0x01, 0x00,
692 0x00, 0x00, 0x00, 0x08, 0x5c, 0x5b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5d, 0x5c, 0x01, 0x00,
694 0x00, 0x00, 0x00, 0x08, 0x5e, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, 0x5e, 0x01, 0x00,
696 0x00, 0x00, 0x00, 0x08, 0x60, 0x5f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x61, 0x60, 0x01, 0x00,
698 0x00, 0x00, 0x00, 0x08, 0x62, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, 0x62, 0x01, 0x00,
700 0x00, 0x00, 0x00, 0x08, 0x64, 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x65, 0x64, 0x01, 0x00,
702 0x00, 0x00, 0x00, 0x08, 0x66, 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x67, 0x66, 0x01, 0x00,
704 0x00, 0x00, 0x00, 0x08, 0x68, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x69, 0x68, 0x01, 0x00,
706 0x00, 0x00, 0x00, 0x08, 0x6a, 0x69, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6b, 0x6a, 0x01, 0x00,
708 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x6c, 0x01, 0x00,
710 0x00, 0x00, 0x00, 0x08, 0x6e, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6f, 0x6e, 0x01, 0x00,
712 0x00, 0x00, 0x00, 0x08, 0x70, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x71, 0x70, 0x01, 0x00,
714 0x00, 0x00, 0x00, 0x08, 0x72, 0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x73, 0x72, 0x01, 0x00,
716 0x00, 0x00, 0x00, 0x08, 0x74, 0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x75, 0x74, 0x01, 0x00,
718 0x00, 0x00, 0x00, 0x08, 0x76, 0x75, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x77, 0x76, 0x01, 0x00,
720 0x00, 0x00, 0x00, 0x08, 0x78, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x79, 0x78, 0x01, 0x00,
722 0x00, 0x00, 0x00, 0x08, 0x7a, 0x79, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7b, 0x7a, 0x01, 0x00,
724 0x00, 0x00, 0x00, 0x08, 0x7c, 0x7b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7d, 0x7c, 0x01, 0x00,
726 0x00, 0x00, 0x00, 0x08, 0x7e, 0x7d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7f, 0x7e, 0x01, 0x00,
728 0x00, 0x00, 0x00, 0x08, 0x80, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x81, 0x80, 0x01, 0x00,
730 0x00, 0x00, 0x00, 0x08, 0x82, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x83, 0x82, 0x01, 0x00,
732 0x00, 0x00, 0x00, 0x08, 0x84, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x85, 0x84, 0x01, 0x00,
734 0x00, 0x00, 0x00, 0x08, 0x86, 0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x87, 0x86, 0x01, 0x00,
736 0x00, 0x00, 0x00, 0x08, 0x88, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x89, 0x88, 0x01, 0x00,
738 0x00, 0x00, 0x00, 0x08, 0x8a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x8b, 0x8a, 0x01, 0x00,
740 0x00, 0x00, 0x00, 0x08, 0x8c, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x8d, 0x8c, 0x01, 0x00,
742 0x00, 0x00, 0x00, 0x08, 0x8e, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x8f, 0x8e, 0x01, 0x00,
744 0x00, 0x00, 0x00, 0x08, 0x90, 0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x91, 0x90, 0x01, 0x00,
746 0x00, 0x00, 0x00, 0x08, 0x92, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x93, 0x92, 0x01, 0x00,
748 0x00, 0x00, 0x00, 0x08, 0x94, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x95, 0x94, 0x01, 0x00,
750 0x00, 0x00, 0x00, 0x08, 0x96, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x97, 0x96, 0x01, 0x00,
752 0x00, 0x00, 0x00, 0x08, 0x98, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x99, 0x98, 0x01, 0x00,
754 0x00, 0x00, 0x00, 0x08, 0x9a, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x9b, 0x9a, 0x01, 0x00,
756 0x00, 0x00, 0x00, 0x08, 0x9c, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x9d, 0x9c, 0x01, 0x00,
758 0x00, 0x00, 0x00, 0x08, 0x9e, 0x9d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x9f, 0x9e, 0x01, 0x00,
760 0x00, 0x00, 0x00, 0x08, 0xa0, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa1, 0xa0, 0x01, 0x00,
762 0x00, 0x00, 0x00, 0x08, 0xa2, 0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa3, 0xa2, 0x01, 0x00,
764 0x00, 0x00, 0x00, 0x08, 0xa4, 0xa3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa5, 0xa4, 0x01, 0x00,
766 0x00, 0x00, 0x00, 0x08, 0xa6, 0xa5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa7, 0xa6, 0x01, 0x00,
768 0x00, 0x00, 0x00, 0x08, 0xa8, 0xa7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa9, 0xa8, 0x01, 0x00,
770 0x00, 0x00, 0x00, 0x08, 0xaa, 0xa9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xab, 0xaa, 0x01, 0x00,
772 0x00, 0x00, 0x00, 0x08, 0xac, 0xab, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xad, 0xac, 0x01, 0x00,
774 0x00, 0x00, 0x00, 0x08, 0xae, 0xad, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xaf, 0xae, 0x01, 0x00,
776 0x00, 0x00, 0x00, 0x08, 0xb0, 0xaf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb1, 0xb0, 0x01, 0x00,
778 0x00, 0x00, 0x00, 0x08, 0xb2, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb3, 0xb2, 0x01, 0x00,
780 0x00, 0x00, 0x00, 0x08, 0xb4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb5, 0xb4, 0x01, 0x00,
782 0x00, 0x00, 0x00, 0x08, 0xb6, 0xb5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb7, 0xb6, 0x01, 0x00,
784 0x00, 0x00, 0x00, 0x08, 0xb8, 0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0xb8, 0x01, 0x00,
786 0x00, 0x00, 0x00, 0x08, 0xba, 0xb9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbb, 0xba, 0x01, 0x00,
788 0x00, 0x00, 0x00, 0x08, 0xbc, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbd, 0xbc, 0x01, 0x00,
790 0x00, 0x00, 0x00, 0x08, 0xbe, 0xbd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbf, 0xbe, 0x01, 0x00,
792 0x00, 0x00, 0x00, 0x08, 0xc0, 0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc1, 0xc0, 0x01, 0x00,
794 0x00, 0x00, 0x00, 0x08, 0xc2, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc3, 0xc2, 0x01, 0x00,
796 0x00, 0x00, 0x00, 0x08, 0xc4, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc5, 0xc4, 0x01, 0x00,
798 0x00, 0x00, 0x00, 0x08, 0xc6, 0xc5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc7, 0xc6, 0x01, 0x00,
800 0x00, 0x00, 0x00, 0x08, 0xc8, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc9, 0xc8, 0x01, 0x00,
802 0x00, 0x00, 0x00, 0x08, 0xca, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xcb, 0xca, 0x01, 0x00,
804 0x00, 0x00, 0x00, 0x08, 0xcc, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xcd, 0xcc, 0x01, 0x00,
806 0x00, 0x00, 0x00, 0x08, 0xce, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xcf, 0xce, 0x01, 0x00,
808 0x00, 0x00, 0x00, 0x08, 0xd0, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd1, 0xd0, 0x01, 0x00,
810 0x00, 0x00, 0x00, 0x08, 0xd2, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd3, 0xd2, 0x01, 0x00,
812 0x00, 0x00, 0x00, 0x08, 0xd4, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd5, 0xd4, 0x01, 0x00,
814 0x00, 0x00, 0x00, 0x08, 0xd6, 0xd5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd7, 0xd6, 0x01, 0x00,
816 0x00, 0x00, 0x00, 0x08, 0xd8, 0xd7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd9, 0xd8, 0x01, 0x00,
818 0x00, 0x00, 0x00, 0x08, 0xda, 0xd9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xdb, 0xda, 0x01, 0x00,
820 0x00, 0x00, 0x00, 0x08, 0xdc, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xdd, 0xdc, 0x01, 0x00,
822 0x00, 0x00, 0x00, 0x08, 0xde, 0xdd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xdf, 0xde, 0x01, 0x00,
824 0x00, 0x00, 0x00, 0x08, 0xe0, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe1, 0xe0, 0x01, 0x00,
826 0x00, 0x00, 0x00, 0x08, 0xe2, 0xe1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe3, 0xe2, 0x01, 0x00,
828 0x00, 0x00, 0x00, 0x08, 0xe4, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe5, 0xe4, 0x01, 0x00,
830 0x00, 0x00, 0x00, 0x08, 0xe6, 0xe5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe7, 0xe6, 0x01, 0x00,
832 0x00, 0x00, 0x00, 0x08, 0xe8, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xe8, 0x01, 0x00,
834 0x00, 0x00, 0x00, 0x08, 0xea, 0xe9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xeb, 0xea, 0x01, 0x00,
836 0x00, 0x00, 0x00, 0x08, 0xec, 0xeb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xed, 0xec, 0x01, 0x00,
838 0x00, 0x00, 0x00, 0x08, 0xee, 0xed, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xef, 0xee, 0x01, 0x00,
840 0x00, 0x00, 0x00, 0x08, 0xf0, 0xef, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xf0, 0x01, 0x00,
842 0x00, 0x00, 0x00, 0x08, 0xf2, 0xf1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf3, 0xf2, 0x01, 0x00,
844 0x00, 0x00, 0x00, 0x08, 0xf4, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf5, 0xf4, 0x01, 0x00,
846 0x00, 0x00, 0x00, 0x08, 0xf6, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf7, 0xf6, 0x01, 0x00,
848 0x00, 0x00, 0x00, 0x08, 0xf8, 0xf7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf9, 0xf8, 0x01, 0x00,
850 0x00, 0x00, 0x00, 0x08, 0xfa, 0xf9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfb, 0xfa, 0x01, 0x00,
852 0x00, 0x00, 0x00, 0x08, 0xfc, 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfd, 0xfc, 0x01, 0x00,
854 0x00, 0x00, 0x00, 0x08, 0xfe, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xfe, 0x01, 0x00,
856 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
858 0x00, 0x00, ];
860
861 let madt = MadtParser::new(DATA).unwrap();
862
863 let entries = madt.entries().collect::<Result<Vec<_>, _>>().unwrap();
864
865 assert!(entries.len() == 256);
866 assert!(matches!(
867 entries[0],
868 MadtEntry::Apic(MadtApic {
869 typ: MadtType::APIC,
870 length: 8,
871 acpi_processor_uid: 1,
872 apic_id: 0,
873 flags: 1
874 })
875 ));
876 assert!(matches!(
877 entries[255],
878 MadtEntry::X2Apic(MadtX2Apic {
879 typ: MadtType::X2APIC,
880 length: 16,
881 reserved: 0,
882 x2_apic_id: 255,
883 flags: 1,
884 acpi_processor_uid: 256
885 })
886 ));
887
888 let entries = madt.parse_apic_ids().unwrap();
889
890 assert_eq!(entries, (0..256).map(Some).collect::<Vec<_>>());
891 }
892}