Port acpiinit()

master
WangRunji 7 years ago
parent 83684cbfd7
commit e9d89576a3

@ -4,15 +4,58 @@ mod structs;
use self::structs::*;
/// See https://wiki.osdev.org/RSDP -- Detecting the RSDP
pub fn find_rdsp() -> Option<*const 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::<rsdp>($begin, $end, 4) } {
return Some(unsafe{ &*(addr as *const rsdp) });
}
)
}
if ebda != 0 {
if let Some(addr) = unsafe{ find_in_memory::<rsdp>(ebda as usize, 1024, 4) } {
return Some(addr as *const rsdp);
return_if_find_in!(ebda as usize, 1024);
}
return_if_find_in!(0xE0000, 0x20000);
None
}
unsafe{ find_in_memory::<rsdp>(0xE0000, 0x20000, 4).map(|addr| addr as *const rsdp) }
#[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> {
use core::mem::size_of;
use util::Checkable;
let rsdp = find_rsdp().expect("acpi: rsdp not found.");
if rsdp.RsdtPhysicalAddress > PHYSICAL_MEMORY_LIMIT {
return Err(ACPI_Error::NotMapped);
}
let rsdt = unsafe{ &*(rsdp.RsdtPhysicalAddress as *const rsdt) };
let entry_count = (rsdt.Header.Length as usize - size_of::<header>()) / 4;
let mut madt: Option<&'static madt> = None;
for i in 0 .. entry_count {
let entry = unsafe{ rsdt.entry_at(i) };
if entry > PHYSICAL_MEMORY_LIMIT {
return Err(ACPI_Error::NotMapped);
}
let header = unsafe{ &*(entry as *const header) };
debug!("{:?}", header);
if &header.Signature == b"APIC" {
madt = Some(unsafe{ &*(entry as *const madt) });
}
}
debug!("{:?}", madt);
// return acpi_config_smp(madt);
Ok(())
}

@ -26,7 +26,7 @@ impl Checkable for rsdp {
#[repr(C)]
#[derive(Debug)]
pub struct header {
pub Signature: [i8; 4],
pub Signature: [u8; 4],
pub Length: u32,
pub Revision: u8,
pub Checksum: u8,
@ -41,7 +41,13 @@ pub struct header {
#[derive(Debug)]
pub struct rsdt {
pub Header: header,
pub TableOffsetEntry: [u32; 1],
TableOffsetEntry: [u32; 0],
}
impl rsdt {
pub unsafe fn entry_at(&self, id: usize) -> u32 {
*(self.TableOffsetEntry.as_ptr().offset(id as isize))
}
}
#[repr(C)]
@ -50,9 +56,14 @@ pub struct madt {
pub Header: header,
pub Address: u32,
pub Flags: u32,
Table: [u32; 0],
}
const MADT_SIGNATURE: [u8; 4] = *b"APIC";
impl Checkable for madt {
fn check(&self) -> bool {
&self.Header.Signature == b"APIC"
}
}
#[repr(C)]
#[derive(Debug)]

@ -46,7 +46,7 @@ mod arch;
pub extern "C" fn rust_main(multiboot_information_address: usize) {
// ATTENTION: we have a very small stack and no guard page
println!("MP = {:?}", arch::driver::mp::find_mp());
println!("RDSP = {:?}", arch::driver::acpi::find_rdsp());
arch::driver::acpi::init();
loop {
}

Loading…
Cancel
Save