From 2a6bbeb584324b95b1a7531977b26a1ebee8876b Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Mon, 3 Jul 2017 11:11:07 +0100 Subject: [PATCH] Added object modification --- src/acpi/aml/mod.rs | 5 +- src/acpi/aml/namedobj.rs | 24 ++------- src/acpi/aml/parser.rs | 49 +++++++++++++++-- src/acpi/aml/type2opcode.rs | 101 +++++++++++++++++++++--------------- 4 files changed, 108 insertions(+), 71 deletions(-) diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs index d20ce4c..fa2e070 100644 --- a/src/acpi/aml/mod.rs +++ b/src/acpi/aml/mod.rs @@ -39,10 +39,7 @@ pub enum AmlError { pub fn parse_aml_table(sdt: &'static Sdt) -> Result, AmlError> { let data = sdt.data(); - let mut ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::from_str("\\").unwrap() - }; + let mut ctx = AmlExecutionContext::new(String::from_str("\\").unwrap()); let term_list = parse_term_list(data, &mut ctx)?; diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 3c4605b..06ad1cf 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -342,11 +342,7 @@ fn parse_def_device(data: &[u8], let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?; let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?; - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); @@ -682,11 +678,7 @@ fn parse_def_power_res(data: &[u8], let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) + ((data[4 + pkg_len_len + name.len] as u16) << 8); - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; ctx.namespace.insert(local_scope_string, AmlValue::PowerResource { @@ -717,11 +709,7 @@ fn parse_def_processor(data: &[u8], ((data[6 + pkg_len_len + name.len] as u32) << 24); let p_blk_len = data[7 + pkg_len_len + name.len]; - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; ctx.namespace.insert(local_scope_string, AmlValue::Processor { @@ -745,11 +733,7 @@ fn parse_def_thermal_zone(data: &[u8], let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - let mut local_ctx = AmlExecutionContext { - namespace: &mut BTreeMap::new(), - scope: String::new() - }; - + let mut local_ctx = AmlExecutionContext::new(String::new()); parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?; ctx.namespace.insert(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace.clone())); diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index b316319..d918292 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -1,7 +1,7 @@ use collections::string::String; use collections::btree_map::BTreeMap; -use super::namespace::AmlValue; +use super::namespace::{ AmlValue, ObjectReference }; use super::AmlError; pub type ParseResult = Result; @@ -12,7 +12,48 @@ pub struct AmlParseTypeGeneric { pub len: usize } -pub struct AmlExecutionContext<'a> { - pub namespace: &'a mut BTreeMap, - pub scope: String +pub struct AmlExecutionContext { + pub namespace: BTreeMap, + pub scope: String, + pub local_vars: [AmlValue; 8], + pub arg_vars: [AmlValue; 8] +} + +impl AmlExecutionContext { + pub fn new(scope: String) -> AmlExecutionContext { + AmlExecutionContext { + namespace: BTreeMap::new(), + scope: scope, + local_vars: [AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized], + arg_vars: [AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized, + AmlValue::Uninitialized] + } + } + + pub fn modify(&mut self, name: AmlValue, value: AmlValue) { + // TODO: throw errors + // TODO: return DRO + match name { + AmlValue::None => (), + AmlValue::ObjectReference(r) => match r { + ObjectReference::ArgObj(i) => (), + ObjectReference::LocalObj(i) => self.local_vars[i as usize] = value, + _ => () + }, + _ => () + } + } } diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 0685251..475b942 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -429,17 +429,18 @@ fn parse_def_to_string(data: &[u8], fn parse_def_subtract(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x74); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? - rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? - rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } @@ -459,11 +460,13 @@ fn parse_def_size_of(data: &[u8], fn parse_def_store(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Perform the store + // TODO: Return the DRO parser_opcode!(data, 0x70); let operand = parse_term_arg(&data[1..], ctx)?; let target = parse_super_name(&data[1 + operand.len..], ctx)?; + + ctx.modify(target.val, operand.val); Ok(AmlParseType { val: AmlValue::Uninitialized, @@ -473,102 +476,108 @@ fn parse_def_store(data: &[u8], fn parse_def_or(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7D); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? | rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_shift_left(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x79); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_shift_right(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7A); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - - let result = lhs.val.get_as_integer()? << rhs.val.get_as_integer()?; - + + let result = AmlValue::Integer(lhs.val.get_as_integer()? << rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); + Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_add(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x72); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? + rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? + rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_and(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7B); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? & rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_xor(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7F); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } @@ -771,14 +780,13 @@ fn parse_def_match(data: &[u8], fn parse_def_from_bcd(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate // TODO: Clean up match block parser_opcode_extended!(data, 0x28); let operand = parse_term_arg(&data[2..], ctx)?; let target = parse_target(&data[2 + operand.len..], ctx)?; - let result = match target.val.get_as_integer() { + let result = AmlValue::Integer(match target.val.get_as_integer() { Ok(i) => { let mut i = i; let mut ires = 0; @@ -796,10 +804,12 @@ fn parse_def_from_bcd(data: &[u8], ires }, Err(e) => return Err(e) - }; + }); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 2 + operand.len + target.len }) } @@ -823,7 +833,6 @@ fn parse_def_mid(data: &[u8], fn parse_def_mod(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate // TODO: Fatal exception on rhs == 0 parser_opcode!(data, 0x85); @@ -831,17 +840,18 @@ fn parse_def_mod(data: &[u8], let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? % rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? % rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_multiply(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate // TODO: Handle overflow parser_opcode!(data, 0x77); @@ -849,60 +859,65 @@ fn parse_def_multiply(data: &[u8], let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = lhs.val.get_as_integer()? * rhs.val.get_as_integer()?; + let result = AmlValue::Integer(lhs.val.get_as_integer()? * rhs.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_nand(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7C); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = !(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?); + let result = AmlValue::Integer(!(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?)); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_nor(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x7E); let lhs = parse_term_arg(&data[1..], ctx)?; let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?; let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?; - let result = !(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?); + let result = AmlValue::Integer(!(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?)); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + lhs.len + rhs.len + target.len }) } fn parse_def_not(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult { - // TODO: Store the result, if appropriate parser_opcode!(data, 0x80); let operand = parse_term_arg(&data[1..], ctx)?; let target = parse_target(&data[1 + operand.len..], ctx)?; - let result = !operand.val.get_as_integer()?; + let result = AmlValue::Integer(!operand.val.get_as_integer()?); + + ctx.modify(target.val, result.clone()); Ok(AmlParseType { - val: AmlValue::IntegerConstant(result), + val: result, len: 1 + operand.len + target.len }) }