From 5c80d903ada496e29ea6170a833bb1074582ed78 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 12 Apr 2018 20:57:56 +0800 Subject: [PATCH] Finish ACPI init --- src/arch/x86_64/driver/acpi/mod.rs | 98 ++++++++++++++++++------------ src/consts.rs | 1 + src/lib.rs | 6 +- 3 files changed, 65 insertions(+), 40 deletions(-) create mode 100644 src/consts.rs diff --git a/src/arch/x86_64/driver/acpi/mod.rs b/src/arch/x86_64/driver/acpi/mod.rs index 6e0e313..913ef5a 100644 --- a/src/arch/x86_64/driver/acpi/mod.rs +++ b/src/arch/x86_64/driver/acpi/mod.rs @@ -2,39 +2,9 @@ mod structs; use self::structs::*; +use consts::*; -/// See https://wiki.osdev.org/RSDP -- Detecting the RSDP -pub fn find_rsdp() -> Option<&'static rsdp> { - use util::{Checkable, find_in_memory}; - let ebda = unsafe { *(0x40E as *const u16) as usize } << 4; - debug!("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 -} - -#[cfg(target_arch="x86")] -const PHYSICAL_MEMORY_LIMIT: u32 = 0x0E000000; -#[cfg(target_arch="x86_64")] -const PHYSICAL_MEMORY_LIMIT: u32 = 0x80000000; - -#[derive(Debug)] -pub enum ACPI_Error { - NotMapped -} - -pub fn init() -> Result<(), ACPI_Error> { +pub fn init() -> Result { use core::mem::size_of; use util::Checkable; let rsdp = find_rsdp().expect("acpi: rsdp not found."); @@ -55,22 +25,72 @@ pub fn init() -> Result<(), ACPI_Error> { } } debug!("{:?}", madt); - config_smp(madt.expect("acpi: madt not found.")); - Ok(()) + config_smp(madt.expect("acpi: madt not found.")) } -fn config_smp(madt: &'static madt) { +#[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 ACPI_Result { + cpu_num: u8, + cpu_acpi_ids: [u8; MAX_CPU_NUM], + ioapic_id: u8, + lapic_addr: u32, +} + +#[derive(Debug)] +pub enum ACPI_Error { + NotMapped, + IOACPI_NotFound, +} + +fn config_smp(madt: &'static madt) -> Result { let lapic_addr = madt.LapicAddress; + let mut cpu_num = 0u8; + let mut cpu_acpi_ids: [u8; MAX_CPU_NUM] = [0; MAX_CPU_NUM]; + let mut ioapic_id: Option = None; for entry in madt.entry_iter() { debug!("{:?}", entry); match &entry { - &MadtEntry::LocalApic(ref lapic) => {}, + &MadtEntry::LocalApic(ref lapic) => { + cpu_acpi_ids[cpu_num as usize] = lapic.Id; + cpu_num += 1; + }, &MadtEntry::IoApic(ref ioapic) => { + ioapic_id = Some(ioapic.Id); }, _ => {}, } } - // TODO - unimplemented!(); -} \ No newline at end of file + + if ioapic_id.is_none() { + return Err(ACPI_Error::IOACPI_NotFound); + } + let ioapic_id = ioapic_id.unwrap(); + Ok(ACPI_Result { 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; + debug!("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/consts.rs b/src/consts.rs new file mode 100644 index 0000000..9e82028 --- /dev/null +++ b/src/consts.rs @@ -0,0 +1 @@ +pub const MAX_CPU_NUM: usize = 8; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 3bf377c..0eb5b52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,7 @@ mod lang; mod util; #[macro_use] // test! mod test_util; +mod consts; #[allow(dead_code)] #[cfg(target_arch = "x86_64")] @@ -49,7 +50,10 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) { test!(extern_fn); test!(find_mp); - arch::driver::acpi::init(); + let acpi = arch::driver::acpi::init(); + debug!("{:?}", acpi); + unimplemented!(); + arch::driver::ioapic::init(); io::init(); println!("Hello World{}", "!");