Prechádzať zdrojové kódy

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 rokov pred
rodič
commit
0ef11142c6
1 zmenil súbory, kde vykonal 42 pridanie a 7 odobranie
  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;
                 }