diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index d161031..f943b54 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -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, 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 { diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 8e9e61b..641ddb5 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -63,7 +63,7 @@ pub enum AmlValue { index: Box, length: Box }, - DDBHandle(u32), // Index into the XSDT + DDBHandle(Vec), DebugObject, Device(Vec), Event(u64), diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index 3493935..eb57bc0 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -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], diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs index 0961d3c..ac19b5c 100644 --- a/src/acpi/mod.rs +++ b/src/acpi/mod.rs @@ -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"), diff --git a/src/acpi/sdt.rs b/src/acpi/sdt.rs index 62d55cf..1a7a4fa 100644 --- a/src/acpi/sdt.rs +++ b/src/acpi/sdt.rs @@ -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::() } /// 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::(); 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()) } } }