Jelajahi Sumber

Parse thermal zones

Isaac Woods 3 tahun lalu
induk
melakukan
a55d82bad3
4 mengubah file dengan 91 tambahan dan 50 penghapusan
  1. 1 0
      aml/src/lib.rs
  2. 2 0
      aml/src/namespace.rs
  3. 1 0
      aml/src/opcode.rs
  4. 87 50
      aml/src/term_object.rs

+ 1 - 0
aml/src/lib.rs

@@ -299,6 +299,7 @@ impl AmlContext {
             // TODO: can any of these contain devices?
             LevelType::Processor => Ok(false),
             LevelType::PowerResource => Ok(false),
+            LevelType::ThermalZone => Ok(false),
             LevelType::MethodLocals => Ok(false),
         })?;
 

+ 2 - 0
aml/src/namespace.rs

@@ -32,6 +32,8 @@ pub enum LevelType {
     Processor,
     /// A `PowerResource` object's sub-objects are stored in a level of this type.
     PowerResource,
+    /// A `ThermalZone` object's sub-objects are stored in a level of this type.
+    ThermalZone,
     /// A level of this type is created at the same path as the name of a method when it is invoked. It can be
     /// used by the method to store local variables.
     MethodLocals,

+ 1 - 0
aml/src/opcode.rs

@@ -32,6 +32,7 @@ pub const EXT_DEF_FIELD_OP: u8 = 0x81;
 pub const EXT_DEF_DEVICE_OP: u8 = 0x82;
 pub const EXT_DEF_PROCESSOR_OP: u8 = 0x83;
 pub const EXT_DEF_POWER_RES_OP: u8 = 0x84;
+pub const EXT_DEF_THERMAL_ZONE_OP: u8 = 0x85;
 
 /*
  * Type 1 opcodes

+ 87 - 50
aml/src/term_object.rs

@@ -104,6 +104,7 @@ where
             def_device(),
             def_processor(),
             def_power_res(),
+            def_thermal_zone(),
             def_mutex()
         ),
     )
@@ -243,56 +244,6 @@ where
         .discard_result()
 }
 
-pub fn def_power_res<'a, 'c>() -> impl Parser<'a, 'c, ()>
-where
-    'c: 'a,
-{
-    /*
-     * DefPowerRes := ExtOpPrefix 0x84 PkgLength NameString SystemLevel ResourceOrder TermList
-     * SystemLevel := ByteData
-     * ResourceOrder := WordData
-     */
-    ext_opcode(opcode::EXT_DEF_POWER_RES_OP)
-        .then(comment_scope(
-            DebugVerbosity::Scopes,
-            "DefPowerRes",
-            pkg_length()
-                .then(name_string())
-                .then(take())
-                .then(take_u16())
-                .map_with_context(|(((pkg_length, name), system_level), resource_order), context| {
-                    /*
-                     * `PowerResource` objects contain data within themselves, and can also have sub-objects,
-                     * so we add both a level for the sub-objects, and a value for the data.
-                     */
-                    let resolved_name = try_with_context!(context, name.resolve(&context.current_scope));
-                    try_with_context!(
-                        context,
-                        context.namespace.add_level(resolved_name.clone(), LevelType::PowerResource)
-                    );
-                    try_with_context!(
-                        context,
-                        context.namespace.add_value(
-                            resolved_name.clone(),
-                            AmlValue::PowerResource { system_level, resource_order }
-                        )
-                    );
-                    let previous_scope = context.current_scope.clone();
-                    context.current_scope = resolved_name;
-
-                    (Ok((previous_scope, pkg_length)), context)
-                })
-                .feed(move |(previous_scope, pkg_length)| {
-                    term_list(pkg_length).map(move |_| Ok(previous_scope.clone()))
-                })
-                .map_with_context(|previous_scope, context| {
-                    context.current_scope = previous_scope;
-                    (Ok(()), context)
-                }),
-        ))
-        .discard_result()
-}
-
 pub fn def_field<'a, 'c>() -> impl Parser<'a, 'c, ()>
 where
     'c: 'a,
@@ -524,6 +475,92 @@ where
         .discard_result()
 }
 
+pub fn def_power_res<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * DefPowerRes := ExtOpPrefix 0x84 PkgLength NameString SystemLevel ResourceOrder TermList
+     * SystemLevel := ByteData
+     * ResourceOrder := WordData
+     */
+    ext_opcode(opcode::EXT_DEF_POWER_RES_OP)
+        .then(comment_scope(
+            DebugVerbosity::Scopes,
+            "DefPowerRes",
+            pkg_length()
+                .then(name_string())
+                .then(take())
+                .then(take_u16())
+                .map_with_context(|(((pkg_length, name), system_level), resource_order), context| {
+                    /*
+                     * `PowerResource` objects contain data within themselves, and can also have sub-objects,
+                     * so we add both a level for the sub-objects, and a value for the data.
+                     */
+                    let resolved_name = try_with_context!(context, name.resolve(&context.current_scope));
+                    try_with_context!(
+                        context,
+                        context.namespace.add_level(resolved_name.clone(), LevelType::PowerResource)
+                    );
+                    try_with_context!(
+                        context,
+                        context.namespace.add_value(
+                            resolved_name.clone(),
+                            AmlValue::PowerResource { system_level, resource_order }
+                        )
+                    );
+                    let previous_scope = context.current_scope.clone();
+                    context.current_scope = resolved_name;
+
+                    (Ok((previous_scope, pkg_length)), context)
+                })
+                .feed(move |(previous_scope, pkg_length)| {
+                    term_list(pkg_length).map(move |_| Ok(previous_scope.clone()))
+                })
+                .map_with_context(|previous_scope, context| {
+                    context.current_scope = previous_scope;
+                    (Ok(()), context)
+                }),
+        ))
+        .discard_result()
+}
+
+pub fn def_thermal_zone<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * DefThermalZone := ExtOpPrefix 0x85 PkgLength NameString TermList
+     * TODO: we use this pattern a lot (move into scope, parse a term_list, move back out). Could we simplify into
+     * just a `feed` by passing a scope into term_list?
+     */
+    ext_opcode(opcode::EXT_DEF_THERMAL_ZONE_OP)
+        .then(comment_scope(
+            DebugVerbosity::Scopes,
+            "DefThermalZone",
+            pkg_length()
+                .then(name_string())
+                .map_with_context(|(pkg_length, name), context| {
+                    let resolved_name = try_with_context!(context, name.resolve(&context.current_scope));
+                    try_with_context!(
+                        context,
+                        context.namespace.add_level(resolved_name.clone(), LevelType::ThermalZone)
+                    );
+
+                    let previous_scope = context.current_scope.clone();
+                    context.current_scope = resolved_name;
+
+                    (Ok((pkg_length, previous_scope)), context)
+                })
+                .feed(|(length, previous_scope)| term_list(length).map(move |_| Ok(previous_scope.clone())))
+                .map_with_context(|previous_scope, context| {
+                    context.current_scope = previous_scope;
+                    (Ok(()), context)
+                }),
+        ))
+        .discard_result()
+}
+
 pub fn def_mutex<'a, 'c>() -> impl Parser<'a, 'c, ()>
 where
     'c: 'a,