Implemented table API in full
This commit is contained in:
@@ -36,8 +36,12 @@ pub enum AmlError {
|
||||
}
|
||||
|
||||
pub fn parse_aml_table(sdt: &Sdt) -> Result<Vec<String>, AmlError> {
|
||||
parse_aml_with_scope(sdt, String::from_str("\\").unwrap())
|
||||
}
|
||||
|
||||
pub fn parse_aml_with_scope(sdt: &Sdt, scope: String) -> Result<Vec<String>, AmlError> {
|
||||
let data = sdt.data();
|
||||
let mut ctx = AmlExecutionContext::new(String::from_str("\\").unwrap());
|
||||
let mut ctx = AmlExecutionContext::new(scope);
|
||||
|
||||
parse_term_list(data, &mut ctx)?;
|
||||
|
||||
|
||||
@@ -113,6 +113,13 @@ impl AmlValue {
|
||||
_ => Err(AmlError::AmlValueError)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_as_ddb_handle(&self) -> Result<Vec<String>, AmlError> {
|
||||
match *self {
|
||||
AmlValue::DDBHandle(ref v) => Ok(v.clone()),
|
||||
_ => Err(AmlError::AmlValueError)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_as_string(&self) -> Result<String, AmlError> {
|
||||
match *self {
|
||||
|
||||
@@ -363,12 +363,19 @@ fn parse_def_unload(data: &[u8],
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: remove from namespace all values added when `object` was loaded
|
||||
// TODO: globally synchronous (how?)
|
||||
parser_opcode_extended!(data, 0x2A);
|
||||
|
||||
let object = parse_super_name(&data[2..], ctx)?;
|
||||
|
||||
let delta = ctx.get(object.val).get_as_ddb_handle()?;
|
||||
let mut namespace = ctx.prelock();
|
||||
|
||||
if let Some(ref mut ns) = *namespace {
|
||||
for o in delta {
|
||||
ns.remove(&o);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(AmlParseType {
|
||||
val: AmlValue::None,
|
||||
len: 2 + object.len
|
||||
|
||||
@@ -2,7 +2,7 @@ use alloc::boxed::Box;
|
||||
use collections::string::String;
|
||||
use collections::vec::Vec;
|
||||
|
||||
use super::AmlError;
|
||||
use super::{AmlError, parse_aml_with_scope};
|
||||
use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
|
||||
use super::namespace::{AmlValue, ObjectReference};
|
||||
use super::pkglength::parse_pkg_length;
|
||||
@@ -11,6 +11,7 @@ use super::namestring::{parse_super_name, parse_target, parse_name_string, parse
|
||||
use super::dataobj::parse_data_ref_obj;
|
||||
|
||||
use time::monotonic;
|
||||
use acpi::ACPI_TABLE;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MatchOpcode {
|
||||
@@ -1263,8 +1264,6 @@ fn parse_def_load_table(data: &[u8],
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: Compute the result
|
||||
// TODO: Store the result, if appropriate
|
||||
// TODO: Clean up
|
||||
parser_opcode_extended!(data, 0x1F);
|
||||
|
||||
@@ -1275,8 +1274,34 @@ fn parse_def_load_table(data: &[u8],
|
||||
let parameter_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len..], ctx)?;
|
||||
let parameter_data = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len..], ctx)?;
|
||||
|
||||
let rxsdt_ptr = ACPI_TABLE.rxsdt.read();
|
||||
|
||||
if let Some(ref rxsdt) = *rxsdt_ptr {
|
||||
let sig_str = unsafe {
|
||||
*(signature.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 4])
|
||||
};
|
||||
let oem_str = unsafe {
|
||||
*(oem_id.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 6])
|
||||
};
|
||||
let oem_table_str = unsafe {
|
||||
*(oem_table_id.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 8])
|
||||
};
|
||||
|
||||
let sdt = rxsdt.find(sig_str, oem_str, oem_table_str);
|
||||
|
||||
if let Some(sdt) = sdt {
|
||||
let hdl = parse_aml_with_scope(sdt, root_path.val.get_as_string()?)?;
|
||||
ctx.modify(parameter_path.val, parameter_data.val);
|
||||
|
||||
return Ok(AmlParseType {
|
||||
val: AmlValue::DDBHandle(hdl),
|
||||
len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(AmlParseType {
|
||||
val: AmlValue::Uninitialized,
|
||||
val: AmlValue::IntegerConstant(0),
|
||||
len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use core::intrinsics::{atomic_load, atomic_store};
|
||||
use core::sync::atomic::Ordering;
|
||||
use collections::btree_map::BTreeMap;
|
||||
use collections::string::String;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use syscall::io::{Io, Pio};
|
||||
|
||||
@@ -25,6 +26,7 @@ use self::rsdt::Rsdt;
|
||||
use self::sdt::Sdt;
|
||||
use self::xsdt::Xsdt;
|
||||
use self::hpet::Hpet;
|
||||
use self::rxsdt::Rxsdt;
|
||||
|
||||
use self::aml::{is_aml_table, parse_aml_table, AmlError, AmlValue};
|
||||
|
||||
@@ -36,6 +38,7 @@ mod rsdt;
|
||||
mod sdt;
|
||||
mod xsdt;
|
||||
mod aml;
|
||||
mod rxsdt;
|
||||
|
||||
const TRAMPOLINE: usize = 0x7E00;
|
||||
const AP_STARTUP: usize = TRAMPOLINE + 512;
|
||||
@@ -261,18 +264,32 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
|
||||
print!("{}", c as char);
|
||||
}
|
||||
println!(":");
|
||||
if let Some(rsdt) = Rsdt::new(rxsdt) {
|
||||
for sdt_address in rsdt.iter() {
|
||||
let sdt = get_sdt(sdt_address, active_table);
|
||||
parse_sdt(sdt, active_table);
|
||||
}
|
||||
|
||||
let rxsdt: Box<Rxsdt + Send + Sync> = if let Some(rsdt) = Rsdt::new(rxsdt) {
|
||||
Box::new(rsdt)
|
||||
} else if let Some(xsdt) = Xsdt::new(rxsdt) {
|
||||
for sdt_address in xsdt.iter() {
|
||||
let sdt = get_sdt(sdt_address, active_table);
|
||||
parse_sdt(sdt, active_table);
|
||||
}
|
||||
Box::new(xsdt)
|
||||
} else {
|
||||
println!("UNKNOWN RSDT OR XSDT SIGNATURE");
|
||||
return;
|
||||
};
|
||||
|
||||
{
|
||||
let mut rxsdt_ptr = ACPI_TABLE.rxsdt.write();
|
||||
*rxsdt_ptr = Some(rxsdt);
|
||||
}
|
||||
|
||||
{
|
||||
let rxsdt_ptr = ACPI_TABLE.rxsdt.read();
|
||||
|
||||
if let Some(ref rxsdt) = *rxsdt_ptr {
|
||||
rxsdt.map_all(active_table);
|
||||
|
||||
for sdt_address in rxsdt.iter() {
|
||||
let sdt = unsafe { &*(sdt_address as *const Sdt) };
|
||||
parse_sdt(sdt, active_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("NO RSDP FOUND");
|
||||
@@ -321,6 +338,7 @@ pub fn set_global_s_state(state: u8) {
|
||||
}
|
||||
|
||||
pub struct Acpi {
|
||||
pub rxsdt: RwLock<Option<Box<Rxsdt + Send + Sync>>>,
|
||||
pub fadt: RwLock<Option<Fadt>>,
|
||||
pub namespace: RwLock<Option<BTreeMap<String, AmlValue>>>,
|
||||
pub hpet: RwLock<Option<Hpet>>,
|
||||
@@ -328,6 +346,7 @@ pub struct Acpi {
|
||||
}
|
||||
|
||||
pub static ACPI_TABLE: Acpi = Acpi {
|
||||
rxsdt: RwLock::new(None),
|
||||
fadt: RwLock::new(None),
|
||||
namespace: RwLock::new(None),
|
||||
hpet: RwLock::new(None),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use core::mem;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use super::sdt::Sdt;
|
||||
use super::rxsdt::Rxsdt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Rsdt(&'static Sdt);
|
||||
@@ -13,12 +15,14 @@ impl Rsdt {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> RsdtIter {
|
||||
RsdtIter {
|
||||
impl Rxsdt for Rsdt {
|
||||
fn iter(&self) -> Box<Iterator<Item = usize>> {
|
||||
Box::new(RsdtIter {
|
||||
sdt: self.0,
|
||||
i: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
28
src/acpi/rxsdt.rs
Normal file
28
src/acpi/rxsdt.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use paging::ActivePageTable;
|
||||
|
||||
use super::sdt::Sdt;
|
||||
use super::get_sdt;
|
||||
|
||||
pub trait Rxsdt {
|
||||
fn iter(&self) -> Box<Iterator<Item = usize>>;
|
||||
|
||||
fn map_all(&self, active_table: &mut ActivePageTable) {
|
||||
for sdt in self.iter() {
|
||||
get_sdt(sdt, active_table);
|
||||
}
|
||||
}
|
||||
|
||||
fn find(&self, signature: [u8; 4], oem_id: [u8; 6], oem_table_id: [u8; 8]) -> Option<&'static Sdt> {
|
||||
for sdt in self.iter() {
|
||||
let sdt = unsafe { &*(sdt as *const Sdt) };
|
||||
|
||||
if sdt.match_pattern(signature, oem_id, oem_table_id) {
|
||||
return Some(sdt);
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -35,4 +35,8 @@ impl Sdt {
|
||||
pub fn data(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.data_address() as *const u8, self.data_len()) }
|
||||
}
|
||||
|
||||
pub fn match_pattern(&self, signature: [u8; 4], oem_id: [u8; 6], oem_table_id: [u8; 8]) -> bool{
|
||||
self.signature == signature && self.oem_id == oem_id && self.oem_table_id == oem_table_id
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use core::mem;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use super::sdt::Sdt;
|
||||
use super::rxsdt::Rxsdt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Xsdt(&'static Sdt);
|
||||
@@ -13,12 +15,14 @@ impl Xsdt {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> XsdtIter {
|
||||
XsdtIter {
|
||||
impl Rxsdt for Xsdt {
|
||||
fn iter(&self) -> Box<Iterator<Item = usize>> {
|
||||
Box::new(XsdtIter {
|
||||
sdt: self.0,
|
||||
i: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(thread_local)]
|
||||
#![feature(unique)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc_kernel as allocator;
|
||||
|
||||
Reference in New Issue
Block a user