Implemented externam

This commit is contained in:
Connor Wood
2017-08-29 12:02:03 +01:00
parent 71c5301448
commit d75dfd3c20
3 changed files with 78 additions and 5 deletions

View File

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

View File

@@ -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());

View File

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