diff --git a/arch/x86_64/src/acpi/mod.rs b/arch/x86_64/src/acpi/mod.rs index 092f609aefd52e251e3cea45955e08c581fd3da0..5b235ce98b24a9a6b73c5904cf1e7135be907c9a 100644 --- a/arch/x86_64/src/acpi/mod.rs +++ b/arch/x86_64/src/acpi/mod.rs @@ -27,7 +27,13 @@ pub mod xsdt; const TRAMPOLINE: usize = 0x7E00; const AP_STARTUP: usize = TRAMPOLINE + 512; -pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { +pub enum AcpiTable { + fadt(Fadt), + madt(Madt), + dmar(Dmar) +} + +pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) -> Option<AcpiTable> { print!(" "); for &c in sdt.signature.iter() { print!("{}", c as char); @@ -35,6 +41,7 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { if let Some(fadt) = Fadt::new(sdt) { println!(": {:#?}", fadt); + Some(AcpiTable::fadt(fadt)) } else if let Some(madt) = Madt::new(sdt) { println!(": {:>08X}: {}", madt.local_address, madt.flags); @@ -138,6 +145,7 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { // Unmap trampoline let result = active_table.unmap(trampoline_page); result.flush(active_table); + Some(AcpiTable::madt(madt)) } else if let Some(dmar) = Dmar::new(sdt) { println!(": {}: {}", dmar.addr_width, dmar.flags); @@ -157,8 +165,10 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { _ => () } } + Some(AcpiTable::dmar(dmar)) } else { println!(": Unknown"); + None } } @@ -167,6 +177,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> { let start_addr = 0xE0000; let end_addr = 0xFFFFF; + let mut theFADT: Option<Fadt> = None; + // Map all of the ACPI RSDP space { let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr)); @@ -212,14 +224,26 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> { if let Some(rsdt) = Rsdt::new(rxsdt) { for sdt_address in rsdt.iter() { let (sdt, mapped) = get_sdt(sdt_address, active_table); - init_sdt(sdt, active_table); - drop_sdt(sdt, mapped, active_table); + + // If we find the FADT, rather than drop it, save a copy of the pointer, as this is needed elsewhere. + // TODO: Eventually, save pointers to all tables containing pertinent information to other parts of + // the kernel + match init_sdt(sdt, active_table) { + Some(AcpiTable::fadt(fadt)) => theFADT = Some(fadt), + _ => drop_sdt(sdt, mapped, active_table) + } } } else if let Some(xsdt) = Xsdt::new(rxsdt) { for sdt_address in xsdt.iter() { let (sdt, mapped) = get_sdt(sdt_address, active_table); - init_sdt(sdt, active_table); - drop_sdt(sdt, mapped, active_table); + + // If we find the FADT, rather than drop it, save a copy of the pointer, as this is needed elsewhere. + // TODO: Eventually, save pointers to all tables containing pertinent information to other parts of + // the kernel + match init_sdt(sdt, active_table) { + Some(AcpiTable::fadt(fadt)) => theFADT = Some(fadt), + _ => drop_sdt(sdt, mapped, active_table) + } } } else { println!("UNKNOWN RSDT OR XSDT SIGNATURE"); @@ -241,10 +265,16 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> { } } - None + if let Some(fadt) = theFADT { + Some(Acpi { fadt: fadt }) + } else { + None + } } -pub struct Acpi; +pub struct Acpi { + pub fadt: Fadt +} /// RSDP #[derive(Copy, Clone, Debug)]