Port part of MADT

master
WangRunji 7 years ago
parent e9d89576a3
commit 1de0087d49

@ -42,20 +42,35 @@ pub fn init() -> Result<(), ACPI_Error> {
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) };
for i in 0 .. rsdt.entry_count() {
let entry = rsdt.entry_at(i);
if entry > PHYSICAL_MEMORY_LIMIT {
return Err(ACPI_Error::NotMapped);
}
let header = unsafe{ &*(entry as *const header) };
debug!("{:?}", header);
// debug!("{:?}", header);
if &header.Signature == b"APIC" {
madt = Some(unsafe{ &*(entry as *const madt) });
}
}
debug!("{:?}", madt);
// return acpi_config_smp(madt);
config_smp(madt.expect("acpi: madt not found."));
Ok(())
}
fn config_smp(madt: &'static madt) {
let lapic_addr = madt.LapicAddress;
for entry in madt.entry_iter() {
debug!("{:?}", entry);
match &entry {
&MadtEntry::LocalApic(ref lapic) => {},
&MadtEntry::IoApic(ref ioapic) => {
},
_ => {},
}
}
// TODO
unimplemented!();
}

@ -2,6 +2,7 @@
// Copy from crate 'acpica-sys'
use util::{Checkable, bytes_sum};
use core::mem::size_of;
#[repr(C)]
#[derive(Debug)]
@ -45,8 +46,15 @@ pub struct rsdt {
}
impl rsdt {
pub unsafe fn entry_at(&self, id: usize) -> u32 {
*(self.TableOffsetEntry.as_ptr().offset(id as isize))
pub fn entry_count(&self) -> usize {
(self.Header.Length as usize - size_of::<Self>()) / 4
}
pub fn entry_at(&self, id: usize) -> u32 {
assert!(id < self.entry_count());
unsafe {
let p = (self as *const Self).offset(1) as *const u32;
*(p.offset(id as isize))
}
}
}
@ -54,34 +62,80 @@ impl rsdt {
#[derive(Debug)]
pub struct madt {
pub Header: header,
pub Address: u32,
pub LapicAddress: u32,
pub Flags: u32,
Table: [u32; 0],
}
impl Checkable for madt {
fn check(&self) -> bool {
&self.Header.Signature == b"APIC"
&self.Header.Signature == b"APIC" && self.Header.Length >= size_of::<Self>() as u32
}
}
#[repr(C)]
#[derive(Debug)]
pub struct madt_local_apic {
pub Type: u8,
pub enum MadtEntry {
Unknown(MadtEntry_Unknown),
LocalApic(MadtEntry_LocalApic),
IoApic(MadtEntry_IoApic),
}
#[repr(C)]
#[derive(Debug, Clone)]
pub struct MadtEntry_Unknown {
pub Type: u8,
pub Length: u8,
}
#[repr(C)]
#[derive(Debug, Clone)]
pub struct MadtEntry_LocalApic {
pub Type: u8, // 0
pub Length: u8,
pub ProcessorId: u8,
pub Id: u8,
pub LapicFlags: u32,
}
#[repr(C)]
#[derive(Debug)]
pub struct madt_io_apic {
pub Type: u8,
#[derive(Debug, Clone)]
pub struct MadtEntry_IoApic {
pub Type: u8, // 1
pub Length: u8,
pub Id: u8,
pub Reserved: u8,
pub Address: u32,
pub GlobalIrqBase: u32,
}
#[derive(Debug)]
pub struct MadtEntryIter<'a> {
madt: &'a madt,
ptr: *const u8,
end_ptr: *const u8,
}
impl madt {
pub fn entry_iter(&self) -> MadtEntryIter {
let ptr = unsafe{ (self as *const Self).offset(1) } as *const u8;
let end_ptr = unsafe{ ptr.offset(self.Header.Length as isize) };
MadtEntryIter { madt: self, ptr, end_ptr }
}
}
impl<'a> Iterator for MadtEntryIter<'a> {
type Item = MadtEntry;
fn next(&mut self) -> Option<Self::Item> {
if self.ptr >= self.end_ptr {
return None;
}
unsafe {
let typeId = *self.ptr.offset(0);
let len = *self.ptr.offset(1);
let ret = Some(match typeId {
0 => MadtEntry::LocalApic( (&*(self.ptr as *const MadtEntry_LocalApic)).clone() ),
1 => MadtEntry::IoApic( (&*(self.ptr as *const MadtEntry_IoApic)).clone() ),
_ => MadtEntry::Unknown( (&*(self.ptr as *const MadtEntry_Unknown)).clone() ),
});
self.ptr = self.ptr.offset(len as isize);
ret
}
}
}
Loading…
Cancel
Save