From 41ce7fdf1f96cf8cfe254981976ddf20f6cf61b4 Mon Sep 17 00:00:00 2001 From: Connor Wood <connorwood71@gmail.com> Date: Sun, 30 Jul 2017 11:23:32 +0300 Subject: [PATCH] Implemented much of ctx::modify and ctx::get --- src/acpi/aml/parser.rs | 90 ++++++++++++++++++++++++++++++++----- src/acpi/aml/termlist.rs | 2 +- src/acpi/aml/type1opcode.rs | 6 +-- src/acpi/aml/type2opcode.rs | 12 ++--- 4 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 1cfc6e08..2cc907cd 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -283,29 +283,95 @@ impl AmlExecutionContext { ACPI_TABLE.namespace.write() } - pub fn modify(&mut self, name: AmlValue, value: AmlValue) { - // TODO: throw errors - // TODO: return DRO + pub fn modify(&mut self, name: AmlValue, value: AmlValue) -> Result<(), AmlError> { match name { - AmlValue::None => (), AmlValue::ObjectReference(r) => match r { - ObjectReference::ArgObj(_) => (), + ObjectReference::ArgObj(_) => return Err(AmlError::AmlValueError), ObjectReference::LocalObj(i) => self.local_vars[i as usize] = value, - _ => () + ObjectReference::Object(s) => if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() { + namespace.insert(s, value); + }, + ObjectReference::Index(c, v) => { + let idx = v.get_as_integer()? as usize; + match *c { + AmlValue::ObjectReference(r) => match r { + ObjectReference::Object(s) => { + if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() { + let obj = if let Some(s) = namespace.get(&s) { + s.clone() + } else { + return Err(AmlError::AmlValueError); + }; + + match obj { + AmlValue::String(ref string) => { + let mut bytes = string.clone().into_bytes(); + bytes[idx] = value.get_as_integer()? as u8; + + let string = String::from_utf8(bytes).unwrap(); + namespace.insert(s, AmlValue::String(string)); + }, + AmlValue::Buffer(ref b) => { + let mut b = b.clone(); + b[idx] = value.get_as_integer()? as u8; + + namespace.insert(s, AmlValue::Buffer(b)); + }, + AmlValue::Package(ref p) => { + let mut p = p.clone(); + p[idx] = value; + + namespace.insert(s, AmlValue::Package(p)); + }, + _ => return Err(AmlError::AmlValueError) + } + } + }, + _ => return Err(AmlError::AmlValueError) + }, + _ => return Err(AmlError::AmlValueError) + } + } }, - _ => () + AmlValue::String(s) => if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() { + namespace.insert(s, value); + }, + _ => return Err(AmlError::AmlValueError) } + + Ok(()) } - pub fn get(&self, name: AmlValue) -> AmlValue { - match name { - AmlValue::None => AmlValue::None, + pub fn get(&self, name: AmlValue) -> Result<AmlValue, AmlError> { + Ok(match name { AmlValue::ObjectReference(r) => match r { ObjectReference::ArgObj(i) => self.arg_vars[i as usize].clone(), ObjectReference::LocalObj(i) => self.local_vars[i as usize].clone(), - _ => AmlValue::None + ObjectReference::Object(ref s) => if let Some(ref namespace) = *ACPI_TABLE.namespace.read() { + if let Some(o) = namespace.get(s) { + o.clone() + } else { + AmlValue::None + } + } else { AmlValue::None }, + ObjectReference::Index(c, v) => if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() { + let idx = v.get_as_integer()? as usize; + match *c { + AmlValue::Package(p) => p[idx].clone(), + _ => AmlValue::None + } + } else { + AmlValue::None + } }, + AmlValue::String(ref s) => if let Some(ref namespace) = *ACPI_TABLE.namespace.read() { + if let Some(o) = namespace.get(s) { + o.clone() + } else { + AmlValue::None + } + } else { AmlValue::None }, _ => AmlValue::None - } + }) } } diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs index 8087c44b..262f7312 100644 --- a/src/acpi/aml/termlist.rs +++ b/src/acpi/aml/termlist.rs @@ -125,7 +125,7 @@ pub fn parse_method_invocation(data: &[u8], } let name = parse_name_string(data, ctx)?; - let method = ctx.get(name.val.clone()); + let method = ctx.get(name.val.clone())?; let method = match method { AmlValue::None => return Err(AmlError::AmlDeferredLoad), diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index bf6f7d60..2ea0482b 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -151,7 +151,7 @@ fn parse_def_load(data: &[u8], let name = parse_name_string(&data[2..], ctx)?; let ddb_handle_object = parse_super_name(&data[2 + name.len..], ctx)?; - let tbl = ctx.get(name.val).get_as_buffer()?; + let tbl = ctx.get(name.val)?.get_as_buffer()?; let sdt = unsafe { &*(tbl.as_ptr() as *const Sdt) }; if is_aml_table(sdt) { @@ -223,7 +223,7 @@ fn parse_def_reset(data: &[u8], parser_opcode_extended!(data, 0x26); let object = parse_super_name(&data[2..], ctx)?; - ctx.get(object.val.clone()).get_as_event()?; + ctx.get(object.val.clone())?.get_as_event()?; ctx.modify(object.val.clone(), AmlValue::Event(0)); @@ -333,7 +333,7 @@ fn parse_def_unload(data: &[u8], let object = parse_super_name(&data[2..], ctx)?; - let delta = ctx.get(object.val).get_as_ddb_handle()?; + let delta = ctx.get(object.val)?.get_as_ddb_handle()?; let mut namespace = ctx.prelock(); if let Some(ref mut ns) = *namespace { diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index d0a6c323..20dc7566 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -271,7 +271,7 @@ fn parse_def_ref_of(data: &[u8], let obj = parse_super_name(&data[1..], ctx)?; let res = match obj.val { AmlValue::String(ref s) => { - match ctx.get(AmlValue::String(s.clone())) { + match ctx.get(AmlValue::String(s.clone()))? { AmlValue::None => return Err(AmlError::AmlValueError), _ => ObjectReference::Object(s.clone()) } @@ -299,7 +299,7 @@ fn parse_def_deref_of(data: &[u8], parser_opcode!(data, 0x83); let obj = parse_term_arg(&data[1..], ctx)?; - let res = ctx.get(obj.val); + let res = ctx.get(obj.val)?; match res { AmlValue::None => Err(AmlError::AmlValueError), @@ -368,7 +368,7 @@ fn parse_def_increment(data: &[u8], let obj = parse_super_name(&data[1..], ctx)?; let mut namespace = ctx.prelock(); - let value = AmlValue::Integer(ctx.get(obj.val.clone()).get_as_integer()? + 1); + let value = AmlValue::Integer(ctx.get(obj.val.clone())?.get_as_integer()? + 1); ctx.modify(obj.val, value.clone()); Ok(AmlParseType { @@ -773,7 +773,7 @@ fn parse_def_size_of(data: &[u8], parser_opcode!(data, 0x87); let name = parse_super_name(&data[1..], ctx)?; - let obj = ctx.get(name.val); + let obj = ctx.get(name.val)?; let res = match obj { AmlValue::Buffer(ref v) => v.len(), @@ -1053,7 +1053,7 @@ fn parse_def_cond_ref_of(data: &[u8], let res = match obj.val { AmlValue::String(ref s) => { - match ctx.get(AmlValue::String(s.clone())) { + match ctx.get(AmlValue::String(s.clone()))? { AmlValue::None => return Ok(AmlParseType { val: AmlValue::Integer(0), len: 1 + obj.len + target.len @@ -1135,7 +1135,7 @@ fn parse_def_decrement(data: &[u8], let obj = parse_super_name(&data[1..], ctx)?; let mut namespace = ctx.prelock(); - let value = AmlValue::Integer(ctx.get(obj.val.clone()).get_as_integer()? - 1); + let value = AmlValue::Integer(ctx.get(obj.val.clone())?.get_as_integer()? - 1); ctx.modify(obj.val, value.clone()); Ok(AmlParseType { -- GitLab