diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs index 1d16d2b..47a8e43 100644 --- a/src/acpi/aml/namedobj.rs +++ b/src/acpi/aml/namedobj.rs @@ -377,7 +377,8 @@ fn parse_def_data_region(data: &[u8], accessor: Accessor { read: |x| 0 as u64, write: |x, y| () - } + }, + accessed_by: None }); Ok(AmlParseType { @@ -477,7 +478,8 @@ fn parse_def_op_region(data: &[u8], accessor: Accessor { read: |x| 0 as u64, write: |x, y| () - } + }, + accessed_by: None }); Ok(AmlParseType { @@ -819,7 +821,7 @@ fn parse_def_mutex(data: &[u8], let sync_level = flags & 0x0F; let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val); - ctx.add_to_namespace(local_scope_string, AmlValue::Mutex(sync_level)); + ctx.add_to_namespace(local_scope_string, AmlValue::Mutex((sync_level, None))); Ok(AmlParseType { val: AmlValue::None, diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index ac3f585..ddead79 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -79,13 +79,14 @@ pub enum AmlValue { Integer(u64), IntegerConstant(u64), Method(Method), - Mutex(u8), + Mutex((u8, Option)), ObjectReference(ObjectReference), OperationRegion { region: RegionSpace, offset: Box, len: Box, - accessor: Accessor + accessor: Accessor, + accessed_by: Option }, Package(Vec), String(String), diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index e31c6f7..a762eba 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -2,6 +2,8 @@ use collections::string::String; use collections::btree_map::BTreeMap; use collections::vec::Vec; +use spin::RwLockWriteGuard; + use super::namespace::{ AmlValue, ObjectReference }; use super::AmlError; @@ -101,6 +103,10 @@ impl AmlExecutionContext { } } + pub fn prelock(&mut self) -> RwLockWriteGuard<'static, Option>> { + ACPI_TABLE.namespace.write() + } + pub fn modify(&mut self, name: AmlValue, value: AmlValue) { // TODO: throw errors // TODO: return DRO diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs index c505201..c91b3bd 100644 --- a/src/acpi/aml/type2opcode.rs +++ b/src/acpi/aml/type2opcode.rs @@ -307,17 +307,70 @@ fn parse_def_acquire(data: &[u8], }) } - // TODO: Store the result - // TODO: Perform computation parser_opcode_extended!(data, 0x23); let obj = parse_super_name(&data[1..], ctx)?; let timeout = (data[2 + obj.len] as u16) + ((data[3 + obj.len] as u16) << 8); + + let (seconds, nanoseconds) = monotonic(); + let starting_time_ns = nanoseconds + (seconds * 1000000000); + + let id = ctx.ctx_id; + + loop { + { + let mut namespace = ctx.prelock(); + let mutex = ctx.get(obj.val.clone()); + + match mutex { + AmlValue::Mutex((sync_level, owner)) => { + if owner == None { + ctx.modify(obj.val.clone(), AmlValue::Mutex((sync_level, Some(id)))); + return Ok(AmlParseType { + val: AmlValue::Integer(0), + len: 4 + obj.len + }); + } + }, + AmlValue::OperationRegion { region, offset, len, accessor, accessed_by } => { + if accessed_by == None { + ctx.modify(obj.val.clone(), AmlValue::OperationRegion { + region, + offset, + len, + accessor, + accessed_by: Some(id) + }); + return Ok(AmlParseType { + val: AmlValue::Integer(0), + len: 4 + 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: 4 + obj.len + }); + } + } + } Ok(AmlParseType { val: AmlValue::Uninitialized, len: 4 + obj.len }) + // This should never run } fn parse_def_increment(data: &[u8], @@ -333,8 +386,9 @@ fn parse_def_increment(data: &[u8], parser_opcode!(data, 0x75); 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); - ctx.modify(obj.val, value.clone()); Ok(AmlParseType {