Implemented Load

This commit is contained in:
Connor Wood
2017-07-23 10:34:50 +01:00
parent 82e814469c
commit 4288182106
5 changed files with 28 additions and 17 deletions

View File

@@ -2,6 +2,7 @@
//! Code to parse and execute AML tables
use collections::string::String;
use collections::vec::Vec;
use core::str::FromStr;
use super::sdt::Sdt;
@@ -34,16 +35,16 @@ pub enum AmlError {
AmlHardFatal
}
pub fn parse_aml_table(sdt: &'static Sdt) -> Result<(), AmlError> {
pub fn parse_aml_table(sdt: &Sdt) -> Result<Vec<String>, AmlError> {
let data = sdt.data();
let mut ctx = AmlExecutionContext::new(String::from_str("\\").unwrap());
parse_term_list(data, &mut ctx)?;
Ok(())
Ok(ctx.namespace_delta)
}
pub fn is_aml_table(sdt: &'static Sdt) -> bool {
pub fn is_aml_table(sdt: &Sdt) -> bool {
if &sdt.signature == b"DSDT" || &sdt.signature == b"SSDT" {
true
} else {

View File

@@ -63,7 +63,7 @@ pub enum AmlValue {
index: Box<AmlValue>,
length: Box<AmlValue>
},
DDBHandle(u32), // Index into the XSDT
DDBHandle(Vec<String>),
DebugObject,
Device(Vec<String>),
Event(u64),

View File

@@ -1,12 +1,15 @@
use super::AmlError;
use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
use super::namespace::AmlValue;
use super::namespace::{AmlValue, ObjectReference};
use super::pkglength::parse_pkg_length;
use super::termlist::{parse_term_arg, parse_term_list};
use super::namestring::{parse_name_string, parse_super_name};
use time::monotonic;
use acpi::Sdt;
use super::{parse_aml_table, is_aml_table};
pub fn parse_type1_opcode(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
match ctx.state {
@@ -143,18 +146,25 @@ fn parse_def_load(data: &[u8],
})
}
// TODO: Load in the table pointed to by `name`
// TODO: Set DDB_Handle to the handle returned by loading in the table
// TODO: Run the AML parser on the table, in a secondary namespace
parser_opcode_extended!(data, 0x20);
let name = parse_name_string(&data[2..], ctx)?;
let ddb_handle_object = parse_super_name(&data[2 + name.len..], ctx)?;
Ok(AmlParseType {
val: AmlValue::None,
len: 2 + name.len + ddb_handle_object.len
})
let tbl = ctx.get(AmlValue::ObjectReference(ObjectReference::NamedObj(name.val.get_as_string()?))).get_as_buffer()?;
let sdt = unsafe { &*(tbl.as_ptr() as *const Sdt) };
if is_aml_table(sdt) {
let delta = parse_aml_table(sdt)?;
ctx.modify(ddb_handle_object.val, AmlValue::DDBHandle(delta));
Ok(AmlParseType {
val: AmlValue::None,
len: 2 + name.len + ddb_handle_object.len
})
} else {
Err(AmlError::AmlValueError)
}
}
fn parse_def_notify(data: &[u8],

View File

@@ -213,7 +213,7 @@ fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
*hpet_t = Some(hpet);
} else if is_aml_table(sdt) {
match parse_aml_table(sdt) {
Ok(()) => println!(": Parsed"),
Ok(_) => println!(": Parsed"),
Err(AmlError::AmlParseError(e)) => println!(": {}", e),
Err(AmlError::AmlInvalidOpCode) => println!(": Invalid opcode"),
Err(AmlError::AmlValueError) => println!(": Type constraints or value bounds not met"),

View File

@@ -17,12 +17,12 @@ pub struct Sdt {
impl Sdt {
/// Get the address of this tables data
pub fn data_address(&'static self) -> usize {
pub fn data_address(&self) -> usize {
self as *const _ as usize + mem::size_of::<Sdt>()
}
/// Get the length of this tables data
pub fn data_len(&'static self) -> usize {
pub fn data_len(&self) -> usize {
let total_size = self.length as usize;
let header_size = mem::size_of::<Sdt>();
if total_size >= header_size {
@@ -32,7 +32,7 @@ impl Sdt {
}
}
pub fn data(&'static self) -> &[u8] {
pub fn data(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.data_address() as *const u8, self.data_len()) }
}
}