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");