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 GIC_MSI_FRAME = 0xd,
46 GIC_ITS = 0xf,
47 }
48}
49
50#[repr(C, packed)]
51#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
52pub struct MadtEntryHeader {
53 pub typ: MadtType,
54 pub length: u8,
55}
56
57#[repr(C, packed)]
58#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
59pub struct MadtApic {
60 pub typ: MadtType,
61 pub length: u8,
62 pub acpi_processor_uid: u8,
63 pub apic_id: u8,
64 pub flags: u32,
65}
66
67const_assert_eq!(size_of::<MadtApic>(), 8);
68
69impl MadtApic {
70 pub fn new() -> Self {
71 Self {
72 typ: MadtType::APIC,
73 length: size_of::<Self>() as u8,
74 acpi_processor_uid: 0,
75 apic_id: 0,
76 flags: 0,
77 }
78 }
79}
80
81pub const MADT_APIC_ENABLED: u32 = 1 << 0;
82pub const MADT_APIC_ONLINE_CAPABLE: u32 = 1 << 1;
83
84#[repr(C, packed)]
85#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
86pub struct MadtX2Apic {
87 pub typ: MadtType,
88 pub length: u8,
89 pub reserved: u16,
90 pub x2_apic_id: u32,
91 pub flags: u32,
92 pub acpi_processor_uid: u32,
93}
94
95const_assert_eq!(size_of::<MadtX2Apic>(), 16);
96
97impl MadtX2Apic {
98 pub fn new() -> Self {
99 Self {
100 typ: MadtType::X2APIC,
101 length: size_of::<Self>() as u8,
102 reserved: 0,
103 x2_apic_id: 0,
104 flags: 0,
105 acpi_processor_uid: 0,
106 }
107 }
108}
109
110#[repr(C, packed)]
111#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
112pub struct MadtIoApic {
113 pub typ: MadtType,
114 pub length: u8,
115 pub io_apic_id: u8,
116 pub rsvd: u8,
117 pub io_apic_address: u32,
118 pub global_system_interrupt_base: u32,
119}
120
121const_assert_eq!(size_of::<MadtIoApic>(), 12);
122
123impl MadtIoApic {
124 pub fn new() -> Self {
125 Self {
126 typ: MadtType::IO_APIC,
127 length: size_of::<Self>() as u8,
128 io_apic_id: 0,
129 rsvd: 0,
130 io_apic_address: 0,
131 global_system_interrupt_base: 0,
132 }
133 }
134}
135
136#[repr(C, packed)]
137#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
138pub struct MadtInterruptSourceOverride {
139 pub typ: MadtType,
140 pub length: u8,
141 pub bus: u8,
142 pub source: u8,
143 pub gsi: u32,
144 pub flags: u16,
145}
146
147const_assert_eq!(size_of::<MadtInterruptSourceOverride>(), 10);
148
149pub enum InterruptPolarity {
150 ActiveLow,
151 ActiveHigh,
152}
153
154pub enum InterruptTriggerMode {
155 Edge,
156 Level,
157}
158
159impl MadtInterruptSourceOverride {
160 pub fn new(
161 source: u8,
162 gsi: u32,
163 polarity: Option<InterruptPolarity>,
164 trigger_mode: Option<InterruptTriggerMode>,
165 ) -> Self {
166 Self {
167 typ: MadtType::INTERRUPT_SOURCE_OVERRIDE,
168 length: size_of::<Self>() as u8,
169 bus: 0,
170 source,
171 gsi,
172 flags: match polarity {
173 None => 0,
174 Some(InterruptPolarity::ActiveHigh) => 1,
175 Some(InterruptPolarity::ActiveLow) => 3,
176 } | (match trigger_mode {
177 None => 0,
178 Some(InterruptTriggerMode::Edge) => 1,
179 Some(InterruptTriggerMode::Level) => 3,
180 } << 2),
181 }
182 }
183}
184
185#[repr(C, packed)]
187#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
188pub struct MadtLocalNmiSource {
189 pub typ: MadtType,
190 pub length: u8,
191 pub acpi_processor_uid: u8,
192 pub flags: u16,
193 pub local_apic_lint: u8,
194}
195
196const_assert_eq!(size_of::<MadtLocalNmiSource>(), 6);
197
198impl MadtLocalNmiSource {
199 pub fn new() -> Self {
200 Self {
201 typ: MadtType::LOCAL_NMI_SOURCE,
202 length: size_of::<Self>() as u8,
203 acpi_processor_uid: 1, flags: 0,
205 local_apic_lint: 1,
206 }
207 }
208}
209
210#[repr(C)]
211#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
212pub struct MadtGicd {
213 pub typ: MadtType,
214 pub length: u8,
215 pub reserved: u16,
216 pub gic_id: u32,
217 pub base_address: u64,
218 pub reserved2: u32,
219 pub gic_version: u8,
220 pub reserved3: [u8; 3],
221}
222
223const_assert_eq!(size_of::<MadtGicd>(), 24);
224
225impl MadtGicd {
226 pub fn new(gic_id: u32, base_address: u64, gic_version: u8) -> Self {
227 Self {
228 typ: MadtType::GICD,
229 length: size_of::<Self>() as u8,
230 reserved: 0,
231 gic_id,
232 base_address,
233 reserved2: 0,
234 gic_version,
235 reserved3: [0; 3],
236 }
237 }
238}
239
240#[repr(C)]
242#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
243pub struct MadtGicMsiFrame {
244 pub typ: MadtType,
245 pub length: u8,
246 pub reserved: u16,
247 pub gic_msi_frame_id: u32,
248 pub base_address: u64,
249 pub flags: u32,
250 pub spi_count: u16,
251 pub spi_base: u16,
252}
253
254const_assert_eq!(size_of::<MadtGicMsiFrame>(), 24);
255
256pub const GIC_MSI_FRAME_FLAGS_SPI_SELECT: u32 = 1 << 0;
257
258impl MadtGicMsiFrame {
259 pub fn new(gic_msi_frame_id: u32, base_address: u64, spi_base: u16, spi_count: u16) -> Self {
260 Self {
261 typ: MadtType::GIC_MSI_FRAME,
262 length: size_of::<Self>() as u8,
263 reserved: 0,
264 gic_msi_frame_id,
265 base_address,
266 flags: GIC_MSI_FRAME_FLAGS_SPI_SELECT,
267 spi_count,
268 spi_base,
269 }
270 }
271}
272
273#[repr(C, packed)]
275#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)]
276pub struct MadtGicIts {
277 pub typ: MadtType,
278 pub length: u8,
279 pub reserved: u16,
280 pub gic_its_id: u32,
281 pub base_address: u64,
282 pub reserved2: u32,
283}
284
285const_assert_eq!(size_of::<MadtGicIts>(), 20);
286
287impl MadtGicIts {
288 pub fn new(gic_its_id: u32, base_address: u64) -> Self {
289 Self {
290 typ: MadtType::GIC_ITS,
291 length: size_of::<Self>() as u8,
292 reserved: 0,
293 gic_its_id,
294 base_address,
295 reserved2: 0,
296 }
297 }
298}
299
300#[repr(C)]
303#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned)]
304pub struct MadtGicc {
305 pub typ: MadtType,
306 pub length: u8,
307 pub reserved: [u8; 2],
308 pub cpu_interface_number: U32<LE>,
309 pub acpi_processor_uid: U32<LE>,
310 pub flags: U32<LE>,
311 pub parking_protocol_version: U32<LE>,
312 pub performance_monitoring_gsiv: U32<LE>,
313 pub parked_address: U64<LE>,
314 pub base_address: U64<LE>,
315 pub gicv: U64<LE>,
316 pub gich: U64<LE>,
317 pub vgic_maintenance_interrupt: U32<LE>,
318 pub gicr_base_address: U64<LE>,
319 pub mpidr: U64<LE>,
320 pub processor_power_efficiency_class: u8,
321 pub reserved2: u8,
322 pub spe_overflow_interrupt: U16<LE>,
323}
324
325const_assert_eq!(size_of::<MadtGicc>(), 80);
326
327impl MadtGicc {
328 pub fn new(acpi_processor_uid: u32, mpidr: u64) -> Self {
329 Self {
330 typ: MadtType::GICC,
331 length: size_of::<Self>() as u8,
332 flags: u32::from(MadtGiccFlags::new().with_enabled(true)).into(),
333 acpi_processor_uid: acpi_processor_uid.into(),
334 mpidr: mpidr.into(),
335 ..Self::new_zeroed()
336 }
337 }
338}
339
340#[bitfield(u32)]
341pub struct MadtGiccFlags {
342 pub enabled: bool,
343 #[bits(31)]
344 _reserved: u32,
345}
346
347pub struct MadtParser<'a>(&'a [u8]);
349
350impl<'a> MadtParser<'a> {
351 pub fn new(table: &'a [u8]) -> Result<Self, ParserError> {
353 let header = crate::Header::read_from_prefix(table)
354 .map_err(|_| ParserError)?
355 .0; if (header.length.get() as usize) < size_of::<Madt>() {
357 return Err(ParserError);
358 }
359 let off = size_of_val(&header);
360 let table = table
361 .get(off..header.length.get() as usize)
362 .ok_or(ParserError)?;
363 Ok(Self(table))
364 }
365
366 pub fn entries(&self) -> MadtIter<'_> {
368 MadtIter {
369 entries: &self.0[size_of::<Madt>()..],
370 }
371 }
372
373 #[cfg(feature = "alloc")]
376 pub fn parse_apic_ids(&self) -> Result<alloc::vec::Vec<Option<u32>>, ParseApicIdError> {
377 use alloc::vec::Vec;
378
379 let mut apic_ids: Vec<Option<u32>> = Vec::new();
380
381 for entry in self.entries() {
382 let (uid, apic_id) = match entry.map_err(ParseApicIdError::Parser)? {
383 MadtEntry::Apic(apic) => {
384 if apic.flags & MADT_APIC_ENABLED == MADT_APIC_ENABLED {
385 (apic.acpi_processor_uid as u32, apic.apic_id as u32)
386 } else {
387 continue;
388 }
389 }
390 MadtEntry::X2Apic(x2apic) => {
391 if x2apic.flags & MADT_APIC_ENABLED == MADT_APIC_ENABLED {
392 (x2apic.acpi_processor_uid, x2apic.x2_apic_id)
393 } else {
394 continue;
395 }
396 }
397 };
398
399 let index = uid as usize - 1;
401
402 if apic_ids.get(index).is_none() {
403 apic_ids.resize(index + 1, None);
404 }
405
406 if apic_ids[index].replace(apic_id).is_some() {
407 return Err(ParseApicIdError::ProcessorNotUnique(uid));
408 }
409 }
410
411 Ok(apic_ids)
412 }
413}
414
415#[derive(Debug, Error)]
417#[error("madt parsing failed")]
418pub struct ParserError;
419
420#[derive(Debug, thiserror::Error)]
422pub enum ParseApicIdError {
423 #[error("error parsing entry")]
424 Parser(#[source] ParserError),
425 #[error("processor_acpi_uid specified more than once in the MADT")]
426 ProcessorNotUnique(u32),
427}
428
429#[derive(Debug, Clone, Copy, PartialEq, Eq)]
431pub enum MadtEntry {
432 Apic(MadtApic),
434 X2Apic(MadtX2Apic),
436}
437
438pub struct MadtIter<'a> {
440 entries: &'a [u8],
441}
442
443impl MadtIter<'_> {
444 fn parse(&mut self) -> Result<Option<MadtEntry>, ParserError> {
445 while let Ok((header, _)) = MadtEntryHeader::read_from_prefix(self.entries) {
447 if self.entries.len() < header.length as usize {
449 return Err(ParserError);
450 }
451 let (buf, rest) = self.entries.split_at(header.length as usize);
452 self.entries = rest;
453 let entry = match header.typ {
454 MadtType::APIC => {
455 MadtEntry::Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0)
456 }
458 MadtType::X2APIC => {
459 MadtEntry::X2Apic(FromBytes::read_from_prefix(buf).map_err(|_| ParserError)?.0)
460 }
462 _ => continue,
463 };
464 return Ok(Some(entry));
465 }
466 Ok(None)
467 }
468}
469
470impl Iterator for MadtIter<'_> {
471 type Item = Result<MadtEntry, ParserError>;
472
473 fn next(&mut self) -> Option<Self::Item> {
474 self.parse().transpose()
475 }
476}
477
478#[cfg(test)]
480mod test {
481 use super::*;
482 #[cfg(feature = "alloc")]
483 use alloc::vec;
484 #[cfg(feature = "alloc")]
485 use alloc::vec::Vec;
486
487 #[test]
489 #[cfg(feature = "alloc")]
490 fn sparse_madt() {
491 const DATA: &[u8] = &[
492 65, 80, 73, 67, 194, 0, 0, 0, 5, 195, 72, 86, 76, 73, 84, 69, 72, 86, 76, 73, 84, 69,
493 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,
494 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,
495 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,
496 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,
497 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,
498 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,
499 0, 0, 8, 32, 15, 1, 0, 0, 0,
500 ];
501
502 let madt = MadtParser::new(DATA).unwrap();
503 let entries = madt.parse_apic_ids().unwrap();
504
505 assert_eq!(
506 entries,
507 vec![
508 Some(0),
509 None,
510 None,
511 Some(1),
512 None,
513 Some(2),
514 None,
515 Some(3),
516 None,
517 Some(4),
518 None,
519 Some(5),
520 None,
521 Some(6),
522 None,
523 Some(7),
524 None,
525 Some(8),
526 None,
527 Some(9),
528 None,
529 Some(10),
530 None,
531 Some(11),
532 None,
533 Some(12),
534 None,
535 Some(13),
536 None,
537 Some(14),
538 None,
539 Some(15)
540 ]
541 );
542 }
543
544 #[test]
545 fn single_apic() {
546 const DATA: &[u8] = &[
548 0x41, 0x50, 0x49, 0x43, 0x50, 0x00, 0x00, 0x00, 0x04, 0x23, 0x56, 0x52, 0x54, 0x55,
549 0x41, 0x4c, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00,
550 0x4d, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0x00, 0x00,
551 0x00, 0x00, 0x01, 0x0c, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
552 0x02, 0x0a, 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x06, 0x01, 0x00,
553 0x00, 0x01, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
554 ];
555
556 let madt = MadtParser::new(DATA).unwrap();
557
558 let entries = madt.entries().collect::<Result<Vec<_>, _>>().unwrap();
559
560 assert_eq!(
561 entries[0],
562 MadtEntry::Apic(MadtApic {
563 typ: MadtType::APIC,
564 length: 8,
565 acpi_processor_uid: 1,
566 apic_id: 0,
567 flags: 1,
568 })
569 );
570 }
571
572 #[test]
573 #[cfg(feature = "alloc")]
574 fn madt_50_vps() {
575 const DATA: &[u8] = &[
576 0x41, 0x50, 0x49, 0x43, 0xd8, 0x01, 0x00, 0x00, 0x04, 0x06, 0x56, 0x52, 0x54, 0x55,
577 0x41, 0x4c, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x53,
579 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a,
581 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x06, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0c,
583 0x32, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00,
585 0x00, 0x00, 0x00, 0x08, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x02, 0x01, 0x00,
587 0x00, 0x00, 0x00, 0x08, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x04, 0x01, 0x00,
589 0x00, 0x00, 0x00, 0x08, 0x06, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x01, 0x00,
591 0x00, 0x00, 0x00, 0x08, 0x08, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x08, 0x01, 0x00,
593 0x00, 0x00, 0x00, 0x08, 0x0a, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x0a, 0x01, 0x00,
595 0x00, 0x00, 0x00, 0x08, 0x0c, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0x0c, 0x01, 0x00,
597 0x00, 0x00, 0x00, 0x08, 0x0e, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x11, 0x01, 0x00,
599 0x00, 0x00, 0x00, 0x08, 0x10, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x13, 0x01, 0x00,
601 0x00, 0x00, 0x00, 0x08, 0x12, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x13, 0x15, 0x01, 0x00,
603 0x00, 0x00, 0x00, 0x08, 0x14, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x15, 0x17, 0x01, 0x00,
605 0x00, 0x00, 0x00, 0x08, 0x16, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x17, 0x19, 0x01, 0x00,
607 0x00, 0x00, 0x00, 0x08, 0x18, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x1b, 0x01, 0x00,
609 0x00, 0x00, 0x00, 0x08, 0x1a, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1b, 0x20, 0x01, 0x00,
611 0x00, 0x00, 0x00, 0x08, 0x1c, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0x22, 0x01, 0x00,
613 0x00, 0x00, 0x00, 0x08, 0x1e, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1f, 0x24, 0x01, 0x00,
615 0x00, 0x00, 0x00, 0x08, 0x20, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x26, 0x01, 0x00,
617 0x00, 0x00, 0x00, 0x08, 0x22, 0x27, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x23, 0x28, 0x01, 0x00,
619 0x00, 0x00, 0x00, 0x08, 0x24, 0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x2a, 0x01, 0x00,
621 0x00, 0x00, 0x00, 0x08, 0x26, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x27, 0x30, 0x01, 0x00,
623 0x00, 0x00, 0x00, 0x08, 0x28, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x29, 0x32, 0x01, 0x00,
625 0x00, 0x00, 0x00, 0x08, 0x2a, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2b, 0x34, 0x01, 0x00,
627 0x00, 0x00, 0x00, 0x08, 0x2c, 0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2d, 0x36, 0x01, 0x00,
629 0x00, 0x00, 0x00, 0x08, 0x2e, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2f, 0x38, 0x01, 0x00,
631 0x00, 0x00, 0x00, 0x08, 0x30, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x3a, 0x01, 0x00,
633 0x00, 0x00, 0x00, 0x08, 0x32, 0x3b, 0x01, 0x00, 0x00, 0x00, ];
636
637 let madt = MadtParser::new(DATA).unwrap();
638
639 let entries = madt.entries().collect::<Result<Vec<_>, _>>().unwrap();
640
641 assert_eq!(entries.len(), 50);
642 assert!(matches!(
643 entries[0],
644 MadtEntry::Apic(MadtApic {
645 typ: MadtType::APIC,
646 length: 8,
647 acpi_processor_uid: 1,
648 apic_id: 0,
649 flags: 1
650 })
651 ));
652 assert!(matches!(
653 entries[49],
654 MadtEntry::Apic(MadtApic {
655 typ: MadtType::APIC,
656 length: 8,
657 acpi_processor_uid: 50,
658 apic_id: 59,
659 flags: 1
660 })
661 ));
662
663 let entries = madt.parse_apic_ids().unwrap();
664
665 assert_eq!(
666 entries,
667 (0..13)
668 .chain(16..29)
669 .chain(32..44)
670 .chain(48..60)
671 .map(Some)
672 .collect::<Vec<_>>()
673 );
674 }
675
676 #[test]
677 #[cfg(feature = "alloc")]
678 fn madt_256() {
679 const DATA: &[u8] = &[
680 0x41, 0x50, 0x49, 0x43, 0x50, 0x08, 0x00, 0x00, 0x04, 0x14, 0x56, 0x52, 0x54, 0x55,
681 0x41, 0x4c, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x53,
683 0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a,
685 0x00, 0x09, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x04, 0x06, 0x01, 0x00, 0x00, 0x01, 0x01, 0x0c,
687 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x00,
689 0x00, 0x00, 0x00, 0x08, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x03, 0x02, 0x01, 0x00,
691 0x00, 0x00, 0x00, 0x08, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x04, 0x01, 0x00,
693 0x00, 0x00, 0x00, 0x08, 0x06, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x01, 0x00,
695 0x00, 0x00, 0x00, 0x08, 0x08, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x08, 0x01, 0x00,
697 0x00, 0x00, 0x00, 0x08, 0x0a, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x0a, 0x01, 0x00,
699 0x00, 0x00, 0x00, 0x08, 0x0c, 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0d, 0x0c, 0x01, 0x00,
701 0x00, 0x00, 0x00, 0x08, 0x0e, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x0e, 0x01, 0x00,
703 0x00, 0x00, 0x00, 0x08, 0x10, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x10, 0x01, 0x00,
705 0x00, 0x00, 0x00, 0x08, 0x12, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x13, 0x12, 0x01, 0x00,
707 0x00, 0x00, 0x00, 0x08, 0x14, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x15, 0x14, 0x01, 0x00,
709 0x00, 0x00, 0x00, 0x08, 0x16, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x17, 0x16, 0x01, 0x00,
711 0x00, 0x00, 0x00, 0x08, 0x18, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x18, 0x01, 0x00,
713 0x00, 0x00, 0x00, 0x08, 0x1a, 0x19, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1b, 0x1a, 0x01, 0x00,
715 0x00, 0x00, 0x00, 0x08, 0x1c, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1d, 0x1c, 0x01, 0x00,
717 0x00, 0x00, 0x00, 0x08, 0x1e, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1f, 0x1e, 0x01, 0x00,
719 0x00, 0x00, 0x00, 0x08, 0x20, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x20, 0x01, 0x00,
721 0x00, 0x00, 0x00, 0x08, 0x22, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x23, 0x22, 0x01, 0x00,
723 0x00, 0x00, 0x00, 0x08, 0x24, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x24, 0x01, 0x00,
725 0x00, 0x00, 0x00, 0x08, 0x26, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x27, 0x26, 0x01, 0x00,
727 0x00, 0x00, 0x00, 0x08, 0x28, 0x27, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x29, 0x28, 0x01, 0x00,
729 0x00, 0x00, 0x00, 0x08, 0x2a, 0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2b, 0x2a, 0x01, 0x00,
731 0x00, 0x00, 0x00, 0x08, 0x2c, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2d, 0x2c, 0x01, 0x00,
733 0x00, 0x00, 0x00, 0x08, 0x2e, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2f, 0x2e, 0x01, 0x00,
735 0x00, 0x00, 0x00, 0x08, 0x30, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x30, 0x01, 0x00,
737 0x00, 0x00, 0x00, 0x08, 0x32, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x32, 0x01, 0x00,
739 0x00, 0x00, 0x00, 0x08, 0x34, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x35, 0x34, 0x01, 0x00,
741 0x00, 0x00, 0x00, 0x08, 0x36, 0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x37, 0x36, 0x01, 0x00,
743 0x00, 0x00, 0x00, 0x08, 0x38, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x39, 0x38, 0x01, 0x00,
745 0x00, 0x00, 0x00, 0x08, 0x3a, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3b, 0x3a, 0x01, 0x00,
747 0x00, 0x00, 0x00, 0x08, 0x3c, 0x3b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3d, 0x3c, 0x01, 0x00,
749 0x00, 0x00, 0x00, 0x08, 0x3e, 0x3d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3f, 0x3e, 0x01, 0x00,
751 0x00, 0x00, 0x00, 0x08, 0x40, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x41, 0x40, 0x01, 0x00,
753 0x00, 0x00, 0x00, 0x08, 0x42, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43, 0x42, 0x01, 0x00,
755 0x00, 0x00, 0x00, 0x08, 0x44, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x45, 0x44, 0x01, 0x00,
757 0x00, 0x00, 0x00, 0x08, 0x46, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x46, 0x01, 0x00,
759 0x00, 0x00, 0x00, 0x08, 0x48, 0x47, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x48, 0x01, 0x00,
761 0x00, 0x00, 0x00, 0x08, 0x4a, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4b, 0x4a, 0x01, 0x00,
763 0x00, 0x00, 0x00, 0x08, 0x4c, 0x4b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x4c, 0x01, 0x00,
765 0x00, 0x00, 0x00, 0x08, 0x4e, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4f, 0x4e, 0x01, 0x00,
767 0x00, 0x00, 0x00, 0x08, 0x50, 0x4f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x51, 0x50, 0x01, 0x00,
769 0x00, 0x00, 0x00, 0x08, 0x52, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x53, 0x52, 0x01, 0x00,
771 0x00, 0x00, 0x00, 0x08, 0x54, 0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x55, 0x54, 0x01, 0x00,
773 0x00, 0x00, 0x00, 0x08, 0x56, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x57, 0x56, 0x01, 0x00,
775 0x00, 0x00, 0x00, 0x08, 0x58, 0x57, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x59, 0x58, 0x01, 0x00,
777 0x00, 0x00, 0x00, 0x08, 0x5a, 0x59, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5b, 0x5a, 0x01, 0x00,
779 0x00, 0x00, 0x00, 0x08, 0x5c, 0x5b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5d, 0x5c, 0x01, 0x00,
781 0x00, 0x00, 0x00, 0x08, 0x5e, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, 0x5e, 0x01, 0x00,
783 0x00, 0x00, 0x00, 0x08, 0x60, 0x5f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x61, 0x60, 0x01, 0x00,
785 0x00, 0x00, 0x00, 0x08, 0x62, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, 0x62, 0x01, 0x00,
787 0x00, 0x00, 0x00, 0x08, 0x64, 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x65, 0x64, 0x01, 0x00,
789 0x00, 0x00, 0x00, 0x08, 0x66, 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x67, 0x66, 0x01, 0x00,
791 0x00, 0x00, 0x00, 0x08, 0x68, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x69, 0x68, 0x01, 0x00,
793 0x00, 0x00, 0x00, 0x08, 0x6a, 0x69, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6b, 0x6a, 0x01, 0x00,
795 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x6c, 0x01, 0x00,
797 0x00, 0x00, 0x00, 0x08, 0x6e, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6f, 0x6e, 0x01, 0x00,
799 0x00, 0x00, 0x00, 0x08, 0x70, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x71, 0x70, 0x01, 0x00,
801 0x00, 0x00, 0x00, 0x08, 0x72, 0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x73, 0x72, 0x01, 0x00,
803 0x00, 0x00, 0x00, 0x08, 0x74, 0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x75, 0x74, 0x01, 0x00,
805 0x00, 0x00, 0x00, 0x08, 0x76, 0x75, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x77, 0x76, 0x01, 0x00,
807 0x00, 0x00, 0x00, 0x08, 0x78, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x79, 0x78, 0x01, 0x00,
809 0x00, 0x00, 0x00, 0x08, 0x7a, 0x79, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7b, 0x7a, 0x01, 0x00,
811 0x00, 0x00, 0x00, 0x08, 0x7c, 0x7b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7d, 0x7c, 0x01, 0x00,
813 0x00, 0x00, 0x00, 0x08, 0x7e, 0x7d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7f, 0x7e, 0x01, 0x00,
815 0x00, 0x00, 0x00, 0x08, 0x80, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x81, 0x80, 0x01, 0x00,
817 0x00, 0x00, 0x00, 0x08, 0x82, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x83, 0x82, 0x01, 0x00,
819 0x00, 0x00, 0x00, 0x08, 0x84, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x85, 0x84, 0x01, 0x00,
821 0x00, 0x00, 0x00, 0x08, 0x86, 0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x87, 0x86, 0x01, 0x00,
823 0x00, 0x00, 0x00, 0x08, 0x88, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x89, 0x88, 0x01, 0x00,
825 0x00, 0x00, 0x00, 0x08, 0x8a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x8b, 0x8a, 0x01, 0x00,
827 0x00, 0x00, 0x00, 0x08, 0x8c, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x8d, 0x8c, 0x01, 0x00,
829 0x00, 0x00, 0x00, 0x08, 0x8e, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x8f, 0x8e, 0x01, 0x00,
831 0x00, 0x00, 0x00, 0x08, 0x90, 0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x91, 0x90, 0x01, 0x00,
833 0x00, 0x00, 0x00, 0x08, 0x92, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x93, 0x92, 0x01, 0x00,
835 0x00, 0x00, 0x00, 0x08, 0x94, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x95, 0x94, 0x01, 0x00,
837 0x00, 0x00, 0x00, 0x08, 0x96, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x97, 0x96, 0x01, 0x00,
839 0x00, 0x00, 0x00, 0x08, 0x98, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x99, 0x98, 0x01, 0x00,
841 0x00, 0x00, 0x00, 0x08, 0x9a, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x9b, 0x9a, 0x01, 0x00,
843 0x00, 0x00, 0x00, 0x08, 0x9c, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x9d, 0x9c, 0x01, 0x00,
845 0x00, 0x00, 0x00, 0x08, 0x9e, 0x9d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x9f, 0x9e, 0x01, 0x00,
847 0x00, 0x00, 0x00, 0x08, 0xa0, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa1, 0xa0, 0x01, 0x00,
849 0x00, 0x00, 0x00, 0x08, 0xa2, 0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa3, 0xa2, 0x01, 0x00,
851 0x00, 0x00, 0x00, 0x08, 0xa4, 0xa3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa5, 0xa4, 0x01, 0x00,
853 0x00, 0x00, 0x00, 0x08, 0xa6, 0xa5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa7, 0xa6, 0x01, 0x00,
855 0x00, 0x00, 0x00, 0x08, 0xa8, 0xa7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa9, 0xa8, 0x01, 0x00,
857 0x00, 0x00, 0x00, 0x08, 0xaa, 0xa9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xab, 0xaa, 0x01, 0x00,
859 0x00, 0x00, 0x00, 0x08, 0xac, 0xab, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xad, 0xac, 0x01, 0x00,
861 0x00, 0x00, 0x00, 0x08, 0xae, 0xad, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xaf, 0xae, 0x01, 0x00,
863 0x00, 0x00, 0x00, 0x08, 0xb0, 0xaf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb1, 0xb0, 0x01, 0x00,
865 0x00, 0x00, 0x00, 0x08, 0xb2, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb3, 0xb2, 0x01, 0x00,
867 0x00, 0x00, 0x00, 0x08, 0xb4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb5, 0xb4, 0x01, 0x00,
869 0x00, 0x00, 0x00, 0x08, 0xb6, 0xb5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb7, 0xb6, 0x01, 0x00,
871 0x00, 0x00, 0x00, 0x08, 0xb8, 0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0xb8, 0x01, 0x00,
873 0x00, 0x00, 0x00, 0x08, 0xba, 0xb9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbb, 0xba, 0x01, 0x00,
875 0x00, 0x00, 0x00, 0x08, 0xbc, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbd, 0xbc, 0x01, 0x00,
877 0x00, 0x00, 0x00, 0x08, 0xbe, 0xbd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbf, 0xbe, 0x01, 0x00,
879 0x00, 0x00, 0x00, 0x08, 0xc0, 0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc1, 0xc0, 0x01, 0x00,
881 0x00, 0x00, 0x00, 0x08, 0xc2, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc3, 0xc2, 0x01, 0x00,
883 0x00, 0x00, 0x00, 0x08, 0xc4, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc5, 0xc4, 0x01, 0x00,
885 0x00, 0x00, 0x00, 0x08, 0xc6, 0xc5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc7, 0xc6, 0x01, 0x00,
887 0x00, 0x00, 0x00, 0x08, 0xc8, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc9, 0xc8, 0x01, 0x00,
889 0x00, 0x00, 0x00, 0x08, 0xca, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xcb, 0xca, 0x01, 0x00,
891 0x00, 0x00, 0x00, 0x08, 0xcc, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xcd, 0xcc, 0x01, 0x00,
893 0x00, 0x00, 0x00, 0x08, 0xce, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xcf, 0xce, 0x01, 0x00,
895 0x00, 0x00, 0x00, 0x08, 0xd0, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd1, 0xd0, 0x01, 0x00,
897 0x00, 0x00, 0x00, 0x08, 0xd2, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd3, 0xd2, 0x01, 0x00,
899 0x00, 0x00, 0x00, 0x08, 0xd4, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd5, 0xd4, 0x01, 0x00,
901 0x00, 0x00, 0x00, 0x08, 0xd6, 0xd5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd7, 0xd6, 0x01, 0x00,
903 0x00, 0x00, 0x00, 0x08, 0xd8, 0xd7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xd9, 0xd8, 0x01, 0x00,
905 0x00, 0x00, 0x00, 0x08, 0xda, 0xd9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xdb, 0xda, 0x01, 0x00,
907 0x00, 0x00, 0x00, 0x08, 0xdc, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xdd, 0xdc, 0x01, 0x00,
909 0x00, 0x00, 0x00, 0x08, 0xde, 0xdd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xdf, 0xde, 0x01, 0x00,
911 0x00, 0x00, 0x00, 0x08, 0xe0, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe1, 0xe0, 0x01, 0x00,
913 0x00, 0x00, 0x00, 0x08, 0xe2, 0xe1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe3, 0xe2, 0x01, 0x00,
915 0x00, 0x00, 0x00, 0x08, 0xe4, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe5, 0xe4, 0x01, 0x00,
917 0x00, 0x00, 0x00, 0x08, 0xe6, 0xe5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe7, 0xe6, 0x01, 0x00,
919 0x00, 0x00, 0x00, 0x08, 0xe8, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xe8, 0x01, 0x00,
921 0x00, 0x00, 0x00, 0x08, 0xea, 0xe9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xeb, 0xea, 0x01, 0x00,
923 0x00, 0x00, 0x00, 0x08, 0xec, 0xeb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xed, 0xec, 0x01, 0x00,
925 0x00, 0x00, 0x00, 0x08, 0xee, 0xed, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xef, 0xee, 0x01, 0x00,
927 0x00, 0x00, 0x00, 0x08, 0xf0, 0xef, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, 0xf0, 0x01, 0x00,
929 0x00, 0x00, 0x00, 0x08, 0xf2, 0xf1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf3, 0xf2, 0x01, 0x00,
931 0x00, 0x00, 0x00, 0x08, 0xf4, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf5, 0xf4, 0x01, 0x00,
933 0x00, 0x00, 0x00, 0x08, 0xf6, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf7, 0xf6, 0x01, 0x00,
935 0x00, 0x00, 0x00, 0x08, 0xf8, 0xf7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf9, 0xf8, 0x01, 0x00,
937 0x00, 0x00, 0x00, 0x08, 0xfa, 0xf9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfb, 0xfa, 0x01, 0x00,
939 0x00, 0x00, 0x00, 0x08, 0xfc, 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfd, 0xfc, 0x01, 0x00,
941 0x00, 0x00, 0x00, 0x08, 0xfe, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xfe, 0x01, 0x00,
943 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
945 0x00, 0x00, ];
947
948 let madt = MadtParser::new(DATA).unwrap();
949
950 let entries = madt.entries().collect::<Result<Vec<_>, _>>().unwrap();
951
952 assert!(entries.len() == 256);
953 assert!(matches!(
954 entries[0],
955 MadtEntry::Apic(MadtApic {
956 typ: MadtType::APIC,
957 length: 8,
958 acpi_processor_uid: 1,
959 apic_id: 0,
960 flags: 1
961 })
962 ));
963 assert!(matches!(
964 entries[255],
965 MadtEntry::X2Apic(MadtX2Apic {
966 typ: MadtType::X2APIC,
967 length: 16,
968 reserved: 0,
969 x2_apic_id: 255,
970 flags: 1,
971 acpi_processor_uid: 256
972 })
973 ));
974
975 let entries = madt.parse_apic_ids().unwrap();
976
977 assert_eq!(entries, (0..256).map(Some).collect::<Vec<_>>());
978 }
979}