diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 47a8e43..c7d2636 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -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, diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index ddead79..0862e72 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -68,7 +68,7 @@ pub enum AmlValue { DDBHandle(u32), // Index into the XSDT DebugObject, Device(Vec), - Event, + Event(u64), FieldUnit { selector: FieldSelector, connection: Box, @@ -109,6 +109,13 @@ impl Debug for AmlValue { } impl AmlValue { + pub fn get_as_event(&self) -> Result { + match *self { + AmlValue::Event(ref e) => Ok(e.clone()), + _ => Err(AmlError::AmlValueError) + } + } + pub fn get_as_string(&self) -> Result { match *self { AmlValue::String(ref s) => Ok(s.clone()), diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index adcb769..e5f42ac 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -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 diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 7d889ec..7ce6532 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -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 }) }