Implemented Event synchronisation objects

This commit is contained in:
Connor Wood
2017-07-22 10:55:09 +01:00
parent b0b8a7e85d
commit b7d9ad60bb
4 changed files with 59 additions and 12 deletions

View File

@@ -402,7 +402,7 @@ fn parse_def_event(data: &[u8],
let name = parse_name_string(&data[2..], ctx)?;
let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val);
ctx.add_to_namespace(local_scope_string, AmlValue::Event);
ctx.add_to_namespace(local_scope_string, AmlValue::Event(0));
Ok(AmlParseType {
val: AmlValue::None,

View File

@@ -68,7 +68,7 @@ pub enum AmlValue {
DDBHandle(u32), // Index into the XSDT
DebugObject,
Device(Vec<String>),
Event,
Event(u64),
FieldUnit {
selector: FieldSelector,
connection: Box<AmlValue>,
@@ -109,6 +109,13 @@ impl Debug for AmlValue {
}
impl AmlValue {
pub fn get_as_event(&self) -> Result<u64, AmlError> {
match *self {
AmlValue::Event(ref e) => Ok(e.clone()),
_ => Err(AmlError::AmlValueError)
}
}
pub fn get_as_string(&self) -> Result<String, AmlError> {
match *self {
AmlValue::String(ref s) => Ok(s.clone()),

View File

@@ -192,9 +192,6 @@ fn parse_def_release(data: &[u8],
})
}
// TODO: Check ownership of the mutex pointed to
// TODO: FATAL if not owned
// TODO: Release if it is
parser_opcode_extended!(data, 0x27);
let obj = parse_super_name(&data[2..], ctx)?;
@@ -246,10 +243,12 @@ fn parse_def_reset(data: &[u8],
})
}
// TODO: object (of type Event) is a semaphore. Reset the resource count to 0
parser_opcode_extended!(data, 0x26);
let object = parse_super_name(&data[2..], ctx)?;
let event = ctx.get(object.val.clone()).get_as_event()?;
ctx.modify(object.val.clone(), AmlValue::Event(0));
Ok(AmlParseType {
val: AmlValue::None,
@@ -267,11 +266,14 @@ fn parse_def_signal(data: &[u8],
})
}
// TODO: Increment the resource count of the semaphore
parser_opcode_extended!(data, 0x24);
let object = parse_super_name(&data[2..], ctx)?;
let namespace = ctx.prelock();
let event = ctx.get(object.val.clone()).get_as_event()?;
ctx.modify(object.val.clone(), AmlValue::Event(event + 1));
Ok(AmlParseType {
val: AmlValue::None,
len: 2 + object.len

View File

@@ -957,15 +957,53 @@ fn parse_def_wait(data: &[u8],
})
}
// TODO: Compute the result
parser_opcode_extended!(data, 0x25);
let event_object = parse_super_name(&data[2..], ctx)?;
let operand = parse_term_arg(&data[2 + event_object.len..], ctx)?;
let obj = parse_super_name(&data[2..], ctx)?;
let timeout_obj = parse_term_arg(&data[2 + obj.len..], ctx)?;
let timeout = timeout_obj.val.get_as_integer()?;
let (seconds, nanoseconds) = monotonic();
let starting_time_ns = nanoseconds + (seconds * 1000000000);
loop {
{
let mut namespace = ctx.prelock();
let mutex = ctx.get(obj.val.clone());
match mutex {
AmlValue::Event(count) => {
if count > 0 {
ctx.modify(obj.val.clone(), AmlValue::Event(count - 1));
return Ok(AmlParseType {
val: AmlValue::Integer(0),
len: 2 + obj.len + timeout_obj.len
});
}
},
_ => return Err(AmlError::AmlValueError)
}
}
if timeout >= 0xFFFF {
// TODO: Brief sleep here
} else {
let (seconds, nanoseconds) = monotonic();
let current_time_ns = nanoseconds + (seconds * 1000000000);
if current_time_ns - starting_time_ns > timeout as u64 * 1000000 {
return Ok(AmlParseType {
val: AmlValue::Integer(1),
len: 2 + obj.len + timeout_obj.len
});
}
}
}
Ok(AmlParseType {
val: AmlValue::Uninitialized,
len: 2 + event_object.len + operand.len
len: 2 + obj.len + timeout_obj.len
})
}