diff --git a/src/acpi/madt/mod.rs b/src/acpi/madt/mod.rs index 3159b9c4..c691eb8d 100644 --- a/src/acpi/madt/mod.rs +++ b/src/acpi/madt/mod.rs @@ -146,6 +146,52 @@ pub struct MadtGicd { _reserved2: [u8; 3], } +/// MADT Local x2APIC (entry type 0x9) +/// Used by modern AMD and Intel platforms with APIC IDs >= 255. +#[derive(Clone, Copy, Debug)] +#[repr(C, packed)] +pub struct MadtLocalX2Apic { + _reserved: u16, + pub x2apic_id: u32, + pub flags: u32, + pub processor_uid: u32, +} + +/// MADT Local APIC NMI (entry type 0x4) +/// Configures NMI routing to a processor's LINT0/LINT1 pin. +#[derive(Clone, Copy, Debug)] +#[repr(C, packed)] +pub struct MadtLocalApicNmi { + pub processor: u8, + pub flags: u16, + pub nmi_pin: u8, +} + +/// MADT Local APIC Address Override (entry type 0x5) +/// Provides 64-bit override for the 32-bit local APIC address. +#[derive(Clone, Copy, Debug)] +#[repr(C, packed)] +pub struct MadtLapicAddressOverride { + _reserved: u16, + pub local_apic_address: u64, +} + +/// MADT Local x2APIC NMI (entry type 0xA) +/// x2APIC equivalent of type 0x4 for APIC IDs >= 255. +#[derive(Clone, Copy, Debug)] +#[repr(C, packed)] +pub struct MadtLocalX2ApicNmi { + _reserved: u16, + pub processor_uid: u32, + pub flags: u16, + pub nmi_pin: u8, + _reserved2: u8, +} + +const _: () = assert!(size_of::() == 4); +const _: () = assert!(size_of::() == 10); +const _: () = assert!(size_of::() == 10); + /// MADT Entries #[derive(Debug)] #[allow(dead_code)] @@ -160,6 +206,14 @@ pub enum MadtEntry { InvalidGicc(usize), Gicd(&'static MadtGicd), InvalidGicd(usize), + LocalX2Apic(&'static MadtLocalX2Apic), + InvalidLocalX2Apic(usize), + LocalApicNmi(&'static MadtLocalApicNmi), + InvalidLocalApicNmi(usize), + LapicAddressOverride(&'static MadtLapicAddressOverride), + InvalidLapicAddressOverride(usize), + LocalX2ApicNmi(&'static MadtLocalX2ApicNmi), + InvalidLocalX2ApicNmi(usize), Unknown(u8), } @@ -176,6 +230,10 @@ impl Iterator for MadtIter { let entry_len = unsafe { *(self.sdt.data_address() as *const u8).add(self.i + 1) } as usize; + if entry_len < 2 { + return None; + } + if self.i + entry_len <= self.sdt.data_len() { let item = match entry_type { 0x0 => { @@ -224,6 +282,44 @@ impl Iterator for MadtIter { MadtEntry::InvalidGicd(entry_len) } } + 0x9 => { + if entry_len == size_of::() + 2 { + MadtEntry::LocalX2Apic(unsafe { + &*((self.sdt.data_address() + self.i + 2) as *const MadtLocalX2Apic) + }) + } else { + MadtEntry::InvalidLocalX2Apic(entry_len) + } + } + 0x4 => { + if entry_len == size_of::() + 2 { + MadtEntry::LocalApicNmi(unsafe { + &*((self.sdt.data_address() + self.i + 2) as *const MadtLocalApicNmi) + }) + } else { + MadtEntry::InvalidLocalApicNmi(entry_len) + } + } + 0x5 => { + if entry_len == size_of::() + 2 { + MadtEntry::LapicAddressOverride(unsafe { + &*((self.sdt.data_address() + self.i + 2) + as *const MadtLapicAddressOverride) + }) + } else { + MadtEntry::InvalidLapicAddressOverride(entry_len) + } + } + 0xA => { + if entry_len == size_of::() + 2 { + MadtEntry::LocalX2ApicNmi(unsafe { + &*((self.sdt.data_address() + self.i + 2) + as *const MadtLocalX2ApicNmi) + }) + } else { + MadtEntry::InvalidLocalX2ApicNmi(entry_len) + } + } _ => MadtEntry::Unknown(entry_type), };