diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index e8a1865..1cfc6e0 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -65,6 +65,73 @@ impl AmlExecutionContext { sync_level: 0 } } + + pub fn wait_for_event(&mut self, event_ptr: AmlValue) -> Result { + let mut namespace_ptr = self.prelock(); + let mut namespace = match *namespace_ptr { + Some(ref mut n) => n, + None => return Err(AmlError::AmlHardFatal) + }; + + let mutex_idx = match event_ptr { + AmlValue::String(ref s) => s.clone(), + AmlValue::ObjectReference(ref o) => match *o { + ObjectReference::Object(ref s) => s.clone(), + _ => return Err(AmlError::AmlValueError) + }, + _ => return Err(AmlError::AmlValueError) + }; + + let mutex = match namespace.get(&mutex_idx) { + Some(s) => s.clone(), + None => return Err(AmlError::AmlValueError) + }; + + match mutex { + AmlValue::Event(count) => { + if count > 0 { + namespace.insert(mutex_idx, AmlValue::Event(count - 1)); + return Ok(true); + } + }, + _ => return Err(AmlError::AmlValueError) + } + + Ok(false) + } + + pub fn signal_event(&mut self, event_ptr: AmlValue) -> Result<(), AmlError> { + let mut namespace_ptr = self.prelock(); + let mut namespace = match *namespace_ptr { + Some(ref mut n) => n, + None => return Err(AmlError::AmlHardFatal) + }; + + + let mutex_idx = match event_ptr { + AmlValue::String(ref s) => s.clone(), + AmlValue::ObjectReference(ref o) => match *o { + ObjectReference::Object(ref s) => s.clone(), + _ => return Err(AmlError::AmlValueError) + }, + _ => return Err(AmlError::AmlValueError) + }; + + let mutex = match namespace.get(&mutex_idx) { + Some(s) => s.clone(), + None => return Err(AmlError::AmlValueError) + }; + + match mutex { + AmlValue::Event(count) => { + namespace.insert(mutex_idx, AmlValue::Event(count + 1)); + return Ok(()); + }, + _ => return Err(AmlError::AmlValueError) + } + + Ok(()) + } pub fn release_mutex(&mut self, mutex_ptr: AmlValue) -> Result<(), AmlError> { let id = self.ctx_id; @@ -123,9 +190,8 @@ impl AmlExecutionContext { Ok(()) } - pub fn acquire_mutex(&mut self, mutex_ptr: AmlValue, timeout: u16) -> Result { - let id = self.ctx_id; - + pub fn acquire_mutex(&mut self, mutex_ptr: AmlValue) -> Result { + let id = self.ctx_id; let mut namespace_ptr = self.prelock(); let mut namespace = match *namespace_ptr { diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs index c277b32..bf6f7d6 100644 --- a/src/acpi/aml/type1opcode.rs +++ b/src/acpi/aml/type1opcode.rs @@ -246,11 +246,7 @@ fn parse_def_signal(data: &[u8], 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)); - + ctx.signal_event(object.val)?; Ok(AmlParseType { val: AmlValue::None, len: 2 + object.len diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index 2ff6017..d0a6c32 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -329,7 +329,7 @@ fn parse_def_acquire(data: &[u8], let starting_time_ns = nanoseconds + (seconds * 1000000000); loop { - match ctx.acquire_mutex(obj.val.clone(), timeout) { + match ctx.acquire_mutex(obj.val.clone()) { Err(e) => return Err(e), Ok(b) => if b { return Ok(AmlParseType { @@ -1012,35 +1012,25 @@ fn parse_def_wait(data: &[u8], 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 { + match ctx.wait_for_event(obj.val.clone()) { + Err(e) => return Err(e), + Ok(b) => if b { return Ok(AmlParseType { - val: AmlValue::Integer(1), + val: AmlValue::Integer(0), len: 2 + obj.len + timeout_obj.len - }); + }) + } else 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 + }); + } } } }