浏览代码

Take the context on value-conversion operations

This is slightly horrifying, but it seems that some implicit conversions
can involve things like reading from PCI config space (e.g. converting a
FieldUnit into an Integer in certain cases). I'm not sure this is 100%
correct just from how ridiculous it sounds, but it does appear to produce
the correct results...
Isaac Woods 4 年之前
父节点
当前提交
3e8efc7af6
共有 5 个文件被更改,包括 21 次插入17 次删除
  1. 1 1
      aml/src/lib.rs
  2. 3 3
      aml/src/pci_routing.rs
  3. 2 2
      aml/src/term_object.rs
  4. 12 8
      aml/src/type2.rs
  5. 3 3
      aml/src/value.rs

+ 1 - 1
aml/src/lib.rs

@@ -328,7 +328,7 @@ impl AmlContext {
             Target::Name(ref path) => {
                 let (_, handle) = self.namespace.search(path, &self.current_scope)?;
                 let desired_type = self.namespace.get(handle).unwrap().type_of();
-                let converted_object = value.as_type(desired_type)?;
+                let converted_object = value.as_type(desired_type, self)?;
 
                 *self.namespace.get_mut(handle)? = converted_object;
                 Ok(self.namespace.get(handle)?.clone())

+ 3 - 3
aml/src/pci_routing.rs

@@ -87,10 +87,10 @@ impl PciRoutingTable {
                      *   |            |           | pin is connected.                                         |
                      *   | -----------|-----------|-----------------------------------------------------------|
                      */
-                    let address = pin_package[0].as_integer()?;
+                    let address = pin_package[0].as_integer(context)?;
                     let device = address.get_bits(16..32).try_into().map_err(|_| AmlError::PrtInvalidAddress)?;
                     let function = address.get_bits(0..16).try_into().map_err(|_| AmlError::PrtInvalidAddress)?;
-                    let pin = match pin_package[1].as_integer()? {
+                    let pin = match pin_package[1].as_integer(context)? {
                         0 => Pin::IntA,
                         1 => Pin::IntB,
                         2 => Pin::IntC,
@@ -110,7 +110,7 @@ impl PciRoutingTable {
                                 pin,
                                 route_type: PciRouteType::Gsi(
                                     pin_package[3]
-                                        .as_integer()?
+                                        .as_integer(context)?
                                         .try_into()
                                         .map_err(|_| AmlError::PrtInvalidGsi)?,
                                 ),

+ 2 - 2
aml/src/term_object.rs

@@ -202,11 +202,11 @@ where
                         space @ 0x80..=0xff => RegionSpace::OemDefined(space),
                         byte => return (Err(AmlError::InvalidRegionSpace(byte)), context),
                     };
-                    let offset = match offset.as_integer() {
+                    let offset = match offset.as_integer(context) {
                         Ok(offset) => offset,
                         Err(err) => return (Err(err), context),
                     };
-                    let length = match length.as_integer() {
+                    let length = match length.as_integer(context) {
                         Ok(length) => length,
                         Err(err) => return (Err(err), context),
                     };

+ 12 - 8
aml/src/type2.rs

@@ -70,8 +70,10 @@ where
             DebugVerbosity::AllScopes,
             "DefBuffer",
             pkg_length().then(term_arg()).feed(|(pkg_length, buffer_size)| {
-                take_to_end_of_pkglength(pkg_length)
-                    .map(move |bytes| Ok((bytes.to_vec(), buffer_size.as_integer()?)))
+                take_to_end_of_pkglength(pkg_length).map_with_context(move |bytes, context| {
+                    let length = try_with_context!(context, buffer_size.as_integer(context));
+                    (Ok((bytes.to_vec(), length)), context)
+                })
             }),
         ))
         .map(|((), (bytes, buffer_size))| Ok(AmlValue::Buffer { bytes, size: buffer_size }))
@@ -89,8 +91,10 @@ where
         .then(comment_scope(
             DebugVerbosity::AllScopes,
             "DefLEqual",
-            term_arg().then(term_arg()).map(|(left_arg, right_arg)| {
-                Ok(AmlValue::Boolean(left_arg.as_integer()? == right_arg.as_integer()?))
+            term_arg().then(term_arg()).map_with_context(|(left_arg, right_arg), context| {
+                let left = try_with_context!(context, left_arg.as_integer(context));
+                let right = try_with_context!(context, right_arg.as_integer(context));
+                (Ok(AmlValue::Boolean(left == right)), context)
             }),
         ))
         .map(|((), result)| Ok(result))
@@ -149,8 +153,8 @@ where
     opcode(opcode::DEF_SHIFT_LEFT)
         .then(comment_scope(DebugVerbosity::Scopes, "DefShiftLeft", term_arg().then(term_arg()).then(target())))
         .map_with_context(|((), ((operand, shift_count), target)), context| {
-            let operand = try_with_context!(context, operand.as_integer());
-            let shift_count = try_with_context!(context, shift_count.as_integer());
+            let operand = try_with_context!(context, operand.as_integer(context));
+            let shift_count = try_with_context!(context, shift_count.as_integer(context));
             let shift_count =
                 try_with_context!(context, shift_count.try_into().map_err(|_| AmlError::InvalidShiftLeft));
 
@@ -176,8 +180,8 @@ where
     opcode(opcode::DEF_SHIFT_RIGHT)
         .then(comment_scope(DebugVerbosity::Scopes, "DefShiftRight", term_arg().then(term_arg()).then(target())))
         .map_with_context(|((), ((operand, shift_count), target)), context| {
-            let operand = try_with_context!(context, operand.as_integer());
-            let shift_count = try_with_context!(context, shift_count.as_integer());
+            let operand = try_with_context!(context, operand.as_integer(context));
+            let shift_count = try_with_context!(context, shift_count.as_integer(context));
             let shift_count =
                 try_with_context!(context, shift_count.try_into().map_err(|_| AmlError::InvalidShiftRight));
 

+ 3 - 3
aml/src/value.rs

@@ -178,7 +178,7 @@ impl AmlValue {
         }
     }
 
-    pub fn as_integer(&self) -> Result<u64, AmlError> {
+    pub fn as_integer(&self, context: &AmlContext) -> Result<u64, AmlError> {
         match self {
             AmlValue::Integer(value) => Ok(*value),
 
@@ -241,7 +241,7 @@ impl AmlValue {
     ///     `Integer` from: `Buffer`, `BufferField`, `DdbHandle`, `FieldUnit`, `String`, `Debug`
     ///     `Package` from: `Debug`
     ///     `String` from: `Integer`, `Buffer`, `Debug`
-    pub fn as_type(&self, desired_type: AmlType) -> Result<AmlValue, AmlError> {
+    pub fn as_type(&self, desired_type: AmlType, context: &AmlContext) -> Result<AmlValue, AmlError> {
         // Cache the type of this object
         let our_type = self.type_of();
 
@@ -252,7 +252,7 @@ impl AmlValue {
 
         // TODO: implement all of the rules
         match desired_type {
-            AmlType::Integer => self.as_integer().map(|value| AmlValue::Integer(value)),
+            AmlType::Integer => self.as_integer(context).map(|value| AmlValue::Integer(value)),
             _ => Err(AmlError::IncompatibleValueConversion),
         }
     }