Implemented much of ctx::modify and ctx::get
This commit is contained in:
@@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user