From d75dfd3c20eeb3a54afed3428a5cc41a84d31209 Mon Sep 17 00:00:00 2001 From: Connor Wood Date: Tue, 29 Aug 2017 12:02:03 +0100 Subject: [PATCH] Implemented externam --- src/acpi/aml/namedobj.rs | 37 +++++++++++++++++++++++++++++++++++++ src/acpi/aml/parser.rs | 12 ++++++++++-- src/acpi/aml/type2opcode.rs | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index ecd761e..1d2a8e5 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -96,6 +96,7 @@ pub fn parse_named_obj(data: &[u8], parse_def_create_field, parse_def_data_region, parse_def_event, + parse_def_external, parse_def_device, parse_def_op_region, parse_def_field, @@ -928,3 +929,39 @@ fn parse_def_thermal_zone(data: &[u8], len: 2 + pkg_len }) } + +fn parse_def_external(data: &[u8], + ctx: &mut AmlExecutionContext) -> ParseResult { + match ctx.state { + ExecutionState::EXECUTING => (), + _ => return Ok(AmlParseType { + val: AmlValue::None, + len: 0 as usize + }) + } + + parser_opcode_extended!(data, 0x15); + + let object_name = parse_name_string(&data[1..], ctx)?; + let object_type = data[1 + object_name.len]; + let argument_count = data[2 + object_name.len]; + + let local_scope_string = get_namespace_string(ctx.scope.clone(), object_name.val)?; + + let obj = match object_type { + 8 => AmlValue::Method(Method { + arg_count: argument_count, + serialized: false, + sync_level: 0, + term_list: vec!() + }), + _ => AmlValue::Uninitialized + }; + + ctx.add_to_namespace(local_scope_string, obj)?; + + Ok(AmlParseType { + val: AmlValue::None, + len: 3 + object_name.len + }) +} diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 3b382d4..e956c02 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -245,8 +245,16 @@ impl AmlExecutionContext { let mut namespace = ACPI_TABLE.namespace.write(); if let Some(ref mut namespace) = *namespace { - if namespace.contains_key(&name) { - return Err(AmlError::AmlValueError); + if let Some(obj) = namespace.get(&name) { + match *obj { + AmlValue::Uninitialized => (), + AmlValue::Method(ref m) => { + if m.term_list.len() != 0 { + return Err(AmlError::AmlValueError); + } + }, + _ => return Err(AmlError::AmlValueError) + } } self.namespace_delta.push(name.clone()); diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 5802584..09c3b93 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -977,16 +977,44 @@ fn parse_def_concat_res(data: &[u8], }) } - // TODO: Compute the result - // TODO: Store the result, if appropriate parser_opcode!(data, 0x84); 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 mut buf1 = lhs.val.get_as_buffer()?.clone(); + let mut buf2 = rhs.val.get_as_buffer()?.clone(); + + if buf1.len() == 1 || buf2.len() == 1 { + return Err(AmlError::AmlValueError); + } + + if buf1.len() >= 2 && buf1[buf1.len() - 2] == 0x79 { + buf1 = buf1[0..buf1.len() - 2].to_vec(); + } + + if buf2.len() >= 2 && buf2[buf2.len() - 2] == 0x79 { + buf2 = buf2[0..buf2.len() - 2].to_vec(); + } + + buf1.append(&mut buf2); + buf1.push(0x79); + + let mut checksum: u8 = 0; + let loopbuf = buf1.clone(); + for b in loopbuf { + checksum += b; + } + + checksum = (!checksum) + 1; + buf1.push(checksum); + + let res = AmlValue::Buffer(buf1); + ctx.modify(target.val, res.clone())?; Ok(AmlParseType { - val: AmlValue::Uninitialized, + val: res, len: 1 + lhs.len + rhs.len + target.len }) }