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