From d2d9affddff44d68e7f3ad4acf84daf14458de19 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 20 Jun 2018 11:08:47 +0800 Subject: [PATCH] Use multiboot2 to locate RSDT --- src/arch/x86_64/driver/acpi/mod.rs | 38 ++---------------------------- src/arch/x86_64/driver/mod.rs | 6 ++--- src/lib.rs | 3 ++- 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/arch/x86_64/driver/acpi/mod.rs b/src/arch/x86_64/driver/acpi/mod.rs index 0e4a755..c7acf30 100644 --- a/src/arch/x86_64/driver/acpi/mod.rs +++ b/src/arch/x86_64/driver/acpi/mod.rs @@ -4,19 +4,11 @@ mod structs; use self::structs::*; use consts::*; -pub fn init() -> Result { - let rsdp = find_rsdp().expect("acpi: rsdp not found."); - if rsdp.rsdt_physical_address > PHYSICAL_MEMORY_LIMIT { - return Err(AcpiError::NotMapped); - } - trace!("RSDT at {:#x}", rsdp.rsdt_physical_address); - let rsdt = unsafe{ &*(rsdp.rsdt_physical_address as *const Rsdt) }; +pub fn init(rsdt_addr: usize) -> Result { + let rsdt = unsafe { &*(rsdt_addr as *const Rsdt) }; let mut madt: Option<&'static Madt> = None; for i in 0 .. rsdt.entry_count() { let entry = rsdt.entry_at(i); - if entry > PHYSICAL_MEMORY_LIMIT { - return Err(AcpiError::NotMapped); - } let header = unsafe{ &*(entry as *const Header) }; trace!("{:?}", header); if &header.signature == b"APIC" { @@ -27,11 +19,6 @@ pub fn init() -> Result { config_smp(madt.expect("acpi: madt not found.")) } -#[cfg(target_arch="x86")] -const PHYSICAL_MEMORY_LIMIT: u32 = 0x0E000000; -#[cfg(target_arch="x86_64")] -const PHYSICAL_MEMORY_LIMIT: u32 = 0x80000000; - #[derive(Debug)] pub struct AcpiResult { pub cpu_num: u8, @@ -72,24 +59,3 @@ fn config_smp(madt: &'static Madt) -> Result { let ioapic_id = ioapic_id.unwrap(); Ok(AcpiResult { cpu_num, cpu_acpi_ids, ioapic_id, lapic_addr }) } - -/// See https://wiki.osdev.org/RSDP -- Detecting the RSDP -fn find_rsdp() -> Option<&'static Rsdp> { - use util::{Checkable, find_in_memory}; - let ebda = unsafe { *(0x40E as *const u16) as usize } << 4; - trace!("EBDA at {:#x}", ebda); - - macro_rules! return_if_find_in { - ($begin:expr, $end:expr) => ( - if let Some(addr) = unsafe{ find_in_memory::($begin, $end, 4) } { - return Some(unsafe{ &*(addr as *const Rsdp) }); - } - ) - } - - if ebda != 0 { - return_if_find_in!(ebda as usize, 1024); - } - return_if_find_in!(0xE0000, 0x20000); - None -} \ No newline at end of file diff --git a/src/arch/x86_64/driver/mod.rs b/src/arch/x86_64/driver/mod.rs index caa4763..be45add 100644 --- a/src/arch/x86_64/driver/mod.rs +++ b/src/arch/x86_64/driver/mod.rs @@ -8,15 +8,13 @@ pub mod keyboard; pub mod pit; pub mod ide; -pub fn init(mut page_map: impl FnMut(usize, usize)) -> acpi::AcpiResult { +pub fn init(rsdt_addr: usize, mut page_map: impl FnMut(usize, usize)) -> acpi::AcpiResult { assert_has_not_been_called!(); - page_map(0, 1); // EBDA - page_map(0xe0_000, 0x100 - 0xe0); page_map(0x07fe1000, 1); // RSDT page_map(0xfec00000, 1); // IOAPIC - let acpi = acpi::init().expect("Failed to init ACPI"); + let acpi = acpi::init(rsdt_addr).expect("Failed to init ACPI"); assert_eq!(acpi.lapic_addr as usize, 0xfee00000); trace!("acpi = {:?}", acpi); diff --git a/src/lib.rs b/src/lib.rs index 595cc2e..ed52957 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,6 +73,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { println!("Hello World{}", "!"); let boot_info = unsafe { multiboot2::load(multiboot_information_address) }; + let rsdt_addr = boot_info.rsdp_v1_tag().unwrap().rsdt_address(); // set up guard page and map the heap pages let mut kernel_memory = memory::init(boot_info); @@ -85,7 +86,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { test!(find_mp); use memory::*; - let acpi = arch::driver::init(|addr: usize, count: usize| { + let acpi = arch::driver::init(rsdt_addr, |addr: usize, count: usize| { kernel_memory.push(MemoryArea::new_identity(addr, addr + count * 0x1000, MemoryAttr::default(), "acpi")) });