فهرست منبع

Parse DefCreateBitField

This is our first working buffer field implementation, and can serve as
the foundation for the rest of them pretty easily, hopefully. It seems to
work correctly, but we'll need to implement support for reading from and
writing to buffer fields manually. Lukily, it errors at the moment, so it
won't confuse anyone to add this.
Isaac Woods 3 سال پیش
والد
کامیت
52f044ecfd
2فایلهای تغییر یافته به همراه37 افزوده شده و 1 حذف شده
  1. 1 0
      aml/src/opcode.rs
  2. 36 1
      aml/src/term_object.rs

+ 1 - 0
aml/src/opcode.rs

@@ -26,6 +26,7 @@ pub const DEF_BUFFER_OP: u8 = 0x11;
 pub const DEF_PACKAGE_OP: u8 = 0x12;
 pub const DEF_METHOD_OP: u8 = 0x14;
 pub const DEF_EXTERNAL_OP: u8 = 0x15;
+pub const DEF_CREATE_BIT_FIELD_OP: u8 = 0x8d;
 pub const EXT_DEF_MUTEX_OP: u8 = 0x01;
 pub const EXT_REVISION_OP: u8 = 0x30;
 pub const EXT_DEF_OP_REGION_OP: u8 = 0x80;

+ 36 - 1
aml/src/term_object.rs

@@ -26,7 +26,7 @@ use crate::{
     AmlHandle,
     DebugVerbosity,
 };
-use alloc::string::String;
+use alloc::{string::String, sync::Arc, vec::Vec};
 use core::str;
 
 /// `TermList`s are usually found within explicit-length objects (so they have a `PkgLength`
@@ -98,6 +98,7 @@ where
         DebugVerbosity::AllScopes,
         "NamedObj",
         choice!(
+            def_create_bit_field(),
             def_op_region(),
             def_field(),
             def_method(),
@@ -173,6 +174,40 @@ where
         .discard_result()
 }
 
+pub fn def_create_bit_field<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * DefCreateBitField := 0x8d SourceBuf BitIndex NameString
+     * SourceBuf := TermArg => Buffer
+     * BitIndex := TermArg => Integer
+     */
+    opcode(opcode::DEF_CREATE_BIT_FIELD_OP)
+        .then(comment_scope(
+            DebugVerbosity::AllScopes,
+            "DefCreateBitField",
+            term_arg().then(term_arg()).then(name_string()).map_with_context(
+                |((source, index), name), context| {
+                    let source_data: Arc<Vec<u8>> = try_with_context!(context, source.as_buffer(context)).clone();
+                    let index = try_with_context!(context, index.as_integer(context));
+
+                    try_with_context!(
+                        context,
+                        context.namespace.add_value_at_resolved_path(
+                            name,
+                            &context.current_scope,
+                            AmlValue::BufferField { buffer_data: source_data, offset: index, length: 1 }
+                        )
+                    );
+
+                    (Ok(()), context)
+                },
+            ),
+        ))
+        .discard_result()
+}
+
 pub fn def_op_region<'a, 'c>() -> impl Parser<'a, 'c, ()>
 where
     'c: 'a,