瀏覽代碼

Parse MADT entries related to the X2APIC

We don't actually need to, and probably can't reliably, separate the APIC
and X2APIC at the ACPI level, as legacy OSs require X2APICs with UIDs less
than 256 to be defined with normal LAPIC entries, and so some OEMs decide
to ship tables that do this. The OSPM will need to detect support for the
X2APIC separately and then deal with this info accordingly.
Isaac Woods 3 年之前
父節點
當前提交
0ef11142c6
共有 1 個文件被更改,包括 42 次插入7 次删除
  1. 42 7
      acpi/src/madt.rs

+ 42 - 7
acpi/src/madt.rs

@@ -62,10 +62,12 @@ impl Madt {
         for entry in self.entries() {
             match entry {
                 MadtEntry::LocalApic(_) |
+                MadtEntry::LocalX2Apic(_) |
                 MadtEntry::IoApic(_) |
                 MadtEntry::InterruptSourceOverride(_) |
                 MadtEntry::NmiSource(_) |   // TODO: is this one used by more than one model?
                 MadtEntry::LocalApicNmi(_) |
+                MadtEntry::X2ApicNmi(_) |
                 MadtEntry::LocalApicAddressOverride(_) => {
                     return self.parse_apic_model();
                 }
@@ -76,11 +78,6 @@ impl Madt {
                     unimplemented!();
                 }
 
-                MadtEntry::LocalX2Apic(_) |
-                MadtEntry::X2ApicNmi(_) => {
-                    unimplemented!();
-                }
-
                 MadtEntry::Gicc(_) |
                 MadtEntry::Gicd(_) |
                 MadtEntry::GicMsiFrame(_) |
@@ -140,8 +137,33 @@ impl Madt {
                     };
 
                     let processor = Processor {
-                        processor_uid: entry.processor_id,
-                        local_apic_id: entry.apic_id,
+                        processor_uid: entry.processor_id as u32,
+                        local_apic_id: entry.apic_id as u32,
+                        state,
+                        is_ap,
+                    };
+
+                    if is_ap {
+                        application_processors.push(processor);
+                    } else {
+                        boot_processor = Some(processor);
+                    }
+                }
+
+                MadtEntry::LocalX2Apic(entry) => {
+                    let is_ap = boot_processor.is_some();
+                    let is_disabled = !{ entry.flags }.get_bit(0);
+
+                    let state = match (is_ap, is_disabled) {
+                        (_, true) => ProcessorState::Disabled,
+                        (true, false) => ProcessorState::WaitingForSipi,
+                        (false, false) => ProcessorState::Running,
+                    };
+                    log::info!("Found X2APIC in MADT!");
+
+                    let processor = Processor {
+                        processor_uid: entry.processor_uid,
+                        local_apic_id: entry.x2apic_id,
                         state,
                         is_ap,
                     };
@@ -199,6 +221,19 @@ impl Madt {
                     },
                 }),
 
+                MadtEntry::X2ApicNmi(entry) => local_apic_nmi_lines.push(NmiLine {
+                    processor: if entry.processor_uid == 0xffffffff {
+                        NmiProcessor::All
+                    } else {
+                        NmiProcessor::ProcessorUid(entry.processor_uid)
+                    },
+                    line: match entry.nmi_line {
+                        0 => LocalInterruptLine::Lint0,
+                        1 => LocalInterruptLine::Lint1,
+                        _ => return Err(AcpiError::InvalidMadt(MadtError::InvalidLocalNmiLine)),
+                    },
+                }),
+
                 MadtEntry::LocalApicAddressOverride(entry) => {
                     local_apic_address = entry.local_apic_address;
                 }