浏览代码

Support writes from buffers into buffer fields (minus zero extension)

Isaac Woods 3 年之前
父节点
当前提交
8cb1df1f64
共有 2 个文件被更改,包括 17 次插入5 次删除
  1. 16 4
      aml/src/value.rs
  2. 1 1
      tests/buffer_fields.asl

+ 16 - 4
aml/src/value.rs

@@ -518,9 +518,10 @@ impl AmlValue {
                      * it's smaller than the length of the buffer field, it's zero-extended. If it's larger, the
                      * upper bits are truncated.
                      */
-                    let bits_to_copy = cmp::min(*length, 64);
-                    bitslice[offset..(offset + length)]
+                    let bits_to_copy = cmp::min(length, 64);
+                    bitslice[offset..(offset + bits_to_copy)]
                         .copy_from_bitslice(&value.to_le_bytes().view_bits()[..(bits_to_copy as usize)]);
+                    // TODO: zero extend the field if needed
                     Ok(())
                 }
                 AmlValue::Boolean(value) => {
@@ -528,8 +529,19 @@ impl AmlValue {
                     Ok(())
                 }
                 AmlValue::Buffer(value) => {
-                    // TODO
-                    todo!()
+                    /*
+                     * When a `Buffer` is written into a `BufferField`, the entire contents are copied into the
+                     * field. If the buffer is smaller than the size of the buffer field, it is zero extended. If
+                     * the buffer is larger, the upper bits are truncated.
+                     * XXX: this behaviour is only explicitly defined in ACPI 2.0+. While undefined in ACPI 1.0,
+                     * we produce the same behaviour there.
+                     */
+                    let value_data = value.lock();
+                    let bits_to_copy = cmp::min(length, value_data.len() * 8);
+                    bitslice[offset..(offset + bits_to_copy)]
+                        .copy_from_bitslice(&value_data.view_bits()[..(bits_to_copy as usize)]);
+                    // TODO: zero extend if needed
+                    Ok(())
                 }
                 _ => Err(AmlError::TypeCannotBeWrittenToBufferField(value.type_of())),
             }

+ 1 - 1
tests/buffer_fields.asl

@@ -13,5 +13,5 @@ DefinitionBlock("buffer_fields.aml", "DSDT", 1, "RSACPI", "BUFFLD", 1) {
 	BYTE = 0x01
 	WORD = 0x0302
 	DWRD = 0x07060504
-	/* QWRD = Buffer() { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f } */
+	QWRD = Buffer() { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }
 }