Browse Source

Parse bits of ComputationalData that we need so far

Isaac Woods 5 years ago
parent
commit
9e868f90d9
4 changed files with 103 additions and 2 deletions
  1. 4 0
      aml_parser/src/lib.rs
  2. 1 1
      aml_parser/src/pkg_length.rs
  3. 94 0
      aml_parser/src/term_object.rs
  4. 4 1
      aml_parser/src/value.rs

+ 4 - 0
aml_parser/src/lib.rs

@@ -23,6 +23,10 @@ use log::{error, trace};
 use parser::Parser;
 use pkg_length::PkgLength;
 
+/// AML has a `RevisionOp` operator that returns the "AML interpreter revision". It's not clear
+/// what this is actually used for, but this is ours.
+pub const AML_INTERPRETER_REVISION: u64 = 0;
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum AmlError {
     UnexpectedEndOfStream,

+ 1 - 1
aml_parser/src/pkg_length.rs

@@ -71,7 +71,7 @@ pub fn raw_pkg_length<'a>() -> impl Parser<'a, u32> {
              * The stream was too short. We return an error, making sure to return the
              * *original* stream (that we haven't consumed any of).
              */
-            Err((_, err)) => return Err((input, AmlError::UnexpectedEndOfStream)),
+            Err(_) => return Err((input, AmlError::UnexpectedEndOfStream)),
         };
 
         Ok((new_input, length))

+ 94 - 0
aml_parser/src/term_object.rs

@@ -3,6 +3,7 @@ use crate::{
     opcode::{opcode, SCOPE_OP},
     parser::{choice, comment, comment_scope, take_n, ParseResult, Parser},
     pkg_length::{pkg_length, PkgLength},
+    value::{AmlValue, FieldFlags},
     AmlNamespace,
 };
 use log::{debug, trace};
@@ -44,3 +45,96 @@ pub fn def_scope<'a>() -> impl Parser<'a, ()> {
         ))
         .discard_result()
 }
+pub fn computational_data<'a>() -> impl Parser<'a, AmlValue> {
+    /*
+     * ComputationalData := ByteConst | WordConst | DWordConst | QWordConst | String |
+     *                      ConstObj | RevisionOp | DefBuffer
+     * ByteConst := 0x0a ByteData
+     * WordConst := 0x0b WordData
+     * DWordConst := 0x0c DWordData
+     * QWordConst := 0x0e QWordData
+     * String := 0x0d AsciiCharList NullChar
+     * ConstObj := ZeroOp(0x00) | OneOp(0x01) | OnesOp(0xff)
+     * RevisionOp := ExtOpPrefix(0x5b) 0x30
+     */
+    let const_parser = |input: &'a [u8]| {
+        let (new_input, op) = take().parse(input)?;
+
+        match op {
+            opcode::BYTE_CONST => {
+                take().map(|value| AmlValue::Integer(value as u64)).parse(new_input)
+            }
+            opcode::WORD_CONST => {
+                take_u16().map(|value| AmlValue::Integer(value as u64)).parse(new_input)
+            }
+            opcode::DWORD_CONST => {
+                take_u32().map(|value| AmlValue::Integer(value as u64)).parse(new_input)
+            }
+            opcode::QWORD_CONST => {
+                take_u64().map(|value| AmlValue::Integer(value)).parse(new_input)
+            }
+            // TODO: implement String
+            opcode::ZERO_OP => Ok((new_input, AmlValue::Integer(0))),
+            opcode::ONE_OP => Ok((new_input, AmlValue::Integer(1))),
+            opcode::ONES_OP => Ok((new_input, AmlValue::Integer(u64::max_value()))),
+
+            _ => Err((input, AmlError::UnexpectedByte(op))),
+        }
+    };
+
+    comment_scope(
+        "ComputationalData",
+        choice!(
+            ext_opcode(opcode::EXT_REVISION_OP)
+                .map(|_| AmlValue::Integer(crate::AML_INTERPRETER_REVISION)),
+            const_parser //TODO: parse DefBuffer here too
+        ),
+    )
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use crate::test_utils::*;
+
+    #[test]
+    fn test_computational_data() {
+        check_ok!(
+            computational_data().parse(&[0x00, 0x34, 0x12]),
+            AmlValue::Integer(0),
+            &[0x34, 0x12]
+        );
+        check_ok!(
+            computational_data().parse(&[0x01, 0x18, 0xf3]),
+            AmlValue::Integer(1),
+            &[0x18, 0xf3]
+        );
+        check_ok!(
+            computational_data().parse(&[0xff, 0x98, 0xc3]),
+            AmlValue::Integer(u64::max_value()),
+            &[0x98, 0xc3]
+        );
+        check_ok!(
+            computational_data().parse(&[0x5b, 0x30]),
+            AmlValue::Integer(crate::AML_INTERPRETER_REVISION),
+            &[]
+        );
+        check_ok!(
+            computational_data().parse(&[0x0a, 0xf3, 0x35]),
+            AmlValue::Integer(0xf3),
+            &[0x35]
+        );
+        check_ok!(computational_data().parse(&[0x0b, 0xf3, 0x35]), AmlValue::Integer(0x35f3), &[]);
+        check_ok!(
+            computational_data().parse(&[0x0c, 0xf3, 0x35, 0x12, 0x65, 0xff, 0x00]),
+            AmlValue::Integer(0x651235f3),
+            &[0xff, 0x00]
+        );
+        check_ok!(
+            computational_data()
+                .parse(&[0x0e, 0xf3, 0x35, 0x12, 0x65, 0xff, 0x00, 0x67, 0xde, 0x28]),
+            AmlValue::Integer(0xde6700ff651235f3),
+            &[0x28]
+        );
+    }
+}

+ 4 - 1
aml_parser/src/value.rs

@@ -1 +1,4 @@
-pub enum AmlValue {}
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub enum AmlValue {
+    Integer(u64),
+}