Implemented much of ctx::modify and ctx::get

This commit is contained in:
Connor Wood
2017-07-30 11:23:32 +03:00
parent 6122b21997
commit 41ce7fdf1f
4 changed files with 88 additions and 22 deletions

View File

@@ -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
}
})
}
}

View File

@@ -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),

View File

@@ -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 {

View File

@@ -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 {