2
0
Эх сурвалжийг харах

aml: add support for the `DefStall` opcode

Isaac Woods 1 жил өмнө
parent
commit
133001e59d

+ 5 - 0
aml/src/lib.rs

@@ -689,6 +689,11 @@ pub trait Handler: Send + Sync {
     fn write_pci_u16(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u16);
     fn write_pci_u32(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u32);
 
+    /// Stall for at least the given number of **microseconds**. An implementation should not relinquish control of
+    /// the processor during the stall, and for this reason, firmwares should not stall for periods of more than
+    /// 100 microseconds.
+    fn stall(&self, microseconds: u64);
+
     fn handle_fatal_error(&self, fatal_type: u8, fatal_code: u32, fatal_arg: u64) {
         panic!("Fatal error while executing AML (encountered DefFatal op). fatal_type = {:?}, fatal_code = {:?}, fatal_arg = {:?}", fatal_type, fatal_code, fatal_arg);
     }

+ 3 - 2
aml/src/opcode.rs

@@ -45,7 +45,7 @@ pub const EXT_DEF_POWER_RES_OP: u8 = 0x84;
 pub const EXT_DEF_THERMAL_ZONE_OP: u8 = 0x85;
 
 /*
- * Type 1 opcodes
+ * Statement opcodes
  */
 pub const DEF_CONTINUE_OP: u8 = 0x9f;
 pub const DEF_IF_ELSE_OP: u8 = 0xa0;
@@ -55,9 +55,10 @@ pub const DEF_NOOP_OP: u8 = 0xa3;
 pub const DEF_RETURN_OP: u8 = 0xa4;
 pub const DEF_BREAK_OP: u8 = 0xa5;
 pub const DEF_BREAKPOINT_OP: u8 = 0xcc;
+pub const EXT_DEF_STALL_OP: u8 = 0x21;
 
 /*
- * Type 2 opcodes
+ * Expression opcodes
  */
 pub const DEF_STORE_OP: u8 = 0x70;
 pub const DEF_ADD_OP: u8 = 0x72;

+ 22 - 0
aml/src/statement.rs

@@ -39,6 +39,7 @@ where
             def_if_else(),
             def_noop(),
             def_return(),
+            def_stall(),
             def_while()
         ),
     )
@@ -209,6 +210,27 @@ where
         .discard_result()
 }
 
+fn def_stall<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * DefStall := ExtOpPrefix 0x21 USecTime
+     * USecTime := TermArg => Integer
+     */
+    ext_opcode(opcode::EXT_DEF_STALL_OP)
+        .then(comment_scope(
+            DebugVerbosity::Scopes,
+            "DefStall",
+            term_arg().map_with_context(|microseconds, context| {
+                let microseconds = try_with_context!(context, microseconds.as_integer(&context));
+                context.handler.stall(microseconds);
+                (Ok(()), context)
+            }),
+        ))
+        .discard_result()
+}
+
 fn def_while<'a, 'c>() -> impl Parser<'a, 'c, ()>
 where
     'c: 'a,