From d315914f29fc212b24edd1f5afdf055c1d96c021 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 17 Jul 2017 11:54:19 +0100 Subject: [PATCH] Implmented method execution and method invocations --- src/acpi/aml/namedobj.rs | 10 +--------- src/acpi/aml/namespace.rs | 29 ++++++++++++++++++++++++++++- src/acpi/aml/parser.rs | 13 +++++++++++++ src/acpi/aml/termlist.rs | 28 ++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index a4f1ab0..27695bb 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -7,20 +7,12 @@ use collections::btree_map::BTreeMap; use super::AmlError; use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext, ExecutionState }; -use super::namespace::{ AmlValue, ObjectReference, FieldSelector, get_namespace_string }; +use super::namespace::{ AmlValue, ObjectReference, FieldSelector, Method, get_namespace_string }; use super::namestring::{parse_name_string, parse_name_seg}; use super::termlist::{parse_term_arg, parse_term_list, parse_object_list}; use super::pkglength::parse_pkg_length; use super::type2opcode::parse_def_buffer; -#[derive(Debug, Clone)] -pub struct Method { - arg_count: u8, - serialized: bool, - sync_level: u8, - term_list: Vec -} - #[derive(Debug, Copy, Clone)] pub enum RegionSpace { SystemMemory, diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 746cd1e..8aed913 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -5,7 +5,8 @@ use collections::btree_map::BTreeMap; use core::str::FromStr; -use super::namedobj::{ RegionSpace, FieldFlags, Method }; +use super::termlist::parse_term_list; +use super::namedobj::{ RegionSpace, FieldFlags }; use super::parser::AmlExecutionContext; use super::AmlError; @@ -30,6 +31,14 @@ pub enum ObjectReference { Object(Box) } +#[derive(Debug, Clone)] +pub struct Method { + pub arg_count: u8, + pub serialized: bool, + pub sync_level: u8, + pub term_list: Vec +} + #[derive(Debug, Clone)] pub enum AmlValue { None, @@ -105,6 +114,24 @@ impl AmlValue { _ => Err(AmlError::AmlValueError) } } + + pub fn get_as_method(&self) -> Result { + match *self { + AmlValue::Method(ref m) => Ok(m.clone()), + _ => Err(AmlError::AmlValueError) + } + } +} + +impl Method { + pub fn execute(&self, scope: String, parameters: Vec) -> AmlValue { + let mut ctx = AmlExecutionContext::new(scope); + ctx.init_arg_vars(parameters); + + parse_term_list(&self.term_list[..], &mut ctx); + + AmlValue::None + } } pub fn get_namespace_string(current: String, modifier_v: AmlValue) -> String { diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 094028b..a358328 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -1,5 +1,6 @@ use collections::string::String; use collections::btree_map::BTreeMap; +use collections::vec::Vec; use super::namespace::{ AmlValue, ObjectReference }; use super::AmlError; @@ -53,6 +54,18 @@ impl AmlExecutionContext { } } + pub fn init_arg_vars(&mut self, parameters: Vec) { + if parameters.len() > 8 { + return; + } + + let mut cur = 0; + while cur < parameters.len() { + self.arg_vars[cur] = parameters[cur].clone(); + cur += 1; + } + } + pub fn modify(&mut self, name: AmlValue, value: AmlValue) { // TODO: throw errors // TODO: return DRO diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index 87021d4..e8a59fc 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -120,12 +120,32 @@ pub fn parse_method_invocation(data: &[u8], }); } - // TODO: Check if method exists in namespace - // TODO: If so, parse appropriate number of parameters - // TODO: If not, add deferred load to ctx let name = parse_name_string(data, ctx)?; + let method = ctx.get(name.val.clone()); + + let method = match method { + AmlValue::None => return Err(AmlError::AmlDeferredLoad), + _ => method.get_as_method()? + }; - Err(AmlError::AmlDeferredLoad) + let mut cur = 0; + let mut params: Vec = vec!(); + + let mut current_offset = name.len; + + while cur < method.arg_count { + let res = parse_term_arg(&data[current_offset..], ctx)?; + + current_offset += res.len; + cur += 1; + + params.push(res.val); + } + + Ok(AmlParseType { + val: method.execute(get_namespace_string(ctx.scope.clone(), name.val), params), + len: current_offset + }) } fn parse_term_obj(data: &[u8],