From 190686a85348ec43c0a5c1f9626a032e7afa0d1b Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 19 Jun 2017 13:33:20 +0100 Subject: [PATCH 01/26] Moved Alias to the namespace --- src/acpi/aml/mod.rs | 18 +++--------------- src/acpi/aml/namespace.rs | 15 +++++++++++++++ src/acpi/aml/namespacemodifier.rs | 6 ++++++ src/start.rs | 3 +++ 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index 296317d..bc0cee9 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -23,7 +23,7 @@ mod type1opcode; mod type2opcode; use self::termlist::{parse_term_list, TermObj}; -pub use self::namespace::{AmlNamespace, AmlValue}; +pub use self::namespace::{get_namespace_string, AmlNamespace, AmlValue}; use self::namespace::AmlNamespaceContents; // TODO: This should be able to take parameters, and may also return multiple values @@ -42,20 +42,6 @@ pub enum AmlError { AmlParseError(&'static str) } -pub fn get_namespace_string(current: String, modifier: String) -> String { - if modifier.starts_with("\\") { - return modifier; - } - - if modifier.starts_with("^") { - // TODO - } - - let mut namespace = current.clone(); - namespace.push('.'); - namespace + &modifier -} - pub fn parse_aml_table(sdt: &'static Sdt) -> Result { let data = sdt.data(); @@ -73,6 +59,8 @@ pub fn parse_aml_table(sdt: &'static Sdt) -> Result { let mut global_namespace = AmlNamespace::new_namespace(&global_namespace_specifier); term_list.execute(&mut global_namespace, global_namespace_specifier.clone()); + println!("{:#?}", global_namespace); + Ok(global_namespace) } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index dc3c1c8..9f7343e 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -17,6 +17,7 @@ pub enum AmlNamespaceContents { Value(AmlValue), SubNamespace(Box), Namespace(Vec), + Alias(String), OpRegion { region: RegionSpace, offset: AmlValue, @@ -223,3 +224,17 @@ impl AmlNamespace { self.push_to(scope_string, AmlNamespaceContents::Namespace(vec!())); } } + +pub fn get_namespace_string(current: String, modifier: String) -> String { + if modifier.starts_with("\\") { + return modifier; + } + + if modifier.starts_with("^") { + // TODO + } + + let mut namespace = current.clone(); + namespace.push('.'); + namespace + &modifier +} diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index 217347a..d6a003f 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -43,6 +43,12 @@ impl AmlExecutable for NamespaceModifier { namespace.push_to(local_scope_string, AmlNamespaceContents::Value(dro)); }, + NamespaceModifier::Alias { ref source_name, ref alias_name } => { + let local_scope_string = get_namespace_string(scope.clone(), source_name.clone()); + let local_alias_string = get_namespace_string(scope.clone(), alias_name.clone()); + + namespace.push_to(local_scope_string, AmlNamespaceContents::Alias(local_alias_string)); + }, _ => () } diff --git a/src/start.rs b/src/start.rs index bf9deda..55e5cbe 100644 --- a/src/start.rs +++ b/src/start.rs @@ -15,6 +15,8 @@ use memory; use paging::{self, entry, Page, VirtualAddress}; use paging::mapper::MapperFlushAll; +use stop; + /// Test of zero values in BSS. static BSS_TEST_ZERO: usize = 0; /// Test of non-zero values in data. @@ -157,6 +159,7 @@ pub unsafe extern fn kstart_ap(cpu_id: usize, bsp_table: usize, stack_start: usi } pub unsafe fn usermode(ip: usize, sp: usize) -> ! { + stop::kstop(); // Go to usermode asm!("mov ds, ax mov es, ax From 3ed94405aa93b0c3df9be0093f6e41da1154a03c Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 19 Jun 2017 13:49:37 +0100 Subject: [PATCH 02/26] Moved DefDevice and DefThermalZone to namespace --- src/acpi/aml/namedobj.rs | 8 ++++++++ src/acpi/aml/namespace.rs | 3 ++- src/acpi/aml/termlist.rs | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 26cca7b..aeb2637 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -163,6 +163,14 @@ impl AmlExecutable for NamedObj { namespace.push_to(local_scope_string, AmlNamespaceContents::Value( AmlValue::Method(method.clone()))); }, + NamedObj::DefDevice { ref name, ref obj_list } => { + let local_scope_string = get_namespace_string(scope, name.clone()); + obj_list.execute(namespace, local_scope_string); + }, + NamedObj::DefThermalZone { ref name, ref obj_list } => { + let local_scope_string = get_namespace_string(scope, name.clone()); + obj_list.execute(namespace, local_scope_string); + }, _ => () } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 9f7343e..f869cea 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -5,6 +5,7 @@ use collections::vec::Vec; use core::str::FromStr; use super::namedobj::{ RegionSpace, FieldFlags, Method }; +use super::termlist::Object; #[derive(Debug, Clone)] pub struct AmlNamespace { @@ -38,7 +39,7 @@ pub enum AmlValue { BufferField, DDBHandle, DebugObject, - Device, + Device(Vec), Event, FieldUnit, Integer, diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index b236584..b998784 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -37,6 +37,25 @@ pub struct MethodInvocation { } +impl AmlExecutable for Vec { + fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + for term in self { + term.execute(namespace, scope.clone()); + } + + None + } +} + +impl AmlExecutable for Object { + fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + match *self { + Object::NamespaceModifier(ref d) => d.execute(namespace, scope), + Object::NamedObj(ref d) => d.execute(namespace, scope) + } + } +} + impl AmlExecutable for Vec { fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { for term in self { From 7095219316eb800c7779f7a463c442dc67af936c Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 19 Jun 2017 14:12:26 +0100 Subject: [PATCH 03/26] Moved ComputationalData::String into namespace --- src/acpi/aml/dataobj.rs | 1 + src/acpi/aml/namespace.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs index 4400c8d..042b9d5 100644 --- a/src/acpi/aml/dataobj.rs +++ b/src/acpi/aml/dataobj.rs @@ -71,6 +71,7 @@ impl AmlExecutable for ComputationalData { ComputationalData::Zero => Some(AmlValue::IntegerConstant(0)), ComputationalData::One => Some(AmlValue::IntegerConstant(1)), ComputationalData::Ones => Some(AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF)), + ComputationalData::String(ref s) => Some(AmlValue::String(s.clone())), _ => Some(AmlValue::Integer) } } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index f869cea..3e12e55 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -49,7 +49,7 @@ pub enum AmlValue { ObjectReference, OperationRegion, Package(Vec), - String, + String(String), PowerResource, Processor, RawDataBuffer, From 636d94fd20273c375187262d42ba19e2c6775d0a Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Wed, 21 Jun 2017 20:02:05 +0100 Subject: [PATCH 04/26] Moved Processor to namespace, and refactored namespace layout to use BTreeMap --- src/acpi/aml/dataobj.rs | 9 +- src/acpi/aml/mod.rs | 10 +- src/acpi/aml/namedobj.rs | 42 ++++-- src/acpi/aml/namespace.rs | 214 ++++-------------------------- src/acpi/aml/namespacemodifier.rs | 13 +- src/acpi/aml/termlist.rs | 13 +- src/acpi/aml/type1opcode.rs | 5 +- src/acpi/aml/type2opcode.rs | 7 +- src/acpi/mod.rs | 6 +- src/stop.rs | 2 +- 10 files changed, 96 insertions(+), 225 deletions(-) diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs index 042b9d5..885396a 100644 --- a/src/acpi/aml/dataobj.rs +++ b/src/acpi/aml/dataobj.rs @@ -1,7 +1,8 @@ use collections::vec::Vec; use collections::string::String; +use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, get_namespace_string}; +use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package, DefBuffer, DefPackage, DefVarPackage}; @@ -43,7 +44,7 @@ pub enum ComputationalData { } impl AmlExecutable for DataRefObj { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { DataRefObj::DataObj(ref cd) => cd.execute(namespace, scope), _ => Some(AmlValue::Integer) @@ -52,7 +53,7 @@ impl AmlExecutable for DataRefObj { } impl AmlExecutable for DataObj { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { DataObj::ComputationalData(ref cd) => cd.execute(namespace, scope), DataObj::DefPackage(ref pkg) => pkg.execute(namespace, scope), @@ -62,7 +63,7 @@ impl AmlExecutable for DataObj { } impl AmlExecutable for ComputationalData { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { ComputationalData::Byte(b) => Some(AmlValue::IntegerConstant(b as u64)), ComputationalData::Word(w) => Some(AmlValue::IntegerConstant(w as u64)), diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index bc0cee9..a50ec4c 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -4,6 +4,7 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use collections::btree_map::BTreeMap; use core::fmt::Debug; use core::str::FromStr; @@ -23,12 +24,11 @@ mod type1opcode; mod type2opcode; use self::termlist::{parse_term_list, TermObj}; -pub use self::namespace::{get_namespace_string, AmlNamespace, AmlValue}; -use self::namespace::AmlNamespaceContents; +pub use self::namespace::{get_namespace_string, AmlValue}; // TODO: This should be able to take parameters, and may also return multiple values pub trait AmlExecutable { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option; + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option; } // TODO: make private @@ -42,7 +42,7 @@ pub enum AmlError { AmlParseError(&'static str) } -pub fn parse_aml_table(sdt: &'static Sdt) -> Result { +pub fn parse_aml_table(sdt: &'static Sdt) -> Result, AmlError> { let data = sdt.data(); let term_list = match parse_term_list(data) { @@ -56,7 +56,7 @@ pub fn parse_aml_table(sdt: &'static Sdt) -> Result { // Unwrap is fine here. I mean come on, if this goes wrong you've got bigger problems than AML // not loading... - let mut global_namespace = AmlNamespace::new_namespace(&global_namespace_specifier); + let mut global_namespace = BTreeMap::new(); term_list.execute(&mut global_namespace, global_namespace_specifier.clone()); println!("{:#?}", global_namespace); diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index aeb2637..8a9f978 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -1,8 +1,11 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use core::str::FromStr; -use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, AmlNamespaceContents, get_namespace_string}; +use collections::btree_map::BTreeMap; + +use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; use super::namestring::{parse_name_string, parse_name_seg}; use super::termlist::{parse_term_arg, parse_term_list, parse_object_list, TermArg, TermObj, Object}; use super::pkglength::parse_pkg_length; @@ -115,7 +118,7 @@ pub struct Method { } impl AmlExecutable for NamedObj { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => { let local_scope_string = get_namespace_string(scope.clone(), name.clone()); @@ -130,10 +133,10 @@ impl AmlExecutable for NamedObj { _ => return None }; - namespace.push_to(local_scope_string, AmlNamespaceContents::OpRegion { + namespace.insert(local_scope_string, AmlValue::OperationRegion { region: *region, - offset: resolved_offset, - len: resolved_len + offset: Box::new(resolved_offset), + len: Box::new(resolved_len) }); }, NamedObj::DefField { ref name, ref flags, ref field_list } => { @@ -145,7 +148,7 @@ impl AmlExecutable for NamedObj { FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); - namespace.push_to(local_scope_string, AmlNamespaceContents::Field { + namespace.insert(local_scope_string, AmlValue::FieldUnit { op_region: name.clone(), flags: flags.clone(), offset: offset.clone(), @@ -160,16 +163,35 @@ impl AmlExecutable for NamedObj { }, NamedObj::DefMethod { ref name, ref method } => { let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - namespace.push_to(local_scope_string, AmlNamespaceContents::Value( - AmlValue::Method(method.clone()))); + namespace.insert(local_scope_string, AmlValue::Method(method.clone())); }, NamedObj::DefDevice { ref name, ref obj_list } => { let local_scope_string = get_namespace_string(scope, name.clone()); - obj_list.execute(namespace, local_scope_string); + + let mut local_namespace = BTreeMap::new(); + obj_list.execute(&mut local_namespace, String::new()); + + namespace.insert(local_scope_string, AmlValue::Device(local_namespace)); }, NamedObj::DefThermalZone { ref name, ref obj_list } => { let local_scope_string = get_namespace_string(scope, name.clone()); - obj_list.execute(namespace, local_scope_string); + + let mut local_namespace = BTreeMap::new(); + obj_list.execute(&mut local_namespace, String::new()); + + namespace.insert(local_scope_string, AmlValue::ThermalZone(local_namespace)); + }, + NamedObj::DefProcessor { ref name, proc_id, p_blk_addr, p_blk_len, ref obj_list } => { + let local_scope_string = get_namespace_string(scope, name.clone()); + + let mut local_namespace = BTreeMap::new(); + obj_list.execute(&mut local_namespace, String::new()); + + namespace.insert(local_scope_string, AmlValue::Processor { + proc_id: proc_id, + p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None }, + obj_list: local_namespace + }); }, _ => () } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 3e12e55..fc801fc 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -1,36 +1,13 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use collections::btree_map::BTreeMap; use core::str::FromStr; use super::namedobj::{ RegionSpace, FieldFlags, Method }; use super::termlist::Object; - -#[derive(Debug, Clone)] -pub struct AmlNamespace { - name: String, - contents: AmlNamespaceContents -} - -#[derive(Debug, Clone)] -pub enum AmlNamespaceContents { - Value(AmlValue), - SubNamespace(Box), - Namespace(Vec), - Alias(String), - OpRegion { - region: RegionSpace, - offset: AmlValue, - len: AmlValue - }, - Field { - op_region: String, - flags: FieldFlags, - offset: usize, - length: usize - } -} +use super::namestring::SuperName; #[derive(Debug, Clone)] pub enum AmlValue { @@ -39,21 +16,34 @@ pub enum AmlValue { BufferField, DDBHandle, DebugObject, - Device(Vec), + Device(BTreeMap), Event, - FieldUnit, + FieldUnit { + op_region: String, + flags: FieldFlags, + offset: usize, + length: usize + }, Integer, IntegerConstant(u64), Method(Method), Mutex, - ObjectReference, - OperationRegion, + ObjectReference(SuperName), + OperationRegion { + region: RegionSpace, + offset: Box, + len: Box + }, Package(Vec), String(String), PowerResource, - Processor, + Processor { + proc_id: u8, + p_blk: Option, + obj_list: BTreeMap + }, RawDataBuffer, - ThermalZone + ThermalZone(BTreeMap) } impl AmlValue { @@ -72,161 +62,15 @@ impl AmlValue { } } -impl AmlNamespace { - pub fn new_namespace(name: &String) -> AmlNamespace { - AmlNamespace { - name: name.clone(), - contents: AmlNamespaceContents::Namespace(vec!()) - } - } - - pub fn find_str(&self, scope_str: &str) -> Option { - let scope_string = String::from_str(scope_str).unwrap(); - self.find(scope_string) - } - - pub fn find(&self, scope_string: String) -> Option { - if scope_string.len() == 0 { - match self.contents { - AmlNamespaceContents::Value(ref v) => return Some(v.clone()), - _ => return None - } - } - - let mut scope_string = scope_string.clone(); - - if scope_string.starts_with("\\") { - if self.name != "\\" { - return None; - } - - scope_string.remove(0); - } - - if scope_string.starts_with(".") { - scope_string.remove(0); - } - - if scope_string.len() == 0 { - match self.contents { - AmlNamespaceContents::Value(ref v) => return Some(v.clone()), - _ => return None - } - } - - let (current, nextset) = match scope_string.find(".") { - Some(s) => { - let (x, mut y) = scope_string.split_at(s); - y = &y[1..]; - - (String::from_str(x).unwrap(), String::from_str(y).unwrap()) - }, - None => if scope_string.len() <= 4 { - (scope_string, String::from_str("").unwrap()) - } else { - return None; - } - }; - - match self.contents { - AmlNamespaceContents::Namespace(ref namespace) => { - // TODO: Remove this while loop here, there has to be a more elegant way - let mut current_index = 0; - while current_index < namespace.len() { - match namespace[current_index] { - AmlNamespaceContents::SubNamespace(ref ns) => if ns.name == current { - return ns.find(nextset); - }, - _ => () - } - - current_index += 1; - } - }, - _ => () - } - - None - } - - pub fn push(&mut self, val: AmlNamespaceContents) { - match self.contents { - AmlNamespaceContents::Namespace(ref mut v) => v.push(val), - _ => () // TODO: Error this - } - } - - pub fn push_to(&mut self, scope_string: String, contents: AmlNamespaceContents) { - if scope_string.len() == 0 { - return; - } - - let mut scope_string = scope_string.clone(); - - if scope_string.starts_with("\\") { - if self.name != "\\" { - return; - // TODO: Error this - } - - scope_string.remove(0); - } - - if scope_string.starts_with(".") { - scope_string.remove(0); - } - - if scope_string.len() == 0 { - return; - } - - let (current, nextset) = match scope_string.find(".") { - Some(s) => { - let (x, mut y) = scope_string.split_at(s); - y = &y[1..]; - - (String::from_str(x).unwrap(), String::from_str(y).unwrap()) - }, - None => if scope_string.len() <= 4 { - (scope_string, String::from_str("").unwrap()) - } else { - return; - } - }; - - match self.contents { - AmlNamespaceContents::Namespace(ref mut namespace) => { - // TODO: Remove this while loop here, there has to be a more elegant way - let mut current_index = 0; - while current_index < namespace.len() { - match namespace[current_index] { - AmlNamespaceContents::SubNamespace(ref mut ns) => if ns.name == current { - ns.push_to(nextset, contents); - return; - }, - _ => () - } - - current_index += 1; - } - - let mut next = AmlNamespace { - name: current, - contents: contents - }; - - namespace.push(AmlNamespaceContents::SubNamespace(Box::new(next))); - } - _ => () // TODO: Error this - } - } - - pub fn push_subordinate_namespace(&mut self, scope_string: String) { - self.push_to(scope_string, AmlNamespaceContents::Namespace(vec!())); - } -} - pub fn get_namespace_string(current: String, modifier: String) -> String { + if current.len() == 0 { + return modifier; + } + + if modifier.len() == 0 { + return current; + } + if modifier.starts_with("\\") { return modifier; } diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index d6a003f..c1e2395 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -1,10 +1,11 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, AmlNamespaceContents, get_namespace_string}; +use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; use super::pkglength::parse_pkg_length; -use super::namestring::parse_name_string; +use super::namestring::{parse_name_string, SuperName}; use super::termlist::{parse_term_list, TermObj}; use super::dataobj::{parse_data_ref_obj, DataRefObj}; @@ -26,12 +27,10 @@ pub enum NamespaceModifier { } impl AmlExecutable for NamespaceModifier { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { NamespaceModifier::Scope { name: ref name, terms: ref terms } => { let local_scope_string = get_namespace_string(scope, name.clone()); - namespace.push_subordinate_namespace(local_scope_string.clone()); - terms.execute(namespace, local_scope_string); }, NamespaceModifier::Name { ref name, ref data_ref_obj } => { @@ -41,13 +40,13 @@ impl AmlExecutable for NamespaceModifier { None => return None }; - namespace.push_to(local_scope_string, AmlNamespaceContents::Value(dro)); + namespace.insert(local_scope_string, dro); }, NamespaceModifier::Alias { ref source_name, ref alias_name } => { let local_scope_string = get_namespace_string(scope.clone(), source_name.clone()); let local_alias_string = get_namespace_string(scope.clone(), alias_name.clone()); - namespace.push_to(local_scope_string, AmlNamespaceContents::Alias(local_alias_string)); + namespace.insert(local_scope_string, AmlValue::ObjectReference(SuperName::NameString(local_alias_string))); }, _ => () } diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index b998784..72d876d 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -1,8 +1,9 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, get_namespace_string}; +use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; use super::namespacemodifier::{parse_namespace_modifier, NamespaceModifier}; use super::namedobj::{parse_named_obj, NamedObj}; use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj, DataObj, ArgObj, LocalObj}; @@ -38,7 +39,7 @@ pub struct MethodInvocation { } impl AmlExecutable for Vec { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { for term in self { term.execute(namespace, scope.clone()); } @@ -48,7 +49,7 @@ impl AmlExecutable for Vec { } impl AmlExecutable for Object { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { Object::NamespaceModifier(ref d) => d.execute(namespace, scope), Object::NamedObj(ref d) => d.execute(namespace, scope) @@ -57,7 +58,7 @@ impl AmlExecutable for Object { } impl AmlExecutable for Vec { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { for term in self { term.execute(namespace, scope.clone()); } @@ -67,7 +68,7 @@ impl AmlExecutable for Vec { } impl AmlExecutable for TermArg { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { TermArg::LocalObj(ref l) => Some(AmlValue::Integer), TermArg::DataObj(ref d) => d.execute(namespace, scope), @@ -78,7 +79,7 @@ impl AmlExecutable for TermArg { } impl AmlExecutable for TermObj { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { TermObj::NamespaceModifier(ref res) => res.execute(namespace, scope.clone()), TermObj::NamedObj(ref res) => res.execute(namespace, scope.clone()), diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index 103e542..d476a24 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -1,8 +1,9 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace}; +use super::{AmlInternalError, AmlExecutable, AmlValue}; use super::pkglength::parse_pkg_length; use super::termlist::{parse_term_arg, parse_term_list, TermObj, TermArg}; use super::namestring::{parse_name_string, parse_super_name, SuperName}; @@ -45,7 +46,7 @@ pub enum Type1OpCode { } impl AmlExecutable for Type1OpCode { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { None } } diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 744dbef..0313d82 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -1,8 +1,9 @@ use alloc::boxed::Box; use collections::string::String; use collections::vec::Vec; +use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace}; +use super::{AmlInternalError, AmlExecutable, AmlValue}; use super::pkglength::parse_pkg_length; use super::termlist::{parse_term_arg, parse_method_invocation, TermArg, MethodInvocation}; use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name, @@ -201,7 +202,7 @@ pub enum Type2OpCode { } impl AmlExecutable for Type2OpCode { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { None } } @@ -273,7 +274,7 @@ pub enum PackageElement { } impl AmlExecutable for DefPackage { - fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { DefPackage::Package { ref num_elements, ref elements } => { let mut values: Vec = vec!(); diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs index 54a55e5..e1f617f 100644 --- a/src/acpi/mod.rs +++ b/src/acpi/mod.rs @@ -3,6 +3,8 @@ use core::intrinsics::{atomic_load, atomic_store}; use core::sync::atomic::Ordering; +use collections::btree_map::BTreeMap; +use collections::string::String; use spin::Mutex; @@ -19,7 +21,7 @@ use self::rsdt::Rsdt; use self::sdt::Sdt; use self::xsdt::Xsdt; -use self::aml::{is_aml_table, parse_aml_table, AmlNamespace, AmlError}; +use self::aml::{is_aml_table, parse_aml_table, AmlError, AmlValue}; mod dmar; mod fadt; @@ -268,7 +270,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) { pub struct Acpi { pub fadt: Option, - pub namespace: Option, + pub namespace: Option>, } pub static ACPI_TABLE: Mutex = Mutex::new(Acpi { fadt: None, namespace: None }); diff --git a/src/stop.rs b/src/stop.rs index 7a9ac75..4f152bf 100644 --- a/src/stop.rs +++ b/src/stop.rs @@ -12,7 +12,7 @@ pub unsafe extern fn kstop() -> ! { let port = fadt.pm1a_control_block as u16; let mut val = 1 << 13; if let Some(ref namespace) = acpi.namespace { - if let Some(s) = namespace.find_str("\\_S5") { + if let Some(s) = namespace.get("\\_S5") { if let Some(p) = s.get_as_package() { let slp_typa = p[0].get_as_integer().expect("SLP_TYPa is not an integer"); let slp_typb = p[1].get_as_integer().expect("SLP_TYPb is not an integer"); From fceba822ebe8e3f008eee7255a89780bc5758df9 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Wed, 21 Jun 2017 20:13:44 +0100 Subject: [PATCH 05/26] Moved PowerResource into namespace --- src/acpi/aml/namedobj.rs | 12 ++++++++++++ src/acpi/aml/namespace.rs | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 8a9f978..8589d6f 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -193,6 +193,18 @@ impl AmlExecutable for NamedObj { obj_list: local_namespace }); }, + NamedObj::DefPowerRes { ref name, system_level, resource_order, ref obj_list } => { + let local_scope_string = get_namespace_string(scope, name.clone()); + + let mut local_namespace = BTreeMap::new(); + obj_list.execute(&mut local_namespace, String::new()); + + namespace.insert(local_scope_string, AmlValue::PowerResource { + system_level, + resource_order, + obj_list: local_namespace + }); + }, _ => () } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index fc801fc..5d725da 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -36,7 +36,11 @@ pub enum AmlValue { }, Package(Vec), String(String), - PowerResource, + PowerResource { + system_level: u8, + resource_order: u16, + obj_list: BTreeMap + }, Processor { proc_id: u8, p_blk: Option, From 19ccb3612b3e0884162a6d8a627076ea43a313dd Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Wed, 21 Jun 2017 20:27:46 +0100 Subject: [PATCH 06/26] Moved Mutex to namespace --- src/acpi/aml/namedobj.rs | 4 ++++ src/acpi/aml/namespace.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 8589d6f..4fdd8f6 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -205,6 +205,10 @@ impl AmlExecutable for NamedObj { obj_list: local_namespace }); }, + NamedObj::DefMutex { ref name, sync_level } => { + let local_scope_string = get_namespace_string(scope, name.clone()); + namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); + }, _ => () } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 5d725da..ab49846 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -27,7 +27,7 @@ pub enum AmlValue { Integer, IntegerConstant(u64), Method(Method), - Mutex, + Mutex(u8), ObjectReference(SuperName), OperationRegion { region: RegionSpace, From 312aff03c458be8725ce92b493bddbed5a063b8b Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Wed, 21 Jun 2017 20:50:08 +0100 Subject: [PATCH 07/26] Moved Event to namespace --- src/acpi/aml/.#namedobj.rs | 1 + src/acpi/aml/namedobj.rs | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 120000 src/acpi/aml/.#namedobj.rs diff --git a/src/acpi/aml/.#namedobj.rs b/src/acpi/aml/.#namedobj.rs new file mode 120000 index 0000000..66a0d21 --- /dev/null +++ b/src/acpi/aml/.#namedobj.rs @@ -0,0 +1 @@ +venos@Maponos.11470:1498034251 \ No newline at end of file diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 4fdd8f6..24b6256 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -209,7 +209,11 @@ impl AmlExecutable for NamedObj { let local_scope_string = get_namespace_string(scope, name.clone()); namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); }, - _ => () + NamedObj::DefEvent { ref name } => { + let local_scope_string = get_namespace_string(scope, name.clone()); + namespace.insert(local_scope_string, AmlValue::Event); + }, +// _ => () } None From 2e64cea81f7037e6c8647f35673a62e40f1a234e Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Wed, 21 Jun 2017 20:54:29 +0100 Subject: [PATCH 08/26] Removed temporary files --- src/acpi/aml/.#namedobj.rs | 1 - src/acpi/aml/namedobj.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 120000 src/acpi/aml/.#namedobj.rs diff --git a/src/acpi/aml/.#namedobj.rs b/src/acpi/aml/.#namedobj.rs deleted file mode 120000 index 66a0d21..0000000 --- a/src/acpi/aml/.#namedobj.rs +++ /dev/null @@ -1 +0,0 @@ -venos@Maponos.11470:1498034251 \ No newline at end of file diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 24b6256..87c5bc7 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -213,7 +213,7 @@ impl AmlExecutable for NamedObj { let local_scope_string = get_namespace_string(scope, name.clone()); namespace.insert(local_scope_string, AmlValue::Event); }, -// _ => () + _ => () } None From 12e7d1ad4db4c8a23e0f71fbd046dbe723e0b511 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 12:02:17 +0100 Subject: [PATCH 09/26] Moved BankField to the namespace --- src/acpi/aml/namedobj.rs | 29 +++++++++++++++++++++++++++++ src/acpi/aml/namespace.rs | 1 + 2 files changed, 30 insertions(+) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 87c5bc7..203d20a 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -120,6 +120,34 @@ pub struct Method { impl AmlExecutable for NamedObj { fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { + NamedObj::DefBankField { ref region_name, ref bank_name, ref bank_value, ref flags, ref field_list } => { + let mut offset: usize = 0; + let bank_val = if let Some(b) = bank_value.execute(namespace, scope.clone()) { + Box::new(b) + } else { + return None; + }; + + for f in field_list { + match *f { + FieldElement::ReservedField { length } => offset += length, + FieldElement::NamedField { name: ref field_name, length } => { + let local_scope_string = get_namespace_string(scope.clone(), + field_name.clone()); + namespace.insert(local_scope_string, AmlValue::FieldUnit { + op_region: region_name.clone(), + bank_selector: Some((bank_name.clone(), bank_val.clone())), + flags: flags.clone(), + offset: offset.clone(), + length: length.clone() + }); + + offset += length; + }, + _ => () + } + } + }, NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => { let local_scope_string = get_namespace_string(scope.clone(), name.clone()); @@ -150,6 +178,7 @@ impl AmlExecutable for NamedObj { field_name.clone()); namespace.insert(local_scope_string, AmlValue::FieldUnit { op_region: name.clone(), + bank_selector: None, flags: flags.clone(), offset: offset.clone(), length: length.clone() diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index ab49846..0e99aaf 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -20,6 +20,7 @@ pub enum AmlValue { Event, FieldUnit { op_region: String, + bank_selector: Option<(String, Box)>, flags: FieldFlags, offset: usize, length: usize From cef562c83213e0f3c0e6c3b02e79be4610b4c442 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 12:16:30 +0100 Subject: [PATCH 10/26] Moved BufferFields into namespace --- src/acpi/aml/namedobj.rs | 90 +++++++++++++++++++++++++++++++++++++++ src/acpi/aml/namespace.rs | 6 ++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 203d20a..1123535 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -148,6 +148,96 @@ impl AmlExecutable for NamedObj { } } }, + NamedObj::DefCreateBitField { ref name, ref source_buf, ref bit_index } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_index = match bit_index.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: resolved_source_buf, + index: resolved_index, + length: 1 + }); + }, + NamedObj::DefCreateByteField { ref name, ref source_buf, ref byte_index } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_index = match byte_index.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: resolved_source_buf, + index: resolved_index, + length: 8 + }); + }, + NamedObj::DefCreateWordField { ref name, ref source_buf, ref byte_index } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_index = match byte_index.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: resolved_source_buf, + index: resolved_index, + length: 16 + }); + }, + NamedObj::DefCreateDWordField { ref name, ref source_buf, ref byte_index } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_index = match byte_index.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: resolved_source_buf, + index: resolved_index, + length: 32 + }); + }, + NamedObj::DefCreateQWordField { ref name, ref source_buf, ref byte_index } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_index = match byte_index.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: resolved_source_buf, + index: resolved_index, + length: 64 + }); + }, NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => { let local_scope_string = get_namespace_string(scope.clone(), name.clone()); diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 0e99aaf..f95a25a 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -13,7 +13,11 @@ use super::namestring::SuperName; pub enum AmlValue { Uninitialized, Buffer, - BufferField, + BufferField { + source_buf: Box, + index: Box, + length: usize + }, DDBHandle, DebugObject, Device(BTreeMap), From 94e391c9b6802b13887d4feff14ddfdfd646b667 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 12:23:14 +0100 Subject: [PATCH 11/26] Moved arbitrary length buffer field into namespace --- src/acpi/aml/namedobj.rs | 32 +++++++++++++++++++++++++++----- src/acpi/aml/namespace.rs | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 1123535..dc206a1 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -163,7 +163,7 @@ impl AmlExecutable for NamedObj { namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: resolved_source_buf, index: resolved_index, - length: 1 + length: Box::new(AmlValue::IntegerConstant(1)) }); }, NamedObj::DefCreateByteField { ref name, ref source_buf, ref byte_index } => { @@ -181,7 +181,7 @@ impl AmlExecutable for NamedObj { namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: resolved_source_buf, index: resolved_index, - length: 8 + length: Box::new(AmlValue::IntegerConstant(8)) }); }, NamedObj::DefCreateWordField { ref name, ref source_buf, ref byte_index } => { @@ -199,7 +199,7 @@ impl AmlExecutable for NamedObj { namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: resolved_source_buf, index: resolved_index, - length: 16 + length: Box::new(AmlValue::IntegerConstant(16)) }); }, NamedObj::DefCreateDWordField { ref name, ref source_buf, ref byte_index } => { @@ -217,7 +217,7 @@ impl AmlExecutable for NamedObj { namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: resolved_source_buf, index: resolved_index, - length: 32 + length: Box::new(AmlValue::IntegerConstant(32)) }); }, NamedObj::DefCreateQWordField { ref name, ref source_buf, ref byte_index } => { @@ -235,7 +235,29 @@ impl AmlExecutable for NamedObj { namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: resolved_source_buf, index: resolved_index, - length: 64 + length: Box::new(AmlValue::IntegerConstant(64)) + }); + }, + NamedObj::DefCreateField { ref name, ref source_buf, ref bit_index, ref num_bits } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_index = match bit_index.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + let resolved_length = match num_bits.execute(namespace, scope.clone()) { + Some(r) => Box::new(r), + _ => return None + }; + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: resolved_source_buf, + index: resolved_index, + length: resolved_length }); }, NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => { diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index f95a25a..f52206f 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -16,7 +16,7 @@ pub enum AmlValue { BufferField { source_buf: Box, index: Box, - length: usize + length: Box }, DDBHandle, DebugObject, From 443c1ac1f8c42432246fc891a14009a6a9c9fb0a Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 12:45:58 +0100 Subject: [PATCH 12/26] Moved indexfield to namespace --- src/acpi/aml/namedobj.rs | 35 +++++++++++++++++++++++++++++++---- src/acpi/aml/namespace.rs | 16 ++++++++++++++-- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index dc206a1..0a21504 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -6,6 +6,7 @@ use core::str::FromStr; use collections::btree_map::BTreeMap; use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; +use super::namespace::FieldSelector; use super::namestring::{parse_name_string, parse_name_seg}; use super::termlist::{parse_term_arg, parse_term_list, parse_object_list, TermArg, TermObj, Object}; use super::pkglength::parse_pkg_length; @@ -135,8 +136,35 @@ impl AmlExecutable for NamedObj { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); namespace.insert(local_scope_string, AmlValue::FieldUnit { - op_region: region_name.clone(), - bank_selector: Some((bank_name.clone(), bank_val.clone())), + selector: FieldSelector::Bank { + region: region_name.clone(), + bank_selector: bank_val.clone() + }, + flags: flags.clone(), + offset: offset.clone(), + length: length.clone() + }); + + offset += length; + }, + _ => () + } + } + }, + NamedObj::DefIndexField { ref idx_name, ref data_name, ref flags, ref field_list } => { + let mut offset: usize = 0; + + for f in field_list { + match *f { + FieldElement::ReservedField { length } => offset += length, + FieldElement::NamedField { name: ref field_name, length } => { + let local_scope_string = get_namespace_string(scope.clone(), + field_name.clone()); + namespace.insert(local_scope_string, AmlValue::FieldUnit { + selector: FieldSelector::Index { + index_selector: idx_name.clone(), + data_selector: data_name.clone() + }, flags: flags.clone(), offset: offset.clone(), length: length.clone() @@ -289,8 +317,7 @@ impl AmlExecutable for NamedObj { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); namespace.insert(local_scope_string, AmlValue::FieldUnit { - op_region: name.clone(), - bank_selector: None, + selector: FieldSelector::Region(name.clone()), flags: flags.clone(), offset: offset.clone(), length: length.clone() diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index f52206f..7d16ec0 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -9,6 +9,19 @@ use super::namedobj::{ RegionSpace, FieldFlags, Method }; use super::termlist::Object; use super::namestring::SuperName; +#[derive(Debug, Clone)] +pub enum FieldSelector { + Region(String), + Bank { + region: String, + bank_selector: Box + }, + Index { + index_selector: String, + data_selector: String + } +} + #[derive(Debug, Clone)] pub enum AmlValue { Uninitialized, @@ -23,8 +36,7 @@ pub enum AmlValue { Device(BTreeMap), Event, FieldUnit { - op_region: String, - bank_selector: Option<(String, Box)>, + selector: FieldSelector, flags: FieldFlags, offset: usize, length: usize From 0a67ad4b235e57fa5d20cb6104c07111c57fc295 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 13:34:05 +0100 Subject: [PATCH 13/26] Moved DataRegion into namespace - more infrastructure required --- src/acpi/aml/namedobj.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 0a21504..7b40db4 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -288,6 +288,15 @@ impl AmlExecutable for NamedObj { length: resolved_length }); }, + NamedObj::DefDataRegion { ref name, ref signature, ref oem_id, ref oem_table_id } => { + let local_scope_string = get_namespace_string(scope.clone(), name.clone()); + + namespace.insert(local_scope_string, AmlValue::OperationRegion { + region: RegionSpace::SystemMemory, + offset: Box::new(AmlValue::IntegerConstant(0)), + len: Box::new(AmlValue::IntegerConstant(0)) + }); + }, NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => { let local_scope_string = get_namespace_string(scope.clone(), name.clone()); From c8eca653b8a894e0f8baa15958edd3d0a30183c6 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 15:09:04 +0100 Subject: [PATCH 14/26] Moved ConnectFieldNameString into namespace --- src/acpi/aml/namedobj.rs | 14 +++++++++++++- src/acpi/aml/namespace.rs | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 7b40db4..40de06f 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -7,7 +7,7 @@ use collections::btree_map::BTreeMap; use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; use super::namespace::FieldSelector; -use super::namestring::{parse_name_string, parse_name_seg}; +use super::namestring::{parse_name_string, parse_name_seg, SuperName}; use super::termlist::{parse_term_arg, parse_term_list, parse_object_list, TermArg, TermObj, Object}; use super::pkglength::parse_pkg_length; use super::type2opcode::{parse_def_buffer, DefBuffer}; @@ -123,6 +123,7 @@ impl AmlExecutable for NamedObj { match *self { NamedObj::DefBankField { ref region_name, ref bank_name, ref bank_value, ref flags, ref field_list } => { let mut offset: usize = 0; + let mut connection = AmlValue::Uninitialized; let bank_val = if let Some(b) = bank_value.execute(namespace, scope.clone()) { Box::new(b) } else { @@ -132,6 +133,8 @@ impl AmlExecutable for NamedObj { for f in field_list { match *f { FieldElement::ReservedField { length } => offset += length, + FieldElement::ConnectFieldNameString(ref name) => connection = + AmlValue::ObjectReference(SuperName::NameString(name.clone())), FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -140,6 +143,7 @@ impl AmlExecutable for NamedObj { region: region_name.clone(), bank_selector: bank_val.clone() }, + connection: Box::new(connection.clone()), flags: flags.clone(), offset: offset.clone(), length: length.clone() @@ -153,10 +157,13 @@ impl AmlExecutable for NamedObj { }, NamedObj::DefIndexField { ref idx_name, ref data_name, ref flags, ref field_list } => { let mut offset: usize = 0; + let mut connection = AmlValue::Uninitialized; for f in field_list { match *f { FieldElement::ReservedField { length } => offset += length, + FieldElement::ConnectFieldNameString(ref name) => connection = + AmlValue::ObjectReference(SuperName::NameString(name.clone())), FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -165,6 +172,7 @@ impl AmlExecutable for NamedObj { index_selector: idx_name.clone(), data_selector: data_name.clone() }, + connection: Box::new(connection.clone()), flags: flags.clone(), offset: offset.clone(), length: length.clone() @@ -318,15 +326,19 @@ impl AmlExecutable for NamedObj { }, NamedObj::DefField { ref name, ref flags, ref field_list } => { let mut offset: usize = 0; + let mut connection = AmlValue::Uninitialized; for f in field_list { match *f { FieldElement::ReservedField { length } => offset += length, + FieldElement::ConnectFieldNameString(ref name) => connection = + AmlValue::ObjectReference(SuperName::NameString(name.clone())), FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); namespace.insert(local_scope_string, AmlValue::FieldUnit { selector: FieldSelector::Region(name.clone()), + connection: Box::new(connection.clone()), flags: flags.clone(), offset: offset.clone(), length: length.clone() diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 7d16ec0..375057e 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -37,6 +37,7 @@ pub enum AmlValue { Event, FieldUnit { selector: FieldSelector, + connection: Box, flags: FieldFlags, offset: usize, length: usize From fb0e5137e883cc2918ef5140eb973b8f18bbbe92 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 15:22:19 +0100 Subject: [PATCH 15/26] Moved ConnectFieldBufferData to the namespace --- src/acpi/aml/namedobj.rs | 18 ++++++++++++++++++ src/acpi/aml/namespace.rs | 5 ++++- src/acpi/aml/type2opcode.rs | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 40de06f..664b767 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -135,6 +135,12 @@ impl AmlExecutable for NamedObj { FieldElement::ReservedField { length } => offset += length, FieldElement::ConnectFieldNameString(ref name) => connection = AmlValue::ObjectReference(SuperName::NameString(name.clone())), + FieldElement::ConnectFieldBufferData(ref buf) => { + connection = match buf.execute(namespace, scope.clone()) { + Some(c) => c, + None => return None + }; + }, FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -164,6 +170,12 @@ impl AmlExecutable for NamedObj { FieldElement::ReservedField { length } => offset += length, FieldElement::ConnectFieldNameString(ref name) => connection = AmlValue::ObjectReference(SuperName::NameString(name.clone())), + FieldElement::ConnectFieldBufferData(ref buf) => { + connection = match buf.execute(namespace, scope.clone()) { + Some(c) => c, + None => return None + }; + }, FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -333,6 +345,12 @@ impl AmlExecutable for NamedObj { FieldElement::ReservedField { length } => offset += length, FieldElement::ConnectFieldNameString(ref name) => connection = AmlValue::ObjectReference(SuperName::NameString(name.clone())), + FieldElement::ConnectFieldBufferData(ref buf) => { + connection = match buf.execute(namespace, scope.clone()) { + Some(c) => c, + None => return None + }; + }, FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 375057e..a492aab 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -25,7 +25,10 @@ pub enum FieldSelector { #[derive(Debug, Clone)] pub enum AmlValue { Uninitialized, - Buffer, + Buffer { + length: Box, + byte_list: Vec + }, BufferField { source_buf: Box, index: Box, diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 0313d82..e96bdbc 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -207,6 +207,25 @@ impl AmlExecutable for Type2OpCode { } } +impl AmlExecutable for DefBuffer { + fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { + match *self { + DefBuffer::Buffer { ref buffer_size, ref byte_list } => { + let length = match buffer_size.execute(namespace, scope.clone()) { + Some(l) => Box::new(l), + _ => return None + }; + + Some(AmlValue::Buffer { + length: length, + byte_list: byte_list.clone() + }) + }, + _ => None + } + } +} + #[derive(Debug, Clone)] pub enum DefObjectType { SuperName(SuperName), From c83cefee089dd414686332b39c591055bb31b0d6 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 15:43:00 +0100 Subject: [PATCH 16/26] Moved AccessType into namespace --- src/acpi/aml/namedobj.rs | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 664b767..66af6d6 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -124,6 +124,7 @@ impl AmlExecutable for NamedObj { NamedObj::DefBankField { ref region_name, ref bank_name, ref bank_value, ref flags, ref field_list } => { let mut offset: usize = 0; let mut connection = AmlValue::Uninitialized; + let mut flags = flags.clone(); let bank_val = if let Some(b) = bank_value.execute(namespace, scope.clone()) { Box::new(b) } else { @@ -141,6 +142,12 @@ impl AmlExecutable for NamedObj { None => return None }; }, + FieldElement::AccessField { ref access_type, ref access_attrib } => { + match *access_type { + AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(access_attrib.clone()), + ref a => flags.access_type = a.clone() + } + }, FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -157,13 +164,13 @@ impl AmlExecutable for NamedObj { offset += length; }, - _ => () } } }, NamedObj::DefIndexField { ref idx_name, ref data_name, ref flags, ref field_list } => { let mut offset: usize = 0; let mut connection = AmlValue::Uninitialized; + let mut flags = flags.clone(); for f in field_list { match *f { @@ -176,6 +183,12 @@ impl AmlExecutable for NamedObj { None => return None }; }, + FieldElement::AccessField { ref access_type, ref access_attrib } => { + match *access_type { + AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(access_attrib.clone()), + ref a => flags.access_type = a.clone() + } + }, FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -191,8 +204,7 @@ impl AmlExecutable for NamedObj { }); offset += length; - }, - _ => () + } } } }, @@ -339,6 +351,7 @@ impl AmlExecutable for NamedObj { NamedObj::DefField { ref name, ref flags, ref field_list } => { let mut offset: usize = 0; let mut connection = AmlValue::Uninitialized; + let mut flags = flags.clone(); for f in field_list { match *f { @@ -351,6 +364,12 @@ impl AmlExecutable for NamedObj { None => return None }; }, + FieldElement::AccessField { ref access_type, ref access_attrib } => { + match *access_type { + AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(access_attrib.clone()), + ref a => flags.access_type = a.clone() + } + }, FieldElement::NamedField { name: ref field_name, length } => { let local_scope_string = get_namespace_string(scope.clone(), field_name.clone()); @@ -363,8 +382,7 @@ impl AmlExecutable for NamedObj { }); offset += length; - }, - _ => () + } } } }, @@ -456,7 +474,7 @@ pub enum AccessType { WordAcc, DWordAcc, QWordAcc, - BufferAcc + BufferAcc(AccessAttrib) } #[derive(Debug, Clone)] @@ -559,7 +577,7 @@ fn parse_def_bank_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErr 2 => AccessType::WordAcc, 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, - 5 => AccessType::BufferAcc, + 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), _ => return Err(AmlInternalError::AmlParseError("BankField - invalid access type")) }, lock_rule: (flags_raw & 0x10) == 0x10, @@ -738,7 +756,7 @@ fn parse_def_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { 2 => AccessType::WordAcc, 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, - 5 => AccessType::BufferAcc, + 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), _ => return Err(AmlInternalError::AmlParseError("Field - Invalid access type")) }, lock_rule: (flags_raw & 0x10) == 0x10, @@ -788,7 +806,7 @@ fn parse_def_index_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalEr 2 => AccessType::WordAcc, 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, - 5 => AccessType::BufferAcc, + 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid access type")) }, lock_rule: (flags_raw & 0x10) == 0x10, @@ -870,7 +888,7 @@ fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalE 2 => AccessType::WordAcc, 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, - 5 => AccessType::BufferAcc, + 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access type")) }; From be1a75e4725323dc7a32612a648574b49eaee575 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 16:25:19 +0100 Subject: [PATCH 17/26] Finalized ACPIType --- src/acpi/aml/dataobj.rs | 6 +++--- src/acpi/aml/namespace.rs | 7 ++++--- src/acpi/aml/termlist.rs | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs index 885396a..27f81f8 100644 --- a/src/acpi/aml/dataobj.rs +++ b/src/acpi/aml/dataobj.rs @@ -47,7 +47,7 @@ impl AmlExecutable for DataRefObj { fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { DataRefObj::DataObj(ref cd) => cd.execute(namespace, scope), - _ => Some(AmlValue::Integer) + _ => Some(AmlValue::Uninitialized) } } } @@ -57,7 +57,7 @@ impl AmlExecutable for DataObj { match *self { DataObj::ComputationalData(ref cd) => cd.execute(namespace, scope), DataObj::DefPackage(ref pkg) => pkg.execute(namespace, scope), - _ => Some(AmlValue::Integer) + _ => Some(AmlValue::Uninitialized) } } } @@ -73,7 +73,7 @@ impl AmlExecutable for ComputationalData { ComputationalData::One => Some(AmlValue::IntegerConstant(1)), ComputationalData::Ones => Some(AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF)), ComputationalData::String(ref s) => Some(AmlValue::String(s.clone())), - _ => Some(AmlValue::Integer) + _ => Some(AmlValue::Uninitialized) } } } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index a492aab..be49f7b 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -8,6 +8,7 @@ use core::str::FromStr; use super::namedobj::{ RegionSpace, FieldFlags, Method }; use super::termlist::Object; use super::namestring::SuperName; +use super::type2opcode::Type2OpCode; #[derive(Debug, Clone)] pub enum FieldSelector { @@ -34,7 +35,7 @@ pub enum AmlValue { index: Box, length: Box }, - DDBHandle, + DDBHandle(u32), // Index into the XSDT DebugObject, Device(BTreeMap), Event, @@ -45,7 +46,7 @@ pub enum AmlValue { offset: usize, length: usize }, - Integer, + Integer(Type2OpCode), IntegerConstant(u64), Method(Method), Mutex(u8), @@ -67,7 +68,7 @@ pub enum AmlValue { p_blk: Option, obj_list: BTreeMap }, - RawDataBuffer, + RawDataBuffer(Vec), ThermalZone(BTreeMap) } diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index 72d876d..c7d0c5f 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -70,10 +70,10 @@ impl AmlExecutable for Vec { impl AmlExecutable for TermArg { fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { match *self { - TermArg::LocalObj(ref l) => Some(AmlValue::Integer), + TermArg::LocalObj(ref l) => Some(AmlValue::Uninitialized), TermArg::DataObj(ref d) => d.execute(namespace, scope), - TermArg::ArgObj(ref a) => Some(AmlValue::Integer), - TermArg::Type2Opcode(ref o) => Some(AmlValue::Integer) + TermArg::ArgObj(ref a) => Some(AmlValue::Uninitialized), + TermArg::Type2Opcode(ref o) => Some(AmlValue::Uninitialized) } } } From 9fb15e7e9255f786b3c135d24642946fc6f0b559 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Thu, 22 Jun 2017 19:12:40 +0100 Subject: [PATCH 18/26] Namespaces can now be concatenated, handling of SSDTs is now performed --- src/acpi/aml/mod.rs | 4 +--- src/acpi/mod.rs | 13 ++++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index a50ec4c..7ad0473 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -59,13 +59,11 @@ pub fn parse_aml_table(sdt: &'static Sdt) -> Result, let mut global_namespace = BTreeMap::new(); term_list.execute(&mut global_namespace, global_namespace_specifier.clone()); - println!("{:#?}", global_namespace); - Ok(global_namespace) } pub fn is_aml_table(sdt: &'static Sdt) -> bool { - if &sdt.signature == b"DSDT" {//|| &sdt.signature == b"SSDT" { + if &sdt.signature == b"DSDT" || &sdt.signature == b"SSDT" { true } else { false diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs index e1f617f..ead12f5 100644 --- a/src/acpi/mod.rs +++ b/src/acpi/mod.rs @@ -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 spin::Mutex; @@ -198,14 +199,20 @@ fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { } } } else if is_aml_table(sdt) { - ACPI_TABLE.lock().namespace = match parse_aml_table(sdt) { + match parse_aml_table(sdt) { Ok(res) => { println!(": Parsed"); - Some(res) + let ref mut namespace = ACPI_TABLE.lock().namespace; + + if let Some(ref mut ns) = *namespace { + let mut res = res.clone(); + ns.append(&mut res); + } else { + *namespace = Some(res); + } }, Err(AmlError::AmlParseError(e)) => { println!(": {}", e); - None } }; } else { From f72f97ef36566a7b6a0f52cf1b0d65b9c8ec923a Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Fri, 23 Jun 2017 14:02:40 +0100 Subject: [PATCH 19/26] Rolled parsing and execution steps into one for namespace modifiers --- src/acpi/aml/mod.rs | 10 +-- src/acpi/aml/namespacemodifier.rs | 119 +++++++++++------------------- src/acpi/aml/parser.rs | 16 ++++ src/acpi/aml/parsermacros.rs | 21 ++++-- src/acpi/aml/termlist.rs | 27 ++++--- 5 files changed, 95 insertions(+), 98 deletions(-) create mode 100644 src/acpi/aml/parser.rs diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index 7ad0473..a6d5a35 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -22,22 +22,16 @@ mod namedobj; mod dataobj; mod type1opcode; mod type2opcode; +mod parser; +use self::parser::{ParseResult, AmlInternalError}; use self::termlist::{parse_term_list, TermObj}; pub use self::namespace::{get_namespace_string, AmlValue}; -// TODO: This should be able to take parameters, and may also return multiple values pub trait AmlExecutable { fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option; } -// TODO: make private -pub enum AmlInternalError { - AmlParseError(&'static str), - AmlInvalidOpCode, - AmlDeferredLoad -} - pub enum AmlError { AmlParseError(&'static str) } diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index c1e2395..8e7e2cc 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -9,55 +9,11 @@ use super::namestring::{parse_name_string, SuperName}; use super::termlist::{parse_term_list, TermObj}; use super::dataobj::{parse_data_ref_obj, DataRefObj}; -#[derive(Debug, Clone)] -pub enum NamespaceModifier { - Name { - name: String, - data_ref_obj: DataRefObj - }, - Scope { - name: String, - terms: Vec - }, - Alias { - source_name: String, - alias_name: String - }, - DeferredLoad(Vec) -} - -impl AmlExecutable for NamespaceModifier { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - NamespaceModifier::Scope { name: ref name, terms: ref terms } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - terms.execute(namespace, local_scope_string); - }, - NamespaceModifier::Name { ref name, ref data_ref_obj } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - let dro = match data_ref_obj.execute(namespace, scope) { - Some(s) => s, - None => return None - }; - - namespace.insert(local_scope_string, dro); - }, - NamespaceModifier::Alias { ref source_name, ref alias_name } => { - let local_scope_string = get_namespace_string(scope.clone(), source_name.clone()); - let local_alias_string = get_namespace_string(scope.clone(), alias_name.clone()); - - namespace.insert(local_scope_string, AmlValue::ObjectReference(SuperName::NameString(local_alias_string))); - }, - _ => () - } - - None - } -} - -pub fn parse_namespace_modifier(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> { +pub fn parse_namespace_modifier(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, + data, namespace, scope, parse_alias_op, parse_scope_op, parse_name_op @@ -66,42 +22,57 @@ pub fn parse_namespace_modifier(data: &[u8]) -> Result<(NamespaceModifier, usize Err(AmlInternalError::AmlInvalidOpCode) } -fn parse_alias_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> { +fn parse_alias_op(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x06); - let (source_name, source_name_len) = parse_name_string(&data[1..])?; - let (alias_name, alias_name_len) = parse_name_string(&data[1 + source_name_len..])?; + let source_name = parse_name_string(&data[1..], namespace, scope)?; + let alias_name = parse_name_string(&data[1 + source_name_len..], namespace, scope)?; + + let local_scope_string = get_namespace_string(scope.clone(), parser_verify_value!(source_name)); + let local_alias_string = get_namespace_string(scope.clone(), parser_verify_value!(alias_name)); - Ok((NamespaceModifier::Alias {source_name, alias_name}, 1 + source_name_len + alias_name_len)) + namespace.insert(local_scope_string, AmlValue::ObjectReference( + SuperName::NameString(local_alias_string))); + + Ok(AmlParseType { + val: None, + len: 1 + source_name.len + alias_name.len + }) } -fn parse_name_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> { +fn parse_name_op(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x08); + + let name = parse_name_string(&data[1..], namespace, scope)?; + let data_ref_obj = parse_data_ref_obj(&data[1 + name_len..], namespace, scope)?; + + let local_scope_string = get_namespace_string(scope.clone(), parser_verify_value!(name)); - let (name, name_len) = parse_name_string(&data[1..])?; - let (data_ref_obj, data_ref_obj_len) = parse_data_ref_obj(&data[1 + name_len..])?; - - Ok((NamespaceModifier::Name {name, data_ref_obj}, 1 + name_len + data_ref_obj_len)) + namespace.insert(local_scope_string, parser_verify_value!(data_ref_obj)); + + Ok(AmlParseType { + val: None, + len: 1 + name_len + data_ref_obj_len + }) } -fn parse_scope_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> { +fn parse_scope_op(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x10); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let (name, name_len) = match parse_name_string(&data[1 + pkg_length_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamespaceModifier::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), - 1 + pkg_length)), - Err(e) => return Err(e) - }; - let terms = match parse_term_list(&data[1 + pkg_length_len + name_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamespaceModifier::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), - 1 + pkg_length)), - Err(e) => return Err(e) - }; - - Ok((NamespaceModifier::Scope {name, terms}, pkg_length + 1)) + let name = parse_name_string(&data[1 + pkg_length_len..], namespace, scope)?; + + let local_scope_string = get_namespace_string(scope, parser_verify_value!(name)); + parse_term_list(&data[1 + pkg_length_len + name_len..], namespace, local_scope_string)?; + + Ok(AmlParseType { + val: None, + len: 1 + pkg_length + }) } diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs new file mode 100644 index 0000000..321f013 --- /dev/null +++ b/src/acpi/aml/parser.rs @@ -0,0 +1,16 @@ +use super::AmlValue; + +pub type ParseResult = Result; + +pub struct AmlParseType { + val: Option, + len: usize +} + +// TODO: make private +pub enum AmlInternalError { + AmlParseError(&'static str), + AmlInvalidOpCode, + AmlValueError, + AmlDeferredLoad +} diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs index 50e3aed..7c9e101 100644 --- a/src/acpi/aml/parsermacros.rs +++ b/src/acpi/aml/parsermacros.rs @@ -1,15 +1,15 @@ #[macro_export] macro_rules! parser_selector { - {$data:expr, $func:expr} => { - match $func($data) { + {$data:expr, $namespace:expr, $scope:expr, $func:expr} => { + match $func($data, $namespace, $scope) { Ok(res) => return Ok(res), Err(AmlInternalError::AmlInvalidOpCode) => (), Err(e) => return Err(e) } }; - {$data:expr, $func:expr, $($funcs:expr),+} => { - parser_selector! {$data, $func}; - parser_selector! {$data, $($funcs),*}; + {$data:expr, $namespace:expr, $scope:expr, $func:expr, $($funcs:expr),+} => { + parser_selector! {$data, $namespace, $scope, $func}; + parser_selector! {$data, $namespace, $scope, $($funcs),*}; }; } @@ -47,3 +47,14 @@ macro_rules! parser_opcode_extended { } }; } + +#[macro_export] +macro_rules! parser_verify_value { + ($val:expr) => { + match $val.val { + Some(s) => s, + None => return Err(AmlInternalError::AmlValueError) + } + }; +} + diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index c7d0c5f..5e5482e 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -89,17 +89,20 @@ impl AmlExecutable for TermObj { } } -pub fn parse_term_list(data: &[u8]) -> Result, AmlInternalError> { - let mut terms: Vec = vec!(); +pub fn parse_term_list(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { let mut current_offset: usize = 0; while current_offset < data.len() { - let (res, len) = parse_term_obj(&data[current_offset..])?; - terms.push(res); + let (res, len) = parse_term_obj(&data[current_offset..], namespace, scope)?; current_offset += len; } - Ok(terms) + Ok(AmlParseType { + val: None, + len: data.len() + }) } pub fn parse_term_arg(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> { @@ -142,13 +145,15 @@ pub fn parse_method_invocation(data: &[u8]) -> Result<(MethodInvocation, usize), Err(AmlInternalError::AmlDeferredLoad) } -fn parse_term_obj(data: &[u8]) -> Result<(TermObj, usize), AmlInternalError> { +fn parse_term_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(TermObj::NamespaceModifier, parser_wrap!(Box::new, parse_namespace_modifier)), - parser_wrap!(TermObj::NamedObj, parser_wrap!(Box::new, parse_named_obj)), - parser_wrap!(TermObj::Type1Opcode, parser_wrap!(Box::new, parse_type1_opcode)), - parser_wrap!(TermObj::Type2Opcode, parser_wrap!(Box::new, parse_type2_opcode)) + data, namespace, scope, + parse_namespace_modifier, + parse_named_obj, + parse_type1_opcode, + parse_type2_opcode }; Err(AmlInternalError::AmlInvalidOpCode) From 590610f4a5d7576c248ff5aaa1bd31f5b3d27b34 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Sun, 2 Jul 2017 13:07:43 +0100 Subject: [PATCH 20/26] Refactored parser to execute in the parse step for efficiency and simplicity --- src/acpi/aml/dataobj.rs | 205 +++-- src/acpi/aml/mod.rs | 30 +- src/acpi/aml/namedobj.rs | 1175 ++++++++++---------------- src/acpi/aml/namespace.rs | 46 +- src/acpi/aml/namespacemodifier.rs | 46 +- src/acpi/aml/namestring.rs | 106 +-- src/acpi/aml/parser.rs | 20 +- src/acpi/aml/parsermacros.rs | 31 +- src/acpi/aml/pkglength.rs | 6 +- src/acpi/aml/termlist.rs | 153 +--- src/acpi/aml/type1opcode.rs | 404 ++++----- src/acpi/aml/type2opcode.rs | 1308 +++++++++++++++-------------- src/acpi/mod.rs | 8 +- src/stop.rs | 2 +- 14 files changed, 1622 insertions(+), 1918 deletions(-) diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs index 27f81f8..77f7d2f 100644 --- a/src/acpi/aml/dataobj.rs +++ b/src/acpi/aml/dataobj.rs @@ -2,132 +2,99 @@ use collections::vec::Vec; use collections::string::String; use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult}; +use super::namespace::{AmlValue, ObjectReference}; -use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package, - DefBuffer, DefPackage, DefVarPackage}; -use super::termlist::{parse_term_arg, TermArg}; -use super::namestring::{parse_super_name, SuperName}; +use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package}; +use super::termlist::parse_term_arg; +use super::namestring::parse_super_name; -#[derive(Debug, Clone)] -pub enum DataObj { - ComputationalData(ComputationalData), - DefPackage(DefPackage), - DefVarPackage(DefVarPackage) -} - -#[derive(Debug, Clone)] -pub enum DataRefObj { - DataObj(DataObj), - ObjectReference(TermArg), - DDBHandle(SuperName) -} - -#[derive(Debug, Clone)] -pub struct ArgObj(u8); -#[derive(Debug, Clone)] -pub struct LocalObj(u8); -// Not actually doing anything to contain data, but does give us type guarantees, which is useful - -#[derive(Debug, Clone)] -pub enum ComputationalData { - Byte(u8), - Word(u16), - DWord(u32), - QWord(u64), - String(String), - Zero, - One, - Ones, - DefBuffer(DefBuffer), - RevisionOp -} - -impl AmlExecutable for DataRefObj { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - DataRefObj::DataObj(ref cd) => cd.execute(namespace, scope), - _ => Some(AmlValue::Uninitialized) - } - } -} - -impl AmlExecutable for DataObj { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - DataObj::ComputationalData(ref cd) => cd.execute(namespace, scope), - DataObj::DefPackage(ref pkg) => pkg.execute(namespace, scope), - _ => Some(AmlValue::Uninitialized) - } - } -} - -impl AmlExecutable for ComputationalData { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - ComputationalData::Byte(b) => Some(AmlValue::IntegerConstant(b as u64)), - ComputationalData::Word(w) => Some(AmlValue::IntegerConstant(w as u64)), - ComputationalData::DWord(d) => Some(AmlValue::IntegerConstant(d as u64)), - ComputationalData::QWord(q) => Some(AmlValue::IntegerConstant(q as u64)), - ComputationalData::Zero => Some(AmlValue::IntegerConstant(0)), - ComputationalData::One => Some(AmlValue::IntegerConstant(1)), - ComputationalData::Ones => Some(AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF)), - ComputationalData::String(ref s) => Some(AmlValue::String(s.clone())), - _ => Some(AmlValue::Uninitialized) - } - } -} - -pub fn parse_data_obj(data: &[u8]) -> Result<(DataObj, usize), AmlInternalError> { +pub fn parse_data_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(DataObj::ComputationalData, parse_computational_data), - parser_wrap!(DataObj::DefPackage, parse_def_package), - parser_wrap!(DataObj::DefVarPackage, parse_def_var_package) + data, namespace, scope.clone(), + parse_computational_data, + parse_def_package, + parse_def_var_package }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_data_ref_obj(data: &[u8]) -> Result<(DataRefObj, usize), AmlInternalError> { +pub fn parse_data_ref_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(DataRefObj::DataObj, parse_data_obj), - parser_wrap!(DataRefObj::ObjectReference, parse_term_arg), - parser_wrap!(DataRefObj::DDBHandle, parse_super_name) + data, namespace, scope.clone(), + parse_data_obj, + parse_term_arg }; - Err(AmlInternalError::AmlInvalidOpCode) -} - -pub fn parse_arg_obj(data: &[u8]) -> Result<(ArgObj, usize), AmlInternalError> { - match data[0] { - 0x68 ... 0x6E => Ok((ArgObj(data[0] - 0x68), 1 as usize)), - _ => Err(AmlInternalError::AmlInvalidOpCode) + match parse_super_name(data, namespace, scope.clone()) { + Ok(res) => match res.val { + AmlValue::String(s) => Ok(AmlParseType { + val: AmlValue::ObjectReference(ObjectReference::NamedObj(s)), + len: res.len + }), + _ => Ok(res) + }, + Err(e) => Err(e) } } -pub fn parse_local_obj(data: &[u8]) -> Result<(LocalObj, usize), AmlInternalError> { +pub fn parse_arg_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { match data[0] { - 0x60 ... 0x67 => Ok((LocalObj(data[0] - 0x60), 1 as usize)), - _ => Err(AmlInternalError::AmlInvalidOpCode) + 0x68 ... 0x6E => Ok(AmlParseType { + val: AmlValue::ObjectReference(ObjectReference::ArgObj(data[0] - 0x68)), + len: 1 as usize + }), + _ => Err(AmlError::AmlInvalidOpCode) } } -fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), AmlInternalError> { +pub fn parse_local_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { match data[0] { - 0x0A => Ok((ComputationalData::Byte(data[1]), 2 as usize)), + 0x68 ... 0x6E => Ok(AmlParseType { + val: AmlValue::ObjectReference(ObjectReference::LocalObj(data[0] - 0x60)), + len: 1 as usize + }), + _ => Err(AmlError::AmlInvalidOpCode) + } +} + +fn parse_computational_data(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + match data[0] { + 0x0A => Ok(AmlParseType { + val: AmlValue::Integer(data[1] as u64), + len: 2 as usize + }), 0x0B => { let res = (data[1] as u16) + ((data[2] as u16) << 8); - Ok((ComputationalData::Word(res), 3 as usize)) + + Ok(AmlParseType { + val: AmlValue::Integer(res as u64), + len: 3 as usize + }) }, 0x0C => { let res = (data[1] as u32) + ((data[2] as u32) << 8) + ((data[3] as u32) << 16) + ((data[4] as u32) << 24); - Ok((ComputationalData::DWord(res), 5 as usize)) + + Ok(AmlParseType { + val: AmlValue::Integer(res as u64), + len: 5 as usize + }) }, 0x0D => { let mut cur_ptr: usize = 1; @@ -139,8 +106,11 @@ fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), A } match String::from_utf8(cur_string) { - Ok(s) => Ok((ComputationalData::String(s.clone()), s.clone().len() + 2)), - Err(_) => Err(AmlInternalError::AmlParseError("String data - invalid string")) + Ok(s) => Ok(AmlParseType { + val: AmlValue::String(s.clone()), + len: s.clone().len() + 2 + }), + Err(_) => Err(AmlError::AmlParseError("String data - invalid string")) } }, 0x0E => { @@ -152,19 +122,32 @@ fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), A ((data[6] as u64) << 40) + ((data[7] as u64) << 48) + ((data[8] as u64) << 56); - Ok((ComputationalData::QWord(res), 9 as usize)) + + Ok(AmlParseType { + val: AmlValue::Integer(res as u64), + len: 9 as usize + }) }, - 0x00 => Ok((ComputationalData::Zero, 1 as usize)), - 0x01 => Ok((ComputationalData::One, 1 as usize)), + 0x00 => Ok(AmlParseType { + val: AmlValue::IntegerConstant(0 as u64), + len: 9 as usize + }), + 0x01 => Ok(AmlParseType { + val: AmlValue::IntegerConstant(1 as u64), + len: 9 as usize + }), 0x5B => if data[1] == 0x30 { - Ok((ComputationalData::RevisionOp, 2 as usize)) + Ok(AmlParseType { + val: AmlValue::IntegerConstant(20170630 as u64), + len: 2 as usize + }) } else { - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) }, - 0xFF => Ok((ComputationalData::Ones, 1 as usize)), - _ => match parse_def_buffer(data) { - Ok((res, size)) => Ok((ComputationalData::DefBuffer(res), size)), - Err(e) => Err(e) - } + 0xFF => Ok(AmlParseType { + val: AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF), + len: 9 as usize + }), + _ => parse_def_buffer(data, namespace, scope.clone()) } } diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index a6d5a35..a113c0b 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -24,34 +24,26 @@ mod type1opcode; mod type2opcode; mod parser; -use self::parser::{ParseResult, AmlInternalError}; -use self::termlist::{parse_term_list, TermObj}; -pub use self::namespace::{get_namespace_string, AmlValue}; - -pub trait AmlExecutable { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option; -} +use self::parser::ParseResult; +use self::termlist::parse_term_list; +pub use self::namespace::AmlValue; +#[derive(Debug)] pub enum AmlError { - AmlParseError(&'static str) + AmlParseError(&'static str), + AmlInvalidOpCode, + AmlValueError, + AmlDeferredLoad, + AmlFatalError(u8, u16, AmlValue) } pub fn parse_aml_table(sdt: &'static Sdt) -> Result, AmlError> { let data = sdt.data(); - let term_list = match parse_term_list(data) { - Ok(res) => res, - Err(AmlInternalError::AmlParseError(s)) => return Err(AmlError::AmlParseError(s)), - Err(AmlInternalError::AmlInvalidOpCode) => return Err(AmlError::AmlParseError("Unable to match opcode")), - Err(AmlInternalError::AmlDeferredLoad) => return Err(AmlError::AmlParseError("Deferred load reached top level")) - }; - let global_namespace_specifier = String::from_str("\\").unwrap(); - // Unwrap is fine here. I mean come on, if this goes wrong you've got bigger problems than AML - // not loading... - let mut global_namespace = BTreeMap::new(); - term_list.execute(&mut global_namespace, global_namespace_specifier.clone()); + + let term_list = parse_term_list(data, &mut global_namespace, global_namespace_specifier.clone())?; Ok(global_namespace) } diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 66af6d6..c521893 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -5,444 +5,20 @@ use core::str::FromStr; use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; -use super::namespace::FieldSelector; -use super::namestring::{parse_name_string, parse_name_seg, SuperName}; -use super::termlist::{parse_term_arg, parse_term_list, parse_object_list, TermArg, TermObj, Object}; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::namespace::{AmlValue, ObjectReference, FieldSelector, 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, DefBuffer}; - -#[derive(Debug, Clone)] -pub enum NamedObj { - DefBankField { - region_name: String, - bank_name: String, - bank_value: TermArg, - flags: FieldFlags, - field_list: Vec - }, - DefCreateBitField { - name: String, - source_buf: TermArg, - bit_index: TermArg - }, - DefCreateByteField { - name: String, - source_buf: TermArg, - byte_index: TermArg - }, - DefCreateWordField { - name: String, - source_buf: TermArg, - byte_index: TermArg - }, - DefCreateDWordField { - name: String, - source_buf: TermArg, - byte_index: TermArg - }, - DefCreateQWordField { - name: String, - source_buf: TermArg, - byte_index: TermArg - }, - DefCreateField { - name: String, - source_buf: TermArg, - bit_index: TermArg, - num_bits: TermArg - }, - DefDataRegion { - name: String, - signature: TermArg, - oem_id: TermArg, - oem_table_id: TermArg - }, - DefDevice { - name: String, - obj_list: Vec - }, - DefEvent { - name: String - }, - DefOpRegion { - name: String, - region: RegionSpace, - offset: TermArg, - len: TermArg - }, - DefField { - name: String, - flags: FieldFlags, - field_list: Vec - }, - DefIndexField { - idx_name: String, - data_name: String, - flags: FieldFlags, - field_list: Vec - }, - DefMethod { - name: String, - method: Method - }, - DefMutex { - name: String, - sync_level: u8 - }, - DefPowerRes { - name: String, - system_level: u8, - resource_order: u16, - obj_list: Vec - }, - DefProcessor { - name: String, - proc_id: u8, - p_blk_addr: u32, - p_blk_len: u8, - obj_list: Vec - }, - DefThermalZone { - name: String, - obj_list: Vec - }, - DeferredLoad(Vec) -} +use super::type2opcode::parse_def_buffer; #[derive(Debug, Clone)] pub struct Method { arg_count: u8, serialized: bool, sync_level: u8, - term_list: Vec -} - -impl AmlExecutable for NamedObj { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - NamedObj::DefBankField { ref region_name, ref bank_name, ref bank_value, ref flags, ref field_list } => { - let mut offset: usize = 0; - let mut connection = AmlValue::Uninitialized; - let mut flags = flags.clone(); - let bank_val = if let Some(b) = bank_value.execute(namespace, scope.clone()) { - Box::new(b) - } else { - return None; - }; - - for f in field_list { - match *f { - FieldElement::ReservedField { length } => offset += length, - FieldElement::ConnectFieldNameString(ref name) => connection = - AmlValue::ObjectReference(SuperName::NameString(name.clone())), - FieldElement::ConnectFieldBufferData(ref buf) => { - connection = match buf.execute(namespace, scope.clone()) { - Some(c) => c, - None => return None - }; - }, - FieldElement::AccessField { ref access_type, ref access_attrib } => { - match *access_type { - AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(access_attrib.clone()), - ref a => flags.access_type = a.clone() - } - }, - FieldElement::NamedField { name: ref field_name, length } => { - let local_scope_string = get_namespace_string(scope.clone(), - field_name.clone()); - namespace.insert(local_scope_string, AmlValue::FieldUnit { - selector: FieldSelector::Bank { - region: region_name.clone(), - bank_selector: bank_val.clone() - }, - connection: Box::new(connection.clone()), - flags: flags.clone(), - offset: offset.clone(), - length: length.clone() - }); - - offset += length; - }, - } - } - }, - NamedObj::DefIndexField { ref idx_name, ref data_name, ref flags, ref field_list } => { - let mut offset: usize = 0; - let mut connection = AmlValue::Uninitialized; - let mut flags = flags.clone(); - - for f in field_list { - match *f { - FieldElement::ReservedField { length } => offset += length, - FieldElement::ConnectFieldNameString(ref name) => connection = - AmlValue::ObjectReference(SuperName::NameString(name.clone())), - FieldElement::ConnectFieldBufferData(ref buf) => { - connection = match buf.execute(namespace, scope.clone()) { - Some(c) => c, - None => return None - }; - }, - FieldElement::AccessField { ref access_type, ref access_attrib } => { - match *access_type { - AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(access_attrib.clone()), - ref a => flags.access_type = a.clone() - } - }, - FieldElement::NamedField { name: ref field_name, length } => { - let local_scope_string = get_namespace_string(scope.clone(), - field_name.clone()); - namespace.insert(local_scope_string, AmlValue::FieldUnit { - selector: FieldSelector::Index { - index_selector: idx_name.clone(), - data_selector: data_name.clone() - }, - connection: Box::new(connection.clone()), - flags: flags.clone(), - offset: offset.clone(), - length: length.clone() - }); - - offset += length; - } - } - } - }, - NamedObj::DefCreateBitField { ref name, ref source_buf, ref bit_index } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_index = match bit_index.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::BufferField { - source_buf: resolved_source_buf, - index: resolved_index, - length: Box::new(AmlValue::IntegerConstant(1)) - }); - }, - NamedObj::DefCreateByteField { ref name, ref source_buf, ref byte_index } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_index = match byte_index.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::BufferField { - source_buf: resolved_source_buf, - index: resolved_index, - length: Box::new(AmlValue::IntegerConstant(8)) - }); - }, - NamedObj::DefCreateWordField { ref name, ref source_buf, ref byte_index } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_index = match byte_index.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::BufferField { - source_buf: resolved_source_buf, - index: resolved_index, - length: Box::new(AmlValue::IntegerConstant(16)) - }); - }, - NamedObj::DefCreateDWordField { ref name, ref source_buf, ref byte_index } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_index = match byte_index.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::BufferField { - source_buf: resolved_source_buf, - index: resolved_index, - length: Box::new(AmlValue::IntegerConstant(32)) - }); - }, - NamedObj::DefCreateQWordField { ref name, ref source_buf, ref byte_index } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_index = match byte_index.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::BufferField { - source_buf: resolved_source_buf, - index: resolved_index, - length: Box::new(AmlValue::IntegerConstant(64)) - }); - }, - NamedObj::DefCreateField { ref name, ref source_buf, ref bit_index, ref num_bits } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_source_buf = match source_buf.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_index = match bit_index.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - let resolved_length = match num_bits.execute(namespace, scope.clone()) { - Some(r) => Box::new(r), - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::BufferField { - source_buf: resolved_source_buf, - index: resolved_index, - length: resolved_length - }); - }, - NamedObj::DefDataRegion { ref name, ref signature, ref oem_id, ref oem_table_id } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - namespace.insert(local_scope_string, AmlValue::OperationRegion { - region: RegionSpace::SystemMemory, - offset: Box::new(AmlValue::IntegerConstant(0)), - len: Box::new(AmlValue::IntegerConstant(0)) - }); - }, - NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - - let resolved_offset = match offset.execute(namespace, scope.clone()) { - Some(r) => r, - _ => return None - }; - - let resolved_len = match len.execute(namespace, scope.clone()) { - Some(r) => r, - _ => return None - }; - - namespace.insert(local_scope_string, AmlValue::OperationRegion { - region: *region, - offset: Box::new(resolved_offset), - len: Box::new(resolved_len) - }); - }, - NamedObj::DefField { ref name, ref flags, ref field_list } => { - let mut offset: usize = 0; - let mut connection = AmlValue::Uninitialized; - let mut flags = flags.clone(); - - for f in field_list { - match *f { - FieldElement::ReservedField { length } => offset += length, - FieldElement::ConnectFieldNameString(ref name) => connection = - AmlValue::ObjectReference(SuperName::NameString(name.clone())), - FieldElement::ConnectFieldBufferData(ref buf) => { - connection = match buf.execute(namespace, scope.clone()) { - Some(c) => c, - None => return None - }; - }, - FieldElement::AccessField { ref access_type, ref access_attrib } => { - match *access_type { - AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(access_attrib.clone()), - ref a => flags.access_type = a.clone() - } - }, - FieldElement::NamedField { name: ref field_name, length } => { - let local_scope_string = get_namespace_string(scope.clone(), - field_name.clone()); - namespace.insert(local_scope_string, AmlValue::FieldUnit { - selector: FieldSelector::Region(name.clone()), - connection: Box::new(connection.clone()), - flags: flags.clone(), - offset: offset.clone(), - length: length.clone() - }); - - offset += length; - } - } - } - }, - NamedObj::DefMethod { ref name, ref method } => { - let local_scope_string = get_namespace_string(scope.clone(), name.clone()); - namespace.insert(local_scope_string, AmlValue::Method(method.clone())); - }, - NamedObj::DefDevice { ref name, ref obj_list } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - - let mut local_namespace = BTreeMap::new(); - obj_list.execute(&mut local_namespace, String::new()); - - namespace.insert(local_scope_string, AmlValue::Device(local_namespace)); - }, - NamedObj::DefThermalZone { ref name, ref obj_list } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - - let mut local_namespace = BTreeMap::new(); - obj_list.execute(&mut local_namespace, String::new()); - - namespace.insert(local_scope_string, AmlValue::ThermalZone(local_namespace)); - }, - NamedObj::DefProcessor { ref name, proc_id, p_blk_addr, p_blk_len, ref obj_list } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - - let mut local_namespace = BTreeMap::new(); - obj_list.execute(&mut local_namespace, String::new()); - - namespace.insert(local_scope_string, AmlValue::Processor { - proc_id: proc_id, - p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None }, - obj_list: local_namespace - }); - }, - NamedObj::DefPowerRes { ref name, system_level, resource_order, ref obj_list } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - - let mut local_namespace = BTreeMap::new(); - obj_list.execute(&mut local_namespace, String::new()); - - namespace.insert(local_scope_string, AmlValue::PowerResource { - system_level, - resource_order, - obj_list: local_namespace - }); - }, - NamedObj::DefMutex { ref name, sync_level } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); - }, - NamedObj::DefEvent { ref name } => { - let local_scope_string = get_namespace_string(scope, name.clone()); - namespace.insert(local_scope_string, AmlValue::Event); - }, - _ => () - } - - None - } + term_list: Vec } #[derive(Debug, Copy, Clone)] @@ -485,20 +61,15 @@ pub enum UpdateRule { } #[derive(Debug, Clone)] -pub enum FieldElement { - NamedField { - name: String, - length: usize - }, - ReservedField { - length: usize - }, - AccessField { - access_type: AccessType, - access_attrib: AccessAttrib - }, - ConnectFieldNameString(String), - ConnectFieldBufferData(DefBuffer), +pub struct NamedField { + name: String, + length: usize +} + +#[derive(Debug, Clone)] +pub struct AccessField { + access_type: AccessType, + access_attrib: AccessAttrib } #[derive(Debug, Clone)] @@ -515,9 +86,11 @@ pub enum AccessAttrib { AttribBlockProcessCall } -pub fn parse_named_obj(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +pub fn parse_named_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, + data, namespace, scope.clone(), parse_def_bank_field, parse_def_create_bit_field, parse_def_create_byte_field, @@ -538,39 +111,26 @@ pub fn parse_named_obj(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErro parse_def_thermal_zone }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -fn parse_def_bank_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_bank_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Why isn't bank name used? parser_opcode_extended!(data, 0x87); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let (region_name, region_name_len) = match parse_name_string( - &data[2 + pkg_length_len .. 2 + pkg_length]) { - Ok(res) => res, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let data = &data[2 + pkg_length_len .. 2 + pkg_length]; + + let region_name = parse_name_string(data, namespace, scope.clone())?; + let bank_name = parse_name_string(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], namespace, scope.clone())?; - let (bank_name, bank_name_len) = match parse_name_string( - &data[2 + pkg_length_len + region_name_len .. 2 + pkg_length]) { - Ok(res) => res, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let bank_value = parse_term_arg( + &data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], namespace, scope.clone())?; - let (bank_value, bank_value_len) = match parse_term_arg( - &data[2 + pkg_length_len + region_name_len .. 2 + pkg_length]) { - Ok(res) => res, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; - - let flags_raw = data[2 + pkg_length_len + region_name_len + bank_name_len + bank_value_len]; - let flags = FieldFlags { + let flags_raw = data[2 + pkg_length_len + region_name.len + bank_name.len + bank_value.len]; + let mut flags = FieldFlags { access_type: match flags_raw & 0x0F { 0 => AccessType::AnyAcc, 1 => AccessType::ByteAcc, @@ -578,145 +138,239 @@ fn parse_def_bank_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErr 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), - _ => return Err(AmlInternalError::AmlParseError("BankField - invalid access type")) + _ => return Err(AmlError::AmlParseError("BankField - invalid access type")) }, lock_rule: (flags_raw & 0x10) == 0x10, update_rule: match (flags_raw & 0x60) >> 5 { 0 => UpdateRule::Preserve, 1 => UpdateRule::WriteAsOnes, 2 => UpdateRule::WriteAsZeros, - _ => return Err(AmlInternalError::AmlParseError("BankField - invalid update rule")) + _ => return Err(AmlError::AmlParseError("BankField - invalid update rule")) } }; - let field_list = match parse_field_list( - &data[3 + pkg_length_len + region_name_len + bank_name_len + bank_value_len .. - 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) + let selector = FieldSelector::Bank { + region: region_name.val.get_as_string()?, + bank_selector: Box::new(bank_value.val) }; - Ok((NamedObj::DefBankField {region_name, bank_name, bank_value, flags, field_list}, - 2 + pkg_length)) + let field_list = parse_field_list( + &data[3 + pkg_length_len + region_name.len + bank_name.len + bank_value.len .. + 2 + pkg_length], namespace, scope, selector, &mut flags)?; + + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_length + }) } -fn parse_def_create_bit_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_create_bit_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x8D); - let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?; - let (bit_index, bit_index_len) = parse_term_arg(&data[1 + source_buf_len..])?; - let (name, name_len) = parse_name_string(&data[1 + source_buf_len + bit_index_len..])?; + let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: Box::new(source_buf.val), + index: Box::new(bit_index.val), + length: Box::new(AmlValue::IntegerConstant(1)) + }); - Ok((NamedObj::DefCreateBitField {name, source_buf, bit_index}, - 1 + source_buf_len + bit_index_len + name_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + source_buf.len + bit_index.len + }) } -fn parse_def_create_byte_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_create_byte_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x8C); - let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?; - let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?; - let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?; + let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: Box::new(source_buf.val), + index: Box::new(bit_index.val), + length: Box::new(AmlValue::IntegerConstant(8)) + }); - Ok((NamedObj::DefCreateByteField {name, source_buf, byte_index}, - 1 + source_buf_len + byte_index_len + name_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + source_buf.len + bit_index.len + }) } -fn parse_def_create_word_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_create_word_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x8B); - let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?; - let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?; - let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?; + let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: Box::new(source_buf.val), + index: Box::new(bit_index.val), + length: Box::new(AmlValue::IntegerConstant(16)) + }); - Ok((NamedObj::DefCreateWordField {name, source_buf, byte_index}, - 1 + source_buf_len + byte_index_len + name_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + source_buf.len + bit_index.len + }) } -fn parse_def_create_dword_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_create_dword_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x8A); - let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?; - let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?; - let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?; + let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: Box::new(source_buf.val), + index: Box::new(bit_index.val), + length: Box::new(AmlValue::IntegerConstant(32)) + }); - Ok((NamedObj::DefCreateDWordField {name, source_buf, byte_index}, - 1 + source_buf_len + byte_index_len + name_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + source_buf.len + bit_index.len + }) } -fn parse_def_create_qword_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_create_qword_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x8F); - let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?; - let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?; - let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?; + let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: Box::new(source_buf.val), + index: Box::new(bit_index.val), + length: Box::new(AmlValue::IntegerConstant(64)) + }); - Ok((NamedObj::DefCreateQWordField {name, source_buf, byte_index}, - 1 + source_buf_len + byte_index_len + name_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + source_buf.len + bit_index.len + }) } -fn parse_def_create_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_create_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x13); - let (source_buf, source_buf_len) = parse_term_arg(&data[2..])?; - let (bit_index, bit_index_len) = parse_term_arg(&data[2 + source_buf_len..])?; - let (num_bits, num_bits_len) = parse_term_arg(&data[2 + source_buf_len + bit_index_len..])?; - let (name, name_len) = parse_name_string( - &data[2 + source_buf_len + bit_index_len + num_bits_len..])?; - - Ok((NamedObj::DefCreateField {name, source_buf, bit_index, num_bits}, - 2 + source_buf_len + bit_index_len + num_bits_len + name_len)) + let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; + let num_bits = parse_term_arg(&data[2 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[2 + source_buf.len + bit_index.len + num_bits.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + + namespace.insert(local_scope_string, AmlValue::BufferField { + source_buf: Box::new(source_buf.val), + index: Box::new(bit_index.val), + length: Box::new(num_bits.val) + }); + + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + source_buf.len + bit_index.len + num_bits.len + }) } -fn parse_def_data_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_data_region(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Find the actual offset and length, once table mapping is implemented parser_opcode_extended!(data, 0x88); - let (name, name_len) = parse_name_string(&data[2..])?; - let (signature, signature_len) = parse_term_arg(&data[2 + name_len..])?; - let (oem_id, oem_id_len) = parse_term_arg(&data[2 + name_len + signature_len..])?; - let (oem_table_id, oem_table_id_len) = parse_term_arg( - &data[2 + name_len + signature_len + oem_id_len..])?; + let name = parse_name_string(&data[2..], namespace, scope.clone())?; + let signature = parse_term_arg(&data[2 + name.len..], namespace, scope.clone())?; + let oem_id = parse_term_arg(&data[2 + name.len + signature.len..], namespace, scope.clone())?; + let oem_table_id = parse_term_arg(&data[2 + name.len + signature.len + oem_id.len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); - Ok((NamedObj::DefDataRegion {name, signature, oem_id, oem_table_id}, - 2 + name_len + signature_len + oem_id_len + oem_table_id_len)) + namespace.insert(local_scope_string, AmlValue::OperationRegion { + region: RegionSpace::SystemMemory, + offset: Box::new(AmlValue::IntegerConstant(0)), + len: Box::new(AmlValue::IntegerConstant(0)) + }); + + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + signature.len + oem_id.len + oem_table_id.len + }) } -fn parse_def_event(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_event(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x02); - let (name, name_len) = parse_name_string(&data[2..])?; + let name = parse_name_string(&data[2..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope, name.val); + namespace.insert(local_scope_string, AmlValue::Event); - Ok((NamedObj::DefEvent {name}, 2 + name_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + }) } -fn parse_def_device(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_device(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x82); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let (name, name_len) = match parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], namespace, scope.clone())?; + + let mut local_namespace = BTreeMap::new(); + let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_namespace, String::new())?; - let obj_list = match parse_object_list(&data[2 + pkg_length_len + name_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let local_scope_string = get_namespace_string(scope, name.val); + namespace.insert(local_scope_string, AmlValue::Device(local_namespace)); - Ok((NamedObj::DefDevice {name, obj_list}, 2 + pkg_length_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_length + }) } -fn parse_def_op_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_op_region(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x80); - let (name, name_len) = parse_name_string(&data[2..])?; - let region = match data[2 + name_len] { + let name = parse_name_string(&data[2..], namespace, scope.clone())?; + let region = match data[2 + name.len] { 0x00 => RegionSpace::SystemMemory, 0x01 => RegionSpace::SystemIO, 0x02 => RegionSpace::PCIConfig, @@ -727,29 +381,36 @@ fn parse_def_op_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErro 0x07 => RegionSpace::IPMI, 0x08 => RegionSpace::GeneralPurposeIO, 0x09 => RegionSpace::GenericSerialBus, - 0x80 ... 0xFF => RegionSpace::UserDefined(data[2 + name_len]), - _ => return Err(AmlInternalError::AmlParseError("OpRegion - invalid region")) + 0x80 ... 0xFF => RegionSpace::UserDefined(data[2 + name.len]), + _ => return Err(AmlError::AmlParseError("OpRegion - invalid region")) }; - let (offset, offset_len) = parse_term_arg(&data[3 + name_len..])?; - let (len, len_len) = parse_term_arg(&data[3 + name_len + offset_len..])?; + let offset = parse_term_arg(&data[3 + name.len..], namespace, scope.clone())?; + let len = parse_term_arg(&data[3 + name.len + offset.len..], namespace, scope.clone())?; - Ok((NamedObj::DefOpRegion {name, region, offset, len}, 3 + name_len + offset_len + len_len)) + let local_scope_string = get_namespace_string(scope.clone(), name.val); + namespace.insert(local_scope_string, AmlValue::OperationRegion { + region: region, + offset: Box::new(offset.val), + len: Box::new(len.val) + }); + + Ok(AmlParseType { + val: AmlValue::None, + len: 3 + name.len + offset.len + len.len + }) } -fn parse_def_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x81); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let (name, name_len) = match parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], namespace, scope.clone())?; - let flags_raw = data[2 + pkg_length_len + name_len]; - let flags = FieldFlags { + let flags_raw = data[2 + pkg_length_len + name.len]; + let mut flags = FieldFlags { access_type: match flags_raw & 0x0F { 0 => AccessType::AnyAcc, 1 => AccessType::ByteAcc, @@ -757,49 +418,38 @@ fn parse_def_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), - _ => return Err(AmlInternalError::AmlParseError("Field - Invalid access type")) + _ => return Err(AmlError::AmlParseError("Field - Invalid access type")) }, lock_rule: (flags_raw & 0x10) == 0x10, update_rule: match (flags_raw & 0x60) >> 5 { 0 => UpdateRule::Preserve, 1 => UpdateRule::WriteAsOnes, 2 => UpdateRule::WriteAsZeros, - _ => return Err(AmlInternalError::AmlParseError("Field - Invalid update rule")) + _ => return Err(AmlError::AmlParseError("Field - Invalid update rule")) } }; - let field_list = match parse_field_list(&data[3 + pkg_length_len + name_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let selector = FieldSelector::Region(name.val.get_as_string()?); - Ok((NamedObj::DefField {name, flags, field_list}, 2 + pkg_length)) + let field_list = parse_field_list(&data[3 + pkg_length_len + name.len .. 2 + pkg_length], namespace, scope, selector, &mut flags)?; + + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_length + }) } -fn parse_def_index_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_index_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x86); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let (idx_name, idx_name_len) = match parse_name_string( - &data[2 + pkg_length_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; + let idx_name = parse_name_string( &data[2 + pkg_length_len .. 2 + pkg_length], namespace, scope.clone())?; + let data_name = parse_name_string(&data[2 + pkg_length_len + idx_name.len .. 2 + pkg_length], namespace, scope.clone())?; - let (data_name, data_name_len) = match parse_name_string( - &data[2 + pkg_length_len + idx_name_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) - }; - - let flags_raw = data[2 + pkg_length_len + idx_name_len + data_name_len]; - let flags = FieldFlags { + let flags_raw = data[2 + pkg_length_len + idx_name.len + data_name.len]; + let mut flags = FieldFlags { access_type: match flags_raw & 0x0F { 0 => AccessType::AnyAcc, 1 => AccessType::ByteAcc, @@ -807,78 +457,129 @@ fn parse_def_index_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalEr 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), - _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid access type")) + _ => return Err(AmlError::AmlParseError("IndexField - Invalid access type")) }, lock_rule: (flags_raw & 0x10) == 0x10, update_rule: match (flags_raw & 0x60) >> 5 { 0 => UpdateRule::Preserve, 1 => UpdateRule::WriteAsOnes, 2 => UpdateRule::WriteAsZeros, - _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid update rule")) + _ => return Err(AmlError::AmlParseError("IndexField - Invalid update rule")) } }; - let field_list = match parse_field_list( - &data[3 + pkg_length_len + idx_name_len + data_name_len .. 2 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)), - Err(e) => return Err(e) + let selector = FieldSelector::Index { + index_selector: idx_name.val.get_as_string()?, + data_selector: data_name.val.get_as_string()? }; - Ok((NamedObj::DefIndexField {idx_name, data_name, flags, field_list}, 2 + pkg_length)) + let field_list = parse_field_list( + &data[3 + pkg_length_len + idx_name.len + data_name.len .. 2 + pkg_length], namespace, scope, selector, &mut flags)?; + + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_length + }) } -fn parse_field_list(data: &[u8]) -> Result, AmlInternalError> { - let mut terms: Vec = vec!(); +fn parse_field_list(data: &[u8], + namespace: &mut BTreeMap, + scope: String, + selector: FieldSelector, + flags: &mut FieldFlags) -> ParseResult { let mut current_offset: usize = 0; + let mut connection = AmlValue::Uninitialized; while current_offset < data.len() { - let (res, len) = match parse_field_element(&data[current_offset..]) { - Ok(r) => r, - Err(AmlInternalError::AmlInvalidOpCode) => - return Err(AmlInternalError::AmlParseError("FieldList - no valid field")), + match parse_field_element(&data[current_offset..], namespace, scope.clone(), selector.clone(), + &mut connection, flags, &mut current_offset) { + Ok(_) => (), + Err(AmlError::AmlInvalidOpCode) => + return Err(AmlError::AmlParseError("FieldList - no valid field")), Err(e) => return Err(e) - }; - - terms.push(res); - current_offset += len; + } } - Ok(terms) + Ok(AmlParseType { + val: AmlValue::None, + len: data.len() + }) } -fn parse_field_element(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> { - parser_selector! { - data, - parse_named_field, - parse_reserved_field, - parse_access_field, - parse_connect_field +fn parse_field_element(data: &[u8], + namespace: &mut BTreeMap, + scope: String, + selector: FieldSelector, + connection: &mut AmlValue, + flags: &mut FieldFlags, + offset: &mut usize) -> ParseResult { + let length = if let Ok(field) = parse_named_field(data, namespace, scope.clone()) { + let local_scope_string = get_namespace_string(scope.clone(), AmlValue::String(field.val.name.clone())); + + namespace.insert(local_scope_string, AmlValue::FieldUnit { + selector: selector.clone(), + connection: Box::new(connection.clone()), + flags: flags.clone(), + offset: offset.clone(), + length: field.val.length + }); + + field.len + } else if let Ok(field) = parse_reserved_field(data, namespace, scope.clone()) { + *offset += field.val; + field.len + } else if let Ok(field) = parse_access_field(data, namespace, scope.clone()) { + match field.val.access_type { + AccessType::BufferAcc(_) => + flags.access_type = AccessType::BufferAcc(field.val.access_attrib.clone()), + ref a => flags.access_type = a.clone() + } + + field.len + } else if let Ok(field) = parse_connect_field(data, namespace, scope.clone()) { + *connection = field.val.clone(); + field.len + } else { + return Err(AmlError::AmlInvalidOpCode); }; - - Err(AmlInternalError::AmlInvalidOpCode) + + Ok(AmlParseType { + val: AmlValue::None, + len: length + }) } -fn parse_named_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> { +fn parse_named_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> Result, AmlError> { let (name_seg, name_seg_len) = parse_name_seg(&data[0..4])?; let name = match String::from_utf8(name_seg) { Ok(s) => s, - Err(_) => return Err(AmlInternalError::AmlParseError("NamedField - invalid name")) + Err(_) => return Err(AmlError::AmlParseError("NamedField - invalid name")) }; let (length, length_len) = parse_pkg_length(&data[4..])?; - Ok((FieldElement::NamedField {name, length}, 4 + length_len)) + Ok(AmlParseTypeGeneric { + val: NamedField { name, length }, + len: 4 + length_len + }) } -fn parse_reserved_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> { +fn parse_reserved_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> Result, AmlError> { parser_opcode!(data, 0x00); let (length, length_len) = parse_pkg_length(&data[1..])?; - Ok((FieldElement::ReservedField {length}, 1 + length_len)) + Ok(AmlParseTypeGeneric { + val: length, + len: 1 + length_len + }) } -fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> { +fn parse_access_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> Result, AmlError> { parser_opcode!(data, 0x01, 0x03); let flags_raw = data[1]; @@ -889,7 +590,7 @@ fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalE 3 => AccessType::DWordAcc, 4 => AccessType::QWordAcc, 5 => AccessType::BufferAcc(AccessAttrib::AttribByte), - _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access type")) + _ => return Err(AmlError::AmlParseError("AccessField - Invalid access type")) }; let access_attrib = match (flags_raw & 0xC0) >> 6 { @@ -904,155 +605,169 @@ fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalE 0x0D => AccessAttrib::AttribBlockProcessCall, 0x0E => AccessAttrib::AttribRawBytes(data[3]), 0x0F => AccessAttrib::AttribRawProcessBytes(data[3]), - _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access attrib")) + _ => return Err(AmlError::AmlParseError("AccessField - Invalid access attrib")) }, 1 => AccessAttrib::AttribBytes(data[2]), 2 => AccessAttrib::AttribRawBytes(data[2]), 3 => AccessAttrib::AttribRawProcessBytes(data[2]), - _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access attrib")) + _ => return Err(AmlError::AmlParseError("AccessField - Invalid access attrib")) // This should never happen but the compiler bitches if I don't cover this }; - return Ok((FieldElement::AccessField {access_type, access_attrib}, if data[0] == 0x01 { - 3 as usize - } else { - 4 as usize - })) + Ok(AmlParseTypeGeneric { + val: AccessField { access_type, access_attrib }, + len: if data[0] == 0x01 { + 3 as usize + } else { + 4 as usize + } + }) } -fn parse_connect_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> { +fn parse_connect_field(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x02); - match parse_def_buffer(&data[1..]) { - Ok((buf, buf_len)) => return Ok((FieldElement::ConnectFieldBufferData(buf), buf_len + 1)), - Err(AmlInternalError::AmlInvalidOpCode) => (), - Err(e) => return Err(e) - } - - match parse_name_string(&data[1..]) { - Ok((name, name_len)) => Ok((FieldElement::ConnectFieldNameString(name), name_len + 1)), - Err(AmlInternalError::AmlInvalidOpCode) => Err(AmlInternalError::AmlParseError("ConnectField - unable to match field")), - Err(e) => Err(e) + if let Ok(e) = parse_def_buffer(&data[1..], namespace, scope.clone()) { + Ok(AmlParseType { + val: e.val, + len: e.len + 1 + }) + } else { + let name = parse_name_string(&data[1..], namespace, scope.clone())?; + Ok(AmlParseType { + val: AmlValue::ObjectReference(ObjectReference::NamedObj(name.val.get_as_string()?)), + len: name.len + 1 + }) } } -fn parse_def_method(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_method(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x14); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[1..])?; - let (name, name_len) = match parse_name_string(&data[1 + pkg_len_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 1 + pkg_len].to_vec()), 1 + pkg_len)), - Err(e) => return Err(e) - }; - let flags = data[1 + pkg_len_len + name_len]; + let name = parse_name_string(&data[1 + pkg_len_len..], namespace, scope.clone())?; + let flags = data[1 + pkg_len_len + name.len]; let arg_count = flags & 0x07; let serialized = (flags & 0x08) == 0x08; let sync_level = flags & 0xF0 >> 4; - let term_list = match parse_term_list(&data[2 + pkg_len_len + name_len .. 1 + pkg_len]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 1 + pkg_len].to_vec()), 1 + pkg_len)), - Err(e) => return Err(e) - }; + let term_list = &data[2 + pkg_len_len + name.len .. 1 + pkg_len]; + + let local_scope_string = get_namespace_string(scope.clone(), name.val); + namespace.insert(local_scope_string, AmlValue::Method(Method { + arg_count, + serialized, + sync_level, + term_list: term_list.to_vec() + })); - Ok((NamedObj::DefMethod { - name: name, - method: Method { - arg_count, - serialized, - sync_level, - term_list - } - }, pkg_len + 1)) + Ok(AmlParseType { + val: AmlValue::None, + len: 1 + pkg_len + }) } -fn parse_def_mutex(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_mutex(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x01); - let (name, name_len) = match parse_name_string(&data[2 ..]) { - Ok(p) => p, - Err(e) => return Err(e), - }; - let flags = data[2 + name_len]; + let name = parse_name_string(&data[2 ..], namespace, scope.clone())?; + let flags = data[2 + name.len]; let sync_level = flags & 0x0F; + + let local_scope_string = get_namespace_string(scope, name.val); + namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); - Ok((NamedObj::DefMutex {name, sync_level}, name_len + 3)) + Ok(AmlParseType { + val: AmlValue::None, + len: 3 + name.len + }) } -fn parse_def_power_res(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_power_res(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x84); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?; - let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)), - Err(e) => return Err(e) - }; + let name = parse_name_string(&data[2 + pkg_len_len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope, name.val); + let mut local_namespace = BTreeMap::new(); - let system_level = data[2 + pkg_len_len + name_len]; - let resource_order: u16 = (data[3 + pkg_len_len + name_len] as u16) + - ((data[4 + pkg_len_len + name_len] as u16) << 8); + let system_level = data[2 + pkg_len_len + name.len]; + let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) + + ((data[4 + pkg_len_len + name.len] as u16) << 8); - let obj_list = match parse_object_list(&data[5 + pkg_len_len + name_len .. 2 + pkg_len]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)), - Err(e) => return Err(e) - }; + parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_namespace, String::new())?; + + namespace.insert(local_scope_string, AmlValue::PowerResource { + system_level, + resource_order, + obj_list: local_namespace + }); - Ok((NamedObj::DefPowerRes {name, system_level, resource_order, obj_list}, 2 + pkg_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_len + }) } -fn parse_def_processor(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { +fn parse_def_processor(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x83); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?; - let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)), - Err(e) => return Err(e) - }; + let name = parse_name_string(&data[2 + pkg_len_len..], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope, name.val); + let mut local_namespace = BTreeMap::new(); + + let proc_id = data[2 + pkg_len_len + name.len]; + let p_blk_addr: u32 = (data[3 + pkg_len_len + name.len] as u32) + + ((data[4 + pkg_len_len + name.len] as u32) << 8) + + ((data[5 + pkg_len_len + name.len] as u32) << 16) + + ((data[6 + pkg_len_len + name.len] as u32) << 24); + let p_blk_len = data[7 + pkg_len_len + name.len]; - let proc_id = data[2 + pkg_len_len + name_len]; - let p_blk_addr: u32 = (data[3 + pkg_len_len + name_len] as u32) + - ((data[4 + pkg_len_len + name_len] as u32) << 8) + - ((data[5 + pkg_len_len + name_len] as u32) << 16) + - ((data[6 + pkg_len_len + name_len] as u32) << 24); - let p_blk_len = data[7 + pkg_len_len + name_len]; + parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_namespace, String::new())?; - let obj_list = match parse_object_list(&data[8 + pkg_len_len + name_len .. 2 + pkg_len]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)), - Err(e) => return Err(e) - }; + namespace.insert(local_scope_string, AmlValue::Processor { + proc_id: proc_id, + p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None }, + obj_list: local_namespace + }); - Ok((NamedObj::DefProcessor {name, proc_id, p_blk_addr, p_blk_len, obj_list}, 2 + pkg_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_len + }) } -fn parse_def_thermal_zone(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> { - parser_opcode_extended!(data, 0x85); - +fn parse_def_thermal_zone(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + parser_opcode_extended!(data, 0x85); + let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?; - let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)), - Err(e) => return Err(e) - }; + let name = parse_name_string(&data[2 + pkg_len_len .. 2 + pkg_len], namespace, scope.clone())?; + + let local_scope_string = get_namespace_string(scope, name.val); + let mut local_namespace = BTreeMap::new(); + + parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_namespace, String::new())?; + + namespace.insert(local_scope_string, AmlValue::ThermalZone(local_namespace)); - let obj_list = match parse_object_list(&data[2 + pkg_len_len + name_len .. 2 + pkg_len]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)), - Err(e) => return Err(e) - }; - - Ok((NamedObj::DefThermalZone {name, obj_list}, 2 + pkg_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + pkg_len + }) } diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index be49f7b..d2ac417 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -6,9 +6,7 @@ use collections::btree_map::BTreeMap; use core::str::FromStr; use super::namedobj::{ RegionSpace, FieldFlags, Method }; -use super::termlist::Object; -use super::namestring::SuperName; -use super::type2opcode::Type2OpCode; +use super::AmlError; #[derive(Debug, Clone)] pub enum FieldSelector { @@ -23,8 +21,17 @@ pub enum FieldSelector { } } +#[derive(Debug, Clone)] +pub enum ObjectReference { + ArgObj(u8), + LocalObj(u8), + NamedObj(String), + Object(Box) +} + #[derive(Debug, Clone)] pub enum AmlValue { + None, Uninitialized, Buffer { length: Box, @@ -46,11 +53,11 @@ pub enum AmlValue { offset: usize, length: usize }, - Integer(Type2OpCode), + Integer(u64), IntegerConstant(u64), Method(Method), Mutex(u8), - ObjectReference(SuperName), + ObjectReference(ObjectReference), OperationRegion { region: RegionSpace, offset: Box, @@ -73,22 +80,37 @@ pub enum AmlValue { } impl AmlValue { - pub fn get_as_package(&self) -> Option> { + // TODO: These should be able to throw errors rather than returning options + pub fn get_as_string(&self) -> Result { match *self { - AmlValue::Package(ref p) => Some(p.clone()), - _ => None + AmlValue::String(ref s) => Ok(s.clone()), + _ => Err(AmlError::AmlValueError) + } + } + + pub fn get_as_package(&self) -> Result, AmlError> { + match *self { + AmlValue::Package(ref p) => Ok(p.clone()), + _ => Err(AmlError::AmlValueError) } } - pub fn get_as_integer(&self) -> Option { + pub fn get_as_integer(&self) -> Result { match *self { - AmlValue::IntegerConstant(ref i) => Some(i.clone()), - _ => None + AmlValue::IntegerConstant(ref i) => Ok(i.clone()), + _ => Err(AmlError::AmlValueError) } } } -pub fn get_namespace_string(current: String, modifier: String) -> String { +pub fn get_namespace_string(current: String, modifier_v: AmlValue) -> String { + // TODO: Type error if modifier not string + let modifier = if let Ok(s) = modifier_v.get_as_string() { + s + } else { + return current; + }; + if current.len() == 0 { return modifier; } diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index 8e7e2cc..b04d405 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -3,23 +3,25 @@ use collections::string::String; use collections::vec::Vec; use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; use super::pkglength::parse_pkg_length; -use super::namestring::{parse_name_string, SuperName}; -use super::termlist::{parse_term_list, TermObj}; -use super::dataobj::{parse_data_ref_obj, DataRefObj}; +use super::namestring::parse_name_string; +use super::termlist::parse_term_list; +use super::dataobj::parse_data_ref_obj; pub fn parse_namespace_modifier(data: &[u8], namespace: &mut BTreeMap, scope: String) -> ParseResult { parser_selector! { - data, namespace, scope, + data, namespace, scope.clone(), parse_alias_op, parse_scope_op, parse_name_op }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } fn parse_alias_op(data: &[u8], @@ -27,17 +29,17 @@ fn parse_alias_op(data: &[u8], scope: String) -> ParseResult { parser_opcode!(data, 0x06); - let source_name = parse_name_string(&data[1..], namespace, scope)?; - let alias_name = parse_name_string(&data[1 + source_name_len..], namespace, scope)?; + let source_name = parse_name_string(&data[1..], namespace, scope.clone())?; + let alias_name = parse_name_string(&data[1 + source_name.len..], namespace, scope.clone())?; - let local_scope_string = get_namespace_string(scope.clone(), parser_verify_value!(source_name)); - let local_alias_string = get_namespace_string(scope.clone(), parser_verify_value!(alias_name)); + let local_scope_string = get_namespace_string(scope.clone(), source_name.val); + let local_alias_string = get_namespace_string(scope.clone(), alias_name.val); namespace.insert(local_scope_string, AmlValue::ObjectReference( - SuperName::NameString(local_alias_string))); + ObjectReference::NamedObj(local_alias_string))); Ok(AmlParseType { - val: None, + val: AmlValue::None, len: 1 + source_name.len + alias_name.len }) } @@ -47,16 +49,16 @@ fn parse_name_op(data: &[u8], scope: String) -> ParseResult { parser_opcode!(data, 0x08); - let name = parse_name_string(&data[1..], namespace, scope)?; - let data_ref_obj = parse_data_ref_obj(&data[1 + name_len..], namespace, scope)?; + let name = parse_name_string(&data[1..], namespace, scope.clone())?; + let data_ref_obj = parse_data_ref_obj(&data[1 + name.len..], namespace, scope.clone())?; - let local_scope_string = get_namespace_string(scope.clone(), parser_verify_value!(name)); + let local_scope_string = get_namespace_string(scope.clone(), name.val); - namespace.insert(local_scope_string, parser_verify_value!(data_ref_obj)); + namespace.insert(local_scope_string, data_ref_obj.val); Ok(AmlParseType { - val: None, - len: 1 + name_len + data_ref_obj_len + val: AmlValue::None, + len: 1 + name.len + data_ref_obj.len }) } @@ -66,13 +68,13 @@ fn parse_scope_op(data: &[u8], parser_opcode!(data, 0x10); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let name = parse_name_string(&data[1 + pkg_length_len..], namespace, scope)?; + let name = parse_name_string(&data[1 + pkg_length_len..], namespace, scope.clone())?; - let local_scope_string = get_namespace_string(scope, parser_verify_value!(name)); - parse_term_list(&data[1 + pkg_length_len + name_len..], namespace, local_scope_string)?; + let local_scope_string = get_namespace_string(scope, name.val); + parse_term_list(&data[1 + pkg_length_len + name.len..], namespace, local_scope_string)?; Ok(AmlParseType { - val: None, + val: AmlValue::None, len: 1 + pkg_length }) } diff --git a/src/acpi/aml/namestring.rs b/src/acpi/aml/namestring.rs index 8015a8c..ccbdcce 100644 --- a/src/acpi/aml/namestring.rs +++ b/src/acpi/aml/namestring.rs @@ -1,27 +1,16 @@ use collections::vec::Vec; use collections::string::String; +use collections::btree_map::BTreeMap; -use super::AmlInternalError; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; +use super::dataobj::{parse_arg_obj, parse_local_obj}; +use super::type2opcode::parse_type6_opcode; -use super::dataobj::{parse_arg_obj, parse_local_obj, ArgObj, LocalObj}; -use super::type2opcode::{parse_type6_opcode, Type6OpCode}; - -#[derive(Debug, Clone)] -pub enum SuperName { - NameString(String), - ArgObj(ArgObj), - LocalObj(LocalObj), - DebugObj, - Type6OpCode(Type6OpCode) -} - -#[derive(Debug, Clone)] -pub enum Target { - SuperName(SuperName), - Null -} - -pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalError> { +pub fn parse_name_string(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { let mut characters: Vec = vec!(); let mut starting_index: usize = 0; @@ -36,7 +25,7 @@ pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalErro } let sel = |data| { - parser_selector! { + parser_selector_simple! { data, parse_dual_name_path, parse_multi_name_path, @@ -44,7 +33,7 @@ pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalErro parse_name_seg }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) }; let (mut chr, len) = sel(&data[starting_index..])?; characters.append(&mut chr); @@ -52,35 +41,38 @@ pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalErro let name_string = String::from_utf8(characters); match name_string { - Ok(s) => Ok((s.clone(), len + starting_index)), - Err(_) => Err(AmlInternalError::AmlParseError("Namestring - Name is invalid")) + Ok(s) => Ok(AmlParseType { + val: AmlValue::String(s.clone()), + len: len + starting_index + }), + Err(_) => Err(AmlError::AmlParseError("Namestring - Name is invalid")) } } -fn parse_null_name(data: &[u8]) -> Result<(Vec, usize), AmlInternalError> { +fn parse_null_name(data: &[u8]) -> Result<(Vec, usize), AmlError> { parser_opcode!(data, 0x00); Ok((vec!(), 1 as usize)) } -pub fn parse_name_seg(data: &[u8]) -> Result<(Vec, usize), AmlInternalError> { +pub fn parse_name_seg(data: &[u8]) -> Result<(Vec, usize), AmlError> { match data[0] { 0x41 ... 0x5A | 0x5F => (), - _ => return Err(AmlInternalError::AmlInvalidOpCode) + _ => return Err(AmlError::AmlInvalidOpCode) } match data[1] { 0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (), - _ => return Err(AmlInternalError::AmlInvalidOpCode) + _ => return Err(AmlError::AmlInvalidOpCode) } match data[2] { 0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (), - _ => return Err(AmlInternalError::AmlInvalidOpCode) + _ => return Err(AmlError::AmlInvalidOpCode) } match data[3] { 0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (), - _ => return Err(AmlInternalError::AmlInvalidOpCode) + _ => return Err(AmlError::AmlInvalidOpCode) } let mut name_seg = vec!(data[0], data[1], data[2], data[3]); @@ -91,7 +83,7 @@ pub fn parse_name_seg(data: &[u8]) -> Result<(Vec, usize), AmlInternalError> Ok((name_seg, 4 as usize)) } -fn parse_dual_name_path(data: &[u8]) -> Result<(Vec, usize), AmlInternalError> { +fn parse_dual_name_path(data: &[u8]) -> Result<(Vec, usize), AmlError> { parser_opcode!(data, 0x2E); let mut characters: Vec = vec!(); @@ -118,12 +110,12 @@ fn parse_dual_name_path(data: &[u8]) -> Result<(Vec, usize), AmlInternalErro Ok((characters, dual_len)) } -fn parse_multi_name_path(data: &[u8]) -> Result<(Vec, usize), AmlInternalError> { +fn parse_multi_name_path(data: &[u8]) -> Result<(Vec, usize), AmlError> { parser_opcode!(data, 0x2F); let seg_count = data[1]; if seg_count == 0x00 { - return Err(AmlInternalError::AmlParseError("MultiName Path - can't have zero name segments")); + return Err(AmlError::AmlParseError("MultiName Path - can't have zero name segments")); } let mut current_seg = 0; @@ -149,40 +141,52 @@ fn parse_multi_name_path(data: &[u8]) -> Result<(Vec, usize), AmlInternalErr Ok((characters, multi_len)) } -pub fn parse_super_name(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> { +pub fn parse_super_name(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, + data, namespace, scope.clone(), parse_simple_name, - parser_wrap!(SuperName::Type6OpCode, parse_type6_opcode), + parse_type6_opcode, parse_debug_obj }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -fn parse_debug_obj(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> { +fn parse_debug_obj(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode_extended!(data, 0x31); - Ok((SuperName::DebugObj, 2 as usize)) + + Ok(AmlParseType { + val: AmlValue::DebugObject, + len: 2 as usize + }) } -pub fn parse_simple_name(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> { +pub fn parse_simple_name(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(SuperName::NameString, parse_name_string), - parser_wrap!(SuperName::ArgObj, parse_arg_obj), - parser_wrap!(SuperName::LocalObj, parse_local_obj) + data, namespace, scope.clone(), + parse_name_string, + parse_arg_obj, + parse_local_obj }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_target(data: &[u8]) -> Result<(Target, usize), AmlInternalError> { +pub fn parse_target(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { if data[0] == 0x00 { - Ok((Target::Null, 1 as usize)) + Ok(AmlParseType { + val: AmlValue::None, + len: 1 as usize + }) } else { - match parse_super_name(data) { - Ok((name, name_len)) => Ok((Target::SuperName(name), name_len)), - Err(e) => Err(e) - } + parse_super_name(data, namespace, scope.clone()) } } diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 321f013..080a1ae 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -1,16 +1,10 @@ -use super::AmlValue; +use super::namespace::AmlValue; +use super::AmlError; -pub type ParseResult = Result; +pub type ParseResult = Result; +pub type AmlParseType = AmlParseTypeGeneric; -pub struct AmlParseType { - val: Option, - len: usize -} - -// TODO: make private -pub enum AmlInternalError { - AmlParseError(&'static str), - AmlInvalidOpCode, - AmlValueError, - AmlDeferredLoad +pub struct AmlParseTypeGeneric { + pub val: T, + pub len: usize } diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs index 7c9e101..6b9555a 100644 --- a/src/acpi/aml/parsermacros.rs +++ b/src/acpi/aml/parsermacros.rs @@ -3,7 +3,7 @@ macro_rules! parser_selector { {$data:expr, $namespace:expr, $scope:expr, $func:expr} => { match $func($data, $namespace, $scope) { Ok(res) => return Ok(res), - Err(AmlInternalError::AmlInvalidOpCode) => (), + Err(AmlError::AmlInvalidOpCode) => (), Err(e) => return Err(e) } }; @@ -13,12 +13,29 @@ macro_rules! parser_selector { }; } +macro_rules! parser_selector_simple { + {$data:expr, $func:expr} => { + match $func($data) { + Ok(res) => return Ok(res), + Err(AmlError::AmlInvalidOpCode) => (), + Err(e) => return Err(e) + } + }; + {$data:expr, $func:expr, $($funcs:expr),+} => { + parser_selector_simple! {$data, $func}; + parser_selector_simple! {$data, $($funcs),*}; + }; +} + #[macro_export] macro_rules! parser_wrap { ($wrap:expr, $func:expr) => { - |data| { + |data, namespace, scope| { match $func(data) { - Ok((res, size)) => Ok(($wrap(res), size)), + Ok(res) => Ok(AmlParseTypeGeneric { + val: $wrap(res.val), + len: res.len + }), Err(e) => Err(e) } } @@ -29,12 +46,12 @@ macro_rules! parser_wrap { macro_rules! parser_opcode { ($data:expr, $opcode:expr) => { if $data[0] != $opcode { - return Err(AmlInternalError::AmlInvalidOpCode); + return Err(AmlError::AmlInvalidOpCode); } }; ($data:expr, $opcode:expr, $alternate_opcode:expr) => { if $data[0] != $opcode && $data[0] != $alternate_opcode { - return Err(AmlInternalError::AmlInvalidOpCode); + return Err(AmlError::AmlInvalidOpCode); } }; } @@ -43,7 +60,7 @@ macro_rules! parser_opcode { macro_rules! parser_opcode_extended { ($data:expr, $opcode:expr) => { if $data[0] != 0x5B || $data[1] != $opcode { - return Err(AmlInternalError::AmlInvalidOpCode); + return Err(AmlError::AmlInvalidOpCode); } }; } @@ -53,7 +70,7 @@ macro_rules! parser_verify_value { ($val:expr) => { match $val.val { Some(s) => s, - None => return Err(AmlInternalError::AmlValueError) + None => return Err(AmlError::AmlValueError) } }; } diff --git a/src/acpi/aml/pkglength.rs b/src/acpi/aml/pkglength.rs index 7c4ace8..b93939f 100644 --- a/src/acpi/aml/pkglength.rs +++ b/src/acpi/aml/pkglength.rs @@ -1,6 +1,6 @@ -use super::AmlInternalError; +use super::AmlError; -pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlInternalError> { +pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlError> { let lead_byte = data[0]; let count_bytes: usize = (lead_byte >> 6) as usize; @@ -10,7 +10,7 @@ pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlInternalError> let upper_two = (lead_byte >> 4) & 0x03; if upper_two != 0 { - return Err(AmlInternalError::AmlParseError("Invalid package length")); + return Err(AmlError::AmlParseError("Invalid package length")); } let mut current_byte = 0; diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index 5e5482e..bc2a747 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -3,158 +3,91 @@ use collections::string::String; use collections::vec::Vec; use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue, get_namespace_string}; -use super::namespacemodifier::{parse_namespace_modifier, NamespaceModifier}; -use super::namedobj::{parse_named_obj, NamedObj}; -use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj, DataObj, ArgObj, LocalObj}; -use super::type1opcode::{parse_type1_opcode, Type1OpCode}; -use super::type2opcode::{parse_type2_opcode, Type2OpCode}; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; +use super::namespacemodifier::parse_namespace_modifier; +use super::namedobj::parse_named_obj; +use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj}; +use super::type1opcode::parse_type1_opcode; +use super::type2opcode::parse_type2_opcode; use super::namestring::parse_name_string; -#[derive(Debug, Clone)] -pub enum TermArg { - LocalObj(Box), - DataObj(Box), - ArgObj(Box), - Type2Opcode(Box) -} - -#[derive(Debug, Clone)] -pub enum TermObj { - NamespaceModifier(Box), - NamedObj(Box), - Type1Opcode(Box), - Type2Opcode(Box) -} - -#[derive(Debug, Clone)] -pub enum Object { - NamespaceModifier(Box), - NamedObj(Box) -} - -#[derive(Debug, Clone)] -pub struct MethodInvocation { - -} - -impl AmlExecutable for Vec { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - for term in self { - term.execute(namespace, scope.clone()); - } - - None - } -} - -impl AmlExecutable for Object { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - Object::NamespaceModifier(ref d) => d.execute(namespace, scope), - Object::NamedObj(ref d) => d.execute(namespace, scope) - } - } -} - -impl AmlExecutable for Vec { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - for term in self { - term.execute(namespace, scope.clone()); - } - - None - } -} - -impl AmlExecutable for TermArg { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - TermArg::LocalObj(ref l) => Some(AmlValue::Uninitialized), - TermArg::DataObj(ref d) => d.execute(namespace, scope), - TermArg::ArgObj(ref a) => Some(AmlValue::Uninitialized), - TermArg::Type2Opcode(ref o) => Some(AmlValue::Uninitialized) - } - } -} - -impl AmlExecutable for TermObj { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - TermObj::NamespaceModifier(ref res) => res.execute(namespace, scope.clone()), - TermObj::NamedObj(ref res) => res.execute(namespace, scope.clone()), - TermObj::Type1Opcode(ref res) => res.execute(namespace, scope.clone()), - TermObj::Type2Opcode(ref res) => res.execute(namespace, scope.clone()) - } - } -} - pub fn parse_term_list(data: &[u8], namespace: &mut BTreeMap, scope: String) -> ParseResult { let mut current_offset: usize = 0; while current_offset < data.len() { - let (res, len) = parse_term_obj(&data[current_offset..], namespace, scope)?; - current_offset += len; + let res = parse_term_obj(&data[current_offset..], namespace, scope.clone())?; + current_offset += res.len; } Ok(AmlParseType { - val: None, + val: AmlValue::None, len: data.len() }) } -pub fn parse_term_arg(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> { +pub fn parse_term_arg(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(TermArg::LocalObj, parser_wrap!(Box::new, parse_local_obj)), - parser_wrap!(TermArg::DataObj, parser_wrap!(Box::new, parse_data_obj)), - parser_wrap!(TermArg::ArgObj, parser_wrap!(Box::new, parse_arg_obj)), - parser_wrap!(TermArg::Type2Opcode, parser_wrap!(Box::new, parse_type2_opcode)) + data, namespace, scope.clone(), + parse_local_obj, + parse_data_obj, + parse_arg_obj, + parse_type2_opcode }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_object_list(data: &[u8]) -> Result, AmlInternalError> { - let mut terms: Vec = vec!(); +pub fn parse_object_list(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { let mut current_offset: usize = 0; while current_offset < data.len() { - let (res, len) = parse_object(&data[current_offset..])?; - terms.push(res); - current_offset += len; + let res = parse_object(&data[current_offset..], namespace, scope.clone())?; + current_offset += res.len; } - Ok(terms) + Ok(AmlParseType { + val: AmlValue::None, + len: data.len() + }) } -fn parse_object(data: &[u8]) -> Result<(Object, usize), AmlInternalError> { +fn parse_object(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(Object::NamespaceModifier, parser_wrap!(Box::new, parse_namespace_modifier)), - parser_wrap!(Object::NamedObj, parser_wrap!(Box::new, parse_named_obj)) + data, namespace, scope.clone(), + parse_namespace_modifier, + parse_named_obj }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_method_invocation(data: &[u8]) -> Result<(MethodInvocation, usize), AmlInternalError> { - let (name, name_len) = parse_name_string(data)?; - Err(AmlInternalError::AmlDeferredLoad) +pub fn parse_method_invocation(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + let name = parse_name_string(data, namespace, scope)?; + Err(AmlError::AmlDeferredLoad) } fn parse_term_obj(data: &[u8], namespace: &mut BTreeMap, scope: String) -> ParseResult { parser_selector! { - data, namespace, scope, + data, namespace, scope.clone(), parse_namespace_modifier, parse_named_obj, parse_type1_opcode, parse_type2_opcode }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index d476a24..b32acf8 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -3,76 +3,22 @@ use collections::string::String; use collections::vec::Vec; use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue}; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult}; +use super::namespace::{AmlValue, ObjectReference}; use super::pkglength::parse_pkg_length; -use super::termlist::{parse_term_arg, parse_term_list, TermObj, TermArg}; -use super::namestring::{parse_name_string, parse_super_name, SuperName}; - -#[derive(Debug, Clone)] -pub enum Type1OpCode { - DefBreak, - DefBreakPoint, - DefContinue, - DefFatal { - fatal_type: u8, - fatal_code: u16, - fatal_arg: TermArg - }, - DefNoop, - DefIfElse { - if_block: IfBlock, - else_block: IfBlock - }, - DefLoad { - name: String, - ddb_handle_object: SuperName - }, - DefNotify { - object: SuperName, - value: TermArg - }, - DefRelease(SuperName), - DefReset(SuperName), - DefSignal(SuperName), - DefSleep(TermArg), - DefStall(TermArg), - DefUnload(SuperName), - DefWhile { - predicate: TermArg, - block: Vec - }, - DefReturn(TermArg), - DeferredLoad(Vec) -} - -impl AmlExecutable for Type1OpCode { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - None - } -} - -#[derive(Debug, Clone)] -pub enum IfBlock { - If { - predicate: TermArg, - if_block: Vec - }, - Else(Vec), - NoBlock, - DeferredLoad(Vec) -} - -pub fn parse_type1_opcode(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - match data[0] { - 0xA5 => return Ok((Type1OpCode::DefBreak, 1 as usize)), - 0xCC => return Ok((Type1OpCode::DefBreakPoint, 1 as usize)), - 0x9F => return Ok((Type1OpCode::DefContinue, 1 as usize)), - 0xA3 => return Ok((Type1OpCode::DefNoop, 1 as usize)), - _ => () - } +use super::termlist::{parse_term_arg, parse_term_list}; +use super::namestring::{parse_name_string, parse_super_name}; +pub fn parse_type1_opcode(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, + data, namespace, scope.clone(), + parse_def_break, + parse_def_breakpoint, + parse_def_continue, + parse_def_noop, parse_def_fatal, parse_def_if_else, parse_def_load, @@ -87,174 +33,248 @@ pub fn parse_type1_opcode(data: &[u8]) -> Result<(Type1OpCode, usize), AmlIntern parse_def_while }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -fn parse_def_fatal(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x32 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_break(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Implement + parser_opcode!(data, 0xA5); + + Ok(AmlParseType { + val: AmlValue::None, + len: 1 as usize + }) +} + +fn parse_def_breakpoint(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Implement + parser_opcode!(data, 0xCC); + + Ok(AmlParseType { + val: AmlValue::None, + len: 1 as usize + }) +} + +fn parse_def_continue(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Implement + parser_opcode!(data, 0x9F); + + Ok(AmlParseType { + val: AmlValue::None, + len: 1 as usize + }) +} + +fn parse_def_noop(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + parser_opcode!(data, 0xA3); + + Ok(AmlParseType { + val: AmlValue::None, + len: 1 as usize + }) +} + +fn parse_def_fatal(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + parser_opcode_extended!(data, 0x32); let fatal_type = data[2]; - let fatal_code: u16 = (data[3] as u16) + - ((data[4] as u16) << 8); - let (fatal_arg, fatal_arg_len) = parse_term_arg(&data[5..])?; + let fatal_code: u16 = (data[3] as u16) + ((data[4] as u16) << 8); + let fatal_arg = parse_term_arg(&data[5..], namespace, scope.clone())?; - Ok((Type1OpCode::DefFatal {fatal_type, fatal_code, fatal_arg}, fatal_arg_len + 5)) + Err(AmlError::AmlFatalError(fatal_type, fatal_code, fatal_arg.val)) } -fn parse_def_load(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x20 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_load(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // 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, name_len) = parse_name_string(&data[2..])?; - let (ddb_handle_object, ddb_handle_object_len) = parse_super_name(&data[2 + name_len..])?; - - Ok((Type1OpCode::DefLoad {name, ddb_handle_object}, 2 + name_len + ddb_handle_object_len)) + let name = parse_name_string(&data[2..], namespace, scope.clone())?; + let ddb_handle_object = parse_super_name(&data[2 + name.len..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + name.len + ddb_handle_object.len + }) } -fn parse_def_notify(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x86 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_notify(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: This requires significantly more infrastructure from the OS itself, see 5.6.6 + parser_opcode!(data, 0x86); - let (object, object_len) = parse_super_name(&data[1..])?; - let (value, value_len) = parse_term_arg(&data[1 + object_len..])?; + let object = parse_super_name(&data[1..], namespace, scope.clone())?; + let value = parse_term_arg(&data[1 + object.len..], namespace, scope.clone())?; - Ok((Type1OpCode::DefNotify {object, value}, 1 + object_len + value_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 1 + object.len + value.len + }) } -fn parse_def_release(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x27 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_release(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Check ownership of the mutex pointed to + // TODO: FATAL if not owned + // TODO: Release if it is + parser_opcode_extended!(data, 0x27); - let (object, object_len) = parse_super_name(&data[2..])?; + let object = parse_super_name(&data[2..], namespace, scope.clone())?; - Ok((Type1OpCode::DefRelease(object), 2 + object_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + object.len + }) } -fn parse_def_reset(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x26 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_reset(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: object (of type Event) is a semaphore. Reset the resource count to 0 + parser_opcode_extended!(data, 0x26); - let (object, object_len) = parse_super_name(&data[2..])?; + let object = parse_super_name(&data[2..], namespace, scope.clone())?; - Ok((Type1OpCode::DefReset(object), 2 + object_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + object.len + }) } -fn parse_def_signal(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x24 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_signal(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Increment the resource count of the semaphore + parser_opcode_extended!(data, 0x24); - let (object, object_len) = parse_super_name(&data[2..])?; + let object = parse_super_name(&data[2..], namespace, scope.clone())?; - Ok((Type1OpCode::DefSignal(object), 2 + object_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + object.len + }) } -fn parse_def_sleep(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x22 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_sleep(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Sleep the processor for the specified number of milliseconds (minimum) + parser_opcode_extended!(data, 0x22); - let (time, time_len) = parse_term_arg(&data[2..])?; + let time = parse_term_arg(&data[2..], namespace, scope.clone())?; - Ok((Type1OpCode::DefSleep(time), 2 + time_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + time.len + }) } -fn parse_def_stall(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x21 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_stall(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Sleep the processor for the specified number of microseconds (minimum) + parser_opcode_extended!(data, 0x21); - let (time, time_len) = parse_term_arg(&data[2..])?; + let time = parse_term_arg(&data[2..], namespace, scope.clone())?; - Ok((Type1OpCode::DefStall(time), 2 + time_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + time.len + }) } -fn parse_def_unload(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x2A { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_unload(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: remove from namespace all values added when `object` was loaded + // TODO: globally synchronous (how?) + parser_opcode_extended!(data, 0x2A); - let (object, object_len) = parse_super_name(&data[2..])?; + let object = parse_super_name(&data[2..], namespace, scope.clone())?; - Ok((Type1OpCode::DefUnload(object), 2 + object_len)) + Ok(AmlParseType { + val: AmlValue::None, + len: 2 + object.len + }) } -fn parse_def_if_else(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0xA0 { - return Err(AmlInternalError::AmlInvalidOpCode); +fn parse_def_if_else(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + parser_opcode!(data, 0xA0); + + let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; + let if_condition = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], namespace, scope.clone())?; + + let (else_length, else_length_len) = if data.len() > 1 + pkg_length && data[1 + pkg_length] == 0xA1 { + parse_pkg_length(&data[2 + pkg_length..])? + } else { + (0 as usize, 0 as usize) + }; + + if if_condition.val.get_as_integer()? > 0 { + parse_term_list(&data[1 + pkg_length_len + if_condition.len .. 1 + pkg_length], + namespace, scope.clone())?; + } else if else_length > 0 { + parse_term_list(&data[2 + pkg_length + else_length_len .. 2 + pkg_length + else_length], + namespace, scope.clone())?; } + Ok(AmlParseType { + val: AmlValue::None, + len: 1 + pkg_length + if else_length > 0 { 1 + else_length } else { 0 } + }) +} + +fn parse_def_while(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + parser_opcode!(data, 0xA2); + let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let if_block = match parse_term_arg(&data[1 + pkg_length_len..]) { - Ok((predicate, predicate_len)) => { - match parse_term_list(&data[1 + pkg_length_len + predicate_len .. 1 + pkg_length]) { - Ok(if_block) => IfBlock::If {predicate, if_block}, - Err(AmlInternalError::AmlDeferredLoad) => - IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), - Err(e) => return Err(e) - } - }, - Err(AmlInternalError::AmlDeferredLoad) => - IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), - Err(e) => return Err(e) - }; - - let (else_block, else_block_len) = parse_def_else(&data[1 + pkg_length..])?; - - return Ok((Type1OpCode::DefIfElse {if_block, else_block}, - pkg_length + else_block_len + 1)); + loop { + let predicate = parse_term_arg(&data[1 + pkg_length_len..], namespace, scope.clone())?; + if predicate.val.get_as_integer()? == 0 { + break; + } + + parse_term_list(&data[1 + pkg_length_len + predicate.len .. 1 + pkg_length], namespace, scope.clone())?; + } + + Ok(AmlParseType { + val: AmlValue::None, + len: 1 + pkg_length + }) } -fn parse_def_else(data: &[u8]) -> Result<(IfBlock, usize), AmlInternalError> { - if data.len() == 0 || data[0] != 0xA1 { - // We might be at the very end of a buffer, in which case there isn't an else - return Ok((IfBlock::NoBlock, 0)); - } +fn parse_def_return(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Return to the calling context + // TODO: We need contexts for that + parser_opcode!(data, 0xA4); - let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - match parse_term_list(&data[1 + pkg_length_len .. 1 + pkg_length]) { - Ok(term_list) => Ok((IfBlock::Else(term_list), 1 + pkg_length)), - Err(AmlInternalError::AmlDeferredLoad) => - Ok((IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)), - Err(e) => return Err(e) - } -} - -fn parse_def_while(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0xA2 { - return Err(AmlInternalError::AmlInvalidOpCode); - } - - let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let (predicate, predicate_len) = match parse_term_arg(&data[1 + pkg_length_len..]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((Type1OpCode::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)), - Err(e) => return Err(e) - }; - let block = match parse_term_list(&data[1 + pkg_length_len + predicate_len .. 1 + pkg_length]) { - Ok(p) => p, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((Type1OpCode::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)), - Err(e) => return Err(e) - }; - - Ok((Type1OpCode::DefWhile {predicate, block}, pkg_length + 1)) -} - -fn parse_def_return(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> { - if data[0] != 0xA4 { - return Err(AmlInternalError::AmlInvalidOpCode); - } - - let (arg_object, arg_object_len) = parse_term_arg(&data[1..])?; - - Ok((Type1OpCode::DefReturn(arg_object), 1 + arg_object_len)) + let arg_object = parse_term_arg(&data[1..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::None, + len: 1 + arg_object.len + }) } diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index e96bdbc..eef85e1 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -3,236 +3,13 @@ use collections::string::String; use collections::vec::Vec; use collections::btree_map::BTreeMap; -use super::{AmlInternalError, AmlExecutable, AmlValue}; +use super::AmlError; +use super::parser::{AmlParseType, ParseResult}; +use super::namespace::{AmlValue, ObjectReference}; use super::pkglength::parse_pkg_length; -use super::termlist::{parse_term_arg, parse_method_invocation, TermArg, MethodInvocation}; -use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name, - SuperName, Target}; -use super::dataobj::{parse_data_ref_obj, DataRefObj}; - -#[derive(Debug, Clone)] -pub enum Type2OpCode { - DefAcquire { - object: SuperName, - timeout: u16 - }, - DefBuffer(DefBuffer), - DefPackage(DefPackage), - DefVarPackage(DefVarPackage), - DefDerefOf(TermArg), - DefRefOf(SuperName), - DefIncrement(SuperName), - DefIndex(DefIndex), - DefDecrement(SuperName), - DefFindSetLeftBit { - operand: TermArg, - target: Target - }, - DefFindSetRightBit { - operand: TermArg, - target: Target - }, - DefFromBCD { - operand: TermArg, - target: Target - }, - DefDivide { - dividend: TermArg, - divisor: TermArg, - remainder: Target, - quotient: Target - }, - DefCondRefOf { - operand: SuperName, - target: Target - }, - DefCopyObject { - source: TermArg, - destination: SuperName - }, - DefLAnd { - lhs: TermArg, - rhs: TermArg - }, - DefLEqual { - lhs: TermArg, - rhs: TermArg - }, - DefLGreater { - lhs: TermArg, - rhs: TermArg - }, - DefLLess { - lhs: TermArg, - rhs: TermArg - }, - DefLNot(TermArg), - DefLOr { - lhs: TermArg, - rhs: TermArg - }, - DefSizeOf(SuperName), - DefStore { - operand: TermArg, - target: SuperName - }, - DefSubtract { - minuend: TermArg, - subtrahend: TermArg, - target: Target - }, - DefToBuffer { - operand: TermArg, - target: Target - }, - DefToHexString { - operand: TermArg, - target: Target - }, - DefToBCD { - operand: TermArg, - target: Target - }, - DefToDecimalString { - operand: TermArg, - target: Target - }, - DefToInteger { - operand: TermArg, - target: Target - }, - DefToString { - operand: TermArg, - length: TermArg, - target: Target - }, - DefConcat { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefConcatRes { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefShiftLeft { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefShiftRight { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefAdd { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefMultiply { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefMod { - dividend: TermArg, - divisor: TermArg, - target: Target - }, - DefAnd { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefNAnd { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefOr { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefXor { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefNOr { - lhs: TermArg, - rhs: TermArg, - target: Target - }, - DefNot { - operand: TermArg, - target: Target - }, - DefLoadTable { - signature: TermArg, - oem_id: TermArg, - oem_table_id: TermArg, - root_path: TermArg, - parameter_path: TermArg, - parameter_data: TermArg - }, - DefMatch { - search_pkg: TermArg, - first_operation: MatchOpcode, - first_operand: TermArg, - second_operation: MatchOpcode, - second_operand: TermArg, - start_index: TermArg - }, - DefMid { - source: TermArg, - index: TermArg, - length: TermArg, - target: Target - }, - DefWait { - event_object: SuperName, - operand: TermArg - }, - DefObjectType(DefObjectType), - DefTimer, - MethodInvocation(MethodInvocation) -} - -impl AmlExecutable for Type2OpCode { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - None - } -} - -impl AmlExecutable for DefBuffer { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - DefBuffer::Buffer { ref buffer_size, ref byte_list } => { - let length = match buffer_size.execute(namespace, scope.clone()) { - Some(l) => Box::new(l), - _ => return None - }; - - Some(AmlValue::Buffer { - length: length, - byte_list: byte_list.clone() - }) - }, - _ => None - } - } -} - -#[derive(Debug, Clone)] -pub enum DefObjectType { - SuperName(SuperName), - DefIndex(DefIndex), - DefRefOf(SuperName), - DefDerefOf(TermArg) -} +use super::termlist::{parse_term_arg, parse_method_invocation}; +use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name}; +use super::dataobj::parse_data_ref_obj; #[derive(Debug, Clone)] pub enum MatchOpcode { @@ -244,84 +21,11 @@ pub enum MatchOpcode { MGT } -#[derive(Debug, Clone)] -pub enum Type6OpCode { - DefDerefOf(TermArg), - DefRefOf(Box), - DefIndex(DefIndex), - MethodInvocation(MethodInvocation) -} - -#[derive(Debug, Clone)] -pub struct DefIndex { - obj: TermArg, - idx: TermArg, - target: Box -} - -#[derive(Debug, Clone)] -pub enum DefBuffer { - Buffer { - buffer_size: TermArg, - byte_list: Vec - }, - DeferredLoad(Vec) -} - -#[derive(Debug, Clone)] -pub enum DefPackage { - Package { - num_elements: u8, - elements: Vec - }, - DeferredLoad(Vec) -} - -#[derive(Debug, Clone)] -pub enum DefVarPackage { - Package { - num_elements: TermArg, - elements: Vec - }, - DeferredLoad(Vec) -} - -#[derive(Debug, Clone)] -pub enum PackageElement { - DataRefObj(DataRefObj), - NameString(String) -} - -impl AmlExecutable for DefPackage { - fn execute(&self, namespace: &mut BTreeMap, scope: String) -> Option { - match *self { - DefPackage::Package { ref num_elements, ref elements } => { - let mut values: Vec = vec!(); - - for element in elements { - match *element { - PackageElement::DataRefObj(ref d) => { - let elem = match d.execute(namespace, scope.clone()) { - Some(e) => e, - None => continue - }; - - values.push(elem); - }, - _ => return None - } - } - - Some(AmlValue::Package(values)) - }, - _ => None - } - } -} - -pub fn parse_type2_opcode(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +pub fn parse_type2_opcode(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, + data, namespace, scope.clone(), parse_def_increment, parse_def_acquire, parse_def_wait, @@ -364,589 +68,905 @@ pub fn parse_type2_opcode(data: &[u8]) -> Result<(Type2OpCode, usize), AmlIntern parse_def_nor, parse_def_not, parse_def_timer, - parser_wrap!(Type2OpCode::DefBuffer, parse_def_buffer), - parser_wrap!(Type2OpCode::DefPackage, parse_def_package), - parser_wrap!(Type2OpCode::DefVarPackage, parse_def_var_package), - parser_wrap!(Type2OpCode::DefObjectType, parse_def_object_type), - parser_wrap!(Type2OpCode::DefDerefOf, parse_def_deref_of), - parser_wrap!(Type2OpCode::DefRefOf, parse_def_ref_of), - parser_wrap!(Type2OpCode::DefIndex, parse_def_index), - parser_wrap!(Type2OpCode::MethodInvocation, parse_method_invocation) + parse_def_buffer, + parse_def_package, + parse_def_var_package, + parse_def_object_type, + parse_def_deref_of, + parse_def_ref_of, + parse_def_index, + parse_method_invocation }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_type6_opcode(data: &[u8]) -> Result<(Type6OpCode, usize), AmlInternalError> { +pub fn parse_type6_opcode(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_selector! { - data, - parser_wrap!(Type6OpCode::DefDerefOf, parse_def_deref_of), - parser_wrap!(Type6OpCode::DefRefOf, parser_wrap!(Box::new, parse_def_ref_of)), - parser_wrap!(Type6OpCode::DefIndex, parse_def_index), - parser_wrap!(Type6OpCode::MethodInvocation, parse_method_invocation) + data, namespace, scope.clone(), + parse_def_deref_of, + parse_def_ref_of, + parse_def_index, + parse_method_invocation }; - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_def_object_type(data: &[u8]) -> Result<(DefObjectType, usize), AmlInternalError> { +pub fn parse_def_object_type(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x8E); parser_selector! { - data, - parser_wrap!(DefObjectType::SuperName, parse_super_name), - parser_wrap!(DefObjectType::DefRefOf, parse_def_ref_of), - parser_wrap!(DefObjectType::DefDerefOf, parse_def_deref_of), - parser_wrap!(DefObjectType::DefIndex, parse_def_index) + data, namespace, scope.clone(), + parse_super_name, + parse_def_ref_of, + parse_def_deref_of, + parse_def_index } - Err(AmlInternalError::AmlInvalidOpCode) + Err(AmlError::AmlInvalidOpCode) } -pub fn parse_def_package(data: &[u8]) -> Result<(DefPackage, usize), AmlInternalError> { +pub fn parse_def_package(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Handle deferred loads in here + // TODO: Truncate/extend array if necessary parser_opcode!(data, 0x12); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; let num_elements = data[1 + pkg_length_len]; - - let elements = match parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length]) { - Ok(e) => e, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((DefPackage::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)), - Err(e) => return Err(e) - }; - - Ok((DefPackage::Package {num_elements, elements}, 1 + pkg_length)) + let elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], + namespace, scope.clone())?; + + Ok(AmlParseType { + val: elements.val, + len: 1 + pkg_length + }) } -pub fn parse_def_var_package(data: &[u8]) -> Result<(DefVarPackage, usize), AmlInternalError> { +pub fn parse_def_var_package(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Handle deferred loads in here + // TODO: Truncate/extend array if necessary parser_opcode!(data, 0x13); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let (num_elements, num_elements_len) = parse_term_arg(&data[1 + pkg_length_len ..])?; - - let elements = match parse_package_elements_list(&data[1 + pkg_length_len + num_elements_len .. - 1 + pkg_length]) { - Ok(e) => e, - Err(AmlInternalError::AmlDeferredLoad) => - return Ok((DefVarPackage::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), - 1 + pkg_length)), - Err(e) => return Err(e) - }; - - Ok((DefVarPackage::Package {num_elements, elements}, 1 + pkg_length)) + let num_elements = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], namespace, scope.clone())?; + let elements = parse_package_elements_list(&data[1 + pkg_length_len + num_elements.len .. + 1 + pkg_length], namespace, scope.clone())?; + + Ok(AmlParseType { + val: elements.val, + len: 1 + pkg_length + }) } -fn parse_package_elements_list(data: &[u8]) -> Result, AmlInternalError> { +fn parse_package_elements_list(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { let mut current_offset: usize = 0; - let mut elements: Vec = vec!(); + let mut elements: Vec = vec!(); while current_offset < data.len() { - match parse_data_ref_obj(&data[current_offset ..]) { - Ok((data_ref_obj, data_ref_obj_len)) => { - elements.push(PackageElement::DataRefObj(data_ref_obj)); - current_offset += data_ref_obj_len; - }, - Err(AmlInternalError::AmlInvalidOpCode) => - match parse_name_string(&data[current_offset ..]) { - Ok((name_string, name_string_len)) => { - elements.push(PackageElement::NameString(name_string)); - current_offset += name_string_len; - }, - Err(e) => return Err(e) - }, - Err(e) => return Err(e) - } + let dro = if let Ok(e) = parse_data_ref_obj(&data[current_offset..], namespace, scope.clone()) { + e + } else { + parse_name_string(&data[current_offset..], namespace, scope.clone())? + }; + + elements.push(dro.val); + current_offset += dro.len; } - Ok(elements) + Ok(AmlParseType { + val: AmlValue::Package(elements), + len: data.len() + }) } -pub fn parse_def_buffer(data: &[u8]) -> Result<(DefBuffer, usize), AmlInternalError> { +pub fn parse_def_buffer(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Perform computation parser_opcode!(data, 0x11); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let (buffer_size, buffer_size_len) = match parse_term_arg(&data[1 + pkg_length_len..]) { - Ok(s) => s, - Err(AmlInternalError::AmlDeferredLoad) => return Ok((DefBuffer::DeferredLoad( - data[0 .. 1 + pkg_length].to_vec() - ), 1 + pkg_length)), - Err(e) => return Err(e), - }; - let byte_list = data[1 + pkg_length_len + buffer_size_len .. 1 + pkg_length].to_vec(); + let buffer_size = parse_term_arg(&data[1 + pkg_length_len..], namespace, scope.clone())?; + let byte_list = data[1 + pkg_length_len + buffer_size.len .. 1 + pkg_length].to_vec(); - Ok((DefBuffer::Buffer {buffer_size, byte_list}, pkg_length + 1)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + pkg_length + }) } -fn parse_def_ref_of(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> { +fn parse_def_ref_of(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Perform computation parser_opcode!(data, 0x71); - let (obj_reference, obj_reference_len) = parse_super_name(&data[1..])?; - Ok((obj_reference, obj_reference_len + 1)) + let obj = parse_super_name(&data[1..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + obj.len + }) } -fn parse_def_deref_of(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> { +fn parse_def_deref_of(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Perform computation parser_opcode!(data, 0x83); - let (obj_reference, obj_reference_len) = parse_term_arg(&data[1..])?; - Ok((obj_reference, obj_reference_len + 1)) + let obj = parse_term_arg(&data[1..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + obj.len + }) } -fn parse_def_acquire(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_acquire(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result + // TODO: Perform computation parser_opcode_extended!(data, 0x23); - let (object, object_len) = parse_super_name(&data[2..])?; - let timeout = (data[2 + object_len] as u16) + - ((data[3 + object_len] as u16) << 8); - - Ok((Type2OpCode::DefAcquire {object, timeout}, object_len + 4)) + let obj = parse_super_name(&data[1..], namespace, scope.clone())?; + let timeout = (data[2 + obj.len] as u16) + ((data[3 + obj.len] as u16) << 8); + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 4 + obj.len + }) } -fn parse_def_increment(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_increment(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result + // TODO: Perform computation parser_opcode!(data, 0x75); - let (obj, obj_len) = parse_super_name(&data[1..])?; - Ok((Type2OpCode::DefIncrement(obj), obj_len + 1)) + let obj = parse_super_name(&data[1..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + obj.len + }) } -fn parse_def_index(data: &[u8]) -> Result<(DefIndex, usize), AmlInternalError> { +fn parse_def_index(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + // TODO: Perform computation parser_opcode!(data, 0x88); - let (obj, obj_len) = parse_term_arg(&data[1..])?; - let (idx, idx_len) = parse_term_arg(&data[1 + obj_len..])?; - let (target, target_len) = parse_target(&data[1 + obj_len + idx_len..])?; - - Ok((DefIndex {obj, idx, target: Box::new(target)}, 1 + obj_len + idx_len + target_len)) + let obj = parse_term_arg(&data[1..], namespace, scope.clone())?; + let idx = parse_term_arg(&data[1 + obj.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + obj.len + idx.len..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + obj.len + idx.len + target.len + }) } -fn parse_def_land(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_land(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x90); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefLAnd {lhs, rhs}, 1 + lhs_len + rhs_len)) + let result = if lhs.val.get_as_integer()? > 0 && rhs.val.get_as_integer()? > 0 { 1 } else { 0 }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + }) } -fn parse_def_lequal(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_lequal(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x93); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefLEqual {lhs, rhs}, 1 + lhs_len + rhs_len)) + let result = if lhs.val.get_as_integer()? == rhs.val.get_as_integer()? { 1 } else { 0 }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + }) } -fn parse_def_lgreater(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_lgreater(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x94); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefLGreater {lhs, rhs}, 1 + lhs_len + rhs_len)) + let result = if lhs.val.get_as_integer()? > rhs.val.get_as_integer()? { 1 } else { 0 }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + }) } -fn parse_def_lless(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_lless(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x95); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefLLess {lhs, rhs}, 1 + lhs_len + rhs_len)) + let result = if lhs.val.get_as_integer()? < rhs.val.get_as_integer()? { 1 } else { 0 }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + }) } -fn parse_def_lnot(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_lnot(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x92); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - - Ok((Type2OpCode::DefLNot(operand), 1 + operand_len)) + let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; + let result = if operand.val.get_as_integer()? == 0 { 1 } else { 0 }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + operand.len + }) } -fn parse_def_lor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_lor(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { parser_opcode!(data, 0x91); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefLOr {lhs, rhs}, 1 + lhs_len + rhs_len)) + let result = if lhs.val.get_as_integer()? > 0 || rhs.val.get_as_integer()? > 0 { 1 } else { 0 }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + }) } -fn parse_def_to_hex_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_to_hex_string(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x98); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefToHexString {operand, target}, 1 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_to_buffer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_to_buffer(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x96); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefToBuffer {operand, target}, 1 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_to_bcd(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_to_bcd(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode_extended!(data, 0x29); - let (operand, operand_len) = parse_term_arg(&data[2..])?; - let (target, target_len) = parse_target(&data[2 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefToBCD {operand, target}, 2 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_to_decimal_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_to_decimal_string(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x97); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefToDecimalString {operand, target}, 1 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_to_integer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_to_integer(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x99); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefToInteger {operand, target}, 1 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_to_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_to_string(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x9C); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (length, length_len) = parse_term_arg(&data[1 + operand_len..])?; - let (target, target_len) = parse_target(&data[1 + operand_len + length_len..])?; + let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; + let length = parse_term_arg(&data[1 + operand.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + operand.len + length.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefToString {operand, length, target}, 1 + operand_len + length_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + length.len + target.len + }) } -fn parse_def_subtract(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_subtract(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x74); - let (minuend, minuend_len) = parse_term_arg(&data[1..])?; - let (subtrahend, subtrahend_len) = parse_term_arg(&data[1 + minuend_len..])?; - let (target, target_len) = parse_target(&data[1 + minuend_len + subtrahend_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefSubtract {minuend, subtrahend, target}, 1 + minuend_len + subtrahend_len + target_len)) + let result = lhs.val.get_as_integer()? - rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_size_of(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_size_of(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Perform the computation parser_opcode!(data, 0x87); - let (name, name_len) = parse_super_name(&data[1..])?; - Ok((Type2OpCode::DefSizeOf(name), name_len + 1)) + let name = parse_super_name(&data[1..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + name.len + }) } -fn parse_def_store(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_store(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Perform the store parser_opcode!(data, 0x70); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_super_name(&data[1 + operand_len..])?; - - Ok((Type2OpCode::DefStore {operand, target}, operand_len + target_len + 1)) + let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; + let target = parse_super_name(&data[1 + operand.len..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_or(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_or(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x7D); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefOr {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + let result = lhs.val.get_as_integer()? | rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_shift_left(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_shift_left(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x79); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefShiftLeft {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + let result = lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_shift_right(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_shift_right(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x7A); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefShiftRight {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + let result = lhs.val.get_as_integer()? << rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_add(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_add(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x72); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefAdd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + let result = lhs.val.get_as_integer()? + rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_and(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_and(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x7B); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefAnd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + let result = lhs.val.get_as_integer()? & rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_xor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_xor(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate parser_opcode!(data, 0x7F); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefXor {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + let result = lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_concat_res(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_concat_res(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x84); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; - - Ok((Type2OpCode::DefConcatRes {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_wait(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_wait(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result parser_opcode_extended!(data, 0x25); - let (event_object, event_object_len) = parse_super_name(&data[2..])?; - let (operand, operand_len) = parse_term_arg(&data[2 + event_object_len..])?; + let event_object = parse_super_name(&data[2..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2 + event_object.len..], namespace, scope.clone())?; - - Ok((Type2OpCode::DefWait {event_object, operand}, 2 + event_object_len + operand_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 2 + event_object.len + operand.len + }) } -fn parse_def_cond_ref_of(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_cond_ref_of(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result parser_opcode_extended!(data, 0x12); - let (operand, operand_len) = parse_super_name(&data[2..])?; - let (target, target_len) = parse_target(&data[2 + operand_len..])?; + let operand = parse_super_name(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefCondRefOf {operand, target}, 2 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 2 + operand.len + target.len + }) } -fn parse_def_copy_object(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_copy_object(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result parser_opcode!(data, 0x9D); - let (source, source_len) = parse_term_arg(&data[1..])?; - let (destination, destination_len) = parse_simple_name(&data[1 + source_len..])?; + let source = parse_term_arg(&data[1..], namespace, scope.clone())?; + let destination = parse_simple_name(&data[1 + source.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefCopyObject {source, destination}, 1 + source_len + destination_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + source.len + destination.len + }) } -fn parse_def_concat(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_concat(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result parser_opcode!(data, 0x73); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefConcat {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_decrement(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_decrement(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result parser_opcode!(data, 0x76); - let (target, target_len) = parse_super_name(&data[1..])?; + let target = parse_super_name(&data[1..], namespace, scope.clone())?; - Ok((Type2OpCode::DefDecrement(target), 1 + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + target.len + }) } -fn parse_def_divide(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_divide(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x78); - let (dividend, dividend_len) = parse_term_arg(&data[1..])?; - let (divisor, divisor_len) = parse_term_arg(&data[1 + dividend_len..])?; - let (remainder, remainder_len) = parse_target(&data[1 + dividend_len + divisor_len..])?; - let (quotient, quotient_len) = parse_target(&data[1 + dividend_len + divisor_len + remainder_len..])?; - - Ok((Type2OpCode::DefDivide {dividend, divisor, remainder, quotient}, - 1 + dividend_len + divisor_len + remainder_len + quotient_len)) + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target_remainder = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let target_quotient = parse_target(&data[1 + lhs.len + rhs.len + target_remainder.len..], namespace, scope.clone())?; + + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + lhs.len + rhs.len + target_remainder.len + target_quotient.len + }) } -fn parse_def_find_set_left_bit(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { +fn parse_def_find_set_left_bit(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate parser_opcode!(data, 0x81); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefFindSetLeftBit {operand, target}, 1 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_find_set_right_bit(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x82 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_find_set_right_bit(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate + parser_opcode!(data, 0x82); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefFindSetRightBit {operand, target}, 1 + operand_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + operand.len + target.len + }) } -fn parse_def_load_table(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x1F { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_load_table(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate + // TODO: Clean up + parser_opcode_extended!(data, 0x1F); - let (signature, signature_len) = parse_term_arg(&data[2..])?; - let (oem_id, oem_id_len) = parse_term_arg(&data[2 + signature_len..])?; - let (oem_table_id, oem_table_id_len) = parse_term_arg(&data[2 + signature_len + oem_id_len..])?; - let (root_path, root_path_len) = - parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len..])?; - let (parameter_path, parameter_path_len) = - parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len + root_path_len..])?; - let (parameter_data, parameter_data_len) = - parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len + root_path_len + - parameter_path_len..])?; + let signature = parse_term_arg(&data[2..], namespace, scope.clone())?; + let oem_id = parse_term_arg(&data[2 + signature.len..], namespace, scope.clone())?; + let oem_table_id = parse_term_arg(&data[2 + signature.len + oem_id.len..], namespace, scope.clone())?; + let root_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len..], namespace, scope.clone())?; + let parameter_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len..], namespace, scope.clone())?; + let parameter_data = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefLoadTable {signature, oem_id, oem_table_id, root_path, - parameter_path, parameter_data}, - 2 + signature_len + oem_id_len + oem_table_id_len + root_path_len + - parameter_path_len + parameter_data_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len + }) } -fn parse_def_match(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x89 { - return Err(AmlInternalError::AmlInvalidOpCode); - } - - let (search_pkg, search_pkg_len) = parse_term_arg(&data[1..])?; - let first_operation = match data[1 + search_pkg_len] { +fn parse_def_match(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate + // TODO: Clean up match blocks + parser_opcode!(data, 0x28); + + let search_pkg = parse_term_arg(&data[1..], namespace, scope.clone())?; + + let first_operation = match data[1 + search_pkg.len] { 0 => MatchOpcode::MTR, 1 => MatchOpcode::MEQ, 2 => MatchOpcode::MLE, 3 => MatchOpcode::MLT, 4 => MatchOpcode::MGE, 5 => MatchOpcode::MGT, - _ => return Err(AmlInternalError::AmlParseError("DefMatch - Invalid Opcode")) + _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode")) }; - let (first_operand, first_operand_len) = parse_term_arg(&data[2 + search_pkg_len..])?; + let first_operand = parse_term_arg(&data[2 + search_pkg.len..], namespace, scope.clone())?; - let second_operation = match data[2 + search_pkg_len + first_operand_len] { + let second_operation = match data[2 + search_pkg.len + first_operand.len] { 0 => MatchOpcode::MTR, 1 => MatchOpcode::MEQ, 2 => MatchOpcode::MLE, 3 => MatchOpcode::MLT, 4 => MatchOpcode::MGE, 5 => MatchOpcode::MGT, - _ => return Err(AmlInternalError::AmlParseError("DefMatch - Invalid Opcode")) + _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode")) }; - let (second_operand, second_operand_len) = - parse_term_arg(&data[3 + search_pkg_len + first_operand_len..])?; + let second_operand = parse_term_arg(&data[3 + search_pkg.len + first_operand.len..], namespace, scope.clone())?; + + let start_index = parse_term_arg(&data[3 + search_pkg.len + first_operand.len + second_operand.len..], namespace, scope.clone())?; - let (start_index, start_index_len) = - parse_term_arg(&data[3 + search_pkg_len + first_operand_len + second_operand_len..])?; - - Ok((Type2OpCode::DefMatch {search_pkg, first_operation, first_operand, - second_operation, second_operand, start_index}, - 3 + search_pkg_len + first_operand_len + second_operand_len + start_index_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len + }) } -fn parse_def_from_bcd(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x28 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_from_bcd(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + // TODO: Clean up match block + parser_opcode_extended!(data, 0x28); - let (operand, operand_len) = parse_term_arg(&data[2..])?; - let (target, target_len) = parse_target(&data[2 + operand_len..])?; + let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; + let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + + let result = match target.val.get_as_integer() { + Ok(i) => { + let mut i = i; + let mut ires = 0; - Ok((Type2OpCode::DefFromBCD {operand, target}, 2 + operand_len + target_len)) + while i != 0 { + if i & 0x0F > 10 { + return Err(AmlError::AmlValueError); + } + + ires *= 10; + ires += i & 0x0F; + i >>= 4; + } + + ires + }, + Err(e) => return Err(e) + }; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 2 + operand.len + target.len + }) } -fn parse_def_mid(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x9E { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_mid(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Compute the result + // TODO: Store the result, if appropriate + parser_opcode!(data, 0x9E); - let (source, source_len) = parse_term_arg(&data[1..])?; - let (index, index_len) = parse_term_arg(&data[1 + source_len..])?; - let (length, length_len) = parse_term_arg(&data[1 + source_len + index_len..])?; - let (target, target_len) = parse_target(&data[1 + source_len + index_len + length_len..])?; + let source = parse_term_arg(&data[1..], namespace, scope.clone())?; + let index = parse_term_arg(&data[1 + source.len..], namespace, scope.clone())?; + let length = parse_term_arg(&data[1 + source.len + index.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + source.len + index.len + length.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefMid {source, index, length, target}, - 1 + source_len + index_len + length_len + target_len)) + Ok(AmlParseType { + val: AmlValue::Uninitialized, + len: 1 + source.len + index.len + length.len + target.len + }) } -fn parse_def_mod(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x85 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_mod(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + // TODO: Fatal exception on rhs == 0 + parser_opcode!(data, 0x85); - let (dividend, dividend_len) = parse_term_arg(&data[1..])?; - let (divisor, divisor_len) = parse_term_arg(&data[1 + dividend_len..])?; - let (target, target_len) = parse_target(&data[1 + dividend_len + divisor_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefMod {dividend, divisor, target}, 1 + dividend_len + divisor_len + target_len)) + let result = lhs.val.get_as_integer()? % rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_multiply(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x77 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_multiply(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + // TODO: Handle overflow + parser_opcode!(data, 0x77); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefMultiply {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let result = lhs.val.get_as_integer()? * rhs.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_nand(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x7C { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_nand(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + parser_opcode!(data, 0x7C); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefNAnd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let result = !(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?); + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_nor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x7E { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_nor(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + parser_opcode!(data, 0x7E); - let (lhs, lhs_len) = parse_term_arg(&data[1..])?; - let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?; - let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?; + let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; + let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefNOr {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len)) + let result = !(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?); + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + lhs.len + rhs.len + target.len + }) } -fn parse_def_not(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x80 { - return Err(AmlInternalError::AmlInvalidOpCode); - } +fn parse_def_not(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Store the result, if appropriate + parser_opcode!(data, 0x80); - let (operand, operand_len) = parse_term_arg(&data[1..])?; - let (target, target_len) = parse_target(&data[1 + operand_len..])?; + let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; + let target = parse_target(&data[1 + operand.len..], namespace, scope.clone())?; - Ok((Type2OpCode::DefNot {operand, target}, 1 + operand_len + target_len)) + let result = !operand.val.get_as_integer()?; + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(result), + len: 1 + operand.len + target.len + }) } -fn parse_def_timer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> { - if data[0] != 0x5B || data[1] != 0x33 { - return Err(AmlInternalError::AmlInvalidOpCode) - } - - Ok((Type2OpCode::DefTimer, 2 as usize)) +fn parse_def_timer(data: &[u8], + namespace: &mut BTreeMap, + scope: String) -> ParseResult { + // TODO: Read from the hardware timer, and split into 100ns intervals + parser_opcode_extended!(data, 0x33); + + Ok(AmlParseType { + val: AmlValue::IntegerConstant(0), + len: 2 as usize + }) } diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs index ead12f5..51b4e96 100644 --- a/src/acpi/mod.rs +++ b/src/acpi/mod.rs @@ -211,9 +211,11 @@ fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { *namespace = Some(res); } }, - Err(AmlError::AmlParseError(e)) => { - println!(": {}", e); - } + Err(AmlError::AmlParseError(e)) => println!(": {}", e), + Err(AmlError::AmlInvalidOpCode) => println!(": Invalid opcode"), + Err(AmlError::AmlValueError) => println!(": Type constraints or value bounds not met"), + Err(AmlError::AmlDeferredLoad) => println!(": Deferred load reached top level"), + Err(AmlError::AmlFatalError(_, _, _)) => println!(": Fatal error occurred") }; } else { println!(": Unknown"); diff --git a/src/stop.rs b/src/stop.rs index 4f152bf..6dec9a1 100644 --- a/src/stop.rs +++ b/src/stop.rs @@ -13,7 +13,7 @@ pub unsafe extern fn kstop() -> ! { let mut val = 1 << 13; if let Some(ref namespace) = acpi.namespace { if let Some(s) = namespace.get("\\_S5") { - if let Some(p) = s.get_as_package() { + if let Ok(p) = s.get_as_package() { let slp_typa = p[0].get_as_integer().expect("SLP_TYPa is not an integer"); let slp_typb = p[1].get_as_integer().expect("SLP_TYPb is not an integer"); From 50ac9d3abed461f9265d5c5aa59d8793ff3583ca Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 3 Jul 2017 10:31:01 +0100 Subject: [PATCH 21/26] Added a context manager --- src/acpi/aml/dataobj.rs | 27 +-- src/acpi/aml/mod.rs | 15 +- src/acpi/aml/namedobj.rs | 294 +++++++++++----------- src/acpi/aml/namespace.rs | 1 + src/acpi/aml/namespacemodifier.rs | 44 ++-- src/acpi/aml/namestring.rs | 23 +- src/acpi/aml/parser.rs | 8 + src/acpi/aml/parsermacros.rs | 10 +- src/acpi/aml/termlist.rs | 35 ++- src/acpi/aml/type1opcode.rs | 91 +++---- src/acpi/aml/type2opcode.rs | 389 +++++++++++++----------------- 11 files changed, 425 insertions(+), 512 deletions(-) diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs index 77f7d2f..4025f7f 100644 --- a/src/acpi/aml/dataobj.rs +++ b/src/acpi/aml/dataobj.rs @@ -3,18 +3,17 @@ use collections::string::String; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult}; -use super::namespace::{AmlValue, ObjectReference}; +use super::parser::{ AmlParseType, ParseResult, AmlExecutionContext }; +use super::namespace::{ AmlValue, ObjectReference }; use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package}; use super::termlist::parse_term_arg; use super::namestring::parse_super_name; pub fn parse_data_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_computational_data, parse_def_package, parse_def_var_package @@ -24,15 +23,14 @@ pub fn parse_data_obj(data: &[u8], } pub fn parse_data_ref_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_data_obj, parse_term_arg }; - match parse_super_name(data, namespace, scope.clone()) { + match parse_super_name(data, ctx) { Ok(res) => match res.val { AmlValue::String(s) => Ok(AmlParseType { val: AmlValue::ObjectReference(ObjectReference::NamedObj(s)), @@ -45,8 +43,7 @@ pub fn parse_data_ref_obj(data: &[u8], } pub fn parse_arg_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { match data[0] { 0x68 ... 0x6E => Ok(AmlParseType { val: AmlValue::ObjectReference(ObjectReference::ArgObj(data[0] - 0x68)), @@ -57,8 +54,7 @@ pub fn parse_arg_obj(data: &[u8], } pub fn parse_local_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { match data[0] { 0x68 ... 0x6E => Ok(AmlParseType { val: AmlValue::ObjectReference(ObjectReference::LocalObj(data[0] - 0x60)), @@ -69,8 +65,7 @@ pub fn parse_local_obj(data: &[u8], } fn parse_computational_data(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { match data[0] { 0x0A => Ok(AmlParseType { val: AmlValue::Integer(data[1] as u64), @@ -148,6 +143,6 @@ fn parse_computational_data(data: &[u8], val: AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF), len: 9 as usize }), - _ => parse_def_buffer(data, namespace, scope.clone()) + _ => parse_def_buffer(data, ctx) } } diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index a113c0b..d20ce4c 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -24,7 +24,7 @@ mod type1opcode; mod type2opcode; mod parser; -use self::parser::ParseResult; +use self::parser::{ ParseResult, AmlExecutionContext }; use self::termlist::parse_term_list; pub use self::namespace::AmlValue; @@ -39,13 +39,14 @@ pub enum AmlError { pub fn parse_aml_table(sdt: &'static Sdt) -> Result, AmlError> { let data = sdt.data(); + let mut ctx = AmlExecutionContext { + namespace: &mut BTreeMap::new(), + scope: String::from_str("\\").unwrap() + }; + + let term_list = parse_term_list(data, &mut ctx)?; - let global_namespace_specifier = String::from_str("\\").unwrap(); - let mut global_namespace = BTreeMap::new(); - - let term_list = parse_term_list(data, &mut global_namespace, global_namespace_specifier.clone())?; - - Ok(global_namespace) + Ok(ctx.namespace.clone()) } pub fn is_aml_table(sdt: &'static Sdt) -> bool { diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index c521893..3c4605b 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -6,8 +6,8 @@ use core::str::FromStr; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; -use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; +use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext }; +use super::namespace::{ AmlValue, ObjectReference, FieldSelector, 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; @@ -87,10 +87,9 @@ pub enum AccessAttrib { } pub fn parse_named_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_def_bank_field, parse_def_create_bit_field, parse_def_create_byte_field, @@ -115,19 +114,17 @@ pub fn parse_named_obj(data: &[u8], } fn parse_def_bank_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Why isn't bank name used? parser_opcode_extended!(data, 0x87); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; let data = &data[2 + pkg_length_len .. 2 + pkg_length]; - let region_name = parse_name_string(data, namespace, scope.clone())?; - let bank_name = parse_name_string(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], namespace, scope.clone())?; + let region_name = parse_name_string(data, ctx)?; + let bank_name = parse_name_string(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], ctx)?; - let bank_value = parse_term_arg( - &data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], namespace, scope.clone())?; + let bank_value = parse_term_arg(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], ctx)?; let flags_raw = data[2 + pkg_length_len + region_name.len + bank_name.len + bank_value.len]; let mut flags = FieldFlags { @@ -156,7 +153,7 @@ fn parse_def_bank_field(data: &[u8], let field_list = parse_field_list( &data[3 + pkg_length_len + region_name.len + bank_name.len + bank_value.len .. - 2 + pkg_length], namespace, scope, selector, &mut flags)?; + 2 + pkg_length], ctx, selector, &mut flags)?; Ok(AmlParseType { val: AmlValue::None, @@ -165,17 +162,16 @@ fn parse_def_bank_field(data: &[u8], } fn parse_def_create_bit_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x8D); - let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; - let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; - let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + let source_buf = parse_term_arg(&data[2..], ctx)?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(1)) @@ -188,17 +184,16 @@ fn parse_def_create_bit_field(data: &[u8], } fn parse_def_create_byte_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x8C); - let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; - let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; - let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + let source_buf = parse_term_arg(&data[2..], ctx)?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(8)) @@ -211,17 +206,16 @@ fn parse_def_create_byte_field(data: &[u8], } fn parse_def_create_word_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x8B); - let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; - let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; - let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + let source_buf = parse_term_arg(&data[2..], ctx)?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(16)) @@ -234,17 +228,16 @@ fn parse_def_create_word_field(data: &[u8], } fn parse_def_create_dword_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x8A); - let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; - let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; - let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + let source_buf = parse_term_arg(&data[2..], ctx)?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(32)) @@ -257,17 +250,16 @@ fn parse_def_create_dword_field(data: &[u8], } fn parse_def_create_qword_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x8F); - let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; - let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; - let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], namespace, scope.clone())?; + let source_buf = parse_term_arg(&data[2..], ctx)?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?; + let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(AmlValue::IntegerConstant(64)) @@ -280,18 +272,17 @@ fn parse_def_create_qword_field(data: &[u8], } fn parse_def_create_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x13); - let source_buf = parse_term_arg(&data[2..], namespace, scope.clone())?; - let bit_index = parse_term_arg(&data[2 + source_buf.len..], namespace, scope.clone())?; - let num_bits = parse_term_arg(&data[2 + source_buf.len + bit_index.len..], namespace, scope.clone())?; - let name = parse_name_string(&data[2 + source_buf.len + bit_index.len + num_bits.len..], namespace, scope.clone())?; + let source_buf = parse_term_arg(&data[2..], ctx)?; + let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?; + let num_bits = parse_term_arg(&data[2 + source_buf.len + bit_index.len..], ctx)?; + let name = parse_name_string(&data[2 + source_buf.len + bit_index.len + num_bits.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::BufferField { + ctx.namespace.insert(local_scope_string, AmlValue::BufferField { source_buf: Box::new(source_buf.val), index: Box::new(bit_index.val), length: Box::new(num_bits.val) @@ -304,19 +295,18 @@ fn parse_def_create_field(data: &[u8], } fn parse_def_data_region(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Find the actual offset and length, once table mapping is implemented parser_opcode_extended!(data, 0x88); - let name = parse_name_string(&data[2..], namespace, scope.clone())?; - let signature = parse_term_arg(&data[2 + name.len..], namespace, scope.clone())?; - let oem_id = parse_term_arg(&data[2 + name.len + signature.len..], namespace, scope.clone())?; - let oem_table_id = parse_term_arg(&data[2 + name.len + signature.len + oem_id.len..], namespace, scope.clone())?; - - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let name = parse_name_string(&data[2..], ctx)?; + let signature = parse_term_arg(&data[2 + name.len..], ctx)?; + let oem_id = parse_term_arg(&data[2 + name.len + signature.len..], ctx)?; + let oem_table_id = parse_term_arg(&data[2 + name.len + signature.len + oem_id.len..], ctx)?; - namespace.insert(local_scope_string, AmlValue::OperationRegion { + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + + ctx.namespace.insert(local_scope_string, AmlValue::OperationRegion { region: RegionSpace::SystemMemory, offset: Box::new(AmlValue::IntegerConstant(0)), len: Box::new(AmlValue::IntegerConstant(0)) @@ -329,14 +319,13 @@ fn parse_def_data_region(data: &[u8], } fn parse_def_event(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x02); - let name = parse_name_string(&data[2..], namespace, scope.clone())?; + let name = parse_name_string(&data[2..], ctx)?; - let local_scope_string = get_namespace_string(scope, name.val); - namespace.insert(local_scope_string, AmlValue::Event); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + ctx.namespace.insert(local_scope_string, AmlValue::Event); Ok(AmlParseType { val: AmlValue::None, @@ -345,18 +334,23 @@ fn parse_def_event(data: &[u8], } fn parse_def_device(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { + // TODO: How to handle local context deferreds + // TODO: How to also handle local context reference to calling context parser_opcode_extended!(data, 0x82); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], namespace, scope.clone())?; - - let mut local_namespace = BTreeMap::new(); - let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_namespace, String::new())?; + let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?; - let local_scope_string = get_namespace_string(scope, name.val); - namespace.insert(local_scope_string, AmlValue::Device(local_namespace)); + let mut local_ctx = AmlExecutionContext { + namespace: &mut BTreeMap::new(), + scope: String::new() + }; + + let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?; + + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + ctx.namespace.insert(local_scope_string, AmlValue::Device(local_ctx.namespace.clone())); Ok(AmlParseType { val: AmlValue::None, @@ -365,11 +359,10 @@ fn parse_def_device(data: &[u8], } fn parse_def_op_region(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x80); - let name = parse_name_string(&data[2..], namespace, scope.clone())?; + let name = parse_name_string(&data[2..], ctx)?; let region = match data[2 + name.len] { 0x00 => RegionSpace::SystemMemory, 0x01 => RegionSpace::SystemIO, @@ -385,11 +378,11 @@ fn parse_def_op_region(data: &[u8], _ => return Err(AmlError::AmlParseError("OpRegion - invalid region")) }; - let offset = parse_term_arg(&data[3 + name.len..], namespace, scope.clone())?; - let len = parse_term_arg(&data[3 + name.len + offset.len..], namespace, scope.clone())?; + let offset = parse_term_arg(&data[3 + name.len..], ctx)?; + let len = parse_term_arg(&data[3 + name.len + offset.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::OperationRegion { + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + ctx.namespace.insert(local_scope_string, AmlValue::OperationRegion { region: region, offset: Box::new(offset.val), len: Box::new(len.val) @@ -402,12 +395,11 @@ fn parse_def_op_region(data: &[u8], } fn parse_def_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x81); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], namespace, scope.clone())?; + let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?; let flags_raw = data[2 + pkg_length_len + name.len]; let mut flags = FieldFlags { @@ -431,7 +423,7 @@ fn parse_def_field(data: &[u8], let selector = FieldSelector::Region(name.val.get_as_string()?); - let field_list = parse_field_list(&data[3 + pkg_length_len + name.len .. 2 + pkg_length], namespace, scope, selector, &mut flags)?; + let field_list = parse_field_list(&data[3 + pkg_length_len + name.len .. 2 + pkg_length], ctx, selector, &mut flags)?; Ok(AmlParseType { val: AmlValue::None, @@ -440,13 +432,12 @@ fn parse_def_field(data: &[u8], } fn parse_def_index_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x86); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; - let idx_name = parse_name_string( &data[2 + pkg_length_len .. 2 + pkg_length], namespace, scope.clone())?; - let data_name = parse_name_string(&data[2 + pkg_length_len + idx_name.len .. 2 + pkg_length], namespace, scope.clone())?; + let idx_name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?; + let data_name = parse_name_string(&data[2 + pkg_length_len + idx_name.len .. 2 + pkg_length], ctx)?; let flags_raw = data[2 + pkg_length_len + idx_name.len + data_name.len]; let mut flags = FieldFlags { @@ -474,7 +465,7 @@ fn parse_def_index_field(data: &[u8], }; let field_list = parse_field_list( - &data[3 + pkg_length_len + idx_name.len + data_name.len .. 2 + pkg_length], namespace, scope, selector, &mut flags)?; + &data[3 + pkg_length_len + idx_name.len + data_name.len .. 2 + pkg_length], ctx, selector, &mut flags)?; Ok(AmlParseType { val: AmlValue::None, @@ -483,21 +474,14 @@ fn parse_def_index_field(data: &[u8], } fn parse_field_list(data: &[u8], - namespace: &mut BTreeMap, - scope: String, + ctx: &mut AmlExecutionContext, selector: FieldSelector, flags: &mut FieldFlags) -> ParseResult { let mut current_offset: usize = 0; let mut connection = AmlValue::Uninitialized; while current_offset < data.len() { - match parse_field_element(&data[current_offset..], namespace, scope.clone(), selector.clone(), - &mut connection, flags, &mut current_offset) { - Ok(_) => (), - Err(AmlError::AmlInvalidOpCode) => - return Err(AmlError::AmlParseError("FieldList - no valid field")), - Err(e) => return Err(e) - } + parse_field_element(&data[current_offset..], ctx, selector.clone(), &mut connection, flags, &mut current_offset)?; } Ok(AmlParseType { @@ -507,16 +491,15 @@ fn parse_field_list(data: &[u8], } fn parse_field_element(data: &[u8], - namespace: &mut BTreeMap, - scope: String, + ctx: &mut AmlExecutionContext, selector: FieldSelector, connection: &mut AmlValue, flags: &mut FieldFlags, offset: &mut usize) -> ParseResult { - let length = if let Ok(field) = parse_named_field(data, namespace, scope.clone()) { - let local_scope_string = get_namespace_string(scope.clone(), AmlValue::String(field.val.name.clone())); + let length = if let Ok(field) = parse_named_field(data, ctx) { + let local_scope_string = get_namespace_string(ctx.scope.clone(), AmlValue::String(field.val.name.clone())); - namespace.insert(local_scope_string, AmlValue::FieldUnit { + ctx.namespace.insert(local_scope_string, AmlValue::FieldUnit { selector: selector.clone(), connection: Box::new(connection.clone()), flags: flags.clone(), @@ -525,10 +508,10 @@ fn parse_field_element(data: &[u8], }); field.len - } else if let Ok(field) = parse_reserved_field(data, namespace, scope.clone()) { + } else if let Ok(field) = parse_reserved_field(data, ctx) { *offset += field.val; field.len - } else if let Ok(field) = parse_access_field(data, namespace, scope.clone()) { + } else if let Ok(field) = parse_access_field(data, ctx) { match field.val.access_type { AccessType::BufferAcc(_) => flags.access_type = AccessType::BufferAcc(field.val.access_attrib.clone()), @@ -536,7 +519,7 @@ fn parse_field_element(data: &[u8], } field.len - } else if let Ok(field) = parse_connect_field(data, namespace, scope.clone()) { + } else if let Ok(field) = parse_connect_field(data, ctx) { *connection = field.val.clone(); field.len } else { @@ -550,8 +533,7 @@ fn parse_field_element(data: &[u8], } fn parse_named_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> Result, AmlError> { + ctx: &mut AmlExecutionContext) -> Result, AmlError> { let (name_seg, name_seg_len) = parse_name_seg(&data[0..4])?; let name = match String::from_utf8(name_seg) { Ok(s) => s, @@ -566,8 +548,7 @@ fn parse_named_field(data: &[u8], } fn parse_reserved_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> Result, AmlError> { + ctx: &mut AmlExecutionContext) -> Result, AmlError> { parser_opcode!(data, 0x00); let (length, length_len) = parse_pkg_length(&data[1..])?; @@ -578,8 +559,7 @@ fn parse_reserved_field(data: &[u8], } fn parse_access_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> Result, AmlError> { + ctx: &mut AmlExecutionContext) -> Result, AmlError> { parser_opcode!(data, 0x01, 0x03); let flags_raw = data[1]; @@ -625,17 +605,16 @@ fn parse_access_field(data: &[u8], } fn parse_connect_field(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x02); - if let Ok(e) = parse_def_buffer(&data[1..], namespace, scope.clone()) { + if let Ok(e) = parse_def_buffer(&data[1..], ctx) { Ok(AmlParseType { val: e.val, len: e.len + 1 }) } else { - let name = parse_name_string(&data[1..], namespace, scope.clone())?; + let name = parse_name_string(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::ObjectReference(ObjectReference::NamedObj(name.val.get_as_string()?)), len: name.len + 1 @@ -644,12 +623,11 @@ fn parse_connect_field(data: &[u8], } fn parse_def_method(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x14); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[1..])?; - let name = parse_name_string(&data[1 + pkg_len_len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + pkg_len_len..], ctx)?; let flags = data[1 + pkg_len_len + name.len]; let arg_count = flags & 0x07; @@ -658,8 +636,8 @@ fn parse_def_method(data: &[u8], let term_list = &data[2 + pkg_len_len + name.len .. 1 + pkg_len]; - let local_scope_string = get_namespace_string(scope.clone(), name.val); - namespace.insert(local_scope_string, AmlValue::Method(Method { + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + ctx.namespace.insert(local_scope_string, AmlValue::Method(Method { arg_count, serialized, sync_level, @@ -673,16 +651,15 @@ fn parse_def_method(data: &[u8], } fn parse_def_mutex(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x01); - let name = parse_name_string(&data[2 ..], namespace, scope.clone())?; + let name = parse_name_string(&data[2 ..], ctx)?; let flags = data[2 + name.len]; let sync_level = flags & 0x0F; - let local_scope_string = get_namespace_string(scope, name.val); - namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + ctx.namespace.insert(local_scope_string, AmlValue::Mutex(sync_level)); Ok(AmlParseType { val: AmlValue::None, @@ -691,26 +668,31 @@ fn parse_def_mutex(data: &[u8], } fn parse_def_power_res(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { + // TODO: How to handle local context deferreds + // TODO: How to also handle local context reference to calling context parser_opcode_extended!(data, 0x84); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?; - let name = parse_name_string(&data[2 + pkg_len_len..], namespace, scope.clone())?; + let name = parse_name_string(&data[2 + pkg_len_len..], ctx)?; - let local_scope_string = get_namespace_string(scope, name.val); - let mut local_namespace = BTreeMap::new(); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); let system_level = data[2 + pkg_len_len + name.len]; let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) + ((data[4 + pkg_len_len + name.len] as u16) << 8); - parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_namespace, String::new())?; + let mut local_ctx = AmlExecutionContext { + namespace: &mut BTreeMap::new(), + scope: String::new() + }; + + parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; - namespace.insert(local_scope_string, AmlValue::PowerResource { + ctx.namespace.insert(local_scope_string, AmlValue::PowerResource { system_level, resource_order, - obj_list: local_namespace + obj_list: local_ctx.namespace.clone() }); Ok(AmlParseType { @@ -720,15 +702,13 @@ fn parse_def_power_res(data: &[u8], } fn parse_def_processor(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x83); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?; - let name = parse_name_string(&data[2 + pkg_len_len..], namespace, scope.clone())?; + let name = parse_name_string(&data[2 + pkg_len_len..], ctx)?; - let local_scope_string = get_namespace_string(scope, name.val); - let mut local_namespace = BTreeMap::new(); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); let proc_id = data[2 + pkg_len_len + name.len]; let p_blk_addr: u32 = (data[3 + pkg_len_len + name.len] as u32) + @@ -737,12 +717,17 @@ fn parse_def_processor(data: &[u8], ((data[6 + pkg_len_len + name.len] as u32) << 24); let p_blk_len = data[7 + pkg_len_len + name.len]; - parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_namespace, String::new())?; + let mut local_ctx = AmlExecutionContext { + namespace: &mut BTreeMap::new(), + scope: String::new() + }; - namespace.insert(local_scope_string, AmlValue::Processor { + parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; + + ctx.namespace.insert(local_scope_string, AmlValue::Processor { proc_id: proc_id, p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None }, - obj_list: local_namespace + obj_list: local_ctx.namespace.clone() }); Ok(AmlParseType { @@ -752,19 +737,22 @@ fn parse_def_processor(data: &[u8], } fn parse_def_thermal_zone(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x85); let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?; - let name = parse_name_string(&data[2 + pkg_len_len .. 2 + pkg_len], namespace, scope.clone())?; + let name = parse_name_string(&data[2 + pkg_len_len .. 2 + pkg_len], ctx)?; - let local_scope_string = get_namespace_string(scope, name.val); - let mut local_namespace = BTreeMap::new(); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + + let mut local_ctx = AmlExecutionContext { + namespace: &mut BTreeMap::new(), + scope: String::new() + }; - parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_namespace, String::new())?; + parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; - namespace.insert(local_scope_string, AmlValue::ThermalZone(local_namespace)); + ctx.namespace.insert(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace.clone())); Ok(AmlParseType { val: AmlValue::None, diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index d2ac417..54cef02 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -6,6 +6,7 @@ use collections::btree_map::BTreeMap; use core::str::FromStr; use super::namedobj::{ RegionSpace, FieldFlags, Method }; +use super::parser::AmlExecutionContext; use super::AmlError; #[derive(Debug, Clone)] diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index b04d405..35cd1a3 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -4,7 +4,7 @@ use collections::vec::Vec; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext}; use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; use super::pkglength::parse_pkg_length; use super::namestring::parse_name_string; @@ -12,10 +12,9 @@ use super::termlist::parse_term_list; use super::dataobj::parse_data_ref_obj; pub fn parse_namespace_modifier(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_alias_op, parse_scope_op, parse_name_op @@ -25,17 +24,16 @@ pub fn parse_namespace_modifier(data: &[u8], } fn parse_alias_op(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x06); - let source_name = parse_name_string(&data[1..], namespace, scope.clone())?; - let alias_name = parse_name_string(&data[1 + source_name.len..], namespace, scope.clone())?; + let source_name = parse_name_string(&data[1..], ctx)?; + let alias_name = parse_name_string(&data[1 + source_name.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), source_name.val); - let local_alias_string = get_namespace_string(scope.clone(), alias_name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), source_name.val); + let local_alias_string = get_namespace_string(ctx.scope.clone(), alias_name.val); - namespace.insert(local_scope_string, AmlValue::ObjectReference( + ctx.namespace.insert(local_scope_string, AmlValue::ObjectReference( ObjectReference::NamedObj(local_alias_string))); Ok(AmlParseType { @@ -45,16 +43,15 @@ fn parse_alias_op(data: &[u8], } fn parse_name_op(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x08); - let name = parse_name_string(&data[1..], namespace, scope.clone())?; - let data_ref_obj = parse_data_ref_obj(&data[1 + name.len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1..], ctx)?; + let data_ref_obj = parse_data_ref_obj(&data[1 + name.len..], ctx)?; - let local_scope_string = get_namespace_string(scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - namespace.insert(local_scope_string, data_ref_obj.val); + ctx.namespace.insert(local_scope_string, data_ref_obj.val); Ok(AmlParseType { val: AmlValue::None, @@ -63,15 +60,18 @@ fn parse_name_op(data: &[u8], } fn parse_scope_op(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x10); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let name = parse_name_string(&data[1 + pkg_length_len..], namespace, scope.clone())?; + let name = parse_name_string(&data[1 + pkg_length_len..], ctx)?; - let local_scope_string = get_namespace_string(scope, name.val); - parse_term_list(&data[1 + pkg_length_len + name.len..], namespace, local_scope_string)?; + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + let containing_scope_string = ctx.scope.clone(); + + ctx.scope = local_scope_string; + parse_term_list(&data[1 + pkg_length_len + name.len..], ctx)?; + ctx.scope = containing_scope_string; Ok(AmlParseType { val: AmlValue::None, diff --git a/src/acpi/aml/namestring.rs b/src/acpi/aml/namestring.rs index ccbdcce..e63a9b0 100644 --- a/src/acpi/aml/namestring.rs +++ b/src/acpi/aml/namestring.rs @@ -3,14 +3,13 @@ use collections::string::String; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext}; use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; use super::dataobj::{parse_arg_obj, parse_local_obj}; use super::type2opcode::parse_type6_opcode; pub fn parse_name_string(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { let mut characters: Vec = vec!(); let mut starting_index: usize = 0; @@ -142,10 +141,9 @@ fn parse_multi_name_path(data: &[u8]) -> Result<(Vec, usize), AmlError> { } pub fn parse_super_name(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_simple_name, parse_type6_opcode, parse_debug_obj @@ -155,8 +153,7 @@ pub fn parse_super_name(data: &[u8], } fn parse_debug_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x31); Ok(AmlParseType { @@ -166,10 +163,9 @@ fn parse_debug_obj(data: &[u8], } pub fn parse_simple_name(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_name_string, parse_arg_obj, parse_local_obj @@ -179,14 +175,13 @@ pub fn parse_simple_name(data: &[u8], } pub fn parse_target(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { if data[0] == 0x00 { Ok(AmlParseType { val: AmlValue::None, len: 1 as usize }) } else { - parse_super_name(data, namespace, scope.clone()) + parse_super_name(data, ctx) } } diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 080a1ae..b316319 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -1,3 +1,6 @@ +use collections::string::String; +use collections::btree_map::BTreeMap; + use super::namespace::AmlValue; use super::AmlError; @@ -8,3 +11,8 @@ pub struct AmlParseTypeGeneric { pub val: T, pub len: usize } + +pub struct AmlExecutionContext<'a> { + pub namespace: &'a mut BTreeMap, + pub scope: String +} diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs index 6b9555a..3f8cf61 100644 --- a/src/acpi/aml/parsermacros.rs +++ b/src/acpi/aml/parsermacros.rs @@ -1,15 +1,15 @@ #[macro_export] macro_rules! parser_selector { - {$data:expr, $namespace:expr, $scope:expr, $func:expr} => { - match $func($data, $namespace, $scope) { + {$data:expr, $ctx:expr, $func:expr} => { + match $func($data, $ctx) { Ok(res) => return Ok(res), Err(AmlError::AmlInvalidOpCode) => (), Err(e) => return Err(e) } }; - {$data:expr, $namespace:expr, $scope:expr, $func:expr, $($funcs:expr),+} => { - parser_selector! {$data, $namespace, $scope, $func}; - parser_selector! {$data, $namespace, $scope, $($funcs),*}; + {$data:expr, $ctx:expr, $func:expr, $($funcs:expr),+} => { + parser_selector! {$data, $ctx, $func}; + parser_selector! {$data, $ctx, $($funcs),*}; }; } diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index bc2a747..bbce0e4 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -4,7 +4,7 @@ use collections::vec::Vec; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult, AmlParseTypeGeneric}; +use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext }; use super::namespace::{AmlValue, ObjectReference, FieldSelector, get_namespace_string}; use super::namespacemodifier::parse_namespace_modifier; use super::namedobj::parse_named_obj; @@ -14,12 +14,11 @@ use super::type2opcode::parse_type2_opcode; use super::namestring::parse_name_string; pub fn parse_term_list(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { let mut current_offset: usize = 0; while current_offset < data.len() { - let res = parse_term_obj(&data[current_offset..], namespace, scope.clone())?; + let res = parse_term_obj(&data[current_offset..], ctx)?; current_offset += res.len; } @@ -30,10 +29,9 @@ pub fn parse_term_list(data: &[u8], } pub fn parse_term_arg(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_local_obj, parse_data_obj, parse_arg_obj, @@ -44,12 +42,11 @@ pub fn parse_term_arg(data: &[u8], } pub fn parse_object_list(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { let mut current_offset: usize = 0; while current_offset < data.len() { - let res = parse_object(&data[current_offset..], namespace, scope.clone())?; + let res = parse_object(&data[current_offset..], ctx)?; current_offset += res.len; } @@ -60,10 +57,9 @@ pub fn parse_object_list(data: &[u8], } fn parse_object(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_namespace_modifier, parse_named_obj }; @@ -72,17 +68,18 @@ fn parse_object(data: &[u8], } pub fn parse_method_invocation(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { - let name = parse_name_string(data, namespace, scope)?; + ctx: &mut AmlExecutionContext) -> ParseResult { + // 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)?; Err(AmlError::AmlDeferredLoad) } fn parse_term_obj(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_namespace_modifier, parse_named_obj, parse_type1_opcode, diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index b32acf8..7bc9546 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -4,17 +4,16 @@ use collections::vec::Vec; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult}; +use super::parser::{AmlParseType, ParseResult, AmlExecutionContext}; 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}; pub fn parse_type1_opcode(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_def_break, parse_def_breakpoint, parse_def_continue, @@ -37,8 +36,7 @@ pub fn parse_type1_opcode(data: &[u8], } fn parse_def_break(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Implement parser_opcode!(data, 0xA5); @@ -49,8 +47,7 @@ fn parse_def_break(data: &[u8], } fn parse_def_breakpoint(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Implement parser_opcode!(data, 0xCC); @@ -61,8 +58,7 @@ fn parse_def_breakpoint(data: &[u8], } fn parse_def_continue(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Implement parser_opcode!(data, 0x9F); @@ -73,8 +69,7 @@ fn parse_def_continue(data: &[u8], } fn parse_def_noop(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0xA3); Ok(AmlParseType { @@ -84,27 +79,25 @@ fn parse_def_noop(data: &[u8], } fn parse_def_fatal(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode_extended!(data, 0x32); let fatal_type = data[2]; let fatal_code: u16 = (data[3] as u16) + ((data[4] as u16) << 8); - let fatal_arg = parse_term_arg(&data[5..], namespace, scope.clone())?; + let fatal_arg = parse_term_arg(&data[5..], ctx)?; Err(AmlError::AmlFatalError(fatal_type, fatal_code, fatal_arg.val)) } fn parse_def_load(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // 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..], namespace, scope.clone())?; - let ddb_handle_object = parse_super_name(&data[2 + name.len..], namespace, scope.clone())?; + 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, @@ -113,13 +106,12 @@ fn parse_def_load(data: &[u8], } fn parse_def_notify(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: This requires significantly more infrastructure from the OS itself, see 5.6.6 parser_opcode!(data, 0x86); - let object = parse_super_name(&data[1..], namespace, scope.clone())?; - let value = parse_term_arg(&data[1 + object.len..], namespace, scope.clone())?; + let object = parse_super_name(&data[1..], ctx)?; + let value = parse_term_arg(&data[1 + object.len..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -128,14 +120,13 @@ fn parse_def_notify(data: &[u8], } fn parse_def_release(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Check ownership of the mutex pointed to // TODO: FATAL if not owned // TODO: Release if it is parser_opcode_extended!(data, 0x27); - let object = parse_super_name(&data[2..], namespace, scope.clone())?; + let object = parse_super_name(&data[2..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -144,12 +135,11 @@ fn parse_def_release(data: &[u8], } fn parse_def_reset(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: object (of type Event) is a semaphore. Reset the resource count to 0 parser_opcode_extended!(data, 0x26); - let object = parse_super_name(&data[2..], namespace, scope.clone())?; + let object = parse_super_name(&data[2..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -158,12 +148,11 @@ fn parse_def_reset(data: &[u8], } fn parse_def_signal(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Increment the resource count of the semaphore parser_opcode_extended!(data, 0x24); - let object = parse_super_name(&data[2..], namespace, scope.clone())?; + let object = parse_super_name(&data[2..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -172,12 +161,11 @@ fn parse_def_signal(data: &[u8], } fn parse_def_sleep(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Sleep the processor for the specified number of milliseconds (minimum) parser_opcode_extended!(data, 0x22); - let time = parse_term_arg(&data[2..], namespace, scope.clone())?; + let time = parse_term_arg(&data[2..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -186,12 +174,11 @@ fn parse_def_sleep(data: &[u8], } fn parse_def_stall(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Sleep the processor for the specified number of microseconds (minimum) parser_opcode_extended!(data, 0x21); - let time = parse_term_arg(&data[2..], namespace, scope.clone())?; + let time = parse_term_arg(&data[2..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -200,13 +187,12 @@ fn parse_def_stall(data: &[u8], } fn parse_def_unload(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // 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..], namespace, scope.clone())?; + let object = parse_super_name(&data[2..], ctx)?; Ok(AmlParseType { val: AmlValue::None, @@ -215,12 +201,11 @@ fn parse_def_unload(data: &[u8], } fn parse_def_if_else(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0xA0); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let if_condition = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], namespace, scope.clone())?; + let if_condition = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?; let (else_length, else_length_len) = if data.len() > 1 + pkg_length && data[1 + pkg_length] == 0xA1 { parse_pkg_length(&data[2 + pkg_length..])? @@ -229,11 +214,9 @@ fn parse_def_if_else(data: &[u8], }; if if_condition.val.get_as_integer()? > 0 { - parse_term_list(&data[1 + pkg_length_len + if_condition.len .. 1 + pkg_length], - namespace, scope.clone())?; + parse_term_list(&data[1 + pkg_length_len + if_condition.len .. 1 + pkg_length], ctx)?; } else if else_length > 0 { - parse_term_list(&data[2 + pkg_length + else_length_len .. 2 + pkg_length + else_length], - namespace, scope.clone())?; + parse_term_list(&data[2 + pkg_length + else_length_len .. 2 + pkg_length + else_length], ctx)?; } Ok(AmlParseType { @@ -243,19 +226,18 @@ fn parse_def_if_else(data: &[u8], } fn parse_def_while(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0xA2); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; loop { - let predicate = parse_term_arg(&data[1 + pkg_length_len..], namespace, scope.clone())?; + let predicate = parse_term_arg(&data[1 + pkg_length_len..], ctx)?; if predicate.val.get_as_integer()? == 0 { break; } - parse_term_list(&data[1 + pkg_length_len + predicate.len .. 1 + pkg_length], namespace, scope.clone())?; + parse_term_list(&data[1 + pkg_length_len + predicate.len .. 1 + pkg_length], ctx)?; } Ok(AmlParseType { @@ -265,13 +247,12 @@ fn parse_def_while(data: &[u8], } fn parse_def_return(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Return to the calling context // TODO: We need contexts for that parser_opcode!(data, 0xA4); - let arg_object = parse_term_arg(&data[1..], namespace, scope.clone())?; + let arg_object = parse_term_arg(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::None, diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index eef85e1..0685251 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -4,7 +4,7 @@ use collections::vec::Vec; use collections::btree_map::BTreeMap; use super::AmlError; -use super::parser::{AmlParseType, ParseResult}; +use super::parser::{AmlParseType, ParseResult, AmlExecutionContext}; use super::namespace::{AmlValue, ObjectReference}; use super::pkglength::parse_pkg_length; use super::termlist::{parse_term_arg, parse_method_invocation}; @@ -22,10 +22,9 @@ pub enum MatchOpcode { } pub fn parse_type2_opcode(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_def_increment, parse_def_acquire, parse_def_wait, @@ -82,10 +81,9 @@ pub fn parse_type2_opcode(data: &[u8], } pub fn parse_type6_opcode(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_def_deref_of, parse_def_ref_of, parse_def_index, @@ -96,11 +94,10 @@ pub fn parse_type6_opcode(data: &[u8], } pub fn parse_def_object_type(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x8E); parser_selector! { - data, namespace, scope.clone(), + data, ctx, parse_super_name, parse_def_ref_of, parse_def_deref_of, @@ -111,16 +108,14 @@ pub fn parse_def_object_type(data: &[u8], } pub fn parse_def_package(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Handle deferred loads in here // TODO: Truncate/extend array if necessary parser_opcode!(data, 0x12); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; let num_elements = data[1 + pkg_length_len]; - let elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], - namespace, scope.clone())?; + let elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], ctx)?; Ok(AmlParseType { val: elements.val, @@ -129,16 +124,15 @@ pub fn parse_def_package(data: &[u8], } pub fn parse_def_var_package(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Handle deferred loads in here // TODO: Truncate/extend array if necessary parser_opcode!(data, 0x13); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let num_elements = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], namespace, scope.clone())?; + let num_elements = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?; let elements = parse_package_elements_list(&data[1 + pkg_length_len + num_elements.len .. - 1 + pkg_length], namespace, scope.clone())?; + 1 + pkg_length], ctx)?; Ok(AmlParseType { val: elements.val, @@ -147,16 +141,15 @@ pub fn parse_def_var_package(data: &[u8], } fn parse_package_elements_list(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { let mut current_offset: usize = 0; let mut elements: Vec = vec!(); while current_offset < data.len() { - let dro = if let Ok(e) = parse_data_ref_obj(&data[current_offset..], namespace, scope.clone()) { + let dro = if let Ok(e) = parse_data_ref_obj(&data[current_offset..], ctx) { e } else { - parse_name_string(&data[current_offset..], namespace, scope.clone())? + parse_name_string(&data[current_offset..], ctx)? }; elements.push(dro.val); @@ -170,13 +163,12 @@ fn parse_package_elements_list(data: &[u8], } pub fn parse_def_buffer(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Perform computation parser_opcode!(data, 0x11); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let buffer_size = parse_term_arg(&data[1 + pkg_length_len..], namespace, scope.clone())?; + let buffer_size = parse_term_arg(&data[1 + pkg_length_len..], ctx)?; let byte_list = data[1 + pkg_length_len + buffer_size.len .. 1 + pkg_length].to_vec(); Ok(AmlParseType { @@ -186,12 +178,11 @@ pub fn parse_def_buffer(data: &[u8], } fn parse_def_ref_of(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Perform computation parser_opcode!(data, 0x71); - let obj = parse_super_name(&data[1..], namespace, scope.clone())?; + let obj = parse_super_name(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -200,12 +191,11 @@ fn parse_def_ref_of(data: &[u8], } fn parse_def_deref_of(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Perform computation parser_opcode!(data, 0x83); - let obj = parse_term_arg(&data[1..], namespace, scope.clone())?; + let obj = parse_term_arg(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -214,13 +204,12 @@ fn parse_def_deref_of(data: &[u8], } fn parse_def_acquire(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result // TODO: Perform computation parser_opcode_extended!(data, 0x23); - let obj = parse_super_name(&data[1..], namespace, scope.clone())?; + let obj = parse_super_name(&data[1..], ctx)?; let timeout = (data[2 + obj.len] as u16) + ((data[3 + obj.len] as u16) << 8); Ok(AmlParseType { @@ -230,13 +219,12 @@ fn parse_def_acquire(data: &[u8], } fn parse_def_increment(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result // TODO: Perform computation parser_opcode!(data, 0x75); - let obj = parse_super_name(&data[1..], namespace, scope.clone())?; + let obj = parse_super_name(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -245,15 +233,14 @@ fn parse_def_increment(data: &[u8], } fn parse_def_index(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate // TODO: Perform computation parser_opcode!(data, 0x88); - let obj = parse_term_arg(&data[1..], namespace, scope.clone())?; - let idx = parse_term_arg(&data[1 + obj.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + obj.len + idx.len..], namespace, scope.clone())?; + let obj = parse_term_arg(&data[1..], ctx)?; + let idx = parse_term_arg(&data[1 + obj.len..], ctx)?; + let target = parse_target(&data[1 + obj.len + idx.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -262,12 +249,11 @@ fn parse_def_index(data: &[u8], } fn parse_def_land(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x90); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let result = if lhs.val.get_as_integer()? > 0 && rhs.val.get_as_integer()? > 0 { 1 } else { 0 }; @@ -278,12 +264,11 @@ fn parse_def_land(data: &[u8], } fn parse_def_lequal(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x93); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let result = if lhs.val.get_as_integer()? == rhs.val.get_as_integer()? { 1 } else { 0 }; @@ -294,12 +279,11 @@ fn parse_def_lequal(data: &[u8], } fn parse_def_lgreater(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x94); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let result = if lhs.val.get_as_integer()? > rhs.val.get_as_integer()? { 1 } else { 0 }; @@ -310,12 +294,11 @@ fn parse_def_lgreater(data: &[u8], } fn parse_def_lless(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x95); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let result = if lhs.val.get_as_integer()? < rhs.val.get_as_integer()? { 1 } else { 0 }; @@ -326,11 +309,10 @@ fn parse_def_lless(data: &[u8], } fn parse_def_lnot(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x92); - let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[1..], ctx)?; let result = if operand.val.get_as_integer()? == 0 { 1 } else { 0 }; Ok(AmlParseType { @@ -340,12 +322,11 @@ fn parse_def_lnot(data: &[u8], } fn parse_def_lor(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { parser_opcode!(data, 0x91); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let result = if lhs.val.get_as_integer()? > 0 || rhs.val.get_as_integer()? > 0 { 1 } else { 0 }; @@ -356,14 +337,13 @@ fn parse_def_lor(data: &[u8], } fn parse_def_to_hex_string(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x98); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -372,14 +352,13 @@ fn parse_def_to_hex_string(data: &[u8], } fn parse_def_to_buffer(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x96); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -388,14 +367,13 @@ fn parse_def_to_buffer(data: &[u8], } fn parse_def_to_bcd(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode_extended!(data, 0x29); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -404,14 +382,13 @@ fn parse_def_to_bcd(data: &[u8], } fn parse_def_to_decimal_string(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x97); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -420,14 +397,13 @@ fn parse_def_to_decimal_string(data: &[u8], } fn parse_def_to_integer(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x99); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -436,15 +412,14 @@ fn parse_def_to_integer(data: &[u8], } fn parse_def_to_string(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x9C); - let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; - let length = parse_term_arg(&data[1 + operand.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + operand.len + length.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[1..], ctx)?; + let length = parse_term_arg(&data[1 + operand.len..], ctx)?; + let target = parse_target(&data[1 + operand.len + length.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -453,14 +428,13 @@ fn parse_def_to_string(data: &[u8], } fn parse_def_subtract(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x74); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? - rhs.val.get_as_integer()?; @@ -471,12 +445,11 @@ fn parse_def_subtract(data: &[u8], } fn parse_def_size_of(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Perform the computation parser_opcode!(data, 0x87); - let name = parse_super_name(&data[1..], namespace, scope.clone())?; + let name = parse_super_name(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -485,13 +458,12 @@ fn parse_def_size_of(data: &[u8], } fn parse_def_store(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Perform the store parser_opcode!(data, 0x70); - let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; - let target = parse_super_name(&data[1 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[1..], ctx)?; + let target = parse_super_name(&data[1 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -500,14 +472,13 @@ fn parse_def_store(data: &[u8], } fn parse_def_or(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x7D); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? | rhs.val.get_as_integer()?; @@ -518,14 +489,13 @@ fn parse_def_or(data: &[u8], } fn parse_def_shift_left(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x79); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?; @@ -536,14 +506,13 @@ fn parse_def_shift_left(data: &[u8], } fn parse_def_shift_right(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x7A); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? << rhs.val.get_as_integer()?; @@ -554,14 +523,13 @@ fn parse_def_shift_right(data: &[u8], } fn parse_def_add(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x72); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? + rhs.val.get_as_integer()?; @@ -572,14 +540,13 @@ fn parse_def_add(data: &[u8], } fn parse_def_and(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x7B); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? & rhs.val.get_as_integer()?; @@ -590,14 +557,13 @@ fn parse_def_and(data: &[u8], } fn parse_def_xor(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x7F); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?; @@ -608,15 +574,14 @@ fn parse_def_xor(data: &[u8], } fn parse_def_concat_res(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x84); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -625,13 +590,12 @@ fn parse_def_concat_res(data: &[u8], } fn parse_def_wait(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result parser_opcode_extended!(data, 0x25); - let event_object = parse_super_name(&data[2..], namespace, scope.clone())?; - let operand = parse_term_arg(&data[2 + event_object.len..], namespace, scope.clone())?; + let event_object = parse_super_name(&data[2..], ctx)?; + let operand = parse_term_arg(&data[2 + event_object.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -640,14 +604,13 @@ fn parse_def_wait(data: &[u8], } fn parse_def_cond_ref_of(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result parser_opcode_extended!(data, 0x12); - let operand = parse_super_name(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_super_name(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -656,14 +619,13 @@ fn parse_def_cond_ref_of(data: &[u8], } fn parse_def_copy_object(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result parser_opcode!(data, 0x9D); - let source = parse_term_arg(&data[1..], namespace, scope.clone())?; - let destination = parse_simple_name(&data[1 + source.len..], namespace, scope.clone())?; + let source = parse_term_arg(&data[1..], ctx)?; + let destination = parse_simple_name(&data[1 + source.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -672,15 +634,14 @@ fn parse_def_copy_object(data: &[u8], } fn parse_def_concat(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result parser_opcode!(data, 0x73); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -689,13 +650,12 @@ fn parse_def_concat(data: &[u8], } fn parse_def_decrement(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result parser_opcode!(data, 0x76); - let target = parse_super_name(&data[1..], namespace, scope.clone())?; + let target = parse_super_name(&data[1..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -704,16 +664,15 @@ fn parse_def_decrement(data: &[u8], } fn parse_def_divide(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x78); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target_remainder = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; - let target_quotient = parse_target(&data[1 + lhs.len + rhs.len + target_remainder.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target_remainder = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; + let target_quotient = parse_target(&data[1 + lhs.len + rhs.len + target_remainder.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -722,14 +681,13 @@ fn parse_def_divide(data: &[u8], } fn parse_def_find_set_left_bit(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x81); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -738,14 +696,13 @@ fn parse_def_find_set_left_bit(data: &[u8], } fn parse_def_find_set_right_bit(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x82); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -754,19 +711,18 @@ fn parse_def_find_set_right_bit(data: &[u8], } fn parse_def_load_table(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate // TODO: Clean up parser_opcode_extended!(data, 0x1F); - let signature = parse_term_arg(&data[2..], namespace, scope.clone())?; - let oem_id = parse_term_arg(&data[2 + signature.len..], namespace, scope.clone())?; - let oem_table_id = parse_term_arg(&data[2 + signature.len + oem_id.len..], namespace, scope.clone())?; - let root_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len..], namespace, scope.clone())?; - let parameter_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len..], namespace, scope.clone())?; - let parameter_data = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len..], namespace, scope.clone())?; + let signature = parse_term_arg(&data[2..], ctx)?; + let oem_id = parse_term_arg(&data[2 + signature.len..], ctx)?; + let oem_table_id = parse_term_arg(&data[2 + signature.len + oem_id.len..], ctx)?; + let root_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len..], ctx)?; + 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)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -775,14 +731,13 @@ fn parse_def_load_table(data: &[u8], } fn parse_def_match(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate // TODO: Clean up match blocks parser_opcode!(data, 0x28); - let search_pkg = parse_term_arg(&data[1..], namespace, scope.clone())?; + let search_pkg = parse_term_arg(&data[1..], ctx)?; let first_operation = match data[1 + search_pkg.len] { 0 => MatchOpcode::MTR, @@ -793,7 +748,7 @@ fn parse_def_match(data: &[u8], 5 => MatchOpcode::MGT, _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode")) }; - let first_operand = parse_term_arg(&data[2 + search_pkg.len..], namespace, scope.clone())?; + let first_operand = parse_term_arg(&data[2 + search_pkg.len..], ctx)?; let second_operation = match data[2 + search_pkg.len + first_operand.len] { 0 => MatchOpcode::MTR, @@ -804,9 +759,9 @@ fn parse_def_match(data: &[u8], 5 => MatchOpcode::MGT, _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode")) }; - let second_operand = parse_term_arg(&data[3 + search_pkg.len + first_operand.len..], namespace, scope.clone())?; + let second_operand = parse_term_arg(&data[3 + search_pkg.len + first_operand.len..], ctx)?; - let start_index = parse_term_arg(&data[3 + search_pkg.len + first_operand.len + second_operand.len..], namespace, scope.clone())?; + let start_index = parse_term_arg(&data[3 + search_pkg.len + first_operand.len + second_operand.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -815,14 +770,13 @@ fn parse_def_match(data: &[u8], } fn parse_def_from_bcd(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate // TODO: Clean up match block parser_opcode_extended!(data, 0x28); - let operand = parse_term_arg(&data[2..], namespace, scope.clone())?; - let target = parse_target(&data[2 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[2..], ctx)?; + let target = parse_target(&data[2 + operand.len..], ctx)?; let result = match target.val.get_as_integer() { Ok(i) => { @@ -851,16 +805,15 @@ fn parse_def_from_bcd(data: &[u8], } fn parse_def_mid(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Compute the result // TODO: Store the result, if appropriate parser_opcode!(data, 0x9E); - let source = parse_term_arg(&data[1..], namespace, scope.clone())?; - let index = parse_term_arg(&data[1 + source.len..], namespace, scope.clone())?; - let length = parse_term_arg(&data[1 + source.len + index.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + source.len + index.len + length.len..], namespace, scope.clone())?; + let source = parse_term_arg(&data[1..], ctx)?; + let index = parse_term_arg(&data[1 + source.len..], ctx)?; + let length = parse_term_arg(&data[1 + source.len + index.len..], ctx)?; + let target = parse_target(&data[1 + source.len + index.len + length.len..], ctx)?; Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -869,15 +822,14 @@ fn parse_def_mid(data: &[u8], } fn parse_def_mod(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate // TODO: Fatal exception on rhs == 0 parser_opcode!(data, 0x85); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? % rhs.val.get_as_integer()?; @@ -888,15 +840,14 @@ fn parse_def_mod(data: &[u8], } fn parse_def_multiply(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate // TODO: Handle overflow parser_opcode!(data, 0x77); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = lhs.val.get_as_integer()? * rhs.val.get_as_integer()?; @@ -907,14 +858,13 @@ fn parse_def_multiply(data: &[u8], } fn parse_def_nand(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x7C); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = !(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?); @@ -925,14 +875,13 @@ fn parse_def_nand(data: &[u8], } fn parse_def_nor(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x7E); - let lhs = parse_term_arg(&data[1..], namespace, scope.clone())?; - let rhs = parse_term_arg(&data[1 + lhs.len..], namespace, scope.clone())?; - let target = parse_target(&data[1 + lhs.len + rhs.len..], namespace, scope.clone())?; + let lhs = parse_term_arg(&data[1..], ctx)?; + let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; + let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let result = !(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?); @@ -943,13 +892,12 @@ fn parse_def_nor(data: &[u8], } fn parse_def_not(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Store the result, if appropriate parser_opcode!(data, 0x80); - let operand = parse_term_arg(&data[1..], namespace, scope.clone())?; - let target = parse_target(&data[1 + operand.len..], namespace, scope.clone())?; + let operand = parse_term_arg(&data[1..], ctx)?; + let target = parse_target(&data[1 + operand.len..], ctx)?; let result = !operand.val.get_as_integer()?; @@ -960,8 +908,7 @@ fn parse_def_not(data: &[u8], } fn parse_def_timer(data: &[u8], - namespace: &mut BTreeMap, - scope: String) -> ParseResult { + ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Read from the hardware timer, and split into 100ns intervals parser_opcode_extended!(data, 0x33); From def456a8e54a1b704a19988e8b14c41f8ccc9841 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 3 Jul 2017 11:11:07 +0100 Subject: [PATCH 22/26] Added object modification --- src/acpi/aml/mod.rs | 5 +- src/acpi/aml/namedobj.rs | 24 ++------- src/acpi/aml/parser.rs | 49 +++++++++++++++-- src/acpi/aml/type2opcode.rs | 101 +++++++++++++++++++++--------------- 4 files changed, 108 insertions(+), 71 deletions(-) diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index d20ce4c..fa2e070 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -39,10 +39,7 @@ pub enum AmlError { pub fn parse_aml_table(sdt: &'static Sdt) -> Result, AmlError> { let data = sdt.data(); - let mut ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::from_str("\\").unwrap() - }; + let mut ctx = AmlExecutionContext::new(String::from_str("\\").unwrap()); let term_list = parse_term_list(data, &mut ctx)?; diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 3c4605b..06ad1cf 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -342,11 +342,7 @@ fn parse_def_device(data: &[u8], let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?; - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); @@ -682,11 +678,7 @@ fn parse_def_power_res(data: &[u8], let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) + ((data[4 + pkg_len_len + name.len] as u16) << 8); - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; ctx.namespace.insert(local_scope_string, AmlValue::PowerResource { @@ -717,11 +709,7 @@ fn parse_def_processor(data: &[u8], ((data[6 + pkg_len_len + name.len] as u32) << 24); let p_blk_len = data[7 + pkg_len_len + name.len]; - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; ctx.namespace.insert(local_scope_string, AmlValue::Processor { @@ -745,11 +733,7 @@ fn parse_def_thermal_zone(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; ctx.namespace.insert(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace.clone())); diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index b316319..d918292 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -1,7 +1,7 @@ use collections::string::String; use collections::btree_map::BTreeMap; -use super::namespace::AmlValue; +use super::namespace::{ AmlValue, ObjectReference }; use super::AmlError; pub type ParseResult = Result; @@ -12,7 +12,48 @@ pub struct AmlParseTypeGeneric { pub len: usize } -pub struct AmlExecutionContext<'a> { - pub namespace: &'a mut BTreeMap, - pub scope: String +pub struct AmlExecutionContext { + pub namespace: BTreeMap, + pub scope: String, + pub local_vars: [AmlValue; 8], + pub arg_vars: [AmlValue; 8] +} + +impl AmlExecutionContext { + pub fn new(scope: String) -> AmlExecutionContext { + AmlExecutionContext { + namespace: BTreeMap::new(), + scope: scope, + local_vars: [AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized], + arg_vars: [AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized] + } + } + + pub fn modify(&mut self, name: AmlValue, value: AmlValue) { + // TODO: throw errors + // TODO: return DRO + match name { + AmlValue::None => (), + AmlValue::ObjectReference(r) => match r { + ObjectReference::ArgObj(i) => (), + ObjectReference::LocalObj(i) => self.local_vars[i as usize] = value, + _ => () + }, + _ => () + } + } } diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 0685251..475b942 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -429,17 +429,18 @@ fn parse_def_to_string(data: &[u8], fn parse_def_subtract(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x74); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? - rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? - rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } @@ -459,11 +460,13 @@ fn parse_def_size_of(data: &[u8], fn parse_def_store(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Perform the store + // TODO: Return the DRO parser_opcode!(data, 0x70); let operand = parse_term_arg(&data[1..], ctx)?; let target = parse_super_name(&data[1 + operand.len..], ctx)?; + + ctx.modify(target.val, operand.val); Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -473,102 +476,108 @@ fn parse_def_store(data: &[u8], fn parse_def_or(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7D); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? | rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_shift_left(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x79); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_shift_right(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7A); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - - let result = lhs.val.get_as_integer()? << rhs.val.get_as_integer()?; - + + let result = AmlValue::Integer(lhs.val.get_as_integer()? << rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); + Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_add(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x72); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? + rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? + rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_and(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7B); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? & rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_xor(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7F); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } @@ -771,14 +780,13 @@ fn parse_def_match(data: &[u8], fn parse_def_from_bcd(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate // TODO: Clean up match block parser_opcode_extended!(data, 0x28); let operand = parse_term_arg(&data[2..], ctx)?; let target = parse_target(&data[2 + operand.len..], ctx)?; - let result = match target.val.get_as_integer() { + let result = AmlValue::Integer(match target.val.get_as_integer() { Ok(i) => { let mut i = i; let mut ires = 0; @@ -796,10 +804,12 @@ fn parse_def_from_bcd(data: &[u8], ires }, Err(e) => return Err(e) - }; + }); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 2 + operand.len + target.len }) } @@ -823,7 +833,6 @@ fn parse_def_mid(data: &[u8], fn parse_def_mod(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate // TODO: Fatal exception on rhs == 0 parser_opcode!(data, 0x85); @@ -831,17 +840,18 @@ fn parse_def_mod(data: &[u8], let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? % rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? % rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_multiply(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate // TODO: Handle overflow parser_opcode!(data, 0x77); @@ -849,60 +859,65 @@ fn parse_def_multiply(data: &[u8], let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? * rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? * rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_nand(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7C); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = !(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?); + let result = AmlValue::Integer(!(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?)); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_nor(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7E); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = !(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?); + let result = AmlValue::Integer(!(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?)); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_not(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x80); let operand = parse_term_arg(&data[1..], ctx)?; let target = parse_target(&data[1 + operand.len..], ctx)?; - let result = !operand.val.get_as_integer()?; + let result = AmlValue::Integer(!operand.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + operand.len + target.len }) } From 980065d4d619a3f81b5f0cb32c7f89dc7461ab0c Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Wed, 5 Jul 2017 14:36:40 +0100 Subject: [PATCH 23/26] Fixed number of bugs --- src/acpi/aml/dataobj.rs | 6 +++--- src/acpi/aml/mod.rs | 2 +- src/acpi/aml/namedobj.rs | 6 +++++- src/acpi/aml/namespace.rs | 6 +++++- src/acpi/aml/namespacemodifier.rs | 6 +++--- src/acpi/aml/parsermacros.rs | 32 +++++-------------------------- src/acpi/aml/termlist.rs | 1 + src/acpi/aml/type2opcode.rs | 6 +++++- src/stop.rs | 1 + 9 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs index 4025f7f..1cd3904 100644 --- a/src/acpi/aml/dataobj.rs +++ b/src/acpi/aml/dataobj.rs @@ -125,11 +125,11 @@ fn parse_computational_data(data: &[u8], }, 0x00 => Ok(AmlParseType { val: AmlValue::IntegerConstant(0 as u64), - len: 9 as usize + len: 1 as usize }), 0x01 => Ok(AmlParseType { val: AmlValue::IntegerConstant(1 as u64), - len: 9 as usize + len: 1 as usize }), 0x5B => if data[1] == 0x30 { Ok(AmlParseType { @@ -141,7 +141,7 @@ fn parse_computational_data(data: &[u8], }, 0xFF => Ok(AmlParseType { val: AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF), - len: 9 as usize + len: 1 as usize }), _ => parse_def_buffer(data, ctx) } diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index fa2e070..a6275db 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -41,7 +41,7 @@ pub fn parse_aml_table(sdt: &'static Sdt) -> Result, let data = sdt.data(); let mut ctx = AmlExecutionContext::new(String::from_str("\\").unwrap()); - let term_list = parse_term_list(data, &mut ctx)?; + parse_term_list(data, &mut ctx)?; Ok(ctx.namespace.clone()) } diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 06ad1cf..3f6a569 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -474,10 +474,13 @@ fn parse_field_list(data: &[u8], selector: FieldSelector, flags: &mut FieldFlags) -> ParseResult { let mut current_offset: usize = 0; + let mut field_offset: usize = 0; let mut connection = AmlValue::Uninitialized; while current_offset < data.len() { - parse_field_element(&data[current_offset..], ctx, selector.clone(), &mut connection, flags, &mut current_offset)?; + let res = parse_field_element(&data[current_offset..], ctx, selector.clone(), &mut connection, flags, &mut field_offset)?; + + current_offset += res.len; } Ok(AmlParseType { @@ -503,6 +506,7 @@ fn parse_field_element(data: &[u8], length: field.val.length }); + *offset += field.val.length; field.len } else if let Ok(field) = parse_reserved_field(data, ctx) { *offset += field.val; diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 54cef02..f2a5ffe 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -129,6 +129,10 @@ pub fn get_namespace_string(current: String, modifier_v: AmlValue) -> String { } let mut namespace = current.clone(); - namespace.push('.'); + + if !namespace.ends_with("\\") { + namespace.push('.'); + } + namespace + &modifier } diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs index 35cd1a3..5d1bbf6 100644 --- a/src/acpi/aml/namespacemodifier.rs +++ b/src/acpi/aml/namespacemodifier.rs @@ -66,13 +66,13 @@ fn parse_scope_op(data: &[u8], let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; let name = parse_name_string(&data[1 + pkg_length_len..], ctx)?; - let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); + let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val.clone()); let containing_scope_string = ctx.scope.clone(); ctx.scope = local_scope_string; - parse_term_list(&data[1 + pkg_length_len + name.len..], ctx)?; + parse_term_list(&data[1 + pkg_length_len + name.len .. 1 + pkg_length], ctx)?; ctx.scope = containing_scope_string; - + Ok(AmlParseType { val: AmlValue::None, len: 1 + pkg_length diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs index 3f8cf61..20cedd9 100644 --- a/src/acpi/aml/parsermacros.rs +++ b/src/acpi/aml/parsermacros.rs @@ -4,7 +4,10 @@ macro_rules! parser_selector { match $func($data, $ctx) { Ok(res) => return Ok(res), Err(AmlError::AmlInvalidOpCode) => (), - Err(e) => return Err(e) + Err(e) => { +// println!("This doesn't work for some reason"); + return Err(e); + } } }; {$data:expr, $ctx:expr, $func:expr, $($funcs:expr),+} => { @@ -13,6 +16,7 @@ macro_rules! parser_selector { }; } +#[macro_export] macro_rules! parser_selector_simple { {$data:expr, $func:expr} => { match $func($data) { @@ -27,21 +31,6 @@ macro_rules! parser_selector_simple { }; } -#[macro_export] -macro_rules! parser_wrap { - ($wrap:expr, $func:expr) => { - |data, namespace, scope| { - match $func(data) { - Ok(res) => Ok(AmlParseTypeGeneric { - val: $wrap(res.val), - len: res.len - }), - Err(e) => Err(e) - } - } - }; -} - #[macro_export] macro_rules! parser_opcode { ($data:expr, $opcode:expr) => { @@ -64,14 +53,3 @@ macro_rules! parser_opcode_extended { } }; } - -#[macro_export] -macro_rules! parser_verify_value { - ($val:expr) => { - match $val.val { - Some(s) => s, - None => return Err(AmlError::AmlValueError) - } - }; -} - diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index bbce0e4..cdf0b80 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -73,6 +73,7 @@ pub fn parse_method_invocation(data: &[u8], // TODO: If so, parse appropriate number of parameters // TODO: If not, add deferred load to ctx let name = parse_name_string(data, ctx)?; + Err(AmlError::AmlDeferredLoad) } diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 475b942..94950c1 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -149,7 +149,11 @@ fn parse_package_elements_list(data: &[u8], let dro = if let Ok(e) = parse_data_ref_obj(&data[current_offset..], ctx) { e } else { - parse_name_string(&data[current_offset..], ctx)? + let d = parse_name_string(&data[current_offset..], ctx)?; + AmlParseType { + val: AmlValue::ObjectReference(ObjectReference::NamedObj(d.val.get_as_string()?)), + len: d.len + } }; elements.push(dro.val); diff --git a/src/stop.rs b/src/stop.rs index 6dec9a1..7e53f10 100644 --- a/src/stop.rs +++ b/src/stop.rs @@ -14,6 +14,7 @@ pub unsafe extern fn kstop() -> ! { if let Some(ref namespace) = acpi.namespace { if let Some(s) = namespace.get("\\_S5") { if let Ok(p) = s.get_as_package() { + println!("{:?}", p); let slp_typa = p[0].get_as_integer().expect("SLP_TYPa is not an integer"); let slp_typb = p[1].get_as_integer().expect("SLP_TYPb is not an integer"); From 00591235e1d75bf1d73ad8f0c47276d302af2ae4 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Fri, 7 Jul 2017 10:37:09 +0100 Subject: [PATCH 24/26] Implemented further opcodes in full, added get to context --- src/acpi/aml/namespace.rs | 13 ++- src/acpi/aml/parser.rs | 12 +++ src/acpi/aml/parsermacros.rs | 5 +- src/acpi/aml/type2opcode.rs | 188 +++++++++++++++++++++++++---------- 4 files changed, 159 insertions(+), 59 deletions(-) diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index f2a5ffe..746cd1e 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -34,10 +34,7 @@ pub enum ObjectReference { pub enum AmlValue { None, Uninitialized, - Buffer { - length: Box, - byte_list: Vec - }, + Buffer(Vec), BufferField { source_buf: Box, index: Box, @@ -81,13 +78,19 @@ pub enum AmlValue { } impl AmlValue { - // TODO: These should be able to throw errors rather than returning options pub fn get_as_string(&self) -> Result { match *self { AmlValue::String(ref s) => Ok(s.clone()), _ => Err(AmlError::AmlValueError) } } + + pub fn get_as_buffer(&self) -> Result, AmlError> { + match *self { + AmlValue::Buffer(ref b) => Ok(b.clone()), + _ => Err(AmlError::AmlValueError) + } + } pub fn get_as_package(&self) -> Result, AmlError> { match *self { diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index d918292..c71025d 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -56,4 +56,16 @@ impl AmlExecutionContext { _ => () } } + + pub fn get(&self, name: AmlValue) -> AmlValue { + match name { + AmlValue::None => AmlValue::None, + AmlValue::ObjectReference(r) => match r { + ObjectReference::ArgObj(i) => self.arg_vars[i as usize].clone(), + ObjectReference::LocalObj(i) => self.local_vars[i as usize].clone(), + _ => AmlValue::None + }, + _ => AmlValue::None + } + } } diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs index 20cedd9..31a2338 100644 --- a/src/acpi/aml/parsermacros.rs +++ b/src/acpi/aml/parsermacros.rs @@ -4,10 +4,7 @@ macro_rules! parser_selector { match $func($data, $ctx) { Ok(res) => return Ok(res), Err(AmlError::AmlInvalidOpCode) => (), - Err(e) => { -// println!("This doesn't work for some reason"); - return Err(e); - } + Err(e) => return Err(e) } }; {$data:expr, $ctx:expr, $func:expr, $($funcs:expr),+} => { diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 94950c1..721b36c 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -110,15 +110,22 @@ pub fn parse_def_object_type(data: &[u8], pub fn parse_def_package(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Handle deferred loads in here - // TODO: Truncate/extend array if necessary parser_opcode!(data, 0x12); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; - let num_elements = data[1 + pkg_length_len]; - let elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], ctx)?; + let numelements = data[1 + pkg_length_len] as usize; + let mut elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], ctx)?.val.get_as_package()?; + + if elements.len() > numelements { + elements = elements[0 .. numelements].to_vec(); + } else if numelements > elements.len() { + for i in 0..numelements - elements.len() { + elements.push(AmlValue::Uninitialized); + } + } Ok(AmlParseType { - val: elements.val, + val: AmlValue::Package(elements), len: 1 + pkg_length }) } @@ -126,16 +133,25 @@ pub fn parse_def_package(data: &[u8], pub fn parse_def_var_package(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { // TODO: Handle deferred loads in here - // TODO: Truncate/extend array if necessary parser_opcode!(data, 0x13); let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?; let num_elements = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?; - let elements = parse_package_elements_list(&data[1 + pkg_length_len + num_elements.len .. - 1 + pkg_length], ctx)?; + let mut elements = parse_package_elements_list(&data[1 + pkg_length_len + num_elements.len .. + 1 + pkg_length], ctx)?.val.get_as_package()?; + + let numelements = num_elements.val.get_as_integer()? as usize; + + if elements.len() > numelements { + elements = elements[0 .. numelements].to_vec(); + } else if numelements > elements.len() { + for i in 0..numelements - elements.len() { + elements.push(AmlValue::Uninitialized); + } + } Ok(AmlParseType { - val: elements.val, + val: AmlValue::Package(elements), len: 1 + pkg_length }) } @@ -224,14 +240,15 @@ fn parse_def_acquire(data: &[u8], fn parse_def_increment(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result - // TODO: Perform computation parser_opcode!(data, 0x75); let obj = parse_super_name(&data[1..], ctx)?; + let value = AmlValue::Integer(ctx.get(obj.val.clone()).get_as_integer()? + 1); + + ctx.modify(obj.val, value.clone()); Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: value, len: 1 + obj.len }) } @@ -464,16 +481,15 @@ fn parse_def_size_of(data: &[u8], fn parse_def_store(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Return the DRO parser_opcode!(data, 0x70); let operand = parse_term_arg(&data[1..], ctx)?; let target = parse_super_name(&data[1 + operand.len..], ctx)?; - ctx.modify(target.val, operand.val); + ctx.modify(target.val.clone(), operand.val); Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: target.val, len: 1 + operand.len + target.len }) } @@ -664,61 +680,99 @@ fn parse_def_concat(data: &[u8], fn parse_def_decrement(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Compute the result - // TODO: Store the result parser_opcode!(data, 0x76); - let target = parse_super_name(&data[1..], ctx)?; + let obj = parse_super_name(&data[1..], ctx)?; + let value = AmlValue::Integer(ctx.get(obj.val.clone()).get_as_integer()? - 1); + ctx.modify(obj.val, value.clone()); + Ok(AmlParseType { - val: AmlValue::Uninitialized, - len: 1 + target.len + val: value, + len: 1 + obj.len }) } fn parse_def_divide(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Compute the result - // TODO: Store the result, if appropriate parser_opcode!(data, 0x78); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target_remainder = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; let target_quotient = parse_target(&data[1 + lhs.len + rhs.len + target_remainder.len..], ctx)?; + + let numerator = lhs.val.get_as_integer()?; + let denominator = rhs.val.get_as_integer()?; + + let remainder = numerator % denominator; + let quotient = (numerator - remainder) / denominator; + + ctx.modify(target_remainder.val, AmlValue::Integer(remainder)); + ctx.modify(target_quotient.val, AmlValue::Integer(quotient)); Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: AmlValue::Integer(quotient), len: 1 + lhs.len + rhs.len + target_remainder.len + target_quotient.len }) } fn parse_def_find_set_left_bit(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Compute the result - // TODO: Store the result, if appropriate parser_opcode!(data, 0x81); let operand = parse_term_arg(&data[2..], ctx)?; let target = parse_target(&data[2 + operand.len..], ctx)?; + let mut first_bit = 32; + let mut test = operand.val.get_as_integer()?; + + while first_bit > 0{ + if test & 0x8000000000000000 > 0 { + break; + } + + test <<= 1; + first_bit -= 1; + } + + let result = AmlValue::Integer(first_bit); + ctx.modify(target.val, result.clone()); + Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: result, len: 1 + operand.len + target.len }) } fn parse_def_find_set_right_bit(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Compute the result - // TODO: Store the result, if appropriate parser_opcode!(data, 0x82); let operand = parse_term_arg(&data[2..], ctx)?; let target = parse_target(&data[2 + operand.len..], ctx)?; + let mut first_bit = 1; + let mut test = operand.val.get_as_integer()?; + + while first_bit <= 32 { + if test & 1 > 0 { + break; + } + + test >>= 1; + first_bit += 1; + } + + if first_bit == 33 { + first_bit = 0; + } + + let result = AmlValue::Integer(first_bit); + ctx.modify(target.val, result.clone()); + Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: result, len: 1 + operand.len + target.len }) } @@ -784,31 +838,25 @@ fn parse_def_match(data: &[u8], fn parse_def_from_bcd(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Clean up match block parser_opcode_extended!(data, 0x28); let operand = parse_term_arg(&data[2..], ctx)?; let target = parse_target(&data[2 + operand.len..], ctx)?; - - let result = AmlValue::Integer(match target.val.get_as_integer() { - Ok(i) => { - let mut i = i; - let mut ires = 0; - while i != 0 { - if i & 0x0F > 10 { - return Err(AmlError::AmlValueError); - } + let mut i = operand.val.get_as_integer()?; + let mut result = 0; - ires *= 10; - ires += i & 0x0F; - i >>= 4; - } + while i != 0 { + if i & 0x0F > 10 { + return Err(AmlError::AmlValueError); + } + + result *= 10; + result += i & 0x0F; + i >>= 4; + } - ires - }, - Err(e) => return Err(e) - }); + let result = AmlValue::Integer(result); ctx.modify(target.val, result.clone()); @@ -820,8 +868,6 @@ fn parse_def_from_bcd(data: &[u8], fn parse_def_mid(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Compute the result - // TODO: Store the result, if appropriate parser_opcode!(data, 0x9E); let source = parse_term_arg(&data[1..], ctx)?; @@ -829,21 +875,63 @@ fn parse_def_mid(data: &[u8], let length = parse_term_arg(&data[1 + source.len + index.len..], ctx)?; let target = parse_target(&data[1 + source.len + index.len + length.len..], ctx)?; + let idx = index.val.get_as_integer()? as usize; + let mut len = length.val.get_as_integer()? as usize; + + let result = match source.val { + AmlValue::String(s) => { + if idx > s.len() { + AmlValue::String(String::new()) + } else { + let mut res = s.clone().split_off(idx); + + if len < res.len() { + res.split_off(len); + } + + AmlValue::String(res) + } + }, + _ => { + // If it isn't a string already, treat it as a buffer. Must perform that check first, + // as Mid can operate on both strings and buffers, but a string can be cast as a buffer + // implicitly. + // Additionally, any type that can be converted to a buffer can also be converted to a + // string, so no information is lost + let b = source.val.get_as_buffer()?; + + if idx > b.len() { + AmlValue::Buffer(vec!()) + } else { + if idx + len > b.len() { + len = b.len() - idx; + } + + AmlValue::Buffer(b[idx .. idx + len].to_vec()) + } + } + }; + + ctx.modify(target.val, result.clone()); + Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: result, len: 1 + source.len + index.len + length.len + target.len }) } fn parse_def_mod(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Fatal exception on rhs == 0 parser_opcode!(data, 0x85); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; + if rhs.val.get_as_integer()? == 0 { + return Err(AmlError::AmlValueError); + } + let result = AmlValue::Integer(lhs.val.get_as_integer()? % rhs.val.get_as_integer()?); ctx.modify(target.val, result.clone()); From 59936e25e6292dd1a6f66f1837eb8152ee241a31 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Fri, 7 Jul 2017 11:39:08 +0100 Subject: [PATCH 25/26] Implemented match --- src/acpi/aml/type2opcode.rs | 106 ++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 721b36c..8956411 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -799,9 +799,7 @@ fn parse_def_load_table(data: &[u8], fn parse_def_match(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Compute the result - // TODO: Store the result, if appropriate - // TODO: Clean up match blocks + // TODO: Clean up parser_opcode!(data, 0x28); let search_pkg = parse_term_arg(&data[1..], ctx)?; @@ -830,8 +828,108 @@ fn parse_def_match(data: &[u8], let start_index = parse_term_arg(&data[3 + search_pkg.len + first_operand.len + second_operand.len..], ctx)?; + let pkg = search_pkg.val.get_as_package()?; + let mut idx = start_index.val.get_as_integer()? as usize; + + match first_operand.val { + AmlValue::Integer(i) => { + let j = second_operand.val.get_as_integer()?; + + while idx < pkg.len() { + let val = if let Ok(v) = pkg[idx].get_as_integer() { v } else { idx += 1; continue; }; + idx += 1; + + match first_operation { + MatchOpcode::MTR => (), + MatchOpcode::MEQ => if val != i { continue }, + MatchOpcode::MLE => if val > i { continue }, + MatchOpcode::MLT => if val >= i { continue }, + MatchOpcode::MGE => if val < i { continue }, + MatchOpcode::MGT => if val <= i { continue } + } + + match second_operation { + MatchOpcode::MTR => (), + MatchOpcode::MEQ => if val != i { continue }, + MatchOpcode::MLE => if val > i { continue }, + MatchOpcode::MLT => if val >= i { continue }, + MatchOpcode::MGE => if val < i { continue }, + MatchOpcode::MGT => if val <= i { continue } + } + + return Ok(AmlParseType { + val: AmlValue::Integer(idx as u64), + len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len + }); + } + }, + AmlValue::String(i) => { + let j = second_operand.val.get_as_string()?; + + while idx < pkg.len() { + let val = if let Ok(v) = pkg[idx].get_as_string() { v } else { idx += 1; continue; }; + idx += 1; + + match first_operation { + MatchOpcode::MTR => (), + MatchOpcode::MEQ => if val != i { continue }, + MatchOpcode::MLE => if val > i { continue }, + MatchOpcode::MLT => if val >= i { continue }, + MatchOpcode::MGE => if val < i { continue }, + MatchOpcode::MGT => if val <= i { continue } + } + + match second_operation { + MatchOpcode::MTR => (), + MatchOpcode::MEQ => if val != i { continue }, + MatchOpcode::MLE => if val > i { continue }, + MatchOpcode::MLT => if val >= i { continue }, + MatchOpcode::MGE => if val < i { continue }, + MatchOpcode::MGT => if val <= i { continue } + } + + return Ok(AmlParseType { + val: AmlValue::Integer(idx as u64), + len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len + }); + } + }, + _ => { + let i = first_operand.val.get_as_buffer()?; + let j = second_operand.val.get_as_buffer()?; + + while idx < pkg.len() { + let val = if let Ok(v) = pkg[idx].get_as_buffer() { v } else { idx += 1; continue; }; + idx += 1; + + match first_operation { + MatchOpcode::MTR => (), + MatchOpcode::MEQ => if val != i { continue }, + MatchOpcode::MLE => if val > i { continue }, + MatchOpcode::MLT => if val >= i { continue }, + MatchOpcode::MGE => if val < i { continue }, + MatchOpcode::MGT => if val <= i { continue } + } + + match second_operation { + MatchOpcode::MTR => (), + MatchOpcode::MEQ => if val != i { continue }, + MatchOpcode::MLE => if val > i { continue }, + MatchOpcode::MLT => if val >= i { continue }, + MatchOpcode::MGE => if val < i { continue }, + MatchOpcode::MGT => if val <= i { continue } + } + + return Ok(AmlParseType { + val: AmlValue::Integer(idx as u64), + len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len + }); + } + } + } + Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF), len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len }) } From fa24650ca7ab7ebf7d84f728b11534f1438a37e0 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Sat, 8 Jul 2017 10:20:33 +0100 Subject: [PATCH 26/26] Implemented opcodes --- src/acpi/aml/type1opcode.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index 7bc9546..d494205 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -48,7 +48,6 @@ fn parse_def_break(data: &[u8], fn parse_def_breakpoint(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Implement parser_opcode!(data, 0xCC); Ok(AmlParseType {