فهرست منبع

Parse `DefFatal` and report to the user

Isaac Woods 3 سال پیش
والد
کامیت
514e55df07
3فایلهای تغییر یافته به همراه48 افزوده شده و 3 حذف شده
  1. 6 0
      aml/src/lib.rs
  2. 1 0
      aml/src/opcode.rs
  3. 41 3
      aml/src/type1.rs

+ 6 - 0
aml/src/lib.rs

@@ -674,6 +674,10 @@ pub trait Handler: Send + Sync {
     fn write_pci_u8(&self, segment: u16, bus: u8, device: u8, function: u8, offset: u16, value: u8);
     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);
+
+    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);
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
@@ -699,6 +703,8 @@ pub enum AmlError {
     /// that parser (e.g. the wrong opcode starts the stream). This is handled specially by some
     /// parsers such as `or` and `choice!`.
     WrongParser,
+    /// Returned when a `DefFatal` op is encountered. This is separately reported using [`Handler::handle_fatal_error`].
+    FatalError,
 
     /*
      * Errors produced manipulating AML names.

+ 1 - 0
aml/src/opcode.rs

@@ -34,6 +34,7 @@ pub const DEF_CREATE_QWORD_FIELD_OP: u8 = 0x8f;
 pub const EXT_DEF_MUTEX_OP: u8 = 0x01;
 pub const EXT_DEF_CREATE_FIELD_OP: u8 = 0x13;
 pub const EXT_REVISION_OP: u8 = 0x30;
+pub const EXT_DEF_FATAL_OP: u8 = 0x32;
 pub const EXT_DEF_OP_REGION_OP: u8 = 0x80;
 pub const EXT_DEF_FIELD_OP: u8 = 0x81;
 pub const EXT_DEF_DEVICE_OP: u8 = 0x82;

+ 41 - 3
aml/src/type1.rs

@@ -1,8 +1,21 @@
 use crate::{
-    opcode::{self, opcode},
-    parser::{choice, comment_scope, id, take_to_end_of_pkglength, ParseResult, Parser, Propagate},
+    opcode::{self, ext_opcode, opcode},
+    parser::{
+        choice,
+        comment_scope,
+        id,
+        take,
+        take_to_end_of_pkglength,
+        take_u32,
+        try_with_context,
+        ParseResult,
+        Parser,
+        Propagate,
+    },
     pkg_length::{pkg_length, PkgLength},
     term_object::{term_arg, term_list},
+    AmlContext,
+    AmlError,
     DebugVerbosity,
 };
 
@@ -19,7 +32,7 @@ where
     comment_scope(
         DebugVerbosity::AllScopes,
         "Type1Opcode",
-        choice!(def_breakpoint(), def_if_else(), def_noop(), def_return()),
+        choice!(def_breakpoint(), def_fatal(), def_if_else(), def_noop(), def_return()),
     )
 }
 
@@ -37,6 +50,31 @@ where
         .discard_result()
 }
 
+fn def_fatal<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * DefFatal := ExtOpPrefix 0x32 FatalType FatalCode FatalArg
+     * FatalType := ByteData
+     * FatalCode := DWordData
+     * FatalArg := TermArg => Integer
+     */
+    ext_opcode(opcode::EXT_DEF_FATAL_OP)
+        .then(comment_scope(
+            DebugVerbosity::Scopes,
+            "DefFatal",
+            take().then(take_u32()).then(term_arg()).map_with_context(
+                |((fatal_type, fatal_code), fatal_arg), context| -> (Result<(), Propagate>, &'c mut AmlContext) {
+                    let fatal_arg = try_with_context!(context, fatal_arg.as_integer(context));
+                    context.handler.handle_fatal_error(fatal_type, fatal_code, fatal_arg);
+                    (Err(Propagate::Err(AmlError::FatalError)), context)
+                },
+            ),
+        ))
+        .discard_result()
+}
+
 fn def_if_else<'a, 'c>() -> impl Parser<'a, 'c, ()>
 where
     'c: 'a,