mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
Use multiboot2 to locate RSDT
This commit is contained in:
parent
0e2cccef9e
commit
d2d9affddf
@ -4,19 +4,11 @@ mod structs;
|
|||||||
use self::structs::*;
|
use self::structs::*;
|
||||||
use consts::*;
|
use consts::*;
|
||||||
|
|
||||||
pub fn init() -> Result<AcpiResult, AcpiError> {
|
pub fn init(rsdt_addr: usize) -> Result<AcpiResult, AcpiError> {
|
||||||
let rsdp = find_rsdp().expect("acpi: rsdp not found.");
|
let rsdt = unsafe { &*(rsdt_addr as *const Rsdt) };
|
||||||
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) };
|
|
||||||
let mut madt: Option<&'static Madt> = None;
|
let mut madt: Option<&'static Madt> = None;
|
||||||
for i in 0 .. rsdt.entry_count() {
|
for i in 0 .. rsdt.entry_count() {
|
||||||
let entry = rsdt.entry_at(i);
|
let entry = rsdt.entry_at(i);
|
||||||
if entry > PHYSICAL_MEMORY_LIMIT {
|
|
||||||
return Err(AcpiError::NotMapped);
|
|
||||||
}
|
|
||||||
let header = unsafe{ &*(entry as *const Header) };
|
let header = unsafe{ &*(entry as *const Header) };
|
||||||
trace!("{:?}", header);
|
trace!("{:?}", header);
|
||||||
if &header.signature == b"APIC" {
|
if &header.signature == b"APIC" {
|
||||||
@ -27,11 +19,6 @@ pub fn init() -> Result<AcpiResult, AcpiError> {
|
|||||||
config_smp(madt.expect("acpi: madt not found."))
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct AcpiResult {
|
pub struct AcpiResult {
|
||||||
pub cpu_num: u8,
|
pub cpu_num: u8,
|
||||||
@ -72,24 +59,3 @@ fn config_smp(madt: &'static Madt) -> Result<AcpiResult, AcpiError> {
|
|||||||
let ioapic_id = ioapic_id.unwrap();
|
let ioapic_id = ioapic_id.unwrap();
|
||||||
Ok(AcpiResult { cpu_num, cpu_acpi_ids, ioapic_id, lapic_addr })
|
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::<Rsdp>($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
|
|
||||||
}
|
|
@ -8,15 +8,13 @@ pub mod keyboard;
|
|||||||
pub mod pit;
|
pub mod pit;
|
||||||
pub mod ide;
|
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!();
|
assert_has_not_been_called!();
|
||||||
|
|
||||||
page_map(0, 1); // EBDA
|
|
||||||
page_map(0xe0_000, 0x100 - 0xe0);
|
|
||||||
page_map(0x07fe1000, 1); // RSDT
|
page_map(0x07fe1000, 1); // RSDT
|
||||||
page_map(0xfec00000, 1); // IOAPIC
|
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);
|
assert_eq!(acpi.lapic_addr as usize, 0xfee00000);
|
||||||
trace!("acpi = {:?}", acpi);
|
trace!("acpi = {:?}", acpi);
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! {
|
|||||||
println!("Hello World{}", "!");
|
println!("Hello World{}", "!");
|
||||||
|
|
||||||
let boot_info = unsafe { multiboot2::load(multiboot_information_address) };
|
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
|
// set up guard page and map the heap pages
|
||||||
let mut kernel_memory = memory::init(boot_info);
|
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);
|
test!(find_mp);
|
||||||
|
|
||||||
use memory::*;
|
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"))
|
kernel_memory.push(MemoryArea::new_identity(addr, addr + count * 0x1000, MemoryAttr::default(), "acpi"))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user